#!/bin/sh set -e # Debian Postfix postinst # LaMont Jones # Based on debconf code by Colin Walters , # and John Goerzen . # Use debconf. . /usr/share/debconf/confmodule CHROOT=/var/spool/postfix . /usr/share/postfix/postinst.functions set_maildrop_perms() { MAILDROP=${CHROOT}/maildrop POSTDROP=/usr/sbin/postdrop mkdir -pZ $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 command -v restorecon >/dev/null; then restorecon "$POSTDROP" /var/spool/postfix/public /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 -Z "$1" 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 } 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="" 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 # cleanup old ca-certificates.crt that should never have been in chroot #991609 # can be removed after bookworm release ca_bundle=/var/spool/postfix/etc/ssl/certs/ca-certificates.crt if [ -f $ca_bundle ]; then echo Removing unneeded chroot file $ca_bundle rm -f $ca_bundle fi set_maildrop_perms postdrop if [ "$mailer" != "No configuration" ]; then # [ myhostname=$(myfqdn) mydomain=${myhostname#*.} 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' sed -i -e '/^mynetworks\s*=/d' 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 smtp, 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 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 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 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