diff options
Diffstat (limited to 'debian/postfix.postinst')
-rw-r--r-- | debian/postfix.postinst | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/debian/postfix.postinst b/debian/postfix.postinst new file mode 100644 index 0000000..5bd81e2 --- /dev/null +++ b/debian/postfix.postinst @@ -0,0 +1,630 @@ +#!/bin/sh -e + +# Debian Postfix postinst +# LaMont Jones <lamont@debian.org> +# Based on debconf code by Colin Walters <walters@cis.ohio-state.edu>, +# and John Goerzen <jgoerzen@progenylinux.com>. + +# Use debconf. +. /usr/share/debconf/confmodule +CHROOT=/var/spool/postfix +config_directory="/etc/postfix" # make variable expansion easier... + +. /usr/share/postfix/postinst.functions + +set_maildrop_perms() { + MAILDROP=${CHROOT}/maildrop + SCRIPT=/etc/postfix/postfix-script + POSTDROP=/usr/sbin/postdrop + mkdir -p $MAILDROP + if ! chown postfix:postdrop $MAILDROP 2>/dev/null; then + addgroup --system postdrop + chown postfix:postdrop $MAILDROP + fi + dpkg-statoverride --remove $POSTDROP >/dev/null 2>&1 || true + dpkg-statoverride --remove /var/spool/postfix/public >/dev/null 2>&1 || true + dpkg-statoverride --remove /usr/sbin/postqueue >/dev/null 2>&1 || true + dpkg-statoverride --update --add root postdrop 02555 $POSTDROP + dpkg-statoverride --update --add postfix postdrop 02710 /var/spool/postfix/public + dpkg-statoverride --update --add root postdrop 02555 /usr/sbin/postqueue + chmod 1730 $MAILDROP + # Make SE Linux happy (hopefully) + if pathfind restorecon; then + restorecon "$MAILDROP" + restorecon "$POSTDROP" + restorecon /var/spool/postfix/public + restorecon /usr/sbin/postqueue + fi +} + +myfqdn() { + myhostname=$(hostname --fqdn 2>/dev/null || echo "") + # If we don't have a name with a dot (which includes ""), then we have work. + if [ $myhostname = ${myhostname%.*} ]; then + # If it's empty, and we have /etc/hostname, try that. + if [ -z $myhostname ] && [ -r /etc/hostname ]; then + myhostname=$(cat /etc/hostname) + fi + # If we are still lacking a domain component, then try resolv.conf. + if [ $myhostname = ${myhostname%.*} ]; then + if [ -f /etc/resolv.conf ]; then + # The resolver uses the last one found, and ignores the rest + mydom=$(sed -n 's/^search[[:space:]]*\.*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\.*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1) + myhostname="$myhostname${mydom:+.$mydom}" + else + myhostname="$myhostname.UNKNOWN" + fi + fi + fi + echo $myhostname +} + +fset_all_changed() { + db_fset postfix/main_mailer_type changed $1 + db_fset postfix/root_address changed $1 + db_fset postfix/destinations changed $1 + db_fset postfix/mailname changed $1 + db_fset postfix/relayhost changed $1 + db_fset postfix/chattr changed $1 + db_fset postfix/mynetworks changed $1 + db_fset postfix/procmail changed $1 + db_fset postfix/mailbox_limit changed $1 + db_fset postfix/recipient_delim changed $1 + db_fset postfix/protocols changed $1 +} + +set_postconf() { + CHANGES=true + postconf -e "$@" +} + +makedir() { + if [ ! -d $1 ]; then + mkdir $1 + if pathfind restorecon; then restorecon "$1" + fi + fi + chown $2 $1 && chmod $3 $1 +} + +fix_master() { + OLD_VERSION="$1" + echoed="" + # Need to handle some changes in services. + MASTER=/etc/postfix/master.cf + if grep -qE '^cleanup[[:space:]]+unix[[:space:]]+-' ${MASTER}; then + echo "In master.cf:"; echoed=y + echo " forcing pickup=unprivileged, cleanup=public, flush=public" + sed 's/^\(cleanup[[:space:]]*unix[[:space:]]*\)-/\1n/ + s/^\(flush[[:space:]]*unix[[:space:]]*\)-/\1n/ + s/^\(pickup[[:space:]]*fifo[[:space:]]*.[[:space:]]*\)n/\1-/ + ' ${MASTER} > ${MASTER}.$$ + mv ${MASTER}.$$ ${MASTER} + fi + + while read line; do + serv=${line%% *} + if ! grep -qE "^${serv}[[:space:]]" ${MASTER}; then + [ -n "$echoed" ] || echo "In master.cf:"; echoed=y + echo " adding missing entry for ${serv} service" + echo "$line" >> ${MASTER} + fi + done << @@EOF@@ +flush unix n - y 1000? 0 flush +proxymap unix - - n - - proxymap +trace unix - - y - 0 bounce +verify unix - - y - 1 verify +tlsmgr unix - - y 1000? 1 tlsmgr +anvil unix - - y - 1 anvil +scache unix - - y - 1 scache +discard unix - - y - - discard +retry unix - - y - - error +@@EOF@@ + + if ! grep -qE '^relay[[:space:]]' ${MASTER}; then + [ -n "$echoed" ] || echo "In master.cf:"; echoed=y + echo " adding missing entry for relay service" + echo "relay unix - - n - - smtp -o smtp_fallback_relay= " \ + >> ${MASTER} + echo "# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5" \ + >> ${MASTER} + fi + + if grep -qE '^tlsmgr[[:space:]]*fifo' ${MASTER}; then + sed '/^tlsmgr/s/fifo/unix/' ${MASTER} > ${MASTER}.$$ + mv ${MASTER}.$$ ${MASTER} + fi + + # After 3.1.3-7 and before 3.1.4-3~ we erroneously changed master. + # Change it back. See Debian bug 850430. Up through 3.1.4-7~ we still + # got it wrong on new installs. See Debian bug 862244. + if dpkg --compare-versions "$OLDVERSION" ge 3.1.3-7 && \ + dpkg --compare-versions "$OLDVERSION" lt 3.1.4-7~; then + if grep -qE '^lmtp[[:space:]].*smtp$' ${MASTER}; then + [ -n "$echoed" ] || echo "In master.cf:"; echoed=y + echo " restoring lmtp binary for lmtp service" + sed '/^lmtp[[:space:]]/s/smtp$/lmtp/' ${MASTER} > ${MASTER}.$$ + mv ${MASTER}.$$ ${MASTER} + if test -f ${MASTER}.proto && grep -qE '^lmtp[[:space:]].*smtp[[:space:]]*$' ${MASTER}.proto; then + echo "In master.cf.proto:" + echo " restoring lmtp binary for lmtp service" + sed '/^lmtp[[:space:]]/s/smtp$/lmtp/' ${MASTER}.proto > ${MASTER}.proto.$$ + mv ${MASTER}.proto.$$ ${MASTER}.proto + fi + fi + fi +} + +add_root_alias() { + db_get postfix/root_address && root_addr="$RET" + ret=$(echo $RET | tr 'A-Z' 'a-z') + if [ "$ret" != "none" ] && [ -n "$ret" ] ; then + echo "adding root: $RET alias" + echo "root: $RET" >> /etc/aliases + fi +} + +umask 022 + +# postinst processing + +case "$1" in + configure) + OLDVERSION="$2" + # see below + ;; + + abort-upgrade) + fix_master "$2" + exit 0 + ;; + + abort-remove|abort-deconfigure) + exit 0 + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +CHANGES="" + +ldconfig + +dpkg-divert --package postfix --remove --rename \ + --divert /usr/share/man/man8/smtpd.real.8.gz \ + /usr/share/man/man8/smtpd.8.gz > /dev/null 2>&1 + +# handle sasl-smtp[d] -> smtp[d] change. oops.. +if [ -d /etc/postfix/sasl ]; then + cd /etc/postfix/sasl + for file in smtp smtpd; do + if [ -r sasl-${file}.conf ] && [ ! -r ${file}.conf ]; then + ln -s sasl-${file}.conf ${file}.conf + fi + done +fi + +cd ${CHROOT} +# make sure that the postfix user exists. Simplest portable way to check is to +# chown something, so we'll create the directories that we need here. +makedir private root:root 700 +chgrp postfix private 2>/dev/null || + addgroup --system postfix +chown postfix private 2>/dev/null || + adduser --system --home ${CHROOT} --no-create-home --disabled-password --ingroup postfix postfix + +# need to have postfix in the right group, but old revs do it wrong.. +if [ "$(id -gn postfix)" != "postfix" ]; then + usermod -g postfix postfix +fi + +chown postfix:root private + +db_fget postfix/chattr changed +if [ "$RET" = "true" ]; then + db_get postfix/chattr && chat="$RET" + echo "setting synchronous mail queue updates: $chat" + if [ "$chat" = "true" ]; then + chat="+S" + else + chat="-S" + fi +fi + +makedir pid root:root 755 +makedir public postfix:root 755 +for dir in incoming active bounce defer deferred flush saved corrupt; do + makedir ${dir} postfix:root 700 + if [ -n "$chat" ]; then + chattr $chat $dir 2>/dev/null || true + fi +done + +cd /etc/postfix + +if [ ! -f dynamicmaps.cf ]; then + echo "Creating /etc/postfix/dynamicmaps.cf" + while read row; do + # Keep the comment lines. + if [ "X${row#\#}" != "X${row}" ]; then + echo "$row" + else + # If the dictionary is on the system, add the row. Subsequent + # installs will add the record themselves. + dict=${row%%[[:space:]]*} + if test -e /usr/lib/postfix/postfix-${dict}.so; then + echo "$row" + fi + fi + done < /usr/share/postfix/dynamicmaps.cf > dynamicmaps.cf + chmod 644 dynamicmaps.cf +fi + +db_get postfix/main_mailer_type && mailer="$RET" + +[ -f master.cf ] || cp /usr/share/postfix/master.cf.dist master.cf + +if [ "$mailer" != "No configuration" ]; then # [ + if [ -f main.cf ]; then + NEWCONF="" + else + cp /usr/share/postfix/main.cf.debian main.cf + if [ -f /etc/ssl/private/ssl-cert-snakeoil.key ]; then + cat /usr/share/postfix/main.cf.tls >> main.cf + fi + postconf -e "smtpd_relay_restrictions=permit_mynetworks permit_sasl_authenticated defer_unauth_destination" + NEWCONF=yes + fi + + # This is the braindead local-only master.cf from elsewhen + # we now deal with this in main.cf, so mark the mailer_type changed. + md5sum=$(md5sum /etc/postfix/master.cf) + if [ "${md5sum%% *}" = "fadb677a071ea2851cc2b8a12345823d" ]; then + cp /usr/share/postfix/master.cf.dist master.cf + db_fset postfix/main_mailer_type changed true + fi +fi # !No configuration ] + +# cleanup from braindamage. +if [ -d /etc/postfix/maildrop ]; then + rmdir /etc/postfix/maildrop 2>/dev/null +fi + +set_maildrop_perms postdrop + +if [ "$mailer" != "No configuration" ]; then # [ + myhostname=$(myfqdn) + mydomain=${myhostname#*.} + + # Fix master.cf for compat changes in 3.0. See Debian bug #816172 + # Also fix myhostname if needed. + if `dpkg --compare-versions "$2" lt 3.1.0-1~`; then + for dir in /etc/postfix $(postconf -hxn multi_instance_directories); do + hname=$(postconf -hx -c "$dir" myhostname) + if [ "${hname}" = "${hname%.*}" ]; then + echo "setting myhostname=$myhostname in ${dir}" + set_postconf -c "$dir" myhostname=$myhostname + fi + SRV=$(postconf -c "$dir" -F '*/*/chroot'| sed -n '/ = -$/s/ =.*$//p') + for SERVICE in $SRV; do + echo "setting explicit chroot on ${dir}:$SERVICE" + set_postconf -F -c "$dir" $SERVICE=y + done + done + fi + if [ -n "$NEWCONF" ]; then + fset_all_changed true + alias_maps=hash:/etc/aliases + nis_status=$(dpkg -l nis 2>/dev/null | sed -n '$p') + if [ "X$nis_status" != "X${nis_status#i}" ] && [ -x /usr/bin/ypcat ] && + /usr/bin/ypcat mail.aliases >/dev/null 2>&1; then + alias_maps="hash:/etc/aliases, nis:mail.aliases" + cat << EOF +It appears that you have an NIS map for mail aliases; using that in +addition to /etc/aliases. + +EOF + fi + if [ -n "$myhostname" ]; then + echo "setting myhostname: $myhostname" + set_postconf "myhostname=$myhostname" + fi + echo "setting alias maps" + set_postconf "alias_maps=$alias_maps" + echo "setting alias database" + set_postconf "alias_database=hash:/etc/aliases" + else + if [ -f /var/spool/postfix/mydomain-upgrade ]; then + rm -f /var/spool/postfix/mydomain-upgrade + db_get postfix/mydomain_upgrade && upgrade="$RET" + if [ "$upgrade" = "true" ]; then + echo "setting mydomain=$mydomain" + set_postconf "mydomain=$mydomain" + fi + fi + fi + + db_fget postfix/mailname changed + if [ "$RET" = "true" ]; then + db_get postfix/mailname && mailname="$RET" + lcmailname="$(echo $RET| tr 'A-Z' 'a-z')" + if [ "X$lcmailname" = "X==default==" ]; then + mailname=$(hostname --fqdn 2>/dev/null || echo localdomain) + fi + lcmailname="$(echo $mailname| tr 'A-Z' 'a-z')" + if [ -f /etc/mailname ] && [ "X$(tr 'A-Z' 'a-z' < /etc/mailname)" = "X$lcmailname" ]; then + MAILNAME="" + else + MAILNAME=yes + fi + if [ "X${lcmailname}" = Xubuntu.com ] || [ "X${lcmailname}" = Xdebian.org ]; then + echo "refusing to set mailname to ${mailname}." + elif [ "X${mailname%.*}" != "X${mailname}" ]; then + if [ -n "$MAILNAME" ]; then + echo "changing /etc/mailname to $mailname" + echo $mailname > /etc/mailname + fi + echo "setting myorigin" + set_postconf "myorigin=/etc/mailname" + else + echo "mailname is not a fully qualified domain name. Not changing /etc/mailname." + fi + fi + db_fget postfix/destinations changed + if [ "$RET" = "true" ]; then + db_get postfix/destinations && destinations="$RET" + echo "setting destinations: $destinations" + set_postconf "mydestination=$destinations" + fi + db_fget postfix/relayhost changed + if [ "$RET" = "true" ]; then + db_get postfix/relayhost && relayhost="$RET" + echo "setting relayhost: $relayhost" + set_postconf "relayhost=$relayhost" + fi + db_fget postfix/mynetworks changed + if [ "$RET" = "true" ]; then + db_get postfix/mynetworks && mynetworks="$RET" + if [ -z "$RET" ]; then + echo "deleting mynetworks" + if grep -q '^mynetworks[[:space:]]*=' main.cf; then + # need to remove it, get postconf to do the hard part. + postconf -e 'mynetworks=127.0.0.0/8' + perl -i -ne 'print unless /^mynetworks\s*=/' main.cf + fi + else + echo "setting mynetworks: $mynetworks" + set_postconf "mynetworks=$mynetworks" + fi + fi + db_fget postfix/procmail changed + if [ "$RET" = "true" ]; then + db_get postfix/procmail && useprocmail="$RET" + if [ "x$useprocmail" = "xtrue" ]; then + echo "setting mailbox_command" + set_postconf 'mailbox_command=procmail -a "$EXTENSION"' + else + if grep -q ^mailbox_command /etc/postfix/main.cf; then + echo "clearing mailbox_command" + set_postconf "mailbox_command=" + fi + fi + fi + db_fget postfix/mailbox_limit changed + if [ "$RET" = "true" ]; then + db_get postfix/mailbox_limit && mailbox_limit="$RET" + echo "setting mailbox_size_limit: $mailbox_limit" + set_postconf "mailbox_size_limit=$mailbox_limit" + fi + + db_fget postfix/recipient_delim changed + if [ "$RET" = "true" ]; then + db_get postfix/recipient_delim && recip="$RET" + echo "setting recipient_delimiter: $recip" + set_postconf "recipient_delimiter=$recip" + fi + + db_fget postfix/main_mailer_type changed + if [ "$RET" = "true" ]; then + # If the user has picked something other than sntp, keep it + dtrans=$(postconf -hx default_transport) + if [ $(postconf -hx default_transport) = error ]; then + dtrans=smtp + fi + # already have mailer + case "$mailer" in + "Local only") val=loopback-only; dtrans=error;; + "Satellite system") val=loopback-only;; + *) val=all;; + esac + echo "setting inet_interfaces: $val" + set_postconf "inet_interfaces=$val" + + if [ $(postconf -hx default_transport) != $dtrans ]; then + echo "setting default_transport: $dtrans" + set_postconf "default_transport=$dtrans" + echo "setting relay_transport: $dtrans" + set_postconf "relay_transport=$dtrans" + fi + fi + + db_fget postfix/protocols changed + if [ "$RET" = "true" ]; then + db_get postfix/protocols && protocols="$RET" + echo "setting inet_protocols: $protocols" + set_postconf "inet_protocols=$protocols" + fi + + # 2.10 upgrade requires us to copy the smtpd_recipient_restrictions + # into smtpd_relay_restrictions Only present for upgrades from before + # 2.10.0-2 + if [ -f /var/spool/postfix/set_relay_restrictions ]; then + # early 2.10.0 was special... see #702374 + # if we got here with 2.10.0 in OLDVERSION, then there is no value for + # smtpd_relay_restrictions specified in main.cf, and + # smtpd_recipient_restrictions is either null (default for 2.10) or + # else it is some non-default value that we should copy to relay. + VALUE="$(postconf -hx smtpd_recipient_restrictions)" + if [ -z "$VALUE" ] && dpkg --compare-versions $OLDVERSION ge 2.10.0; then + # null, so use the correct default + VALUE="permit_mynetworks, reject_unauth_destination" + fi + echo "setting smtpd_relay_restrictions: $VALUE" + set_postconf "smtpd_relay_restrictions=$VALUE" + rm -f /var/spool/postfix/set_relay_restrictions + fi + + # Handle migrating daemon_directory, if present, and coming from before + # 3.0.4-5 + if [ -n "$OLDVERSION" ] && dpkg --compare-versions $OLDVERSION lt 3.0.4-5; then + for dir in /etc/postfix $(postconf -hxn multi_instance_directories); do + DD=$(postconf -c "$dir" -hxn daemon_directory) + if [ "X${DD}" = X/usr/lib/postfix ]; then + # The install was aborted in preinst if we didn't get + # permission to fix this. While we're here, also clean out + # specific setting of shlib_directory to the default. + echo "removing daemon_directory setting from ${dir}/main.cf" + sed -i '/^daemon_directory[[:space:]]*=/d' "${dir}/main.cf" + CHANGES=true + SD=$(postconf -c "$dir" -hxn shlib_directory) + if [ "X${SD}" = X/usr/lib/postfix ]; then + echo "removing shlib_directory setting from ${dir}/main.cf" + sed -i '/^shlib_directory[[:space:]]*=/d' "${dir}/main.cf" + fi + fi + done + fi + + if [ -z "$CHANGES" ]; then + MSG="configuration was not changed" + else if [ -n "$NEWCONF" ]; then + MSG="is now set up with a default configuration" + else + MSG="is now set up with the changes above" + fi + fi +else # ] No configuration [ + if [ -f main.cf ]; then + MSG="configuration was untouched" + else + MSG="was not set up. Start with + cp /usr/share/postfix/main.cf.debian /etc/postfix/main.cf +" + # make sure that we don't try anything stupid below. + db_fset postfix/newaliases run false + rm -f /var/spool/postfix/restart /var/spool/postfix/reload + fi +fi # not 'No configuration' ] + +if [ ! -f /etc/aliases ]; then # no /etc/aliases [ + echo "/etc/aliases does not exist, creating it." + cat << EOF > /etc/aliases +# See man 5 aliases for format +postmaster: root +EOF + if [ "$mailer" != "No configuration" ]; then # [ + db_fset postfix/newaliases run true + db_fget postfix/root_address changed + if [ "$RET" = "true" ]; then + add_root_alias + fi + fi # not 'No configuration' ] +fi # ] no /etc/aliases + +if [ "X$OLDVERSION" = "X" ]; then + # On fresh installs, push a root alias into the file. + if ! grep -q ^root: /etc/aliases && ! [ -f ~root/.forward ]; then + add_root_alias + db_fset postfix/newaliases run true + fi + # And update the doc dirs if postfix-doc is already unpacked + if [ -f /etc/postfix/main.cf ] && \ + [ -f /usr/share/doc/postfix-doc/changelog.Debian.gz ]; then + postconf -e readme_directory=/usr/share/doc/postfix \ + html_directory=/usr/share/doc/postfix/html + fi +fi + +db_fget postfix/root_address changed +if [ "$RET" = "true" ] && ! grep -q ^root: /etc/aliases; then + echo "WARNING: /etc/aliases exists, but does not have a root alias." +fi + +fset_all_changed false + +fix_master "$2" + +fold -s << EOF + +Postfix (main.cf) $MSG. If you need to make changes, edit /etc/postfix/main.cf (and others) as needed. To view Postfix configuration values, see postconf(1). + +After modifying main.cf, be sure to run 'systemctl reload postfix'. + +EOF + +# Fix old permissions +chown postfix:postfix /var/lib/postfix +if [ -f /var/lib/postfix/prng_exch ]; then + chown postfix:postfix /var/lib/postfix/prng_exch +fi + +if [ "X$OLDVERSION" = "X" ] && [ ! -f /etc/aliases.db ]; then + db_fset postfix/newaliases run true +fi + +if [ -x /usr/sbin/update-inetd ]; then + update-inetd --disable smtp </dev/null >/dev/null 2>&1 || true +fi + +# Make sure we have main/master.cf.proto for multi-inst (#838528) +if [ ! -f /etc/postfix/main.cf.proto ]; then + cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf.proto + rm -rf /etc/postfix/main.cf.proto.old +fi +if [ ! -f /etc/postfix/master.cf.proto ]; then + cp /usr/share/postfix/master.cf.dist /etc/postfix/master.cf.proto + rm -rf /etc/postfix/master.cf.proto.old +fi + +if [ "$mailer" != "No configuration" ] || [ -f /etc/postfix/main.cf ]; then + aliastype=$(postconf -h alias_database | cut -f1 -d:) + if ( [ "$aliastype" != "ldap" ] && [ "$aliastype" != "lmdb" ] && \ + [ "$aliastype" != "cdb" ] && [ "$aliastype" != "pcre" ] && \ + [ "$aliastype" != "mysql" ] && [ "$aliastype" != "pgsql" ] && \ + [ "$aliastype" != "sqlite" ] ) ; then + runnewaliases + else + echo "Newaliases not run - external map type. Ensure postfix-$aliastype is installed." + fi + + [ -x /usr/sbin/invoke-rc.d ] && \ + INIT="invoke-rc.d postfix" || \ + INIT="/etc/init.d/postfix" + # start postfix + if [ -f /var/spool/postfix/restart ]; then + rm -f /var/spool/postfix/restart + ${INIT} restart + else + # or maybe just restart postfix + if [ -f /var/spool/postfix/reload ]; then + rm -f /var/spool/postfix/reload + ${INIT} restart + fi + fi +fi + +# all done with debconf here. +db_stop + +#DEBHELPER# + +# we want it out of /etc to not be a conffile, but users might expect it there +# so leave a symlink at the expected place in /etc +if [ -f "/usr/share/postfix/makedefs.out" ]; then + if [ ! -e "/etc/postfix/makedefs.out" ]; then + ln -s /usr/share/postfix/makedefs.out /etc/postfix/makedefs.out + fi +fi |