Try to route outgoing messages through diff IPs depending on trust
[sysconfig/postfix.git] / postfix-script
1 #!/bin/sh
2
3 #++
4 # NAME
5 #       postfix-script 1
6 # SUMMARY
7 #       execute Postfix administrative commands
8 # SYNOPSIS
9 #       \fBpostfix-script\fR \fIcommand\fR
10 # DESCRIPTION
11 #       The \fBpostfix-script\fR script executes Postfix administrative
12 #       commands in an environment that is set up by the \fBpostfix\fR(1)
13 #       command.
14 # SEE ALSO
15 #       master(8) Postfix master program
16 #       postfix(1) Postfix administrative interface
17 # LICENSE
18 # .ad
19 # .fi
20 #       The Secure Mailer license must be distributed with this software.
21 # AUTHOR(S)
22 #       Wietse Venema
23 #       IBM T.J. Watson Research
24 #       P.O. Box 704
25 #       Yorktown Heights, NY 10598, USA
26 #--
27
28 # Avoid POSIX death due to SIGHUP when some parent process exits.
29
30 trap '' 1
31
32 case $daemon_directory in
33 "") echo This script must be run by the postfix command. 1>&2
34     echo Do not run directly. 1>&2
35     exit 1
36 esac
37
38 LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
39 INFO="$LOGGER -p info"
40 WARN="$LOGGER -p warn"
41 ERROR="$LOGGER -p error"
42 FATAL="$LOGGER -p fatal"
43 PANIC="$LOGGER -p panic"
44
45 if [ "X${1#quiet-}" != "X${1}" ]; then
46     INFO=:
47     x=${1#quiet-}
48     shift
49     set -- $x "$@"
50 fi
51
52 umask 022
53 SHELL=/bin/sh
54
55 #
56 # Can't do much without these in place.
57 #
58 cd $command_directory || {
59         $FATAL no Postfix command directory $command_directory!
60         exit 1
61 }
62 cd $daemon_directory || {
63         $FATAL no Postfix daemon directory $daemon_directory!
64         exit 1
65 }
66 test -f master || {
67         $FATAL no Postfix master program $daemon_directory/master!
68         exit 1
69 }
70 cd $config_directory || {
71         $FATAL no Postfix configuration directory $config_directory!
72         exit 1
73 }
74 cd $queue_directory || {
75         $FATAL no Postfix queue directory $queue_directory!
76         exit 1
77 }
78 def_config_directory=`$command_directory/postconf -dh config_directory` || {
79         $FATAL cannot execute $command_directory/postconf!
80         exit 1
81 }
82
83 # If this is a secondary instance, don't touch shared files.
84
85 instances=`test ! -f $def_config_directory/main.cf ||
86     $command_directory/postconf -c $def_config_directory \
87     -h multi_instance_directories | sed 's/,/ /'` || {
88         $FATAL cannot execute $command_directory/postconf!
89         exit 1
90 }
91
92 check_shared_files=1
93 for name in $instances
94 do
95     case "$name" in
96     "$def_config_directory") ;;
97     "$config_directory") check_shared_files=; break;;
98     esac
99 done
100
101 #
102 # Parse JCL
103 #
104 case $1 in
105
106 start_msg)
107
108         echo "Start postfix"
109         ;;
110
111 stop_msg)
112
113         echo "Stop postfix"
114         ;;
115
116 quick-start)
117
118         $daemon_directory/master -t 2>/dev/null || {
119                 $FATAL the Postfix mail system is already running
120                 exit 1
121         }
122         $daemon_directory/postfix-script quick-check || {
123                 $FATAL Postfix integrity check failed!
124                 exit 1
125         }
126         $INFO starting the Postfix mail system
127         $daemon_directory/master &
128         ;;
129
130 start)
131
132         $daemon_directory/master -t 2>/dev/null || {
133                 $FATAL the Postfix mail system is already running
134                 exit 1
135         }
136         if [ -f $queue_directory/quick-start ]
137         then
138                 rm -f $queue_directory/quick-start
139         else
140                 $daemon_directory/postfix-script check-fatal || {
141                         $FATAL Postfix integrity check failed!
142                         exit 1
143                 }
144                 # Foreground this so it can be stopped. All inodes are cached.
145                 $daemon_directory/postfix-script check-warn
146         fi
147         $INFO starting the Postfix mail system
148         # NOTE: wait in foreground process to get the initialization status.
149         $daemon_directory/master -w || {
150             $FATAL "mail system startup failed"
151             exit 1
152         }
153         ;;
154
155 drain)
156
157         $daemon_directory/master -t 2>/dev/null && {
158                 $FATAL the Postfix mail system is not running
159                 exit 1
160         }
161         $INFO stopping the Postfix mail system
162         kill -9 `sed 1q pid/master.pid`
163         ;;
164
165 quick-stop)
166
167         $daemon_directory/postfix-script stop
168         touch $queue_directory/quick-start
169         ;;
170
171 stop)
172
173         $daemon_directory/master -t 2>/dev/null && {
174                 $FATAL the Postfix mail system is not running
175                 exit 0
176         }
177         $INFO stopping the Postfix mail system
178         kill `sed 1q pid/master.pid`
179         for i in 5 4 3 2 1
180         do
181             $daemon_directory/master -t && exit 0
182             $INFO waiting for the Postfix mail system to terminate
183             sleep 1
184         done
185         $WARN stopping the Postfix mail system with force
186         pid=`awk '{ print $1; exit 0 } END { exit 1 }' pid/master.pid` && 
187                 kill -9 -$pid
188         ;;
189
190 abort)
191
192         $daemon_directory/master -t 2>/dev/null && {
193                 $FATAL the Postfix mail system is not running
194                 exit 0
195         }
196         $INFO aborting the Postfix mail system
197         kill `sed 1q pid/master.pid`
198         ;;
199
200 reload)
201
202         $daemon_directory/master -t 2>/dev/null && {
203                 $FATAL the Postfix mail system is not running
204                 exit 1
205         }
206         $INFO refreshing the Postfix mail system
207         $command_directory/postsuper active || exit 1
208         kill -HUP `sed 1q pid/master.pid`
209         $command_directory/postsuper &
210         ;;
211
212 flush)
213
214         cd $queue_directory || {
215                 $FATAL no Postfix queue directory $queue_directory!
216                 exit 1
217         }
218         $command_directory/postqueue -f
219         ;;
220
221 check)
222
223         $daemon_directory/postfix-script check-fatal || exit 1
224         $daemon_directory/postfix-script check-warn
225         exit 0
226         ;;
227
228 status)
229
230         $daemon_directory/master -t 2>/dev/null && {
231                 $INFO the Postfix mail system is not running
232                 exit 1
233         }
234         $INFO the Postfix mail system is running: PID: `sed 1q pid/master.pid`
235         exit 0
236         ;;
237
238 quick-check)
239         # This command is NOT part of the public interface.
240
241         $SHELL $daemon_directory/post-install create-missing || {
242                 $WARN unable to create missing queue directories
243                 exit 1
244         }
245
246         # Look for incomplete installations.
247
248         test -f $config_directory/master.cf || {
249                 $FATAL no $config_directory/master.cf file found
250                 exit 1
251         }
252         exit 0
253         ;;
254
255 check-fatal)
256         # This command is NOT part of the public interface.
257
258         $daemon_directory/postfix-script quick-check
259
260         # See if all queue files are in the right place. This is slow.
261         # We must scan all queues for mis-named queue files before the
262         # mail system can run.
263
264         $command_directory/postsuper || exit 1
265         exit 0
266         ;;
267
268 check-warn)
269         # This command is NOT part of the public interface.
270
271         todo="$config_directory $queue_directory $queue_directory/pid"
272         test -n "$check_shared_files" && todo="$daemon_directory $todo"
273
274         for dir in $todo
275         do
276                 ls -lLd $dir | (grep " root " >/dev/null ||
277                     $WARN not owned by root: $dir)
278         done
279
280         # Some people break Postfix's security model.
281         ls -lLd $queue_directory | egrep '^.....(w|...w)' >/dev/null && \
282                 $WARN group or other writable: $queue_directory
283
284         todo="$config_directory/*"
285         test -n "$check_shared_files" && todo="$daemon_directory/* $todo"
286
287         find $todo ! -user root \
288                 -exec $WARN not owned by root: {} \;
289
290         todo="$config_directory/."
291         test -n "$check_shared_files" && todo="$daemon_directory/. $todo"
292
293         find $todo \
294                 \( -perm -020 -o -perm -002 \) -type f \
295                 -exec $WARN group or other writable: {} \;
296
297         find $data_directory/. ! -user $mail_owner \
298             -exec $WARN not owned by $mail_owner: {} \;
299
300         ls -lLd $data_directory | egrep '^.....(w|...w)' >/dev/null && \
301                 $WARN group or other writable: $data_directory
302
303         find `ls -d $queue_directory/* | \
304             egrep '/(saved|incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
305             ! \( -type p -o -type s \) ! -user $mail_owner \
306                 -exec $WARN not owned by $mail_owner: {} \;
307
308         todo="$queue_directory/public $queue_directory/maildrop"
309         test -n "$check_shared_files" && 
310            todo="$command_directory/postqueue $command_directory/postdrop $todo"
311
312         find $todo \
313             -prune ! -group $setgid_group \
314             -exec $WARN not owned by group $setgid_group: {} \;
315
316         test -n "$check_shared_files" &&
317         find $command_directory/postqueue $command_directory/postdrop \
318             -prune ! -perm -02111 \
319             -exec $WARN not set-gid or not owner+group+world executable: {} \;
320
321         for name in `ls -d $queue_directory/* | \
322             egrep '/(bin|etc|lib|usr)$'` ; \
323         do \
324             find $name ! -user root \
325                 -exec $WARN not owned by root: {} \; ; \
326         done
327
328         # WARNING: this should not descend into the maildrop directory.
329         # maildrop is the least trusted Postfix directory.
330
331         find $queue_directory/maildrop/. -prune ! -user $mail_owner \
332             -exec $WARN not owned by $mail_owner: $queue_directory/maildrop \;
333
334         for dir in bin etc lib sbin usr
335         do
336                 test -d $dir && find $dir -type f -print | while read path
337                 do
338                         test -f /$path && {
339                             cmp -s $path /$path || 
340                                 $WARN $queue_directory/$path and /$path differ
341                         }
342                 done
343         done
344
345         find corrupt -type f -exec $WARN damaged message: {} \;
346
347         # XXX also: look for weird stuff, weird permissions, etc.
348
349         test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \
350                 -f /usr/lib/sendmail && {
351             cmp -s /usr/sbin/sendmail /usr/lib/sendmail || {
352                 $WARN /usr/lib/sendmail and /usr/sbin/sendmail differ
353                 $WARN Replace one by a symbolic link to the other
354             }
355         }
356         exit 0
357         ;;
358
359 set-permissions|upgrade-configuration)
360         $daemon_directory/post-install create-missing "$@"
361         ;;
362
363 post-install)
364         # Currently not part of the public interface.
365         shift
366         $daemon_directory/post-install "$@"
367         ;;
368
369 /*)
370         # Currently not part of the public interface.
371         "$@"
372         ;;
373
374 *)
375         $ERROR "unknown command: '$1'"
376         $FATAL "usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration)"
377         exit 1
378         ;;
379
380 esac