Package: postfix
Version: 2.5.5-1.1
Severity: normal
Tags: patch

I found some issues in the postfix init.d script regarding the chroot
setup.

1. There are more options in Postfix besides smtp_use_tls and
   smtpd_use_tls to enable TLS. In the other cases
   /etc/ssl/certs/ca-certificates.crt should be copied as well.

   In my patch I added checks for:
   * smtp_tls_security_level
   * smtpd_tls_security_level

   This is probably still not perfect, because there is also
   smtp_tls_per_site and smtp_tls_policy_maps. But these seem much more
   difficult to check (and are probably much less used).

2. The FILES variable can't be overridden by /etc/default/postfix.

   This could be a very neat way to expand the files that need to be
   copied to the chroot.

   In my patch I renamed the FILES variable to CHROOT_FILES and moved
   it before sourcing of /etc/default/postfix.

3. There is no way to update the chroot without restarting the postfix
   daemon.

   I can imagine people want to avoid restarting postfix in production
   environments and prefer reloading it in stead after configuration
   changes. However, if a configuration change needs an extra file in
   the chroot, reloading is not enough. Now, people have the choice
   between manually copying the file the chroot (before reloading) or
   restarting postfix (after modifying the FILES variable).

   In my patch I added a third option, a new argument (update-chroot)
   can be called to update the chroot. To realise this I've put all
   chroot logic in a function (update_chroot()).

4. Another issue seems that files that don't have to be put in the
   chroot anymore, due to configuration changes, will never get removed
   from the chroot. People have to remove them manually.

   This might be intentionally and I didn't try to fix it in the patch,
   'cause it seems a bit complicated as not all the files in the chroot
   were created by the init.d script. So you can't simply remove all
   files before copying the files again.

Please review the attached patch (init.d-chroot.patch) and consider
applying it.

I saw that a patch to the init.d script in bug #433660 is still waiting
to be included. Obviously, my patch won't work if it the other one get
applied.

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
--- postfix-2.5.5-orig/debian/init.d    2008-10-30 15:51:43.000000000 +0100
+++ postfix-2.5.5/debian/init.d 2008-10-30 17:44:39.000000000 +0100
@@ -25,6 +25,8 @@
 
 # Defaults - don't touch, edit /etc/default/postfix
 SYNC_CHROOT="y"
+CHROOT_FILES="etc/localtime etc/services etc/resolv.conf etc/hosts \
+   etc/nsswitch.conf etc/nss_mdns.config"
 
 test -f /etc/default/postfix && . /etc/default/postfix
 
@@ -45,6 +47,54 @@
     fi
 }
 
+update_chroot() {
+    # see if anything is running chrooted.
+    NEED_CHROOT=$(awk '/^[0-9a-z]/ && ($5 ~ "[-yY]") { print "y"; exit}' 
/etc/postfix/master.cf)
+
+    if [ -n "$NEED_CHROOT" ] && [ -n "$SYNC_CHROOT" ]; then
+       # Make sure that the chroot environment is set up correctly.
+       oldumask=$(umask)
+       umask 022
+       cd $(postconf -h queue_directory)
+
+       # if we're using tls, then we need to add 
etc/ssl/certs/ca-certificates.crt.
+       smtp_tls_security_level=$(postconf -h smtp_tls_security_level)
+       smtp_use_tls=$(postconf -h smtp_use_tls)
+       smtpd_tls_security_level=$(postconf -h smtpd_tls_security_level)
+       smtpd_use_tls=$(postconf -h smtpd_use_tls)
+       if [ "X$smtp_use_tls" = "Xyes" -o "X$smtpd_use_tls" = "Xyes" \
+               -o "X$smtp_tls_security_level" != "X" -a 
"X$smtp_tls_security_level" != "Xnone" \
+               -o "X$smtpd_tls_security_level" != "X" -a 
"X$smtpd_tls_security_level" != "Xnone" ]; then
+           if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then 
+               mkdir -p etc/ssl/certs
+               cp /etc/ssl/certs/ca-certificates.crt etc/ssl/certs/
+           fi
+       fi
+
+       # if we're using unix:passwd.byname, then we need to add etc/passwd.
+       local_maps=$(postconf -h local_recipient_maps)
+       if [ "X$local_maps" != "X${local_maps#*unix:passwd.byname}" ]; then
+           if [ "X$local_maps" = "X${local_maps#*proxy:unix:passwd.byname}" ]; 
then
+               sed 's/^\([^:]*\):[^:]*/\1:x/' /etc/passwd > etc/passwd
+               chmod a+r etc/passwd
+           fi
+       fi
+
+       for file in $CHROOT_FILES; do 
+           [ -d ${file%/*} ] || mkdir -p ${file%/*}
+           if [ -f /${file} ]; then rm -f ${file} && cp /${file} ${file}; fi
+           if [ -f  ${file} ]; then chmod a+rX ${file}; fi
+       done
+       rm -f usr/lib/zoneinfo/localtime
+       mkdir -p usr/lib/zoneinfo
+       ln -sf /etc/localtime usr/lib/zoneinfo/localtime
+       rm -f lib/libnss_*so*
+       tar cf - /lib/libnss_*so* 2>/dev/null |tar xf -
+       umask $oldumask
+    fi
+}
+
+
 case "$1" in
     start)
        log_daemon_msg "Starting Postfix Mail Transport Agent" postfix
@@ -65,48 +115,7 @@
                exit 1
            fi
 
-           # see if anything is running chrooted.
-           NEED_CHROOT=$(awk '/^[0-9a-z]/ && ($5 ~ "[-yY]") { print "y"; 
exit}' /etc/postfix/master.cf)
-
-           if [ -n "$NEED_CHROOT" ] && [ -n "$SYNC_CHROOT" ]; then
-               # Make sure that the chroot environment is set up correctly.
-               oldumask=$(umask)
-               umask 022
-               cd $(postconf -h queue_directory)
-
-               # if we're using tls, then we need to add 
etc/ssl/certs/ca-certificates.crt.
-               smtp_use_tls=$(postconf -h smtp_use_tls)
-               smtpd_use_tls=$(postconf -h smtpd_use_tls)
-               if [ "X$smtp_use_tls" = "Xyes" -o "X$smtpd_use_tls" = "Xyes" ]; 
then
-                   if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then 
-                       mkdir -p etc/ssl/certs
-                       cp /etc/ssl/certs/ca-certificates.crt etc/ssl/certs/
-                   fi
-               fi
-
-               # if we're using unix:passwd.byname, then we need to add 
etc/passwd.
-               local_maps=$(postconf -h local_recipient_maps)
-               if [ "X$local_maps" != "X${local_maps#*unix:passwd.byname}" ]; 
then
-                   if [ "X$local_maps" = 
"X${local_maps#*proxy:unix:passwd.byname}" ]; then
-                       sed 's/^\([^:]*\):[^:]*/\1:x/' /etc/passwd > etc/passwd
-                       chmod a+r etc/passwd
-                   fi
-               fi
-
-               FILES="etc/localtime etc/services etc/resolv.conf etc/hosts \
-                   etc/nsswitch.conf etc/nss_mdns.config"
-               for file in $FILES; do 
-                   [ -d ${file%/*} ] || mkdir -p ${file%/*}
-                   if [ -f /${file} ]; then rm -f ${file} && cp /${file} 
${file}; fi
-                   if [ -f  ${file} ]; then chmod a+rX ${file}; fi
-               done
-               rm -f usr/lib/zoneinfo/localtime
-               mkdir -p usr/lib/zoneinfo
-               ln -sf /etc/localtime usr/lib/zoneinfo/localtime
-               rm -f lib/libnss_*so*
-               tar cf - /lib/libnss_*so* 2>/dev/null |tar xf -
-               umask $oldumask
-           fi
+           update_chroot
 
            if start-stop-daemon --start --exec ${DAEMON} -- quiet-quick-start; 
then
                log_end_msg 0
@@ -159,8 +168,14 @@
        ${DAEMON} $1
     ;;
 
+    update-chroot)
+       log_action_begin_msg "Updating the Postfix chroot"
+       update_chroot
+       log_action_end_msg 0
+    ;;
+
     *)
-       log_action_msg "Usage: /etc/init.d/postfix 
{start|stop|restart|reload|flush|check|abort|force-reload}"
+       log_action_msg "Usage: /etc/init.d/postfix 
{start|stop|restart|reload|flush|check|abort|force-reload|update-chroot}"
        exit 1
     ;;
 esac

Reply via email to