diff options
Diffstat (limited to 'debian/configure-instance.sh')
-rw-r--r-- | debian/configure-instance.sh | 234 |
1 files changed, 114 insertions, 120 deletions
diff --git a/debian/configure-instance.sh b/debian/configure-instance.sh index 6a297d1..ccbe1fb 100644 --- a/debian/configure-instance.sh +++ b/debian/configure-instance.sh @@ -1,24 +1,70 @@ #! /bin/sh -e -# This helper script is used by the postfix init scripts, -# upstart jobs, systemd services, openrc scripts, etc. in -# prepping the instance of postfix to be started. +# This helper script is run by postfix-script with all +# postfix instance specific environment variables set. +# It is used mostly to update chroot setup for a given +# instance. Run every time any instance starts from +# /usr/lib/postfix/sbin/postfix-script # It was originally part of the postfix init script, which # was written by LaMont Jones <lamont@debian.org>, and based # off of the sendmail init script. +# safety +[ -f "$MAIL_CONFIG/main.cf" ] && [ -d "$queue_directory/pid" ] && +[ -x "$command_directory/postconf" ] && [ $# = 0 ] || +{ echo "E: This is internal script used by postfix" >&2 + [ $# != 1 ] || + echo "E: old postfix initscript will not work with this postfix package version" >&2 + exit 1 +} + chroot_extra_files= chroot_extra_CAdir= - -INSTANCE="$1" - SYNC_CHROOT="y" if test -r /etc/default/postfix; then . /etc/default/postfix fi +POSTCONF="$command_directory/postconf" + +# if you set myorigin to 'ubuntu.com' or 'debian.org', it is wrong +# and annoys the admins of those domains. See also sender_canonical_maps. +myorigin=$($POSTCONF -hx myorigin) +[ "X${myorigin#/}" = "X${myorigin}" ] || + myorigin=$(head -n1 -- "$myorigin") +case "$(echo "$myorigin" | tr A-Z a-z)" in + (ubuntu.com | debian.org) + echo "Invalid \$myorigin ($myorigin), refusing to start" + exit 1 + ;; +esac + +[ -n "$SYNC_CHROOT" ] || exit 0 + +compat=$($POSTCONF -xh compatibility_level) +[ ${compat%%.*} -ge 1 ] && chroot_test="[y]" || chroot_test="[-y]" + +# parse master.cf and find out which amount of chroot setup do we need +need_chroot=$($POSTCONF -M | awk '# $5=chroot $8=cmd + BEGIN { need="" } + $5 !~ /'$chroot_test'/ { next } # skip non-chrooted services + $8 ~ /^(anvil|bounce|discard|error|flush|pickup|[no]?qmgr|scache|showq|tlsmgr|trivial-rewrite|verify)/ { + next } # internal simple safe services which need no extra chroot setup + $8 ~ /^(dnsblog|postscreen)/ { need="dns"; next } + $8 ~ /^(qmqpd)/ { need="dns"; next } # does it need dns? + $8 ~ /^(cleanup)/ { print "y"; exit } # #948321 - to move to safe list + $8 ~ /^(local|pipe|postlogd|proxymap|virtual)/ { print "y"; exit } # non-chrootable? + $8 ~ /^(smtp|smtpd|lmtp)/ { print "y"; exit } # the interesting ones + { print "y"; exit } # by default assume chroot is needed + END { print need } + ') + +# might remove/cleanup chroot here + +[ -n "$need_chroot" ] || exit 0 + # Sigh. Because reasons, files is relative, CAdir not [ "$chroot_extra_CAdir" != '' ] && [ ! "${chroot_extra_CAdir%${chroot_extra_CAdir#?}}"x = '/x' ] && chroot_extra_CAdir=/$chroot_extra_CAdir if [ "$chroot_extra_files" != '' ]; then @@ -31,118 +77,66 @@ if [ "$chroot_extra_files" != '' ]; then chroot_extra_files=$files fi -if [ "X$INSTANCE" = X ] || [ "X$INSTANCE" = "X-" ]; then - POSTCONF="postconf -o inet_interfaces=" -else - POSTCONF="postmulti -i $INSTANCE -x postconf -o inet_interfaces=" -fi - -# if you set myorigin to 'ubuntu.com' or 'debian.org', it's wrong, and annoys the admins of -# those domains. See also sender_canonical_maps. - -MYORIGIN=$($POSTCONF -hx myorigin | tr 'A-Z' 'a-z') -if [ "X${MYORIGIN#/}" != "X${MYORIGIN}" ]; then - MYORIGIN=$(tr 'A-Z' 'a-z' < $MYORIGIN) -fi -if [ "X$MYORIGIN" = Xubuntu.com ] || [ "X$MYORIGIN" = Xdebian.org ]; then - echo "Invalid \$myorigin ($MYORIGIN), refusing to start" - exit 1 -fi - -config_dir=$($POSTCONF -hx config_directory) -MAJOR_VER=$($POSTCONF -hx mail_version|cut -d. -f1) -COMPAT=$($POSTCONF -xh compatibility_level|cut -d. -f1) -[ $MAJOR_VER -ge 3 ] && [ $COMPAT -ge 1 ] && CHROOT_TEST="[yY]" || CHROOT_TEST="[-yY]" -# see if anything is running chrooted. -NEED_CHROOT=$(awk '/^[0-9a-z]/ && ($5 ~ "'"$CHROOT_TEST"'") { print "y"; exit}' ${config_dir}/master.cf) - -# Functions for chroot setup - -copyCAdir() { - # Copy/update CA directory in chroot - ca_path=$1 - case "$ca_path" in - '') :;; # no ca_path - $queue_dir/*) :;; # skip stuff already in chroot - *) - if test -d "$ca_path"; then - dest_dir="$queue_dir/${ca_path#/}" - # strip any/all trailing / - while [ "${dest_dir%/}" != "${dest_dir}" ]; do - dest_dir="${dest_dir%/}" - done - new=0 - if test -d "$dest_dir"; then - # write to a new directory ... - dest_dir="${dest_dir}.NEW" - new=1 - fi - mkdir --parent ${dest_dir} - # handle files in subdirectories - (cd "$ca_path" && find . -name '*.pem' -not -xtype l -print0 | cpio -0pdL --quiet "$dest_dir") 2>/dev/null || - (echo failure copying certificates; exit 1) - openssl rehash "$dest_dir" >/dev/null 2>&1 - if [ "$new" = 1 ]; then - # and replace the old directory - rm -rf "${dest_dir%.NEW}" - mv "$dest_dir" "${dest_dir%.NEW}" - fi - fi - ;; - esac -} - -if [ -n "$NEED_CHROOT" ] && [ -n "$SYNC_CHROOT" ]; then - # Make sure that the chroot environment is set up correctly. - umask 022 - queue_dir=$($POSTCONF -hx queue_directory) - cd "$queue_dir" - - # Set the smtp CA path to be copied, if specified - sca_path=$($POSTCONF -hx smtp_tls_CApath) - - # Set the smtpd CA path to be copied, if specified - dca_path=$($POSTCONF -hx smtpd_tls_CApath) - - # Copy or update each defined CA directory - for CA in $sca_path $dca_path $chroot_extra_CAdir - do - copyCAdir $CA - done - - # if we're using unix:passwd.byname, then we need to add etc/passwd. - local_maps=$($POSTCONF -hx 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/host.conf etc/nsswitch.conf etc/nss_mdns.config \ - $chroot_extra_files" - 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 - # ldaps needs this. debian bug 572841 - (echo /dev/random; echo /dev/urandom) | cpio -pdL --quiet . 2>/dev/null || true - rm -f usr/lib/zoneinfo/localtime - mkdir -p usr/lib/zoneinfo - ln -sf /etc/localtime usr/lib/zoneinfo/localtime - - LIBLIST=$(for name in gcc_s nss resolv; do - for f in /lib/*/lib${name}*.so* /lib/lib${name}*.so*; do - if [ -f "$f" ]; then echo ${f#/}; fi; - done; - done) - - if [ -n "$LIBLIST" ]; then - for f in $LIBLIST; do - rm -f "$f" - done - tar cf - -C / $LIBLIST 2>/dev/null |tar xf - - fi +# Make sure that the chroot environment is set up correctly. +umask 022 +cd "$queue_directory" + +#XXX lib=>usr/lib? +mkdir -p dev etc lib usr +mkdir -p usr/lib/sasl2 # https://bugs.debian.org/426338 + +# Copy certificate dirs +cadirs_copied= +for cadir in \ + $($POSTCONF -hx smtp_tls_CApath smtpd_tls_CApath) \ + $chroot_extra_CAdir +do + + # strip trailing / + while [ "x${cadir%/}" != "x${cadir}" ]; do cadir=${cadir%/}; done + case "$cadir" in + ($queue_directory/*) continue;; # skip stuff already in chroot + (/*) [ -d $cadir ] || continue;; + (*) continue;; + esac + case "$cadis_copied " in + (*" $cadir "*) continue ;; + esac + cadirs_copied="$cadirs_copied $cadir" + + dest=$queue_directory$cadir + rm -rf $dest.NEW; mkdir -p $dest.NEW + ( cd $cadir + # *.pem are mostly symlinks to /usr/share/ca-certificates/ + #XXX we can copy just [0-9a-f]{8}\.r?[0-9] files and omit rehash - + # do we really want pem and nothing else? + find -L . -maxdepth 1 -name '*.pem' -type f -print0 | + cpio -p -L0 $dest.NEW ) + openssl rehash $dest.NEW + rm -rf $dest + mv $dest.NEW $dest +done + +FILES="etc/localtime etc/services etc/resolv.conf etc/hosts \ + etc/host.conf etc/nsswitch.conf etc/nss_mdns.config \ + $chroot_extra_files" +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 +# ldaps needs this. debian bug 572841 +(echo /dev/random; echo /dev/urandom) | cpio -pdL --quiet . 2>/dev/null || true + +LIBLIST=$(for name in gcc_s nss resolv; do + for f in /lib/*/lib${name}*.so* /lib/lib${name}*.so*; do + if [ -f "$f" ]; then echo ${f#/}; fi; + done; +done) + +if [ -n "$LIBLIST" ]; then + for f in $LIBLIST; do + rm -f "$f" + done + tar cf - -C / $LIBLIST 2>/dev/null |tar xf - fi |