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