/**
  * recurse through all groups, adding parent groups to $all_group_dns array.
  *
  * @param array $current_group_entries of ldap group entries that are starting point.  should include at least 1 entry.
  * @param array $all_group_dns as array of all groups user is a member of.  MIXED CASE VALUES
  * @param array $tested_group_ids as array of tested group dn, cn, uid, etc.  MIXED CASE VALUES
  *   whether these value are dn, cn, uid, etc depends on what attribute members, uniquemember, memberUid contains
  *   whatever attribute is in $this->$tested_group_ids to avoid redundant recursing
  * @param int $level of recursion
  * @param int $max_levels as max recursion allowed
  *
  * given set of groups entries ($current_group_entries such as it, hr, accounting),
  * find parent groups (such as staff, people, users) and add them to list of group memberships ($all_group_dns)
  *
  * (&(objectClass=[$this->groupObjectClass])(|([$this->groupMembershipsAttr]=groupid1)([$this->groupMembershipsAttr]=groupid2))
  *
  * @return FALSE for error or misconfiguration, otherwise TRUE.  results are passed by reference.
  */
 public function groupMembershipsFromEntryRecursive($current_group_entries, &$all_group_dns, &$tested_group_ids, $level, $max_levels)
 {
     if (!$this->groupGroupEntryMembershipsConfigured || !is_array($current_group_entries) || count($current_group_entries) == 0) {
         return FALSE;
     }
     if (isset($current_group_entries['count'])) {
         unset($current_group_entries['count']);
     }
     $ors = array();
     foreach ($current_group_entries as $i => $group_entry) {
         if ($this->groupMembershipsAttrMatchingUserAttr == 'dn') {
             $member_id = $group_entry['dn'];
         } else {
             // maybe cn, uid, etc is held
             $member_id = ldap_servers_get_first_rdn_value_from_dn($group_entry['dn'], $this->groupMembershipsAttrMatchingUserAttr);
             if (!$member_id) {
                 if ($this->detailed_watchdog_log) {
                     watchdog('ldap_server', 'group_entry: %ge', array('%ge' => pretty_print_ldap_entry($group_entry)));
                 }
                 // group not identified by simple checks yet!
                 // examine the entry and see if it matches the configured groupObjectClass
                 $goc = $group_entry['objectclass'];
                 // TODO do we need to ensure such entry is there?
                 if (is_array($goc)) {
                     // TODO is it always an array?
                     foreach ($goc as $g) {
                         $g = drupal_strtolower($g);
                         if ($g == $this->groupObjectClass) {
                             // found a group, current user must be member in it - so:
                             if ($this->detailed_watchdog_log) {
                                 watchdog('ldap_server', 'adding %mi', array('%mi' => $member_id));
                             }
                             $member_id = $group_entry['dn'];
                             break;
                         }
                     }
                 }
             }
         }
         if ($member_id && !in_array($member_id, $tested_group_ids)) {
             $tested_group_ids[] = $member_id;
             $all_group_dns[] = $group_entry['dn'];
             // add $group_id (dn, cn, uid) to query
             $ors[] = $this->groupMembershipsAttr . '=' . ldap_pear_escape_filter_value($member_id);
         }
     }
     if ($level < $max_levels && count($ors)) {
         $count = count($ors);
         for ($i = 0; $i < $count; $i = $i + LDAP_SERVER_LDAP_QUERY_CHUNK) {
             // only 50 or so per query
             $current_ors = array_slice($ors, $i, LDAP_SERVER_LDAP_QUERY_CHUNK);
             $or = '(|(' . join(")(", $current_ors) . '))';
             // e.g. (|(cn=group1)(cn=group2)) or   (|(dn=cn=group1,ou=blah...)(dn=cn=group2,ou=blah...))
             $query_for_parent_groups = '(&(objectClass=' . $this->groupObjectClass . ')' . $or . ')';
             foreach ($this->basedn as $base_dn) {
                 // need to search on all basedns one at a time
                 $group_entries = $this->search($base_dn, $query_for_parent_groups);
                 // no attributes, just dns needed
                 if ($group_entries !== FALSE) {
                     $this->groupMembershipsFromEntryRecursive($group_entries, $all_group_dns, $tested_group_ids, $level + 1, $max_levels);
                 }
             }
         }
     }
     return TRUE;
 }
Пример #2
0
 /**
  * recurse through all groups, adding parent groups to $all_group_dns array.
  *
  * @param array $current_group_entries of ldap group entries that are starting point.  should include at least 1 entry.
  * @param array $all_group_dns as array of all groups user is a member of.  MIXED CASE VALUES
  * @param array $tested_group_ids as array of tested group dn, cn, uid, etc.  MIXED CASE VALUES
  *   whether these value are dn, cn, uid, etc depends on what attribute members, uniquemember, memberUid contains
  *   whatever attribute is in $this->$tested_group_ids to avoid redundant recursing
  * @param int $level of recursion
  * @param int $max_levels as max recursion allowed
  *
  * given set of groups entries ($current_group_entries such as it, hr, accounting),
  * find parent groups (such as staff, people, users) and add them to list of group memberships ($all_group_dns)
  *
  * (&(objectClass=[$this->groupObjectClass])(|([$this->groupMembershipsAttr]=groupid1)([$this->groupMembershipsAttr]=groupid2))
  *
  * @return FALSE for error or misconfiguration, otherwise TRUE.  results are passed by reference.
  */
 public function groupMembershipsFromEntryRecursive($current_group_entries, &$all_group_dns, &$tested_group_ids, $level, $max_levels)
 {
     if (!$this->groupGroupEntryMembershipsConfigured || !is_array($current_group_entries) || count($current_group_entries) == 0) {
         return FALSE;
     }
     if (isset($current_group_entries['count'])) {
         unset($current_group_entries['count']);
     }
     $ors = array();
     foreach ($current_group_entries as $i => $group_entry) {
         if ($this->groupMembershipsAttrMatchingUserAttr == 'dn') {
             $member_id = $group_entry['dn'];
         } else {
             // maybe cn, uid, etc is held
             $member_id = ldap_servers_get_first_rdn_value_from_dn($group_entry['dn'], $this->groupMembershipsAttrMatchingUserAttr);
         }
         if ($member_id && !in_array($member_id, $tested_group_ids)) {
             $tested_group_ids[] = $member_id;
             $all_group_dns[] = $group_entry['dn'];
             // add $group_id (dn, cn, uid) to query
             $ors[] = $this->groupMembershipsAttr . '=' . ldap_pear_escape_filter_value($member_id);
         }
     }
     if ($level < $max_levels && count($ors)) {
         $count = count($ors);
         for ($i = 0; $i < $count; $i = $i + LDAP_SERVER_LDAP_QUERY_CHUNK) {
             // only 50 or so per query
             $current_ors = array_slice($ors, $i, LDAP_SERVER_LDAP_QUERY_CHUNK);
             $or = '(|(' . join(")(", $current_ors) . '))';
             // e.g. (|(cn=group1)(cn=group2)) or   (|(dn=cn=group1,ou=blah...)(dn=cn=group2,ou=blah...))
             $query_for_parent_groups = '(&(objectClass=' . $this->groupObjectClass . ')' . $or . ')';
             foreach ($this->basedn as $base_dn) {
                 // need to search on all basedns one at a time
                 $group_entries = $this->search($base_dn, $query_for_parent_groups);
                 // no attributes, just dns needed
                 if ($group_entries !== FALSE) {
                     $this->groupMembershipsFromEntryRecursive($group_entries, $all_group_dns, $tested_group_ids, $level + 1, $max_levels);
                 }
             }
         }
     }
     return TRUE;
 }
Пример #3
0
 /**
  * not working yet
  * will be ton of permission issues with service accounts
  * need configurable obj type to avoid binding to a million user entries, printers, etc.
  */
 private function deriveFromAttrGroupsResursive(&$all_groups, &$groups_by_level, $level, $derive_from_attribute_name, $max_depth)
 {
     // derive query with & of all groups at current level
     // e.g. (|(distinguishedname=cn=content editors,ou=groups,dc=ad,dc=myuniversity,dc=edu)(distinguishedname=cn=content approvers,ou=groups,dc=ad,dc=myuniversity,dc=edu))
     // execute query and loop through it to populate $groups_by_level[$level + 1]
     // call recursively provided max depth not excluded and $groups_by_level[$level + 1] > 0
     // this needs to be configurable also and default per ldap implementation
     $group_values = ldap_pear_escape_filter_value($groups_by_level[$derive_from_attribute_name][$level]);
     $filter = "(&\n  (objectClass=" . $this->groupObjectClass . ")\n  (" . $derive_from_attribute_name . "=*)\n  (|\n    (distinguishedname=" . join(")\n    (distinguishedname=", $group_values) . ")\n  )\n)";
     $level++;
     foreach ($this->basedn as $base_dn) {
         // need to search on all basedns one at a time
         $entries = $this->search($base_dn, $filter, array($derive_from_attribute_name));
         foreach ($entries as $entry) {
             $attr_values = array();
             if (is_array($entry) && count($entry)) {
                 if (isset($entry[$derive_from_attribute_name])) {
                     $attr_values = $entry[$derive_from_attribute_name];
                 } elseif (isset($entry[drupal_strtolower($derive_from_attribute_name)])) {
                     $attr_values = $entry[drupal_strtolower($derive_from_attribute_name)];
                 } else {
                     foreach ($entry as $attr_name => $values) {
                         if (strcasecmp($derive_from_attribute_name, $attr_name) != 0) {
                             continue;
                         }
                         $attr_values = $entry[$attr_name];
                         break;
                     }
                 }
                 if (count($attr_values)) {
                     for ($i = 0; $i < $attr_values['count']; $i++) {
                         $value = (string) $attr_values[$i];
                         if (!in_array($value, $all_groups)) {
                             $groups_by_level[$derive_from_attribute_name][$level][] = $value;
                             $all_groups[] = $value;
                         }
                     }
                 }
             }
         }
     }
     if (isset($groups_by_level[$derive_from_attribute_name][$level]) && count($groups_by_level[$derive_from_attribute_name][$level]) && $level < $max_depth) {
         $this->deriveFromAttrGroupsResursive($all_groups, $groups_by_level, $level, $derive_from_attribute_name, $max_depth);
     }
 }