* Univention: mail app was not working for in UCS created users

because of not set "mail" attribute, UCS only set "mailPrimaryAddress", changed our code to also use just that attribute
This commit is contained in:
Ralf Becker 2015-02-14 12:55:05 +00:00
parent c54e69977a
commit 50e44741a2
4 changed files with 70 additions and 53 deletions

View File

@ -261,8 +261,8 @@ class addressbook_ldap
/**
* constructor of the class
*
* @param array $ldap_config=null default use from $GLOBALS['egw_info']['server']
* @param resource $ds=null ldap connection to use
* @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)
{
@ -292,7 +292,7 @@ class addressbook_ldap
}
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($this->ldap_config['ldap_contact_host']);
foreach($this->schema2egw as $schema => $attributes)
foreach($this->schema2egw as $attributes)
{
$this->all_attributes = array_merge($this->all_attributes,array_values($attributes));
}
@ -312,7 +312,7 @@ class addressbook_ldap
/**
* connect to LDAP server
*
* @param boolean $admin=false true (re-)connect with admin not user credentials, eg. to modify accounts
* @param boolean $admin =false true (re-)connect with admin not user credentials, eg. to modify accounts
*/
function connect($admin = false)
{
@ -395,7 +395,7 @@ class addressbook_ldap
/**
* reads contact data
*
* @param string/array $contact_id contact_id or array with values for id or account_id
* @param string|array $contact_id contact_id or array with values for id or account_id
* @return array/boolean data if row could be retrived else False
*/
function read($contact_id)
@ -444,11 +444,9 @@ class addressbook_ldap
{
$this->data = is_array($this->data) ? array_merge($this->data,$keys) : $keys;
}
$contactUID = '';
$data =& $this->data;
$isUpdate = false;
$newObjectClasses = array();
$ldapContact = array();
// generate addressbook dn
@ -494,7 +492,7 @@ class addressbook_ldap
$contactUID = $this->data[$this->contacts_id];
if (!empty($contactUID) &&
($result = ldap_search($this->ds, $base=$this->allContactsDN, $filter=$this->id_filter($contactUID), $attributes)) &&
($result = ldap_search($this->ds, $base=$this->allContactsDN, $this->id_filter($contactUID), $attributes)) &&
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
{
unset($oldContactInfo[0]['objectclass']['count']);
@ -591,8 +589,8 @@ class addressbook_ldap
if ($needRecreation)
{
$result = ldap_read($this->ds, $dn, 'objectclass=*');
$oldContact = ldap_get_entries($this->ds, $result);
$oldContact = ldap::result2array($oldContact[0]);
$entries = ldap_get_entries($this->ds, $result);
$oldContact = ldap::result2array($entries[0]);
unset($oldContact['dn']);
$newContact = $oldContact;
@ -681,8 +679,8 @@ class addressbook_ldap
foreach($keys as $entry)
{
$entry = ldap::quote(is_array($entry) ? $entry['id'] : $entry);
if($result = ldap_search($this->ds, $this->allContactsDN,
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
if(($result = ldap_search($this->ds, $this->allContactsDN,
"(|(entryUUID=$entry)(uid=$entry))", $attributes)))
{
$contactInfo = ldap_get_entries($this->ds, $result);
if(@ldap_delete($this->ds, $contactInfo[0]['dn']))
@ -699,23 +697,25 @@ class addressbook_ldap
*
* '*' and '?' are replaced with sql-wildcards '%' and '_'
*
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys to return
* @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
* @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
* @param string $wildcard='' appended befor and after each criteria
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
* @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
* @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num)
* @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
* @param array|string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
* @param boolean|string $only_keys =true True returns only keys, False returns all cols. comma seperated list of keys to return
* @param string $order_by ='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
* @param string|array $extra_cols ='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
* @param string $wildcard ='' appended befor and after each criteria
* @param boolean $empty =false False=empty criteria are ignored in query, True=empty have to be empty in row
* @param string $op ='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
* @param mixed $start =false if != false, return only maxmatch rows begining with start, or array($start,$num)
* @param array $filter =null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards
* @param string $join ='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
* "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join!
* @param boolean $need_full_no_count=false If true an unlimited query is run to determine the total number of rows, default false
* @param boolean $need_full_no_count =false If true an unlimited query is run to determine the total number of rows, default false
* @return array of matching rows (the row is an array of the cols) or False
*/
function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
{
//error_log(__METHOD__."(".array2string($criteria).", ".array2string($only_keys).", '$order_by', ".array2string($extra_cols).", '$wildcard', '$empty', '$op', ".array2string($start).", ".array2string($filter).")");
unset($only_keys, $extra_cols, $empty, $join, $need_full_no_count); // not used, but required by function signature
if (is_array($filter['owner']))
{
if (count($filter['owner']) == 1)
@ -738,6 +738,7 @@ class addressbook_ldap
);
foreach($filter as $key => $value)
{
$matches = null;
if (is_int($key) && preg_match('/^(contact_)?(modified|created)([<=>]+)([0-9]+)$/', $value, $matches))
{
$append = '';
@ -952,6 +953,7 @@ class addressbook_ldap
break;
default:
$matches = null;
if (!is_int($key))
{
foreach($this->schema2egw as $mapping)
@ -996,7 +998,7 @@ class addressbook_ldap
* @param string $_filter
* @param array $_attributes
* @param int $_addressbooktype
* @param array $_skipPlugins=null schema-plugins to skip
* @param array $_skipPlugins =null schema-plugins to skip
* @return array/boolean with eGW contacts or false on error
*/
function _searchLDAP($_ldapContext, $_filter, $_attributes, $_addressbooktype, array $_skipPlugins=null)
@ -1062,6 +1064,7 @@ class addressbook_ldap
$bin = ldap_get_values_len($this->ds,ldap_first_entry($this->ds,$result),'jpegphoto');
$contact['jpegphoto'] = $bin[0];
}
$matches = null;
if(preg_match('/cn=([^,]+),'.preg_quote($this->personalContactsDN,'/').'$/i',$entry['dn'],$matches))
{
// personal addressbook
@ -1269,6 +1272,7 @@ class addressbook_ldap
*/
function _inetorgperson2egw(&$contact, $data, $cn='cn')
{
$matches = null;
if(empty($data['givenname'][0]))
{
$parts = explode($data['sn'][0], $data[$cn][0]);
@ -1301,7 +1305,8 @@ class addressbook_ldap
*/
function _posixaccount2egw(&$contact,$data)
{
static $shadowExpireNow;
unset($contact); // not used, but required by function signature
static $shadowExpireNow=null;
if (!isset($shadowExpireNow)) $shadowExpireNow = floor((time()-date('Z'))/86400);
// exclude expired or deactivated accounts
@ -1369,6 +1374,7 @@ class addressbook_ldap
*/
function _mozillaorgperson2egw(&$contact,$data)
{
unset($contact, $data); // not used, but required by function signature
// no special handling necessary, as it supports two distinct attributes: c, cn
}

View File

@ -10,11 +10,17 @@
*/
/**
* Univention backend for accounts
* Univention backend for addressbook
*
* There's currently no difference to LDAP backend
* Different mail attribute is only difference to LDAP backend
*/
class addressbook_univention extends addressbook_ldap
{
function __construct($ldap_config = null, $ds = null)
{
$this->schema2egw['univentionmail'] = array(
'email' => accounts_univention::MAIL_ATTR,
);
parent::__construct($ldap_config, $ds);
}
}

View File

@ -40,6 +40,10 @@
*/
class accounts_ldap
{
/**
* Name of mail attribute
*/
const MAIL_ATTR = 'mail';
/**
* resource with connection to the ldap server
*
@ -84,7 +88,7 @@ class accounts_ldap
),
'user-if-supported' => array( // these classes get added, if server supports them
'mozillaabpersonalpha', 'mozillaorgperson', 'evolutionperson',
'univentionperson', array('univentionobject', 'univentionObjectType' => 'users/user'),
'univentionperson', 'univentionmail', array('univentionobject', 'univentionObjectType' => 'users/user'),
),
'group' => array(
'top','posixgroup','groupofnames'
@ -97,10 +101,9 @@ class accounts_ldap
* Classes allowing to set a mail-address for a group and specify the memberaddresses as forwarding addresses
*
* $objectclass => $forward
* $objectclass => [$forward, $extra_attr, $mail_attr, $keep_objectclass]
* $objectclass => [$forward, $extra_attr, $keep_objectclass]
* $forward : name of attribute to set forwards for members mail addresses, false if not used/required
* $extra_attr : required attribute (eg. 'uid'), which need to be set, default none
* $mail_attr : name of attribute for mail-address, if not 'mail'
* $keep_objectclass : true to not remove objectclass, if not mail set
*
* @var array
@ -110,7 +113,7 @@ class accounts_ldap
'dbmailuser' => array('mailforwardingaddress','uid'),
'qmailuser' => array('mailforwardingaddress','uid'),
'mailaccount' => 'mailalias',
'univentiongroup' => array(false, false, 'mailprimaryaddress', true),
'univentiongroup' => array(false, false, true),
);
/**
@ -294,12 +297,11 @@ class accounts_ldap
foreach($this->group_mail_classes as $objectclass => $forward)
{
$extra_attr = false;
$mail_attr = 'mail';
$keep_objectclass = false;
if (is_array($forward)) list($forward,$extra_attr,$mail_attr,$keep_objectclass) = $forward;
if (is_array($forward)) list($forward,$extra_attr,$keep_objectclass) = $forward;
if ($this->ldapServerInfo->supportsObjectClass($objectclass) &&
($old && in_array($objectclass,$old['objectclass']) || $data_utf8['account_email'] || $old[$mail_attr]))
($old && in_array($objectclass,$old['objectclass']) || $data_utf8['account_email'] || $old[static::MAIL_ATTR]))
{
if ($data_utf8['account_email']) // setting an email
{
@ -309,7 +311,7 @@ class accounts_ldap
$to_write['objectclass'][] = $objectclass;
}
if ($extra_attr) $to_write[$extra_attr] = $data_utf8['account_lid'];
$to_write[$mail_attr] = $data_utf8['account_email'];
$to_write[static::MAIL_ATTR] = $data_utf8['account_email'];
if ($forward)
{
@ -326,7 +328,7 @@ class accounts_ldap
}
elseif($old) // remove the mail and forwards only for existing entries
{
$to_write[$mail_attr] = array();
$to_write[static::MAIL_ATTR] = array();
if ($forward) $to_write[$forward] = array();
if ($extra_attr) $to_write[$extra_attr] = array();
if (!$keep_objectclass && ($key = array_search($objectclass,$old['objectclass'])))
@ -345,11 +347,11 @@ class accounts_ldap
{
$to_write = $this->_merge_user($to_write,$data_utf8,!$old);
// make sure multiple email-addresses in the mail attribute "survive"
if (isset($to_write['mail']) && count($old['mail']) > 1)
if (isset($to_write[static::MAIL_ATTR]) && count($old[static::MAIL_ATTR]) > 1)
{
$mail = $old['mail'];
$mail[0] = $to_write['mail'];
$to_write['mail'] = array_values(array_unique($mail));
$mail = $old[static::MAIL_ATTR];
$mail[0] = $to_write[static::MAIL_ATTR];
$to_write[static::MAIL_ATTR] = array_values(array_unique($mail));
}
$data['account_type'] = 'u';
@ -430,23 +432,21 @@ class accounts_ldap
*/
protected function _read_group($account_id)
{
$mail_attr = 'mail';
$group = array();
if (!is_object($this->ldapServerInfo))
{
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($this->frontend->config['ldap_host']);
}
foreach($this->group_mail_classes as $objectclass => $attrs)
foreach(array_keys($this->group_mail_classes) as $objectclass)
{
if ($this->ldapServerInfo->supportsObjectClass($objectclass))
{
$group['mailAllowed'] = $objectclass;
if (is_array($attrs) && $attrs[2]) $mail_attr = $attrs[2];
break;
}
}
$sri = ldap_search($this->ds, $this->group_context,'(&(objectClass=posixGroup)(gidnumber=' . abs($account_id).'))',
array('dn', 'gidnumber', 'cn', 'objectclass', $mail_attr, 'memberuid'));
array('dn', 'gidnumber', 'cn', 'objectclass', static::MAIL_ATTR, 'memberuid'));
$ldap_data = ldap_get_entries($this->ds, $sri);
if (!$ldap_data['count'])
@ -465,7 +465,7 @@ class accounts_ldap
'account_lastname' => lang('Group'),
'account_fullname' => lang('Group').' '.$data['cn'][0],
'objectclass' => array_map('strtolower', $data['objectclass']),
'account_email' => $data[$mail_attr][0],
'account_email' => $data[static::MAIL_ATTR][0],
'members' => array(),
);
@ -495,7 +495,7 @@ class accounts_ldap
protected function _read_user($account_id)
{
$sri = ldap_search($this->ds, $this->user_context, '(&(objectclass=posixAccount)(uidnumber=' . (int)$account_id.'))',
array('dn','uidnumber','uid','gidnumber','givenname','sn','cn','mail','userpassword','telephonenumber',
array('dn','uidnumber','uid','gidnumber','givenname','sn','cn',static::MAIL_ATTR,'userpassword','telephonenumber',
'shadowexpire','shadowlastchange','homedirectory','loginshell','createtimestamp','modifytimestamp'));
$ldap_data = ldap_get_entries($this->ds, $sri);
@ -514,7 +514,7 @@ class accounts_ldap
'account_primary_group' => -$data['gidnumber'][0],
'account_firstname' => $data['givenname'][0],
'account_lastname' => $data['sn'][0],
'account_email' => $data['mail'][0],
'account_email' => $data[static::MAIL_ATTR][0],
'account_fullname' => $data['cn'][0],
'account_pwd' => $data['userpassword'][0],
'account_phone' => $data['telephonenumber'][0],
@ -581,7 +581,7 @@ class accounts_ldap
$to_write['sn'] = $data['account_lastname'];
if (!$new_entry || $data['account_email'])
{
$to_write['mail'] = $data['account_email'] ? $data['account_email'] : array();
$to_write[static::MAIL_ATTR] = $data['account_email'] ? $data['account_email'] : array();
}
$to_write['cn'] = $data['account_fullname'] ? $data['account_fullname'] : $data['account_firstname'].' '.$data['account_lastname'];
@ -707,7 +707,7 @@ class accounts_ldap
'firstname' => 'givenname',
'lastname' => 'sn',
'lid' => 'uid',
'email' => 'mail',
'email' => static::MAIL_ATTR,
);
$filter .= '('.$to_ldap[$param['query_type']].'=*'.$query.'*)';
break;
@ -761,7 +761,7 @@ class accounts_ldap
$filter = '(&(objectclass=posixaccount)(|(uid='.implode(')(uid=',$relevantAccounts).'))' . $this->account_filter.')';
$filter = str_replace(array('%user','%domain'),array('*',$GLOBALS['egw_info']['user']['domain']),$filter);
}
$sri = ldap_search($this->ds, $this->user_context, $filter,array('uid','uidNumber','givenname','sn','mail','shadowExpire','createtimestamp','modifytimestamp','objectclass','gidNumber'));
$sri = ldap_search($this->ds, $this->user_context, $filter,array('uid','uidNumber','givenname','sn',static::MAIL_ATTR,'shadowExpire','createtimestamp','modifytimestamp','objectclass','gidNumber'));
//echo "<p>ldap_search(,$this->user_context,'$filter',) ".($sri ? '' : ldap_error($this->ds)).microtime()."</p>\n";
$utc_diff = date('Z');
@ -779,7 +779,7 @@ class accounts_ldap
'account_lastname' => translation::convert($allVals['sn'][0],'utf-8'),
'account_status' => isset($allVals['shadowexpire'][0]) && $allVals['shadowexpire'][0]*24*3600-$utc_diff < time() ? false : 'A',
'account_expires' => isset($allVals['shadowexpire']) && $allVals['shadowexpire'][0] ? $allVals['shadowexpire'][0]*24*3600+$utc_diff : -1, // LDAP date is in UTC
'account_email' => $allVals['mail'][0],
'account_email' => $allVals[static::MAIL_ATTR][0],
'account_created' => isset($allVals['createtimestamp'][0]) ? self::accounts_ldap2ts($allVals['createtimestamp'][0]) : null,
'account_modified' => isset($allVals['modifytimestamp'][0]) ? self::accounts_ldap2ts($allVals['modifytimestamp'][0]) : null,
'account_primary_group' => (string)-$allVals['gidnumber'][0],
@ -954,7 +954,7 @@ class accounts_ldap
}
$to_ldap = array(
'account_lid' => 'uid',
'account_email' => 'mail',
'account_email' => static::MAIL_ATTR,
'account_fullname' => 'cn',
);
if (!isset($to_ldap[$which]) || $account_type === 'g') {

View File

@ -20,6 +20,11 @@
*/
class accounts_univention extends accounts_ldap
{
/**
* Attribute with mail address
*/
const MAIL_ATTR = 'mailprimaryaddress';
/**
* Name of binary to call
*/