#!/bin/sh
#++
# NAME
# postfix-script
1
# SUMMARY
# execute Postfix administrative commands
# SYNOPSIS
# \fBpostfix-script\fR \fIcommand\fR
# DESCRIPTION
# The \fBpostfix-script\fR script executes Postfix administrative
# commands in an environment that is set up by the \fBpostfix\fR(
1)
# command.
# SEE ALSO
# master(
8) Postfix master program
# postfix(
1) Postfix administrative interface
# LICENSE
# .ad
# .fi
# The Secure Mailer license must be distributed with
this software.
# AUTHOR(S)
# Wietse Venema
# IBM T.J. Watson Research
# P.O. Box
704
# Yorktown Heights, NY
10598, USA
java.lang.NullPointerException
# Wietse Venema
# Google, Inc.
# 111 8th Avenue
# New York, NY
10011, USA
java.lang.NullPointerException
# Wietse Venema
# porcupine.org
# Amawalk, NY
10501, USA
#--
# Avoid POSIX death due to SIGHUP when some parent process exits.
trap
'' 1
case $daemon_directory in
"") echo
This script must be run by the postfix command.
1>&
2
echo
Do not run directly.
1>&
2
exit 1
esac
LOGGER=
"$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
INFO=
"$LOGGER -p info"
WARN=
"$LOGGER -p warn"
ERROR=
"$LOGGER -p error"
FATAL=
"$LOGGER -p fatal"
PANIC=
"$LOGGER -p panic"
umask
022
SHELL=/bin/sh
java.lang.NullPointerException
# Can
't do much without these in place.
java.lang.NullPointerException
cd $command_directory || {
$FATAL no Postfix command directory $command_directory!
exit 1
}
cd $daemon_directory || {
$FATAL no Postfix daemon directory $daemon_directory!
exit 1
}
test -f master || {
$FATAL no Postfix master program $daemon_directory/master!
exit 1
}
cd $config_directory || {
$FATAL no Postfix configuration directory $config_directory!
exit 1
}
case $shlib_directory in
no) ;;
*) cd $shlib_directory || {
$FATAL no Postfix shared-library directory $shlib_directory!
exit 1
}
esac
cd $meta_directory || {
$FATAL no Postfix meta directory $meta_directory!
exit 1
}
cd $queue_directory || {
$FATAL no Postfix queue directory $queue_directory!
exit 1
}
def_config_directory=`$command_directory/postconf -dh config_directory` || {
$FATAL cannot execute $command_directory/postconf!
exit 1
}
# If this is a secondary instance, don
't touch shared files.
instances=`test ! -f $def_config_directory/main.cf ||
$command_directory/postconf -qc $def_config_directory \
-h multi_instance_directories | sed
'y/,/ /'` || {
$FATAL cannot execute $command_directory/postconf!
exit 1
}
check_shared_files=
1
for name in $instances
do
case "$name" in
"$def_config_directory") ;;
"$config_directory") check_shared_files=;
break;;
esac
done
java.lang.NullPointerException
# Parse JCL
java.lang.NullPointerException
case $
1 in
start_msg)
echo
"Start postfix"
;;
stop_msg)
echo
"Stop postfix"
;;
start|start-fg)
$daemon_directory/master -t
2>/dev/null || {
$FATAL the Postfix mail system is already running
exit 1
}
if [ -f $queue_directory/quick-start ]
then
rm -f $queue_directory/quick-start
else
$daemon_directory/postfix-script check-fatal || {
$FATAL Postfix integrity check failed!
exit 1
}
# Foreground
this so it can be stopped. All inodes are cached.
$daemon_directory/postfix-script check-warn
$daemon_directory/postfix-script check-alias-maps-migration
fi
$INFO starting the Postfix mail system ||
exit 1
case $
1 in
start)
# NOTE: wait in foreground process to get the initialization status.
$daemon_directory/master -w || {
$FATAL
"mail system startup failed"
exit 1
}
;;
start-fg)
# Foreground start-up is incompatible with multi-instance mode.
# Use
"exec $daemon_directory/master" only
if PID ==
1.
# Otherwise, doing so would
break process group management,
# and "postfix stop" would kill too many processes.
case $instances in
"")
case $$ in
1) exec $daemon_directory/master -i
$FATAL
"cannot start-fg the master daemon"
exit 1;;
*) $daemon_directory/master -s;;
esac
;;
*) $FATAL
"start-fg does not support multi_instance_directories"
exit 1
;;
esac
;;
esac
;;
drain)
$daemon_directory/master -t
2>/dev/null && {
$FATAL the Postfix mail system is
not running
exit 1
}
$INFO stopping the Postfix mail system
kill -
9 `sed
1q pid/master.pid`
;;
quick-stop)
$daemon_directory/postfix-script stop
touch $queue_directory/quick-start
;;
stop)
$daemon_directory/master -t
2>/dev/null && {
$FATAL the Postfix mail system is
not running
exit 1
}
$INFO stopping the Postfix mail system
kill `sed
1q pid/master.pid`
for i in
5 4 3 2 1
do
$daemon_directory/master -t &&
exit 0
$INFO waiting
for the Postfix mail system to terminate
sleep
1
done
$WARN stopping the Postfix mail system with force
pid=`awk
'{ print $1; exit 0 } END { exit 1 }' pid/master.pid` &&
kill -
9 -$pid
;;
abort)
$daemon_directory/master -t
2>/dev/null && {
$FATAL the Postfix mail system is
not running
exit 1
}
$INFO aborting the Postfix mail system
kill `sed
1q pid/master.pid`
;;
reload)
# Warn once
for deprecated parameters.
$command_directory/postconf >/dev/null
$daemon_directory/master -t
2>/dev/null && {
$FATAL the Postfix mail system is
not running
exit 1
}
$INFO refreshing the Postfix mail system
$command_directory/postsuper active ||
exit 1
kill -HUP `sed
1q pid/master.pid`
$command_directory/postsuper &
;;
flush)
cd $queue_directory || {
$FATAL no Postfix queue directory $queue_directory!
exit 1
}
$command_directory/postqueue -f
;;
check)
$daemon_directory/postfix-script check-fatal ||
exit 1
$daemon_directory/postfix-script check-alias-maps-migration
$daemon_directory/postfix-script check-warn
exit 0
;;
status)
# Warn once
for deprecated parameters.
$command_directory/postconf >/dev/null
$daemon_directory/master -t
2>/dev/null && {
$INFO the Postfix mail system is
not running
exit 1
}
$INFO the Postfix mail system is running: PID: `sed
1q pid/master.pid`
exit 0
;;
check-fatal)
# This command is
NOT part of the
public interface.
$SHELL $daemon_directory/post-install create-missing || {
$FATAL unable to create missing queue directories
exit 1
}
# Look
for incomplete installations.
test -f $config_directory/master.cf || {
$FATAL no $config_directory/master.cf file found
exit 1
}
maillog_file=`$command_directory/postconf -qh maillog_file` || {
$FATAL cannot execute $command_directory/postconf!
exit 1
}
test -n
"$maillog_file" && {
$command_directory/postconf -qM postlog/unix-dgram
2>/dev/null \
| grep . >/dev/null || {
$FATAL
"missing 'postlog' service in master.cf - run 'postfix upgrade-configuration'"
exit 1
}
}
# See
if all queue files are in the right place.
This is slow.
# We must scan all queues
for mis-named queue files before the
# mail system can run.
$command_directory/postsuper ||
exit 1
exit 0
;;
check-alias-maps-migration)
# This command is
NOT part of the
public interface.
# As of Postfix
3.
11, the
default alias_maps value
# contains $default_database_type:/path/to/aliases. When
# default_database_type is changed to lmdb
or cdb, Postfix
# will
not generate hash:/path/to/aliases requests that can
# be resolved dynamically with enable-redirect
or enable-reindex.
#
# To avoid
this, craft a one-time stand-alone re-indexing request.
test -f $config_directory/check-alias-maps-migration-done &&
exit 0
test
"x`$command_directory/postconf -h non_bdb_migration_level`" = xenable-reindex ||
exit 0
BACKUP_IFS=
"$IFS"
for map in `$command_directory/postconf -hx alias_maps`
do
echo
"$map" | (
IFS=: read type path; IFS=
"$BACKUP_IFS"
case "$type" in
cdb|lmdb)
test ! -f
"$path.$type" -a -f
"$path" -a -f
"$path.db" && {
$daemon_directory/nbdb_reindexd -S
"hash:$path" ||
$WARN
"See https://www.postfix.org/NON_BERKELEYDB_README.html for suggestions"
}
esac
)
done
touch $config_directory/check-alias-maps-migration-done
;;
check-warn)
# This command is
NOT part of the
public interface.
# Warn once
for deprecated parameters.
$command_directory/postconf >/dev/null
# Check Postfix root-owned directory owner/permissions.
find $queue_directory/. $queue_directory/pid \
-prune ! -user root \
-exec $WARN
not owned by root: {} \;
find $queue_directory/. $queue_directory/pid \
-prune \( -perm -
020 -o -perm -
002 \) \
-exec $WARN group
or other writable: {} \;
# Check Postfix root-owned directory tree owner/permissions.
todo=
"$config_directory/."
test -n
"$check_shared_files" && {
todo=
"$daemon_directory/. $meta_directory/. $todo"
test
"$shlib_directory" =
"no" ||
todo=
"$shlib_directory/. $todo"
}
todo=`echo
"$todo" | tr
' ' '\12' | sort -u`
find $todo ! -user root \
-exec $WARN
not owned by root: {} \;
find $todo \( -perm -
020 -o -perm -
002 \) \
-exec $WARN group
or other writable: {} \;
# Check Postfix mail_owner-owned directory tree owner/permissions.
find $data_directory/. ! -user $mail_owner \
-exec $WARN
not owned by $mail_owner: {} \;
find $data_directory/. \( -perm -
020 -o -perm -
002 \) \
-exec $WARN group
or other writable: {} \;
# Check Postfix mail_owner-owned directory tree owner.
find `ls -d $queue_directory
/* | \
grep -E '/(saved|incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
! \( -type p -o -type s \) ! -user $mail_owner \
-exec $WARN not owned by $mail_owner: {} \;
# WARNING: this should not descend into the maildrop directory.
# maildrop is the least trusted Postfix directory.
find $queue_directory/maildrop -prune ! -user $mail_owner \
-exec $WARN not owned by $mail_owner: $queue_directory/maildrop \;
# Check Postfix setgid_group-owned directory and file group/permissions.
todo="$queue_directory/public $queue_directory/maildrop"
test -n "$check_shared_files" &&
todo="$command_directory/postqueue $command_directory/postdrop $todo"
find $todo \
-prune ! -group $setgid_group \
-exec $WARN not owned by group $setgid_group: {} \;
test -n "$check_shared_files" &&
find $command_directory/postqueue $command_directory/postdrop \
-prune ! -perm -02111 \
-exec $WARN not set-gid or not owner+group+world executable: {} \;
# Check non-Postfix root-owned directory tree owner/content.
for dir in bin etc lib sbin usr
do
test -d $dir && {
find $dir ! -user root \
-exec $WARN not owned by root: $queue_directory/{} \;
find $dir -type f -print | while read path
do
test -f /$path && {
cmp -s $path /$path ||
$WARN $queue_directory/$path and /$path differ
}
done
}
done
find corrupt -type f -exec $WARN damaged message: {} \;
# Check for non-Postfix MTA remnants.
test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \
-f /usr/lib/sendmail && {
cmp -s /usr/sbin/sendmail /usr/lib/sendmail || {
$WARN /usr/lib/sendmail and /usr/sbin/sendmail differ
$WARN Replace one by a symbolic link to the other
}
}
exit 0
;;
set-permissions|upgrade-configuration)
$daemon_directory/post-install create-missing "$@"
;;
post-install)
# Currently not part of the public interface.
shift
$daemon_directory/post-install "$@"
;;
tls|non-bdb)
cmd=$1; shift
$daemon_directory/postfix-$cmd-script "$@"
;;
/*)
# Currently not part of the public interface.
"$@"
;;
logrotate)
case $# in
1) ;;
*) $FATAL "usage postfix $1 (no arguments)"; exit 1;;
esac
for name in maillog_file maillog_file_compressor \
maillog_file_rotate_suffix
do
value="`$command_directory/postconf -qh $name`"
case "$value" in
"") $FATAL "empty '$name' parameter value - logfile rotation failed"
exit 1;;
esac
eval $name='"$value"';
done
case "$maillog_file" in
/dev/*) $FATAL "not rotating '$maillog_file'"; exit 1;;
esac
errors=`(
suffix="\`date +$maillog_file_rotate_suffix\`" || exit 1
mv "$maillog_file" "$maillog_file.$suffix" || exit 1
$daemon_directory/master -t 2>/dev/null ||
kill -HUP \`sed 1q pid/master.pid\` || exit 1
sleep 1
"$maillog_file_compressor" "$maillog_file.$suffix" || exit 1
) 2>&1` || {
$FATAL "logfile '$maillog_file' rotation failed: $errors"
exit 1
}
;;
*)
$FATAL "unknown command: '$1'. Usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration, logrotate, tls, non-bdb)"
exit 1
;;
esac