问题在PHP中查询LDAP

时间:2013-12-17 17:15:11

标签: php active-directory ldap

我目前正在编写一个查询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);

?> 

1 个答案:

答案 0 :(得分:1)

基于代码,我假设你试图在最后的for循环中遍历返回的对象及其属性。问题是你如何迭代。这是manual的返回数据结构。

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)来查看其中的确切内容。