I am attempting to use Net::LDAP to authenticate requests to MS Active
Directory, and at first glance to below code works fine. We find however
that if you specify a valid username in any container with ANY non-blank
password you get authenticated. A username that does not exist or using
a blank password will not authenticate though. Anyone see anything in
this code that would cause the Perl module for LDAP to NOT return an 
 error code when authentication fails. Or is it my directory which is
allowing a bind with an incorrect password???

Any thoughts appreciated!

Regards,

Edward Brookhouse
[EMAIL PROTECTED]



#!/usr/bin/perl -w
 
use Net::LDAP;


use CLI;

#my $LDAPServerAddress =  '172.19.1.10';   # You should redefine these
values
#my $LDAPServerAddress2 = '172.17.17.110';

my @LDAPServerAddress = [ '172.17.17.110', '172.19.1.10' ];



my $LDAPAdminDN =
'CN=administrator,CN=users,DC=corp,DC=phillips,DC=com';
my $LDAPAdminPassword = 'passwd';
my $LDAPSearchBase = 'DC=CORP,DC=PHILLIPS,DC=com';

my $CGServerAddress =  '172.17.17.73';   # You should redefine these
values
my $CLILogin = 'postmaster';
my $CLIPassword = 'passwd';


$| = 1;     #force STDOUT autoflush after each write

   
while(<STDIN>) {
  chomp;    # remove \n from the end of line
  my ($prefix,$method,@eargs) = split(/ /);

  if($method eq 'VRFY') {
    unless($prefix && $method && $eargs[0] && $eargs[1]) {  
      print "$prefix ERROR Expected: nnn VRFY [EMAIL PROTECTED] password\n";

    } else {
      if($eargs[0] =~ /^\(.*\)$/) {
        shift @eargs;  
      }
      my $errorMsg=checkPassword($eargs[0],$eargs[1]);   
      if(defined $errorMsg) {
        print "$prefix ERROR $errorMsg\n";
      } else {
        print "$prefix OK\n";
      }
    }    
  } elsif($method eq 'NEW') {
    unless($prefix && $method && $eargs[0]) {  
      print "$prefix ERROR Expected: nnn NEW [EMAIL PROTECTED]";    
    } else {
      my $errorMsg=new_command($eargs[0]);
      if(defined $errorMsg) {
        print "$prefix ERROR $errorMsg\n";
      } else {
        print "$prefix OK\n";
      }    
    }
  } else {
    print "$prefix ERROR Only VRFY and NEW commands supported\n";    
  }   
}


sub checkPassword {
  my ($user,$password)[EMAIL PROTECTED];


  my ($name,$domain)=("",""); 
  if($user =~ /(.+)\@(.+)/) {  
    $name=$1;
    $domain=$2;
  } else {
    return "Full account name with \@ and domain part expected";
  }

  my $ldap = Net::LDAP->new(@LDAPServerAddress,port=>389,timeout=>5)
    || return "Can't connect to @LDAPServerAddress via LDAP";

  my $result=$ldap->bind("CN=$name",$LDAPSearchBase,password=>$password)
    || return "Can't bind:".$result->error;

  $ldap->unbind();                        # unbind & disconnect
  $result->code && return $result->error; # return error message if
failed
  return undef;                           # return "undef" on success
}

sub new_command {
  my $user=$_[0];

  my ($name,$domain)=("",""); 
  if($user =~ /(.+)\@(.+)/) {  
    $name=$1;
    $domain=$2;
  } else {
    return "Full account name with \@ and domain part expected";
  }
  my $ldap = Net::LDAP->new(@LDAPServerAddress,port=>389,timeout=>5)
    || return "Can't connect to @LDAPServerAddress via LDAP";

  my $result=$ldap->bind($LDAPAdminDN,password=>$LDAPAdminPassword)
    || return "Can't bind as admin: ".$result->error;
  $result->code && return "Can't bind as admin: ".$result->error;
 
  my $mesg = $ldap->search (  # perform a search
               base   => $LDAPSearchBase,  #"cn=$domain",
        scope  => 'sub',
               filter => "(&(CN=$name) (objectclass=*))"
             );

  $ldap->unbind();                        # unbind & disconnect

  unless(defined $mesg && !$mesg->code) {
    return "LDAP search failed: ".$result->error;   
  } 
  if($mesg->all_entries() eq 0) {
    return "LDAP: nothing found for 'CN=$name'";
  }
  my ($realName,$password);  
  foreach $entry ($mesg->all_entries) {
    my [EMAIL PROTECTED]'asn'};
    my [EMAIL PROTECTED]'attributes'};
    foreach $atrRef (@$attrs) {
      my [EMAIL PROTECTED]'type'};
      my [EMAIL PROTECTED]'vals'};
      [EMAIL PROTECTED] if($type eq 'uid');
      [EMAIL PROTECTED] if($type eq 'userPassword');
    }
    last; # we need only 1 entry
  }
  my %userData;
  $userData{'RealName'}=$realName if(defined $realName); 
  $userData{'Password'}=$password if(defined $password); 
  my $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,
                          PeerPort => 106,
                          login    => $CLILogin,
                          password => $CLIPassword
                        } )  
   || return "Can't login to CGPro via CLI: ".$CGP::ERR_STRING;

  $cli->CreateAccount(accountName=>"$user",settings=>\%userData)
    || return "Can't create account via CLI:".$cli->getErrMessage;
  $cli->Logout();
  return undef;
}

Reply via email to