The following is the contents of the post at . 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/.pid, and when there are multiple pid's files they should be located together in a subdirectory, /var/run//. 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