Package: pure-ftpd
Version: 1.0.21-11.4
Severity: wishlist
Tags: patch

I needed to enable the external authentication daemon pure-authd.

Found out about /etc/pure-ftpd/conf/ExtAuth, but the FTP daemon would not
start, because the socket (which gets created by pure-authd) was missing.

It seemed illogical to create another init script, since the upload handler
is already started from the pure-ftpd init script. The auth daemon has to be
started before pure-ftpd because it needs to create the authentication
socket first (configured in ExtAuth, but in my opinion it should be static,
the ExtAuth value changed to boolean, like CallUploadScript[B)

I'm attaching the diff from the old init script (I did this on Lenny, but I
checked the sid init script and it doesn't seem like anything changed).

I'm also attaching an example python external authentication script which
could be a little more polished, but it was just a proof of concept for me.
If you're interested in including it, I'm willing to spruce it up a little.

There are also a few new variables to be set in
/etc/default/pure-ftpd-common:

AUTHDSCRIPT=/path/to/authhandler[B
AUTHDUID=
AUTHDGID=

in line with the variables used for upload handler.




-- System Information:
Debian Release: 5.0.8
  APT prefers oldstable
  APT policy: (500, 'oldstable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-2-xen-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages pure-ftpd depends on:
ii  libc6                  2.7-18lenny7      GNU C Library: Shared libraries
ii  libcap1                1:1.10-14         support for getting/setting POSIX.
ii  libpam0g               1.0.1-5+lenny1    Pluggable Authentication Modules l
ii  libssl0.9.8            0.9.8g-15+lenny11 SSL shared libraries
ii  pure-ftpd-common       1.0.21-11.4       Pure-FTPd FTP server (Common Files

pure-ftpd recommends no packages.

pure-ftpd suggests no packages.

-- no debconf information
#!/usr/bin/python
"""
pure-authd authentication handler

Checks for username/password files on the filesystem which allow chrooted FTP 
access to a directory.
"""

import sys
import os
from os import environ as env
from syslog import *

# Requires getent - hg clone https://bitbucket.org/maze/getent
import getent

openlog('pure-authhandler.py[%s]' % os.getpid(),LOG_INFO,LOG_DAEMON)
syslog('starting operation.')

try:
        AUTHD_ACCOUNT = env['AUTHD_ACCOUNT']
        AUTHD_PASSWORD = env['AUTHD_PASSWORD']
        AUTHD_LOCAL_IP = env['AUTHD_LOCAL_IP']
        AUTHD_LOCAL_PORT = env['AUTHD_LOCAL_PORT']
        AUTHD_REMOTE_IP = env['AUTHD_REMOTE_IP']
except KeyError, e:
        syslog('Parameter error: missing environment variable %s' % e)
        print "auth_ok:0\nend"
        sys.exit(1)

# Split the username on @
try:
        (subuser,sysuser) = AUTHD_ACCOUNT.split('@')
except ValueError, e:
        syslog('username %s not in subuser@systemuser format: %s' % 
(AUTHD_ACCOUNT, e))
        print "auth_ok:0\nend"
        sys.exit(0)

try:
        website = getent.passwd(sysuser)
        if not website:
                syslog('user/website %s does not exist' % sysuser)
                print "auth_ok:0\nend"
                sys.exit(0)

        if website.uid < 1000:
                syslog('uid of user %s is less than 1000 (%s), denied' % 
(sysuser, website.uid) )
                print "auth_ok:-1\nend"
                sys.exit(0)
        
        subdir = website.dir + '/FTP/' + subuser
        subpassfile = subdir + '.passwd'
        if os.path.isdir(subdir) and os.path.isfile(subpassfile):
                passfile = open(subpassfile)
                password = passfile.readline().rstrip()
                
                if password != AUTHD_PASSWORD:
                        #syslog('Password for user %s does not match: is %s, 
should be %s' % (AUTHD_ACCOUNT,password,AUTHD_PASSWORD) )
                        syslog('Authentication failure for user %s: wrong 
password' % AUTHD_ACCOUNT )
                        print "auth_ok:-1\nend"
                        sys.exit(0)
                else:
                        syslog('User %s successfully authenticated' % 
AUTHD_ACCOUNT)
                        print "auth_ok:1\nuid:%s\ngid:%s\ndir:%s\nend" % 
(website.uid,website.gid,subdir+'/./')
                        sys.exit(0)
        else:
                syslog('subuser %s does not exist' % AUTHD_ACCOUNT)
                print "auth_ok:0\nend"
                sys.exit(0)
except Exception, e:
        syslog('Exception checking credentials: %s' % e)
        print "auth_ok:0\nend"
        sys.exit(0)

--- /etc/init.d/pure-ftpd.ORIG  2011-03-25 13:59:43.000000000 +0100
+++ /etc/init.d/pure-ftpd       2011-03-25 14:21:04.000000000 +0100
@@ -18,6 +18,10 @@
 UDDESC="ftp upload handler"
 WRAPPER=/usr/sbin/pure-ftpd-wrapper
 
+AUTHDAEMON=/usr/sbin/pure-authd
+ADNAME=pure-authd
+ADDESC="external authentication daemon"
+
 # try to figure with suffix this script is called,
 # $0 might be a symlink pointing to this script
 if [ -h $0 ]; then
@@ -65,9 +69,23 @@
        fi
 }
 
+start_authd() {
+       if [ -x "$AUTHDSCRIPT" -a "$STANDALONE_OR_INETD" != inetd ]
+       then
+               AOPTS=""
+               test "$AUTHDUID" && AOPTS="$UOPTS -u $AUTHDUID"
+               test "$AUTHDGID" && AOPTS="$UOPTS -u $AUTHDGID"
+               echo -n "$1 $ADDESC: "
+               start-stop-daemon --start $SSDAEMONLOGOPTS --oknodo \
+                       --exec $AUTHDAEMON -- -r "$AUTHDSCRIPT" -B -s `head -1 
/etc/pure-ftpd/conf/ExtAuth` $AOPTS
+               echo "$ADNAME."
+       fi
+}
+
 case "$1" in
   start)
        test "$STANDALONE_OR_INETD" = standalone || exit 0
+       start_authd Starting
        echo -n "Starting $DESC: "
        start-stop-daemon --start $SSDAEMONLOGOPTS --pidfile 
/var/run/pure-ftpd/pure-ftpd.pid \
                --exec $WRAPPER -- $SUFFIX
@@ -78,6 +96,7 @@
        start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo \
                --pidfile /var/run/pure-ftpd/pure-ftpd.pid
        start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo --exec $UPLOADDAEMON
+       start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo --exec $AUTHDAEMON
        echo "$NAME."
        ;;
   restart|force-reload)
@@ -86,10 +105,12 @@
        start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo \
                --pidfile /var/run/pure-ftpd/pure-ftpd.pid
        start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo --exec $UPLOADDAEMON
+       start-stop-daemon --stop $SSDAEMONLOGOPTS --oknodo --exec $AUTHDAEMON
        sleep 1
        start-stop-daemon --start $SSDAEMONLOGOPTS --pidfile \
                /var/run/pure-ftpd/pure-ftpd.pid --exec $WRAPPER -- $SUFFIX
        start_uploadscript Restarting
+       start_authd Restarting
        ;;
   *)
        N=/etc/init.d/$NAME

Reply via email to