ldapauth module.');
break;
case 'admin/settings/ldapgroups':
$output = t('Configure the Drupal Roles mapping with the LDAP Groups below. ');
$output .= t('Only the %activated LDAP configurations are listed. ', array('%activated' => 'activated'));
$output .= t('Additional LDAP Sources may be configured/enabled in the ');
$output .= l(t('!modulename', array('!modulename' => 'LDAP Integration')), 'admin/settings/ldapauth');
$output .= t(' administration area.
PLEASE NOTE : advanced configuration for this module can be set by editing the module\'s config file, located at modules/ldap_integration/ldap_integration/ldapgroups.conf.php in your Drupal install.
');
break;
}
return $output;
}
/**
* Implementation of hook_menu()
*/
function ldapgroups_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/settings/ldapgroups',
'title' => t('LDAP Groups'),
'description' => t('Configure LDAP Groups Settings'),
'callback' => 'ldapgroups_admin_list',
'access' => user_access('administer ldap modules'),
);
$items[] = array(
'path' => 'admin/settings/ldapgroups/edit',
'title' => t('LDAP Groups'),
'callback' => 'drupal_get_form',
'callback arguments' => array('ldapgroups_admin_edit'),
'type' => MENU_CALLBACK,
'weight' => 1,
'access' => user_access('administer ldap modules'),
);
$items[] = array(
'path' => 'admin/settings/ldapgroups/reset',
'title' => t('LDAP Groups'),
'callback' => 'drupal_get_form',
'callback arguments' => array('ldapgroups_admin_edit'),
'type' => MENU_CALLBACK,
'weight' => 1,
'access' => user_access('administer ldap modules'),
);
}
return $items;
}
// ldapgroups admin pages
function ldapgroups_admin_list() {
$result = db_query("SELECT sid, name FROM {ldapauth} WHERE status = '%s' ORDER BY sid", 1);
$rows = array();
while ($row = db_fetch_object($result)) {
$rows[] = array(check_plain($row->name), l(t('edit'), 'admin/settings/ldapgroups/edit/'.$row->sid), l(t('reset'), 'admin/settings/ldapgroups/reset/'.$row->sid));
}
$header = array(
t('LDAP Config'),
array(
'data' => t('Operations'),
'colspan' => 2
)
);
return theme('table', $header, $rows);
}
function ldapgroups_admin_edit() {
$sid = arg(4);
if ((arg(3) == 'reset') && is_numeric($sid)) {
$form['sid'] = array(
'#type' => 'value',
'#value' => $sid,
);
return confirm_form(
$form,
t('Are you sure you want to reset the groups mapping to defaults ?'),
'admin/settings/ldapgroups',
t('This action cannot be undone.'),
t('Reset'),
t('Cancel')
);
}
elseif ((arg(3) == 'edit') && ($sid)) {
$edit = db_fetch_array(db_query("SELECT ldap_groups_in_dn, ldap_groups_in_dn_desc, ldap_group_dn_attribute, ldap_groups_in_attr, ldap_group_attr, ldap_groups_as_entries, ldap_group_entries, ldap_group_entries_attribute FROM {ldapauth} WHERE sid = %d", $sid));
$form['server-settings']['ldap_groups_in_dn'] = array(
'#type' => 'checkbox',
'#title' => t('Group is specified in user\'s DN'),
'#default_value' => $edit['ldap_groups_in_dn'],
'#prefix' => '',
'#suffix' => ' '
);
$form['server-settings']['ldap_groups_in_dn_desc'] = array(
'#value' => 'Check this option if your users\' DNs look like cn=jdoe,ou=Group1 ,cn=example,cn=com and Group1 turns out to be the group you want.
'
);
$form['server-settings']['ldap_group_dn_attribute'] = array(
'#type' => 'textfield',
'#title' => t('Attribute of the DN which contains the group name'),
'#default_value' => $edit['ldap_group_dn_attribute'],
'#size' => 50,
'#maxlength' => 255,
'#description' => t('The name of the attribute which contains the group name. In the example above, it would be ou , as the DN contains the string ou=Group1 and Group1 happens to be the desired group name.'),
'#suffix' => ' '
);
$form['server-settings']['ldap_groups_in_attr'] = array(
'#type' => 'checkbox',
'#title' => t('Groups are specified by LDAP attributes'),
'#default_value' => $edit['ldap_groups_in_attr'],
'#prefix' => '',
'#suffix' => ' '
);
$form['server-settings']['ldap_group_attr'] = array(
'#type' => 'textarea',
'#title' => t('Attribute names (one per line)'),
'#default_value' => $edit['ldap_group_attr'],
'#cols' => 50,
'#rows' => 6,
'#description' => t('If the groups are stored in the user entries, along with the rest of their data, then enter here a list of attributes which may contain them.'),
'#suffix' => ' '
);
$form['server-settings']['ldap_groups_as_entries'] = array(
'#type' => 'checkbox',
'#title' => t('Groups exist as LDAP entries where a multivalued attribute contains the members\' CNs'),
'#default_value' => $edit['ldap_groups_as_entries'],
'#prefix' => '',
'#suffix' => ' '
);
$form['server-settings']['ldap_group_entries'] = array(
'#type' => 'textarea',
'#title' => t('Nodes containing groups (one per line)'),
'#default_value' => $edit['ldap_group_entries'],
'#cols' => 50,
'#rows' => 6,
'#description' => t('Enter here a list of nodes from where groups should be searched for. The module will look them up recursively from the given nodes.'),
);
$form['server-settings']['ldap_group_entries_attribute'] = array(
'#type' => 'textfield',
'#title' => t('Attribute holding group members'),
'#default_value' => $edit['ldap_group_entries_attribute'],
'#size' => 50,
'#maxlength' => 255,
'#description' => t('Name of the multivalued attribute which holds the CNs of group members, for example: !attr', array('!attr' => theme('placeholder', LDAP_DEFAULT_GROUP_ENTRIES_ATTRIBUTE))),
);
$form['sid'] = array(
'#type' => 'hidden',
'#value' => $sid,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save configuration',
);
}
return $form;
}
function ldapgroups_admin_edit_submit($form_id, $form_values) {
$sid = $form_values['sid'];
if ($form_values['confirm']) {
// reset the ldapgroups config to default values - in effect, deactivate this config
db_query("UPDATE {ldapauth} SET ldap_groups_in_dn = '%d', ldap_groups_in_dn_desc = '%d', ldap_group_dn_attribute = '%s', ldap_groups_in_attr = '%d', ldap_group_attr = '%s', ldap_groups_as_entries = '%d', ldap_group_entries = '%s', ldap_group_entries_attribute = '%s' WHERE sid = %d", '0', '0', '', '0', '', '0', '', '', $sid);
watchdog('ldap', t('ldapgroups: ldap config %config updated.' ,array('%config' => $sid)));
}
else {
// update the ldapgroups configuration
db_query("UPDATE {ldapauth} SET ldap_groups_in_dn = '%d', ldap_groups_in_dn_desc = '%d', ldap_group_dn_attribute = '%s', ldap_groups_in_attr = '%d', ldap_group_attr = '%s', ldap_groups_as_entries = '%d', ldap_group_entries = '%s', ldap_group_entries_attribute = '%s' WHERE sid = %d", $form_values['ldap_groups_in_dn'], $form_values['ldap_groups_in_dn_desc'], $form_values['ldap_group_dn_attribute'], $form_values['ldap_groups_in_attr'], $form_values['ldap_group_attr'], $form_values['ldap_groups_as_entries'], $form_values['ldap_group_entries'], $form_values['ldap_group_entries_attribute'], $sid);
watchdog('ldap', t('ldapgroups: ldap config %config updated.' ,array('%config' => $sid)));
}
return 'admin/settings/ldapgroups';
}
/**
* Implementation of hook_user()
*/
function ldapgroups_user($op, &$edit, &$user, $category = NULL) {
switch($op) {
case 'login':
ldapgroups_user_login($user);
break;
}
}
/*********************************
* 2. Delegate functions *
*********************************/
function ldapgroups_user_login(&$user) {
if (!$user->ldap_authentified) {
return true;
}
// setup the global $ldapdata_ldap object
if (!_ldapgroups_ldap_init($user)) {
return;
}
// First, we take every mapped role from the user, later below
// we'll grant back those deserved.
//dsm($user);
$user->ldap_drupal_roles = isset($user->ldap_drupal_roles) ? $user->ldap_drupal_roles : array();
foreach ($user->ldap_drupal_roles as $role) {
//dsm($role);
_ldapgroups_deny_role($user, $role);
}
// Then, we figure out the appropriate groups
$groups = _ldapgroups_detect_groups($user);
if ($groups === false) {
// Oh, this means this user didn't even have to be here. Bye!
return true;
}
// Next, we apply site-specific rules
if (function_exists('ldapgroups_roles_filter')) {
$roles = ldapgroups_roles_filter($groups);
}
else {
// grant all the roles
$roles = $groups;
}
// At this point, the roles are in the full DN format
// Turn them in into friendly names
// Finally, we grant the roles
//need to check for empty roles
if ($roles) {
foreach ($roles as $role) {
$friendly_role = _ldapgroups_translate_role($role);
_ldapgroups_create_role($friendly_role);
_ldapgroups_grant_role($user, $friendly_role);
}
}
// Store roles in the user object so we know which ones
// were granted here
user_save($user, array('ldap_drupal_roles' => $roles));
}
/*********************************
* 3. Auxiliary functions *
*********************************/
/**
* Depending on ldap schema, converts ldap group to drupal role
*/
function _ldapgroups_translate_role($ldap_role) {
global $ldap_group_role_mappings;
if ($friendly_role = $ldap_group_role_mappings[$ldap_role]) {
// Just that
}
else if (preg_match('/^[^=]*=([^,]*),.*$/', $ldap_role, $matches)) {
$friendly_role = $matches[1];
}
else {
$friendly_role = $ldap_role;
}
return $friendly_role;
}
function _ldapgroups_detect_groups($user) {
global $ldapgroups_ldap;
// Nothing to do if the user is not LDAP authentified
// or there are no groups configured
$row = db_fetch_object(db_query("SELECT ldap_groups_in_dn, ldap_groups_in_attr, ldap_groups_as_entries, ldap_group_dn_attribute, ldap_group_attr, ldap_group_entries, ldap_group_entries_attribute FROM {ldapauth} WHERE name = '%s'", $ldapgroups_ldap->getOption('name')));
$groups_in_dn = $row->ldap_groups_in_dn;
$groups_in_attr = $row->ldap_groups_in_attr;
$groups_as_entries = $row->ldap_groups_as_entries;
$group_dn_attribute = $row->ldap_group_dn_attribute ? $row->ldap_group_dn_attribute : LDAP_DEFAULT_GROUP_DN_ATTRIBUTE;
$group_attr = $row->ldap_group_attr;
$group_entries = $row->ldap_group_entries ? $row->ldap_group_entries : '';
if ( ! ($groups_in_dn || $groups_in_attr || $groups_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 (!$ldapgroups_ldap->connect($dn, $pass)) {
$row2 = db_fetch_object(db_query("SELECT binddn, bindpw FROM {ldapauth} WHERE name = '%s'", $ldapgroups_ldap->getOption('name')));
$dn = $row2->binddn;
$pass = $row2->bindpw;
if (!$ldapgroups_ldap->connect($dn,$pass)) {
watchdog('user', "User login: user $user->name's data could not be read in the LDAP directory", WATCHDOG_WARNING);
return false;
}
}
// Strategy 1: group extracted from user's DN
$dn_groups = array();
if ($groups_in_dn && $dn_group_attr = $group_dn_attribute) {
$pairs = explode(',', $user->ldap_dn);
foreach ($pairs as $p) {
$pair = explode('=', $p);
if (strtoupper(trim($pair[0])) == strtoupper($dn_group_attr)) {
$dn_groups[] = trim($pair[1]);
}
}
}
// Strategy 2: groups in user attributes
$attrib_groups = array();
if ($groups_in_attr && $attributes = $group_attr) {
$attributes_array = explode("\r\n", $attributes);
foreach ($attributes_array as $attribute) {
$tmp = $ldapgroups_ldap->retrieveMultiAttribute($user->ldap_dn, $attribute);
$attrib_groups = array_merge($attrib_groups, $tmp);
}
}
// Strategy 3: groups as entries
$entries_groups = array();
if ($groups_as_entries && $branches = $group_entries) {
$branches_array = explode("\r\n", $branches);
$group_attr = ($row->ldap_group_entries_attribute ? $row->ldap_group_entries_attribute : LDAP_DEFAULT_GROUP_ENTRIES_ATTRIBUTE);
foreach ($branches_array as $branch) {
$entries = $ldapgroups_ldap->search($branch, "$group_attr=$user->ldap_dn", array($group_attr));
if ($entries['count'] == 0) {
$entries = $ldapgroups_ldap->search($branch, "$group_attr=$user->name", array($group_attr));
}
foreach ($entries as $entry) {
if (isset($entry['dn'])) {
$entries_groups[] = $entry['dn'];
}
}
}
}
$ldapgroups_ldap->disconnect();
return array_merge($dn_groups, $attrib_groups, $entries_groups);
}
function _ldapgroups_grant_role($user, $rolename) {
$result = db_query("SELECT * FROM {role} WHERE name = '$rolename'");
$role_exists = db_num_rows($result);
if ($role_exists) {
$role = db_fetch_object($result);
$result = db_query("SELECT * FROM {users_roles} WHERE uid = $user->uid AND rid = $role->rid");
$role_already_given = db_num_rows($result);
if (!$role_already_given) {
db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $user->uid, $role->rid);
}
}
}
function _ldapgroups_deny_role($user, $rolename) {
$drupal_role = _ldapgroups_translate_role($rolename);
$result = db_query("SELECT * FROM {role} WHERE name = '$drupal_role'");
$role_exists = db_num_rows($result);
if ($role_exists) {
$role = db_fetch_object($result);
$result = db_query("SELECT * FROM {users_roles} WHERE uid = $user->uid AND rid = $role->rid");
$role_present = db_num_rows($result);
if ($role_present) {
db_query("DELETE FROM {users_roles} WHERE uid = $user->uid AND rid = $role->rid");
}
}
}
function _ldapgroups_create_role($rolename) {
$result = db_query("SELECT * FROM {role} WHERE name = '$rolename'");
$role_exists = db_num_rows($result);
if (!$role_exists) {
db_query("INSERT INTO {role} (name) VALUES ('%s')", $rolename);
}
}
function _ldapgroups_ldap_init(&$user) {
global $ldapgroups_ldap;
if ($row = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = '%s' AND name = '%s'", 1, $user->ldap_config))) {
$ldapgroups_ldap = new LDAPInterface();
$ldapgroups_ldap->setOption('name', $row->name);
$ldapgroups_ldap->setOption('server', $row->server);
$ldapgroups_ldap->setOption('port', $row->port);
$ldapgroups_ldap->setOption('tls', $row->tls);
$ldapgroups_ldap->setOption('encrypted', $row->encrypted);
$ldapgroups_ldap->setOption('basedn', $row->basedn);
$ldapgroups_ldap->setOption('user_attr', $row->user_attr);
return $ldapgroups_ldap;
}
else {
return;
}
}
?>