#!/usr/bin/perl
## This is an example of an 'auth-check' trigger used by Perforce (2005.2) to
## authenticate a user against an LDAP server.
##
## This example uses challenge response CRAM-MD5 for authentication and
## has been tested against openldap (open directory) on Mac OSX Tiger.
##
## The password is sent to this triggers <stdin> with an argument list of
## host (hostname of ldap server), port (port of ldap server), user, dn
##
## e.g. ldap.mycompany.com 389 joeb uid=joeb,cn=users,dc=mycompany,dc=com
##
## The Perforce trigger definition would looks something like this:-
##
## example auth-check auth /scripts/checkpass localhost 389 %user% uid=%user%,cn
## =users,dc=wombat,dc=perforce,dc=com"
##
use strict;
use Net::LDAP;
use Authen::SASL;
## Perforce requires messages on stdout
##
open(STDERR, ">&STDOUT") or die "Can't dup stdout";
## check argument count
##
my $argc = scalar(@ARGV);
if( $argc != 4 ) {
die "wrong number of arguments!\n";
}
## assign arguments
##
my $host = shift @ARGV;
my $port = shift @ARGV;
my $user = shift @ARGV;
my $dn = shift @ARGV;
## read the password from <stdin> and truncate the newline
##
my $password = <STDIN>;
$password =~ s/\n//;
## make a standard non-encrypted connection to LDAP
##
my $ldap = Net::LDAP->new( $host, port => $port ) or die "$@";
## authenticate using cram-md5 (challenge response)
##
my $sasl = Authen::SASL->new( mechanism => 'CRAM-MD5',
password => $password,
user => $user );
## bind
##
my $result = $ldap->bind( dn => $dn, sasl => $sasl, version => 3 ) or die "$@";
## check result, report errors
##
if( $result->code ){
die "LDAP bind failure!\n";
}