The following is the contents of the post at
<http://mail.python.org/pipermail/mailman-developers/2004-October/017343.html>.

The actual patch is at redhat_fhs.patch in this (contrib/) directory.

Note that this patch only patches configure.in, so if you apply this patch,
you need to then run GNU autoconf to build the patched ./configure.


[Mailman-Developers] FHS installation changes
John Dennis jdennis at redhat.com
Mon Oct 18 22:26:21 CEST 2004

Overview:
---------

Earlier I wrote about our (Red Hat's) desire to make mailman be FHS
compliant, in part to allow mailman to fall under the protection of
SELinux security policy which is file and directory based and as a
consequence much easier to author when packages install into canonical
locations (e.g. FHS).

Previously we had installed all of mailman under /var/mailman
(prefix=var_prefix=/var/mailman) and I had proposed a much simpler
change of just setting prefix=/usr/lib/mailman. This took care of the
majority of SELinux issues and limited the scope of changes. There was
a concern that sites and administrators who were familiar either with
our RPM, the upstream package, or were working with an existing
installation would run afoul of the location changes and keeping them
to absolute minimum was advantageous. However a few folks in private
email pointed out that if changes were going to occur its best to do
it all at once and not piecemeal, in other words endure the pain once.

Thus I embarked on an exercise to make everything FHS compliant. There
are two reasons I'm addressing the developer community here:

1) I want to apprise you of the exact changes, their rational, provide
   a patch against 2.1.5 and solicit review.

2) Test the results.

Description:
------------

Currently the configuration allows for partitioning the mailman
installation between two installation roots, prefix for non-modifiable
files and var_prefix for variable data. This is a great start and
covers 90% of the installation, but there remains a small set of items
which even in this scheme are not FHS compliant, in summary:

1) config files located under /etc

2) pid file located under /var/run

3) queue files located under /var/spool

4) lock files located /var/lock

5) log files located under /var/log

I think one could characterize the competing installation philosophies
as follows:

Mailman not knowing what type of system its going to be installed on
elects to group all of its files together (makes perfect sense). FHS
on the other hand says most packages share common traits and we group
by functional component thus spreading out package installations
across a diverse set of directories.

Implementation:
---------------

I discovered I had to add some new directories to configure and alter
some of the *_DIR variables in Defaults.py.in so they pick up their
values from configure. My strategy was to allow configure when run
without providing any other parameters to produce the exact same set
of installation defaults as previously existed so unless you specify a
different installation mapping a user won't see any change.

Configure added:

--with_lock_dir
--with_log_dir
--with_config_dir
--with_data_dir
--with_pid_dir
--with_queue_dir

I also modified bin/check_perms so it was aware of the new directory
specifications. The patch also made a few non FHS fixes to the install
target of the Makefiles, some generic issues were discovered when
testing check_perms. Those changes included: setting SETGID on the root
prefix and var_prefix directories, check_perms demands all
directories, including the roots are SETGID. The messages Makefile was
creating a two level directory hierarchy but only setting SETGID on
the child. Some of the "make install" logic seemed to depend on the
property that new child directories created under a parent that was
SETGID inherits the SETGID property. To the best of my understanding
this is true only on Linux and Solaris and not generally portable. I
replaced the use of the local mkinstalldirs (and subsequent chmod g+s)
with what I believe is much more standard "install -d" and with the
SETGID as part of the mode. All directories are created this way,
nothing depends on inheritance. I also removed some ancient Makefile
cruft that is no longer in use, variables no longer initialized by
configure, etc. (just confusing, accidents waiting to happen if
someone thought it was valid).

Issues:
-------

Most of the changes were isolated to whole directories and were well
defined. Only the contents of DATA_DIR required splitting its contents
across more than one directory. DATA_DIR contained both pickle files
created during processing and what would be characterized as
configuration files (e.g. password files, MTA alias
files. sitelist.cfg). A new directory CONFIG_DIR was created (in FHS
its /etc/mailman) to hold what has traditionally been in /etc
(e.g. configuration, passwords, aliases, etc). The other things that
were in DATA_DIR was left there.

The mailman configuration file presented the biggest challenge and the
one exception to FHS. The culprit is mm_cfg.py. This is really
mailman's configuration file and it should be located in CONFIG_DIR
(/etc/mailman). But there were several major problems with moving that
file there.

1) It's executable python code, not a text file containing
   configuration parameters. Executable code should be in a "lib" or
   "bin" location. Why is this an issue? Because SELinux pays very
   close attention to who can execute and with precise control over a
   host of run time operations, its often based on directory
   location. But most importantly config files have to be editable,
   security properties transit when modified and new files pick up
   security properties of the directory that contains the file. We do
   not want any file created (or modified) in a configuration
   directory to pick up security permissions granting execution
   rights or for that matter any other run time security permissions.

2) The import of mm_cfg and its directory (Mailman) is all through the
   code, it would be very invasive to change. If mm_cfg continues to be
   executable python code as opposed to a text file then paths.py
   would have to be altered to prepend /etc/mailman to the import
   path, another significant security violation.

3) Any experienced mailman admin will know that mm_cfg.py is located
   with the rest of the mailman executable code under $prefix/Mailman
   and will expect to find this critical file there.

I concluded for the above reasons that mm_cfg.py in the 2.1.x
time frame was best handled as an FHS exception. Our rpm does however
create a symbolic link from /etc/mailman/mm_cfg.py to
$prefix/Mailman/mm_cfg.py so that it "appears" in configuration
directory. This will prepare admins to start looking for mm_cfg along
with the other configuration files. Note that security policies do not
transit across links therefore there are no security policy issues
with the sym link in /etc/mailman. Hopefully in MM 3.0 the
configuration file will be textural which will eliminate the security
policy issue. Also note that sitelist.cfg was completely moved to
/etc/mailman as that is not executed, but rather "evaluated" (I think
evaluation in /etc is fine, but I'm not 100% positive :-).

Request for testing:
--------------------

I have created RPM's with the changes outlined above and documented
below, you may obtain them here:

ftp://people.redhat.com/jdennis/mailman-2.1.5-26.i386.rpm
ftp://people.redhat.com/jdennis/mailman-2.1.5-26.src.rpm

I have tested the new rpm and have not found any problems. The
modified check_perms does not report any problems. But I'm well aware
my testing is limited and my comprehension of mailman is limited, it
is inevitable something has been missed that only wider testing will
reveal and I would appreciate that testing by experts. These changes
are slated to appear in our Fedora Core 3 release which is closing in
a couple of days in preparation for release. Testing prior to that
close would be appreciated. Note that with Fedora Core 3 SELinux will
be enabled by default in "targeted mode". This means that SELinux
policy will be applied to key system services only, mail and hence
mailman is one of those key system services. Ideally any testing
should be done from "rawhide" with the 2.1.5-26 version of mailman and
the new matching SELinux security policy, but I would be perfectly
happy for any testing of the basic rpm even if its not running under
targeted security policy.

Patch File:
-----------

Attached is the patch made against a virgin 2.1.5 tarball with the
changes outlined above.


User / Admin Documentation:
---------------------------

The following is what I prepared for our installation documentation
which can be found in /usr/share/doc/mailman-*



IMPORTANT NOTE FOR USERS UPGRADING FROM A PREVIOUS RED HAT MAILMAN
INSTALLATION OR THOSE FAMILIAR WITH "STANDARD MAILMAN INSTALLATIONS"

    Earlier Red Hat mailman rpms installed all of the mailman files under
    /var/mailman. This did not conform to the Filesystem Hierarchy
    Standard (FHS) and created security violations when SELinux is
    enabled. As of mailman-2.1.5-21 the following directory and file
    changes occurred:

    variable data (e.g. lists) is in /var/lib/mailman, library code,
    executables, and scripts are located in /usr/lib/mailman, lock files are in
    /var/lock/mailman, the pid file is in /var/run/mailman, qfiles are in /var/spool/mailman,
    and configuration files have been moved to the new /etc/mailman

    If you previously had mailman installed and have edited files in
    /var/mailman (e.g. configuration) you will need to move those changes
    to their new locations.

    The mapping of old locations to new locations is as follows:

    Directory Mapping:
    /var/mailman				--> /var/lib/mailman
    /var/mailman/Mailman			--> /usr/lib/mailman/Mailman
    /var/mailman/archives			--> /var/lib/mailman/archives
    /var/mailman/bin				--> /usr/lib/mailman/bin
    /var/mailman/cgi-bin			--> /usr/lib/mailman/cgi-bin
    /var/mailman/cron				--> /usr/lib/mailman/cron
    /var/mailman/data				--> /var/lib/mailman/data
    /var/mailman/lists				--> /var/lib/mailman/lists
    /var/mailman/locks				--> /var/lock/mailman
    /var/mailman/logs				--> /var/log/mailman
    /var/mailman/mail				--> /usr/lib/mailman/mail
    /var/mailman/messages			--> /usr/lib/mailman/messages
    /var/mailman/pythonlib			--> /usr/lib/mailman/pythonlib
    /var/mailman/qfiles				--> /var/spool/mailman
    /var/spool/mailman/qfiles			--> /var/spool/mailman
    /var/mailman/scripts			--> /usr/lib/mailman/scripts
    /var/mailman/spam				--> /var/lib/mailman/spam
    /var/mailman/templates			--> /usr/lib/mailman/templates
    /var/mailman/tests				--> /usr/lib/mailman/tests

    File Mapping:
    /var/mailman/data/adm.pw			--> /etc/mailman/adm.pw
    /var/mailman/data/creator.pw		--> /etc/mailman/creator.pw
    /var/mailman/data/aliases			--> /etc/mailman/aliases
    /var/mailman/data/virtual-mailman		--> /etc/mailman/virtual-mailman
    /var/mailman/data/sitelist.cfg		--> /etc/mailman/sitelist.cfg
    /var/mailman/data/master-qrunner.pid	--> /var/run/mailman/master-qrunner.pid

    Discussion of directory and file relocation:

    Two new directories were created and three existing directories which
    were hardcoded are now configurable.

    PID_DIR is used to hold the process id and is new because FHS wants
    pid files to be located in /var/run. The FHS says when there is only a
    single pid file it should be located in /var/run/<name>.pid, and when
    there are multiple pid's files they should be located together in a
    subdirectory, /var/run/<name>/. Currently mailman only has a single
    pid file, but it does have multiple processes (qrunners). Also SELinux
    security policy is easier to write if processes are segregated into
    individual subdirectories. Therefore we elected to place the mailman
    pid file in its own subdirectory, there is some debate if this is 100%
    FHS compliant because there is only currently a single pid file, but
    this gives us greater future flexibility and is in the spirit of FHS.

    CONFIG_DIR is used to hold the site configuration files. FHS wants
    configuration files stored in /etc/mailman. Previously configuration
    files were mixed in with data files in DATA_DIR and with the run-time
    code (e.g. Mailman/mm_cfg.py). CONFIG_DIR continues to exist but is
    now restricted to data files (e.g. python pickle files). The password
    files, alias files, and .cfg (e.g. sitelist.cfg) files have been moved
    to CONFIG_DIR. mm_cfg.py which is the primary mailman configuration
    file was presented a bit of a dilemma. In theory it should be located
    in /etc/mailman, however it is executable code which argues it should
    be located with the other executable files, it has traditionally lived
    in $PREFIX/Mailman and experienced mailman admins will expect to find
    it there. Modifying all the mm_cfg import statements and paths.py was
    believed to be too invasive a change, and technically its part of the
    "Mailman" package and moving it would take it out of the package
    (although currently I don't think that presents any known
    issues). Instead a compromise approach was adopted, mm_cfg.py is
    symbolically linked into the /etc/mailman directory pointing to
    $PREFIX/Mailman/mm_cfg.py. Thus mm_cfg.py "appears" in the
    configuration directory but retains its traditional location, this was
    deemed a reasonable compromise for the mailman 2.1.x timeframe.

    sitelist.cfg has a symbolic link in its old location in the DATA_DIR
    pointing to its new location in the CONFIG_DIR.

    New Directories (can be specified as parameter to configure):

    CONFIG_DIR:	default=$VAR_PREFIX/data		FHS=/etc/mailman
    PID_DIR	default=$VAR_PREFIX/data		FHS=/var/run/mailman

    Existing directories that can now be specified as parameter to configure:

    LOCK_DIR:	default=$VAR_PREFIX/locks	FHS=/var/lock/mailman
    LOG_DIR:	default=$VAR_PREFIX/logs	FHS=/var/log/mailman
    QUEUE_DIR	default=$VAR_PREFIX/qfiles	FHS=/var/spool/mailman


-- 
John Dennis <jdennis at redhat.com>
