#!/usr/bin/perl -w # # oraclevmail: # tpop3d auth-perl script to authenticate users against an Oracle database. # # The relevant tpop3d.conf lines are-- # # auth-perl-enable: yes # auth-perl-start: do '/etc/tpop3d/tpop3d.pl' # auth-perl-finish: auth_finish() # auth-perl-pass: auth # # The database schema in use should be fairly self-evident, and is similar to # that used by vmail-sql. # # (The #! line is for testing on the command line.) # # Copyright (c) 2001 Paul Makepeace (realprogrammers.com). # All rights reserved. # # $Id: oraclevmail,v 1.2 2001/07/22 00:32:04 chris Exp $ # use strict; use Data::Dumper; use DBI; use Digest::MD5; warn scalar(localtime), ": Perl started...\n"; my @DSN = qw(dbi:Oracle:vmail postmaster postmaster); my $dbh = DBI->connect(@DSN) or die "Unable to connect to DSN '@DSN': ", DBI->errstr, "\n"; # These keys are named based on the authentication method # passwd into auth() below by auth_perl.c my %sql = ( PASS => < <prepare($sql{$auth_type}) or die "Unable to prepare SQL '$sql{$auth_type}': ", DBI->errstr, "\n"; } ### END of start-up code # auth($) # Called by tpop3d with a hashref containing keys: # { method => (PASS, APOP), user => 'user@domain.example', pass => # 'letmein' } # Returns hashref with { result => YES, ... } for a successful # authentication # match or { result => NO } sub auth { my $packet = shift; my ($local_part, $domain) = $packet->{user} =~ /(.*?)\@(.*)/; my $passwd = $packet->{pass}; warn Dumper([$packet]), "\n"; my $sth = $sth{$packet->{method}}; $sth ->execute($local_part, $domain) or die "Couldn't execute $sql{$packet}: ", DBI->errstr, "\n"; my ($path, $password_hash, $mbox_name, $mbox_driver, $unix_user) = $sth->fetchrow_array; if (Digest::MD5::md5_hex($passwd) eq $password_hash) { $packet = { result => 'YES', uid => (getpwnam($unix_user))[2], gid => (getgrnam($unix_user))[2], mailbox => "$path/$mbox_name", mboxtype=> $mbox_driver, domain => $domain, } } else { $packet = { result => 'NO' }; }; warn Dumper([$packet]), "\n"; $packet; } # auth_finish(): # Clean up statement handles and then disconnect sub auth_finish { $_->finish for values %sth; $dbh->disconnect(); }