Hi,
  Attached is my first attempt at authldap, which currently works for our
site. It takes a simple username/password combination. The search filter
is currently fixed at cn=<username>, but this could easily be made
configurable. Once it has found the dn for that particular user, it
authenticates. Enjoy.
  It seems that cram-md5 requires that the client has a plaintext copy of
the real password. Am I correct? If so then authldap could never provide
cram-md5 support?
  Cheers.

-- 
Mark Powell - UNIX System Administrator - The University of Salford
Information Services Division, Clifford Whitworth Building,
Salford University, Manchester, M5 4WT, UK.
Tel: +44 161 295 4837  Fax: +44 161 295 5888  www.pgp.com for PGP key
use Net::LDAP;
use Qpsmtpd::Constants;
use Digest::HMAC_MD5 qw(hmac_md5_hex);

sub register {
  my ( $self, $qp ) = @_;

  $self->register_hook('auth-plain', 'authldap');
  $self->register_hook('auth-login', 'authldap');
#  $self->register_hook('auth-cram-md5', 'authldap');
}

sub authldap {
  my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket ) = @_;
  my $ldap_host = 'ldap.example.org';
  my $basedn    = 'o=Example Inc.';

  $self->log(LOGDEBUG, "method = $method user =", $user || '', "passClear =", 
$passClear || '', "passHash =", $passHash || '', "ticket =", $ticket || '');
  if (!defined $user || $user eq '' || !defined $passClear || $passClear eq '') {
    $self->log(LOGDEBUG, "username or password missing");
    return(DENY, "authldap/$method - wrong password");
  }

  my $ldap = Net::LDAP->new($ldap_host) or $self->log(LOGINFO, "connect to ldap server 
failed: $@"), return(DENY, "authldap/$method - wrong password");
  my $mesg = $ldap->bind;
  $mesg = $ldap->search(base => $basedn, filter => "cn=$user", typesonly => 1);
  my @entries = $mesg->entries;
  if ($#entries) {
    $self->log(LOGDEBUG, "search for cn=$user failed");
    return(DENY, "authldap/$method - wrong password");
  }
  my $dn = $entries[0]->dn;
  $self->log(LOGDEBUG, "found dn = $dn\n");
  $mesg = $ldap->bind($dn, password => $passClear);

  if ($mesg->code) {
    return(DENY, "authldap/$method - wrong password");
  } else {
    $ENV{RELAYCLIENT} = '';
    return(OK, "authldap/$method");
  }
}

Reply via email to