mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 07:53:39 +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();
|
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->db_data_cols = $this->stock_contact_fields + $this->non_contact_fields;
|
||||||
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
||||||
|
|
||||||
$this->personalContactsDN = 'ou=personal,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
if ($ldap_config)
|
||||||
$this->sharedContactsDN = 'ou=shared,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
{
|
||||||
|
$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();
|
if ($ds)
|
||||||
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($GLOBALS['egw_info']['server']['ldap_contact_host']);
|
{
|
||||||
|
$this->ds = $ds;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->connect();
|
||||||
|
}
|
||||||
|
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($this->ldap_config['ldap_contact_host']);
|
||||||
|
|
||||||
foreach($this->schema2egw as $schema => $attributes)
|
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 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)
|
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'];
|
$this->ldap_config['ldap_contact_host'] = $this->ldap_config['ldap_host'];
|
||||||
$GLOBALS['egw_info']['server']['ldap_contact_context'] = $GLOBALS['egw_info']['server']['ldap_context'];
|
$this->ldap_config['ldap_contact_context'] = $this->ldap_config['ldap_context'];
|
||||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect(
|
$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']['account_dn'],
|
||||||
$GLOBALS['egw_info']['user']['passwd']
|
$GLOBALS['egw_info']['user']['passwd']
|
||||||
);
|
);
|
||||||
@ -298,7 +323,7 @@ class addressbook_ldap
|
|||||||
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']));
|
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']));
|
||||||
$filter = "(|(entryUUID=$contact_id)(uid=$contact_id))";
|
$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);
|
$filter, $this->all_attributes, ADDRESSBOOK_ALL);
|
||||||
|
|
||||||
return $rows ? $rows[0] : false;
|
return $rows ? $rows[0] : false;
|
||||||
@ -339,7 +364,7 @@ class addressbook_ldap
|
|||||||
$data['account_id'] == $GLOBALS['egw_info']['user']['account_id']))
|
$data['account_id'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||||
{
|
{
|
||||||
// account
|
// account
|
||||||
$baseDN = $GLOBALS['egw_info']['server']['ldap_context'];
|
$baseDN = $this->ldap_config['ldap_context'];
|
||||||
$cn = false;
|
$cn = false;
|
||||||
// we need an admin connection
|
// we need an admin connection
|
||||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||||
@ -366,7 +391,7 @@ class addressbook_ldap
|
|||||||
$attributes = array('dn','cn','objectClass','uid','mail');
|
$attributes = array('dn','cn','objectClass','uid','mail');
|
||||||
$contactUID = $this->data[$this->contacts_id];
|
$contactUID = $this->data[$this->contacts_id];
|
||||||
if(!empty($contactUID) &&
|
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)) &&
|
'(|(entryUUID='.ldap::quote($contactUID).')(uid='.ldap::quote($contactUID).'))', $attributes)) &&
|
||||||
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
|
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
|
||||||
{
|
{
|
||||||
@ -547,7 +572,7 @@ class addressbook_ldap
|
|||||||
foreach($keys as $entry)
|
foreach($keys as $entry)
|
||||||
{
|
{
|
||||||
$entry = ldap::quote(is_array($entry) ? $entry['id'] : $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))
|
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
|
||||||
{
|
{
|
||||||
$contactInfo = ldap_get_entries($this->ds, $result);
|
$contactInfo = ldap_get_entries($this->ds, $result);
|
||||||
@ -625,12 +650,12 @@ class addressbook_ldap
|
|||||||
}
|
}
|
||||||
elseif (!isset($filter['owner']))
|
elseif (!isset($filter['owner']))
|
||||||
{
|
{
|
||||||
$searchDN = $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
$searchDN = $this->ldap_config['ldap_contact_context'];
|
||||||
$addressbookType = ADDRESSBOOK_ALL;
|
$addressbookType = ADDRESSBOOK_ALL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$searchDN = $GLOBALS['egw_info']['server']['ldap_context'];
|
$searchDN = $this->ldap_config['ldap_context'];
|
||||||
$addressbookType = ADDRESSBOOK_ACCOUNTS;
|
$addressbookType = ADDRESSBOOK_ACCOUNTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,7 +980,7 @@ class addressbook_ldap
|
|||||||
/**
|
/**
|
||||||
* check if $baseDN exists. If not create it
|
* 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
|
* @return boolean/string false on success or string with error-message
|
||||||
*/
|
*/
|
||||||
function _check_create_dn($baseDN)
|
function _check_create_dn($baseDN)
|
||||||
@ -975,8 +1000,8 @@ class addressbook_ldap
|
|||||||
|
|
||||||
list(,$ou) = explode(',',$baseDN);
|
list(,$ou) = explode(',',$baseDN);
|
||||||
foreach(array(
|
foreach(array(
|
||||||
'ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
'ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||||
$ou.',ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
$ou.',ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||||
$baseDN,
|
$baseDN,
|
||||||
) as $dn)
|
) 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)
|
function migrate2ldap($type)
|
||||||
{
|
{
|
||||||
|
//error_log(__METHOD__."(".array2string($type).")");
|
||||||
$sql_contacts = new addressbook_sql();
|
$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;
|
$start = $n = 0;
|
||||||
$num = 100;
|
$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;
|
// direction SQL --> LDAP, either only accounts, or only contacts or both
|
||||||
$n++;
|
if (($do = array_intersect($type, array('contacts', 'accounts'))))
|
||||||
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
|
|
||||||
{
|
{
|
||||||
// very worse hack, until Ralf finds a better solution
|
$filter = count($do) == 2 ? null :
|
||||||
// when migrating data, we need to bind as global ldap admin account
|
array($do[0] == 'contacts' ? 'contact_owner != 0' : 'contact_owner = 0');
|
||||||
// and not as currently logged in user
|
|
||||||
$ldap_contacts->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
while (($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||||
foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
array($start,$num),$filter)))
|
||||||
false,$type == 'sql'?null:array('owner' => 0)) as $contact)
|
|
||||||
{
|
{
|
||||||
|
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
|
if ($contact['jpegphoto']) // photo is NOT read by LDAP backend on search, need to do an extra read
|
||||||
{
|
{
|
||||||
$contact = $ldap_contacts->read($contact['id']);
|
$contact = $ldap_contacts->read($contact['id']);
|
||||||
}
|
}
|
||||||
unset($contact['id']); // ldap uid/account_lid
|
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'];
|
$contact['id'] = $old['id'];
|
||||||
}
|
}
|
||||||
|
@ -990,10 +990,9 @@ class setup
|
|||||||
if (!$config)
|
if (!$config)
|
||||||
{
|
{
|
||||||
// load the configuration from the database
|
// load the configuration from the database
|
||||||
$this->db->select($this->config_table,'config_name,config_value',
|
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__);
|
"config_name LIKE 'ldap%' OR config_name LIKE 'account_%' OR config_name LIKE '%encryption%' OR config_name='auth_type'",
|
||||||
|
__LINE__,__FILE__) as $row)
|
||||||
while(($row = $this->db->row(true)))
|
|
||||||
{
|
{
|
||||||
$GLOBALS['egw_info']['server'][$row['config_name']] = $config[$row['config_name']] = $row['config_value'];
|
$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);
|
$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();
|
$this->restore_db();
|
||||||
|
|
||||||
return lang('%1 users and %2 groups created, %3 errors',$accounts_created,$groups_created,$errors).
|
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();
|
$this->test_ldap = new ldap();
|
||||||
|
|
||||||
$error_rep = error_reporting();
|
$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();
|
ob_start();
|
||||||
$ds = $this->test_ldap->ldapConnect($this->ldap_host,$dn,$pw);
|
$ds = $this->test_ldap->ldapConnect($this->ldap_host,$dn,$pw);
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
Loading…
Reference in New Issue
Block a user