Apache-AuthLDAP

 view release on metacpan or  search on metacpan

AuthLDAP.pm  view on Meta::CPAN

package Apache::AuthLDAP;

use strict;
use Apache::Constants ':common';
use Net::LDAPapi;

$Apache::AuthLDAP::VERSION = '0.21';

sub handler
{
   my $r = shift;
   my ($res, $sent_pwd) = $r->get_basic_auth_pw;
   return $res if $res;

   my $name = $r->connection->user;

   my $basedn = $r->dir_config('BaseDN') || "";
   my $ldapserver = $r->dir_config('LDAPServer') || "localhost";
   my $ldapport = $r->dir_config('LDAPPort') || 389;
   my $uidattr = $r->dir_config('UIDAttr') || "uid";

   if ($sent_pwd eq "")
   {
      $r->note_basic_auth_failure;
      $r->log_reason("user $name: no password supplied",$r->uri);
      return AUTH_REQUIRED;
   }

   my $ld = new Net::LDAPapi($ldapserver,$ldapport);
   if ($ld <= 0)
   {
      $r->note_basic_auth_failure;
      $r->log_reason("user $name: LDAP Connection Failed",$r->uri);
      return AUTH_REQUIRED;
   }

   if ($ld->bind_s != LDAP_SUCCESS)
   {
      $r->note_basic_auth_failure;
      $r->log_reason("user $name: LDAP Initial Bind Failed",$r->uri);
      return AUTH_REQUIRED;
   }

   my $filter = "$uidattr=$name";
   my $status = $ld->search_s($basedn,LDAP_SCOPE_SUBTREE,$filter,["c"],1);
   if ($status != LDAP_SUCCESS)
   {
      $r->note_basic_auth_failure;
      $r->log_reason("user $name: ldap search failed",$r->uri);
      $ld->unbind;
      return AUTH_REQUIRED;
   }

   if ($ld->count_entries != 1)
   {
      $r->note_basic_auth_failure;
      $r->log_reason("user $name: username not found",$r->uri);
      $ld->unbind;
      return AUTH_REQUIRED;
   }

   $ld->first_entry;

   my $dn = $ld->get_dn;

   $status = $ld->bind_s($dn,$sent_pwd);
   if ($status == LDAP_SUCCESS)
   {
      $r->push_handlers(PerlAuthzHandler => \&authz);
      $ld->unbind;
      return OK;
   }

   $ld->unbind;
   $r->note_basic_auth_failure;
   $r->log_reason("user $name: password mismatch", $r->uri);
   return AUTH_REQUIRED;
}

sub authz
{
   my $r = shift;
   my $requires = $r->requires;
   return OK unless $requires;

   my $name = $r->connection->user;

   my $basedn = $r->dir_config('BaseDN') || "";
   my $ldapserver = $r->dir_config('LDAPServer') || "localhost";
   my $ldapport = $r->dir_config('LDAPPort') || 389;
   my $uidattr = $r->dir_config('UIDAttr') || "uid";

   for my $req (@$requires)
   {
      my ($require, @rest) = split /\s+/, $req->{requirement};

      if ($require eq "user")
      {
         return OK if grep $name eq $_, @rest;
      } elsif ($require eq "valid-user")
      {
         return OK;
      } else {
         my $ld = new Net::LDAPapi($ldapserver,$ldapport);
         $ld->bind_s;
         my $filter = "(&(|($require=" . join(")($require=",@rest) .
               "))($uidattr=$name))";
         my $status = $ld->search_s($basedn,LDAP_SCOPE_SUBTREE,$filter,["c"],1);
         if ($status != LDAP_SUCCESS)
         {
            $r->note_basic_auth_failure;
            $r->log_reason("LDAP Lookup Failed",$r->uri);
            $ld->unbind;
            return AUTH_REQUIRED;
         }
         if ($ld->count_entries == 1)
         {
            $ld->unbind;
            return OK;
         }
         $ld->unbind;
      }
   }

   $r->note_basic_auth_failure;
   $r->log_reason("user $name: not authorized", $r->uri);
   return AUTH_REQUIRED;
}

1;
__END__

=head1 NAME

Apache::AuthLDAP - mod_perl LDAP Access Control and Authentication Module



( run in 0.592 second using v1.01-cache-2.11-cpan-39bf76dae61 )