forked from extern/egroupware
allow to update passwords from LDAP, if accounts stored in SQL and authentication is against LDAP
This commit is contained in:
parent
eb2a814c0d
commit
e5b3a83693
@ -66,7 +66,7 @@ array_shift($base_parts);
|
||||
|
||||
$cmd = new setup_cmd_ldap(array(
|
||||
'domain' => $GLOBALS['egw_setup']->ConfigDomain,
|
||||
'sub_command' => 'migrate_to_'.$to,
|
||||
'sub_command' => $_POST['passwords2sql'] ? 'passwords_to_sql' : 'migrate_to_'.$to,
|
||||
// allow to set ldap root DN (ldap_admin) to create instance specific admin DN and structure
|
||||
'ldap_admin' => !empty($_POST['ldap_admin']) ? $_POST['ldap_admin'] : $GLOBALS['egw_info']['server']['ldap_root_dn'],
|
||||
'ldap_admin_pw' => !empty($_POST['ldap_admin']) ? $_POST['ldap_admin_pw'] : $GLOBALS['egw_info']['server']['ldap_root_pw'],
|
||||
@ -74,7 +74,7 @@ $cmd = new setup_cmd_ldap(array(
|
||||
'truncate_egw_accounts' => !empty($_POST['truncate_egw_accounts']),
|
||||
)+$GLOBALS['egw_info']['server']);
|
||||
|
||||
if (!$_POST['migrate'])
|
||||
if (!$_POST['migrate'] && !$_POST['passwords2sql'])
|
||||
{
|
||||
$accounts = $cmd->accounts($from == 'ldap');
|
||||
|
||||
@ -100,7 +100,7 @@ if (!$_POST['migrate'])
|
||||
else
|
||||
{
|
||||
$user_list .= '<option value="' . $account_id . '" selected="1">'.
|
||||
$GLOBALS['egw']->common->display_fullname($account['account_lid'],
|
||||
common::display_fullname($account['account_lid'],
|
||||
$account['account_firstname'],$account['account_lastname']) . "</option>\n";
|
||||
}
|
||||
}
|
||||
@ -119,6 +119,10 @@ if (!$_POST['migrate'])
|
||||
$setup_tpl->set_var('ldap_admin_pw_label', lang('Root DN password'));
|
||||
$setup_tpl->set_var('migrate',$direction);
|
||||
$setup_tpl->set_var('cancel',lang('Cancel'));
|
||||
if ($from == 'sql' && $GLOBALS['egw_info']['server']['auth_type'] == 'ldap')
|
||||
{
|
||||
$setup_tpl->set_var('extra_button', html::submit_button('passwords2sql', lang('Passwords --> SQL')));
|
||||
}
|
||||
|
||||
$setup_tpl->pfp('out','header');
|
||||
if($user_list)
|
||||
@ -143,15 +147,20 @@ if (!$_POST['migrate'])
|
||||
}
|
||||
else // do the migration
|
||||
{
|
||||
$cmd->only = array_merge((array)$_POST['users'],(array)$_POST['groups']);
|
||||
$cmd->only = (array)$_POST['users'];
|
||||
if (empty($_POST['passwords2sql'])) $cmd->only = array_merge($cmd->only, (array)$_POST['groups']);
|
||||
$cmd->verbose = true;
|
||||
echo '<p align="center">'.str_replace("\n","</p>\n<p align='center'>",$cmd->run())."</p>\n";
|
||||
|
||||
// store new repostory (and auth_type), as we are migrated now
|
||||
if ($_POST['migrate'])
|
||||
{
|
||||
config::save_value('account_repository', $GLOBALS['egw_info']['server']['account_repository']=$to, 'phpgwapi');
|
||||
if (empty($GLOBALS['egw_info']['server']['auth_type']) || $GLOBALS['egw_info']['server']['auth_type'] == $from)
|
||||
{
|
||||
config::save_value('auth_type', $GLOBALS['egw_info']['server']['auth_type']=$to, 'phpgwapi');
|
||||
}
|
||||
}
|
||||
echo '<p align="center">'.lang('Click <a href="index.php">here</a> to return to setup.')."</p>\n";
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,11 @@
|
||||
*
|
||||
* - copies mail-attributes from ldap to AD (example is from Mandriva mailAccount schema, need to adapt to other schema!)
|
||||
* (no_sid_check=1 uses all objectClass=posixAccount, not checking for having a SID and uid not ending in $ for computer accounts)
|
||||
*
|
||||
* setup/setup-cli.php [--dry-run] --setup_cmd_ldap <domain>,<config-user>,<config-pw> sub_command=passwords_to_sql \
|
||||
* ldap_base=dc=local ldap_root_dn=cn=admin,dc=local ldap_root_pw=secret ldap_host=localhost
|
||||
*
|
||||
* Updating passwords for existing users in SQL from LDAP, eg. to switch off authentication to LDAP on a SQL install.
|
||||
*/
|
||||
class setup_cmd_ldap extends setup_cmd
|
||||
{
|
||||
@ -141,7 +146,8 @@ class setup_cmd_ldap extends setup_cmd
|
||||
break;
|
||||
case 'migrate_to_ldap':
|
||||
case 'migrate_to_sql':
|
||||
$msg = $this->migrate($this->sub_command == 'migrate_to_ldap');
|
||||
case 'passwords_to_sql':
|
||||
$msg = $this->migrate($this->sub_command);
|
||||
break;
|
||||
case 'set_mailbox':
|
||||
$msg = $this->set_mailbox($check_only);
|
||||
@ -326,13 +332,14 @@ class setup_cmd_ldap extends setup_cmd
|
||||
throw new egw_exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
||||
}
|
||||
$changed = 0;
|
||||
$utc_diff = null;
|
||||
foreach($entries as $key => $entry)
|
||||
{
|
||||
if ($key === 'count') continue;
|
||||
|
||||
$entry = ldap::result2array($entry);
|
||||
$uid = $entry['uid'];
|
||||
$entry = array_diff_key($entry, $ignore_attr);
|
||||
$entry_arr = ldap::result2array($entry);
|
||||
$uid = $entry_arr['uid'];
|
||||
$entry = array_diff_key($entry_arr, $ignore_attr);
|
||||
|
||||
if (!($sr = ldap_search($ads->ds, $this->ads_context,
|
||||
$search='(&(objectClass=user)(sAMAccountName='.ldap::quote($uid).'))', array('dn'))) ||
|
||||
@ -354,8 +361,8 @@ class setup_cmd_ldap extends setup_cmd
|
||||
else
|
||||
{
|
||||
if (is_null($utc_diff)) $utc_diff = date('Z');
|
||||
$entry['shadowexpire'] = $value*24*3600+$utc_diff; // ldap time to unixTime
|
||||
$entry['shadowexpire'] = accounts_ads::convertUnixTimeToWindowsTime($entry['shadowexpire']);
|
||||
$entry['shadowexpire'] = accounts_ads::convertUnixTimeToWindowsTime(
|
||||
$entry['shadowexpire']*24*3600+$utc_diff); // ldap time to unixTime
|
||||
}
|
||||
}
|
||||
$update = array();
|
||||
@ -364,7 +371,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
if ($value || $attr === '')
|
||||
{
|
||||
$to = isset($rename[$attr]) ? $rename[$attr] : $attr;
|
||||
unset($prefix);
|
||||
$prefix = null;
|
||||
if ($to[0] == '{') // eg. {smtp:}proxyAddresses=forwardTo
|
||||
{
|
||||
list($prefix, $to) = explode('}', substr($to, 1));
|
||||
@ -414,12 +421,15 @@ class setup_cmd_ldap extends setup_cmd
|
||||
/**
|
||||
* Migrate to other account storage
|
||||
*
|
||||
* @param boolean $to_ldap true: sql --> ldap, false: ldap --> sql
|
||||
* @param boolean|string $to_ldap true: sql --> ldap, false: ldap --> sql, "passwords_to_sql", "migrate_to_(sql|ldap)"
|
||||
* @return string with success message
|
||||
* @throws Exception on error
|
||||
*/
|
||||
private function migrate($to_ldap)
|
||||
{
|
||||
$passwords2sql = $to_ldap === "passwords_to_sql";
|
||||
if (is_string($to_ldap)) $to_ldap = substr($to_ldap, -8) == '_to_ldap';
|
||||
|
||||
$msg = array();
|
||||
// if migrating to ldap, check ldap and create context if not yet exiting
|
||||
if ($to_ldap && !empty($this->ldap_admin_pw))
|
||||
@ -431,7 +441,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$msg[] = $this->connect();
|
||||
}
|
||||
// read accounts from old store
|
||||
$accounts = $this->accounts(!$to_ldap);
|
||||
$accounts = $this->accounts(!$to_ldap, $passwords2sql ? 'accounts' : 'both');
|
||||
|
||||
// clean up SQL before migration
|
||||
if (!$to_ldap && $this->truncate_egw_accounts)
|
||||
@ -442,7 +452,8 @@ class setup_cmd_ldap extends setup_cmd
|
||||
// instanciate accounts obj for new store
|
||||
$accounts_obj = $this->accounts_obj($to_ldap);
|
||||
|
||||
$accounts_created = $groups_created = $errors = 0;
|
||||
$accounts_created = $groups_created = $errors = $egw_info_set = 0;
|
||||
$emailadmin_src = $ldap_class = null;
|
||||
$target = $to_ldap ? 'LDAP' : 'SQL';
|
||||
foreach($accounts as $account_id => $account)
|
||||
{
|
||||
@ -456,6 +467,31 @@ class setup_cmd_ldap extends setup_cmd
|
||||
// invalidate cache: otherwise no migration takes place, if cached results says account already exists
|
||||
accounts::cache_invalidate($account_id);
|
||||
|
||||
if ($passwords2sql)
|
||||
{
|
||||
if (!($sql_account = $accounts_obj->read($account_id)))
|
||||
{
|
||||
$msg[] = lang('%1 does NOT exist in %2.',$what,$target);
|
||||
$errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql_account['account_passwd'] = self::hash_ldap2sql($account['account_pwd']);
|
||||
|
||||
if (!$accounts_obj->save($sql_account))
|
||||
{
|
||||
$msg[] = lang('Update of %1 in %2 failed !!!',$what,$target);
|
||||
$errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg[] = lang('%1 password set in %2.',$what,$target);
|
||||
$accounts_created++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($account['account_type'] == 'u')
|
||||
{
|
||||
if ($accounts_obj->exists($account_id))
|
||||
@ -601,6 +637,11 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$accounts_obj->set_members($account['members'],$account_id);
|
||||
}
|
||||
}
|
||||
if ($passwords2sql)
|
||||
{
|
||||
return lang('%1 passwords updated, %3 errors',$accounts_created,$groups_created,$errors).
|
||||
($errors || $this->verbose ? "\n- ".implode("\n- ",$msg) : '');
|
||||
}
|
||||
// migrate addressbook data
|
||||
$GLOBALS['egw_info']['user']['apps']['admin'] = true; // otherwise migration will not run in setup!
|
||||
$addressbook = new addressbook_so();
|
||||
@ -613,12 +654,12 @@ class setup_cmd_ldap extends setup_cmd
|
||||
}
|
||||
ob_start();
|
||||
$addressbook->migrate2ldap($to_ldap ? 'accounts' : 'accounts-back');
|
||||
$msg = array_merge($msg, explode("\n", strip_tags(ob_get_clean())));
|
||||
$msgs = array_merge($msg, explode("\n", strip_tags(ob_get_clean())));
|
||||
|
||||
$this->restore_db();
|
||||
|
||||
return lang('%1 users and %2 groups created, %3 errors',$accounts_created,$groups_created,$errors).
|
||||
($errors || $this->verbose ? "\n- ".implode("\n- ",$msg) : '');
|
||||
($errors || $this->verbose ? "\n- ".implode("\n- ",$msgs) : '');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,6 +672,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
{
|
||||
if (!($type = $GLOBALS['egw_info']['server']['sql_encryption_type'])) $type = 'md5';
|
||||
|
||||
$matches = null;
|
||||
if (preg_match('/^\\{(.*)\\}(.*)$/',$hash,$matches))
|
||||
{
|
||||
list(,$type,$hash) = $matches;
|
||||
@ -673,14 +715,15 @@ class setup_cmd_ldap extends setup_cmd
|
||||
* Read all accounts from sql or ldap
|
||||
*
|
||||
* @param boolean $from_ldap =true true: ldap, false: sql
|
||||
* @param string $type ='both'
|
||||
* @return array
|
||||
*/
|
||||
public function accounts($from_ldap=true)
|
||||
public function accounts($from_ldap=true, $type='both')
|
||||
{
|
||||
$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', 'objectclass' => true));
|
||||
$accounts = $accounts_obj->search(array('type' => $type, 'objectclass' => true));
|
||||
|
||||
foreach($accounts as $account_id => &$account)
|
||||
{
|
||||
@ -713,7 +756,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
*/
|
||||
private function accounts_obj($ldap)
|
||||
{
|
||||
static $enviroment_setup;
|
||||
static $enviroment_setup=null;
|
||||
if (!$enviroment_setup)
|
||||
{
|
||||
parent::_setup_enviroment($this->domain);
|
||||
@ -813,7 +856,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$this->ldap_root_dn => array('userPassword' => auth::encrypt_ldap($this->ldap_root_pw,'ssha')),
|
||||
) as $dn => $extra)
|
||||
{
|
||||
if (!$this->_create_node($dn,$extra,$check_only) && $dn == $this->ldap_root_dn)
|
||||
if (!$this->_create_node($dn,$extra,$this->check_only) && $dn == $this->ldap_root_dn)
|
||||
{
|
||||
// ldap_root already existed, lets check the pw is correct
|
||||
$this->connect();
|
||||
@ -931,7 +974,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$mbox_attr => $mbox,
|
||||
)))
|
||||
{
|
||||
throw new egw_exception(lang("Error modifying dn=%1: %2='%3'!",$dn,$mbox_attr,$mbox));
|
||||
throw new egw_exception(lang("Error modifying dn=%1: %2='%3'!",$entry['dn'],$mbox_attr,$mbox));
|
||||
}
|
||||
++$modified;
|
||||
if ($check_only) echo "$modified: $entry[dn]: $mbox_attr={$entry[$mbox_attr][0]} --> $mbox\n";
|
||||
|
@ -54,6 +54,7 @@
|
||||
<tr bgcolor="#e6e6e6">
|
||||
<td colspan="2" align="center">
|
||||
<input type="submit" name="migrate" value="{migrate}" />
|
||||
{extra_button}
|
||||
<input type="submit" name="cancel" value="{cancel}" />
|
||||
</td>
|
||||
</tr>
|
||||
|
Loading…
Reference in New Issue
Block a user