问题查询PHP中的LDAP


Issue Querying LDAP in PHP

我目前正在编写一个脚本,该脚本查询Active Directory以检查用户是否是域管理员。当我用ldp.exe测试它时,过滤器工作正常。但是,当我在php中运行过滤器时,它不会返回任何内容。但是,只要检查SAM帐户返回正确即可。非常感谢。

$ldap_host = "Example.internal";
$base_dn = "DC=Prefix,DC=Example,DC=internal";
$filter = "(&(sAMAccountName=test)(memberof=CN=Domain Admins,CN=Users,DC=Prefix,DC=Example,DC=internal))";
$ldap_user  = "username";
$ldap_pass = "password";
$ldap_port = 3268;

$connect = ldap_connect( $ldap_host, $ldap_port)
          or exit(">>Could not connect to LDAP server<<");
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($connect, $ldap_user, $ldap_pass)
       or exit(">>Could not bind to $ldap_host<<");
$read = ldap_search($connect, $base_dn, $filter)
       or exit(">>Unable to search ldap server<<");
$info = ldap_get_entries($connect, $read);
echo $info["count"]." entries returned<p>";
$ii=0;
 for ($i=0; $ii<$info[$i]["count"]; $ii++){
     $data = $info[$i][$ii];
     echo $data.":&nbsp;&nbsp;".$info[$i][$data][0]."<br>";
 }
ldap_close($connect);
?> 

根据代码,我假设您正在尝试在末尾的for循环中遍历返回的对象及其属性。问题在于你是如何迭代的。这是根据手册返回的数据结构。

return_value["count"] = number of entries in the result
return_value[0] : refers to the details of first entry
return_value[i]["dn"] =  DN of the ith entry in the result
return_value[i]["count"] = number of attributes in ith entry
return_value[i][j] = NAME of the jth attribute in the ith entry in the result
return_value[i]["attribute"]["count"] = number of values for
                                        attribute in ith entry
return_value[i]["attribute"][j] = jth value of attribute in ith entry

基于此代码:

$ii=0;
for ($i=0; $ii<$info[$i]["count"]; $ii++){
    $data = $info[$i][$ii];
    echo $data.":&nbsp;&nbsp;".$info[$i][$data][0]."<br>";
}

您正在设置$i=0;,而不是迭代它,因此它始终为0,与返回数组中的第一个条目相对应。实际上,您正在遍历对象的属性,如果您只期望返回1个结果(我怀疑情况并非如此),那么这是可以的。

您可以从文档中尝试以下功能:

function cleanUpEntry( $entry ) {
  $retEntry = array();
  for ( $i = 0; $i < $entry['count']; $i++ ) {
    if (is_array($entry[$i])) {
      $subtree = $entry[$i];
      //This condition should be superfluous so just take the recursive call
      //adapted to your situation in order to increase perf.
      if ( ! empty($subtree['dn']) and ! isset($retEntry[$subtree['dn']])) {
        $retEntry[$subtree['dn']] = cleanUpEntry($subtree);
      }
      else {
        $retEntry[] = cleanUpEntry($subtree);
      }
    }
    else {
      $attribute = $entry[$i];
      if ( $entry[$attribute]['count'] == 1 ) {
        $retEntry[$attribute] = $entry[$attribute][0];
      } else {
        for ( $j = 0; $j < $entry[$attribute]['count']; $j++ ) {
          $retEntry[$attribute][] = $entry[$attribute][$j];
        }
      }
    }
  }
  return $retEntry;
}

用法:

$info = ldap_get_entries($connect, $read);
$clean_info = Array();
foreach($info as $entry)
{
    $clean_info[] = cleanUpEntry($entry);
}
print_r($clean_info);

输出:

array(256) {
  ["uid=doe,ou=People,dc=example,dc=net"]=>
  array(3) {
    ["uid"]=>
    string(4) "doe"
    ["cn"]=>
    string(14) "John Doe"
    ["telephonenumber"]=>
    string(4) "1234"
  }
  ["uid=foo,ou=People,dc=example,dc=net"]=>
  ...

您还可以考虑在调用ldap_get_entries()之后使用print_r($info)来查看其中的确切内容。