2013-07-24 3 views
1

Как выполнить поиск/аутентификацию LDL Perl для пользователя, являющегося атрибутом в группе доступа или ее подгруппах?Perl LDAP поиск пользователя, являющегося атрибутом CN

Все пользователи (UIDs) находятся в:

ou=Users,o=company,c=com 

группа Доступ:

cn=Site Full Access,ou=Access,o=company,c=com 

группа доступа имеет пользователей и подгруппы в качестве атрибутов, таких как:

uniquemember | uid=usernameA,ou=Users,o=company,c=com 
uniquemember | uid=usernameB,ou=Users,o=company,c=com 
uniquemember | uid=usernameC,ou=Users,o=company,c=com 
uniquemember | cn=Site Full Access Employees,ou=Access,o=company,c=com 

(подгруппа имеет его собственные уникальные атрибуты)

Идея сценария аутентификации:

  1. Связать пользователя с его логином/паролем (сделано).
  2. В случае успеха, создать DN пользователя, как uid=$username,ou=Users,o=company,c=com (сделано)
  3. перебирать атрибутов cn=Site Full Access,ou=Access,o=company,c=com и сравнить их с пользователем DN
  4. Если обнаружена группа, поиск DN пользователя в этой группе слишком

Я использую Net :: LDAP, но не так много кода для показа, так как все работает довольно стандартно. Это перечисление uniquemember атрибутов:

my $mesg = $ldap->bind ($user_dn, password=>"$pass"); 
$mesg->code && return undef; 

$mesg = $ldap->search(base=>$ldap_access_full, filter=>"(objectclass=*)"); 
$mesg->code && return undef; 

my @entries = $mesg->entries; 
my $entry; 
foreach $entry (@entries) 
{ 
    if ($entry->exists('uniquemember')) 
    { 
     my $ref = $entr->get_value('uniquemember', asref=>1); 
     for my $uid (@$ref) 
     { 
    print $uid . "<br/>"; 
     } 
    } 
} 

Это дает мне массив пользовательских DNs, но и группы, которые должны быть перечислены и сравниваются в некоторой рекурсивной функции.

Как подойти к этому? Возможно, есть еще один способ проверить как пароль, так и группу доступа, при этом пользователь по-прежнему является атрибутом группы доступа или ее подгрупп? Я не могу изменять LDAP.

ответ

1

Это называется вложенными группами. Для AD это одно решение: How to retrieve all Groups from LDAP with Perl

Одним из решений является игнорировать группы, разрешать только прямые пользовательские объекты.

Если вам необходимо обработать подгруппы, вы должны получить запись и проверить, что это группа или люди. В случае, если вам нужно проверить это на многих уровнях (подгруппы подгрупп ..), вам необходимо выполнить рекурсию.

Для одного уровня вложенных групп. Он наполовину закончен и не проверен, но вы получили эту идею.

конечно же подпрограммы использования, но я не использовал для облегчения понимания (и отсутствия времени)

$mesg = $ldap->search(base=>$ldap_access_full, filter=>"(objectclass=*)",attrs => [qw(uniquemember)]); 
$mesg->code && die $mesg->code; 

my @entries = $mesg->entries; 
my $entry; 

foreach $entry (@entries) { 
    my @uniquemembers = $entr->get_value('uniquemember'); 
    foreach my $uniquemember (@uniquemembers){ 
     #get entry 
     $mesg = $ldap->search(base=>$uniquemember, filter=>"(objectclass=*)", attrs => [qw(objectclass uid uniquemember)], scope => 'base'); 
     $mesg->code && die $mesg->code; 
     #if is a group or user? 
     my $uniquemember_entry = ($mesg->entries)[0]; 
     my @objectclasses = $uniquemember_entry->get_value('objectclass'); 

     my $uid = $uniquemember_entry->get_value('uid'); 
     if (grep {/user/i} @objectclasses || defined $uid){ 
      print "$uniquemember has uid: $uid\n"; 

     } elsif (grep {/group/i} @objectclasses){ 
      print "it is a group: $uniquemember\n"; 
      #get its members 
      my @nested_group_uniquemembers = $uniquemember_entry->get_value('uniquemember');  
      #get entries 
      foreach my $nested_group_uniquemember (@nested_group_uniquemembers){ 
       $mesg = $ldap->search(base=>$nested_group_uniquemember, filter=>"(objectclass=*)", attrs => [qw(objectclass uid uniquemember)], scope => 'base'); 
       $mesg->code && die $mesg->code;   
      } 
      #check it is an user or group... 
     } else { 

     } 
    } 
} 
+0

Спасибо. Это на самом деле очень похоже на то, что я сделал в конце, но заставило меня понять некоторые незначительные ошибки производительности, которые я сделал. Кроме того, я использую 'if ($ uniquemember = ~/^ cn = /)', чтобы проверить, является ли это группой. Это может быть немного быстрее, чем открытие каждого пользователя с помощью ldap-> search. – yosh

+0

Это может сработать, но что, если кто-то создает объект человека, например cn = john, doe? – user1126070

Смежные вопросы