1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
#! /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
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 }
')
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*
rmdir lib/* 2>/dev/null || :
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
[ -n "$need_chroot" ] || exit 0
# put just the right nsswitch libraries ($multiarch/libnss_*.so.2)
# directly to lib/ (no subdirs)
# nss stuff is needed for "native" smtp host lookups (smtp_host_lookup)
cp -pLuv -t lib /usr/lib/$multiarch/libnss_*.so.2 || :
case "$chroot_extra_CAdir" in # ensure CAdir is absolute
( /* ) ;;
( ?* ) chroot_extra_CAdir=/$chroot_extra_CAdir ;;
esac
# 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"
# 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 cert (to process later), delete everything else..
find . -mindepth 1 -maxdepth 1 \( \
\( -name '[0-9a-f]*[0-9a-f].[0-9]' -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 || :
|