mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-02-24 22:21:34 +01:00
moved logic of account-migration to setup_cmd_ldap and using setup_cmd_ldap for account_migration.php, that way we can also create the ldap-structur during the migration
This commit is contained in:
parent
5c2a64c1de
commit
7be62b431f
@ -21,15 +21,6 @@ if (!$GLOBALS['egw_setup']->auth('Config') || $_POST['cancel'])
|
|||||||
}
|
}
|
||||||
// Does not return unless user is authorized
|
// Does not return unless user is authorized
|
||||||
|
|
||||||
// the migration script needs a session to store the accounts
|
|
||||||
session_name('setup_session');
|
|
||||||
session_set_cookie_params(0,'/',$GLOBALS['egw_setup']->cookie_domain);
|
|
||||||
if (isset($_REQUEST['setup_session']))
|
|
||||||
{
|
|
||||||
session_id($_REQUEST['setup_session']);
|
|
||||||
}
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
$tpl_root = $GLOBALS['egw_setup']->html->setup_tpl_dir('setup');
|
$tpl_root = $GLOBALS['egw_setup']->html->setup_tpl_dir('setup');
|
||||||
$setup_tpl = CreateObject('phpgwapi.Template',$tpl_root);
|
$setup_tpl = CreateObject('phpgwapi.Template',$tpl_root);
|
||||||
$setup_tpl->set_file(array(
|
$setup_tpl->set_file(array(
|
||||||
@ -69,7 +60,7 @@ if (!is_object($GLOBALS['egw_setup']->db))
|
|||||||
{
|
{
|
||||||
$GLOBALS['egw_setup']->loaddb();
|
$GLOBALS['egw_setup']->loaddb();
|
||||||
}
|
}
|
||||||
// Load configuration values account_repository and auth_type, a setup has not yet done so
|
// Load configuration values account_repository and auth_type, as setup has not yet done so
|
||||||
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'config_name,config_value',
|
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'config_name,config_value',
|
||||||
"config_name LIKE 'ldap%' OR config_name LIKE 'account_%' OR config_name LIKE '%encryption%' OR config_name='auth_type'",
|
"config_name LIKE 'ldap%' OR config_name LIKE 'account_%' OR config_name LIKE '%encryption%' OR config_name='auth_type'",
|
||||||
__LINE__,__FILE__) as $row)
|
__LINE__,__FILE__) as $row)
|
||||||
@ -87,40 +78,23 @@ $direction = strtoupper($from).' --> '.strtoupper($to);
|
|||||||
$GLOBALS['egw_setup']->html->show_header($direction,False,'config',$GLOBALS['egw_setup']->ConfigDomain .
|
$GLOBALS['egw_setup']->html->show_header($direction,False,'config',$GLOBALS['egw_setup']->ConfigDomain .
|
||||||
'(' . $GLOBALS['egw_domain'][$GLOBALS['egw_setup']->ConfigDomain]['db_type'] . ')');
|
'(' . $GLOBALS['egw_domain'][$GLOBALS['egw_setup']->ConfigDomain]['db_type'] . ')');
|
||||||
|
|
||||||
|
// create base one level off ldap_context
|
||||||
|
$base_parts = explode(',',$GLOBALS['egw_info']['server']['ldap_context']);
|
||||||
|
array_shift($base_parts);
|
||||||
|
|
||||||
|
$cmd = new setup_cmd_ldap(array(
|
||||||
|
'domain' => $GLOBALS['egw_setup']->ConfigDomain,
|
||||||
|
'sub_command' => 'migrate_to_'.$to,
|
||||||
|
// in regular setup we only support one ldap root user, setting him as admin user too
|
||||||
|
'ldap_admin' => $GLOBALS['egw_info']['server']['ldap_root_dn'],
|
||||||
|
'ldap_admin_pw' => $GLOBALS['egw_info']['server']['ldap_root_pw'],
|
||||||
|
'ldap_base' => implode(',',$base_parts),
|
||||||
|
)+$GLOBALS['egw_info']['server']);
|
||||||
|
|
||||||
if (!$_POST['migrate'])
|
if (!$_POST['migrate'])
|
||||||
{
|
{
|
||||||
// fetch and display the accounts of the NOT set $from repository
|
$accounts = $cmd->accounts($from == 'ldap');
|
||||||
$GLOBALS['egw_info']['server']['account_repository'] = $from;
|
|
||||||
$GLOBALS['egw_setup']->setup_account_object($GLOBALS['egw_info']['server']);
|
|
||||||
|
|
||||||
// fetch all users and groups
|
|
||||||
$accounts = $GLOBALS['egw_setup']->accounts->search(array(
|
|
||||||
'type' => 'both',
|
|
||||||
));
|
|
||||||
// fetch the complete data (search reads not everything), plus the members(hips)
|
|
||||||
foreach($accounts as $account_id => $account)
|
|
||||||
{
|
|
||||||
if ($account_id != $account['account_id']) // not all backends have as key the account_id
|
|
||||||
{
|
|
||||||
unset($accounts[$account_id]);
|
|
||||||
$account_id = $account['account_id'];
|
|
||||||
}
|
|
||||||
$accounts[$account_id] = $GLOBALS['egw_setup']->accounts->read($account_id);
|
|
||||||
|
|
||||||
if ($account['account_type'] == 'g')
|
|
||||||
{
|
|
||||||
$accounts[$account_id]['members'] = $GLOBALS['egw_setup']->accounts->members($account_id,true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$accounts[$account_id]['memberships'] = $GLOBALS['egw_setup']->accounts->memberships($account_id,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//_debug_array($accounts);
|
|
||||||
// store the complete info in the session to be availible after user selected what to migrate
|
|
||||||
// we cant instanciate to account-repositories at the same time, as the backend-classes have identical names
|
|
||||||
$_SESSION['all_accounts'] =& $accounts;
|
|
||||||
|
|
||||||
// now outputting the account selection
|
// now outputting the account selection
|
||||||
$setup_tpl->set_block('migration','header','header');
|
$setup_tpl->set_block('migration','header','header');
|
||||||
$setup_tpl->set_block('migration','user_list','user_list');
|
$setup_tpl->set_block('migration','user_list','user_list');
|
||||||
@ -166,85 +140,9 @@ if (!$_POST['migrate'])
|
|||||||
}
|
}
|
||||||
else // do the migration
|
else // do the migration
|
||||||
{
|
{
|
||||||
$GLOBALS['egw_info']['server']['account_repository'] = $to;
|
$cmd->only = array_merge((array)$_POST['users'],(array)$_POST['groups']);
|
||||||
$GLOBALS['egw_setup']->setup_account_object($GLOBALS['egw_info']['server']);
|
$cmd->verbose = true;
|
||||||
|
echo '<p align="center">'.str_replace("\n","</p>\n<p align='center'>",$cmd->run())."</p>\n";
|
||||||
$target = strtoupper($to);
|
|
||||||
$accounts =& $_SESSION['all_accounts'];
|
|
||||||
|
|
||||||
if($_POST['users'])
|
|
||||||
{
|
|
||||||
foreach($_POST['users'] as $account_id)
|
|
||||||
{
|
|
||||||
if (!isset($accounts[$account_id])) continue;
|
|
||||||
|
|
||||||
// check if user already exists
|
|
||||||
if ($GLOBALS['egw_setup']->accounts->exists($account_id))
|
|
||||||
{
|
|
||||||
echo '<p>'.lang('%1 already exists in %2.',lang('User')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($to == 'ldap')
|
|
||||||
{
|
|
||||||
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
|
|
||||||
{
|
|
||||||
$accounts[$account_id]['homedirectory'] = $GLOBALS['egw_info']['server']['ldap_account_home'] . '/' . $accounts[$account_id]['account_lid'];
|
|
||||||
$accounts[$account_id]['loginshell'] = $GLOBALS['egw_info']['server']['ldap_account_shell'];
|
|
||||||
}
|
|
||||||
$accounts[$account_id]['account_passwd'] = hash_sql2ldap($accounts[$account_id]['account_pwd']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ($accounts[$account_id]['account_pwd'][0] != '{') // plain has to be explicitly specified for sql, in ldap it's the default
|
|
||||||
{
|
|
||||||
$accounts[$account_id]['account_passwd'] = '{PLAIN}'.$accounts[$account_id]['account_pwd'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$accounts[$account_id]['account_passwd'] = $accounts[$account_id]['account_pwd'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($accounts[$account_id]['person_id']);
|
|
||||||
|
|
||||||
if (!$GLOBALS['egw_setup']->accounts->save($accounts[$account_id]))
|
|
||||||
{
|
|
||||||
echo '<p>'.lang('Creation of %1 in %2 failed !!!',lang('User')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$GLOBALS['egw_setup']->accounts->set_memberships($accounts[$account_id]['memberships'],$account_id);
|
|
||||||
echo '<p>'.lang('%1 created in %2.',lang('User')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($_POST['groups'])
|
|
||||||
{
|
|
||||||
foreach($_POST['groups'] as $account_id)
|
|
||||||
{
|
|
||||||
if (!isset($accounts[$account_id])) continue;
|
|
||||||
|
|
||||||
// check if group already exists
|
|
||||||
if (!$GLOBALS['egw_setup']->accounts->exists($account_id))
|
|
||||||
{
|
|
||||||
if (!$GLOBALS['egw_setup']->accounts->save($accounts[$account_id]))
|
|
||||||
{
|
|
||||||
echo '<p>'.lang('Creation of %1 in %2 failed !!!',lang('Group')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
echo '<p>'.lang('%1 created in %2.',lang('Group')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo '<p>'.lang('%1 already exists in %2.',lang('Group')." $account_id ({$accounts[$account_id]['account_lid']})",$target)."</p>\n";
|
|
||||||
|
|
||||||
if ($GLOBALS['egw_setup']->accounts->id2name($account_id) != $accounts[$account_id]['account_lid'])
|
|
||||||
{
|
|
||||||
continue; // different group under that gidnumber!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now saving / updating the memberships
|
|
||||||
$GLOBALS['egw_setup']->accounts->set_members($accounts[$account_id]['members'],$account_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '<p align="center">'.lang('Export has been completed!')."</p>\n";
|
|
||||||
echo '<p align="center">'.lang('Click <a href="index.php">here</a> to return to setup.')."</p>\n";
|
echo '<p align="center">'.lang('Click <a href="index.php">here</a> to return to setup.')."</p>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
*/
|
*/
|
||||||
function __construct($domain,$ldap_host=null,$ldap_suffix=null,$ldap_admin=null,$ldap_admin_pw=null,
|
function __construct($domain,$ldap_host=null,$ldap_suffix=null,$ldap_admin=null,$ldap_admin_pw=null,
|
||||||
$ldap_base=null,$ldap_root_dn=null,$ldap_root_pw=null,$ldap_context=null,$ldap_search_filter=null,
|
$ldap_base=null,$ldap_root_dn=null,$ldap_root_pw=null,$ldap_context=null,$ldap_search_filter=null,
|
||||||
$ldap_group_context=null,$sub_command='create_ldap')
|
$ldap_group_context=null,$sub_command='create_ldap',$ldap_encryption_type='des')
|
||||||
{
|
{
|
||||||
if (!is_array($domain))
|
if (!is_array($domain))
|
||||||
{
|
{
|
||||||
@ -61,7 +61,8 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
'ldap_context' => $ldap_context,
|
'ldap_context' => $ldap_context,
|
||||||
'ldap_search_filter' => $ldap_search_filter,
|
'ldap_search_filter' => $ldap_search_filter,
|
||||||
'ldap_group_context' => $ldap_group_context,
|
'ldap_group_context' => $ldap_group_context,
|
||||||
'sub_command' => $sub_command
|
'sub_command' => $sub_command,
|
||||||
|
'ldap_encryption_type' => $ldap_encryption_type,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//echo __CLASS__.'::__construct()'; _debug_array($domain);
|
//echo __CLASS__.'::__construct()'; _debug_array($domain);
|
||||||
@ -101,6 +102,10 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
case 'users_ldap':
|
case 'users_ldap':
|
||||||
$msg = $this->users();
|
$msg = $this->users();
|
||||||
break;
|
break;
|
||||||
|
case 'migrate_to_ldap':
|
||||||
|
case 'migrate_to_sql':
|
||||||
|
$msg = $this->migrate($this->sub_command == 'migrate_to_ldap');
|
||||||
|
break;
|
||||||
case 'create_ldap':
|
case 'create_ldap':
|
||||||
default:
|
default:
|
||||||
$msg = $this->create();
|
$msg = $this->create();
|
||||||
@ -108,6 +113,210 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
}
|
}
|
||||||
return $msg;
|
return $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate to other account storage
|
||||||
|
*
|
||||||
|
* @param boolean $to_ldap true: sql --> ldap, false: ldap --> sql
|
||||||
|
* @return string with success message
|
||||||
|
* @throws Exception on error
|
||||||
|
*/
|
||||||
|
private function migrate($to_ldap)
|
||||||
|
{
|
||||||
|
$msg = array();
|
||||||
|
// if migrating to ldap, check ldap and create context if not yet exiting
|
||||||
|
if ($to_ldap)
|
||||||
|
{
|
||||||
|
$msg[] = $this->create();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$msg[] = $this->connect();
|
||||||
|
}
|
||||||
|
// read accounts from old store
|
||||||
|
$accounts = $this->accounts(!$to_ldap);
|
||||||
|
|
||||||
|
// instanciate accounts obj for new store
|
||||||
|
$accounts_obj = $this->accounts_obj($to_ldap);
|
||||||
|
|
||||||
|
$accounts_created = $groups_created = $errors = 0;
|
||||||
|
$target = $to_ldap ? 'LDAP' : 'SQL';
|
||||||
|
foreach($accounts as $account_id => $account)
|
||||||
|
{
|
||||||
|
if (isset($this->only) && !in_array($account_id,$this->only))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$what = ($account['account_type'] == 'u' ? lang('User') : lang('Group')).' '.
|
||||||
|
$account_id.' ('.$account['account_lid'].')';
|
||||||
|
|
||||||
|
if ($account['account_type'] == 'u')
|
||||||
|
{
|
||||||
|
if ($accounts_obj->exists($account_id))
|
||||||
|
{
|
||||||
|
$msg[] = lang('%1 already exists in %2.',$what,$target);
|
||||||
|
$errors++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($to_ldap)
|
||||||
|
{
|
||||||
|
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
|
||||||
|
{
|
||||||
|
$account['homedirectory'] = $GLOBALS['egw_info']['server']['ldap_account_home'] . '/' . $account['account_lid'];
|
||||||
|
$account['loginshell'] = $GLOBALS['egw_info']['server']['ldap_account_shell'];
|
||||||
|
}
|
||||||
|
$account['account_passwd'] = self::hash_sql2ldap($account['account_pwd']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($account['account_pwd'][0] != '{') // plain has to be explicitly specified for sql, in ldap it's the default
|
||||||
|
{
|
||||||
|
$account['account_passwd'] = '{PLAIN}'.$account['account_pwd'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$account['account_passwd'] = $account['account_pwd'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($account['person_id']);
|
||||||
|
|
||||||
|
if (!$accounts_obj->save($account))
|
||||||
|
{
|
||||||
|
$msg[] = lang('Creation of %1 in %2 failed !!!',$what,$target);
|
||||||
|
$errors++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$accounts_obj->set_memberships($account['memberships'],$account_id);
|
||||||
|
$msg[] = lang('%1 created in %2.',$what,$target);
|
||||||
|
$accounts_created++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check if group already exists
|
||||||
|
if (!$accounts_obj->exists($account_id))
|
||||||
|
{
|
||||||
|
if (!$accounts_obj->save($account))
|
||||||
|
{
|
||||||
|
$msg[] = lang('Creation of %1 in %2 failed !!!',$what,$target);
|
||||||
|
++$errors;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$msg[] = lang('%1 created in %2.',$what,$target);
|
||||||
|
$groups_created++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$msg[] = lang('%1 already exists in %2.',$what,$target);
|
||||||
|
|
||||||
|
if ($accounts_obj->id2name($account_id) != $account['account_lid'])
|
||||||
|
{
|
||||||
|
++$errors;
|
||||||
|
continue; // different group under that gidnumber!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now saving / updating the memberships
|
||||||
|
$accounts_obj->set_members($account['members'],$account_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lang('%1 users and %2 groups created, %3 errors',$accounts_created,$groups_created,$errors).
|
||||||
|
($errors || $this->verbose ? "\n- ".implode("\n- ",$msg) : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert SQL hash to LDAP hash
|
||||||
|
*
|
||||||
|
* @param string $hash
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function hash_sql2ldap($hash)
|
||||||
|
{
|
||||||
|
$type = $GLOBALS['egw_info']['server']['sql_encryption_type'];
|
||||||
|
|
||||||
|
if (preg_match('/^\\{(.*)\\}(.*)$/',$hash,$matches))
|
||||||
|
{
|
||||||
|
$type = $matches[1];
|
||||||
|
$hash = $matches[2];
|
||||||
|
}
|
||||||
|
switch(strtolower($type))
|
||||||
|
{
|
||||||
|
case '': // not set sql_encryption_type
|
||||||
|
case 'md5':
|
||||||
|
$hash = '{md5}' . base64_encode(pack("H*",$hash));
|
||||||
|
break;
|
||||||
|
case 'crypt':
|
||||||
|
$hash = '{crypt}' . $hash;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'plain':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read all accounts from sql or ldap
|
||||||
|
*
|
||||||
|
* @param boolean $from_ldap=true true: ldap, false: sql
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function accounts($from_ldap=true)
|
||||||
|
{
|
||||||
|
$accounts_obj = $this->accounts_obj($from_ldap);
|
||||||
|
//error_log(__METHOD__."(from_ldap=".array2string($from_ldap).') get_class(accounts_obj->backend)='.get_class($accounts_obj->backend));
|
||||||
|
|
||||||
|
$accounts = $accounts_obj->search(array('type' => 'both'));
|
||||||
|
|
||||||
|
foreach($accounts as $account_id => &$account)
|
||||||
|
{
|
||||||
|
if ($account_id != $account['account_id']) // not all backends have as key the account_id
|
||||||
|
{
|
||||||
|
unset($account);
|
||||||
|
$account_id = $account['account_id'];
|
||||||
|
}
|
||||||
|
$account = $accounts_obj->read($account_id);
|
||||||
|
|
||||||
|
if ($account['account_type'] == 'g')
|
||||||
|
{
|
||||||
|
$account['members'] = $accounts_obj->members($account_id,true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$account['memberships'] = $accounts_obj->memberships($account_id,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instancate accounts object from either sql of ldap
|
||||||
|
*
|
||||||
|
* @param boolean $ldap true: ldap, false: sql
|
||||||
|
* @return accounts
|
||||||
|
*/
|
||||||
|
private function accounts_obj($ldap)
|
||||||
|
{
|
||||||
|
static $enviroment_setup;
|
||||||
|
if (!$enviroment_setup)
|
||||||
|
{
|
||||||
|
parent::_setup_enviroment($this->domain);
|
||||||
|
$enviroment_setup = true;
|
||||||
|
}
|
||||||
|
if ($ldap) $this->connect(); // throws exception, if it can NOT connect
|
||||||
|
|
||||||
|
// otherwise search does NOT work, as accounts_sql uses addressbook_bo for it
|
||||||
|
$GLOBALS['egw_info']['server']['account_repository'] = $ldap ? 'ldap' : 'sql';
|
||||||
|
|
||||||
|
if (!self::$egw_setup->setup_account_object(
|
||||||
|
array(
|
||||||
|
'account_repository' => $GLOBALS['egw_info']['server']['account_repository'],
|
||||||
|
) + $this->as_array()) ||
|
||||||
|
!is_a(self::$egw_setup->accounts,'accounts') ||
|
||||||
|
!is_a(self::$egw_setup->accounts->backend,'accounts_'.($ldap?'ldap':'sql')))
|
||||||
|
{
|
||||||
|
throw new Exception(lang("Can NOT instancate accounts object for %1",$ldap?'LDAP':'SQL'));
|
||||||
|
}
|
||||||
|
return self::$egw_setup->accounts;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to ldap server
|
* Connect to ldap server
|
||||||
|
Loading…
Reference in New Issue
Block a user