mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 17:33:49 +01:00
1127 lines
37 KiB
PHP
1127 lines
37 KiB
PHP
<?php
|
|
/**************************************************************************\
|
|
* eGroupWare API - Accounts manager for LDAP *
|
|
* Written by Joseph Engo <jengo@phpgroupware.org> *
|
|
* and Lars Kneschke <lkneschke@phpgw.de> *
|
|
* and Miles Lott <milos@groupwhere.org> *
|
|
* and Bettina Gille <ceb@phpgroupware.org> *
|
|
* View and manipulate account records using LDAP *
|
|
* Copyright (C) 2000 - 2002 Joseph Engo, Lars Kneschke *
|
|
* Copyright (C) 2003 Lars Kneschke, Bettina Gille *
|
|
* ------------------------------------------------------------------------ *
|
|
* This library is part of the eGroupWare API *
|
|
* http://www.egroupware.org *
|
|
* ------------------------------------------------------------------------ *
|
|
* This library is free software; you can redistribute it and/or modify it *
|
|
* under the terms of the GNU Lesser General Public License as published by *
|
|
* the Free Software Foundation; either version 2.1 of the License, *
|
|
* or any later version. *
|
|
* This library is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* See the GNU Lesser General Public License for more details. *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this library; if not, write to the Free Software Foundation, *
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
|
\**************************************************************************/
|
|
/* $Id$ */
|
|
|
|
class accounts_
|
|
{
|
|
var $db;
|
|
var $ds;
|
|
var $account_id;
|
|
var $data;
|
|
var $user_context = '';
|
|
var $group_context = '';
|
|
var $total;
|
|
|
|
var $requiredObjectClasses = array(
|
|
'user' => array(
|
|
'top','person','organizationalperson','inetorgperson','posixaccount','shadowaccount','phpgwaccount'
|
|
),
|
|
'group' => array(
|
|
'top','posixgroup','phpgwaccount',
|
|
// some newer ldap require namedObject here, as none of the above is a structural object there
|
|
// this gets now autodetected
|
|
//'namedObject'
|
|
)
|
|
);
|
|
|
|
function accounts_()
|
|
{
|
|
$this->ds = $GLOBALS['egw']->common->ldapConnect();
|
|
if(!@is_object($GLOBALS['egw']->translation))
|
|
{
|
|
$GLOBALS['egw']->translation =& CreateObject('phpgwapi.translation');
|
|
}
|
|
$this->user_context = $GLOBALS['egw_info']['server']['ldap_context'];
|
|
$this->group_context = $GLOBALS['egw_info']['server']['ldap_group_context'] ?
|
|
$GLOBALS['egw_info']['server']['ldap_group_context'] : $GLOBALS['egw_info']['server']['ldap_context'];
|
|
}
|
|
|
|
function read_repository()
|
|
{
|
|
$acct_type = $this->get_type($this->account_id);
|
|
|
|
/* search the dn for the given uid */
|
|
if(($acct_type == 'g') && $this->group_context)
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, 'gidnumber=' . abs((int)$this->account_id));
|
|
}
|
|
else
|
|
{
|
|
$sri = ldap_search($this->ds, $this->user_context, 'uidnumber=' . (int)$this->account_id);
|
|
}
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
/* Now dump it into the array; take first entry found */
|
|
if($acct_type =='g')
|
|
{
|
|
$this->data['account_id'] = -$allValues[0]['gidnumber'][0];
|
|
$this->data['account_lid'] = $allValues[0]['cn'][0];
|
|
$this->data['firstname'] = $GLOBALS['egw']->translation->convert($allValues[0]['cn'][0],'utf-8');
|
|
$this->data['lastname'] = lang('Group');
|
|
}
|
|
else
|
|
{
|
|
$this->data['account_id'] = $allValues[0]['uidnumber'][0];
|
|
$this->data['account_primary_group'] = -$allValues[0]['gidnumber'][0];
|
|
$this->data['account_lid'] = $allValues[0]['uid'][0];
|
|
$this->data['firstname'] = $GLOBALS['egw']->translation->convert($allValues[0]['givenname'][0],'utf-8');
|
|
$this->data['lastname'] = $GLOBALS['egw']->translation->convert($allValues[0]['sn'][0],'utf-8');
|
|
if(isset($allValues[0]['mail'][0]))
|
|
{
|
|
$this->data['email'] = $allValues[0]['mail'][0];
|
|
}
|
|
}
|
|
$this->data['account_dn'] = $allValues[0]['dn'];
|
|
$this->data['fullname'] = $GLOBALS['egw']->translation->convert($allValues[0]['cn'][0],'utf-8');
|
|
|
|
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
|
|
{
|
|
$this->data['homedirectory'] = $allValues[0]['homedirectory'][0];
|
|
$this->data['loginshell'] = $allValues[0]['loginshell'][0];
|
|
}
|
|
|
|
$this->data['lastlogin'] = $allValues[0]['phpgwaccountlastlogin'][0];
|
|
$this->data['lastloginfrom'] = $allValues[0]['phpgwaccountlastloginfrom'][0];
|
|
$this->data['lastpasswd_change'] = @$allValues[0]['phpgwlastpasswdchange'][0];
|
|
$this->data['status'] = trim($allValues[0]['phpgwaccountstatus'][0]);
|
|
$this->data['type'] = $allValues[0]['phpgwaccounttype'][0];
|
|
$this->data['expires'] = $allValues[0]['phpgwaccountexpires'][0];
|
|
|
|
return $this->data;
|
|
}
|
|
|
|
function save_repository()
|
|
{
|
|
$acct_type = $this->get_type($this->account_id);
|
|
|
|
/* search the dn for the given u/gidnumber */
|
|
if(($acct_type == 'g') && $this->group_context)
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, 'gidnumber=' . abs((int)$this->account_id));
|
|
}
|
|
else
|
|
{
|
|
$sri = ldap_search($this->ds, $this->user_context, 'uidnumber=' . (int)$this->account_id);
|
|
}
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
$this->data['account_type'] = $allValues[0]['phpgwaccounttype'][0];
|
|
|
|
if($acct_type == 'u')
|
|
{
|
|
// data for posixaccount
|
|
$newData['cn'] = $GLOBALS['egw']->translation->convert(sprintf("%s %s",
|
|
$this->data['firstname'],
|
|
$this->data['lastname']),$GLOBALS['egw']->translation->charset(),'utf-8'
|
|
);
|
|
$newData['uid'] = $GLOBALS['egw']->translation->convert(
|
|
$this->data['account_lid'],
|
|
$GLOBALS['egw']->translation->charset(),'utf-8'
|
|
);
|
|
if($this->data['lastname'])
|
|
{
|
|
$newData['sn'] = $GLOBALS['egw']->translation->convert(
|
|
$this->data['lastname'],
|
|
$GLOBALS['egw']->translation->charset(),'utf-8'
|
|
);
|
|
}
|
|
|
|
if($this->data['firstname'])
|
|
{
|
|
$newData['givenname'] = $GLOBALS['egw']->translation->convert(
|
|
$this->data['firstname'],
|
|
$GLOBALS['egw']->translation->charset(),'utf-8'
|
|
);
|
|
}
|
|
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
|
|
{
|
|
$newData['homedirectory'] = $this->data['homedirectory'];
|
|
$newData['loginshell'] = $this->data['loginshell'];
|
|
}
|
|
else
|
|
{
|
|
// the posixaccount schema requires this
|
|
$entry['homedirectory'] = '/home/'.$this->data['account_lid'];
|
|
$entry['loginshell'] = '/bin/false';
|
|
}
|
|
if($this->data['account_primary_group'])
|
|
{
|
|
$newData['gidnumber'] = abs($this->data['account_primary_group']);
|
|
}
|
|
if($this->data['lastlogin'])
|
|
{
|
|
$newData['phpgwaccountlastlogin'] = $this->data['lastlogin'];
|
|
}
|
|
if($this->data['lastloginfrom'])
|
|
{
|
|
$newData['phpgwaccountlastloginfrom'] = $this->data['lastloginfrom'];
|
|
}
|
|
if($this->data['lastpasswd_change'])
|
|
{
|
|
$newData['phpgwlastpasswdchange'] = $this->data['lastpasswd_change'];
|
|
}
|
|
if($this->data['status'])
|
|
{
|
|
$newData['phpgwaccountstatus'] = $this->data['status'];
|
|
}
|
|
else
|
|
{
|
|
$newData['phpgwaccountstatus'] = array();
|
|
}
|
|
if($this->data['expires'])
|
|
{
|
|
$newData['phpgwaccountexpires'] = $this->data['expires'];
|
|
}
|
|
if($this->data['email'])
|
|
{
|
|
$newData['mail'] = $this->data['email'];
|
|
}
|
|
|
|
// check that we have all required objectclasses
|
|
unset($allValues[0]['objectclass']['count']);
|
|
// convert all values to lowercase
|
|
$currentObjectClasses = array_flip(array_change_key_case(array_flip($allValues[0]['objectclass'])));
|
|
$missingObjectClasses = array_diff($this->requiredObjectClasses['user'],$currentObjectClasses);
|
|
if(count($missingObjectClasses) > 0)
|
|
{
|
|
$newData['objectclass'] = array_merge($currentObjectClasses, $missingObjectClasses);
|
|
}
|
|
$newAccountID = $newData['uid'];
|
|
$oldAccountID = $newData['uid'];
|
|
}
|
|
else
|
|
{
|
|
// data for posixgroup
|
|
$newData['cn'] = $GLOBALS['egw']->translation->convert(
|
|
$this->data['account_lid'],
|
|
$GLOBALS['egw']->translation->charset(), 'utf-8'
|
|
);
|
|
$newData['gidnumber'] = abs($this->account_id);
|
|
$newGroupID = $newData['cn'];
|
|
$oldGroupID = $newData['cn'];
|
|
}
|
|
if($this->data['account_type'])
|
|
{
|
|
$newData['phpgwaccounttype'] = $this->data['account_type'];
|
|
}
|
|
|
|
/*
|
|
Changing the uid: Need to delete and add new, since
|
|
PHP cannot change the dn for the entry.
|
|
*/
|
|
if ($acct_type == 'g')
|
|
{
|
|
$test = $allValues[0]['cn'][0];
|
|
}
|
|
else
|
|
{
|
|
$test = $allValues[0]['uid'][0];
|
|
}
|
|
if($GLOBALS['egw']->translation->convert($test,'utf-8') != $this->data['account_lid'])
|
|
{
|
|
$oldData = $allValues[0];
|
|
$oldDN = $oldData['dn'];
|
|
// remove all unneeded fields
|
|
unset($oldData['dn']);
|
|
unset($oldData['count']);
|
|
foreach($oldData as $key => $value)
|
|
{
|
|
if(is_numeric($key))
|
|
{
|
|
// remove the key, its no ldap key
|
|
unset($oldData[$key]);
|
|
}
|
|
else
|
|
{
|
|
// remove the count key
|
|
if($oldData[$key]['count'] == 1)
|
|
{
|
|
$oldData[$key] = $value[0];
|
|
}
|
|
else
|
|
{
|
|
unset($oldData[$key]['count']);
|
|
}
|
|
}
|
|
}
|
|
|
|
$oldAccountID = $oldData['uid'];
|
|
$oldGroupID = $oldData['cn'];
|
|
|
|
// merge the old data with the new one
|
|
$newData = array_merge($oldData, $newData);
|
|
|
|
/* Groups */
|
|
if($this->data['account_type'] == 'g' && $this->group_context )
|
|
{
|
|
$newDN = 'cn='.$this->data['account_lid'].','.$this->group_context;
|
|
$newData['memberuid'] = array();
|
|
if (($members = $this->member($this->account_id)))
|
|
{
|
|
foreach($members as $member)
|
|
{
|
|
if (!in_array($member['account_name'],$newData['memberuid']))
|
|
{
|
|
$newData['memberuid'][] = $member['account_name'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Accounts */
|
|
else
|
|
{
|
|
$newDN = 'uid='.$this->data['account_lid'].','.$this->user_context;
|
|
}
|
|
// delete the old account
|
|
ldap_delete($this->ds,$oldDN);
|
|
|
|
// add the new account
|
|
#_debug_array($newData);
|
|
if (!@ldap_add($this->ds, $newDN, $newData) && $this->data['account_type'] == 'g')
|
|
{
|
|
// try again with namedObject added, in case we have the newer schema which eg. SuSE uses
|
|
// in which our required objectclasses for a group, have no structural object
|
|
$newData['objectclass'][] = 'namedObject';
|
|
ldap_add($this->ds, $newDN, $newData);
|
|
}
|
|
}
|
|
/* Normal behavior for save_repository update Account */
|
|
else
|
|
{
|
|
// add the list group members
|
|
if($this->data['account_type'] == 'g' && ($members = $this->member($this->account_id)))
|
|
{
|
|
$newData['memberuid'] = array();
|
|
foreach($members as $member)
|
|
{
|
|
if (!in_array($member['account_name'],$newData['memberuid']))
|
|
{
|
|
$newData['memberuid'][] = $member['account_name'];
|
|
}
|
|
}
|
|
}
|
|
// modify the DN
|
|
//echo "<p>ldap_modify(,'{$allValues[0]['dn']}',".print_r($newData,true).")</p>\n";
|
|
ldap_modify($this->ds, $allValues[0]['dn'], $newData);
|
|
}
|
|
|
|
if ($this->data['account_type'] == 'u')
|
|
{
|
|
// lets check for groups, the user needs to be removed
|
|
|
|
// first lets search for the groups, the user is currently member of
|
|
// and from which he needs to be removed
|
|
$filter = "(&(objectclass=posixgroup)(memberuid=" . (int)$oldAccountID . "))";
|
|
$justThese = array('memberuid','gidnumber');
|
|
$sri = ldap_search($this->ds, $this->group_context, $filter, $justThese);
|
|
if($sri)
|
|
{
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
if($allValues['count'] > 0)
|
|
{
|
|
unset($allValues['count']);
|
|
foreach($allValues as $key)
|
|
{
|
|
#_debug_array($key);
|
|
#_debug_array($this->data['account_groups']);
|
|
// delete the old accountid from any group
|
|
if($newAccountID != $oldAccountID)
|
|
{
|
|
$dn = $key['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'] = $key['memberuid'];
|
|
unset($newData['memberuid']['count']);
|
|
// remove the uid from memberuid
|
|
$newData['memberuid'] = array_flip($newData['memberuid']);
|
|
unset($newData['memberuid'][$oldAccountID]);
|
|
# $newData['memberuid'] = array_values(sort(array_flip($newData['memberuid'])));
|
|
$newData['memberuid'] = array_values(array_flip($newData['memberuid']));
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
#print ldap_error($this->ds);
|
|
}
|
|
else
|
|
{
|
|
if(!in_array($key['gidnumber'][0],$this->data['account_groups']))
|
|
{
|
|
$dn = $key['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'] = $key['memberuid'];
|
|
unset($newData['memberuid']['count']);
|
|
// remove the uid from memberuid
|
|
$newData['memberuid'] = array_flip($newData['memberuid']);
|
|
unset($newData['memberuid'][$oldAccountID]);
|
|
$newData['memberuid'] = array_values(sort(array_flip($newData['memberuid'])));
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
#print ldap_error($this->ds);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// lets check group the user needs to be added
|
|
foreach($this->data['account_groups'] as $key => $value)
|
|
{
|
|
// search for the group
|
|
$filter = 'gidnumber=' . abs((int)$value);
|
|
$justThese = array('memberuid');
|
|
$sri = ldap_search($this->ds, $this->group_context, $filter, $justThese);
|
|
if($sri)
|
|
{
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
// if the user is not member of this group, add him
|
|
if(is_array($allValues[0]['memberuid']))
|
|
{
|
|
// this group has already some members
|
|
if(!in_array($newData['uid'],$allValues[0]['memberuid']))
|
|
{
|
|
$dn = $allValues[0]['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'] = $allValues[0]['memberuid'];
|
|
unset($newData['memberuid']['count']);
|
|
$newData['memberuid'][] = $newAccountID;
|
|
$newData['memberuid'] = array_values(array_unique($newData['memberuid']));
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// this group has no members
|
|
$dn = $allValues[0]['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'][] = $newAccountID;
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function delete($accountid = '')
|
|
{
|
|
$account_id = get_account_id($accountid);
|
|
$account_lid = $this->id2name((int)$account_id);
|
|
|
|
if ($account_id < 0)
|
|
{
|
|
$filter = 'gidnumber=' . abs((int)$account_id);
|
|
$context = $this->group_context;
|
|
}
|
|
else
|
|
{
|
|
$filter = 'uid=' . (string)$account_lid;
|
|
$context = $this->user_context;
|
|
$wasAccount = True;
|
|
}
|
|
|
|
$sri = ldap_search($this->ds, $context, $filter);
|
|
if($sri)
|
|
{
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
$accountID = $allValues['0']['uid'][0];
|
|
}
|
|
|
|
if ($allValues[0]['dn'])
|
|
{
|
|
$del = ldap_delete($this->ds, $allValues[0]['dn']);
|
|
}
|
|
|
|
if($wasAccount)
|
|
{
|
|
// remove the user from any group he is member of
|
|
$filter = "(&(objectclass=posixgroup)(memberuid=" . $accountID . "))";
|
|
$justThese = array('memberuid','gidnumber');
|
|
$sri = ldap_search($this->ds, $this->group_context, $filter, $justThese);
|
|
if($sri)
|
|
{
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
if($allValues['count'] > 0)
|
|
{
|
|
unset($allValues['count']);
|
|
foreach($allValues as $key)
|
|
{
|
|
$dn = $key['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'] = $key['memberuid'];
|
|
unset($newData['memberuid']['count']);
|
|
// remove the uid from memberuid
|
|
$newData['memberuid'] = array_flip($newData['memberuid']);
|
|
unset($newData['memberuid'][$accountID]);
|
|
$newData['memberuid'] = array_unique(array_flip($newData['memberuid']));
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function get_list($_type='both', $start = '',$sort = '', $order = '', $query = '', $offset = '', $query_type='')
|
|
{
|
|
//print "\$_type=$_type, \$start=$start , \$sort=$sort, \$order=$order, \$query=$query, \$offset=$offset, \$query_type=$query_type<br>";
|
|
$query = strtolower($query);
|
|
|
|
if($_type != 'groups')
|
|
{
|
|
$filter = "(&(uidnumber=*)(phpgwaccounttype=u)";
|
|
if (!empty($query) && $query != '*')
|
|
{
|
|
switch($query_type)
|
|
{
|
|
case 'all':
|
|
default:
|
|
$query = '*'.$query;
|
|
// fall-through
|
|
case 'start':
|
|
$query .= '*';
|
|
// fall-through
|
|
case 'exact':
|
|
$filter .= "(|(uid=$query)(sn=$query)(cn=$query)(givenname=$query)(mail=$query))";
|
|
break;
|
|
case 'firstname':
|
|
case 'lastname':
|
|
case 'lid':
|
|
case 'email':
|
|
$to_ldap = array(
|
|
'firstname' => 'givenname',
|
|
'lastname' => 'sn',
|
|
'lid' => 'uid',
|
|
'email' => 'mail',
|
|
);
|
|
$filter .= '('.$to_ldap[$query_type].'=*'.$query.'*)';
|
|
break;
|
|
}
|
|
}
|
|
$filter .= ')';
|
|
|
|
$sri = ldap_search($this->ds, $this->user_context, $filter);
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
while (list($null,$allVals) = @each($allValues))
|
|
{
|
|
settype($allVals,'array');
|
|
$test = @$allVals['uid'][0];
|
|
if (!$GLOBALS['egw_info']['server']['global_denied_users'][$test] && $allVals['uid'][0])
|
|
{
|
|
$accounts[] = Array(
|
|
'account_id' => $allVals['uidnumber'][0],
|
|
'account_lid' => $allVals['uid'][0],
|
|
'account_type' => $allVals['phpgwaccounttype'][0],
|
|
'account_firstname' => $GLOBALS['egw']->translation->convert($allVals['givenname'][0],'utf-8'),
|
|
'account_lastname' => $GLOBALS['egw']->translation->convert($allVals['sn'][0],'utf-8'),
|
|
'account_status' => $allVals['phpgwaccountstatus'][0],
|
|
'account_email' => $allVals['mail'][0],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if ($_type != 'accounts')
|
|
{
|
|
if(empty($query) || $query == '*')
|
|
{
|
|
$filter = '(&(gidnumber=*)(phpgwaccounttype=g))';
|
|
}
|
|
else
|
|
{
|
|
$filter = "(&(gidnumber=*)(phpgwaccounttype=g)(|(uid=*$query*)(sn=*$query*)(cn=*$query*)(givenname=*$query*)))";
|
|
}
|
|
$sri = ldap_search($this->ds, $this->group_context, $filter);
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
while (list($null,$allVals) = @each($allValues))
|
|
{
|
|
settype($allVals,'array');
|
|
$test = $allVals['cn'][0];
|
|
if (!$GLOBALS['egw_info']['server']['global_denied_groups'][$test] && $allVals['cn'][0])
|
|
{
|
|
$accounts[] = Array(
|
|
'account_id' => -$allVals['gidnumber'][0],
|
|
'account_lid' => $allVals['cn'][0],
|
|
'account_type' => $allVals['phpgwaccounttype'][0],
|
|
'account_firstname' => $GLOBALS['egw']->translation->convert($allVals['givenname'][0],'utf-8'),
|
|
'account_lastname' => $GLOBALS['egw']->translation->convert($allVals['sn'][0],'utf-8'),
|
|
'account_status' => $allVals['phpgwaccountstatus'][0],
|
|
'account_email' => $allVals['mail'][0],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// sort the array
|
|
$arrayFunctions =& CreateObject('phpgwapi.arrayfunctions');
|
|
if(empty($order))
|
|
{
|
|
$order = 'account_lid';
|
|
}
|
|
$sortedAccounts = $arrayFunctions->arfsort($accounts,explode(',',$order),$sort);
|
|
$this->total = count($accounts);
|
|
// return only the wanted accounts
|
|
if (is_array($sortedAccounts))
|
|
{
|
|
reset($sortedAccounts);
|
|
if(is_numeric($start) && is_numeric($offset))
|
|
{
|
|
return array_slice($sortedAccounts, $start, $offset);
|
|
}
|
|
elseif(is_numeric($start))
|
|
{
|
|
if (!($maxmatchs = $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'])) $maxmatchs = 15;
|
|
|
|
return array_slice($sortedAccounts, $start, $maxmatchs);
|
|
}
|
|
else
|
|
{
|
|
return $sortedAccounts;
|
|
}
|
|
}
|
|
return False;
|
|
}
|
|
|
|
function name2id($name,$which='account_lid')
|
|
{
|
|
if ($which == 'account_lid') // groups only support account_lid
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, '(&(cn=' . (string)$name . ')(phpgwaccounttype=g))');
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
if (@$allValues[0]['gidnumber'][0])
|
|
{
|
|
return -(int)$allValues[0]['gidnumber'][0];
|
|
}
|
|
}
|
|
$to_ldap = array(
|
|
'account_lid' => 'uid',
|
|
'account_email' => 'mail',
|
|
);
|
|
if (!isset($to_ldap[$which])) return False;
|
|
|
|
$sri = ldap_search($this->ds, $this->user_context, '(&('.$to_ldap[$which].'=' . (string)$name . ')(phpgwaccounttype=u))');
|
|
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
if (@$allValues[0]['uidnumber'][0])
|
|
{
|
|
return (int)$allValues[0]['uidnumber'][0];
|
|
}
|
|
|
|
return False;
|
|
}
|
|
|
|
function id2name($account_id,$which='account_lid')
|
|
{
|
|
if (($which == 'account_lid' || $which == 'account_type') && $account_id < 0) // groups only support account_lid and account_type
|
|
{
|
|
$allValues = array();
|
|
$sri = ldap_search($this->ds, $this->group_context, '(&(gidnumber=' . abs((int)$account_id) . ')(phpgwaccounttype=g))');
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
$attr = $which == 'account_lid' ? 'cn' : 'phpgwaccounttype';
|
|
if (@$allValues[0]['cn'][0])
|
|
{
|
|
return $allValues[0]['cn'][0];
|
|
}
|
|
}
|
|
$to_ldap = array(
|
|
'account_lid' => 'uid',
|
|
'account_email' => 'mail',
|
|
'account_firstname' => 'surname',
|
|
'account_lastname' => 'cn',
|
|
'account_type' => 'phpgwaccounttype',
|
|
);
|
|
if (!isset($to_ldap[$which])) return False;
|
|
|
|
$allValues = array();
|
|
$sri = ldap_search($this->ds, $this->user_context, '(&(uidnumber=' . (int)$account_id . ')(phpgwaccounttype=u))');
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
if (@$allValues[0][$to_ldap[$which]][0])
|
|
{
|
|
return $allValues[0][$to_ldap[$which]][0];
|
|
}
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* returns nonzero if $account exists in LDAP: 0: nowhere 1: user accounts, 2: group accounts, 3: both
|
|
* $account can be an account_id (LDAP: uidnumber) or an account_lid (LDAP: uid) (is determinded by ettype($account) == 'integer')
|
|
*/
|
|
function exists($account)
|
|
{
|
|
/* This sets up internal caching variables for this functon */
|
|
static $by_id, $by_lid;
|
|
$users = array();
|
|
$groups = array();
|
|
|
|
if(is_numeric($account))
|
|
{
|
|
$ldapgroup = 'gidnumber';
|
|
$ldapacct = 'uidnumber';
|
|
/* If data is cached, use it. */
|
|
if(isset($by_id[$account]))
|
|
{
|
|
return $by_id[$account];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$ldapgroup = 'cn';
|
|
$ldapacct = 'uid';
|
|
/* If data is cached, use it. */
|
|
if(@isset($by_lid[$account]) && @$by_lid[$account])
|
|
{
|
|
return $by_lid[$account];
|
|
}
|
|
}
|
|
|
|
$acct_type = $this->get_type($account) ? $this->get_type($account) : $this->account_type;
|
|
|
|
if ($acct_type == 'g' && $this->group_context)
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, $ldapgroup . '=' . abs($account));
|
|
$groups = ldap_get_entries($this->ds, $sri);
|
|
}
|
|
$sri = ldap_search($this->ds, $this->user_context, $ldapacct . '=' . $account);
|
|
$users = ldap_get_entries($this->ds, $sri);
|
|
|
|
if ($users[0]['dn'])
|
|
{
|
|
$in += 1;
|
|
}
|
|
if ($groups[0]['dn'])
|
|
{
|
|
$in += 2;
|
|
}
|
|
/* This sets up internal caching for this function */
|
|
if($ldapgroup == 'gidnumber')
|
|
{
|
|
$by_id[$account] = $in;
|
|
$by_lid[$this->id2name($account)] = $in;
|
|
}
|
|
else
|
|
{
|
|
$by_lid[$account] = $in;
|
|
$by_id[$this->name2id($account)] = $in;
|
|
}
|
|
return $in;
|
|
}
|
|
|
|
function create($account_info,$default_prefs=True)
|
|
{
|
|
/* echo '<br>in create for account_lid: "'.$account_lid.'"'; */
|
|
if (empty($account_info['account_id']) || !$account_info['account_id'])
|
|
{
|
|
$account_id = $this->get_nextid($account_info['account_type']);
|
|
/* echo '<br>using'.$account_id;exit; */
|
|
}
|
|
else
|
|
{
|
|
$account_id = abs($account_info['account_id']);
|
|
}
|
|
$entry['userpassword'] = $account_info['account_passwd'];
|
|
$entry['phpgwaccounttype'] = $account_info['account_type'];
|
|
$entry['phpgwaccountexpires'] = $account_info['account_expires'];
|
|
|
|
if($account_info['account_type'] == 'g')
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, 'cn=' . (string)$account_info['account_lid']);
|
|
}
|
|
else
|
|
{
|
|
$sri = ldap_search($this->ds, $this->user_context, 'uid=' . (string)$account_info['account_lid']);
|
|
}
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'] && $account_info['account_type'] != 'g')
|
|
{
|
|
$entry['homedirectory'] = $account_info['homedirectory'] && $account_info['homedirectory'] != $GLOBALS['egw_info']['server']['ldap_account_home'] ? $account_info['homedirectory'] : $GLOBALS['egw_info']['server']['ldap_account_home'].SEP.$account_info['account_lid'];
|
|
$entry['loginshell'] = $account_info['loginshell'] ? $account_info['loginshell'] : $GLOBALS['egw_info']['server']['ldap_account_shell'];
|
|
}
|
|
elseif($account_info['account_type'] != 'g')
|
|
{
|
|
$entry['homedirectory'] = '/home/'.$account_info['account_lid'];
|
|
$entry['loginshell'] = '/bin/false';
|
|
}
|
|
|
|
if ($allValues[0]['dn'])
|
|
{
|
|
/* This should keep the password from being overwritten here on ldap import */
|
|
unset($entry['userpassword']);
|
|
$entry['gidnumber'] = $account_id;
|
|
|
|
while (list($key,$val) = each($entry))
|
|
{
|
|
$tmpentry = '';
|
|
$tmpentry[$key] = trim($val); /* must trim! */
|
|
/* echo '<br>'.$key.' '.$val; */
|
|
if ($tmpentry[$key])
|
|
{
|
|
if (!$allValues[0][$key][0])
|
|
{
|
|
/* attribute was not in LDAP, add it */
|
|
ldap_mod_add($this->ds, $allValues[0]['dn'], $tmpentry);
|
|
}
|
|
else
|
|
{
|
|
/* attribute was in LDAP, modify it */
|
|
ldap_modify($this->ds, $allValues[0]['dn'], $tmpentry);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($account_info['account_type'] == 'g')
|
|
{
|
|
$tmpentry['objectclass'] = $this->requiredObjectClasses['group'];
|
|
}
|
|
else
|
|
{
|
|
$tmpentry['objectclass'] = $this->requiredObjectClasses['user'];
|
|
$tmpentry['uidnumber'] = $account_id;
|
|
$tmpentry['userpassword'] = $GLOBALS['egw']->common->encrypt_password($account_info['account_passwd'],False);
|
|
$tmpentry['phpgwaccountstatus'] = $account_info['account_status'];
|
|
$tmpentry['phpgwaccounttype'] = $account_info['account_type'];
|
|
$tmpentry['phpgwaccountexpires'] = $account_info['account_expires'];
|
|
}
|
|
ldap_modify($this->ds, $allValues[0]['dn'], $tmpentry);
|
|
}
|
|
else
|
|
{
|
|
/* Not already there, we will add it */
|
|
if ($account_info['account_type'] == 'g')
|
|
{
|
|
$dn = 'cn='.$account_info['account_lid'] . ',' . $this->group_context;
|
|
unset($entry['homedirectory']);
|
|
unset($entry['loginshell']);
|
|
unset($entry['userpassword']);
|
|
$entry['objectclass'] = $this->requiredObjectClasses['group'];
|
|
$entry['cn'] = $GLOBALS['egw']->translation->convert($account_info['account_lid'],$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
$entry['gidnumber'] = $account_id;
|
|
$entry['description'] = 'eGW-created group';
|
|
}
|
|
else
|
|
{
|
|
$dn = 'uid=' . $account_info['account_lid'] . ',' . $this->user_context;
|
|
|
|
$entry['cn'] = $GLOBALS['egw']->translation->convert(
|
|
sprintf(
|
|
"%s %s",
|
|
$account_info['account_firstname'],
|
|
$account_info['account_lastname']
|
|
),
|
|
$GLOBALS['egw']->translation->charset(),
|
|
'utf-8'
|
|
);
|
|
|
|
$entry['sn'] = $GLOBALS['egw']->translation->convert(
|
|
$account_info['account_lastname'] ? $account_info['account_lastname'] : 'not set',
|
|
$GLOBALS['egw']->translation->charset(),
|
|
'utf-8'
|
|
);
|
|
|
|
if($account_info['account_firstname'])
|
|
{
|
|
$entry['givenname'] = $GLOBALS['egw']->translation->convert(
|
|
$account_info['account_firstname'],
|
|
$GLOBALS['egw']->translation->charset(),
|
|
'utf-8'
|
|
);
|
|
}
|
|
if($account_info['account_email'])
|
|
{
|
|
$entry['mail'] = $GLOBALS['egw']->translation->convert(
|
|
$account_info['account_email'],
|
|
$GLOBALS['egw']->translation->charset(),
|
|
'utf-8'
|
|
);
|
|
}
|
|
$entry['uid'] = $account_info['account_lid'];
|
|
$entry['uidnumber'] = $account_id;
|
|
$entry['gidnumber'] = abs($account_info['account_primary_group']);
|
|
$entry['userpassword'] = $GLOBALS['egw']->common->encrypt_password($account_info['account_passwd']);
|
|
$entry['objectclass'] = $this->requiredObjectClasses['user'];
|
|
if($account_info['account_status'])
|
|
{
|
|
$entry['phpgwaccountstatus'] = $account_info['account_status'];
|
|
}
|
|
$entry['phpgwaccounttype'] = $account_info['account_type'];
|
|
$entry['phpgwaccountexpires'] = $account_info['account_expires'];
|
|
}
|
|
|
|
#_debug_array($entry);
|
|
|
|
// stop processing if ldap_add fails
|
|
if(!@ldap_add($this->ds, $dn, $entry))
|
|
{
|
|
if ($account_info['account_type'] != 'g')
|
|
{
|
|
return false;
|
|
}
|
|
// try again with namedObject added, in case we have the newer schema which eg. SuSE uses
|
|
// in which our required objectclasses for a group, have no structural object
|
|
if ($account_info['account_type'] == 'g')
|
|
{
|
|
$entry['objectclass'][] = 'namedObject';
|
|
|
|
if (!@ldap_add($this->ds, $dn, $entry))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// print ldap_error($this->ds);
|
|
|
|
// lets check group the user needs to be added
|
|
if($account_info['account_type'] == 'u')
|
|
{
|
|
@settype($account_info['account_groups'],'array');
|
|
foreach($account_info['account_groups'] as $key => $value)
|
|
{
|
|
// search for the group
|
|
$filter = 'gidnumber=' . abs($value);
|
|
$justThese = array('memberuid');
|
|
$sri = ldap_search($this->ds, $this->group_context, $filter, $justThese);
|
|
if($sri)
|
|
{
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
// if the user is not member of this group, add him
|
|
if(is_array($allValues[0]['memberuid']))
|
|
{
|
|
// this group has already some members
|
|
if(!in_array($account_info['account_lid'],$allValues[0]['memberuid']))
|
|
{
|
|
$dn = $allValues[0]['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'] = $allValues[0]['memberuid'];
|
|
unset($newData['memberuid']['count']);
|
|
$newData['memberuid'][] = $account_info['account_lid'];
|
|
$newData['memberuid'] = array_unique($newData['memberuid']);
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
#print ldap_error($this->ds)."<br>";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// this group has no members
|
|
$dn = $allValues[0]['dn'];
|
|
$newData = array();
|
|
$newData['memberuid'][] = $account_info['account_lid'];
|
|
ldap_mod_replace($this->ds, $dn, $newData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if($account_id && is_object($GLOBALS['egw']->preferences) && $default_prefs)
|
|
{
|
|
$GLOBALS['egw']->preferences->create_defaults($account_id);
|
|
}
|
|
|
|
if($account_info['account_type'] == 'g')
|
|
{
|
|
return -$account_id;
|
|
}
|
|
else
|
|
{
|
|
return $account_id;
|
|
}
|
|
}
|
|
|
|
function auto_add($accountname, $passwd, $default_prefs = False, $default_acls = False, $expiredate = 0, $account_status = 'A')
|
|
{
|
|
if ($expiredate == 0)
|
|
{
|
|
if(isset($GLOBALS['egw_info']['server']['auto_create_expire']) == True)
|
|
{
|
|
if($GLOBALS['egw_info']['server']['auto_create_expire'] == 'never')
|
|
{
|
|
$expires = -1;
|
|
}
|
|
else
|
|
{
|
|
$expiredate = time() + $GLOBALS['egw_info']['server']['auto_create_expire'];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* expire in 30 days by default */
|
|
$expiredate = time() + ((60 * 60) * (30 * 24));
|
|
}
|
|
|
|
if ($expires != -1)
|
|
{
|
|
$expires = mktime(2,0,0,date('n',$expiredate), (int)date('d',$expiredate), date('Y',$expiredate));
|
|
}
|
|
|
|
$default_group_id = $this->name2id($GLOBALS['egw_info']['server']['default_group_lid']);
|
|
if (!$default_group_id)
|
|
{
|
|
$default_group_id = abs((int)$this->name2id('Default'));
|
|
}
|
|
$primary_group = $GLOBALS['auto_create_acct']['primary_group'] &&
|
|
$this->get_type((int)$GLOBALS['auto_create_acct']['primary_group']) == 'g' ?
|
|
(int)$GLOBALS['auto_create_acct']['primary_group'] : $default_group_id;
|
|
|
|
$acct_info = array(
|
|
'account_lid' => $accountname,
|
|
'account_type' => 'u',
|
|
'account_passwd' => $passwd,
|
|
'account_firstname' => $GLOBALS['auto_create_acct']['firstname'] ? $GLOBALS['auto_create_acct']['firstname'] : 'New',
|
|
'account_lastname' => $GLOBALS['auto_create_acct']['lastname'] ? $GLOBALS['auto_create_acct']['lastname'] : 'User',
|
|
'account_status' => $account_status,
|
|
'account_expires' => $expires,
|
|
'account_primary_group' => $primary_group,
|
|
);
|
|
|
|
/* attempt to set an email address */
|
|
if (isset($GLOBALS['auto_create_acct']['email']) == True && $GLOBALS['auto_create_acct']['email'] != '')
|
|
{
|
|
$acct_info['account_email'] = $GLOBALS['auto_create_acct']['email'];
|
|
}
|
|
elseif(isset($GLOBALS['egw_info']['server']['mail_suffix']) == True && $GLOBALS['egw_info']['server']['mail_suffix'] != '')
|
|
{
|
|
$acct_info['account_email'] = $accountname . '@' . $GLOBALS['egw_info']['server']['mail_suffix'];
|
|
}
|
|
|
|
$this->db->transaction_begin();
|
|
|
|
$this->create($acct_info,$default_prefs); /* create the account */
|
|
|
|
$accountid = $this->name2id($accountname); /* grab the account id or an error code */
|
|
|
|
if ($accountid) /* begin account setup */
|
|
{
|
|
if($primary_group)
|
|
{
|
|
$GLOBALS['egw']->acl->add_repository('phpgw_group', $primary_group,$accountid,1);
|
|
}
|
|
|
|
/* if we have an mail address set it in the users' email preference */
|
|
if (isset($GLOBALS['auto_create_acct']['email']) && $GLOBALS['auto_create_acct']['email'] != '')
|
|
{
|
|
$GLOBALS['egw']->acl->acl($accountid); /* needed als preferences::save_repository calls acl */
|
|
$GLOBALS['egw']->preferences->preferences($accountid);
|
|
$GLOBALS['egw']->preferences->read_repository();
|
|
$GLOBALS['egw']->preferences->add('email','address',$GLOBALS['auto_create_acct']['email']);
|
|
$GLOBALS['egw']->preferences->save_repository();
|
|
}
|
|
/* use the default mail domain to set the uesrs' email preference */
|
|
elseif(isset($GLOBALS['egw_info']['server']['mail_suffix']) && $GLOBALS['egw_info']['server']['mail_suffix'] != '')
|
|
{
|
|
$GLOBALS['egw']->acl->acl($accountid); /* needed als preferences::save_repository calls acl */
|
|
$GLOBALS['egw']->preferences->preferences($accountid);
|
|
$GLOBALS['egw']->preferences->read_repository();
|
|
$GLOBALS['egw']->preferences->add('email','address', $accountname . '@' . $GLOBALS['egw_info']['server']['mail_suffix']);
|
|
$GLOBALS['egw']->preferences->save_repository();
|
|
}
|
|
|
|
/* commit the new account transaction */
|
|
$this->db->transaction_commit();
|
|
|
|
// call hook to notify interested apps about the new account
|
|
$GLOBALS['hook_values']['account_lid'] = $acct_info['account_lid'];
|
|
$GLOBALS['hook_values']['account_id'] = $accountid;
|
|
$GLOBALS['hook_values']['new_passwd'] = $acct_info['account_passwd'];
|
|
$GLOBALS['hook_values']['account_status'] = $acct_info['account_status'];
|
|
$GLOBALS['hook_values']['account_firstname'] = $acct_info['account_firstname'];
|
|
$GLOBALS['hook_values']['account_lastname'] = $acct_info['account_lastname'];
|
|
$GLOBALS['egw']->hooks->process($GLOBALS['hook_values']+array(
|
|
'location' => 'addaccount',
|
|
// at login-time only the hooks from the following apps will be called
|
|
'order' => array('felamimail','fudforum'),
|
|
),False,True); // called for every app now, not only enabled ones
|
|
} /* end account setup */
|
|
else /* if no account id abort the account creation */
|
|
{
|
|
$this->db->transaction_abort();
|
|
}
|
|
|
|
/*
|
|
* If we succeeded in creating the account (above), return the accountid, else,
|
|
* return the error value from $this->name2id($accountname)
|
|
*/
|
|
return $accountid;
|
|
} /* end auto_add() */
|
|
|
|
function get_account_name($account_id,&$lid,&$fname,&$lname)
|
|
{
|
|
$acct_type = $this->get_type($account_id);
|
|
|
|
/* search the dn for the given uid */
|
|
if(($acct_type == 'g') && $this->group_context)
|
|
{
|
|
$sri = ldap_search($this->ds, $this->group_context, 'gidnumber=' . abs((int)$account_id));
|
|
}
|
|
else
|
|
{
|
|
$sri = ldap_search($this->ds, $this->user_context, 'uidnumber=' . (int)$account_id);
|
|
}
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
if($acct_type =='g')
|
|
{
|
|
$lid = $GLOBALS['egw']->translation->convert($allValues[0]['cn'][0],'utf-8');
|
|
$fname = $GLOBALS['egw']->translation->convert($allValues[0]['cn'][0],'utf-8');
|
|
$lname = lang('Group');
|
|
}
|
|
else
|
|
{
|
|
$lid = $GLOBALS['egw']->translation->convert($allValues[0]['uid'][0],'utf-8');
|
|
$fname = $GLOBALS['egw']->translation->convert($allValues[0]['givenname'][0],'utf-8');
|
|
$lname = $GLOBALS['egw']->translation->convert($allValues[0]['sn'][0],'utf-8');
|
|
}
|
|
return !empty($lid);
|
|
}
|
|
|
|
function getDNforID($_accountid = '')
|
|
{
|
|
$_account_id = get_account_id($_accountid);
|
|
|
|
$sri = ldap_search($this->ds, $this->user_context, 'uidnumber=' . (int)$_account_id);
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
return $allValues[0]['dn'];
|
|
}
|
|
|
|
/**
|
|
* Update the last login timestamps and the IP
|
|
*
|
|
* @param int $account_id
|
|
* @param string $ip
|
|
* @return int lastlogin time
|
|
*/
|
|
function update_lastlogin($_account_id, $ip)
|
|
{
|
|
$entry['phpgwaccountlastlogin'] = time();
|
|
$entry['phpgwaccountlastloginfrom'] = $ip;
|
|
|
|
$sri = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_context'], 'uidnumber=' . (int)$_account_id);
|
|
$allValues = ldap_get_entries($this->ds, $sri);
|
|
|
|
$dn = $allValues[0]['dn'];
|
|
@ldap_modify($this->ds, $dn, $entry);
|
|
|
|
return $allValues[0]['phpgwaccountlastlogin'][0];
|
|
}
|
|
}
|