mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-07 08:34:42 +01:00
* Setup: when migrating accounts from SQL to LDAP or back, also migrate addressbook data
This commit is contained in:
parent
26de26873b
commit
ec2ce0f943
@ -203,18 +203,43 @@ class addressbook_ldap
|
||||
var $all_attributes = array();
|
||||
|
||||
/**
|
||||
* constructor of the class
|
||||
* LDAP configuration
|
||||
*
|
||||
* @var array values for keys "ldap_contact_context", "ldap_host", "ldap_context"
|
||||
*/
|
||||
function __construct()
|
||||
private $ldap_config;
|
||||
|
||||
/**
|
||||
* constructor of the class
|
||||
*
|
||||
* @param array $ldap_config=null default use from $GLOBALS['egw_info']['server']
|
||||
* @param resource $ds=null ldap connection to use
|
||||
*/
|
||||
function __construct(array $ldap_config=null, $ds=null)
|
||||
{
|
||||
//$this->db_data_cols = $this->stock_contact_fields + $this->non_contact_fields;
|
||||
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
||||
|
||||
$this->personalContactsDN = 'ou=personal,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
||||
$this->sharedContactsDN = 'ou=shared,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
||||
if ($ldap_config)
|
||||
{
|
||||
$this->ldap_config = $ldap_config;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ldap_config =& $GLOBALS['egw_info']['server'];
|
||||
}
|
||||
$this->personalContactsDN = 'ou=personal,ou=contacts,'. $this->ldap_config['ldap_contact_context'];
|
||||
$this->sharedContactsDN = 'ou=shared,ou=contacts,'. $this->ldap_config['ldap_contact_context'];
|
||||
|
||||
$this->connect();
|
||||
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($GLOBALS['egw_info']['server']['ldap_contact_host']);
|
||||
if ($ds)
|
||||
{
|
||||
$this->ds = $ds;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connect();
|
||||
}
|
||||
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($this->ldap_config['ldap_contact_host']);
|
||||
|
||||
foreach($this->schema2egw as $schema => $attributes)
|
||||
{
|
||||
@ -241,14 +266,14 @@ class addressbook_ldap
|
||||
// if ldap is NOT the contact repository, we only do accounts and need to use the account-data
|
||||
if (substr($GLOBALS['egw_info']['server']['contact_repository'],-4) != 'ldap') // not (ldap or sql-ldap)
|
||||
{
|
||||
$GLOBALS['egw_info']['server']['ldap_contact_host'] = $GLOBALS['egw_info']['server']['ldap_host'];
|
||||
$GLOBALS['egw_info']['server']['ldap_contact_context'] = $GLOBALS['egw_info']['server']['ldap_context'];
|
||||
$this->ldap_config['ldap_contact_host'] = $this->ldap_config['ldap_host'];
|
||||
$this->ldap_config['ldap_contact_context'] = $this->ldap_config['ldap_context'];
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect(
|
||||
$GLOBALS['egw_info']['server']['ldap_contact_host'],
|
||||
$this->ldap_config['ldap_contact_host'],
|
||||
$GLOBALS['egw_info']['user']['account_dn'],
|
||||
$GLOBALS['egw_info']['user']['passwd']
|
||||
);
|
||||
@ -298,7 +323,7 @@ class addressbook_ldap
|
||||
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']));
|
||||
$filter = "(|(entryUUID=$contact_id)(uid=$contact_id))";
|
||||
}
|
||||
$rows = $this->_searchLDAP($GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
$rows = $this->_searchLDAP($this->ldap_config['ldap_contact_context'],
|
||||
$filter, $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
|
||||
return $rows ? $rows[0] : false;
|
||||
@ -339,7 +364,7 @@ class addressbook_ldap
|
||||
$data['account_id'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
// account
|
||||
$baseDN = $GLOBALS['egw_info']['server']['ldap_context'];
|
||||
$baseDN = $this->ldap_config['ldap_context'];
|
||||
$cn = false;
|
||||
// we need an admin connection
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
@ -366,7 +391,7 @@ class addressbook_ldap
|
||||
$attributes = array('dn','cn','objectClass','uid','mail');
|
||||
$contactUID = $this->data[$this->contacts_id];
|
||||
if(!empty($contactUID) &&
|
||||
($result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
($result = ldap_search($this->ds, $this->ldap_config['ldap_contact_context'],
|
||||
'(|(entryUUID='.ldap::quote($contactUID).')(uid='.ldap::quote($contactUID).'))', $attributes)) &&
|
||||
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
|
||||
{
|
||||
@ -547,7 +572,7 @@ class addressbook_ldap
|
||||
foreach($keys as $entry)
|
||||
{
|
||||
$entry = ldap::quote(is_array($entry) ? $entry['id'] : $entry);
|
||||
if($result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
if($result = ldap_search($this->ds, $this->ldap_config['ldap_contact_context'],
|
||||
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
|
||||
{
|
||||
$contactInfo = ldap_get_entries($this->ds, $result);
|
||||
@ -625,12 +650,12 @@ class addressbook_ldap
|
||||
}
|
||||
elseif (!isset($filter['owner']))
|
||||
{
|
||||
$searchDN = $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
||||
$searchDN = $this->ldap_config['ldap_contact_context'];
|
||||
$addressbookType = ADDRESSBOOK_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchDN = $GLOBALS['egw_info']['server']['ldap_context'];
|
||||
$searchDN = $this->ldap_config['ldap_context'];
|
||||
$addressbookType = ADDRESSBOOK_ACCOUNTS;
|
||||
}
|
||||
|
||||
@ -955,7 +980,7 @@ class addressbook_ldap
|
||||
/**
|
||||
* check if $baseDN exists. If not create it
|
||||
*
|
||||
* @param string $baseDN cn=xxx,ou=yyy,ou=contacts,$GLOBALS['egw_info']['server']['ldap_contact_context']
|
||||
* @param string $baseDN cn=xxx,ou=yyy,ou=contacts,$this->ldap_config['ldap_contact_context']
|
||||
* @return boolean/string false on success or string with error-message
|
||||
*/
|
||||
function _check_create_dn($baseDN)
|
||||
@ -975,8 +1000,8 @@ class addressbook_ldap
|
||||
|
||||
list(,$ou) = explode(',',$baseDN);
|
||||
foreach(array(
|
||||
'ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
$ou.',ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
'ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||
$ou.',ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||
$baseDN,
|
||||
) as $dn)
|
||||
{
|
||||
|
@ -868,58 +868,72 @@ class addressbook_so
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates an SQL contact storage to LDAP or SQL-LDAP
|
||||
* Migrates an SQL contact storage to LDAP, SQL-LDAP or back to SQL
|
||||
*
|
||||
* @param string $type "contacts" (default), "contacts+accounts" or "contacts+accounts-back" (sql-ldap!)
|
||||
* @param string|array $type comma-separated list or array of:
|
||||
* - "contacts" contacts to ldap
|
||||
* - "accounts" accounts to ldap
|
||||
* - "accounts-back" accounts back to sql (for sql-ldap!)
|
||||
* - "sql" contacts and accounts to sql
|
||||
*/
|
||||
function migrate2ldap($type)
|
||||
{
|
||||
//error_log(__METHOD__."(".array2string($type).")");
|
||||
$sql_contacts = new addressbook_sql();
|
||||
$ldap_contacts = new addressbook_ldap();
|
||||
// we need an admin connection
|
||||
$ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
$ldap_contacts = new addressbook_ldap(null, $ds);
|
||||
|
||||
if (!is_array($type)) $type = explode(',', $type);
|
||||
|
||||
$start = $n = 0;
|
||||
$num = 100;
|
||||
while ($type != 'sql' && ($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
array($start,$num),$type != 'contacts,accounts' ? array('contact_owner != 0') : false)))
|
||||
{
|
||||
// very worse hack, until Ralf finds a better solution
|
||||
// when migrating data, we need to bind as global ldap admin account
|
||||
// and not as currently logged in user
|
||||
$ldap_contacts->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
foreach($contacts as $contact)
|
||||
{
|
||||
if ($contact['account_id']) $contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
|
||||
|
||||
$ldap_contacts->data = $contact;
|
||||
$n++;
|
||||
if (!($err = $ldap_contacts->save()))
|
||||
{
|
||||
echo '<p style="margin: 0px;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '')." --> LDAP</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<p style="margin: 0px; color: red;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '').': '.$err."</p>\n";
|
||||
}
|
||||
}
|
||||
$start += $num;
|
||||
}
|
||||
if ($type == 'contacts,accounts-back' || $type == 'sql') // migrate the accounts to sql
|
||||
// direction SQL --> LDAP, either only accounts, or only contacts or both
|
||||
if (($do = array_intersect($type, array('contacts', 'accounts'))))
|
||||
{
|
||||
// very worse hack, until Ralf finds a better solution
|
||||
// when migrating data, we need to bind as global ldap admin account
|
||||
// and not as currently logged in user
|
||||
$ldap_contacts->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
false,$type == 'sql'?null:array('owner' => 0)) as $contact)
|
||||
$filter = count($do) == 2 ? null :
|
||||
array($do[0] == 'contacts' ? 'contact_owner != 0' : 'contact_owner = 0');
|
||||
|
||||
while (($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
array($start,$num),$filter)))
|
||||
{
|
||||
foreach($contacts as $contact)
|
||||
{
|
||||
if ($contact['account_id']) $contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
|
||||
|
||||
$ldap_contacts->data = $contact;
|
||||
$n++;
|
||||
if (!($err = $ldap_contacts->save()))
|
||||
{
|
||||
echo '<p style="margin: 0px;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '')." --> LDAP</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<p style="margin: 0px; color: red;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '').': '.$err."</p>\n";
|
||||
}
|
||||
}
|
||||
$start += $num;
|
||||
}
|
||||
}
|
||||
// direction LDAP --> SQL: either "sql" (contacts and accounts) or "accounts-back" (only accounts)
|
||||
if (($do = array_intersect(array('accounts-back','sql'), $type)))
|
||||
{
|
||||
//error_log(__METHOD__."(".array2string($type).") do=".array2string($type));
|
||||
$filter = in_array('sql', $do) ? null : array('owner' => 0);
|
||||
|
||||
foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
false, $filter) as $contact)
|
||||
{
|
||||
//error_log(__METHOD__."(".array2string($type).") do=".array2string($type)." migrating ".array2string($contact));
|
||||
if ($contact['jpegphoto']) // photo is NOT read by LDAP backend on search, need to do an extra read
|
||||
{
|
||||
$contact = $ldap_contacts->read($contact['id']);
|
||||
}
|
||||
unset($contact['id']); // ldap uid/account_lid
|
||||
if ($type != 'sql' && $contact['account_id'] && ($old = $sql_contacts->read(array('account_id' => $contact['account_id']))))
|
||||
if ($contact['account_id'] && ($old = $sql_contacts->read(array('account_id' => $contact['account_id']))))
|
||||
{
|
||||
$contact['id'] = $old['id'];
|
||||
}
|
||||
|
@ -990,10 +990,9 @@ class setup
|
||||
if (!$config)
|
||||
{
|
||||
// load the configuration from the database
|
||||
$this->db->select($this->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'",__LINE__,__FILE__);
|
||||
|
||||
while(($row = $this->db->row(true)))
|
||||
foreach($this->db->select($this->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'",
|
||||
__LINE__,__FILE__) as $row)
|
||||
{
|
||||
$GLOBALS['egw_info']['server'][$row['config_name']] = $config[$row['config_name']] = $row['config_value'];
|
||||
}
|
||||
|
@ -257,6 +257,18 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$accounts_obj->set_members($account['members'],$account_id);
|
||||
}
|
||||
}
|
||||
// migrate addressbook data
|
||||
$GLOBALS['egw_info']['user']['apps']['admin'] = true; // otherwise migration will not run in setup!
|
||||
$addressbook = new addressbook_so();
|
||||
foreach($this->as_array() as $name => $value)
|
||||
{
|
||||
if (substr($name, 5) == 'ldap_')
|
||||
{
|
||||
$GLOBALS['egw_info']['server'][$name] = $value;
|
||||
}
|
||||
}
|
||||
$addressbook->migrate2ldap($to_ldap ? 'accounts' : 'accounts-back');
|
||||
|
||||
$this->restore_db();
|
||||
|
||||
return lang('%1 users and %2 groups created, %3 errors',$accounts_created,$groups_created,$errors).
|
||||
@ -397,7 +409,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$this->test_ldap = new ldap();
|
||||
|
||||
$error_rep = error_reporting();
|
||||
//error_reporting($error_rep & ~E_WARNING); // switch warnings of, in case they are on
|
||||
error_reporting($error_rep & ~E_WARNING); // switch warnings of, in case they are on
|
||||
ob_start();
|
||||
$ds = $this->test_ldap->ldapConnect($this->ldap_host,$dn,$pw);
|
||||
ob_end_clean();
|
||||
|
Loading…
Reference in New Issue
Block a user