title: Discovering nested groups using LDAP with PHP
body: <p>I have an LDAP authentication system that can find and retrieve the memberOf attribute from AD but I'm not sure how to go about getting nested group memberships. I'm aware of the memberOf:1.2.840.113556.1.4.1941: extension but unsure how to adapt it to my code. My code that is working is below (it just doesn't do nested groups). Can someone with more experience help?</p>
  
  <p>IN CONFIG.PHP</p>
  
  <pre><code>$adbase = "some.domain.com";
  $adtree = "OU=All Departments,DC=some,DC=domain,DC=com";
  $group_admins = "Test App Admins";
  $group_staff = "Test App Staff";
  </code></pre>
  
  <p>IN RUN.PHP</p>
  
  <pre><code>function extract_unit($string, $start, $end) {
      $pos = stripos($string, $start);
      $str = substr($string, $pos);
      $str_two = substr($str, strlen($start));
      $second_pos = stripos($str_two, $end);
      $str_three = substr($str_two, 0, $second_pos);
      $unit = trim($str_three); // remove whitespaces
      return $unit;
      }
  
  extract($_POST);
  
  if($action == "logon") {
      $ldap = ldap_connect($adbase);
      $userID = "$user@$adbase";
      $bind = @ldap_bind($ldap, $userID, $pass);
  
      if($bind == true) {
          // assign session variables
          $_SESSION['username'] = $user;
  
          // get group memberships
          $results = ldap_search($ldap, $adtree, "(samaccountname=$user)",array("memberof", "mail"));
          $entries = ldap_get_entries($ldap, $results);
  
          // get group count (first entry) and group listings
          $beat = 0; $str = ""; foreach($entries[0]['memberof'] as $temp) {
              if($beat == 0) {
                  $count = $temp;
                  }
              else {
                  $temp = extract_unit($temp, "CN=", ",OU=");
                  $str .= "$temp, ";
                  $groups[] = $temp;
                  }
              $beat++;
              }
          // return the mail address, stackoverflow.com/questions/16224720/searching-for-email-address-ldap-active-directory
          $mail = $entries[0]["mail"][0];
          // assign session variables
          $_SESSION['mail'] = $mail;
  
          // groups defined in config.php
          $client = "You are logged in as a client.";
          if(in_array($group_admins, $groups)) {
              $_SESSION['admin'] = true;
              $client = "You are logged in as an administrator.";
              }
          else {
              $_SESSION['admin'] = false;
              }
          // groups defined in config.php
          if(in_array($group_staff, $groups)) {
              $_SESSION['staff'] = true;
              $client = "You are logged in as staff.";
              }
          else {
              $_SESSION['staff'] = false;
              }
  
          // if it returns true user was found
          print "&lt;h2&gt;Signed in as $user&lt;/h2&gt;\n";
          print "$client&lt;br&gt;\n";
          print "&lt;img src=\"./images/next.png\"&gt; &lt;a href=\"./?d=welcome\"&gt;Continue ...&lt;/a&gt;\n";
          print "&lt;!-- count is $count --&gt;";
          print "&lt;!-- groups are $str --&gt;";
          print "&lt;!-- mail is $mail --&gt;";
          }
      else {
          print "&lt;h2&gt;Login attempt failed&lt;/h2&gt;\n";
          print "&lt;img src=\"./images/logon.png\"&gt; &lt;a href=\"./?d=user/logon\"&gt;You may try again ...&lt;/a&gt;\n";
          }
      }
  </code></pre>