1

I am creating a login page that uses Active Directory credentials. I found some documentation about LDAP in the PHP Manual and managed to successfully login using Active Directory credentials by binding with LDAP.

My challenge is that I have multiple Organizational Units (OU) and can't find an efficient way to bind using OUs.

Currently I am using a for loop to loop over each OU in an array. However, this throws an error each time the incorrect OU is being used. I am new to LDAP and found resources that mentioned ldap_search; however, I was not able to successfully bind without including the OU. Any advice/ help would be great.

$ou=array("Group1", "Group2", "Group3", "Group4", "Group5");



$arrlength = count($ou);

for($x = 0; $x < $arrlength; $x++){



    
    
    
    $ldapuser = "CN=".$_POST["username"].",OU=".$ou[$x].",DC=com,DC=com";

    $ldappass = trim($_POST["password"]);
    

    //LDAP server connection

    
    $ldapserver = "ldaps:server.domain";

            
    

    //options are require, never, allow
    //require is most secure, the others could allow for man in the middle attacks
    putenv('LDAPTLS_REQCERT=require');

        
    // connect to ldap server
    $ldapconn = ldap_connect($ldapserver) or die ("Couldn't connect");

    ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

    // binding to ldap server
    $ldapbind = false;

   

      $ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass);
      if ($ldapbind) {

     
          $x = $arrlength;

     }
  • Update: I found out that the @ sign in PHP can be used to suppress the PHP warning errors (source: https://stackoverflow.com/questions/1032161/what-is-the-use-of-the-symbol-in-php). I merged the $ldapbind connection along with the if statement eg (if(@$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass)){ $x = $arrlength;}. This stopped the PHP Error warning which was really what I wanted. However, I am still want to know if there is a more efficient way. – Tajay Marshall Jul 06 '22 at 20:46

1 Answers1

1

The most common generic method (i.e. one that'll work with any kind of LDAP system) is:

  1. Bind using a preconfigured "service" account and password. (Ask the AD admins to create a dedicated account for your webapp. They might need to add it to the "Pre-Win2000 systems" group.)

  2. Search the LDAP directory for the username to find the correct user account object.

    (You can search by any attribute you like, but note that the username is usually sAMAccountName, not the CN – the CN field is supposed to hold the user's "real" name. This also means that a user's DN may change, so you have to search it every time.)

  3. Unbind (disconnect), then connect/bind again with the user's DN that you just found.

If this is specifically Active Directory, there's a shortcut – you can bind to AD LDAP without knowing the user's DN at all, just by specifying the UPN (i.e. username@domain) within the "bind DN" field. This won't work with other server types, and won't be all that useful if you also need to retrieve the user's attributes (still need a search for that...)

Also, if this is AD, you'll usually want to disable the REFERRALS option.

user1686
  • 13,155
  • 2
  • 35
  • 54
  • Thank You! I initially had a service account for the application but I was thinking it would be more secure to bind with the user's credentials. However, I have successfully binded by using the username@domain which is much more efficient than what I was doing initially. – Tajay Marshall Jul 14 '22 at 18:46