176 lines
5.8 KiB
Bash
176 lines
5.8 KiB
Bash
#! /bin/sh -e
|
|
|
|
# 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
|
|
|
|
# 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=
|
|
SYNC_CHROOT="y"
|
|
|
|
if test -r /etc/default/postfix; then
|
|
. /etc/default/postfix
|
|
fi
|
|
|
|
# multiarch triplet for the host this package is built for
|
|
# (substituted at package build time)
|
|
multiarch=@MULTIARCH@
|
|
|
|
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
|
|
|
|
# Get a command to set chroot off (ignoring simple ones but
|
|
# include custom if any).
|
|
# If it is empty, no interesting services are chrooted
|
|
need_chroot=$($daemon_directory/postfix-script chroot -n -Sc off)
|
|
|
|
cd "$queue_directory"
|
|
# Make sure that the chroot environment is set up correctly.
|
|
umask 022
|
|
|
|
# some users keep actual files in /var/spool/postfix/{etc,lib,usr}
|
|
# (as primary place) because the chroot setup doesn't work right
|
|
|
|
if [ -d usr/lib/zoneinfo ] # unused, <<3.9.1-4
|
|
then
|
|
rm -f usr/lib/zoneinfo/*
|
|
rmdir usr/lib/zoneinfo 2>/dev/null || :
|
|
fi
|
|
if [ -f lib/$multiarch/libgcc_s.so.1 ] # <<3.9.1-5
|
|
then
|
|
# we now place libnss_*.so.2 directly to lib/ (below), but this rm is a one-time op
|
|
rm -fv lib/libgcc_s*.so* lib/libnss*.so* lib/libresolv*.so* # very old cruft
|
|
rm -f lib/*/libgcc_s*.so* lib/*/libnss*.so* lib/*/libresolv*.so* dev/random dev/urandom
|
|
rmdir lib/* dev 2>/dev/null || :
|
|
fi
|
|
if [ -f lib/libnss_files.so.2 ] # <<3.9.1-7. Modules from glibc aren't needed in chroot
|
|
then
|
|
rm -f lib/libnss_*.so.2
|
|
fi
|
|
if [ -f etc/ssl/cert/GlobalSign_Root_CA.pem ] # arbitrary, <<3.9.1-5
|
|
then # we re-created everything each run before 3.9.1-5
|
|
# remove just the most common dir
|
|
rm -rf etc/ssl/cert
|
|
fi
|
|
|
|
# always copy/update small stuff so simple services works too
|
|
mkdir -p etc
|
|
cp= rm=
|
|
for file in \
|
|
etc/localtime etc/services etc/resolv.conf etc/hosts \
|
|
etc/host.conf etc/nsswitch.conf etc/nss_mdns.config \
|
|
$chroot_extra_files
|
|
do
|
|
[ -f /$file ] && cp="$cp /$file" || rm="$rm ./$file"
|
|
done
|
|
[ -n "$rm" ] && rm -f $rm
|
|
[ -n "$cp" ] && cp -pLuf --parents -t . -- $cp
|
|
|
|
if [ -z "$need_chroot" ]; then
|
|
[ ! -d etc/ssl/certs ] || rm -rf etc/ssl/certs
|
|
rm -f lib/libnss_*.so.2
|
|
exit 0
|
|
fi
|
|
|
|
# put just the right nsswitch libraries ($multiarch/libnss_*.so.2)
|
|
# directly to lib/ (no subdirs). Modules from glibc aren't needed (built-in).
|
|
# nss stuff is needed for "native" smtp host lookups (smtp_host_lookup)
|
|
# and might be used by other pieces (SASL et al)
|
|
nss=$(find -L /usr/lib/$multiarch/ -mindepth 1 -maxdepth 1 \
|
|
-name 'libnss_*.so.2' \
|
|
! -regex '.*/libnss_\(compat\|dns\|files\|hesiod\)\.so\..' \
|
|
-type f)
|
|
if [ -n "$nss" ]; then
|
|
mkdir -p lib
|
|
cp -pLuv -t lib -- $nss || :
|
|
#XXX ldd? We should have a way to load whole nss stuff before chroot(),
|
|
# and avoid all of this entirely
|
|
fi
|
|
|
|
case "$chroot_extra_CAdir" in # ensure CAdir is absolute
|
|
( /* ) ;;
|
|
( ?* ) chroot_extra_CAdir=/$chroot_extra_CAdir ;;
|
|
esac
|
|
|
|
# Copy certificate dirs
|
|
# There are 2 types of certs storage: ca-certificates.crt file (smtp_tls_CAfile)
|
|
# and a directory with xxxxxxxx.N files (smtp_tls_CAdir)
|
|
# It is best to use just CAfile (/etc/ssl/certs/ca-certificates.crt) which is read
|
|
# before chrooting, - usually it isn't large, and requires no processing.
|
|
# Can show a warning here suggesting to switch to smtp_tls_CAfile.
|
|
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"
|
|
|
|
# only copy already hashed names. This means we only trust
|
|
# what's trusted on the system, not everything present
|
|
# Before 3.9.1-5 we truested everything
|
|
dest=$queue_directory$cadir
|
|
if [ -d $dest ]; then (
|
|
cd $dest
|
|
# cp does not write over dangling symlinks (#1089836).
|
|
# walk through the dest dir, print names of regular files looking
|
|
# like a hashed cert or ca-certificates.crt (#1003982) (to process later),
|
|
# delete everything else..
|
|
find . -mindepth 1 -maxdepth 1 \( \
|
|
\( \( -name '[0-9a-f]*[0-9a-f].[0-9]' -o -name ca-certificates.crt \) -type f -print \) \
|
|
-o -delete \
|
|
\) | while read file; do
|
|
# ..and remove files which don't exist in source anymore
|
|
[ -f "$caddr/$file" ] || rm -f "$file"
|
|
done
|
|
) fi
|
|
mkdir -p $dest
|
|
( cd $cadir
|
|
find -L . -name '[0-9a-f]*.[0-9]' -type f \
|
|
-exec cp -pLuf -t $dest '{}' +
|
|
)
|
|
done
|
|
|
|
mkdir -p usr/lib/sasl2 # https://bugs.debian.org/426338
|
|
|
|
## ldaps needs this. debian bug 572841 (Mar-2010)
|
|
# let's omit this for now (in Dec-2024) for new installs and see what happens
|
|
# Having device nodes in /var causes numerous issues
|
|
# If anything, it can be bind-mounted from actual /dev,
|
|
# or better yet, just use proxy: map types.
|
|
# Might as well remove existing dev/*random from old chroot
|
|
#cp -a -n --parents /dev/random /dev/urandom . 2>/dev/null || :
|