Permanently reject unknown recipients
[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 #       Wietse Venema
28 #       Google, Inc.
29 #       111 8th Avenue
30 #       New York, NY 10011, USA
31 #--
32
33 # Avoid POSIX death due to SIGHUP when some parent process exits.
34
35 trap '' 1
36
37 case $daemon_directory in
38 "") echo This script must be run by the postfix command. 1>&2
39     echo Do not run directly. 1>&2
40     exit 1
41 esac
42
43 LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
44 INFO="$LOGGER -p info"
45 WARN="$LOGGER -p warn"
46 ERROR="$LOGGER -p error"
47 FATAL="$LOGGER -p fatal"
48 PANIC="$LOGGER -p panic"
49
50 if [ "X${1#quiet-}" != "X${1}" ]; then
51     INFO=:
52     x=${1#quiet-}
53     shift
54     set -- $x "$@"
55 fi
56
57 umask 022
58 SHELL=/bin/sh
59
60 #
61 # Can't do much without these in place.
62 #
63 cd $command_directory || {
64         $FATAL no Postfix command directory $command_directory!
65         exit 1
66 }
67 cd $daemon_directory || {
68         $FATAL no Postfix daemon directory $daemon_directory!
69         exit 1
70 }
71 test -f master || {
72         $FATAL no Postfix master program $daemon_directory/master!
73         exit 1
74 }
75 cd $config_directory || {
76         $FATAL no Postfix configuration directory $config_directory!
77         exit 1
78 }
79 case $shlib_directory in
80 no) ;;
81  *) cd $shlib_directory || {
82         $FATAL no Postfix shared-library directory $shlib_directory!
83         exit 1
84     }
85 esac
86 cd $meta_directory || {
87         $FATAL no Postfix meta directory $meta_directory!
88         exit 1
89 }
90 cd $queue_directory || {
91         $FATAL no Postfix queue directory $queue_directory!
92         exit 1
93 }
94 def_config_directory=`$command_directory/postconf -dh config_directory` || {
95         $FATAL cannot execute $command_directory/postconf!
96         exit 1
97 }
98
99 # If this is a secondary instance, don't touch shared files.
100
101 instances=`test ! -f $def_config_directory/main.cf ||
102     $command_directory/postconf -c $def_config_directory \
103     -h multi_instance_directories | sed 's/,/ /'` || {
104         $FATAL cannot execute $command_directory/postconf!
105         exit 1
106 }
107
108 check_shared_files=1
109 for name in $instances
110 do
111     case "$name" in
112     "$def_config_directory") ;;
113     "$config_directory") check_shared_files=; break;;
114     esac
115 done
116
117 #
118 # Parse JCL
119 #
120 case $1 in
121
122 start_msg)
123
124         echo "Start postfix"
125         ;;
126
127 stop_msg)
128
129         echo "Stop postfix"
130         ;;
131
132 quick-start)
133
134        $daemon_directory/master -t 2>/dev/null || {
135                $FATAL the Postfix mail system is already running
136                exit 1
137        }
138        $daemon_directory/postfix-script quick-check || {
139                $FATAL Postfix integrity check failed!
140                exit 1
141        }
142        $INFO starting the Postfix mail system
143        $daemon_directory/master &
144        ;;
145
146 start|start-fg)
147
148         $daemon_directory/master -t 2>/dev/null || {
149                 $FATAL the Postfix mail system is already running
150                 exit 1
151         }
152         if [ -f $queue_directory/quick-start ]
153         then
154                 rm -f $queue_directory/quick-start
155         else
156                 $daemon_directory/postfix-script check-fatal || {
157                         $FATAL Postfix integrity check failed!
158                         exit 1
159                 }
160                 # Foreground this so it can be stopped. All inodes are cached.
161                 $daemon_directory/postfix-script check-warn
162         fi
163         $INFO starting the Postfix mail system
164         case $1 in
165         start)
166             # NOTE: wait in foreground process to get the initialization status.
167             $daemon_directory/master -w || {
168                 $FATAL "mail system startup failed"
169                 exit 1
170             }
171             ;;
172         start-fg)
173             # Foreground start-up is incompatible with multi-instance mode.
174             # We can't use "exec $daemon_directory/master" here: that would
175             # break process group management, and "postfix stop" would kill
176             # too many processes.
177             case $instances in
178             "") $daemon_directory/master
179                 ;;
180              *) $FATAL "start-fg does not support multi_instance_directories"
181                 exit 1
182                 ;;
183             esac
184             ;;
185         esac
186         ;;
187
188 drain)
189
190         $daemon_directory/master -t 2>/dev/null && {
191                 $FATAL the Postfix mail system is not running
192                 exit 1
193         }
194         $INFO stopping the Postfix mail system
195         kill -9 `sed 1q pid/master.pid`
196         ;;
197
198 quick-stop)
199
200         $daemon_directory/postfix-script stop
201         touch $queue_directory/quick-start
202         ;;
203
204 stop)
205
206         $daemon_directory/master -t 2>/dev/null && {
207                 $FATAL the Postfix mail system is not running
208                 exit 0
209         }
210         $INFO stopping the Postfix mail system
211         kill `sed 1q pid/master.pid`
212         for i in 5 4 3 2 1
213         do
214             $daemon_directory/master -t && exit 0
215             $INFO waiting for the Postfix mail system to terminate
216             sleep 1
217         done
218         $WARN stopping the Postfix mail system with force
219         pid=`awk '{ print $1; exit 0 } END { exit 1 }' pid/master.pid` && 
220                 kill -9 -$pid
221         ;;
222
223 abort)
224
225         $daemon_directory/master -t 2>/dev/null && {
226                 $FATAL the Postfix mail system is not running
227                 exit 0
228         }
229         $INFO aborting the Postfix mail system
230         kill `sed 1q pid/master.pid`
231         ;;
232
233 reload)
234
235         $daemon_directory/master -t 2>/dev/null && {
236                 $FATAL the Postfix mail system is not running
237                 exit 1
238         }
239         $INFO refreshing the Postfix mail system
240         $command_directory/postsuper active || exit 1
241         kill -HUP `sed 1q pid/master.pid`
242         $command_directory/postsuper &
243         ;;
244
245 flush)
246
247         cd $queue_directory || {
248                 $FATAL no Postfix queue directory $queue_directory!
249                 exit 1
250         }
251         $command_directory/postqueue -f
252         ;;
253
254 check)
255
256         $daemon_directory/postfix-script check-fatal || exit 1
257         $daemon_directory/postfix-script check-warn
258         exit 0
259         ;;
260
261 status)
262
263         $daemon_directory/master -t 2>/dev/null && {
264                 $INFO the Postfix mail system is not running
265                 exit 1
266         }
267         $INFO the Postfix mail system is running: PID: `sed 1q pid/master.pid`
268         exit 0
269         ;;
270
271 quick-check)
272         # This command is NOT part of the public interface.
273
274         $SHELL $daemon_directory/post-install create-missing || {
275                 $WARN unable to create missing queue directories
276                 exit 1
277         }
278
279         # Look for incomplete installations.
280
281         test -f $config_directory/master.cf || {
282                 $FATAL no $config_directory/master.cf file found
283                 exit 1
284         }
285         exit 0
286         ;;
287
288 check-fatal)
289         # This command is NOT part of the public interface.
290
291         $daemon_directory/postfix-script quick-check
292
293         # See if all queue files are in the right place. This is slow.
294         # We must scan all queues for mis-named queue files before the
295         # mail system can run.
296
297         $command_directory/postsuper || exit 1
298         exit 0
299         ;;
300
301 check-warn)
302         # This command is NOT part of the public interface.
303
304         # Check Postfix root-owned directory owner/permissions.
305
306         find $queue_directory/. $queue_directory/pid \
307             -prune ! -user root \
308             -exec $WARN not owned by root: {} \;
309
310         find $queue_directory/. $queue_directory/pid \
311             -prune \( -perm -020 -o -perm -002 \) \
312             -exec $WARN group or other writable: {} \;
313
314         # Check Postfix root-owned directory tree owner/permissions.
315
316         todo="$config_directory/."
317         test -n "$check_shared_files" && {
318                 todo="$daemon_directory/. $meta_directory/. $todo"
319                 test "$shlib_directory" = "no" || 
320                     todo="$shlib_directory/. $todo"
321         }
322         todo=`echo "$todo" | tr ' ' '\12' | sort -u`
323
324         find $todo ! -user root \
325             -exec $WARN not owned by root: {} \;
326
327         # Handle symlinks separately
328         find -L $todo \( -perm -020 -o -perm -002 \) \
329             -exec $WARN group or other writable: {} \;
330
331         find $todo -type l | while read f; do \
332             readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f"; \
333         done; \
334
335         # Check Postfix mail_owner-owned directory tree owner/permissions.
336
337         find $data_directory/. ! -user $mail_owner \
338             -exec $WARN not owned by $mail_owner: {} \;
339
340         find $data_directory/. \( -perm -020 -o -perm -002 \) \
341             -exec $WARN group or other writable: {} \;
342
343         # Check Postfix mail_owner-owned directory tree owner.
344
345         find `ls -d $queue_directory/* | \
346             egrep '/(saved|incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
347             ! \( -type p -o -type s \) ! -user $mail_owner \
348                 -exec $WARN not owned by $mail_owner: {} \;
349
350         # WARNING: this should not descend into the maildrop directory.
351         # maildrop is the least trusted Postfix directory.
352
353         find $queue_directory/maildrop -prune ! -user $mail_owner \
354             -exec $WARN not owned by $mail_owner: $queue_directory/maildrop \;
355
356         # Check Postfix setgid_group-owned directory and file group/permissions.
357
358         todo="$queue_directory/public $queue_directory/maildrop"
359         test -n "$check_shared_files" && 
360            todo="$command_directory/postqueue $command_directory/postdrop $todo"
361
362         find $todo \
363             -prune ! -group $setgid_group \
364             -exec $WARN not owned by group $setgid_group: {} \;
365
366         test -n "$check_shared_files" &&
367         find $command_directory/postqueue $command_directory/postdrop \
368             -prune ! -perm -02111 \
369             -exec $WARN not set-gid or not owner+group+world executable: {} \;
370
371         # Check non-Postfix root-owned directory tree owner/content.
372
373         for dir in bin etc lib sbin usr
374         do
375             test -d $dir && {
376                 find $dir ! -user root \
377                     -exec $WARN not owned by root: $queue_directory/{} \;
378
379                 find $dir -type f -print | while read path
380                 do
381                     test -f /$path && {
382                         cmp -s $path /$path || 
383                             $WARN $queue_directory/$path and /$path differ
384                     }
385                 done
386             }
387         done
388
389         find corrupt -type f -exec $WARN damaged message: {} \;
390
391         # Check for non-Postfix MTA remnants.
392
393         test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \
394                 -f /usr/lib/sendmail && {
395             cmp -s /usr/sbin/sendmail /usr/lib/sendmail || {
396                 $WARN /usr/lib/sendmail and /usr/sbin/sendmail differ
397                 $WARN Replace one by a symbolic link to the other
398             }
399         }
400         exit 0
401         ;;
402
403 set-permissions|upgrade-configuration)
404         $daemon_directory/post-install create-missing "$@"
405         ;;
406
407 post-install)
408         # Currently not part of the public interface.
409         shift
410         $daemon_directory/post-install "$@"
411         ;;
412
413 tls)
414         shift
415         $daemon_directory/postfix-tls-script "$@"
416         ;;
417
418 /*)
419         # Currently not part of the public interface.
420         "$@"
421         ;;
422
423 *)
424         $FATAL "unknown command: '$1'. Usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration)"
425         exit 1
426         ;;
427
428 esac