2016-04-28 10 views
0

У меня вопрос о членстве пользователей в группах в Active Directory и захвате таких членств с PHP. Мой большой вопрос/ситуация в том, что у меня есть сайт, который я создаю, и по существу я пытаюсь назначить администраторов на основе групп в Active Directory, и я знаю, как проверить член статуса в учетной записи, но моя проблема в том, что есть некоторые группы которые не отображаются там, и одна из групп, которые не отображаются, - это группа, в которой я нуждаюсь. Есть ли способ проверить, кто является членом этой группы, а не проверять, является ли этот пользователь членом этой группы. В качестве альтернативы, если кто-то знает, почему определенные группы не появляются в моем поиске, я бы предпочел искать членство таким образом, потому что тогда было бы простой логический оператор, чтобы проверить, находится ли пользователь в этой группе, мой код ниже, и он работает, но как Я сказал, что есть определенные группы, которые не появляются, и я думаю, что я где-то читал о том, как членство сохраняется, а также если оно является прямым членом или если вы являетесь членом группы, которая является членом другой группы. Одна группа, которую мы используем в качестве нашей группы по умолчанию, - это пользователи домена, но никто не имеет этого массива memberOf, хотя членство этой группы является прямым, так как в членах этой группы все пользователи не являются другими группами безопасности, содержащими пользователей.LDAP Поиск членов группы PHP

В какой-то момент в этой программе мне нужно отметить определенных пользователей как «менеджеров», и самым простым способом для меня было бы хранить переменную сеанса VIA, если они являются членами определенной группы менеджеров, так как выше, проблема, с которой я сталкиваюсь, заключается в том, что пользователи не появляются в некоторых своих группах, поэтому это не работает, группа, которая предоставит доступ к менеджерам, не появится в моей области MemberOf. На заключительном этапе мне придется пройти через 5-6 групп и добавить всех членов в базу данных, это аналогичная проблема, и у нее должно быть аналогичное решение, поэтому, возможно, я смогу убить двух птиц с 1 камнем, если я подумаю, что один из них слишком. То, что я имею в виду под этой проблемой, - это то, что мне нужно будет захватить такую ​​группу, как «пользовательский HR», а затем загрузить их в базу данных по имени и фамилии и некоторым значениям по умолчанию для других полей, но я не знаю, как хватайте пользователей из группы, я знаю, как захватить группы пользователей, но даже это не захватывает 100% групп, и если я могу отменить этот порядок и действовать как группа и проверить мои собственные члены, которые сделают вещи очень легкими , наше текущее приложение, которое мы используем, чтобы сделать все это для нас, находится в ASP.net, но лет 10 или около того, и у него есть учетная запись администратора, жестко закодированная для доступа к группам и т. д., даже делая это, я до сих пор не уверен, как я получат членов группы.

Код:

<?php 
$ldap = ldap_connect("192.168.1.**"); 
$ldap_dn = "DC=************,DC=local"; 
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); 
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); 
$access = NULL; 
if ($bind = ldap_bind($ldap, "***********\\" . $_POST['username'], $_POST['password'])) { 
    $filter = "(sAMAccountName=" . $_POST['username'] . ")"; 
    $attr = array("memberof","givenname","sn","mail"); 
    $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server"); 
    $entries = ldap_get_entries($ldap, $result); 
    $givenname = $entries[0]['givenname'][0] . " " . $entries[0]['sn'][0]; 
    ldap_unbind($ldap); 
    //var_dump($entries[0]["sn"][0]); 
    //var_dump($givenname); 
    //var_dump($entries[0]); 
    // check groups 
    foreach($entries[0]['memberof'] as $grps) { 
     // is manager, break loop 
     //if (strpos($grps, $ldap_manager_group)) { $access = 2; break; } 
     // is user 
     //var_dump($grps); 
     if (strpos($grps, "****** * *** *****")) $access = "****** *"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "***")) $access = "***"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "***")) $access = "***"; 
    } 
    if ($access != NULL) { 
     // establish session variables 
     $_SESSION['user'] = $_POST['username']; 
     $_SESSION['access'] = $access; 
     $_SESSION['givenname'] = $givenname; 
     $_SESSION['email'] = $entries[0]['mail'][0]; 
     return true; 
     } else { 
     //echo "No rights?"; 
     // user has no rights 
     return false; 
    } 
} else { 
    //header("Location: login.php?Error=Invalid Identity"); 
    echo "Elese Here"; 
} 
?> 

Edit:

Я пытался использовать этот учебник: samjlevy.com и я понимаю, по большей части, но я получаю несколько ошибок:

Warning: ldap_search(): Search: Operations error in C:\inetpub\wwwroot\InOutBoard\test.php on line 62 

Warning: ldap_get_entries() expects parameter 2 to be resource, boolean given in C:\inetpub\wwwroot\InOutBoard\test.php on line 63 

Warning: array_shift() expects parameter 1 to be array, null given in C:\inetpub\wwwroot\InOutBoard\test.php on line 66 

Warning: Invalid argument supplied for foreach() in C:\inetpub\wwwroot\InOutBoard\test.php on line 72 
Array () 

Все они, похоже, находятся в поиске, потому что он не работает, он возвращает значение NULL, которое не позволяет запускать другие части. Я не уверен, что мой $ ldap_dn правильный, поскольку я использую тот же самый из кода php выше. Мой макет выглядит следующим образом (я новичок в этом, я считаю, что это правильно): DC = компания, DC = локальная, и поэтому она должна быть для группы, которую я хочу: CN = Group Looking For, OU = lowerLevel Ou, OU = Groups , OU = компания, DC = Компания, DC = местная

Должен ли я использовать это как мой $ ldap_dn?

EDIT 2: (Обновлено код)

Этот код отображает все группы, которые пользователь находится в и работает очень хорошо, есть способ, чтобы написать вторую страницу, которая использует аналогичную страницу, чтобы принять одна из этих групп и захватывает всех членов из этого?

<?php 

$ldap = ldap_connect("192.168.1.**"); 
$ldap_dn = "DC=Company,DC=local"; 
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); 
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); 
$access = NULL; 
if ($bind = ldap_bind($ldap, "**********\\" . $_POST['username'], $_POST['password'])) { 
    $filter = "(sAMAccountName=" . $_POST['username'] . ")"; 
    $attr = array("memberof","givenname","sn","mail","distinguishedname"); 
    $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server"); 
    $entries = ldap_get_entries($ldap, $result); 
    $givenname = $entries[0]['givenname'][0] . " " . $entries[0]['sn'][0]; 
    //ldap_unbind($ldap); 
    //var_dump($entries[0]["sn"][0]); 
    //var_dump($givenname); 
    //var_dump($entries[0]); 
    var_dump($entries[0]['distinguishedname'][0]); 

    $gFilter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=".$entries[0]['distinguishedname'][0]."))"; 
    $gAttr = array("cn"); 
    $result1 = ldap_search($ldap, $ldap_dn, $gFilter, $gAttr) or exit("Unable to search LDAP server"); 
    $groups = ldap_get_entries($ldap, $result1); 
    var_dump($groups); 
    // check groups 
    foreach($entries[0]['memberof'] as $grps) { 
     // is manager, break loop 
     //if (strpos($grps, $ldap_manager_group)) { $access = 2; break; } 

     // is user 
     //var_dump($grps); 
     if (strpos($grps, "****** * *** *****")) $access = "****** *"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "***")) $access = "***"; 
     if (strpos($grps, "*** Group")) $access = "***"; 
     if (strpos($grps, "***")) $access = "***"; 

    } 

    if ($access != NULL) { 
     // establish session variables 
     $_SESSION['user'] = $_POST['username']; 
     $_SESSION['access'] = $access; 
     $_SESSION['givenname'] = $givenname; 
     $_SESSION['email'] = $entries[0]['mail'][0]; 
     return true; 
     } else { 
     //echo "No rights?"; 
     // user has no rights 
     return false; 
    } 
} else { 
    //header("Location: login.php?Error=Invalid Identity"); 
    echo "Elese Here"; 
} 
?> 

Вторая страница: Эта страница должна найти член группы, которая выглядит, как он может пытаться сделать это, но не выбирая член группы, но один из нашего OU вместо этого. Посмотрите ниже код для макета и то, что он захватывает.

<?php 
function get_members($group=FALSE,$inclusive=FALSE) { 
    $ldap_host = "192.168.1.***"; 
    $ldap_dn = "OU=******,OU=*****,OU=**********,DC=Company,DC=local"; 
    $ldap_usr_dom = "@".$ldap_host; 
    $user = "*******"; 
    $password = "******"; 
    $keep = array(
     "samaccountname", 
     "distinguishedname" 
    ); 
    $ldap = ldap_connect($ldap_host) or die("Could not connect to LDAP"); 
    ldap_bind($ldap, "REGION5SYSTEMS\\" . $user, $password) or die("Could not bind to LDAP");ry 
    if($group) $query = "(&"; else $query = ""; 
    $query .= "(&(objectClass=user)(objectCategory=person))"; 
    if(is_array($group)) { 
     // Looking for a members amongst multiple groups 
      if($inclusive) { 
       $query .= "(|"; 
      } else { 
       $query .= "(&"; 
      } 
      foreach($group as $g) $query .= "(memberOf=CN=$g,$ldap_dn)"; 
      $query .= ")"; 
    } elseif($group) { 
     $query .= "(memberOf=CN=$group,$ldap_dn)"; 
    } 
    if($group) $query .= ")"; else $query .= ""; 
    $results = ldap_search($ldap,$ldap_dn,$query); 
    $entries = ldap_get_entries($ldap, $results); 
    array_shift($entries); 
    $output = array(); // Declare the output array 
    $i = 0; // Counter 
    // Build output array 
    foreach($entries as $u) { 
     foreach($keep as $x) { 
      // Check for attribute 
      if(isset($u[$x][0])) $attrval = $u[$x][0]; else $attrval = NULL; 
      $output[$i][$x] = $attrval; 
     } 
     $i++; 
    } 

    return $output; 
} 

// Example Output 
print_r(get_members()); // Gets all users in 'Users' 
print_r(get_members("Group I'm search for")); // Gets all members of 'Test Group' 
?> 

Итак, наш DC является DC = CompanyName, DC = Local и затем мы имеем папки и OU и один из OU имеет имя «CompanyName» и вложенные в него являются OU, такие как Admins Компьютеры, контакты, группы, ect ect ... OU, на который я смотрю, - это пользователи и вложенные в это разные организации в нашем здании (они используют наш domian) и одно дополнительное OU, созданное для этого проекта. Предыстория проекта - это сотрудник inoutBoard, и поэтому у нас есть 3 группы безопасности в этом подразделении, один для членов другой организации, один для наших членов организации и один для тех, кто является менеджерами как нашего Org, так и их организации, в основном люди, которые могут изменить статус других, если они забывают это сделать. В идеале мы хотим, чтобы у вас была какая-то кнопка синхронизации, которая могла проверять членов этих групп, а затем загружать их в базу данных, а также некоторые значения по умолчанию, такие как статус по умолчанию вне офиса и без описания или что-то в этом роде , Эти группы также не содержат людей, они содержат другие группы безопасности. Это то, что мы хотим работать, мы хотим найти членов этих групп, второй бит, который я прикреплял, будет работать иногда, если я установил $ ldap_dn в «CN = Company, DC = Company, DC = Local», он будет печатать всех пользователей в подразделении пользователей, а затем переходить во все OU и распечатывать пользователей из тех подразделений, за исключением OU, в котором мы действительно нуждаемся, это OU, в котором есть группы для внебиржевых платформ. Если я укажу этот путь как $ ldap_dn, он просто печатает массив() и ничего больше. Есть идеи?

ответ

0

Атрибут memberOf будет содержать только прямые членства в группах, поэтому рекурсивные членства не будут перечислены. Тем не менее, вы можете специально запросить рекурсивное членство в группах от пользователя, как так (адаптировать свой код НЕМНОГО непосредственно после привязки):

$filter = "(sAMAccountName=" . $_POST['username'] . ")"; 
$attr = array("givenname","sn","mail", "distinguishedname"); 
$result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server"); 
$entries = ldap_get_entries($ldap, $result); 

$gFilter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=".$entries[0]['distinguishedname'][0]."))"; 
$gAttr = array("cn"); 
$result = ldap_search($ldap, $ldap_dn, $gFilter, $gAttr) or exit("Unable to search LDAP server"); 
$groups = ldap_get_entries($ldap, $result); 

Не тестировался на данный момент, но это общий фильтр и процесс для этого. Получите DN пользователя, затем используйте соответствующее правило OID 1.2.840.113556.1.4.1941, чтобы получить группы рекурсивно.

Причина, по которой вы не получаете группу «Пользователи домена», которая появляется, потому что это «специальная» первичная группа в AD, хранящаяся в атрибуте primaryGroupId пользователя. Дополнительная информация о том, что здесь:

https://support.microsoft.com/en-us/kb/297951

+0

Я пытаюсь выяснить правила OID, я должен изменить это число на то, что я тянуть на моем конце? – AndyPet74

+0

Также код содержит эту ошибку: Предупреждение: ldap_search(): 4 не является действительным ресурсом ссылки ldap в C: \ inetpub \ wwwroot \ InOutBoard \ authorize.php в строке 22 Связано ли это с областью gAttr? – AndyPet74

+0

Нет, OID всегда будет этим номером. Единственное, что действительно меняется в этом фильтре, - это то, что происходит в самом конце (в настоящее время в нем помещается значение атрибута 'distinctName', поскольку это будет меняться в зависимости от того, во что зарегистрирован пользователь). Что касается вашей ошибки ... это кажется действительно странным. Я просмотрел логику несколько раз, и я не уверен, как вы это понимаете. Я бы начал с того, что вы делали заявление 'ldap_unbind' из вашего кода, поскольку это не нужно. Ваш сценарий по-прежнему выглядит так же, как и в вашем оригинальном посте? – ChadSikorra