简体   繁体   中英

PHP LDAP search issue

I'm trying for the first time to use LDAP in some PHP code. I want to determine if someone is a member of a particular AD group.

I've cobbled together some code from other examples and this runs without error, but indicates 0 results, when the user is in fact a member of the group.

Here is my code:

$hostname="192.168.1.1";
$conn=ldap_connect($hostname, 389);
ldap_set_option ($conn, LDAP_OPT_REFERRALS, 0) or die('Unable to set LDAP opt referrals');
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');

if ($conn) {
    $dn = "DC=domain,DC=local";

    // if (!($ldapc=ldap_bind($conn,'CN=Username,CN=Users,DC=domain,DC=local','P@ssw0rd'))) { 
    if (!($ldapc=ldap_bind($conn,'username@domain.local','N0tMyP@ssw0rd'))) { 

Is the full CN=,DC=, etc or the @domain.local the preferred method here?

Also, I am assuming that all searches performed for membership will be against the user authenticated by the ldap_bind()?

code continues:

    echo "<p>Error:" . ldap_error($conn) . "</p>"; 
    echo "<p>Error number:" . ldap_errno($conn) . "</p>"; 
    echo "<p>Error:" . ldap_err2str(ldap_errno($conn)) . "</p>"; 
    die;
    } 

    $attributes = array("memberOf");
    $filter = "(memberOf=myGroup,OU=Application Security,DC=domain,DC=local)";
    $result = ldap_search($conn, $dn, $filter, $attributes);

    echo $result."<BR />";
    $info = ldap_get_entries($conn, $result);
    echo $info["count"]." entries returned.\n";

    for ($i=0; $i < $info["count"]; $i++) {
        echo $info[$i]["ou"][0];
    }
} else {
    echo "<h4>Unable to connect to LDAP server</h4>";
}

ldap_unbind($conn);

EDIT: After suggestions below, I was able to get this working as expected. Here is the final working code for those who would benefit...

$hostname="192.168.1.1";
$conn=ldap_connect($hostname, 389);
ldap_set_option ($conn, LDAP_OPT_REFERRALS, 0) or die('Unable to set LDAP opt referrals');
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
if ($conn) {
    $dn = "DC=domain,DC=local";
    if (!($ldapc=ldap_bind($conn,'CN=Administrator,CN=Users,DC=domain,DC=local','password'))) { 
        echo "<p>Error:" . ldap_error($conn) . "</p>"; 
        echo "<p>Error number:" . ldap_errno($conn) . "</p>"; 
        echo "<p>Error:" . ldap_err2str(ldap_errno($conn)) . "</p>"; 
        die;
    } 

    $filter = "(memberOf=cn=Dashboard,OU=Application Security,DC=domain,DC=LOCAL)";
    $result = ldap_search($conn, $dn, $filter);
    // $attributes = array('samaccountname');
    //$result = ldap_search($conn, $dn, $filter, $attributes);
    $info = ldap_get_entries($conn, $result);
    echo $info["count"]." entries returned.<br />";
    for ($i=0; $i < $info["count"]; $i++) {
        echo $i . " " . $info[$i]["samaccountname"][0] . "<br />";
    }
} else {
    echo "<h4>Unable to connect to LDAP server</h4>";
}
ldap_unbind($conn);

Personally I prefer the cn=... way to bind to a directory as it's universal. The username@domain -version only works on AD.

And the user that binds to the directory is NOT the user you are looking up the groups for but the user you are looking up the information with .

So when the user you are binding to the LDAP-Server with doesn't have the right to see the group information you won't have much luck. On the other hand if you'd need to login with the user you are looking the group-memberships for you could only retrieve the group-memberships when you know the password of the user. Taht would be a bit strange, wouldn't it?

And as the user binding to the LDAP-Server only has to have read-permission to the LDAP-Server often it is possible to use an anonymous bind without the need for a real user to bind. You would then simply omit the user and password-fields on the ldap_bind . But that depends on the setup of the Server.

To get the number of results returned by your query you can also use the ldap_count_entries($connectionHandle, $resultHandle) -function but I assume that there is an issue in your search-filter.

The search-filter has to contain a query. In your case you just give a string but you don't tell the LDAP-Server wwhich field to map it against. The filter always looks something ike this: <fieldname>=<querystring> . So in your case that would be memberOf=cn=mygroup,OU=Application Security,DC=domain,DC=local . The difference being that the group is identified by it's complete DN which (I assume here) is cn=mygroup,OU=Application Security,DC=domain,DC=local - You'll have to verify that!

The query will return you all users that are a member of that role. And it will only return you the memberOf -Attribute of those users which you know already. So you should either leave the $attributes empty or use something like ['cn', 'sAMAcountName', 'mail'] to get the CN, the Users ID and the email-address returned.

In a second step you will then have to check whether the user you are looking for actually is in that returned array.

Alternatively you could just search vor the user (filter would be something like mail=<email-address> or sAMAcountName=<user-ID> and get the memberOf value returned. you will then have to look whether the required group is one of the ones in the memberOf -Entry.

Scared? Didn't understand it? Don't worry. Ask!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM