first run at ldap group support

This commit is contained in:
Rob Ostensen 2010-03-21 02:50:14 -05:00 committed by Andrew McMillan
parent d8e34dd211
commit 34c1fee3c6
3 changed files with 158 additions and 4 deletions

View File

@ -221,14 +221,19 @@ $c->collections_always_exist = false;
// 'protocolVersion' => '3', //Version of LDAP protocol to use
// 'baseDNUsers'=> 'dc=tennaxia,dc=net', //where to look at valid user
// 'filterUsers' => 'objectClass=kolabInetOrgPerson', //filter which must validate a user according to RFC4515, i.e. surrounded by brackets
// 'baseDNGroups' => 'ou=divisions,dc=tennaxia,dc=net', //not used ATM
// 'filterGroups' => 'objectClass=groupOfUniqueNames', //not used ATM
// 'baseDNGroups' => 'ou=divisions,dc=tennaxia,dc=net', //where to look for groups
// 'filterGroups' => 'objectClass=groupOfUniqueNames', //filter with same rules as filterUsers
/** /!\ "username" should be set and "updated" must be set **/
// 'mapping_field' => array("username" => "uid",
// "updated" => "modifyTimestamp",
// "fullname" => "cn" ,
// "email" =>"mail"
// ), //used to create the user based on his ldap properties
// 'group_mapping_field' => array("username" => "cn",
// "updated" => "modifyTimestamp",
// "fullname" => "cn" ,
// "members" =>"memberUid"
// ), //used to create the group based on the ldap properties
/** used to set default value for all users, will be overcharged by ldap if defined also in mapping_field **/
// 'default_value' => array("date_format_type" => "E","locale" => "fr_FR"),
/** foreach key set start and length in the string provided by ldap

View File

@ -24,6 +24,10 @@ if( function_exists("sync_LDAP") && isset($_POST['Sync_LDAP'])){
sync_LDAP();
}
if( function_exists("sync_LDAP_groups") && isset($_POST['Sync_LDAP_groups'])){
sync_LDAP_groups();
}
if(isset($_POST['import_from_directory'])){
Tools::importFromDirectory();
}
@ -52,6 +56,15 @@ class Tools {
$html .= "</table>\n";
$html .= $ef->SubmitButton( "Sync_LDAP", translate('Submit'));
$html .= '<h1>'.translate('Sync LDAP Groups with RSCDS') .'</h1>';
$html .= "<table width=\"100%\" class=\"data\">\n";
$html .= $ef->StartForm( array("autocomplete" => "off" ) );
$html .= sprintf( "<tr><td style=\"text-align:left\" colspan=\"2\" >%s</td></tr>\n",
translate("This operation does the following: <ul><li>check valid groups in LDAP directory</li> <li>check groups in DAViCal</li></ul> then <ul><li>if a group is present in DAViCal but not in LDAP set as inactive in DAViCal</li> <li>if a group is present in LDAP but not in DAViCal create the group in DAViCal</li> <li>if a group in present in LDAP and DAViCal then update information in DAViCal</li> </ul>"));
$html .= "</table>\n";
$html .= $ef->SubmitButton( "Sync_LDAP_groups", translate('Submit'));
$html .= $ef->EndForm();
$html .= "</div>";

View File

@ -114,7 +114,7 @@ class ldapDrivers
//root to start search
$this->baseDNUsers = is_string($config['baseDNUsers']) ? array($config['baseDNUsers']) : $config['baseDNUsers'];
$this->filterUsers = (isset($config['filterUsers']) ? $config['filterUsers'] : null);
$this->baseDNGroups = (isset($config['baseDNGroups']) ? $config['baseDNGroups'] : null);
$this->baseDNGroups = is_string($config['baseDNGroups']) ? array($config['baseDNGroups']) : $config['baseDNGroups'];
$this->filterGroups = (isset($config['filterGroups']) ? $config['filterGroups'] : null);
}
@ -147,6 +147,36 @@ class ldapDrivers
}
return $ret;
}
/**
* Retrieve all groups from the LDAP directory
*/
function getAllGroups($attributes){
global $c;
$query = $this->ldap_query_all;
foreach($this->baseDNGroups as $baseDNGroups) {
$entry = $query($this->connect,$baseDNGroups,$this->filterGroups,$attributes);
if (!ldap_first_entry($this->connect,$entry)) {
$c->messages[] = sprintf(translate('Error NoGroupFound with filter >%s<, attributes >%s< , dn >%s<'),
$this->filterUsers,
join(', ', $attributes),
$baseDNGroups);
}
$row = array();
for($i = ldap_first_entry($this->connect,$entry);
$i && $arr = ldap_get_attributes($this->connect,$i);
$i = ldap_next_entry($this->connect,$i) ) {
for ($j=0; $j < $arr['count']; $j++) {
$row[$arr[$j]] = count($arr[$arr[$j]])>2?$arr[$arr[$j]]:$arr[$arr[$j]][0];
}
$ret[]=$row;
}
}
return $ret;
}
/**
* Returns the result of the LDAP query
@ -322,6 +352,112 @@ function LDAP_check($username, $password ){
}
/**
* sync LDAP Groups against the DB
*/
function sync_LDAP_groups(){
global $c;
$ldapDriver = getStaticLdap();
if($ldapDriver->valid){
$mapping = $c->authenticate_hook['config']['group_mapping_field'];
//$attributes = array('cn','modifyTimestamp','memberUid');
$attributes = array_values($mapping);
$ldap_groups_tmp = $ldapDriver->getAllGroups($attributes);
if ( sizeof($ldap_groups_tmp) == 0 )
return;
foreach($ldap_groups_tmp as $key => $ldap_group){
$ldap_groups_info[$ldap_group[$mapping['username']]] = $ldap_group;
unset ( $ldap_groups_info[$ldap_group[$mapping['username']]][$mapping['members']]['count'] );
unset($ldap_groups_tmp[$key]);
}
$db_groups = array ();
$db_group_members = array ();
$qry = new AwlQuery( "SELECT g.username AS group_name, member.username AS member_name FROM dav_principal g JOIN group_member ON (g.principal_id=group_member.group_id) JOIN dav_principal member ON (member.principal_id=group_member.member_id) WHERE g.type_id = 3");
$qry->Exec('sync_LDAP',__LINE__,__FILE__);
while($db_group = $qry->Fetch()) {
$db_groups[$db_group->group_name] = $db_group->group_name;
$db_group_members[$db_group->group_name][] = $db_group->member_name;
}
$ldap_groups = array_keys($ldap_groups_info);
// users only in ldap
$groups_to_create = array_diff($ldap_groups,$db_groups);
// users only in db
$groups_to_deactivate = array_diff($db_groups,$ldap_groups);
// users present in ldap and in the db
$groups_to_update = array_intersect($db_groups,$ldap_groups);
if ( sizeof ( $groups_to_create ) ){
$c->messages[] = sprintf(i18n('- creating groups : %s'),join(', ',$groups_to_create));
$validUserFields = get_fields('usr');
foreach ( $groups_to_create as $k => $group ){
$user = (object) array( 'user_no' => 0, 'username' => '' );
if ( isset($c->authenticate_hook['config']['default_value']) && is_array($c->authenticate_hook['config']['default_value']) ) {
foreach ( $c->authenticate_hook['config']['default_value'] as $field => $value ) {
if ( isset($validUserFields[$field]) ) {
$usr->{$field} = $value;
dbg_error_log( "LDAP", "Setting usr->%s to %s from configured defaults", $field, $value );
}
}
}
$user->user_no = 0;
foreach ( $mapping as $field => $value ) {
dbg_error_log( "LDAP", "Considering copying %s", $field );
if ( isset($validUserFields[$field]) ) {
$user->{$field} = $ldap_values[$value];
dbg_error_log( "LDAP", "Setting usr->%s to %s from LDAP field %s", $field, $ldap_values[$value], $value );
}
}
$user->fullname = $group;
$user->displayname = $group;
$user->username = $group;
UpdateUserFromExternal( $user );
$qry = new AwlQuery( "UPDATE dav_principal set type_id = 3 WHERE username=:group ",array(':group'=>$group) );
$qry->Exec('sync_LDAP',__LINE__,__FILE__);
$c->messages[] = sprintf(i18n('- adding users %s to group : %s'),join(',',$ldap_groups_info[$group][$mapping['members']]),$group);
foreach ( $ldap_groups_info[$group][$mapping['members']] as $member ){
$qry = new AwlQuery( "INSERT INTO group_member SELECT g.principal_id AS group_id,u.principal_id AS member_id FROM dav_principal g, dav_principal u WHERE g.username=:group AND u.username=:member;",array (':group'=>$group,':member'=>$member) );
$qry->Exec('sync_LDAP_groups',__LINE__,__FILE__);
}
}
}
if ( sizeof ( $groups_to_update ) ){
$c->messages[] = sprintf(i18n('- updating groups : %s'),join(', ',$groups_to_update));
foreach ( $groups_to_update as $group ){
$db_members = array_values ( $db_group_members[$group] );
$ldap_members = array_values ( $ldap_groups_info[$group][$mapping['members']] );
$add_users = array_diff ( $ldap_members, $db_members );
if ( sizeof ( $add_users ) ){
$c->messages[] = sprintf(i18n('- adding %s to group : %s'),join(', ', $add_users ), $group);
foreach ( $add_users as $member ){
$qry = new AwlQuery( "INSERT INTO group_member SELECT g.principal_id AS group_id,u.principal_id AS member_id FROM dav_principal g, dav_principal u WHERE g.username=:group AND u.username=:member",array (':group'=>$group,':member'=>$member) );
$qry->Exec('sync_LDAP_groups',__LINE__,__FILE__);
}
}
$remove_users = array_diff ( $db_members, $ldap_members );
if ( sizeof ( $remove_users ) ){
$c->messages[] = sprintf(i18n('- removing %s from group : %s'),join(', ', $remove_users ), $group);
foreach ( $remove_users as $member ){
$qry = new AwlQuery( "DELETE FROM group_member USING dav_principal g,dav_principal m WHERE group_id=g.principal_id AND member_id=m.principal_id AND g.username=:group AND m.username=:member",array (':group'=>$group,':member'=>$member) );
$qry->Exec('sync_LDAP_groups',__LINE__,__FILE__);
}
}
}
}
if ( sizeof ( $groups_to_deactivate ) ){
$c->messages[] = sprintf(i18n('- deactivate groups : %s'),join(', ',$groups_to_deactivate));
foreach ( $groups_to_deactivate as $group ){
$qry = new AwlQuery( "UPDATE dav_principal set active='f'::bool WHERE username=:group AND type_id = 3",array(':group'=>$group) );
$qry->Exec('sync_LDAP',__LINE__,__FILE__);
}
}
}
}
/**
* sync LDAP against the DB
@ -341,7 +477,7 @@ function sync_LDAP(){
$ldap_users_info[$ldap_user[$mapping["username"]]] = $ldap_user;
unset($ldap_users_tmp[$key]);
}
$qry = new AwlQuery( "SELECT username, user_no, updated FROM usr ");
$qry = new AwlQuery( "SELECT username, user_no, modified as updated FROM dav_principal where type_id=1");
$qry->Exec('sync_LDAP',__LINE__,__FILE__);
while($db_user = $qry->Fetch()) {
$db_users[] = $db_user->username;