1 |
#!/bin/sh |
2 |
# |
3 |
# postfix-chroot.sh - enable or disable Postfix chroot |
4 |
# |
5 |
# (C) 2003 Luca Berra <bluca@vodka.it> |
6 |
# |
7 |
# originally based on postfix-chroot.sh |
8 |
# (C) 2003 Simon J Mudd <sjmudd@pobox.com> |
9 |
# |
10 |
# This script is intended to enable you to enable or disable the Postfix |
11 |
# chroot environment. |
12 |
# |
13 |
# License: |
14 |
# This program is free software; you can redistribute it and/or |
15 |
# modify it under the terms of the GNU General Public License |
16 |
# as published by the Free Software Foundation; either version 2 |
17 |
# of the License, or (at your option) any later version. |
18 |
# |
19 |
# This program is distributed in the hope that it will be useful, |
20 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 |
# GNU General Public License for more details. |
23 |
# |
24 |
# You may have received a copy of the GNU General Public License |
25 |
# along with this program; if not, write to the Free Software |
26 |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
27 |
# USA. |
28 |
# |
29 |
# An on-line copy of the GNU General Public License can be found |
30 |
# http://www.fsf.org/copyleft/gpl.html. |
31 |
|
32 |
usage () { |
33 |
myname=${0##*/} |
34 |
cat <<EOF |
35 |
Usage: $myname [-q|-h] {enable|disable|update|check|check_update} |
36 |
|
37 |
Options: |
38 |
-h - this help |
39 |
-q - do not issue action/error messages |
40 |
Commands: |
41 |
enable - setup Postfix chroot (removing the previous setup) |
42 |
disable - remove Postfix chroot |
43 |
update - update files in Postfix chroot |
44 |
check - check differences between files in chroot and system |
45 |
check_update - check differences between files in chroot and system |
46 |
and update if needed |
47 |
EOF |
48 |
} |
49 |
|
50 |
# print an error message and exit |
51 |
error () { |
52 |
echo "Error: $@" >&2 |
53 |
exit 1 |
54 |
} |
55 |
|
56 |
# print a warning message |
57 |
warn () { |
58 |
echo "Warning: $@" >&2 |
59 |
} |
60 |
|
61 |
# if $verbose==1 print message ($2) otherwise do nothing |
62 |
info () { |
63 |
[ "$verbose" = 1 ] && echo "$@" >&2 || : |
64 |
} |
65 |
|
66 |
# Link source file to chroot directory if possible. If the source is a |
67 |
# symbolic link, make a copy of the link in the chroot directory, |
68 |
# otherwise copy the file. |
69 |
copy() { |
70 |
local T L |
71 |
if [ -n "$2" ]; then |
72 |
T=${chroot%/}/${2#/} |
73 |
else |
74 |
T=${chroot%/}/${1#/} |
75 |
fi |
76 |
info " $1 -> $T" |
77 |
mkdir -p ${T%/*} |
78 |
if [ -L $1 ]; then |
79 |
L=`readlink -f $1` |
80 |
ln -sf $L $T |
81 |
copy $L |
82 |
else |
83 |
ln -f $1 $T 2>/dev/null || \ |
84 |
cp -pf $1 $T |
85 |
fi |
86 |
} |
87 |
|
88 |
rmtree() { |
89 |
local d=${1#$chroot}/ |
90 |
while [ -n "${d%/*}" ]; do |
91 |
rmdir ${chroot}${d} 2>/dev/null || return 1 |
92 |
done |
93 |
} |
94 |
|
95 |
remove() { |
96 |
local L |
97 |
local f=${1#$chroot} |
98 |
f=${chroot%/}/${f#/} |
99 |
if [ -L $f ]; then |
100 |
L=`readlink -f $f` |
101 |
[ -f ${chroot}$L ] && rm -f ${chroot}$L |
102 |
rmtree ${chroot}${L%/*} |
103 |
rm -f $f |
104 |
elif [ -f $f ];then |
105 |
rm -f $f |
106 |
fi |
107 |
rmtree ${f%/*} |
108 |
} |
109 |
|
110 |
# update syslog configuration (rsyslog, sysklogd or syslog-ng) |
111 |
update_sysklogd() { |
112 |
local SYSLOGD_OPTIONS="" |
113 |
local NEW_SYSLOGD_OPTIONS="" |
114 |
|
115 |
[ -s /etc/sysconfig/syslog ] && . /etc/sysconfig/syslog |
116 |
|
117 |
case $1 in |
118 |
enable) |
119 |
if ! grep -qs "^[[:space:]]*SYSLOGD_OPTIONS" /etc/sysconfig/syslog ; then |
120 |
info "Adding SYSLOGD_OPTIONS in the /etc/sysconfig/syslog file." |
121 |
echo "SYSLOGD_OPTIONS=\"-a ${chroot}/dev/log\"" >> /etc/sysconfig/syslog |
122 |
service_restart_syslog=1 |
123 |
else |
124 |
if ! grep -q "^[[:space:]]*SYSLOGD_OPTIONS=.*-a ${chroot}/dev/log" /etc/sysconfig/syslog; then |
125 |
NEW_SYSLOGD_OPTIONS="${SYSLOGD_OPTIONS} -a ${chroot}/dev/log" |
126 |
sed -i -e "s!^[[:space:]]*SYSLOGD_OPTIONS=.*\$!SYSLOGD_OPTIONS=\"${NEW_SYSLOGD_OPTIONS}\"!" /etc/sysconfig/syslog |
127 |
service_restart_syslog=1 |
128 |
fi |
129 |
fi |
130 |
;; |
131 |
disable) |
132 |
NEW_SYSLOGD_OPTIONS="`echo ${SYSLOGD_OPTIONS} | sed -e \"s! *-a ${chroot}/dev/log!!\"`" |
133 |
if [ "${NEW_SYSLOGD_OPTIONS}" != "${SYSLOGD_OPTIONS}" ]; then |
134 |
sed -i -e "s!^[[:space:]]*SYSLOGD_OPTIONS=.*\$!SYSLOGD_OPTIONS=\"${NEW_SYSLOGD_OPTIONS}\"!" /etc/sysconfig/syslog |
135 |
service_restart_syslog=1 |
136 |
fi |
137 |
;; |
138 |
esac |
139 |
} |
140 |
|
141 |
update_rsyslog() { |
142 |
# note: we use a single configuration file for all postfix instances, to avoid issue in case an instance is renamed |
143 |
case $1 in |
144 |
enable) |
145 |
if ! grep -qs "\$AddUnixListenSocket ${chroot}/dev/log" /etc/rsyslog.d/postfix.conf; then |
146 |
echo "\$AddUnixListenSocket ${chroot}/dev/log" >> /etc/rsyslog.d/postfix.conf |
147 |
service_restart_rsyslog=1 |
148 |
fi |
149 |
;; |
150 |
disable) |
151 |
if grep -qs "\$AddUnixListenSocket ${chroot}/dev/log" /etc/rsyslog.d/postfix.conf; then |
152 |
sed -i -e "\!\$AddUnixListenSocket ${chroot}/dev/log!d" /etc/rsyslog.d/postfix.conf |
153 |
[ -f /etc/rsyslog.d/postfix.conf -a ! -s /etc/rsyslog.d/postfix.conf ] && rm -f /etc/rsyslog.d/postfix.conf |
154 |
service_restart_rsyslog=1 |
155 |
fi |
156 |
;; |
157 |
esac |
158 |
} |
159 |
update_syslogng_old() { |
160 |
case $1 in |
161 |
enable) |
162 |
if ! grep -q -E "(unix-stream|file)[[:space:]]*\([[:space:]]*([\"'])${chroot}/dev/log\2" /etc/syslog-ng.conf; then |
163 |
if [ ! -e ${confdir}/syslog-ng.conf ]; then |
164 |
warn "cannot find ${confdir}/syslog-ng.conf, instance will not log properly" |
165 |
elif [ -s ${confdir}/syslog-ng.conf ]; then |
166 |
sed -e "s!@CHROOT@!${chroot}!" -e "s!@CONFDIR@!${confdir}!" -e "/^@/d" ${confdir}/syslog-ng.conf >> /etc/syslog-ng.conf |
167 |
service_restart_syslog_ng=1 |
168 |
fi |
169 |
fi |
170 |
;; |
171 |
disable) |
172 |
if grep -q "^# BEGIN: Automatically added by postfix chroot setup script for ${chroot}\$" /etc/syslog-ng.conf; then |
173 |
sed -i -e "\!^# BEGIN: Automatically added by postfix chroot setup script for ${chroot}\$!,\!^# END ${chroot}\$!d" /etc/syslog-ng.conf |
174 |
service_restart_syslog_ng=1 |
175 |
elif grep -q "^# BEGIN: Automatically added by postfix chroot setup script\$" /etc/syslog-ng.conf; then |
176 |
sed -i -e '/^# BEGIN: Automatically added by postfix chroot setup script$/,/^# END$/d' /etc/syslog-ng.conf |
177 |
service_restart_syslog_ng=1 |
178 |
fi |
179 |
;; |
180 |
esac |
181 |
} |
182 |
update_syslogng() { |
183 |
# note: we use a single configuration file for all postfix instances, to avoid issue in case an instance is renamed |
184 |
case $1 in |
185 |
enable) |
186 |
if ! grep -qs -E "(unix-stream|file)[[:space:]]*\([[:space:]]*([\"'])${chroot}/dev/log\2" /etc/syslog-ng.d/postfix_chroot.conf; then |
187 |
# we need to give a different name to each source |
188 |
local instance_name=`postconf -c ${confdir} -h multi_instance_name 2>/dev/null` |
189 |
echo "# BEGIN: Automatically added by postfix chroot setup script for ${chroot}" >> /etc/syslog-ng.d/postfix_chroot.conf |
190 |
echo "source s_postfix_chroot${instance_name:+_$instance_name} { unix-stream(\"${chroot}/dev/log\"); };" >> /etc/syslog-ng.d/postfix_chroot.conf |
191 |
echo "# END ${chroot}" >> /etc/syslog-ng.d/postfix_chroot.conf |
192 |
service_restart_syslog_ng=1 |
193 |
fi |
194 |
;; |
195 |
disable) |
196 |
if grep -qs "^# BEGIN: Automatically added by postfix chroot setup script for ${chroot}\$" /etc/syslog-ng.d/postfix_chroot.conf; then |
197 |
sed -i -e "\!^# BEGIN: Automatically added by postfix chroot setup script for ${chroot}\$!,\!^# END ${chroot}\$!d" /etc/syslog-ng.d/postfix_chroot.conf |
198 |
[ -f /etc/syslog-ng.d/postfix_chroot.conf -a ! -s /etc/syslog-ng.d/postfix_chroot.conf ] && rm -f /etc/syslog-ng.d/postfix_chroot.conf |
199 |
service_restart_syslog_ng=1 |
200 |
fi |
201 |
;; |
202 |
esac |
203 |
} |
204 |
update_syslog() { |
205 |
case $1 in |
206 |
enable) |
207 |
mkdir -p ${chroot}/dev 2>/dev/null |
208 |
;; |
209 |
disable) |
210 |
rm -f ${chroot}/dev/log 2>/dev/null |
211 |
rmdir ${chroot}/dev 2>/dev/null |
212 |
;; |
213 |
esac |
214 |
[ -f '/etc/sysconfig/syslog' ] && update_sysklogd $1 |
215 |
[ -f '/etc/sysconfig/rsyslog' ] && update_rsyslog $1 |
216 |
if [ -f '/etc/syslog-ng.conf' ]; then |
217 |
if [ -d '/etc/syslog-ng.d' ]; then |
218 |
update_syslogng_old disable # clean cruft if upgraded syslog-ng version |
219 |
update_syslogng $1 |
220 |
else |
221 |
update_syslogng_old $1 |
222 |
fi |
223 |
fi |
224 |
} |
225 |
|
226 |
########################################################################## |
227 |
# |
228 |
# remove chroot jail |
229 |
|
230 |
remove_chroot () { |
231 |
verbose=1 |
232 |
|
233 |
[ "$1" = "quiet" ] && verbose=0 |
234 |
[ "$1" = "noconf" ] && verbose=0 && noconf=1 |
235 |
|
236 |
info "removing chroot from: ${chroot}" |
237 |
|
238 |
# remove system files |
239 |
info "remove system files from chroot" |
240 |
for i in ${BASE_FILES} \ |
241 |
etc/passwd etc/group \ |
242 |
etc/samba/smb.conf etc/samba/lmhosts \ |
243 |
etc/ldap.conf ; do |
244 |
remove $i |
245 |
done |
246 |
|
247 |
info "remove additional files from chroot" |
248 |
for i in $ADDITIONAL_FILES; do |
249 |
# in case we have /path/file=/newpath/newfile |
250 |
remove ${i##*=} |
251 |
done |
252 |
|
253 |
info "removing chroot libraries from: ${chroot}" |
254 |
|
255 |
# remove nss libraries |
256 |
libs="" |
257 |
for l in ${chroot}/${_lib}/lib*.so* ${chroot}/usr/${_lib}/lib*.so*; do |
258 |
[ -f $l ] && \ |
259 |
libs="$libs $l `ldd $l | awk -v c=${chroot} '{print c $3}'`" |
260 |
done |
261 |
|
262 |
if [ -n "$libs" ]; then |
263 |
info "remove nss files from chroot" |
264 |
for l in $libs; do |
265 |
remove $l |
266 |
done |
267 |
fi |
268 |
|
269 |
info "remove system directories from chroot" |
270 |
for dir in var/lib/sasl2 var/lib var usr/share/zoneinfo \ |
271 |
usr/share usr/${_lib} usr ${_lib} etc; do |
272 |
[ -d ${chroot}/${dir} ] && \ |
273 |
info " ${chroot}/${dir}" && \ |
274 |
rmtree ${chroot}/${dir} |
275 |
done |
276 |
|
277 |
[ "$noconf" = "1" ] && return |
278 |
|
279 |
# remove chroot settings from master.cf |
280 |
awk -v ALWAYS_CHROOT_PROGRAM="$ALWAYS_CHROOT_PROGRAM" \ |
281 |
-v ALWAYS_CHROOT_SERVICE="$ALWAYS_CHROOT_SERVICE" ' |
282 |
BEGIN { IFS="[ \t]+"; OFS="\t"; } |
283 |
/^#/ { print; next; } |
284 |
/^ / { print; next; } |
285 |
$1 ~ ALWAYS_CHROOT_SERVICE { print; next; } |
286 |
$8 ~ ALWAYS_CHROOT_PROGRAM { print; next; } |
287 |
$5 == "y" { $5="n"; print $0; next; } |
288 |
{ print; } |
289 |
' ${confdir}/master.cf.${bckext} > ${confdir}/master.cf |
290 |
} |
291 |
|
292 |
# |
293 |
########################################################################## |
294 |
|
295 |
########################################################################## |
296 |
# |
297 |
# setup chroot jail |
298 |
|
299 |
setup_chroot () { |
300 |
verbose=1 |
301 |
|
302 |
[ -n "$1" ] && [ "$1" = quiet ] && verbose=0 |
303 |
|
304 |
# Check master.cf is where we expect it |
305 |
[ -f ${confdir}/master.cf ] || error "${confdir}/master.cf missing, exiting" |
306 |
info "setting up chroot at: ${chroot}" |
307 |
|
308 |
# copy system files into chroot environment |
309 |
info "copy system files into chroot" |
310 |
for i in ${BASE_FILES}; do |
311 |
[ -e ${i} ] && copy ${i} |
312 |
done |
313 |
|
314 |
info "copy additional files into chroot" |
315 |
for i in $ADDITIONAL_FILES; do |
316 |
# in case we have /path/file=/newpath/newfile |
317 |
copy ${i%%=*} ${i##*=} |
318 |
done |
319 |
|
320 |
# for sasl |
321 |
mkdir -p ${chroot}/var/lib/sasl2 2>/dev/null |
322 |
|
323 |
# for ldaps |
324 |
mkdir -p ${chroot}/dev |
325 |
cp -af /dev/urandom ${chroot}/dev |
326 |
|
327 |
# check smtpd's dependencies to determine which libraries |
328 |
# don't need to be copied into the chroot |
329 |
|
330 |
smtpd=`${postconf} -c ${confdir} -h daemon_directory`/smtpd |
331 |
if [ ! -x "${smtpd}" ];then |
332 |
warn "cannot find \$daemon_directory/smtpd" |
333 |
fi |
334 |
|
335 |
# check also dynamic maps dependencies |
336 |
[ -s ${confdir}/dynamicmaps.cf ] && \ |
337 |
dynmaps=`awk '/^[[:space:]]*#/ {next} {print $2}' ${confdir}/dynamicmaps.cf` |
338 |
|
339 |
prunedeps="none" |
340 |
for i in ${smtpd} ${dynmaps}; do |
341 |
prunedeps=`echo $prunedeps;/usr/bin/ldd $i | awk '/\// {print $(NF-1)}'` |
342 |
done |
343 |
|
344 |
nss_libs= |
345 |
for i in ${nss_databases}; do |
346 |
nss=`[ -s /etc/nsswitch.conf ] && \ |
347 |
awk -v db=$i: -v IGNORE_NSS_LIBS="${IGNORE_NSS_LIBS}" ' |
348 |
/^[[:space:]]*#/ {next} |
349 |
$1 == db { |
350 |
for (i=2;i<=NF;i++) { |
351 |
if (match($i,"#")) {next} |
352 |
if (!match($i,"=") && !match($i,IGNORE_NSS_LIBS)) {print $i} |
353 |
} |
354 |
} ' /etc/nsswitch.conf` |
355 |
[ -z "$nss" ] && eval `echo nss=\\\$nss_default_$i` |
356 |
nss_libs="$nss_libs $nss" |
357 |
done |
358 |
|
359 |
libs= |
360 |
for i in ${nss_libs}; do |
361 |
case $i in |
362 |
wins) conf="/etc/samba/smb.conf /etc/samba/lmhosts" ;; |
363 |
ldap) conf="/etc/ldap.conf" ;; # i purposefully ignore copying of /etc/ldap.secret |
364 |
*) conf="" ;; |
365 |
esac |
366 |
l=/${_lib}/libnss_$i.$nss_soname |
367 |
[ -e ${l} -a "${libs##*$l*}" == "${libs}" ] && \ |
368 |
libs=`echo $conf; echo $l;echo $libs;/usr/bin/ldd $l | awk '/\// {print $(NF-1)}'` |
369 |
done |
370 |
|
371 |
#now copy nss libraries and dependencies if we don't already have them loaded |
372 |
info "copy nss libraries into chroot" |
373 |
for i in $libs; do |
374 |
[ -n "${prunedeps##*$i*}" ] && copy ${i} |
375 |
done |
376 |
|
377 |
# chroot master.cf change all lines except pipe, local, proxymap, |
378 |
# virtual and spawn |
379 |
awk -v NEVER_CHROOT_PROGRAM="$NEVER_CHROOT_PROGRAM" \ |
380 |
-v NEVER_CHROOT_SERVICE="$NEVER_CHROOT_SERVICE" ' |
381 |
BEGIN { IFS="[ \t]+"; OFS="\t"; } |
382 |
/^#/ { print; next; } |
383 |
/^ / { print; next; } |
384 |
$1 ~ NEVER_CHROOT_SERVICE { print; next; } |
385 |
$8 ~ NEVER_CHROOT_PROGRAM { print; next; } |
386 |
$5 == "n" { $5="y"; print $0; next; } |
387 |
{ print; } |
388 |
' ${confdir}/master.cf.${bckext} > ${confdir}/master.cf |
389 |
} |
390 |
|
391 |
# |
392 |
########################################################################## |
393 |
|
394 |
########################################################################## |
395 |
# |
396 |
# check files in chroot |
397 |
|
398 |
check_files() { |
399 |
local i j f rc |
400 |
rc=0 |
401 |
for i in ${BASE_FILES} ${ADDITIONAL_FILES}; do |
402 |
f=${i%%=*} |
403 |
f=${f#/} |
404 |
i=${i##*=} |
405 |
i=${i#/} |
406 |
if [ -f /${i} -a ! -f ${chroot%/}/${f} ]; then |
407 |
info "file ${chroot%/}/${i} missing" |
408 |
rc=1 |
409 |
fi |
410 |
done |
411 |
cd $chroot || return 1 |
412 |
for i in `find bin etc lib sbin usr -type f -print 2>/dev/null`; do |
413 |
f=$i |
414 |
for j in ${ADDITIONAL_FILES}; do |
415 |
[ "$i" = "${j%%=*}" ] && f=${i##*=} |
416 |
done |
417 |
if [ -f /$f ]; then |
418 |
cmp -s $i /$f || { |
419 |
info "files ${chroot%/}/${i} and /${f#/} differ" |
420 |
rc=1 |
421 |
} |
422 |
fi |
423 |
done |
424 |
|
425 |
if [ ! -d ${chroot%/}/var/lib/sasl2 ]; then |
426 |
info "directory ${chroot%/}/var/lib/sasl2 missing" |
427 |
rc=1 |
428 |
fi |
429 |
|
430 |
if [ ! -c ${chroot%/}/dev/urandom ]; then |
431 |
info "device file ${chroot%/}/dev/urandom missing" |
432 |
rc=1 |
433 |
fi |
434 |
|
435 |
return $rc |
436 |
} |
437 |
|
438 |
# |
439 |
########################################################################## |
440 |
|
441 |
########################################################################## |
442 |
# |
443 |
# create/update /etc/sysconfig/postfix |
444 |
|
445 |
create_sysconfig() { |
446 |
cat > /etc/sysconfig/postfix <<-EOF |
447 |
# this file is automatically generated by postfix-chroot.sh |
448 |
# you can modify the parameters and they will be mantained |
449 |
# comments will not be preserved |
450 |
|
451 |
# use postfix-chroot.sh to change this |
452 |
CHROOT=${CHROOT} |
453 |
# this are regular expressions matching a whole line |
454 |
NEVER_CHROOT_PROGRAM='${NEVER_CHROOT_PROGRAM}' |
455 |
ALWAYS_CHROOT_PROGRAM='${ALWAYS_CHROOT_PROGRAM}' |
456 |
NEVER_CHROOT_SERVICE='${NEVER_CHROOT_SERVICE}' |
457 |
ALWAYS_CHROOT_SERVICE='${ALWAYS_CHROOT_SERVICE}' |
458 |
# nss names as they would appear in nsswitch.conf |
459 |
IGNORE_NSS_LIBS='${IGNORE_NSS_LIBS}' |
460 |
# space separated list of full pathname of file you want to be copied |
461 |
# use /path/file=/newpath/newfile for path mappings |
462 |
ADDITIONAL_FILES='${ADDITIONAL_FILES}' |
463 |
# Automatically rebuild maps at daemon startup |
464 |
REBUILD_ALIASES=${REBUILD_ALIASES} |
465 |
REBUILD_MAPS=${REBUILD_MAPS} |
466 |
# Multi instance support in initscripts and chroot. If disabled only |
467 |
# default instance will be started/stopped automatically |
468 |
MANAGE_MULTI_INSTANCES=${MANAGE_MULTI_INSTANCES} |
469 |
# The following two variables are used to limit the instances (or |
470 |
# groups of) that are started/stopped automatically. Put space |
471 |
# separated lists of instance or group _names_ there. |
472 |
MANAGE_ONLY_INSTANCES='${MANAGE_ONLY_INSTANCES}' |
473 |
MANAGE_ONLY_INSTANCE_GROUPS='${MANAGE_ONLY_INSTANCE_GROUPS}' |
474 |
# Space separated list of instance configuration _directories_ |
475 |
# that will not be chrooted |
476 |
DONT_CHROOT_INSTANCES='${DONT_CHROOT_INSTANCES}' |
477 |
|
478 |
EOF |
479 |
} |
480 |
|
481 |
# |
482 |
########################################################################## |
483 |
|
484 |
|
485 |
default_config_directory=/etc/postfix |
486 |
verbose=1 |
487 |
[ "$1" = "-q" ] && { quiet=quiet; verbose=0; shift; } |
488 |
[ "$1" = "-h" ] && { usage; exit 0; } |
489 |
|
490 |
[ -z "$1" -o -n "$3" ] && { usage; exit 1; } |
491 |
|
492 |
if [ -n "$2" ]; then |
493 |
config_directory="$2" |
494 |
else |
495 |
config_directory=${default_config_directory} |
496 |
fi |
497 |
|
498 |
[ "$UID" = "0" ] || error "your must be root to run this script" |
499 |
|
500 |
_lib=`rpm --eval '%_lib'` |
501 |
postconf=/usr/sbin/postconf |
502 |
[ -x ${postconf} ] || error "can not find postconf" |
503 |
[ -d "${config_directory}" -a -s "${config_directory}/main.cf" -a -s "${config_directory}/master.cf" ] || error "${config_directory} is not a postfix configuration directory" |
504 |
|
505 |
if [ "${config_directory}" == "${default_config_directory}" -a "`postconf -c ${config_directory} -h multi_instance_enable 2>/dev/null`" = "yes" ]; then |
506 |
multi_instance_directories=`postconf -c ${config_directory} -h multi_instance_directories 2>/dev/null` |
507 |
fi |
508 |
|
509 |
# defaults |
510 |
CHROOT=0 |
511 |
NEVER_CHROOT_PROGRAM='^(proxymap|local|pipe|virtual|spawn)$' |
512 |
NEVER_CHROOT_SERVICE='^cyrus$' |
513 |
ALWAYS_CHROOT_PROGRAM='^$' |
514 |
ALWAYS_CHROOT_SERVICE='^$' |
515 |
IGNORE_NSS_LIBS='^(mdns.*|ldap|db|wins)$' |
516 |
ADDITIONAL_FILES='' |
517 |
REBUILD_ALIASES=1 |
518 |
REBUILD_MAPS=1 |
519 |
MANAGE_MULTI_INSTANCES=1 |
520 |
MANAGE_ONLY_INSTANCES='' |
521 |
MANAGE_ONLY_INSTANCE_GROUPS='' |
522 |
DONT_CHROOT_INSTANCES='' |
523 |
[ -s /etc/sysconfig/postfix ] && . /etc/sysconfig/postfix |
524 |
|
525 |
BASE_FILES='/etc/localtime /etc/host.conf /etc/resolv.conf /etc/nsswitch.conf /etc/hosts /etc/services' |
526 |
|
527 |
# defaults for NSS |
528 |
# do i really need to look at passwd and group? |
529 |
nss_databases='passwd group hosts services' |
530 |
nss_default_passwd="compat" |
531 |
nss_default_group="compat" |
532 |
nss_default_hosts="dns files" |
533 |
nss_default_services="nis files" |
534 |
nss_soname=so.2 |
535 |
|
536 |
bckext=`date '+%Y%m%d-%H%M'` |
537 |
|
538 |
get_chroot() { |
539 |
local dir |
540 |
for dir in ${DONT_CHROOT_INSTANCES}; do |
541 |
[ "${confdir}" == "${dir}" ] && return |
542 |
done |
543 |
if [ "${config_directory}" != "${confdir}" -a "`postconf -c ${confdir} -h multi_instance_enable 2>/dev/null`" != "yes" ]; then |
544 |
info "skipping disabled instance ${confdir}" |
545 |
return |
546 |
fi |
547 |
|
548 |
local chroot=`${postconf} -c ${confdir} -h queue_directory 2>/dev/null` |
549 |
if [ -z "${chroot}" ]; then |
550 |
warn "chroot (${chroot}) is not defined" |
551 |
return |
552 |
fi |
553 |
if [ "${chroot}" = "/" ]; then |
554 |
warn "chroot (${chroot}) is set to /" |
555 |
return |
556 |
fi |
557 |
if [ ! -d "${chroot}" ]; then |
558 |
warn "chroot (${chroot}) is not a directory" |
559 |
return |
560 |
fi |
561 |
echo ${chroot} |
562 |
} |
563 |
|
564 |
enable_chroot() { |
565 |
for confdir in ${config_directory} ${multi_instance_directories}; do |
566 |
chroot=`get_chroot` |
567 |
[ -z "${chroot}" ] && continue |
568 |
|
569 |
cp -p ${confdir}/master.cf ${confdir}/master.cf.${bckext} |
570 |
remove_chroot noconf |
571 |
setup_chroot $quiet |
572 |
cmp -s ${confdir}/master.cf ${confdir}/master.cf.${bckext} && rm -f ${confdir}/master.cf.${bckext} |
573 |
[ -f ${confdir}/master.cf.${bckext} ] && info "${confdir}/master.cf backed up as ${confdir}/master.cf.${bckext}" |
574 |
update_syslog enable |
575 |
done |
576 |
} |
577 |
|
578 |
disable_chroot() { |
579 |
for confdir in ${config_directory} ${multi_instance_directories}; do |
580 |
chroot=`get_chroot` |
581 |
[ -z "${chroot}" ] && continue |
582 |
|
583 |
update_syslog disable |
584 |
cp -p ${confdir}/master.cf ${confdir}/master.cf.${bckext} |
585 |
remove_chroot ${1} |
586 |
cmp -s ${confdir}/master.cf ${confdir}/master.cf.${bckext} && rm -f ${confdir}/master.cf.${bckext} |
587 |
[ -f ${confdir}/master.cf.${bckext} ] && info "${confdir}/master.cf backed up as ${confdir}/master.cf.${bckext}" |
588 |
done |
589 |
} |
590 |
|
591 |
delete_chroot() { |
592 |
for confdir in ${config_directory} ${multi_instance_directories}; do |
593 |
chroot=`get_chroot` |
594 |
[ -z "${chroot}" ] && continue |
595 |
|
596 |
cp -p ${confdir}/master.cf ${confdir}/master.cf.${bckext} |
597 |
update_syslog disable |
598 |
remove_chroot noconf |
599 |
done |
600 |
} |
601 |
|
602 |
check_chroot() { |
603 |
for confdir in ${config_directory} ${multi_instance_directories}; do |
604 |
chroot=`get_chroot` |
605 |
[ -z "${chroot}" ] && continue |
606 |
|
607 |
check_files |
608 |
done |
609 |
} |
610 |
|
611 |
update_chroot() { |
612 |
for confdir in ${config_directory} ${multi_instance_directories}; do |
613 |
chroot=`get_chroot` |
614 |
[ -z "${chroot}" ] && continue |
615 |
|
616 |
check_files && continue |
617 |
|
618 |
cp -p ${confdir}/master.cf ${confdir}/master.cf.${bckext} |
619 |
remove_chroot noconf |
620 |
setup_chroot $quiet |
621 |
cmp -s ${confdir}/master.cf ${confdir}/master.cf.${bckext} && rm -f ${confdir}/master.cf.${bckext} |
622 |
[ -f ${confdir}/master.cf.${bckext} ] && info "${confdir}/master.cf backed up as ${confdir}/master.cf.${bckext}" |
623 |
update_syslog enable |
624 |
done |
625 |
} |
626 |
|
627 |
# create readable directories into the chroot |
628 |
umask 022 |
629 |
|
630 |
# See how we were called. |
631 |
case "$1" in |
632 |
enable) |
633 |
CHROOT=1 |
634 |
create_sysconfig |
635 |
enable_chroot |
636 |
;; |
637 |
disable) |
638 |
CHROOT=0 |
639 |
create_sysconfig |
640 |
disable_chroot $quiet |
641 |
;; |
642 |
remove) |
643 |
# used by rpm preuninstall script |
644 |
delete_chroot |
645 |
_noreload=1 |
646 |
;; |
647 |
update) |
648 |
if [ $CHROOT = 0 ];then |
649 |
info "chroot disabled in /etc/sysconfig/postfix" |
650 |
exit 0 |
651 |
else |
652 |
enable_chroot |
653 |
fi |
654 |
;; |
655 |
check) |
656 |
if [ $CHROOT = 0 ];then |
657 |
info "chroot disabled in /etc/sysconfig/postfix" |
658 |
exit 0 |
659 |
else |
660 |
check_chroot |
661 |
_noreload=1 |
662 |
fi |
663 |
;; |
664 |
check_update) |
665 |
if [ $CHROOT = 0 ];then |
666 |
info "chroot disabled in /etc/sysconfig/postfix" |
667 |
exit 0 |
668 |
else |
669 |
update_chroot |
670 |
fi |
671 |
;; |
672 |
*) |
673 |
usage |
674 |
exit 1 |
675 |
;; |
676 |
esac |
677 |
|
678 |
[ -n "${service_restart_syslog}" ] && service syslog condrestart |
679 |
[ -n "${service_restart_rsyslog}" ] && service rsyslog condrestart |
680 |
[ -n "${service_restart_syslog_ng}" ] && service syslog-ng condrestart |
681 |
[ -z "${_noreload}" -a -f /var/lock/subsys/postfix ] && service postfix reload |
682 |
|
683 |
exit 0 |
684 |
|
685 |
# vim:ts=8:sw=4 |