3

I could use help with adapting the standard courier-authdaemon initscript.

I run a small business server with postfix, courier, mariadb, amavisd-new with clamav and spamassassin and sasl. After the upgrade to xenial I had problems because the setup refused to authenticate sasl as before. I learnt googling around that this was the result of a seriously broken libpam-mysql in xenial. Fortunately it is possible to authenticate against couriers authentication routines in courier-authdaemon, so I changed my postfix smtpd.conf to point to that. The courier-authdaemon is controlled by an initscript (in /et/init.d) as follows:

#! /bin/sh -e
#
### BEGIN INIT INFO
# Provides:          courier-authdaemon
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

prefix="/usr"
exec_prefix=${prefix}
sysconfdir="/etc/courier"
sbindir="${exec_prefix}/sbin"
daemonscript="${sbindir}/authdaemond"
rundir_courier="/var/run/courier"
rundir="/var/run/courier/authdaemon"
pidfile="${rundir}/pid"

. /lib/lsb/init-functions

# Check for a leftover init script
if [ ! -x $daemonscript ]; then
    exit 0
fi

case "$1" in
start)
    # Start daemon.
    cd /
    log_daemon_msg "Starting Courier authentication services" "authdaemond"
    if [ ! -d "$rundir_courier" ]; then
        mkdir -m 0775 $rundir_courier
        chown daemon:daemon $rundir_courier
        # set file context for SELinux (#668564)
        [ -x /sbin/restorecon ] && /sbin/restorecon $rundir_courier
    fi
    if [ ! -d "$rundir" ]; then
        mkdir -m 0750 $rundir 
        chown daemon:daemon $rundir
        # set file context for SELinux (#668564)
        [ -x /sbin/restorecon ] && /sbin/restorecon $rundir
    fi
    $daemonscript start
    log_end_msg 0
    ;;
stop)
    # Stop daemon.
    cd /
    log_daemon_msg "Stopping Courier authentication services" "authdaemond"
    $daemonscript stop
    log_end_msg 0
    ;;
restart|force-reload)
    $0 stop
    $0 start
    ;;
status)
    status_of_proc -p "$pidfile" "" "authdaemond" && exit 0 || exit $?
    ;;
*)
    echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
    exit 2
    ;;
esac
exit 0

Next issue: I have postfix running in a chroot jail, which cannot access the standard courier-authdaemon socket. So I found this:

service courier-authdaemon stop
rm -rf /var/run/courier/authdaemon/ /var/spool/postfix/var/run/courier/authdaemon/
mkdir -p /var/spool/postfix/var/run/courier/authdaemon/
ln -s /var/spool/postfix/var/run/courier/authdaemon/ /var/run/courier/authdaemon
service courier-authdaemon start
postfix reload

Which basically stops the authentication daemon, removes the old stuff in both the current directory and the one in the postfix chroot jail and then sets them up again and sets the link from outside to inside the chroot jail and starts everything back up again. Which works. What it doesn't do, is make these changes permanent, because after a reboot (or an update/upgrade of courier) courier sets everything up anew, so I have to redo the above fix.

So obviously I was trying to find out whether someone would have found something to apply the fix at bootup. Turns out there was somebody, and he rewrote the authdaemon initscript as follows

! /bin/sh -e
#
### BEGIN INIT INFO
# Provides:          courier-authdaemon
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

prefix="/usr"
exec_prefix=${prefix}
sysconfdir="/etc/courier"
sbindir="${exec_prefix}/sbin"
daemonscript="${sbindir}/authdaemond"
rundir_courier="/var/run/courier"
rundir="/var/run/courier/authdaemon"
pidfile="${rundir}/pid"

. /lib/lsb/init-functions

# Check for a leftover init script
if [ ! -x $daemonscript ]; then
    exit 0
fi

#== Postfix chrooted ==#+20131117 <GB@Nline.it>
postfix_check() {
  local PFINIT=/etc/init.d/postfix
  local PFMASTER=/etc/postfix/master.cf
  local PFSMTPD=/etc/postfix/sasl/smtpd.conf

  if [ -s $PFINIT ] && [ -s $PFMASTER ] ; then
    # Use Postfix
    if [ "$(/usr/bin/awk '$1~/^smtp$/ && $8~/smtpd/ {print $5}
             ' $PFMASTER)0" != "n0" ]
    then # chroot: Yes
      if [ -s $PFSMTPD ] && [ "0$(/bin/sed -n \
-e '/^authdaemond_path:/s,.\+:\s*,,p' $PFSMTPD)" = "0$rundir/socket" ] &&
         [ ! -L $rundir ]
      then
        /bin/rm -fr $rundir &&
        /bin/ln -s /var/spool/postfix/$rundir $rundir_courier
      fi
    else # chroot: No
      if [ -L $rundir ] ;then
        /bin/rm -fr $rundir
      fi
    fi # Postfix chrooted ?
  fi # Use Postfix
} # postfix_check()
#-- Postfix chrooted --#

case "$1" in
start)
    # Start daemon.
    cd /
    log_daemon_msg "Starting Courier authentication services" "authdaemond"
    if [ ! -d "$rundir_courier" ]; then
        mkdir -m 0775 $rundir_courier
        chown daemon:daemon $rundir_courier
        # set file context for SELinux (#668564)
        [ -x /sbin/restorecon ] && /sbin/restorecon $rundir_courier
    fi
postfix_check
    if [ ! -d "$rundir" ]; then
        mkdir -m 0750 $rundir 
        chown daemon:daemon $rundir
        # set file context for SELinux (#668564)
        [ -x /sbin/restorecon ] && /sbin/restorecon $rundir
    fi
    $daemonscript start
    log_end_msg 0
    ;;
stop)
    # Stop daemon.
    cd /
    log_daemon_msg "Stopping Courier authentication services" "authdaemond"
    $daemonscript stop
    log_end_msg 0
    ;;
restart|force-reload)
    $0 stop
    $0 start
    ;;
status)
    status_of_proc -p "$pidfile" "" "authdaemond" && exit 0 || exit $?
    ;;
*)
    echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
    exit 2
    ;;
esac
exit 0

The problem is: it doesn't seem to work, and my skills at regular expressions are not such that I can debug this. I have a suspicion it has to do with file locations, but I'm not sure. Is there anyone who can point me in the right direction so I don't have to remember to apply the commands after a reboot?

1 Answers1

1

The problem is that Xenial 16.04 has broken sasl PAM AND switched to systemd startup. The init.d script you edited for courier-authdaemon to run chrooted is never run. I found that out the hard way.

I now run a similar set up to you (postfix chrooted plus authentication against courier, whilst previously I used SASL PAM on 14.04 Trusty).

Here's my current setup:

  • configure to authenticate against courier

vi /etc/postfix/sasl/smtpd.conf

#pwcheck_method: saslauthd
#mech_list: plain login
#allow_plaintext: true
pwcheck_method: authdaemond
authdaemond_path: /var/run/courier/authdaemon/socket
mech_list: plain login
log_level: 9
  • create a start up script to create the chroot dir and symlinks

vi /etc/systemd/system/courier-authdaemon.sh

#! /bin/sh -e
#
# Starts:          courier-authdaemon

prefix="/usr"
exec_prefix=${prefix}
sysconfdir="/etc/courier"
sbindir="${exec_prefix}/sbin"
daemonscript="${sbindir}/authdaemond"
rundir_courier="/var/run/courier"
rundir="/var/run/courier/authdaemon"
rundir_chroot="/var/spool/postfix/var/run/courier/authdaemon"
pidfile="${rundir}/pid"
/bin/echo "Checkpoint 1 Courier authentication services" "authdaemond" >/log.txt

# Check for a leftover init script
if [ ! -x $daemonscript ]; then
        exit 0
fi
/bin/echo "Checkpoint 2 Courier authentication services" "authdaemond" >>/log.txt

        # Start daemon.
        cd /
        /bin/echo "Starting Courier authentication services" "authdaemond" >>/log.txt
        # RAH 20170123. Change to chroot postfix setup
        if [ ! -d "$rundir_courier" ]; then
                /bin/echo  "making parent location" "authdaemond" >>/log.txt
                /bin/mkdir -m 0775 $rundir_courier
                /bin/chown daemon:daemon $rundir_courier
        # set file context for SELinux (#668564)
        [ -x /sbin/restorecon ] && /sbin/restorecon $rundir_courier
        fi
        # clean up chroot location
        if [ -d "$rundir_chroot" ]; then
                /bin/echo  "Cleaning chroot location" "authdaemond" >>/log.txt
                /bin/rm -rf "$rundir_chroot"
        fi
        # remove traditional directory if it exists
        if [ -L "$rundir" ]; then
                /bin/echo  "Unlinking traditional location" "authdaemond" >>/log.txt
                /usr/bin/unlink "$rundir"
        fi
        if [ -d "$rundir" ]; then
                /bin/echo  "Cleaning traditional location" "authdaemond" >>/log.txt
                /bin/rm -rf "$rundir"
        fi
        # make new chroot location
        if [ ! -d "$rundir_chroot" ]; then
                /bin/echo  "making chroot location" "authdaemond" >>/log.txt
                /bin/mkdir -p "$rundir_chroot"
                # /bin/echo mkdir -p "$rundir_chroot"
                /bin/chown daemon:daemon "$rundir_chroot"
                [ -x /sbin/restorecon ] && /sbin/restorecon $rundir_chroot
        fi
        # link chroot location to the original location
        if [ ! -L "$rundir" ]; then
                /bin/echo  "linking chroot location" "authdaemond" >>/log.txt
                /bin/ln -sn "$rundir_chroot" "$rundir"
                # /bin/echo /bin/ln -sfn "$rundir_chroot" "$rundir"
        fi
#       $daemonscript start

exit 0
  • create an override for the startup via systemd

    sudo systemctl edit courier-authdaemon
    
  • edit contents of the systemd override to trigger the shell script above:

    $ more /etc/systemd/system/courier-authdaemon.service.d/override.conf

    [Service]
    ExecStartPre=/etc/systemd/system/courier-authdaemon.sh
    
Zanna
  • 70,465
RayH
  • 11
  • Really sorry I didn't respond earlier, they've been keeping me busy. I went over this a couple of times and I see that I have to get to learn about systemd. As you noticed quite correctly, I should have realised it was one of the big changes from 14.04. – martin lentink Feb 22 '17 at 16:31
  • I went over your courier-authdaemon.sh a couple of times to make sure I understand verything that's being done in it. The one thing I noticed, is that you make the new directory owned by daemon:daemon. Since I perform the individual steps by hand after a reboot at the moment, the new linked rundir is owned by root:root. Will this present a problem? I don't think so as the script runs with root priviliges before it changes ownership to daemon, but I just would like to be sure.

    Anyhow, thanks for helping out and teaching me a couple of things, I really appreciate it!

    – martin lentink Feb 22 '17 at 16:49
  • I did "sudo systemctl edit courier-authdaemon" but this does not create /etc/systemd/system/courier-authdaemon.service.d/override.conf What am i doing wrong? – martin lentink Feb 23 '17 at 18:44
  • root:root shouldn't be a problem. I was just following a recipe. If it fails then you can always alter it and reboot to test. As for systemctl I have no clue. Did it start up a nano editor? Did you save the modified file? See http://askubuntu.com/questions/659267/how-do-i-override-or-configure-systemd-services for details that I followed. – RayH Feb 24 '17 at 07:17