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