/**
  * Perform an LDAP search.
  * @param string $basedn
  *   The search base. If NULL, we use $this->basedn. should not be esacaped
  *
  * @param string $filter
  *   The search filter. such as sAMAccountName=jbarclay.  attribute values (e.g. jbarclay) should be esacaped before calling
  * @param array $attributes
  *   List of desired attributes. If omitted, we only return "dn".
  *
  * @remaining params mimick ldap_search() function params
  *
  * @return
  *   An array of matching entries->attributes, or FALSE if the search is empty.
  */
 function search($base_dn = NULL, $filter, $attributes = array(), $attrsonly = 0, $sizelimit = 0, $timelimit = 0, $deref = LDAP_DEREF_NEVER, $scope = LDAP_SCOPE_SUBTREE)
 {
     //debug("feaux_server_filter=$filter");
     $filter = trim(str_replace(array("\n", "  "), array('', ''), $filter));
     // for test matching simplicity remove line breaks and tab spacing
     // debug("filter=$filter");
     // debug('search');  debug("base_dn: $base_dn"); debug("filter:<pre>$filter</pre>");
     $my_debug = $filter == "(samaccountname=verykool)" || $filter == "(sAMAccountName=verykool)";
     //  if ($my_debug) {debug('attributes'); debug($attributes); debug('search');  debug("base_dn: $base_dn"); debug("filter:<pre>$filter</pre>");}
     if ($base_dn == NULL) {
         if (count($this->basedn) == 1) {
             $base_dn = $this->basedn[0];
         } else {
             return FALSE;
         }
     }
     // return prepolulated search results in test data array if present
     if (isset($this->searchResults[$filter][$base_dn])) {
         //  if ($my_debug) {debug('set search results'); debug($this->searchResults[$filter][$base_dn]);}
         return $this->searchResults[$filter][$base_dn];
     }
     $base_dn = drupal_strtolower($base_dn);
     $filter = strtolower(trim($filter, "()"));
     list($filter_attribute, $filter_value) = explode('=', $filter);
     if (strtolower($filter_attribute) == 'dn') {
         // don't allow filtering on dn.  filters should use distinguishedName
         continue;
     }
     //  $filter_value = ldap_pear_unescape_filter_value($filter_value);
     // need to perform feaux ldap search here with data in
     $results = array();
     // debug('test users'); debug($this->testUsers); debug("filter_attribute=$filter_attribute, filter_value=$filter_value");
     foreach ($this->testUsers as $dn => $user_data) {
         $my_debug2 = $my_debug && $dn == 'cn=Flintstone\\, Wilma,ou=guest accounts,dc=ad,dc=myuniversity,dc=edu';
         // if ($my_debug2) {debug('test user ' . $dn); debug($user_data);}
         $user_data_lcase = array();
         foreach ($user_data['attr'] as $attr => $values) {
             $user_data_lcase['attr'][drupal_strtolower($attr)] = $values;
         }
         // if not in basedn, skip
         // eg. basedn ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
         // should be leftmost string in:
         // cn=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
         $dn = strtolower($dn);
         $pos = stripos($dn, $base_dn);
         if ($pos === FALSE || strcasecmp($base_dn, substr($dn, 0, $pos + 1)) == FALSE) {
             if ($my_debug2) {
                 debug("dn={$dn} not in base_dn={$base_dn}");
             }
             continue;
             // not in basedn
         }
         // check for mixed case and lowercase attribute's existance
         // trying to mimic ldap implementation
         if (isset($user_data['attr'][$filter_attribute])) {
             $contained_values = $user_data['attr'][$filter_attribute];
             // if ($my_debug2) { debug('mixed case match success');}
         } elseif (isset($user_data_lcase['attr'][ldap_server_massage_text($filter_attribute, 'attr_name', LDAP_SERVER_MASSAGE_QUERY_ARRAY)])) {
             $contained_values = $user_data_lcase['attr'][ldap_server_massage_text($filter_attribute, 'attr_name', LDAP_SERVER_MASSAGE_QUERY_ARRAY)];
             //  if ($my_debug2) { debug('lower case match success');}
         } else {
             // if ($my_debug2) {debug('match fail');}
             continue;
         }
         //debug("contained_values"); debug($contained_values);
         unset($contained_values['count']);
         if (!in_array($filter_value, array_values($contained_values))) {
             //   if ($my_debug2) { debug("match to value $filter_attribute=$filter_value failed");}
             continue;
         }
         // loop through all attributes, if any don't match continue
         $user_data_lcase['attr']['distinguishedname'] = $dn;
         if ($attributes) {
             $selected_user_data = array();
             foreach ($attributes as $i => $attr_name) {
                 $key = drupal_strtolower($attr_name);
                 $selected_user_data[$key] = isset($user_data_lcase['attr'][$key]) ? $user_data_lcase['attr'][$key] : NULL;
             }
             $results[] = $selected_user_data;
         } elseif (isset($user_data_lcase['attr'])) {
             $results[] = $user_data_lcase['attr'];
         }
     }
     //    if ($my_debug) { debug("results post user loop"); debug($results);}
     foreach ($this->testGroups as $dn => $group_data) {
         // debug("group dn $dn"); debug($group_data);
         // if not in basedn, skip
         // eg. basedn ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
         // should be leftmost string in:
         // cn=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
         $pos = strpos($dn, $base_dn);
         if ($pos === FALSE || strcasecmp($base_dn, substr($dn, 0, $pos + 1)) == FALSE) {
             continue;
             // not in basedn
         } else {
         }
         // if doesn't filter attribute has no data, continue
         if (!isset($group_data['attr'][$filter_attribute])) {
             continue;
         }
         // if doesn't match filter, continue
         $contained_values = $group_data['attr'][$filter_attribute];
         unset($contained_values['count']);
         if (!in_array($filter_value, array_values($contained_values))) {
             continue;
         }
         // loop through all attributes, if any don't match continue
         // $group_data['attr']['distinguishedname'] = $dn;
         // $group_data['distinguishedname'] = $dn;
         if ($attributes) {
             $selected_group_data = array();
             foreach ($attributes as $key => $value) {
                 $selected_group_data[$key] = isset($group_data['attr'][$key]) ? $group_data['attr'][$key] : NULL;
             }
             $results[] = $selected_group_data;
         } else {
             $results[] = $group_data['attr'];
         }
         // debug($results);
     }
     $results['count'] = count($results);
     $results = $results['count'] > 0 ? $results : FALSE;
     // if ($my_debug) {  debug('search-results 2'); debug($results);}
     return $results;
 }
Example #2
0
 /**
  * Queries LDAP server for the user.
  *
  * @param string $drupal_user_name
  *
  * @param string or int $prov_event
  *   This could be anything, particularly when used by other modules.  Other modules should use string like 'mymodule_myevent'
  *   LDAP_USER_EVENT_ALL signifies get all attributes needed by all other contexts/ops
  *
  * @return associative array representing ldap data of a user.  for example of returned value.
  *   'sid' => ldap server id
  *   'mail' => derived from ldap mail (not always populated).
  *   'dn'   => dn of user
  *   'attr' => single ldap entry array in form returned from ldap_search() extension, e.g.
  *   'dn' => dn of entry
  */
 function userUserNameToExistingLdapEntry($drupal_user_name, $ldap_context = NULL)
 {
     $watchdog_tokens = array('%drupal_user_name' => $drupal_user_name);
     $ldap_username = $this->userUsernameToLdapNameTransform($drupal_user_name, $watchdog_tokens);
     if (!$ldap_username) {
         return FALSE;
     }
     if (!$ldap_context) {
         $attributes = array();
     } else {
         $attribute_maps = ldap_servers_attributes_needed($this->sid, $ldap_context);
         $attributes = array_keys($attribute_maps);
     }
     foreach ($this->basedn as $basedn) {
         if (empty($basedn)) {
             continue;
         }
         $filter = '(' . $this->user_attr . '=' . ldap_server_massage_text($ldap_username, 'attr_value', LDAP_SERVER_MASSAGE_QUERY_LDAP) . ')';
         $result = $this->search($basedn, $filter, $attributes);
         if (!$result || !isset($result['count']) || !$result['count']) {
             continue;
         }
         // Must find exactly one user for authentication to work.
         if ($result['count'] != 1) {
             $count = $result['count'];
             watchdog('ldap_servers', "Error: !count users found with {$filter} under {$basedn}.", array('!count' => $count), WATCHDOG_ERROR);
             continue;
         }
         $match = $result[0];
         // These lines serve to fix the attribute name in case a
         // naughty server (i.e.: MS Active Directory) is messing the
         // characters' case.
         // This was contributed by Dan "Gribnif" Wilga, and described
         // here: http://drupal.org/node/87833
         $name_attr = $this->user_attr;
         if (isset($match[$name_attr][0])) {
             // leave name
         } elseif (isset($match[drupal_strtolower($name_attr)][0])) {
             $name_attr = drupal_strtolower($name_attr);
         } else {
             if ($this->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {
                 $result = array('dn' => $match['dn'], 'mail' => $this->userEmailFromLdapEntry($match), 'attr' => $match, 'sid' => $this->sid);
                 return $result;
             } else {
                 continue;
             }
         }
         // Finally, we must filter out results with spaces added before
         // or after, which are considered OK by LDAP but are no good for us
         // We allow lettercase independence, as requested by Marc Galera
         // on http://drupal.org/node/97728
         //
         // Some setups have multiple $name_attr per entry, as pointed out by
         // Clarence "sparr" Risher on http://drupal.org/node/102008, so we
         // loop through all possible options.
         foreach ($match[$name_attr] as $value) {
             if (drupal_strtolower(trim($value)) == drupal_strtolower($ldap_username)) {
                 $result = array('dn' => $match['dn'], 'mail' => $this->userEmailFromLdapEntry($match), 'attr' => $match, 'sid' => $this->sid);
                 return $result;
             }
         }
     }
 }
Example #3
0
 public function deriveEmailFromEntry($ldap_entry)
 {
     if ($this->mail_attr) {
         // not using template
         return @$ldap_entry[ldap_server_massage_text($this->mail_attr, 'attr_name', LDAP_SERVER_MASSAGE_QUERY_ARRAY)][0];
     } elseif ($this->mail_template) {
         // template is of form [cn]@illinois.edu
         ldap_server_module_load_include('inc', 'ldap_servers', 'ldap_servers.functions');
         return ldap_server_token_replace($ldap_entry, $this->mail_template);
     } else {
         return FALSE;
     }
 }