Apache-AuthzLDAP

 view release on metacpan or  search on metacpan

AuthzLDAP.pm  view on Meta::CPAN

# no rights or licenses to the intellectual property of any
# Contributor under this Agreement, whether expressly, by implication,
# estoppel or otherwise. All rights in the Program not expressly
# granted under this Agreement are reserved.
#
# This Agreement is governed by the laws of the State of New York and
# the intellectual property laws of the United States of America. No
# party to this Agreement will bring a legal action under this
# Agreement more than one year after the cause of action arose. Each
# party waives its rights to a jury trial in any resulting litigation.
#
###############################################################################


# Package name
package Apache::AuthzLDAP;


# Required libraries
use strict;
use mod_perl ();
use Apache::Constants ':common';
use Apache::Log ();
use Net::LDAP qw(:all);
use Text::ParseWords ();


# Global constants
use constant REQUIRE_OPTS => { 'inagroup'     => 1,
			       'inmanygroups' => 2,
			       'inallgroups'  => 3 };


# Global variables
$Apache::AuthzLDAP::VERSION = '1.11';


###############################################################################
###############################################################################
# check_group: check user membership in group
###############################################################################
###############################################################################
sub check_group {
  my ($r, $ld, $basedn, $groupattrtype, $memberattrtype,
      $userinfo, $groups, $nestedattrtype, $nested_groups,
      $requirement, $recursion_depth) = @_;
  my ($group, $authgroups, $member) = undef;
  my $foundgroups = '';
  my @grouplist = ();

  $r->log->debug("check_group: Recursion depth is $recursion_depth");
  $r->log->debug("check_group: Parsing on $groups");
  @grouplist = Text::ParseWords::parse_line('\s+', 0, $groups);

  foreach $group (@grouplist) {
    # Look up the group
    my $filter = qq(($groupattrtype=$group));
    $r->log->debug("check_group: Iterating over group $group");
    $r->log->debug("check_group: Using filter: $filter");
    $r->log->debug("check_group: Using base: $basedn");
    # Want to just validate group's existence, not get its contents
    my $msg = $ld->search(base => $basedn, filter => $filter,
			  attrs => [ $nestedattrtype ]);
    unless ($msg->code == LDAP_SUCCESS) {
      $r->note_basic_auth_failure;
      $r->log_reason("user $userinfo: Could not search for $group: " .
		     $msg->code . " " . $msg->error, $r->uri);
      next unless $requirement == 3;
      return AUTH_REQUIRED;
    }

    # Did we get any entries?
    unless ($msg->count) {
      $r->log->debug("check_group: user $userinfo: could not find $group");
      return AUTH_REQUIRED if $requirement == 3;
      next;
    }

    # Check the group
    my $entry = $msg->first_entry; # Only want one
    my $dn = $entry->dn;
    $r->log->debug("check_group: Checking group $dn for $userinfo");
    $msg = $ld->compare($dn, attr => $memberattrtype, value => $userinfo);

    if ($msg->code == LDAP_COMPARE_TRUE) {
      return (OK, $group) unless $recursion_depth == 1;
      if ($requirement == 1) {
	$r->log->debug("LDAP compare inAGroup user found; returning");
	return (OK, "\"$group\"");
      } elsif ($foundgroups eq '') {
	$r->log->debug("LDAP compare inManyGroups or inAllGroups user found; appending");
	$foundgroups = "\"$group\"";
      } else {
	$r->log->debug("LDAP compare inManyGroups or inAllGroups user found; appending");
	$foundgroups .= " \"$group\"";
      }
      next;
    }

    # Return undef if nested groups is not set
    $r->log->debug("check_group: Could not find $userinfo in $group");
    next unless $nested_groups =~ /on/i;

    # If we did not find the person in the group let's check the
    # group's members
    foreach $member ($entry->get($nestedattrtype)) {
      $r->log->debug("check_group: Checking $member");
      # We just want the group's name
      if ($member =~ /^[^=]+="([^"]+)",/) {
	$member = $1;
	$r->log->debug("check_group: Setting quoted $member");
      } elsif ($member =~ /^[^=]+=([^,]+),/) {
	$member = $1;
	$r->log->debug("check_group: Examining escaped $member");
	$member =~ s/\\(.)/$1/g;
	$r->log->debug("check_group: Setting escaped $member");
      }

      $r->log->debug("check_group: Member now $member");
      my ($result, $child_group) = check_group($r, $ld, $basedn, $groupattrtype,
					       $memberattrtype, $userinfo,



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