/[drupal]/contributions/modules/ldap_integration/ldapgroups.module
ViewVC logotype

Diff of /contributions/modules/ldap_integration/ldapgroups.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.39, Tue Jul 28 14:03:05 2009 UTC revision 1.40, Tue Aug 25 13:23:37 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: ldapgroups.module,v 1.38 2009/07/27 16:28:19 miglius Exp $  // $Id: ldapgroups.module,v 1.39 2009/07/28 14:03:05 miglius Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 15  define('LDAPGROUPS_DEFAULT_ENTRIES_ATTRI Line 15  define('LDAPGROUPS_DEFAULT_ENTRIES_ATTRI
15  // Core API hooks  // Core API hooks
16    
17  /**  /**
  * Implements hook_init().  
  */  
 function ldapgroups_init() {  
   require_once(drupal_get_path('module', 'ldapgroups') .'/includes/LDAPInterface.inc');  
 }  
   
 /**  
18   * Implementation of hook_menu().   * Implementation of hook_menu().
19   */   */
20  function ldapgroups_menu() {  function ldapgroups_menu() {
# Line 60  function ldapgroups_menu() { Line 53  function ldapgroups_menu() {
53  function ldapgroups_user($op, &$edit, &$account, $category = NULL) {  function ldapgroups_user($op, &$edit, &$account, $category = NULL) {
54    switch ($op) {    switch ($op) {
55      case 'login':      case 'login':
56          require_once(drupal_get_path('module', 'ldapgroups') .'/includes/LDAPInterface.inc');
57          require_once(drupal_get_path('module', 'ldapgroups') .'/ldapgroups.inc');
58        ldapgroups_user_login($account);        ldapgroups_user_login($account);
59        break;        break;
60    }    }
61  }  }
62    
 //////////////////////////////////////////////////////////////////////////////  
 // hook_user() functions  
   
 /**  
  * Implements hook_user() login operation.  
  */  
 function ldapgroups_user_login(&$account) {  
   $authmap = user_get_authmaps($account->name);  
   if (!isset($authmap['ldapauth'])) {  
     // This user is not authenticated via lapauth.  
     return;  
   }  
   
   // Setup the global $_ldapgroups_ldap object.  
   if (!_ldapgroups_ldap_init($account))  
     return;  
   
   // First, we figure out the appropriate groups.  
   $groups = _ldapgroups_detect_groups($account);  
   
   // Apply groups restrictions.  
   if (count($groups_allow = _ldapgroups_ldap_info($account, 'ldapgroups_groups')) > 0 && count(array_intersect($groups, $groups_allow)) == 0) {  
     $account = user_load(0);  
     return;  
   }  
   
   // Then, we take every mapped role from the user, later below  
   // we'll grant back those deserved.  
   $account->ldap_drupal_roles = isset($account->ldap_drupal_roles) ? $account->ldap_drupal_roles : array();  
   foreach ($account->ldap_drupal_roles as $role) {  
     _ldapgroups_deny_role($account, $role);  
   }  
   
   // Are there LDAP groups for the user?  
   if ($groups === FALSE)  
     return TRUE;  
   
   // Next, we apply site-specific rules.  
   $groups = _ldapgroups_filter($account, $groups);  
   
   // At this point, the roles are in the full DN format.  
   $roles = array();  
   if (!empty($groups)) {  
     $ldapgroups_mappings = _ldapgroups_ldap_info($account, 'ldapgroups_mappings');  
     foreach ($groups as $group) {  
       $role = _ldapgroups_mapping($account, $group);  
       _ldapgroups_create_role($role);  
       _ldapgroups_grant_role($account, $role);  
       $roles[] = $role;  
     }  
   }  
   
   // Store roles in the user object so we know which ones  
   // were granted here.  
   user_save($account, array('ldap_drupal_roles' => $roles));  
 }  
   
 //////////////////////////////////////////////////////////////////////////////  
 // Auxiliary functions  
   
 /**  
  * Detect user groups from the LDAP.  
  *  
  * @param $user  
  *   A user object.  
  *  
  * @return  
  *   An array of user groups.  
  */  
 function _ldapgroups_detect_groups($user) {  
   global $_ldapgroups_ldap;  
   
   // Nothing to do if the user is not LDAP authentified  
   // or there are no groups configured.  
   if (!(_ldapgroups_ldap_info($user, 'ldapgroups_in_dn') || _ldapgroups_ldap_info($user, 'ldapgroups_in_attr') || _ldapgroups_ldap_info($user, 'ldapgroups_as_entries')))  
     return FALSE;  
   
   // First try to connect with the stored user's DN and password.  
   // If unsuccessful, connect with the BINDDN and BINDPW stored in the database for this config.  
   $dn = isset($_SESSION['ldap_login']['dn']) ? $_SESSION['ldap_login']['dn'] : '';  
   $pass = isset($_SESSION['ldap_login']['pass']) ? $_SESSION['ldap_login']['pass'] : '';  
   
   // If I try to connect using a blank dn and pass, I dont get an error until ldap_read,  
   // so I just check to see if they would be blank, based on ldap_forget_passwords, and  
   // make it read from the database.  
   if (LDAPAUTH_FORGET_PASSWORDS || !$_ldapgroups_ldap->connect($dn, $pass)) {  
     $row2 = db_fetch_object(db_query("SELECT binddn, bindpw FROM {ldapauth} WHERE sid = %d", $_ldapgroups_ldap->getOption('sid')));  
     $dn = $row2->binddn;  
     $pass = $row2->bindpw;  
     if (!$_ldapgroups_ldap->connect($dn, $pass)) {  
       watchdog('ldapgroups', "User login: user %name data could not be read in the LDAP directory", array('%name' => $user->name), WATCHDOG_WARNING);  
       return FALSE;  
     }  
   }  
   
   // Strategy 1: group extracted from user's DN.  
   $dn_groups = array();  
   if (_ldapgroups_ldap_info($user, 'ldapgroups_in_dn')) {  
     $pairs = explode(',', $user->ldap_dn);  
     foreach ($pairs as $p) {  
       $pair = explode('=', $p);  
       if (drupal_strtolower(trim($pair[0])) == drupal_strtolower(_ldapgroups_ldap_info($user, 'ldapgroups_dn_attribute')))  
         $dn_groups[] = trim($pair[1]);  
     }  
   }  
   
   // Strategy 2: groups in user attributes.  
   $attrib_groups = array();  
   if (_ldapgroups_ldap_info($user, 'ldapgroups_in_attr')) {  
     foreach (_ldapgroups_ldap_info($user, 'ldapgroups_attr') as $attribute)  
       $attrib_groups = array_merge($attrib_groups, $_ldapgroups_ldap->retrieveMultiAttribute($user->ldap_dn, $attribute));  
   }  
   
   // Strategy 3: groups as entries.  
   $entries_groups = array();  
   $ldapgroups_entries_attribute = _ldapgroups_ldap_info($user, 'ldapgroups_entries_attribute');  
   if (_ldapgroups_ldap_info($user, 'ldapgroups_as_entries')) {  
     foreach (_ldapgroups_ldap_info($user, 'ldapgroups_entries') as $branch) {  
       $entries = $_ldapgroups_ldap->search($branch, $ldapgroups_entries_attribute .'='. $user->ldap_dn, array($ldapgroups_entries_attribute));  
       if (empty($entries) || $entries['count'] == 0)  
         $entries = $_ldapgroups_ldap->search($branch, $ldapgroups_entries_attribute .'='. $user->name, array($ldapgroups_entries_attribute));  
       foreach ($entries as $entry) {  
         if (isset($entry['dn']))  
           $entries_groups[] = $entry['dn'];  
       }  
     }  
   }  
   
   $_ldapgroups_ldap->disconnect();  
   return array_unique(array_merge($dn_groups, $attrib_groups, $entries_groups));  
 }  
   
 /**  
  * Grant a user with a role.  
  *  
  * @param $user  
  *   A user object.  
  * @param $rolename  
  *   A name of the role.  
  *  
  * @return  
  */  
 function _ldapgroups_grant_role($user, $rolename) {  
   $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);  
   if ($row = db_fetch_object($result)) {  
     $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);  
     if (!db_fetch_object($result)) {  
       db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $user->uid, $row->rid);  
     }  
   }  
 }  
   
 /**  
  * Deny a user with a role.  
  *  
  * @param $user  
  *   A user object.  
  * @param $rolename  
  *   A name of the role.  
  *  
  * @return  
  */  
 function _ldapgroups_deny_role($user, $rolename) {  
   $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);  
   if ($row = db_fetch_object($result)) {  
     $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);  
     if (db_fetch_object($result)) {  
       db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);  
     }  
   }  
 }  
   
 /**  
  * Create a new role.  
  *  
  * @param $rolename  
  *   A name of the role.  
  *  
  * @return  
  */  
 function _ldapgroups_create_role($rolename) {  
   $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);  
   if (!($row = db_fetch_object($result)))  
     db_query("INSERT INTO {role} (name) VALUES ('%s')", $rolename);  
 }  
   
 /**  
  * Filters groups only to a explicitely defined groups.  
  *  
  * @param $groups  
  *   An array of the LDAP groups.  
  *  
  * @return  
  *   An array of the filtered groups.  
  */  
 function _ldapgroups_filter($account, $groups) {  
   if (_ldapgroups_ldap_info($account, 'ldapgroups_mappings_filter') && count(_ldapgroups_ldap_info($account, 'ldapgroups_mappings') > 0)) {  
     $groups_new = array();  
     foreach ($groups as $group) {  
       foreach (_ldapgroups_ldap_info($account, 'ldapgroups_mappings') as $group_approved => $role) {  
         if (strcasecmp($group_approved, $group) == 0)  
           $groups_new[] = $group;  
       }  
     }  
     $groups = $groups_new;  
   }  
   
   if ($code = _ldapgroups_ldap_info($account, 'ldapgroups_filter_php'))  
     $groups = eval($code);  
   
   return $groups;  
 }  
   
 /**  
  * Maps LDAP group name to a Drupal role.  
  *  
  * @param $user  
  *   A user object.  
  * @param $group  
  *   A LDAP group name.  
  *  
  * @return  
  *   An Drupal role.  
  */  
 function _ldapgroups_mapping($user, $group) {  
   $ldapgroups_mappings = _ldapgroups_ldap_info($user, 'ldapgroups_mappings');  
   if (isset($ldapgroups_mappings[$group]))  
     return $ldapgroups_mappings[$group];  
   else if (preg_match('/^[^=]+=([^,]+),.*$/', $group, $matches))  
     return $matches[1];  
   else  
     return $group;  
 }  
   
 /**  
  * Initiates the LDAPInterfase class.  
  *  
  * @param $sid  
  *   A server ID or user object.  
  *  
  * @return  
  */  
 function _ldapgroups_ldap_init($sid) {  
   global $_ldapgroups_ldap;  
   
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))  
     return;  
   
   static $servers = array();  
   if (!isset($servers[$sid]))  
     $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = 1 AND sid = %d", $sid));  
   
   if ($servers[$sid]) {  
     $_ldapgroups_ldap = new LDAPInterface();  
     $_ldapgroups_ldap->setOption('sid', $sid);  
     $_ldapgroups_ldap->setOption('name', $servers[$sid]->name);  
     $_ldapgroups_ldap->setOption('server', $servers[$sid]->server);  
     $_ldapgroups_ldap->setOption('port', $servers[$sid]->port);  
     $_ldapgroups_ldap->setOption('tls', $servers[$sid]->tls);  
     $_ldapgroups_ldap->setOption('encrypted', $servers[$sid]->encrypted);  
     $_ldapgroups_ldap->setOption('basedn', $servers[$sid]->basedn);  
     $_ldapgroups_ldap->setOption('user_attr', $servers[$sid]->user_attr);  
     return $_ldapgroups_ldap;  
   }  
 }  
   
 /**  
  * Retrieve the saved ldapgroups saved setting.  
  *  
  * @param $sid  
  *   A server ID or user object.  
  * @param $req  
  *   An attribute name.  
  *  
  * @return  
  *   The attribute value.  
  */  
 function _ldapgroups_ldap_info($sid, $req) {  
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))  
     return;  
   
   static $servers = array();  
   if (!isset($servers[$sid]))  
     $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));  
   
   switch ($req) {  
     case 'ldapgroups_in_dn':  
       return $servers[$sid]->ldapgroups_in_dn;  
     case 'ldapgroups_dn_attribute':  
       return !empty($servers[$sid]->ldapgroups_dn_attribute) ? $servers[$sid]->ldapgroups_dn_attribute : LDAPGROUPS_DEFAULT_DN_ATTRIBUTE;  
     case 'ldapgroups_in_attr':  
       return $servers[$sid]->ldapgroups_in_attr;  
     case 'ldapgroups_attr':  
       return !empty($servers[$sid]->ldapgroups_attr) ? unserialize($servers[$sid]->ldapgroups_attr) : array();  
     case 'ldapgroups_as_entries':  
       return $servers[$sid]->ldapgroups_as_entries;  
     case 'ldapgroups_entries':  
       return !empty($servers[$sid]->ldapgroups_entries) ? unserialize($servers[$sid]->ldapgroups_entries) : array();  
     case 'ldapgroups_entries_attribute':  
       return !empty($servers[$sid]->ldapgroups_entries_attribute) ? $servers[$sid]->ldapgroups_entries_attribute : LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE;  
     case 'ldapgroups_mappings':  
       return !empty($servers[$sid]->ldapgroups_mappings) ? unserialize($servers[$sid]->ldapgroups_mappings) : array();  
     case 'ldapgroups_mappings_filter':  
       return $servers[$sid]->ldapgroups_mappings_filter;  
     case 'ldapgroups_filter_php':  
       return $servers[$sid]->ldapgroups_filter_php;  
     case 'ldapgroups_groups':  
       return !empty($servers[$sid]->ldapgroups_groups) ? unserialize($servers[$sid]->ldapgroups_groups) : array();  
   }  
 }  
   

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.40

  ViewVC Help
Powered by ViewVC 1.1.2