skip to Main Content

Newbie here. I recently started coding (HTML, CSS, JS, PHP…) and I’m having a little problem with LDAP searches, and especially with filters.

In order to create a site that will look for information in an Active Directory, I have set up a search bar that searches in users registered in AD, in order to return the results. But I would like to exclude certain OUs from this search, including the users present in them.

Here is my code:

            $nom = $_POST['nom'];
            $base_dn = "DC=TOTO, DC=COM";
            $filter = "(&(objectClass=person)(|(givenname=*$nom*)(sn=*$nom*))(!(ou=USERS)(ou=TEST)))";
            $attributes = ["sn", "givenname", "mail"];

            $search_result = ldap_search($ldap_conn, $base_dn, $filter, $attributes);

            $entries = ldap_get_entries($ldap_conn, $search_result);

            $results = [];

            if ($entries['count'] === 0) {
                echo "Pas de résultats";
            } else {
                foreach ($entries as $entry) {
                    if (isset($entry['cn'][0])) {
                        $result = [
                            'sn' => isset($entry['sn'][0]) ? $entry['sn'][0] : ' ',
                            'givenname' => isset($entry['givenname'][0]) ? $entry['givenname'][0] : ' ',
                            'mail' => isset($entry['mail'][0]) ? $entry['mail'][0] : 'Non renseigné',
                        ];
                        array_push($results, $result);
                    } else {
                      echo " ";
                    }
                }

                ldap_unbind($ldap_conn);

The search works fine, but despite the exclusion of OUs in the filter, the search still displays the users present in the excluded OUs and whose sn/givenname correspond to the searched string.

I specify that I do this in PHP, and from scratch, without framework.

Any ideas ?

I tried a lot of filters, with no results. I don’t know if it’s my syntax that’s wrong, or something else.

// I didn't have high hopes for that.
$filter = "(&(objectClass=person)(|(givenname=*$nom*)(sn=*$nom*))(!(memberOf=OU=Users,OU=USERS SERVEURS)))";

$filter = "(&(objectClass=person)(|(givenname=*$nom*)(sn=*$nom*))(!(ou=USERS))(!(ou=TEST)))";

Thanks !

2

Answers


  1. Chosen as BEST ANSWER

    Thanks for your answer !

    There is no ou attribute, so (!(ou=USERS))(!(ou=TEST)) means nothing at all. There are two attributes that would have the OU, but you can't use either:

    That's strange, because there's an attribute named "ou" in the list in my Active Directory.

    attribute list image in ad

    I assume this is an exception (or else), but I supposed it was indeed an attribute by seeing it in the list. My mistake.

    I actually found one of the options you suggested shortly after posting here. But I was still a bit curious if I could still exclude the OUs.

    I share here the code I wrote before closing. My code is still a bit messy but i'm getting better !

    $filter = "(&(objectClass=person)(|(givenname=*$nom*)(sn=*$nom*)))";
    $attributes = ["cn", "sn", "dn", "givenname", "mobile"];
    $excluded = ['OU=USERS', 'OU=Microsoft', 'OU=TEST', 'OU=System', 'OU=SERVEURS'];
    
    $search_result = ldap_search($ldap_conn, $base_dn, $filter, $attributes);
    
    $entries = ldap_get_entries($ldap_conn, $search_result);
    
    $results = [];
    
    if ($entries['count'] === 0) {
        echo "Pas de résultats";
    } else {
      $all_excluded = true;
      foreach ($entries as $entry) {
        if (isset($entry['cn'][0])) {
          $dn = $entry['dn'];
          $excluded_entry = false;
            foreach ($excluded as $excluded_dn) {
              if (strpos($dn, $excluded_dn) !== false) {
                $excluded_entry = true;
                break;
              }   
            } 
            
            if (!$excluded_entry) {
                $result = [
                    'sn' => isset($entry['sn'][0]) ? $entry['sn'][0] : ' ',
                    'givenname' => isset($entry['givenname'][0]) ? $entry['givenname'][0] : ' ',
                    'mobile' => isset($entry['mobile'][0]) ? $entry['mobile'][0] : 'Non assigné'
                  
                ];
                array_push($results, $result);
                $all_excluded = false; 
    
            } else {
              echo " ";
            }
        } else {
          echo " ";
        }
        }
    

    Thanks again for your answer !


  2. The short answer is that you cannot exclude OUs in an LDAP filter – at least not in Active Directory.

    There is no ou attribute, so (!(ou=USERS))(!(ou=TEST)) means nothing at all. There are two attributes that would have the OU, but you can’t use either:

    1. distinguishedName would contain the DN of the OU, but you cannot do partial matches on any DN attribute.
    2. msDS-parentdistname is the DN of the OU, but it is a constructed attribute (only returned if you specifically ask for it), and constructed attributes cannot be used in search filters.

    So you have two options:

    1. Exclude them after the results are returned. In your $attributes, ask for either distinguishedName or msDS-parentdistname and inside your foreach, check if one of those attributes contains the DN of the OU, and if so, continue;.
    2. Only search the OUs you want. Do this by setting the $base_dn to the OU, and repeat for each OU you want to search. If you want to exclude sub-OUs, then use ldap_list instead of ldap_search.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search