OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Meng Weng Wong (mengwongdumbo.pobox.com)
Date: Mon Oct 01 2001 - 23:13:20 CDT

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    On Mon, Oct 01, 2001 at 10:22:09PM +0000, Ralf Hildebrandt wrote:
    | > 1-A MySQL database with username:password:group etc... (done)
    | > 2-Postfix (pop3 actually) authenticating users from there too, so they can
    | > check (and send) their email stored in /var/spool/ but without using system
    | > passwd+shadow and therefore there will be no need to create a user in the
    | > system for mail accounts. (not a clue, any suggestions?)
    |
    | Use courier-IMAP with PAM authentication.

    and if you want sasl support for postfix smtp, one
    alternative to patching mysql support into sasl
    (http://freshmeat.net/projects/cyrus-sasl-mysqlpatch/
     http://www.dmzs.com/~dmz/projects/cyrus-sasl-mysql/)
    is to just use the pwcheck backend, with a custom pwcheckd
    that talks to mysql.

    here's a custom pwcheckd that talks to mysql.

    #!/usr/bin/perl -sw-

    # ----------------------------------------------------------
    # mypwcheckd
    #
    # Meng Weng Wong
    # $Id: mypwcheckd,v 1.2 2001/08/17 05:26:57 devel Exp $
    #
    # usage: run mypwcheckd at boot
    #
    # input: accepts unix domain socket connections in /var/pwcheck/pwcheck
    #
    # output: returns OK or NO based on the user/pass provided.
    #
    # license: GPL
    #
    # example:
    # new connection 1!
    # 1: received username tester, password foo
    # 1: sent OK
    # new connection 2!
    # 2: received username tester, password foo
    # 2: sent OK
    # new connection 3!
    # 3: received username exampleuser, password bar
    # 3: sent NO
    # ----------------------------------------------------------

    # ----------------------------------------------------------
    # initialization
    # ----------------------------------------------------------

    my $SOCKFILE = "/var/pwcheck/pwcheck";

    my $MYSQL_HOST = "localhost";
    my $MYSQL_DB = "mail";
    my $MYSQL_TABLE = "smtp_auth";
    my $MYSQL_USER = "xxx";
    my $MYSQL_PASS = "yyy";

    my $MYSQL_USERCOL = "alias";
    my $MYSQL_CRYPTPW = undef;

    my $PIDFILE = "/var/run/mypwcheckd.pid";

    # ----------------------------------------------------------
    # no user-serviceable parts below this line
    # ----------------------------------------------------------

    use strict;
    use IO::Socket;
    use DBI;

    # ----------------------------------------------------------
    # authentication routine
    # ----------------------------------------------------------

    sub auth_mysql {
        my ($username, $password) = _;

        my $DBH = DBI->connect("DBI:mysql:database=$MYSQL_DB;hostname=$MYSQL_HOST",
                               $MYSQL_USER,
                               $MYSQL_PASS);
        if (not $DBH) {
            #
            # mengwong 20010813: TODO: log warning to syslog
            #

            # default to OK in case we can't reach the database.
            return "OK: couldn't connect to database: $DBI::errstr";
        }

        my $MYSQL_GETUSER = $DBH->prepare("SELECT * FROM $MYSQL_TABLE WHERE $MYSQL_USERCOL = ?");

        $MYSQL_GETUSER->execute($username);

        my %result = %{$MYSQL_GETUSER->fetchrow_hashref() || {}};

        $MYSQL_GETUSER->finish();
        $DBH->disconnect();

        if (not keys %result) { return "user unknown"; }

        # by default, if the password is NULL, return OK
        if (not defined($result{'password'})) { return "OK: user found but password not defined on SASL server"; }

        if (uc $result{'auth'} ne "OK") { return $result{'auth'} }

        if (crypt($password, $result{'password'})
            eq $result{'password'}) { return "OK: password matched" }
        else { return "incorrect password" }

        return "OK by default";
    }

    # ----------------------------------------------------------
    # main
    # ----------------------------------------------------------

    &exit_if_already_running;
    $SIG{'HUP'} = \&restart;

    unlink $SOCKFILE;
    my $sock = IO::Socket::UNIX->new(Local=>$SOCKFILE, Listen=>4, Type=>SOCK_STREAM) or die "mypwcheckd: unable to create socket $SOCKFILE: $!";

    chmod(01777, $SOCKFILE);

    $SIG{CHLD} = 'IGNORE';

    my $connid;

    while (my $conn = $sock->accept) {
        $connid++;
        if (fork) { $conn->close(); next };

        print "new connection $connid!\n";

        my $request; my $c; while ($conn->recv($c, 1024)) { $request .= $c; last if $request =~ /^.*\0.*\0$/; }

        my ($username, $password) = split(/\0/, $request);
        print " $connid: received username $username, password XXXX\n";

        my $response = auth_mysql($username, $password);

        print " $connid: sending response $response\n";
        $conn->send($response . "\0");
        $conn->flush();
        $conn->close();
        exit;
    }

    sub exit_if_already_running {
        my $writepid = 1;
        if (open (PIDFILE, $PIDFILE)) {
            my ($pid) = <PIDFILE>;
            chomp $pid;

            if ($pid =~ /\d+/) {
                if ($pid == $$) { $writepid = 0; }
                elsif (kill (0, $pid) == 1) {
                    print "mypwcheckd: another instance is already running at pid $pid. perhaps you meant to kill -HUP $pid\n";
                    exit (1);
                }
            }
        }

        if ($writepid) {
            open (PIDFILE, ">$PIDFILE") or warn "unable to open $PIDFILE for writing: $!\n";
            print PIDFILE "$$\n";
            print PIDFILE "# started at " . scalar(localtime()) . "\n";
            close PIDFILE;
        }
        else {
            open (PIDFILE, ">>$PIDFILE") or warn "unable to open $PIDFILE for appending: $!\n";
            print PIDFILE "# restarted at " . scalar(localtime()) . "\n";
            close PIDFILE;
        }
    }

    sub restart {
        exec($0);
    }

    -
    To unsubscribe, send mail to majordomopostfix.org with content
    (not subject): unsubscribe postfix-users