mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-23 00:13:35 +01:00
* API/Addressbook/EMailAdmin: full support for active directory as account storage, tested with Samba4 and win2008r2
Trunk commits r42507, r42545, r42556, r42557, r42612, r42630 plugin to support Active Directory to store email configuration (in proxyAddresses attribute, no Exchange schema and support!), also fully autodetecting plugins now in emailadmin/inc directory
This commit is contained in:
commit
3e40eaf0cb
203
addressbook/inc/class.addressbook_ads.inc.php
Normal file
203
addressbook/inc/class.addressbook_ads.inc.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Addressbook - ADS Backend
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <rb@stylite.de>
|
||||
* @package addressbook
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Active directory backend for accounts (not yet AD contacts)
|
||||
*
|
||||
* We use ADS string representation of objectGUID as contact ID and UID.
|
||||
*
|
||||
* Unfortunatly Samba4 and active directory of win2008r2 differn on how to search for an objectGUID:
|
||||
* - Samba4 can only search for string representation eg. (objectGUID=2336A3FC-EDBD-42A2-9EEB-BD7A5DD2804E)
|
||||
* - win2008r2 can only search for hex representation eg. (objectGUID=\FC\A3\36\23\BD\ED\A2\42\9E\EB\BD\7A\5D\D2\80\4E)
|
||||
* We could use both filters or-ed together, for now we detect Samba4 and use string GUID for it.
|
||||
*
|
||||
* All values used to construct filters need to run through ldap::quote(),
|
||||
* to be save against LDAP query injection!!!
|
||||
*/
|
||||
class addressbook_ads extends addressbook_ldap
|
||||
{
|
||||
/**
|
||||
* LDAP searches only a limited set of attributes for performance reasons,
|
||||
* you NEED an index for that columns, ToDo: make it configurable
|
||||
* minimum: $this->columns_to_search = array('n_family','n_given','org_name','email');
|
||||
*/
|
||||
var $search_attributes = array(
|
||||
'n_family','n_middle','n_given','org_name','org_unit',
|
||||
'adr_one_location','note','email','samaccountname',
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter used for accounts addressbook
|
||||
* @var string
|
||||
*/
|
||||
var $accountsFilter = '(objectclass=user)';
|
||||
|
||||
/**
|
||||
* Attribute used for DN
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $dn_attribute='cn';
|
||||
|
||||
/**
|
||||
* Accounts ADS object
|
||||
*
|
||||
* @var accounts_ads
|
||||
*/
|
||||
protected $accounts_ads;
|
||||
|
||||
/**
|
||||
* ADS is Samba4 (true), otherwise false
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $is_samba4 = false;
|
||||
|
||||
|
||||
/**
|
||||
* 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'];
|
||||
|
||||
if ($ldap_config)
|
||||
{
|
||||
$this->ldap_config = $ldap_config;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ldap_config =& $GLOBALS['egw_info']['server'];
|
||||
}
|
||||
|
||||
$this->accounts_ads = $GLOBALS['egw']->accounts->backend;
|
||||
//$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->allContactsDN = $this->accountContactsDN = $this->accounts_ads->ads_context();
|
||||
|
||||
if ($ds)
|
||||
{
|
||||
$this->ds = $ds;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connect();
|
||||
}
|
||||
$this->ldapServerInfo = ldapserverinfo::get($this->ds, $this->ldap_config['ads_host']);
|
||||
$this->is_samba4 = $this->ldapServerInfo->serverType == SAMBA4_LDAPSERVER;
|
||||
|
||||
// AD seems to use user, instead of inetOrgPerson
|
||||
$this->schema2egw['user'] = $this->schema2egw['inetorgperson'];
|
||||
$this->schema2egw['user'] += array(
|
||||
'account_id' => 'objectsid',
|
||||
'account_lid' => 'samaccountname',
|
||||
'contact_uid' => 'objectguid',
|
||||
);
|
||||
|
||||
foreach($this->schema2egw as $schema => $attributes)
|
||||
{
|
||||
$this->all_attributes = array_merge($this->all_attributes,array_values($attributes));
|
||||
}
|
||||
$this->all_attributes = array_values(array_unique($this->all_attributes));
|
||||
|
||||
$this->charset = translation::charset();
|
||||
}
|
||||
|
||||
/**
|
||||
* connect to LDAP server
|
||||
*
|
||||
* @param boolean $admin=false true (re-)connect with admin not user credentials, eg. to modify accounts
|
||||
*/
|
||||
function connect($admin=false)
|
||||
{
|
||||
$this->ds = $this->accounts_ads->ldap_connection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LDAP filter for contact id
|
||||
*
|
||||
* @param string $contact_id
|
||||
* @return string
|
||||
*/
|
||||
protected function id_filter($contact_id)
|
||||
{
|
||||
// check that GUID eg. from URL contains only valid hex characters and dash
|
||||
// we cant use ldap::quote() for win2008r2 hex GUID, as it contains backslashes
|
||||
if (!preg_match('/^[0-9A-Fa-f-]+/', $contact_id))
|
||||
{
|
||||
throw new egw_exception_assertion_failed("'$contact_id' is NOT a valid GUID!");
|
||||
}
|
||||
|
||||
// samba4 can only search by string representation of objectGUID, while win2008r2 requires hex representation
|
||||
return '(objectguid='.($this->is_samba4 ? $contact_id : $this->accounts_ads->objectguid2hex($contact_id)).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* reads contact data
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
if (is_array($contact_id) && isset($contact_id['account_id']) ||
|
||||
!is_array($contact_id) && substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
$account_id = (int)(is_array($contact_id) ? $contact_id['account_id'] : substr($contact_id,8));
|
||||
$contact_id = $GLOBALS['egw']->accounts->id2name($account_id, 'person_id');
|
||||
}
|
||||
$contact_id = !is_array($contact_id) ? $contact_id :
|
||||
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']);
|
||||
|
||||
$rows = $this->_searchLDAP($this->allContactsDN, $filter=$this->id_filter($contact_id), $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
//error_log(__METHOD__."('$contact_id') _searchLDAP($this->allContactsDN, '$filter',...)=".array2string($rows));
|
||||
return $rows ? $rows[0] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for mapping data of ADA user objectclass to eGW contact
|
||||
*
|
||||
* Please note: all regular fields are already copied!
|
||||
*
|
||||
* @internal
|
||||
* @param array &$contact already copied fields according to the mapping
|
||||
* @param array $data eGW contact data
|
||||
*/
|
||||
function _user2egw(&$contact, $data)
|
||||
{
|
||||
$contact['account_id'] = $this->accounts_ads->objectsid2account_id($data['objectsid']);
|
||||
$contact['id'] = $contact['contact_uid'] = $this->accounts_ads->objectguid2str($data['objectguid']);
|
||||
|
||||
// ignore system accounts
|
||||
if ($contact['account_id'] < accounts_ads::MIN_ACCOUNT_ID) return false;
|
||||
|
||||
$this->_inetorgperson2egw($contact, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove attributes we are not allowed to update
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
function sanitize_update(array &$ldapContact)
|
||||
{
|
||||
// not allowed and not need to update these in AD
|
||||
unset($ldapContact['objectguid']);
|
||||
unset($ldapContact['objectsid']);
|
||||
|
||||
parent::sanitize_update($ldapContact);
|
||||
}
|
||||
|
||||
}
|
@ -59,6 +59,29 @@ class addressbook_ldap
|
||||
*/
|
||||
var $sharedContactsDN;
|
||||
|
||||
/**
|
||||
* @var string $accountContactsDN holds the base DN for accounts addressbook
|
||||
*/
|
||||
var $accountContactsDN;
|
||||
|
||||
/**
|
||||
* Filter used for accounts addressbook
|
||||
* @var string
|
||||
*/
|
||||
var $accountsFilter = '(objectclass=posixaccount)';
|
||||
|
||||
/**
|
||||
* @var string $allContactsDN holds the base DN of all addressbook
|
||||
*/
|
||||
var $allContactsDN;
|
||||
|
||||
/**
|
||||
* Attribute used for DN
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $dn_attribute='uid';
|
||||
|
||||
/**
|
||||
* @var int $total holds the total count of found rows
|
||||
*/
|
||||
@ -71,6 +94,17 @@ class addressbook_ldap
|
||||
*/
|
||||
var $charset;
|
||||
|
||||
/**
|
||||
* LDAP searches only a limited set of attributes for performance reasons,
|
||||
* you NEED an index for that columns, ToDo: make it configurable
|
||||
* minimum: $this->columns_to_search = array('n_family','n_given','org_name','email');
|
||||
*/
|
||||
var $search_attributes = array(
|
||||
'n_family','n_middle','n_given','org_name','org_unit',
|
||||
'adr_one_location','adr_two_location','note',
|
||||
'email','mozillasecondemail','uidnumber',
|
||||
);
|
||||
|
||||
/**
|
||||
* maps between diverse ldap schema and the eGW internal names
|
||||
*
|
||||
@ -82,6 +116,7 @@ class addressbook_ldap
|
||||
'posixaccount' => array(
|
||||
'account_id' => 'uidnumber',
|
||||
'account_lid' => 'uid',
|
||||
'shadowexpire',
|
||||
),
|
||||
'inetorgperson' => array(
|
||||
'n_fn' => 'cn',
|
||||
@ -209,6 +244,13 @@ class addressbook_ldap
|
||||
*/
|
||||
private $ldap_config;
|
||||
|
||||
/**
|
||||
* LDAP connection
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
var $ds;
|
||||
|
||||
/**
|
||||
* constructor of the class
|
||||
*
|
||||
@ -228,8 +270,10 @@ class addressbook_ldap
|
||||
{
|
||||
$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->accountContactsDN = $this->ldap_config['ldap_context'];
|
||||
$this->allContactsDN = $this->ldap_config['ldap_contact_context'];
|
||||
$this->personalContactsDN = 'ou=personal,ou=contacts,'. $this->allContactsDN;
|
||||
$this->sharedContactsDN = 'ou=shared,ou=contacts,'. $this->allContactsDN;
|
||||
|
||||
if ($ds)
|
||||
{
|
||||
@ -260,14 +304,20 @@ class addressbook_ldap
|
||||
|
||||
/**
|
||||
* connect to LDAP server
|
||||
*
|
||||
* @param boolean $admin=false true (re-)connect with admin not user credentials, eg. to modify accounts
|
||||
*/
|
||||
function connect()
|
||||
function connect($admin = false)
|
||||
{
|
||||
if ($admin)
|
||||
{
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
}
|
||||
// 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)
|
||||
elseif (substr($GLOBALS['egw_info']['server']['contact_repository'],-4) != 'ldap') // not (ldap or sql-ldap)
|
||||
{
|
||||
$this->ldap_config['ldap_contact_host'] = $this->ldap_config['ldap_host'];
|
||||
$this->ldap_config['ldap_contact_context'] = $this->ldap_config['ldap_context'];
|
||||
$this->allContactsDN = $this->ldap_config['ldap_context'];
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
}
|
||||
else
|
||||
@ -304,6 +354,37 @@ class addressbook_ldap
|
||||
return array_values(array_unique($fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LDAP filter for contact id
|
||||
*
|
||||
* @param string $id
|
||||
* @return string
|
||||
*/
|
||||
protected function id_filter($id)
|
||||
{
|
||||
return '(|(entryUUID='.ldap::quote($id).')(uid='.ldap::quote($id).'))';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LDAP filter for (multiple) contact ids
|
||||
*
|
||||
* @param array|string $ids
|
||||
* @return string
|
||||
*/
|
||||
protected function ids_filter($ids)
|
||||
{
|
||||
if (!is_array($ids) || count($ids) == 1)
|
||||
{
|
||||
return $this->id_filter(is_array($ids) ? array_shift($ids) : $ids);
|
||||
}
|
||||
$filter = array();
|
||||
foreach($ids as $id)
|
||||
{
|
||||
$filter[] = $this->id_filter($id);
|
||||
}
|
||||
return '(|'.implode('', $filter).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* reads contact data
|
||||
*
|
||||
@ -319,16 +400,30 @@ class addressbook_ldap
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact_id = ldap::quote(!is_array($contact_id) ? $contact_id :
|
||||
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']));
|
||||
$filter = "(|(entryUUID=$contact_id)(uid=$contact_id))";
|
||||
if (is_array($contact_id)) $contact_id = isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid'];
|
||||
$filter = $this->id_filter($contact_id);
|
||||
}
|
||||
$rows = $this->_searchLDAP($this->ldap_config['ldap_contact_context'],
|
||||
$rows = $this->_searchLDAP($this->allContactsDN,
|
||||
$filter, $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
|
||||
return $rows ? $rows[0] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove attributes we are not allowed to update
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
function sanitize_update(array &$ldapContact)
|
||||
{
|
||||
// never allow to change the uidNumber (account_id) on update, as it could be misused by eg. xmlrpc or syncml
|
||||
unset($ldapContact['uidnumber']);
|
||||
|
||||
unset($ldapContact['entryuuid']); // not allowed to modify that, no need either
|
||||
|
||||
unset($ldapContact['objectClass']);
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the content of data to the db
|
||||
*
|
||||
@ -364,10 +459,10 @@ class addressbook_ldap
|
||||
$data['account_id'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
// account
|
||||
$baseDN = $this->ldap_config['ldap_context'];
|
||||
$baseDN = $this->accountContactsDN;
|
||||
$cn = false;
|
||||
// we need an admin connection
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
$this->connect(true);
|
||||
|
||||
// for sql-ldap we need to account_lid/uid as id, NOT the contact_id in id!
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'] == 'sql-ldap')
|
||||
@ -380,7 +475,6 @@ class addressbook_ldap
|
||||
error_log("Permission denied, to write: data[owner]=$data[owner], data[account_id]=$data[account_id], account_id=".$GLOBALS['egw_info']['user']['account_id']);
|
||||
return lang('Permission denied !!!'); // only admin or the user itself is allowd to write accounts!
|
||||
}
|
||||
|
||||
// check if $baseDN exists. If not create it
|
||||
if (($err = $this->_check_create_dn($baseDN)))
|
||||
{
|
||||
@ -388,11 +482,11 @@ class addressbook_ldap
|
||||
}
|
||||
// check the existing objectclasses of an entry, none = array() for new ones
|
||||
$oldObjectclasses = array();
|
||||
$attributes = array('dn','cn','objectClass','uid','mail');
|
||||
$attributes = array('dn','cn','objectClass',$this->dn_attribute,'mail');
|
||||
|
||||
$contactUID = $this->data[$this->contacts_id];
|
||||
if(!empty($contactUID) &&
|
||||
($result = ldap_search($this->ds, $this->ldap_config['ldap_contact_context'],
|
||||
'(|(entryUUID='.ldap::quote($contactUID).')(uid='.ldap::quote($contactUID).'))', $attributes)) &&
|
||||
if (!empty($contactUID) &&
|
||||
($result = ldap_search($this->ds, $base=$this->allContactsDN, $filter=$this->id_filter($contactUID), $attributes)) &&
|
||||
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
|
||||
{
|
||||
unset($oldContactInfo[0]['objectclass']['count']);
|
||||
@ -402,13 +496,12 @@ class addressbook_ldap
|
||||
}
|
||||
$isUpdate = true;
|
||||
}
|
||||
if(!$contactUID)
|
||||
|
||||
if(empty($contactUID))
|
||||
{
|
||||
$this->data[$this->contacts_id] = $contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
||||
$ldapContact[$this->contacts_id] = $this->data[$this->contacts_id] = $contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
||||
}
|
||||
|
||||
$ldapContact['uid'] = $contactUID;
|
||||
|
||||
//error_log(__METHOD__."() contactUID='$contactUID', isUpdate=".array2string($isUpdate).", oldContactInfo=".array2string($oldContactInfo));
|
||||
// add for all supported objectclasses the objectclass and it's attributes
|
||||
foreach($this->schema2egw as $objectclass => $mapping)
|
||||
{
|
||||
@ -448,7 +541,7 @@ class addressbook_ldap
|
||||
$this->$egw2objectclass($ldapContact,$data,$isUpdate);
|
||||
}
|
||||
}
|
||||
if($isUpdate)
|
||||
if ($isUpdate)
|
||||
{
|
||||
// make sure multiple email-addresses in the mail attribute "survive"
|
||||
if (isset($ldapContact['mail']) && $oldContactInfo[0]['mail']['count'] > 1)
|
||||
@ -461,9 +554,6 @@ class addressbook_ldap
|
||||
// update entry
|
||||
$dn = $oldContactInfo[0]['dn'];
|
||||
$needRecreation = false;
|
||||
// never allow to change the uidNumber (account_id) on update, as it could be misused by eg. xmlrpc or syncml
|
||||
unset($ldapContact['uidnumber']);
|
||||
unset($ldapContact['entryuuid']); // not allowed to modify that, no need either
|
||||
|
||||
// add missing objectclasses
|
||||
if($ldapContact['objectClass'] && array_diff($ldapContact['objectClass'],$oldObjectclasses))
|
||||
@ -486,9 +576,9 @@ class addressbook_ldap
|
||||
}
|
||||
|
||||
// check if we need to rename the DN or need to recreate the contact
|
||||
$newRDN = 'uid='. ldap::quote($contactUID);
|
||||
$newRDN = $this->dn_attribute.'='. ldap::quote($ldapContact[$this->dn_attribute]);
|
||||
$newDN = $newRDN .','. $baseDN;
|
||||
if(strtolower($dn) != strtolower($newDN) || $needRecreation)
|
||||
if ($needRecreation)
|
||||
{
|
||||
$result = ldap_read($this->ds, $dn, 'objectclass=*');
|
||||
$oldContact = ldap_get_entries($this->ds, $result);
|
||||
@ -500,7 +590,7 @@ class addressbook_ldap
|
||||
$newContact[$key] = $value;
|
||||
}
|
||||
}
|
||||
$newContact['uid'] = $contactUID;
|
||||
$newContact[$this->dn_attribute] = $ldapContact[$this->dn_attribute];
|
||||
|
||||
if(is_array($ldapContact['objectClass']) && count($ldapContact['objectClass']) > 0)
|
||||
{
|
||||
@ -523,7 +613,21 @@ class addressbook_ldap
|
||||
}
|
||||
$dn = $newDN;
|
||||
}
|
||||
unset($ldapContact['objectClass']);
|
||||
// try renaming entry if content of dn-attribute changed
|
||||
if (strtolower($dn) != strtolower($newDN) || $ldapContact[$this->dn_attribute] != $oldContactInfo[$this->dn_attribute])
|
||||
{
|
||||
if (@ldap_rename($this->ds, $dn, $newRDN, null, true))
|
||||
{
|
||||
$dn = $newDN;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log(__METHOD__."() ldap_rename or $dn to $newRDN failed! ".ldap_error($this->ds));
|
||||
}
|
||||
}
|
||||
unset($ldapContact[$this->dn_attribute]);
|
||||
|
||||
$this->sanitize_update($ldapContact);
|
||||
|
||||
if (!@ldap_modify($this->ds, $dn, $ldapContact))
|
||||
{
|
||||
@ -535,7 +639,7 @@ class addressbook_ldap
|
||||
}
|
||||
else
|
||||
{
|
||||
$dn = 'uid='. ldap::quote($ldapContact['uid']) .','. $baseDN;
|
||||
$dn = $this->dn_attribute.'='. ldap::quote($ldapContact[$this->dn_attribute]) .','. $baseDN;
|
||||
unset($ldapContact['entryuuid']); // trying to write it, gives an error
|
||||
|
||||
if (!@ldap_add($this->ds, $dn, $ldapContact))
|
||||
@ -572,7 +676,7 @@ class addressbook_ldap
|
||||
foreach($keys as $entry)
|
||||
{
|
||||
$entry = ldap::quote(is_array($entry) ? $entry['id'] : $entry);
|
||||
if($result = ldap_search($this->ds, $this->ldap_config['ldap_contact_context'],
|
||||
if($result = ldap_search($this->ds, $this->allContactsDN,
|
||||
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
|
||||
{
|
||||
$contactInfo = ldap_get_entries($this->ds, $result);
|
||||
@ -606,7 +710,6 @@ class addressbook_ldap
|
||||
*/
|
||||
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)
|
||||
{
|
||||
//_debug_array($criteria); print "OrderBY: $order_by";_debug_array($extra_cols);_debug_array($filter);
|
||||
#$order_by = explode(',',$order_by);
|
||||
#$order_by = explode(' ',$order_by);
|
||||
#$sort = $order_by[0];
|
||||
@ -635,20 +738,19 @@ class addressbook_ldap
|
||||
}
|
||||
elseif (!isset($filter['owner']))
|
||||
{
|
||||
$searchDN = $this->ldap_config['ldap_contact_context'];
|
||||
$searchDN = $this->allContactsDN;
|
||||
$addressbookType = ADDRESSBOOK_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchDN = $this->ldap_config['ldap_context'];
|
||||
$searchDN = $this->accountContactsDN;
|
||||
$addressbookType = ADDRESSBOOK_ACCOUNTS;
|
||||
}
|
||||
|
||||
// create the search filter
|
||||
switch($addressbookType)
|
||||
{
|
||||
case ADDRESSBOOK_ACCOUNTS:
|
||||
$objectFilter = '(objectclass=posixaccount)';
|
||||
$objectFilter = $this->accountsFilter;
|
||||
break;
|
||||
default:
|
||||
$objectFilter = '(objectclass=inetorgperson)';
|
||||
@ -666,6 +768,11 @@ class addressbook_ldap
|
||||
$searchFilter = '';
|
||||
foreach($criteria as $egwSearchKey => $searchValue)
|
||||
{
|
||||
if (in_array($egwSearchKey, array('id','contact_id')))
|
||||
{
|
||||
$searchFilter .= $this->ids_filter($searchValue);
|
||||
continue;
|
||||
}
|
||||
foreach($this->schema2egw as $mapping)
|
||||
{
|
||||
if(($ldapSearchKey = $mapping[$egwSearchKey]))
|
||||
@ -687,7 +794,6 @@ class addressbook_ldap
|
||||
}
|
||||
$colFilter = $this->_colFilter($filter);
|
||||
$ldapFilter = "(&$objectFilter$searchFilter$colFilter)";
|
||||
|
||||
if (!($rows = $this->_searchLDAP($searchDN, $ldapFilter, $this->all_attributes, $addressbookType)))
|
||||
{
|
||||
return $rows;
|
||||
@ -788,6 +894,11 @@ class addressbook_ldap
|
||||
}
|
||||
break;
|
||||
|
||||
case 'id':
|
||||
case 'contact_id':
|
||||
$filter .= $this->ids_filter($value);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!is_int($key))
|
||||
{
|
||||
@ -840,16 +951,14 @@ class addressbook_ldap
|
||||
$this->total = 0;
|
||||
|
||||
$_attributes[] = 'entryUUID';
|
||||
$_attributes[] = 'uid';
|
||||
$_attributes[] = 'uidNumber';
|
||||
$_attributes[] = 'objectClass';
|
||||
$_attributes[] = 'createTimestamp';
|
||||
$_attributes[] = 'modifyTimestamp';
|
||||
$_attributes[] = 'creatorsName';
|
||||
$_attributes[] = 'modifiersName';
|
||||
$_attributes[] = 'shadowExpire';
|
||||
|
||||
//echo "<p>ldap_search($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit)</p>\n";
|
||||
//echo "<p>ldap_search($this->ds, '$_ldapContext', '$_filter', ".array2string($_attributes).", 0, $this->ldapLimit)</p>\n";
|
||||
|
||||
if($_addressbooktype == ADDRESSBOOK_ALL)
|
||||
{
|
||||
$result = ldap_search($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
||||
@ -858,22 +967,13 @@ class addressbook_ldap
|
||||
{
|
||||
$result = @ldap_list($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
||||
}
|
||||
if(!$result) return array();
|
||||
|
||||
$entries = ldap_get_entries($this->ds, $result);
|
||||
if(!$result || !$entries = ldap_get_entries($this->ds, $result)) return array();
|
||||
|
||||
$this->total = $entries['count'];
|
||||
$shadowExpireNow = floor((time()-date('Z'))/86400);
|
||||
foreach((array)$entries as $i => $entry)
|
||||
foreach($entries as $i => $entry)
|
||||
{
|
||||
if (!is_int($i)) continue; // eg. count
|
||||
|
||||
// exclude expired or deactivated accounts
|
||||
if (isset($entry['shadowexpire']) && $entry['shadowexpire'][0] <= $shadowExpireNow)
|
||||
{
|
||||
--$this->total;
|
||||
continue;
|
||||
}
|
||||
$contact = array(
|
||||
'id' => $entry['uid'][0] ? $entry['uid'][0] : $entry['entryuuid'][0],
|
||||
'tid' => 'n', // the type id for the addressbook
|
||||
@ -887,7 +987,7 @@ class addressbook_ldap
|
||||
}
|
||||
foreach($this->schema2egw[$objectclass] as $egwFieldName => $ldapFieldName)
|
||||
{
|
||||
if(!empty($entry[$ldapFieldName][0]) && !isset($contact[$egwFieldName]))
|
||||
if(!empty($entry[$ldapFieldName][0]) && !is_int($egwFieldName) && !isset($contact[$egwFieldName]))
|
||||
{
|
||||
$contact[$egwFieldName] = translation::convert($entry[$ldapFieldName][0],'utf-8');
|
||||
}
|
||||
@ -895,7 +995,11 @@ class addressbook_ldap
|
||||
$objectclass2egw = '_'.$objectclass.'2egw';
|
||||
if (method_exists($this,$objectclass2egw))
|
||||
{
|
||||
$this->$objectclass2egw($contact,$entry);
|
||||
if (($ret=$this->$objectclass2egw($contact,$entry)) === false)
|
||||
{
|
||||
--$this->total;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// read binary jpegphoto only for one result == call by read
|
||||
@ -966,7 +1070,7 @@ class addressbook_ldap
|
||||
/**
|
||||
* check if $baseDN exists. If not create it
|
||||
*
|
||||
* @param string $baseDN cn=xxx,ou=yyy,ou=contacts,$this->ldap_config['ldap_contact_context']
|
||||
* @param string $baseDN cn=xxx,ou=yyy,ou=contacts,$this->allContactsDN
|
||||
* @return boolean/string false on success or string with error-message
|
||||
*/
|
||||
function _check_create_dn($baseDN)
|
||||
@ -976,8 +1080,10 @@ class addressbook_ldap
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//error_log(__METHOD__."('$baseDN') !ldap_read({$this->ds}, '$baseDN', 'objectclass=*') ldap_errno()=".ldap_errno($this->ds).', ldap_error()='.ldap_error($this->ds).get_class($this));
|
||||
if(ldap_errno($this->ds) != 32 || substr($baseDN,0,3) != 'cn=')
|
||||
{
|
||||
error_log(__METHOD__."('$baseDN') baseDN does NOT exist and we cant/wont create it! ldap_errno()=".ldap_errno($this->ds).', ldap_error()='.ldap_error($this->ds));
|
||||
return $this->_error(__LINE__); // baseDN does NOT exist and we cant/wont create it
|
||||
}
|
||||
// create a admin connection to add the needed DN
|
||||
@ -986,8 +1092,8 @@ class addressbook_ldap
|
||||
|
||||
list(,$ou) = explode(',',$baseDN);
|
||||
foreach(array(
|
||||
'ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||
$ou.',ou=contacts,'.$this->ldap_config['ldap_contact_context'],
|
||||
'ou=contacts,'.$this->allContactsDN,
|
||||
$ou.',ou=contacts,'.$this->allContactsDN,
|
||||
$baseDN,
|
||||
) as $dn)
|
||||
{
|
||||
@ -1129,6 +1235,27 @@ class addressbook_ldap
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for mapping data of posixAccount objectclass to eGW contact
|
||||
*
|
||||
* Please note: all regular fields are already copied!
|
||||
*
|
||||
* @internal
|
||||
* @param array &$contact already copied fields according to the mapping
|
||||
* @param array $data eGW contact data
|
||||
*/
|
||||
function _posixaccount2egw(&$contact,$data)
|
||||
{
|
||||
static $shadowExpireNow;
|
||||
if (!isset($shadowExpireNow)) $shadowExpireNow = floor((time()-date('Z'))/86400);
|
||||
|
||||
// exclude expired or deactivated accounts
|
||||
if (isset($data['shadowexpire']) && $data['shadowexpire'][0] <= $shadowExpireNow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for mapping data of the mozillaAbPersonAlpha objectclass to eGW contact
|
||||
*
|
||||
|
@ -114,16 +114,6 @@ class addressbook_so
|
||||
*/
|
||||
var $memberships;
|
||||
|
||||
/**
|
||||
* LDAP searches only a limited set of attributes for performance reasons,
|
||||
* you NEED an index for that columns, ToDo: make it configurable
|
||||
* minimum: $this->columns_to_search = array('n_family','n_given','org_name','email');
|
||||
*/
|
||||
var $ldap_search_attributes = array(
|
||||
'n_family','n_middle','n_given','org_name','org_unit',
|
||||
'adr_one_location','adr_two_location','note',
|
||||
'email','mozillasecondemail','uidnumber',
|
||||
);
|
||||
/**
|
||||
* In SQL we can search all columns, though a view make on real sense
|
||||
*/
|
||||
@ -232,8 +222,7 @@ class addressbook_so
|
||||
{
|
||||
$this->contact_repository = 'ldap';
|
||||
$this->somain = new addressbook_ldap();
|
||||
|
||||
$this->columns_to_search = $this->ldap_search_attributes;
|
||||
$this->columns_to_search = $this->somain->search_attributes;
|
||||
}
|
||||
else // sql or sql->ldap
|
||||
{
|
||||
@ -250,12 +239,13 @@ class addressbook_so
|
||||
{
|
||||
$this->grants = $this->get_grants($this->user,$contact_app);
|
||||
}
|
||||
if ($this->account_repository == 'ldap' && $this->contact_repository == 'sql')
|
||||
if ($this->account_repository != 'sql' && $this->contact_repository == 'sql')
|
||||
{
|
||||
if ($this->account_repository != $this->contact_repository)
|
||||
{
|
||||
$this->so_accounts = new addressbook_ldap();
|
||||
$this->account_cols_to_search = $this->ldap_search_attributes;
|
||||
$class = 'addressbook_'.$this->account_repository;
|
||||
$this->so_accounts = new $class();
|
||||
$this->account_cols_to_search = $this->so_accounts->search_attributes;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
271
emailadmin/doc/qmail.new.schema
Normal file
271
emailadmin/doc/qmail.new.schema
Normal file
@ -0,0 +1,271 @@
|
||||
#
|
||||
# qmail-ldap (20030901) ldapv3 directory schema
|
||||
#
|
||||
# The offical qmail-ldap OID assigned by IANA is 7914
|
||||
#
|
||||
# Created by: David E. Storey <dave@tamos.net>
|
||||
# Modified and included into qmail-ldap by Andre Oppermann <opi@nrg4u.com>
|
||||
# Schema fixes by Mike Jackson <mjj@pp.fi>
|
||||
# Schema fixes by Christian Zoffoli (XMerlin) <czoffoli@xmerlin.org>
|
||||
#
|
||||
#
|
||||
# This schema depends on:
|
||||
# - core.schema
|
||||
# - cosine.schema
|
||||
# - nis.schema
|
||||
#
|
||||
|
||||
# Attribute Type Definitions
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'qmailUID'
|
||||
DESC 'UID of the user on the mailsystem'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.2 NAME 'qmailGID'
|
||||
DESC 'GID of the user on the mailsystem'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'mailMessageStore'
|
||||
DESC 'Path to the maildir/mbox on the mail system'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailAlternateAddress'
|
||||
DESC 'Secondary (alias) mailaddresses for the same user'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
#
|
||||
# mailQuota format is no longer supported from qmail-ldap 20030901 on,
|
||||
# user mailQuotaSize and mailQuotaCount instead.
|
||||
#
|
||||
#attributetype ( 1.3.6.1.4.1.7914.1.2.1.5 NAME 'mailQuota'
|
||||
# DESC 'The amount of space the user can use until all further messages get bounced.'
|
||||
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
|
||||
#
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'mailHost'
|
||||
DESC 'On which qmail server the messagestore of this user is located.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE)
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.7 NAME 'mailForwardingAddress'
|
||||
DESC 'Address(es) to forward all incoming messages to.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.8 NAME 'deliveryProgramPath'
|
||||
DESC 'Program to execute for all incoming mails.'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.9 NAME 'qmailDotMode'
|
||||
DESC 'Interpretation of .qmail files: both, dotonly, ldaponly, ldapwithprog'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.10 NAME 'deliveryMode'
|
||||
DESC 'multi field entries of: nolocal, noforward, noprogram, reply'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.11 NAME 'mailReplyText'
|
||||
DESC 'A reply text for every incoming message'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.12 NAME 'accountStatus'
|
||||
DESC 'The status of a user account: active, noaccess, disabled, deleted'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.14 NAME 'qmailAccountPurge'
|
||||
DESC 'The earliest date when a mailMessageStore will be purged'
|
||||
EQUALITY numericStringMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.15 NAME 'mailQuotaSize'
|
||||
DESC 'The size of space the user can have until further messages get bounced.'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.16 NAME 'mailQuotaCount'
|
||||
DESC 'The number of messages the user can have until further messages get bounced.'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.2.1.17 NAME 'mailSizeMax'
|
||||
DESC 'The maximum size of a single messages the user accepts.'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
#
|
||||
# qmailGroup attributes
|
||||
#
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.1 NAME 'dnmember'
|
||||
DESC 'Group member specified as distinguished name.'
|
||||
EQUALITY distinguishedNameMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.2 NAME 'rfc822member'
|
||||
DESC 'Group member specified as normal rf822 email address.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.3 NAME 'filtermember'
|
||||
DESC 'Group member specified as ldap search filter.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.4 NAME 'senderconfirm'
|
||||
DESC 'Sender to Group has to answer confirmation email.'
|
||||
EQUALITY booleanMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.5 NAME 'membersonly'
|
||||
DESC 'Sender to Group must be group member itself.'
|
||||
EQUALITY booleanMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.6 NAME 'confirmtext'
|
||||
DESC 'Text that will be sent with sender confirmation email.'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.7 NAME 'dnmoderator'
|
||||
DESC 'Group moderator specified as Distinguished name.'
|
||||
EQUALITY distinguishedNameMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.8 NAME 'rfc822moderator'
|
||||
DESC 'Group moderator specified as normal rfc822 email address.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.9 NAME 'moderatortext'
|
||||
DESC 'Text that will be sent with request for moderation email.'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.10 NAME 'dnsender'
|
||||
DESC 'Allowed sender specified as distinguished name.'
|
||||
EQUALITY distinguishedNameMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.11 NAME 'rfc822sender'
|
||||
DESC 'Allowed sender specified as normal rf822 email address.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.3.1.12 NAME 'filtersender'
|
||||
DESC 'Allowed sender specified as ldap search filter.'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
|
||||
|
||||
|
||||
#
|
||||
# qldapAdmin Attributes
|
||||
#
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.1 NAME 'qladnmanager'
|
||||
DESC ''
|
||||
EQUALITY distinguishedNameMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.2 NAME 'qlaDomainList'
|
||||
DESC ''
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.3 NAME 'qlaUidPrefix'
|
||||
DESC ''
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.4 NAME 'qlaQmailUid'
|
||||
DESC ''
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.5 NAME 'qlaQmailGid'
|
||||
DESC ''
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.6 NAME 'qlaMailMStorePrefix'
|
||||
DESC ''
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.7 NAME 'qlaMailQuotaSize'
|
||||
DESC ''
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.8 NAME 'qlaMailQuotaCount'
|
||||
DESC ''
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.9 NAME 'qlaMailSizeMax'
|
||||
DESC ''
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7914.1.4.1.10 NAME 'qlaMailHostList'
|
||||
DESC ''
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
|
||||
|
||||
|
||||
# Object Class Definitions
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'qmailUser'
|
||||
DESC 'QMail-LDAP User'
|
||||
SUP top
|
||||
AUXILIARY
|
||||
MUST ( mail )
|
||||
MAY ( uid $ mailMessageStore $ homeDirectory $ userPassword $
|
||||
mailAlternateAddress $ qmailUID $ qmailGID $
|
||||
mailHost $ mailForwardingAddress $ deliveryProgramPath $
|
||||
qmailDotMode $ deliveryMode $ mailReplyText $
|
||||
accountStatus $ qmailAccountPurge $
|
||||
mailQuotaSize $ mailQuotaCount $ mailSizeMax ) )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7914.1.3.2.1 NAME 'qmailGroup'
|
||||
DESC 'QMail-LDAP Group'
|
||||
SUP top
|
||||
AUXILIARY
|
||||
MUST ( mail $ mailAlternateAddress $ mailMessageStore )
|
||||
MAY ( dnmember $ rfc822member $ filtermember $ senderconfirm $
|
||||
membersonly $ confirmtext $ dnmoderator $ rfc822moderator $
|
||||
moderatortext $ dnsender $ rfc822sender $ filtersender) )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7914.1.4.2.1 NAME 'qldapAdmin'
|
||||
DESC 'QMail-LDAP Subtree Admin'
|
||||
SUP top
|
||||
AUXILIARY
|
||||
MUST ( qlaDnManager $ qlaDomainList $ qlaMailMStorePrefix $
|
||||
qlaMailHostList )
|
||||
MAY ( qlaUidPrefix $ qlaQmailUid $ qlaQmailGid $ qlaMailQuotaSize $
|
||||
qlaMailQuotaCount $ qlaMailSizeMax ) )
|
@ -18,6 +18,11 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.defaultimap.inc.php");
|
||||
*/
|
||||
class cyrusimap extends defaultimap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'Cyrus';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, sieve, admin, logintypeemail
|
||||
*/
|
||||
|
@ -20,6 +20,11 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.defaultimap.inc.php");
|
||||
*/
|
||||
class dbmaildbmailuser extends defaultimap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'dbmail (dbmailUser Schema)';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, sieve, admin, logintypeemail
|
||||
*/
|
||||
|
@ -20,6 +20,11 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.defaultimap.inc.php");
|
||||
*/
|
||||
class dbmailqmailuser extends defaultimap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'dbmail (qmailUser Schema)';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, sieve, admin, logintypeemail
|
||||
*/
|
||||
|
@ -27,6 +27,11 @@ define('IMAP_NAMESPACE_ALL' , 'all');
|
||||
*/
|
||||
class defaultimap extends Net_IMAP
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'standard IMAP server';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, sieve, admin, logintypeemail
|
||||
*/
|
||||
@ -183,6 +188,16 @@ class defaultimap extends Net_IMAP
|
||||
$this->Net_IMAPProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return description for EMailAdmin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function description()
|
||||
{
|
||||
return static::DESCRIPTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to re-connect with the imapserver, if the object get's restored from the session
|
||||
*/
|
||||
|
@ -412,7 +412,7 @@ class emailadmin_bo extends so_sql
|
||||
static public function getSMTPServerTypes($extended=true)
|
||||
{
|
||||
$retData = array();
|
||||
foreach(self::$SMTPServerType as $key => $value)
|
||||
/* foreach(self::$SMTPServerType as $key => $value)
|
||||
{
|
||||
if ($extended)
|
||||
{
|
||||
@ -420,14 +420,22 @@ class emailadmin_bo extends so_sql
|
||||
$retData[$key]['description'] = isset($value['description'])?$value['description']:$key;
|
||||
$retData[$key]['classname'] = isset($value['classname'])?$value['classname']:$key;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
foreach($GLOBALS['egw']->hooks->process(array(
|
||||
'location' => 'smtp_server_types',
|
||||
'extended' => $extended,
|
||||
),array(),true) as $app => $data)
|
||||
), array('managementserver', 'emailadmin'), true) as $app => $data)
|
||||
{
|
||||
if ($data) $retData += $data;
|
||||
}
|
||||
uksort($retData, function($a, $b) {
|
||||
static $prio = array( // not explicitly mentioned get 0
|
||||
'emailadmin_smtp' => 9,
|
||||
'emailadmin_smtp_sql' => 8,
|
||||
'smtpplesk' => -1,
|
||||
);
|
||||
return (int)$prio[$b] - (int)$prio[$a];
|
||||
});
|
||||
return $retData;
|
||||
}
|
||||
|
||||
@ -442,7 +450,7 @@ class emailadmin_bo extends so_sql
|
||||
static public function getIMAPServerTypes($extended=true)
|
||||
{
|
||||
$retData = array();
|
||||
foreach(self::$IMAPServerType as $key => $value)
|
||||
/* foreach(self::$IMAPServerType as $key => $value)
|
||||
{
|
||||
if ($extended)
|
||||
{
|
||||
@ -455,14 +463,24 @@ class emailadmin_bo extends so_sql
|
||||
{
|
||||
$retData[$key] = $value['description'];
|
||||
}
|
||||
}
|
||||
}*/
|
||||
foreach($GLOBALS['egw']->hooks->process(array(
|
||||
'location' => 'imap_server_types',
|
||||
'extended' => $extended,
|
||||
),array(),true) as $app => $data)
|
||||
), array('managementserver', 'emailadmin'), true) as $app => $data)
|
||||
{
|
||||
if ($data) $retData += $data;
|
||||
}
|
||||
uksort($retData, function($a, $b) {
|
||||
static $prio = array( // not explicitly mentioned get 0
|
||||
'defaultimap' => 9,
|
||||
'managementserver_imap' => 8,
|
||||
'emailadmin_dovecot' => 7,
|
||||
'cyrusimap' => 6,
|
||||
'pleskimap' => -1,
|
||||
);
|
||||
return (int)$prio[$b] - (int)$prio[$a];
|
||||
});
|
||||
return $retData;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.defaultimap.inc.php");
|
||||
*/
|
||||
class emailadmin_dovecot extends defaultimap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'Dovecot';
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, sieve, admin, logintypeemail
|
||||
*/
|
||||
|
@ -119,7 +119,7 @@ class emailadmin_hooks
|
||||
}
|
||||
|
||||
/**
|
||||
* Add further imap and smtp server plugins to emailadmin
|
||||
* Detect imap and smtp server plugins from EMailAdmin's inc directory
|
||||
*
|
||||
* @param string|array $data location string or array with key 'location' and other params
|
||||
* @return array
|
||||
@ -129,74 +129,37 @@ class emailadmin_hooks
|
||||
$location = is_array($data) ? $data['location'] : $data;
|
||||
$extended = is_array($data) ? $data['extended'] : false;
|
||||
|
||||
switch($location)
|
||||
$types = array();
|
||||
foreach(scandir($dir=EGW_INCLUDE_ROOT.'/emailadmin/inc') as $file)
|
||||
{
|
||||
case 'imap_server_types':
|
||||
return array(
|
||||
'defaultimap' => $extended ? array(
|
||||
'description' => 'standard IMAP server',
|
||||
'protocol' => 'imap',
|
||||
'classname' => 'defaultimap'
|
||||
) : 'standard IMAP server',
|
||||
'emailadmin_dovecot' => $extended ? array(
|
||||
'description' => 'Dovecot',
|
||||
'classname' => 'emailadmin_dovecot',
|
||||
'protocol' => 'imap',
|
||||
) : 'Dovecot',
|
||||
'cyrusimap' => $extended ? array(
|
||||
'description' => 'Cyrus IMAP Server',
|
||||
'protocol' => 'imap',
|
||||
'classname' => 'cyrusimap'
|
||||
) : 'Cyrus IMAP Server',
|
||||
'dbmailqmailuser' => $extended ? array(
|
||||
'description' => 'DBMail (qmailUser schema)',
|
||||
'protocol' => 'imap',
|
||||
'classname' => 'dbmailqmailuser'
|
||||
) : 'DBMail (qmailUser schema)',
|
||||
'pleskimap' => $extended ? array(
|
||||
'description' => 'Plesk IMAP Server (Courier)',
|
||||
'protocol' => 'imap',
|
||||
'classname' => 'pleskimap'
|
||||
) : 'Plesk IMAP Server (Courier)',
|
||||
'dbmaildbmailuser' => $extended ? array(
|
||||
'description' => 'DBMail (dbmailUser schema)',
|
||||
'protocol' => 'imap',
|
||||
'classname' => 'dbmaildbmailuser'
|
||||
) : 'DBMail (dbmailUser schema)',
|
||||
if (!preg_match('/^class\.([^.]*(smtp|imap|postfix|dovecot|dbmail)[^.*]*)\.inc\.php$/', $file, $matches)) continue;
|
||||
$class_name = $matches[1];
|
||||
include_once($dir.'/'.$file);
|
||||
if (!class_exists($class_name)) continue;
|
||||
|
||||
$is_imap = $class_name == 'defaultimap' || is_subclass_of($class_name, 'defaultimap');
|
||||
$is_smtp = $class_name == 'emailadmin_smtp' || is_subclass_of($class_name, 'emailadmin_smtp') && $class_name != 'defaultsmtp';
|
||||
|
||||
if ($is_smtp && $location == 'smtp_server_types' || $is_imap && $location == 'imap_server_types')
|
||||
{
|
||||
$type = array(
|
||||
'classname' => $class_name,
|
||||
'description' => is_callable($function=$class_name.'::description') ? call_user_func($function) : $class_name,
|
||||
);
|
||||
|
||||
case 'smtp_server_types': // nothing yet
|
||||
return array(
|
||||
'emailadmin_smtp' => $extended ? array(
|
||||
'description' => 'standard SMTP-Server',
|
||||
'classname' => 'emailadmin_smtp'
|
||||
) : 'standard SMTP-Server',
|
||||
'emailadmin_smtp_sql' => $extended ? array(
|
||||
'description' => 'Postfix (SQL)',
|
||||
'classname' => 'emailadmin_smtp_sql',
|
||||
) : 'Postfix (SQL)',
|
||||
'postfixldap' => $extended ? array(
|
||||
'description' => 'Postfix (qmail Schema)',
|
||||
'classname' => 'postfixldap'
|
||||
) : 'Postfix (qmail Schema)',
|
||||
'emailadmin_smtp_qmail' => $extended ? array(
|
||||
'description' => 'Postfix (new qmail Schema)',
|
||||
'classname' => 'emailadmin_smtp_qmail'
|
||||
) : 'Postfix (new qmail Schema)',
|
||||
'postfixinetorgperson' => $extended ? array(
|
||||
'description' => 'Postfix (inetOrgPerson Schema)',
|
||||
'classname' => 'postfixinetorgperson'
|
||||
) : 'Postfix (inetOrgPerson Schema)',
|
||||
'smtpplesk' => $extended ? array(
|
||||
'description' => 'Plesk SMTP-Server (Qmail)',
|
||||
'classname' => 'smtpplesk'
|
||||
) : 'Plesk SMTP-Server (Qmail)',
|
||||
'postfixdbmailuser' => $extended ? array(
|
||||
'description' => 'Postfix (dbmail Schema)',
|
||||
'classname' => 'postfixdbmailuser'
|
||||
) : 'Postfix (dbmail Schema)',
|
||||
);
|
||||
break;
|
||||
if ($is_imap) $type['protocol'] = 'imap';
|
||||
|
||||
$types[$class_name] = $type;
|
||||
}
|
||||
}
|
||||
if (!$extended)
|
||||
{
|
||||
foreach($types as $class_name => &$type)
|
||||
{
|
||||
$type = $type['description'];
|
||||
}
|
||||
}
|
||||
//error_log(__METHOD__."(".array2string($data).") returning ".array2string($types));
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,11 @@
|
||||
*/
|
||||
class emailadmin_smtp
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'standard SMTP-Server';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, forward
|
||||
*/
|
||||
@ -74,6 +79,16 @@ class emailadmin_smtp
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return description for EMailAdmin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function description()
|
||||
{
|
||||
return static::DESCRIPTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called on account creation
|
||||
*
|
||||
|
166
emailadmin/inc/class.emailadmin_smtp_ads.inc.php
Normal file
166
emailadmin/inc/class.emailadmin_smtp_ads.inc.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware EMailAdmin: Postfix using Active Directorys Exchange attributes
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package emailadmin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2013 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postfix using Active Directorys proxyAddresses attribute
|
||||
* (available without installing Exchange schemas).
|
||||
*
|
||||
* This plugin is NOT meant to administrate an Exchange Server using AD!
|
||||
*
|
||||
* Aliases, forwards, forward only and quota is stored in
|
||||
* multivalued attribute proxyAddresses with different prefixes.
|
||||
*
|
||||
* Primary mail address is additionally stored in proxyAddresses.
|
||||
* Disabling mail removes proxyAddresses completly.
|
||||
*
|
||||
* @link http://msdn.microsoft.com/en-us/library/ms679424(v=vs.85).aspx
|
||||
* @link http://www.dovecot.org/list/dovecot/2010-February/046763.html
|
||||
*/
|
||||
class emailadmin_smtp_ads extends emailadmin_smtp_ldap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'Active Directory';
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, forward
|
||||
*/
|
||||
const CAPABILITIES = 'default|forward';
|
||||
|
||||
/**
|
||||
* Name of schema, has to be in the right case!
|
||||
*/
|
||||
const SCHEMA = 'top';
|
||||
|
||||
/**
|
||||
* Filter for users
|
||||
*
|
||||
* objectCategory is indexed, while objectclass is not!
|
||||
*/
|
||||
const USER_FILTER = '(objectCategory=person)';
|
||||
|
||||
/**
|
||||
* Name of schema for groups, has to be in the right case!
|
||||
*/
|
||||
const GROUP_SCHEMA = 'group';
|
||||
|
||||
/**
|
||||
* Attribute to enable mail for an account, OR false if existence of ALIAS_ATTR is enough for mail delivery
|
||||
*/
|
||||
const MAIL_ENABLE_ATTR = false;
|
||||
|
||||
/**
|
||||
* Attribute for aliases OR false to use mail
|
||||
*/
|
||||
const ALIAS_ATTR = 'proxyaddresses';
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for aliases (eg. "smtp:"), aliases get added with it and only aliases with it are reported
|
||||
*/
|
||||
const ALIAS_PREFIX = 'smtp:';
|
||||
|
||||
/**
|
||||
* Primary mail address required as an alias too: true or false
|
||||
*/
|
||||
const REQUIRE_MAIL_AS_ALIAS = true;
|
||||
|
||||
/**
|
||||
* Attribute for forwards OR false if not possible
|
||||
*/
|
||||
const FORWARD_ATTR = 'proxyaddresses';
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for forwards (eg. "forward:"), forwards get added with it and only forwards with it are reported
|
||||
*/
|
||||
const FORWARD_PREFIX = 'forward:';
|
||||
|
||||
/**
|
||||
* Attribute to only forward mail, OR false if not available
|
||||
*/
|
||||
const FORWARD_ONLY_ATTR = 'proxyaddresses';
|
||||
|
||||
/**
|
||||
* Value of forward-only attribute, if not set any value will switch forward only on (checked with =*)
|
||||
*/
|
||||
const FORWARD_ONLY_VALUE = 'forwardOnly';
|
||||
|
||||
/**
|
||||
* Attribute for mailbox, to which mail gets delivered OR false if not supported
|
||||
*/
|
||||
const MAILBOX_ATTR = false;
|
||||
|
||||
/**
|
||||
* Attribute for quota limit of user in MB
|
||||
*/
|
||||
const QUOTA_ATTR = 'proxyaddresses';
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for quota (eg. "quota:"), quota get added with it and only quota with it are reported
|
||||
*/
|
||||
const QUOTA_PREFIX = 'quota:';
|
||||
|
||||
/**
|
||||
* Internal quota in MB is multiplicated with this factor before stored in LDAP
|
||||
*/
|
||||
const QUOTA_FACTOR = 1048576;
|
||||
|
||||
/**
|
||||
* Attribute for user name
|
||||
*/
|
||||
const USER_ATTR = 'samaccountname';
|
||||
|
||||
/**
|
||||
* Attribute for numeric user id (optional)
|
||||
*
|
||||
* No single uidNumber attribute, as we use RID (last part of objectSid attribute) for it.
|
||||
*/
|
||||
const USERID_ATTR = false;
|
||||
|
||||
/**
|
||||
* Return LDAP connection
|
||||
*/
|
||||
protected function getLdapConnection()
|
||||
{
|
||||
static $ldap;
|
||||
|
||||
if (is_null($ldap))
|
||||
{
|
||||
if (!is_a($GLOBALS['egw']->accounts->backend, 'accounts_ads'))
|
||||
{
|
||||
throw new egw_exception_wrong_userinput('Postfix with Active Directory requires accounts stored in ADS!');
|
||||
}
|
||||
$ldap = $GLOBALS['egw']->accounts->backend->ldap_connection();
|
||||
}
|
||||
return $ldap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $defaultDomain=null
|
||||
*/
|
||||
function __construct($defaultDomain=null)
|
||||
{
|
||||
parent::__construct($defaultDomain);
|
||||
|
||||
$this->setBase($GLOBALS['egw']->accounts->backend->ads_context());
|
||||
}
|
||||
/**
|
||||
* Return description for EMailAdmin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function description()
|
||||
{
|
||||
return static::DESCRIPTION;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
* @link http://www.stylite.de
|
||||
* @package emailadmin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -18,8 +18,13 @@
|
||||
* Aliases are stored as aditional mail Attributes. The primary mail address is the first one.
|
||||
* This schema does NOT support forwarding or disabling of an account for mail.
|
||||
*
|
||||
* Please do NOT copy this class! Extend it and set the constants different
|
||||
* (incl. protected config var as long as we can not require PHP5.3 for LSB).
|
||||
* Aliases, forwards, forward-only and quota attribute can be stored in same multivalued attribute
|
||||
* with different prefixes.
|
||||
*
|
||||
* Please do NOT copy this class! Extend it and set the constants different.
|
||||
*
|
||||
* Please note: schema names muse use correct case (eg. "inetOrgPerson"),
|
||||
* while attribute name muse use lowercase, as LDAP returns them as keys in lowercase!
|
||||
*/
|
||||
class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
{
|
||||
@ -28,6 +33,16 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
*/
|
||||
const SCHEMA = 'inetOrgPerson';
|
||||
|
||||
/**
|
||||
* Filter for users
|
||||
*/
|
||||
const USER_FILTER = '(objectClass=posixAccount)';
|
||||
|
||||
/**
|
||||
* Name of schema for groups, has to be in the right case!
|
||||
*/
|
||||
const GROUP_SCHEMA = 'posixGroup';
|
||||
|
||||
/**
|
||||
* Attribute to enable mail for an account, OR false if existence of ALIAS_ATTR is enough for mail delivery
|
||||
*/
|
||||
@ -38,21 +53,36 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
*/
|
||||
const ALIAS_ATTR = false;
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for aliases (eg. "smtp:"), aliases get added with it and only aliases with it are reported
|
||||
*/
|
||||
const ALIAS_PREFIX = '';
|
||||
|
||||
/**
|
||||
* Primary mail address required as an alias too: true or false
|
||||
*/
|
||||
const REQUIRE_MAIL_AS_ALIAS=false;
|
||||
const REQUIRE_MAIL_AS_ALIAS = false;
|
||||
|
||||
/**
|
||||
* Attribute for forwards OR false if not possible
|
||||
*/
|
||||
const FORWARD_ATTR = false;
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for forwards (eg. "forward:"), forwards get added with it and only forwards with it are reported
|
||||
*/
|
||||
const FORWARD_PREFIX = '';
|
||||
|
||||
/**
|
||||
* Attribute to only forward mail, OR false if not available
|
||||
*/
|
||||
const FORWARD_ONLY_ATTR = false;
|
||||
|
||||
/**
|
||||
* Value of forward-only attribute, if empty any value will switch forward only on (checked with =*)
|
||||
*/
|
||||
const FORWARD_ONLY = 'forwardOnly';
|
||||
|
||||
/**
|
||||
* Attribute for mailbox, to which mail gets delivered OR false if not supported
|
||||
*/
|
||||
@ -63,55 +93,92 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
*/
|
||||
const QUOTA_ATTR = false;
|
||||
|
||||
/**
|
||||
* Caseinsensitive prefix for quota (eg. "quota:"), quota get added with it and only quota with it are reported
|
||||
*/
|
||||
const QUOTA_PREFIX = '';
|
||||
|
||||
/**
|
||||
* Internal quota in MB is multiplicated with this factor before stored in LDAP
|
||||
*/
|
||||
const QUOTA_FACTOR = 1048576;
|
||||
|
||||
/**
|
||||
* Attribute for user name
|
||||
*/
|
||||
const USER_ATTR = 'uid';
|
||||
|
||||
/**
|
||||
* Attribute for numeric user id (optional)
|
||||
*/
|
||||
const USERID_ATTR = 'uidnumber';
|
||||
|
||||
/**
|
||||
* Base for all searches, defaults to $GLOBALS['egw_info']['server']['ldap_context'] and can be set via setBase($base)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $search_base;
|
||||
|
||||
/**
|
||||
* Special search filter for getUserData only
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $search_filter;
|
||||
|
||||
/**
|
||||
* Log all LDAP writes / actions to error_log
|
||||
*/
|
||||
var $debug = false;
|
||||
|
||||
/**
|
||||
* LDAP schema configuration
|
||||
*
|
||||
* Parent can NOT use constants direct as we have no late static binding in currenlty required PHP 5.2
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config = array(
|
||||
'schema' => self::SCHEMA,
|
||||
'mail_enable_attr' => self::MAIL_ENABLE_ATTR,
|
||||
'mail_enabled' => self::MAIL_ENABLED,
|
||||
'alias_attr' => self::ALIAS_ATTR,
|
||||
'require_mail_as_alias' => self::REQUIRE_MAIL_AS_ALIAS,
|
||||
'forward_attr' => self::FORWARD_ATTR,
|
||||
'forward_only_attr' => self::FORWARD_ONLY_ATTR,
|
||||
'forward_only' => self::FORWARD_ONLY,
|
||||
'mailbox_attr' => self::MAILBOX_ATTR,
|
||||
'quota_attr' => self::QUOTA_ATTR,
|
||||
'search_filter' => null,
|
||||
'search_base' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
* from here on implementation, please do NOT copy but extend it!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set ldap search filter for aliases and forwards
|
||||
* Constructor
|
||||
*
|
||||
* @param string $defaultDomain=null
|
||||
*/
|
||||
function __construct($defaultDomain=null)
|
||||
{
|
||||
parent::__construct($defaultDomain);
|
||||
|
||||
if (empty($this->search_base))
|
||||
{
|
||||
$this->setBase($GLOBALS['egw_info']['server']['ldap_context']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return description for EMailAdmin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function description()
|
||||
{
|
||||
return 'LDAP ('.static::SCHEMA.')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ldap search filter for aliases and forwards (getUserData)
|
||||
*
|
||||
* @param string $filter
|
||||
*/
|
||||
function setFilter($filter)
|
||||
{
|
||||
$this->config['search_filter'] = $filter;
|
||||
$this->search_filter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ldap search base for aliases and forwards
|
||||
* Set ldap search base, default $GLOBALS['egw_info']['server']['ldap_context']
|
||||
*
|
||||
* @param string $base
|
||||
*/
|
||||
function setBase($base)
|
||||
{
|
||||
$this->config['search_base'] = $base;
|
||||
$this->search_base = $base;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,11 +193,11 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
common::email_address($_hookValues['account_firstname'],
|
||||
$_hookValues['account_lastname'],$_hookValues['account_lid'],$this->defaultDomain);
|
||||
|
||||
$ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
$ds = $this->getLdapConnection();
|
||||
|
||||
$filter = "uid=".$_hookValues['account_lid'];
|
||||
$filter = static::USER_ATTR."=".ldap::quote($_hookValues['account_lid']);
|
||||
|
||||
if (!($sri = @ldap_search($ds,$GLOBALS['egw_info']['server']['ldap_context'],$filter)))
|
||||
if (!($sri = @ldap_search($ds, $this->search_base, $filter)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -140,9 +207,9 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
unset($objectClasses['count']);
|
||||
|
||||
// add our mail schema, if not already set
|
||||
if(!in_array($this->config['schema'],$objectClasses) && !in_array(strtolower($this->config['schema']),$objectClasses))
|
||||
if(!in_array(static::SCHEMA,$objectClasses) && !in_array(strtolower(static::SCHEMA),$objectClasses))
|
||||
{
|
||||
$objectClasses[] = $this->config['schema'];
|
||||
$objectClasses[] = static::SCHEMA;
|
||||
}
|
||||
// the new code for postfix+cyrus+ldap
|
||||
$newData = array(
|
||||
@ -150,19 +217,19 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
'objectclass' => $objectClasses
|
||||
);
|
||||
// does schema have explicit alias attribute AND require mail added as alias too
|
||||
if ($this->config['alias_attr'] && $this->config['require_mail_as_alias'] && $this->config['alias_attr'])
|
||||
if (static::ALIAS_ATTR && static::REQUIRE_MAIL_AS_ALIAS)
|
||||
{
|
||||
$newData[$this->config['alias_attr']] = $mailLocalAddress;
|
||||
$newData[static::ALIAS_ATTR] = static::ALIAS_PREFIX.$mailLocalAddress;
|
||||
}
|
||||
// does schema support enabling/disabling mail via attribute
|
||||
if ($this->config['mail_enable_attr'])
|
||||
if (static::MAIL_ENABLE_ATTR)
|
||||
{
|
||||
$newData[$this->config['mail_enable_attr']] = $this->config['mail_enabled'];
|
||||
$newData[static::MAIL_ENABLE_ATTR] = static::MAIL_ENABLED;
|
||||
}
|
||||
// does schema support an explicit mailbox name --> set it
|
||||
if ($this->config['mailbox_attr'])
|
||||
if (static::MAILBOX_ATTR)
|
||||
{
|
||||
$newData[$this->config['mailbox_attr']] = self::mailbox_addr($_hookValues);
|
||||
$newData[static::MAILBOX_ATTR] = self::mailbox_addr($_hookValues);
|
||||
}
|
||||
|
||||
if (!($ret = ldap_mod_replace($ds, $accountDN, $newData)) || $this->debug)
|
||||
@ -183,10 +250,10 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
function getAccountEmailAddress($_accountName)
|
||||
{
|
||||
$emailAddresses = array();
|
||||
$ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
$filter = sprintf("(&(uid=%s)(objectclass=posixAccount))",$_accountName);
|
||||
$attributes = array('dn','mail',$this->config['alias_attr']);
|
||||
$sri = @ldap_search($ds, $GLOBALS['egw_info']['server']['ldap_context'], $filter, $attributes);
|
||||
$ds = $this->getLdapConnection();
|
||||
$filter = '(&'.static::USER_FILTER.'('.static::USER_ATTR.'='.ldap::quote($_accountName).'))';
|
||||
$attributes = array('dn', 'mail', static::ALIAS_ATTR);
|
||||
$sri = @ldap_search($ds, $this->search_base, $filter, $attributes);
|
||||
|
||||
if ($sri)
|
||||
{
|
||||
@ -206,12 +273,10 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($this->config['alias_attr'] && isset($allValues[0][$this->config['alias_attr']]))
|
||||
if (static::ALIAS_ATTR && isset($allValues[0][static::ALIAS_ATTR]))
|
||||
{
|
||||
foreach($allValues[0][$this->config['alias_attr']] as $key => $value)
|
||||
foreach(self::getAttributePrefix($allValues[0][static::ALIAS_ATTR], static::ALIAS_PREFIX) as $value)
|
||||
{
|
||||
if ($key === 'count') continue;
|
||||
|
||||
$emailAddresses[] = array(
|
||||
'name' => $realName,
|
||||
'address' => $value,
|
||||
@ -239,24 +304,29 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
*/
|
||||
function getUserData($user, $match_uid_at_domain=false)
|
||||
{
|
||||
$userData = array();
|
||||
$userData = array(
|
||||
'mailbox' => array(),
|
||||
'forward' => array(),
|
||||
|
||||
$ldap = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
);
|
||||
|
||||
if (is_numeric($user))
|
||||
$ldap = $this->getLdapConnection();
|
||||
|
||||
if (is_numeric($user) && static::USERID_ATTR)
|
||||
{
|
||||
$filter = '(uidnumber='.(int)$user.')';
|
||||
$filter = '('.static::USERID_ATTR.'='.(int)$user.')';
|
||||
}
|
||||
elseif (strpos($user, '@') === false)
|
||||
{
|
||||
$filter = '(uid='.ldap::quote($user).')';
|
||||
if (is_numeric($user)) $user = $GLOBALS['egw']->accounts->id2name($user);
|
||||
$filter = '(&'.static::USER_FILTER.'('.static::USER_ATTR.'='.ldap::quote($user).'))';
|
||||
}
|
||||
else // email address --> build filter by attributes defined in config
|
||||
{
|
||||
list($namepart, $domain) = explode('@', $user);
|
||||
if (!empty($this->config['search_filter']))
|
||||
if (!empty($this->search_filter))
|
||||
{
|
||||
$filter = strtr($this->config['search_filter'], array(
|
||||
$filter = strtr($this->search_filter, array(
|
||||
'%s' => ldap::quote($user),
|
||||
'%u' => ldap::quote($namepart),
|
||||
'%d' => ldap::quote($domain),
|
||||
@ -265,57 +335,67 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
else
|
||||
{
|
||||
$filter = array('(mail='.ldap::quote($user).')');
|
||||
if ($match_uid_at_domain) $filter[] = '(uid='.ldap::quote($namepart).')';
|
||||
if ($this->config['alias_attr'])
|
||||
if ($match_uid_at_domain) $filter[] = '('.static::USER_ATTR.'='.ldap::quote($namepart).')';
|
||||
if (static::ALIAS_ATTR)
|
||||
{
|
||||
$filter[] = '('.$this->config['alias_attr'].'='.ldap::quote($user).')';
|
||||
$filter[] = '('.static::ALIAS_ATTR.'='.static::ALIAS_PREFIX.ldap::quote($user).')';
|
||||
}
|
||||
$filter = count($filter) > 1 ? '(|'.explode('', $filter).')' : $filter[0];
|
||||
|
||||
// if an enable attribute is set, only return enabled accounts
|
||||
if ($this->config['mail_enable_attr'])
|
||||
if (static::MAIL_ENABLE_ATTR)
|
||||
{
|
||||
$filter = '(&('.$this->config['mail_enable_attr'].'='.
|
||||
($this->config['mail_enabled'] ? $this->config['mail_enabled'] : '*').")$filter)";
|
||||
$filter = '(&('.static::MAIL_ENABLE_ATTR.'='.
|
||||
(static::MAIL_ENABLED ? static::MAIL_ENABLED : '*').")$filter)";
|
||||
}
|
||||
}
|
||||
}
|
||||
$base = empty($this->config['search_base']) ?
|
||||
$GLOBALS['egw_info']['server']['ldap_context'] : $this->config['search_base'];
|
||||
$sri = ldap_search($ldap, $base, $filter, array($this->config['schema']));
|
||||
$attributes = array_values(array_diff(array(
|
||||
'mail', 'objectclass', static::USER_ATTR, static::MAIL_ENABLE_ATTR, static::ALIAS_ATTR,
|
||||
static::MAILBOX_ATTR, static::FORWARD_ATTR, static::FORWARD_ONLY_ATTR, static::QUOTA_ATTR,
|
||||
), array(false, '')));
|
||||
|
||||
$sri = ldap_search($ldap, $this->search_base, $filter, $attributes);
|
||||
|
||||
if ($sri)
|
||||
{
|
||||
$allValues = ldap_get_entries($ldap, $sri);
|
||||
if ($this->debug) error_log(__METHOD__."('$user') --> ldap_search(, '$base', '$filter') --> ldap_get_entries=".array2string($allValues[0]));
|
||||
if ($this->debug) error_log(__METHOD__."('$user') --> ldap_search(, '$this->search_base', '$filter') --> ldap_get_entries=".array2string($allValues[0]));
|
||||
|
||||
foreach($allValues as $key => $values)
|
||||
{
|
||||
if ($key === 'count') continue;
|
||||
|
||||
// groups are always active (if they have an email) and allways forwardOnly
|
||||
if (in_array('posixGroup', $values['objectclass']))
|
||||
if (in_array(static::GROUP_SCHEMA, $values['objectclass']))
|
||||
{
|
||||
$accountStatus = emailadmin_smtp::MAIL_ENABLED;
|
||||
$deliveryMode = emailadmin_smtp::FORWARD_ONLY;
|
||||
}
|
||||
else // for users we have to check the attributes
|
||||
{
|
||||
if ($this->config['mail_enable_attr'])
|
||||
if (static::MAIL_ENABLE_ATTR)
|
||||
{
|
||||
$accountStatus = isset($values[$this->config['mail_enable_attr']]) &&
|
||||
($this->config['mail_enabled'] && !strcasecmp($values[$this->config['mail_enable_attr']][0], $this->config['mail_enabled']) ||
|
||||
!$this->config['mail_enabled'] && $values[$this->config['alias_attr']]['count'] > 0) ? emailadmin_smtp::MAIL_ENABLED : '';
|
||||
$accountStatus = isset($values[static::MAIL_ENABLE_ATTR]) &&
|
||||
(static::MAIL_ENABLED && !strcasecmp($values[static::MAIL_ENABLE_ATTR][0], static::MAIL_ENABLED) ||
|
||||
!static::MAIL_ENABLED && $values[static::ALIAS_ATTR]['count'] > 0) ? emailadmin_smtp::MAIL_ENABLED : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$accountStatus = $values[$this->config['alias_attr']]['count'] > 0 ? emailadmin_smtp::MAIL_ENABLED : '';
|
||||
$accountStatus = $values[static::ALIAS_ATTR]['count'] > 0 ? emailadmin_smtp::MAIL_ENABLED : '';
|
||||
}
|
||||
if ($this->config['forward_only_attr'])
|
||||
if (static::FORWARD_ONLY_ATTR)
|
||||
{
|
||||
$deliveryMode = isset($values[$this->config['forward_only_attr']]) &&
|
||||
($this->config['forward_only'] && !strcasecmp($values[$this->config['forward_only_attr']][0], $this->config['forward_only']) ||
|
||||
!$this->config['forward_only'] && $values[$this->config['forward_only_attr']]['count'] > 0) ? emailadmin_smtp::FORWARD_ONLY : '';
|
||||
if (static::FORWARD_ONLY) // check caseinsensitiv for existence of that value
|
||||
{
|
||||
$deliveryMode = self::getAttributePrefix($values[static::FORWARD_ONLY_ATTR], static::FORWARD_ONLY) ?
|
||||
emailadmin_smtp::FORWARD_ONLY : '';
|
||||
}
|
||||
else // check for existence of any value
|
||||
{
|
||||
$deliveryMode = $values[static::FORWARD_ONLY_ATTR]['count'] > 0 ?
|
||||
emailadmin_smtp::FORWARD_ONLY : '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -329,29 +409,28 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
// groups never have a mailbox, accounts can have a deliveryMode of "forwardOnly"
|
||||
if ($deliveryMode != emailadmin_smtp::FORWARD_ONLY)
|
||||
{
|
||||
$userData['uid'][] = $values['uid'][0];
|
||||
if ($this->config['mailbox_attr'] && isset($values[$this->config['mailbox_attr']]))
|
||||
$userData[static::USER_ATTR][] = $values[static::USER_ATTR][0];
|
||||
if (static::MAILBOX_ATTR && isset($values[static::MAILBOX_ATTR]))
|
||||
{
|
||||
$userData['mailbox'][] = $values[$this->config['mailbox_attr']][0];
|
||||
$userData['mailbox'][] = $values[static::MAILBOX_ATTR][0];
|
||||
}
|
||||
}
|
||||
if ($this->config['forward_attr'] && $values[$this->config['forward_attr']])
|
||||
if (static::FORWARD_ATTR && $values[static::FORWARD_ATTR])
|
||||
{
|
||||
$userData['forward'] = array_merge((array)$userData['forward'], $values[$this->config['forward_attr']]);
|
||||
unset($userData['forward']['count']);
|
||||
$userData['forward'] = array_merge($userData['forward'],
|
||||
self::getAttributePrefix($values[static::FORWARD_ATTR], static::FORWARD_PREFIX, false));
|
||||
}
|
||||
}
|
||||
|
||||
// regular user-data can only be from users, NOT groups
|
||||
if (in_array('posixGroup', $values['objectclass'])) continue;
|
||||
if (in_array(static::GROUP_SCHEMA, $values['objectclass'])) continue;
|
||||
|
||||
$userData['mailLocalAddress'] = $values['mail'][0];
|
||||
$userData['accountStatus'] = $accountStatus;
|
||||
|
||||
if ($this->config['alias_attr'])
|
||||
if (static::ALIAS_ATTR)
|
||||
{
|
||||
$userData['mailAlternateAddress'] = (array)$values[$this->config['alias_attr']];
|
||||
unset($userData['mailAlternateAddress']['count']);
|
||||
$userData['mailAlternateAddress'] = self::getAttributePrefix($values[static::ALIAS_ATTR], static::ALIAS_PREFIX);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -361,31 +440,27 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
$userData['mailAlternateAddress'] = array_values($userData['mailAlternateAddress']);
|
||||
}
|
||||
|
||||
$userData['mailForwardingAddress'] = $this->config['forward_attr'] ? $values[$this->config['forward_attr']] : array();
|
||||
unset($userData['mailForwardingAddress']['count']);
|
||||
|
||||
if ($this->config['mailbox_attr']) $userData['mailMessageStore'] = $values[$this->config['mailbox_attr']][0];
|
||||
|
||||
if ($this->config['forward_only_attr'])
|
||||
if (static::FORWARD_ATTR)
|
||||
{
|
||||
$userData['deliveryMode'] = isset($values[$this->config['forward_only_attr']]) &&
|
||||
($this->config['forward_only'] && !strcasecmp($values[$this->config['forward_only_attr']][0], $this->config['forward_only']) ||
|
||||
!$this->config['forward_only'] && $values[$this->config['forward_only_attr']]['count'] > 0) ? emailadmin_smtp::FORWARD_ONLY : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$userData['deliveryMode'] = '';
|
||||
$userData['mailForwardingAddress'] = self::getAttributePrefix($values[static::FORWARD_ATTR], static::FORWARD_PREFIX);
|
||||
}
|
||||
|
||||
if (static::MAILBOX_ATTR) $userData['mailMessageStore'] = $values[static::MAILBOX_ATTR][0];
|
||||
|
||||
$userData['deliveryMode'] = $deliveryMode;
|
||||
|
||||
// eg. suse stores all email addresses as aliases
|
||||
if ($this->config['require_mail_as_alias'] &&
|
||||
if (static::REQUIRE_MAIL_AS_ALIAS &&
|
||||
($k = array_search($userData['mailLocalAddress'],$userData['mailAlternateAddress'])) !== false)
|
||||
{
|
||||
unset($userData['mailAlternateAddress'][$k]);
|
||||
}
|
||||
|
||||
if ($this->config['quota_attr'] && isset($values[$this->config['quota_attr']]))
|
||||
if (static::QUOTA_ATTR && isset($values[static::QUOTA_ATTR]))
|
||||
{
|
||||
$userData['quotaLimit'] = $values[$this->config['quota_attr']][0] / 1048576;
|
||||
$userData['quotaLimit'] = self::getAttributePrefix($values[static::QUOTA_ATTR], static::QUOTA_PREFIX);
|
||||
$userData['quotaLimit'] = array_shift($userData['quotaLimit']);
|
||||
$userData['quotaLimit'] = $userData['quotaLimit'] ? $userData['quotaLimit'] / static::QUOTA_FACTOR : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -411,25 +486,32 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
function setUserData($_uidnumber, array $_mailAlternateAddress, array $_mailForwardingAddress, $_deliveryMode,
|
||||
$_accountStatus, $_mailLocalAddress, $_quota, $_forwarding_only=false, $_setMailbox=null)
|
||||
{
|
||||
$filter = 'uidnumber='.(int)$_uidnumber;
|
||||
if (static::USERID_ATTR)
|
||||
{
|
||||
$filter = static::USERID_ATTR.'='.(int)$_uidnumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
$uid = $GLOBALS['egw']->accounts->id2name($_uidnumber);
|
||||
$filter = static::USER_ATTR.'='.ldap::quote($uid);
|
||||
}
|
||||
$ldap = $this->getLdapConnection();
|
||||
|
||||
$ldap = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
|
||||
if (!($sri = @ldap_search($ldap,$GLOBALS['egw_info']['server']['ldap_context'],$filter)))
|
||||
if (!($sri = @ldap_search($ldap, $this->search_base, $filter)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$allValues = ldap_get_entries($ldap, $sri);
|
||||
|
||||
$accountDN = $allValues[0]['dn'];
|
||||
$uid = $allValues[0]['uid'][0];
|
||||
$uid = $allValues[0][static::USER_ATTR][0];
|
||||
$objectClasses = $allValues[0]['objectclass'];
|
||||
|
||||
unset($objectClasses['count']);
|
||||
|
||||
if(!in_array($this->config['schema'],$objectClasses) && !in_array(strtolower($this->config['schema']),$objectClasses))
|
||||
if(!in_array(static::SCHEMA,$objectClasses) && !in_array(strtolower(static::SCHEMA),$objectClasses))
|
||||
{
|
||||
$objectClasses[] = $this->config['schema'];
|
||||
$objectClasses[] = static::SCHEMA;
|
||||
$newData['objectclass'] = $objectClasses;
|
||||
}
|
||||
|
||||
@ -438,53 +520,61 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
|
||||
$newData['mail'] = $_mailLocalAddress;
|
||||
// does schema have explicit alias attribute
|
||||
if ($this->config['alias_attr'])
|
||||
if (static::ALIAS_ATTR)
|
||||
{
|
||||
$newData[$this->config['alias_attr']] = (array)$_mailAlternateAddress;
|
||||
self::setAttributePrefix($newData[static::ALIAS_ATTR], $_mailAlternateAddress, static::ALIAS_PREFIX);
|
||||
|
||||
// all email must be stored as alias for suse
|
||||
if ($this->config['require_mail_as_alias'] && !in_array($_mailLocalAddress,(array)$_mailAlternateAddress))
|
||||
if (static::REQUIRE_MAIL_AS_ALIAS && !in_array($_mailLocalAddress,(array)$_mailAlternateAddress))
|
||||
{
|
||||
$newData[$this->config['alias_attr']][] = $_mailLocalAddress;
|
||||
self::setAttributePrefix($newData[static::ALIAS_ATTR], $_mailLocalAddress, static::ALIAS_PREFIX);
|
||||
}
|
||||
}
|
||||
// or de we add them - if existing - to mail attr
|
||||
elseif ($_mailAlternateAddress)
|
||||
{
|
||||
$newData['mail'] = array_merge((array)$newData['mail'],(array)$_mailAlternateAddress);
|
||||
self::setAttributePrefix($newData['mail'], $_mailAlternateAddress, static::ALIAS_PREFIX);
|
||||
}
|
||||
// does schema support to store forwards
|
||||
if ($this->config['forward_attr'])
|
||||
if (static::FORWARD_ATTR)
|
||||
{
|
||||
$newData[$this->config['forward_attr']] = (array)$_mailForwardingAddress;
|
||||
self::setAttributePrefix($newData[static::FORWARD_ATTR], $_mailForwardingAddress, static::FORWARD_PREFIX);
|
||||
}
|
||||
// does schema support only forwarding incomming mail
|
||||
if ($this->config['forward_only_attr'])
|
||||
if (static::FORWARD_ONLY_ATTR)
|
||||
{
|
||||
$newData[$this->config['forward_only_attr']] = $_deliveryMode ? $this->config['forward_only'] : array();
|
||||
}
|
||||
// does schema support enabling/disabling mail via attribute
|
||||
if ($this->config['mail_enable_attr'])
|
||||
{
|
||||
$newData[$this->config['mail_enable_attr']] = $_accountStatus ? $this->config['mail_enabled'] : array();
|
||||
self::setAttributePrefix($newData[static::FORWARD_ONLY_ATTR],
|
||||
$_deliveryMode ? (static::FORWARD_ONLY ? static::FORWARD_ONLY : 'forwardOnly') : array());
|
||||
}
|
||||
// does schema support an explicit mailbox name --> set it with $uid@$domain
|
||||
if ($this->config['mailbox_attr'] && empty($allValues[0][$this->config['mailbox_attr']][0]))
|
||||
if (static::MAILBOX_ATTR && empty($allValues[0][static::MAILBOX_ATTR][0]))
|
||||
{
|
||||
$newData[$this->config['mailbox_attr']] = $this->mailbox_addr(array(
|
||||
$newData[static::MAILBOX_ATTR] = $this->mailbox_addr(array(
|
||||
'account_id' => $_uidnumber,
|
||||
'account_lid' => $uid,
|
||||
'account_email' => $_mailLocalAddress,
|
||||
));
|
||||
}
|
||||
if ($this->config['quota_attr'])
|
||||
if (static::QUOTA_ATTR)
|
||||
{
|
||||
$newData[$this->config['quota_attr']] = (int)$_quota >= 0 ? (int)$_quota*1048576 : array();
|
||||
self::setAttributePrefix($newData[static::QUOTA_ATTR],
|
||||
(int)$_quota > 0 ? (int)$_quota*static::QUOTA_FACTOR : array(), static::QUOTA_PREFIX);
|
||||
}
|
||||
// does schema support enabling/disabling mail via attribute
|
||||
if (static::MAIL_ENABLE_ATTR)
|
||||
{
|
||||
$newData[static::MAIL_ENABLE_ATTR] = $_accountStatus ? static::MAIL_ENABLED : array();
|
||||
}
|
||||
// if we have no mail-enabled attribute, but require primary mail in aliases-attr
|
||||
// we do NOT write aliases, if mail is not enabled
|
||||
if (!$_accountStatus && !static::MAIL_ENABLE_ATTR && static::REQUIRE_MAIL_AS_ALIAS)
|
||||
{
|
||||
$newData[static::ALIAS_ATTR] = array();
|
||||
}
|
||||
// does schema support an explicit mailbox name --> set it, $_setMailbox is given
|
||||
if ($this->config['mailbox_attr'] && $_setMailbox)
|
||||
if (static::MAILBOX_ATTR && $_setMailbox)
|
||||
{
|
||||
$newData[$this->config['mailbox_attr']] = $_setMailbox;
|
||||
$newData[static::MAILBOX_ATTR] = $_setMailbox;
|
||||
}
|
||||
if ($this->debug) error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".array2string($newData).')');
|
||||
|
||||
@ -501,14 +591,22 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
*/
|
||||
function saveSMTPForwarding($_accountID, $_forwardingAddress, $_keepLocalCopy)
|
||||
{
|
||||
$ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
$filter = sprintf('(&(uidnumber=%d)(objectclass=posixAccount))',$_accountID);
|
||||
$attributes = array('dn',$this->config['forward_attr'],'objectclass');
|
||||
if ($this->config['forward_only_attr'])
|
||||
$ds = $this->getLdapConnection();
|
||||
if (static::USERID_ATTR)
|
||||
{
|
||||
$attributes[] = $this->config['forward_only_attr'];
|
||||
$filter = '(&'.static::USER_FILTER.'('.static::USERID_ATTR.'='.(int)$_accountID.'))';
|
||||
}
|
||||
$sri = ldap_search($ds, $GLOBALS['egw_info']['server']['ldap_context'], $filter, $attributes);
|
||||
else
|
||||
{
|
||||
$uid = $GLOBALS['egw']->accounts->id2name($_accountID);
|
||||
$filter = '(&'.static::USER_FILTER.'('.static::USER_ATTR.'='.ldap::quote($uid).'))';
|
||||
}
|
||||
$attributes = array('dn', static::FORWARD_ATTR, 'objectclass');
|
||||
if (static::FORWARD_ONLY_ATTR)
|
||||
{
|
||||
$attributes[] = static::FORWARD_ONLY_ATTR;
|
||||
}
|
||||
$sri = ldap_search($ds, $this->search_base, $filter, $attributes);
|
||||
|
||||
if ($sri)
|
||||
{
|
||||
@ -519,46 +617,163 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
||||
|
||||
unset($newData['objectclass']['count']);
|
||||
|
||||
if(!in_array($this->config['schema'],$objectClasses))
|
||||
if(!in_array(static::SCHEMA,$objectClasses))
|
||||
{
|
||||
$newData['objectclass'][] = $this->config['schema'];
|
||||
$newData['objectclass'][] = static::SCHEMA;
|
||||
}
|
||||
if ($this->config['forward_attr'])
|
||||
if (static::FORWARD_ATTR)
|
||||
{
|
||||
// copy all non-forward data (different prefix) to newData, all existing forwards to $forwards
|
||||
$newData[static::FORWARD_ATTR] = $allValues[0][static::FORWARD_ATTR];
|
||||
$forwards = self::getAttributePrefix($newData[static::FORWARD_ATTR], static::FORWARD_PREFIX);
|
||||
|
||||
if(!empty($_forwardingAddress))
|
||||
{
|
||||
if(is_array($allValues[0][$this->config['forward_attr']]))
|
||||
if($forwards)
|
||||
{
|
||||
$newData[$this->config['forward_attr']] = $allValues[0][$this->config['forward_attr']];
|
||||
unset($newData[$this->config['forward_attr']]['count']);
|
||||
if (!is_array($_forwardingAddress))
|
||||
{
|
||||
// replace the first forwarding address (old behavior)
|
||||
$newData[$this->config['forward_attr']][0] = $_forwardingAddress;
|
||||
$forwards[0] = $_forwardingAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
// replace all forwarding Addresses
|
||||
$newData[$this->config['forward_attr']] = $_forwardingAddress;
|
||||
$forwards = $_forwardingAddress;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$newData[$this->config['forward_attr']] = (array)$_forwardingAddress;
|
||||
$forwards = (array)$_forwardingAddress;
|
||||
}
|
||||
if ($this->config['forward_only_attr'])
|
||||
if (static::FORWARD_ONLY_ATTR)
|
||||
{
|
||||
$newData['deliverymode'] = $_keepLocalCopy == 'yes' ? array() : $this->config['forward_only'];
|
||||
self::getAttributePrefix($newData[static::FORWARD_ONLY_ATTR], static::FORWARD_ONLY);
|
||||
self::setAttributePrefix($newData[static::FORWARD_ONLY_ATTR],
|
||||
$_keepLocalCopy == 'yes' ? array() : static::FORWARD_ONLY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$newData[$this->config['forward_attr']] = array();
|
||||
$forwards = array();
|
||||
}
|
||||
// merge in again all new set forwards incl. opt. prefix
|
||||
self::getAttributePrefix($newData[static::FORWARD_ATTR], $forwards, static::FORWARD_PREFIX);
|
||||
}
|
||||
if ($this->debug) error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".array2string($newData).')');
|
||||
|
||||
return ldap_modify ($ds, $allValues[0]['dn'], $newData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configured mailboxes of a domain
|
||||
*
|
||||
* @param boolean $return_inactive return mailboxes NOT marked as accountStatus=active too
|
||||
* @return array uid => name-part of mailMessageStore
|
||||
*/
|
||||
function getMailboxes($return_inactive)
|
||||
{
|
||||
$ds = $this->getLdapConnection();
|
||||
$filter = array("(mail=*)");
|
||||
$attrs = array(static::USER_ATTR, 'mail');
|
||||
if (static::MAILBOX_ATTR)
|
||||
{
|
||||
$filter[] = '('.static::MAILBOX_ATTR.'=*)';
|
||||
$attrs[] = static::MAILBOX_ATTR;
|
||||
}
|
||||
if (!$return_inactive && static::MAIL_ENABLE_ATTR)
|
||||
{
|
||||
$filter[] = '('.static::MAIL_ENABLE_ATTR.'='.static::MAIL_ENABLED.')';
|
||||
}
|
||||
if (count($filter) > 1)
|
||||
{
|
||||
$filter = '(&'.implode('', $filter).')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter = $filter[0];
|
||||
}
|
||||
if (!($sr = @ldap_search($ds, $this->search_base, $filter, $attrs)))
|
||||
{
|
||||
//error_log("Error ldap_search(\$ds, '$base', '$filter')!");
|
||||
return array();
|
||||
}
|
||||
$entries = ldap_get_entries($ds, $sr);
|
||||
|
||||
unset($entries['count']);
|
||||
|
||||
$mailboxes = array();
|
||||
foreach($entries as $entry)
|
||||
{
|
||||
if ($entry[static::USER_ATTR][0] == 'anonymous') continue; // anonymous is never a mail-user!
|
||||
list($mailbox) = explode('@', $entry[static::MAILBOX_ATTR ? static::MAILBOX_ATTR : 'mail'][0]);
|
||||
$mailboxes[$entry[static::USER_ATTR][0]] = $mailbox;
|
||||
}
|
||||
return $mailboxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set values in a given LDAP attribute using an optional prefix
|
||||
*
|
||||
* @param array &$attribute on return array with values set and existing values preseved
|
||||
* @param string|array $values value(s) to set
|
||||
* @param string $prefix='' prefix to use or ''
|
||||
*/
|
||||
protected static function setAttributePrefix(&$attribute, $values, $prefix='')
|
||||
{
|
||||
$attribute_in = $attribute;
|
||||
if (!isset($attribute)) $attribute = array();
|
||||
if (!is_array($attribute)) $attribute = array($attribute);
|
||||
|
||||
foreach((array)$values as $value)
|
||||
{
|
||||
$attribute[] = $prefix.$value;
|
||||
}
|
||||
//error_log(__METHOD__."(".array2string($attribute_in).", ".array2string($values).", '$prefix') attribute=".array2string($attribute));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get values having an optional prefix from a given LDAP attribute
|
||||
*
|
||||
* @param array &$attribute only "count" and prefixed values get removed, get's reindexed, if values have been removed
|
||||
* @param string $prefix='' prefix to use or ''
|
||||
* @param boolean $remove=true remove returned values from $attribute
|
||||
* @return array with values (prefix removed) or array() if nothing found
|
||||
*/
|
||||
protected static function getAttributePrefix(&$attribute, $prefix='', $remove=true)
|
||||
{
|
||||
$attribute_in = $attribute;
|
||||
$values = array();
|
||||
|
||||
if (isset($attribute))
|
||||
{
|
||||
unset($attribute['count']);
|
||||
|
||||
foreach($attribute as $key => $value)
|
||||
{
|
||||
if (!$prefix || stripos($value, $prefix) === 0)
|
||||
{
|
||||
if ($remove) unset($attribute[$key]);
|
||||
$values[] = substr($value, strlen($prefix));
|
||||
}
|
||||
}
|
||||
// reindex $attribute, if neccessary
|
||||
if ($values && $attribute) $attribute = array_values($attribute);
|
||||
}
|
||||
//error_log(__METHOD__."(".array2string($attribute_in).", '$prefix', $remove) attribute=".array2string($attribute).' returning '.array2string($values));
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LDAP connection
|
||||
*/
|
||||
protected function getLdapConnection()
|
||||
{
|
||||
static $ldap;
|
||||
|
||||
if (is_null($ldap)) $ldap = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
|
||||
return $ldap;
|
||||
}
|
||||
}
|
||||
|
@ -53,10 +53,6 @@ class emailadmin_smtp_qmail extends emailadmin_smtp_ldap
|
||||
* Attribute to only forward mail, OR false if not available
|
||||
*/
|
||||
const FORWARD_ONLY_ATTR = 'deliverymode';
|
||||
/**
|
||||
* Attribute value to only forward mail
|
||||
*/
|
||||
const FORWARD_ONLY = 'forwardOnly';
|
||||
|
||||
/**
|
||||
* Attribute for mailbox, to which mail gets delivered OR false if not supported
|
||||
@ -69,27 +65,12 @@ class emailadmin_smtp_qmail extends emailadmin_smtp_ldap
|
||||
const QUOTA_ATTR = 'mailquotasize';
|
||||
|
||||
/**
|
||||
* Log all LDAP writes / actions to error_log
|
||||
*/
|
||||
var $debug = false;
|
||||
|
||||
/**
|
||||
* LDAP schema configuration
|
||||
* Return description for EMailAdmin
|
||||
*
|
||||
* Parent can NOT use constants direct as we have no late static binding in currenlty required PHP 5.2
|
||||
*
|
||||
* @var array
|
||||
* @return string
|
||||
*/
|
||||
protected $config = array(
|
||||
'schema' => self::SCHEMA,
|
||||
'mail_enable_attr' => self::MAIL_ENABLE_ATTR,
|
||||
'mail_enabled' => self::MAIL_ENABLED,
|
||||
'alias_attr' => self::ALIAS_ATTR,
|
||||
'require_mail_as_alias' => self::REQUIRE_MAIL_AS_ALIAS,
|
||||
'forward_attr' => self::FORWARD_ATTR,
|
||||
'forward_only_attr' => self::FORWARD_ONLY_ATTR,
|
||||
'forward_only' => self::FORWARD_ONLY,
|
||||
'mailbox_attr' => self::MAILBOX_ATTR,
|
||||
'quota_attr' => self::QUOTA_ATTR,
|
||||
);
|
||||
public static function description()
|
||||
{
|
||||
return 'LDAP (new '.static::SCHEMA.')';
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* @link http://www.stylite.de
|
||||
* @package emailadmin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2012 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2012-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -15,6 +15,11 @@
|
||||
*/
|
||||
class emailadmin_smtp_sql extends emailadmin_smtp
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'SQL';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, forward
|
||||
*/
|
||||
|
@ -33,6 +33,11 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.defaultimap.inc.php");
|
||||
|
||||
class pleskimap extends defaultimap
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'Plesk (Courier)';
|
||||
|
||||
/**
|
||||
* @var string $psa_mail_script full path to Plesk's mail.sh (Linux including sudo!) or mail.exe (Windows) interface
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
* @link http://www.egroupware.org
|
||||
* @package emailadmin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -54,10 +54,6 @@ class postfixdbmailuser extends emailadmin_smtp_ldap
|
||||
* Attribute to only forward mail, OR false if not available
|
||||
*/
|
||||
const FORWARD_ONLY_ATTR = 'deliverymode';
|
||||
/**
|
||||
* Attribute value to only forward mail
|
||||
*/
|
||||
const FORWARD_ONLY = 'forwardOnly';
|
||||
|
||||
/**
|
||||
* Attribute for mailbox, to which mail gets delivered OR false if not supported
|
||||
@ -65,28 +61,4 @@ class postfixdbmailuser extends emailadmin_smtp_ldap
|
||||
//const MAILBOX_ATTR = 'deliveryprogrampath';
|
||||
//const MAILBOX_ATTR = 'dbmailuid';
|
||||
const MAILBOX_ATTR = false;
|
||||
|
||||
/**
|
||||
* Log all LDAP writes / actions to error_log
|
||||
*/
|
||||
var $debug = false;
|
||||
|
||||
/**
|
||||
* LDAP schema configuration
|
||||
*
|
||||
* Parent can NOT use constants direct as we have no late static binding in currenlty required PHP 5.2
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config = array(
|
||||
'schema' => self::SCHEMA,
|
||||
'mail_enable_attr' => self::MAIL_ENABLE_ATTR,
|
||||
'mail_enabled' => self::MAIL_ENABLED,
|
||||
'alias_attr' => self::ALIAS_ATTR,
|
||||
'require_mail_as_alias' => self::REQUIRE_MAIL_AS_ALIAS,
|
||||
'forward_attr' => self::FORWARD_ATTR,
|
||||
'forward_only_attr' => self::FORWARD_ONLY_ATTR,
|
||||
'forward_only' => self::FORWARD_ONLY,
|
||||
'mailbox_attr' => self::MAILBOX_ATTR,
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* @link http://www.egroupware.org
|
||||
* @package emailadmin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2010-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -54,10 +54,6 @@ class postfixldap extends emailadmin_smtp_ldap
|
||||
* Attribute to only forward mail, OR false if not available
|
||||
*/
|
||||
const FORWARD_ONLY_ATTR = 'deliverymode';
|
||||
/**
|
||||
* Attribute value to only forward mail
|
||||
*/
|
||||
const FORWARD_ONLY = 'forwardOnly';
|
||||
|
||||
/**
|
||||
* Attribute for mailbox, to which mail gets delivered OR false if not supported
|
||||
@ -68,29 +64,4 @@ class postfixldap extends emailadmin_smtp_ldap
|
||||
* Attribute for quota limit of user in MB
|
||||
*/
|
||||
const QUOTA_ATTR = 'mailquota';
|
||||
|
||||
/**
|
||||
* Log all LDAP writes / actions to error_log
|
||||
*/
|
||||
var $debug = false;
|
||||
|
||||
/**
|
||||
* LDAP schema configuration
|
||||
*
|
||||
* Parent can NOT use constants direct as we have no late static binding in currenlty required PHP 5.2
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config = array(
|
||||
'schema' => self::SCHEMA,
|
||||
'mail_enable_attr' => self::MAIL_ENABLE_ATTR,
|
||||
'mail_enabled' => self::MAIL_ENABLED,
|
||||
'alias_attr' => self::ALIAS_ATTR,
|
||||
'require_mail_as_alias' => self::REQUIRE_MAIL_AS_ALIAS,
|
||||
'forward_attr' => self::FORWARD_ATTR,
|
||||
'forward_only_attr' => self::FORWARD_ONLY_ATTR,
|
||||
'forward_only' => self::FORWARD_ONLY,
|
||||
'mailbox_attr' => self::MAILBOX_ATTR,
|
||||
'quota_attr' => self::QUOTA_ATTR,
|
||||
);
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ include_once(EGW_SERVER_ROOT."/emailadmin/inc/class.pleskimap.inc.php");
|
||||
|
||||
class smtpplesk extends defaultsmtp
|
||||
{
|
||||
/**
|
||||
* Label shown in EMailAdmin
|
||||
*/
|
||||
const DESCRIPTION = 'Plesk (Qmail)';
|
||||
|
||||
/**
|
||||
* Capabilities of this class (pipe-separated): default, forward
|
||||
*/
|
||||
|
@ -116,7 +116,7 @@ class uiuserdata
|
||||
"style='width: 100%;' id='mailRoutingAddress'",
|
||||
5)
|
||||
);
|
||||
if (isset($userData["quotaUsed"]) && $userData["quotaUsed"]>0) $this->t->set_var('lang_qoutainmbyte',lang('qouta size in MByte').'<br><b><i>('.(int)$userData["quotaUsed"].' '.lang('MB used').')</i></b>');
|
||||
if (isset($userData["quotaUsed"]) && $userData["quotaUsed"]>0) $this->t->set_var('lang_quotainmbyte',lang('Quota size in MByte').'<br><b><i>('.(int)$userData["quotaUsed"].' '.lang('MB used').')</i></b>');
|
||||
$this->t->set_var("quotaLimit",$userData["quotaLimit"]);
|
||||
|
||||
$this->t->set_var("mailLocalAddress",$userData["mailLocalAddress"]);
|
||||
@ -209,7 +209,7 @@ class uiuserdata
|
||||
$this->t->set_var('lang_qmaildotmode',lang('qmaildotmode'));
|
||||
$this->t->set_var('lang_default',lang('default'));
|
||||
$this->t->set_var('lang_quota_settings',lang('quota settings'));
|
||||
$this->t->set_var('lang_qoutainmbyte',lang('qouta size in MByte'));
|
||||
$this->t->set_var('lang_quotainmbyte',lang('Quota size in MByte'));
|
||||
$this->t->set_var('lang_inmbyte',lang('in MByte'));
|
||||
$this->t->set_var('lang_0forunlimited',lang('leave empty for no quota'));
|
||||
$this->t->set_var('lang_forward_only',lang('forward only'));
|
||||
|
@ -79,7 +79,7 @@ var langModifyAddress="{lang_update_current_address}";
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="{tr_color2}">
|
||||
<td width="200">{lang_qoutainmbyte}</td>
|
||||
<td width="200">{lang_quotainmbyte}</td>
|
||||
<td colspan="2">
|
||||
<input name="quotaLimit" value="{quotaLimit}" style="width:350px;"> ({lang_0forunlimited})
|
||||
</td>
|
||||
|
@ -319,8 +319,7 @@ class accounts
|
||||
$account_search[$serial]['total'] = $this->total;
|
||||
}
|
||||
// search via ldap backend
|
||||
elseif ($this->config['account_repository'] == 'ldap')
|
||||
//not correct for php<5.1 elseif ((method_exists($this,'search')) // implements its on search function ==> use it
|
||||
elseif (method_exists($this->backend, 'search')) // implements its on search function ==> use it
|
||||
{
|
||||
$account_search[$serial]['data'] = $this->backend->search($param);
|
||||
$account_search[$serial]['total'] = $this->total = $this->backend->total;
|
||||
@ -443,8 +442,7 @@ class accounts
|
||||
if (($id = $this->backend->save($data)) && $data['account_type'] != 'g')
|
||||
{
|
||||
// if we are not on a pure LDAP system, we have to write the account-date via the contacts class now
|
||||
if (($this->config['account_repository'] != 'ldap' ||
|
||||
$this->config['contact_repository'] == 'sql-ldap') &&
|
||||
if (($this->config['account_repository'] == 'sql' || $this->config['contact_repository'] == 'sql-ldap') &&
|
||||
(!($old = $this->read($data['account_id'])) || // only for new account or changed contact-data
|
||||
$old['account_firstname'] != $data['account_firstname'] ||
|
||||
$old['account_lastname'] != $data['account_lastname'] ||
|
||||
@ -1018,11 +1016,11 @@ class accounts
|
||||
{
|
||||
if ($instance->get_type($account_id) == 'u')
|
||||
{
|
||||
$account['memberships'] = $instance->backend->memberships($account_id);
|
||||
if (!isset($account['memberships'])) $account['memberships'] = $instance->backend->memberships($account_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$account['members'] = $instance->backend->members($account_id);
|
||||
if (!isset($account['members'])) $account['members'] = $instance->backend->members($account_id);
|
||||
}
|
||||
egw_cache::setInstance(__CLASS__, 'account-'.$account_id, $account, self::READ_CACHE_TIMEOUT);
|
||||
}
|
||||
|
1498
phpgwapi/inc/class.accounts_ads.inc.php
Normal file
1498
phpgwapi/inc/class.accounts_ads.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -637,7 +637,7 @@ class accounts_ldap
|
||||
function search($param)
|
||||
{
|
||||
//echo "<p>accounts_ldap::search(".print_r($param,true)."): ".microtime()."</p>\n";
|
||||
$account_search = &$this->cache['account_search'];
|
||||
$account_search =& accounts::$cache['account_search'];
|
||||
|
||||
// check if the query is cached
|
||||
$serial = serialize($param);
|
||||
@ -918,7 +918,7 @@ class accounts_ldap
|
||||
if ($which == 'account_lid' && $account_type !== 'u') // groups only support account_lid
|
||||
{
|
||||
|
||||
$sri = ldap_search($this->ds, $this->group_context, '(&(cn=' . $name . ')(objectclass=posixgroup))');
|
||||
$sri = ldap_search($this->ds, $this->group_context, '(&(cn=' . $name . ')(objectclass=posixgroup))', array('gidNumber'));
|
||||
$allValues = ldap_get_entries($this->ds, $sri);
|
||||
|
||||
if (@$allValues[0]['gidnumber'][0])
|
||||
@ -935,7 +935,7 @@ class accounts_ldap
|
||||
return False;
|
||||
}
|
||||
|
||||
$sri = ldap_search($this->ds, $this->user_context, '(&('.$to_ldap[$which].'=' . $name . ')(objectclass=posixaccount))');
|
||||
$sri = ldap_search($this->ds, $this->user_context, '(&('.$to_ldap[$which].'=' . $name . ')(objectclass=posixaccount))', array('uidNumber'));
|
||||
|
||||
$allValues = ldap_get_entries($this->ds, $sri);
|
||||
|
||||
|
@ -36,42 +36,22 @@ class auth_ads implements auth_backend
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!$ldap = @ldap_connect($GLOBALS['egw_info']['server']['ads_host']))
|
||||
{
|
||||
//echo "<p>Failed connecting to ADS server '".$GLOBALS['egw_info']['server']['ads_host']."' for authenication, execution stopped</p>\n";
|
||||
$GLOBALS['egw']->log->message('F-Abort, Failed connecting to ADS server for authenication, execution stopped');
|
||||
$GLOBALS['egw']->log->commit();
|
||||
return False;
|
||||
}
|
||||
//echo "<p>Connected to LDAP server '".$GLOBALS['egw_info']['server']['ads_host']."' for authenication</p>\n";
|
||||
|
||||
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
$adldap = accounts_ads::get_adldap();
|
||||
// bind with username@ads_domain, only if a non-empty password given, in case anonymous search is enabled
|
||||
if(empty($passwd) || !@ldap_bind($ldap,$username.'@'.$GLOBALS['egw_info']['server']['ads_domain'],$passwd))
|
||||
if(empty($passwd) || !$adldap->authenticate($username, $passwd))
|
||||
{
|
||||
//echo "<p>Cant bind with '$username@".$GLOBALS['egw_info']['server']['ads_domain']."' with PW '$passwd' !!!</p>\n";
|
||||
//error_log(__METHOD__."('$username', ".(empty($passwd) ? "'') passwd empty" : '$passwd) adldap->authenticate() returned false')." --> returning false");
|
||||
return False;
|
||||
}
|
||||
//echo "<p>Bind with '$username@".$GLOBALS['egw_info']['server']['ads_domain']."' with PW '$passwd'.</p>\n";
|
||||
|
||||
$attributes = array('samaccountname','givenName','sn','mail','homeDirectory');
|
||||
$filter = "(samaccountname=$username)";
|
||||
// automatic create dn from domain: domain.com ==> DC=domain,DC=com
|
||||
$base_dn = array();
|
||||
foreach(explode('.',$GLOBALS['egw_info']['server']['ads_domain']) as $dc)
|
||||
if (($allValues = $adldap->user()->info($username, $attributes)))
|
||||
{
|
||||
$base_dn[] = 'DC='.$dc;
|
||||
$allValues[0]['objectsid'][0] = $adldap->utilities()->getTextSID($allValues[0]['objectsid'][0]);
|
||||
}
|
||||
$base_dn = implode(',',$base_dn);
|
||||
//error_log(__METHOD__."('$username', \$passwd) allValues=".array2string($allValues));
|
||||
|
||||
//echo "<p>Trying ldap_search(,$base_dn,$filter,".print_r($attributes,true)."</p>\n";
|
||||
$sri = ldap_search($ldap, $base_dn, $filter, $attributes);
|
||||
$allValues = ldap_get_entries($ldap, $sri);
|
||||
//_debug_array($allValues);
|
||||
|
||||
if ($allValues['count'] > 0)
|
||||
if ($allValues && $allValues['count'] > 0)
|
||||
{
|
||||
if($GLOBALS['egw_info']['server']['case_sensitive_username'] == true)
|
||||
{
|
||||
@ -92,6 +72,8 @@ class auth_ads implements auth_backend
|
||||
}
|
||||
if ($GLOBALS['egw_info']['server']['auto_create_acct'])
|
||||
{
|
||||
$GLOBALS['auto_create_acct']['account_id'] = accounts_ads::sid2account_id($allValues[0]['objectsid'][0]);
|
||||
|
||||
// create a global array with all availible info about that account
|
||||
foreach(array(
|
||||
'givenname' => 'firstname',
|
||||
@ -102,6 +84,7 @@ class auth_ads implements auth_backend
|
||||
$GLOBALS['auto_create_acct'][$acct_name] =
|
||||
translation::convert($allValues[0][$ldap_name][0],'utf-8');
|
||||
}
|
||||
//error_log(__METHOD__."() \$GLOBALS[auto_create_acct]=".array2string($GLOBALS['auto_create_acct']));
|
||||
return True;
|
||||
}
|
||||
}
|
||||
@ -109,8 +92,38 @@ class auth_ads implements auth_backend
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes password
|
||||
*
|
||||
* @param string $old_passwd must be cleartext
|
||||
* @param string $new_passwd must be cleartext
|
||||
* @param int $account_id account id of user whose passwd should be changed
|
||||
* @return boolean true if password successful changed, false otherwise
|
||||
*/
|
||||
function change_password($old_passwd, $new_passwd, $_account_id=0)
|
||||
{
|
||||
if (!($adldap = accounts_ads::get_adldap()) || !($adldap->getUseSSL() || $adldap->getUseTLS()))
|
||||
{
|
||||
error_log(__METHOD__."('$old_passwd', '$new_passwd', $account_id) adldap=".array2string($adldap)." returning false");
|
||||
return false; // Cant change passwd in ADS
|
||||
}
|
||||
|
||||
if(!$account_id || $GLOBALS['egw_info']['flags']['currentapp'] == 'login')
|
||||
{
|
||||
$admin = false;
|
||||
$username = $GLOBALS['egw_info']['user']['account_lid'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$admin = true;
|
||||
$username = $GLOBALS['egw']->accounts->id2name($account_id);
|
||||
}
|
||||
// Check the old_passwd to make sure this is legal
|
||||
if(!$admin && !$adldap->authenticate($username, $old_passwd))
|
||||
{
|
||||
//error_log(__METHOD__."() old password '$old_passwd' for '$username' is wrong!");
|
||||
return false;
|
||||
}
|
||||
return $adldap->user()->password($username, $new_passwd);
|
||||
}
|
||||
}
|
||||
|
@ -193,83 +193,7 @@ class ldap
|
||||
//error_log("no ldap server info found");
|
||||
$ldapbind = @ldap_bind($this->ds, $GLOBALS['egw_info']['server']['ldap_root_dn'], $GLOBALS['egw_info']['server']['ldap_root_pw']);
|
||||
|
||||
$filter='(objectclass=*)';
|
||||
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry');
|
||||
|
||||
if(($sr = @ldap_read($this->ds, '', $filter, $justthese)))
|
||||
{
|
||||
if($info = ldap_get_entries($this->ds, $sr))
|
||||
{
|
||||
$this->ldapServerInfo = new ldapserverinfo($host);
|
||||
|
||||
$this->ldapServerInfo->setVersion($supportedLDAPVersion);
|
||||
|
||||
// check for naming contexts
|
||||
if($info[0]['namingcontexts'])
|
||||
{
|
||||
for($i=0; $i<$info[0]['namingcontexts']['count']; $i++)
|
||||
{
|
||||
$namingcontexts[] = $info[0]['namingcontexts'][$i];
|
||||
}
|
||||
$this->ldapServerInfo->setNamingContexts($namingcontexts);
|
||||
}
|
||||
|
||||
// check for ldap server type
|
||||
if($info[0]['structuralobjectclass'])
|
||||
{
|
||||
switch($info[0]['structuralobjectclass'][0])
|
||||
{
|
||||
case 'OpenLDAProotDSE':
|
||||
$ldapServerType = OPENLDAP_LDAPSERVER;
|
||||
break;
|
||||
default:
|
||||
$ldapServerType = UNKNOWN_LDAPSERVER;
|
||||
break;
|
||||
}
|
||||
$this->ldapServerInfo->setServerType($ldapServerType);
|
||||
}
|
||||
|
||||
// check for subschema entry dn
|
||||
if($info[0]['subschemasubentry'])
|
||||
{
|
||||
$subschemasubentry = $info[0]['subschemasubentry'][0];
|
||||
$this->ldapServerInfo->setSubSchemaEntry($subschemasubentry);
|
||||
}
|
||||
|
||||
// create list of supported objetclasses
|
||||
if(!empty($subschemasubentry))
|
||||
{
|
||||
$filter='(objectclass=*)';
|
||||
$justthese = array('objectClasses');
|
||||
|
||||
if($sr=ldap_read($this->ds, $subschemasubentry, $filter, $justthese))
|
||||
{
|
||||
if($info = ldap_get_entries($this->ds, $sr))
|
||||
{
|
||||
if($info[0]['objectclasses']) {
|
||||
for($i=0; $i<$info[0]['objectclasses']['count']; $i++)
|
||||
{
|
||||
$pattern = '/^\( (.*) NAME \'(\w*)\' /';
|
||||
if(preg_match($pattern, $info[0]['objectclasses'][$i], $matches))
|
||||
{
|
||||
#_debug_array($matches);
|
||||
if(count($matches) == 3)
|
||||
{
|
||||
$supportedObjectClasses[$matches[1]] = strtolower($matches[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($this->ldapServerInfo);
|
||||
}
|
||||
$this->ldapServerInfo = ldapserverinfo::get($this->ds, $host, $supportedLDAPVersion);
|
||||
$this->saveSessionData();
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
define('UNKNOWN_LDAPSERVER',0);
|
||||
define('OPENLDAP_LDAPSERVER',1);
|
||||
define('SAMBA4_LDAPSERVER',2);
|
||||
|
||||
/**
|
||||
* Class to store and retrieve information (eg. supported object classes) of a connected ldap server
|
||||
@ -140,4 +141,92 @@ class ldapserverinfo
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query given ldap connection for available information
|
||||
*
|
||||
* @param resource $ds
|
||||
* @param string $host
|
||||
* @param int $version 2 or 3
|
||||
* @return ldapserverinfo
|
||||
*/
|
||||
public static function get($ds, $host, $version=3)
|
||||
{
|
||||
$filter='(objectclass=*)';
|
||||
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname');
|
||||
if(($sr = @ldap_read($ds, '', $filter, $justthese)))
|
||||
{
|
||||
if($info = ldap_get_entries($ds, $sr))
|
||||
{
|
||||
$ldapServerInfo = new ldapserverinfo($host);
|
||||
$ldapServerInfo->setVersion($version);
|
||||
|
||||
// check for naming contexts
|
||||
if($info[0]['namingcontexts'])
|
||||
{
|
||||
for($i=0; $i<$info[0]['namingcontexts']['count']; $i++)
|
||||
{
|
||||
$namingcontexts[] = $info[0]['namingcontexts'][$i];
|
||||
}
|
||||
$ldapServerInfo->setNamingContexts($namingcontexts);
|
||||
}
|
||||
|
||||
// check for ldap server type
|
||||
if($info[0]['structuralobjectclass'])
|
||||
{
|
||||
switch($info[0]['structuralobjectclass'][0])
|
||||
{
|
||||
case 'OpenLDAProotDSE':
|
||||
$ldapServerType = OPENLDAP_LDAPSERVER;
|
||||
break;
|
||||
default:
|
||||
$ldapServerType = UNKNOWN_LDAPSERVER;
|
||||
break;
|
||||
}
|
||||
$ldapServerInfo->setServerType($ldapServerType);
|
||||
}
|
||||
if ($info[0]['vendorname'] && stripos($info[0]['vendorname'][0], 'samba') !== false)
|
||||
{
|
||||
$ldapServerInfo->setServerType(SAMBA4_LDAPSERVER);
|
||||
}
|
||||
|
||||
// check for subschema entry dn
|
||||
if($info[0]['subschemasubentry'])
|
||||
{
|
||||
$subschemasubentry = $info[0]['subschemasubentry'][0];
|
||||
$ldapServerInfo->setSubSchemaEntry($subschemasubentry);
|
||||
}
|
||||
|
||||
// create list of supported objetclasses
|
||||
if(!empty($subschemasubentry))
|
||||
{
|
||||
$filter='(objectclass=*)';
|
||||
$justthese = array('objectClasses');
|
||||
|
||||
if($sr=ldap_read($ds, $subschemasubentry, $filter, $justthese))
|
||||
{
|
||||
if($info = ldap_get_entries($ds, $sr))
|
||||
{
|
||||
if($info[0]['objectclasses']) {
|
||||
for($i=0; $i<$info[0]['objectclasses']['count']; $i++)
|
||||
{
|
||||
$pattern = '/^\( (.*) NAME \'(\w*)\' /';
|
||||
if(preg_match($pattern, $info[0]['objectclasses'][$i], $matches))
|
||||
{
|
||||
#_debug_array($matches);
|
||||
if(count($matches) == 3)
|
||||
{
|
||||
$supportedObjectClasses[$matches[1]] = strtolower($matches[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ldapServerInfo;
|
||||
}
|
||||
}
|
||||
|
@ -96,10 +96,14 @@ else
|
||||
if($_POST['delete_all'])
|
||||
{
|
||||
/* Now, clear out existing tables */
|
||||
foreach(array($GLOBALS['egw_setup']->accounts_table,$GLOBALS['egw_setup']->prefs_table,$GLOBALS['egw_setup']->acl_table,'egw_access_log') as $table)
|
||||
foreach(array($GLOBALS['egw_setup']->accounts_table,$GLOBALS['egw_setup']->acl_table,'egw_access_log') as $table)
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->delete($table,'1=1',__LINE__,__FILE__);
|
||||
}
|
||||
// keep default and forced prefs from installed apps
|
||||
$GLOBALS['egw_setup']->db->delete($GLOBALS['egw_setup']->prefs_table,'preferences_owner NOT IN (-1,-2)',__LINE__,__FILE__);
|
||||
// remove accounts from addressbook
|
||||
$GLOBALS['egw_setup']->db->delete('egw_addressbook','account_id IS NOT NULL',__LINE__,__FILE__);
|
||||
}
|
||||
/* Create the demo groups */
|
||||
$defaultgroupid = (int)$GLOBALS['egw_setup']->add_account('Default','Default','Group',False,False);
|
||||
|
@ -1004,7 +1004,7 @@ class setup
|
||||
{
|
||||
// load the configuration from the database
|
||||
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'",
|
||||
"config_name LIKE 'ads%' OR 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'];
|
||||
|
@ -245,7 +245,7 @@ however, the application may still work setup ca Tanmateix, l'aplicació encara
|
||||
if no acl records for user or any group the user is a member of setup ca Si no hi han registres ACL ni grup per a l'usuari, aleshores és membre de
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup ca Si mode_segur està activat, eGW no pot canviar determinades configuracions en temps d'execució ni tampoc podem carregar cap mòdul que no estigui carregat.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup ca Si l'aplicació no ha definit taules, seleccionant actualitzar hauria de resoldre el problema
|
||||
if using ads (active directory) authentication setup ca Si feu servir autentificació ADS (Activer Directory)
|
||||
if using ads (active directory) setup ca Si feu servir autentificació ADS (Activer Directory)
|
||||
if using ldap setup ca Si feu servir LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup ca Si utilitzeu LDAP, voleu administrar els atributs del directori personal i l'interpret d'ordres?
|
||||
if you did not receive any errors, your applications have been setup ca Si no heu rebut cap error, les aplicacions han estat
|
||||
|
@ -314,7 +314,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup cs
|
||||
if no acl records for user or any group the user is a member of setup cs Pokud nejsou ACL záznamy pro uživatele nebo libovolnou skupinu, které je členem
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup cs Pokud je zapnutý režim safe_mode, eGW nemůže za běhu měnit některá nastavení ani načítat dosud nenačtené moduly
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup cs Pokud aplikace nemá definovány tabulky, aktualizace by měla problém napravit
|
||||
if using ads (active directory) authentication setup cs Při použití ADS (Active Directory) autentikace
|
||||
if using ads (active directory) setup cs Při použití ADS (Active Directory) autentikace
|
||||
if using cas (central authentication service): setup cs Při použití CAS (Central Authentication Service):
|
||||
if using ldap setup cs Při použití LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup cs Chcete při použití LDAP spravovat atributy pro domovský adresář a loginshell?
|
||||
|
@ -14,7 +14,7 @@
|
||||
'%1' is no valid domain name! setup de '%1' ist kein gültiger Domainname!
|
||||
'%1' is not allowed as %2. arguments of option %3 !!! setup de '%1' ist nicht erlaubt als %2. Parameter für die Option %3 !!!
|
||||
'%1' must be integer setup de %1 muß ein Integer-Wert sein.
|
||||
(searching accounts and changing passwords) setup de Benutzerkonten suchen und Passwörter ändern)
|
||||
(searching accounts and changing passwords) setup de (Benutzerkonten suchen und Passwörter ändern)
|
||||
*** do not update your database via setup, as the update might be interrupted by the max_execution_time, which leaves your db in an unrecoverable state (your data is lost) !!! setup de *** Updaten Sie NICHT Ihre Datenbank via Setup, da das Update von der max_execution_time (max. Ausführungszeit für Skripte) unterbrochen werden kann. Ihre Datenbank ist dann in einem nicht mehr wiederherstellbaren Zustand (Ihre Daten sind VERLOREN)!!!
|
||||
*** you have to do the changes manualy in your php.ini (usualy in /etc on linux) in order to get egw fully working !!! setup de *** Sie müssen die Änderungen manuell in Ihrer php.ini Datei (üblicherweise in /etc unter Linux) durchführen, um EGroupware vollständig/fehlerfrei ausführen zu können!!!
|
||||
00 (disable) setup de 00 (abgeschaltet/empfohlen)
|
||||
@ -41,6 +41,7 @@ admin first name setup de Admin Vorname
|
||||
admin last name setup de Admin Nachname
|
||||
admin password setup de Admin Passwort
|
||||
admin password to header manager setup de Admin Passwort für Headerverwaltung
|
||||
admin user setup de Administrator Konto
|
||||
admin user for header manager setup de Admin Benutzer für Headerverwaltung
|
||||
admin username setup de Admin Benutzername
|
||||
admins setup de Administratoren
|
||||
@ -168,6 +169,7 @@ configuration user setup de Konfigurationsbenutzer
|
||||
configure now setup de Jetzt konfigurieren
|
||||
confirm to delete this backup? setup de Bestätigen Sie diese Datensicherung zu löschen?
|
||||
contain setup de enthält
|
||||
context to create users setup de Kontext um Benutzer anzulegen
|
||||
continue setup de Weiter
|
||||
continue to the header admin setup de Weiter zur Headerverwaltung
|
||||
convert setup de Konvertieren
|
||||
@ -243,9 +245,11 @@ domain-name setup de Domainname
|
||||
don't change, if you already stored files! you will loose them! setup de Nicht ändern, wenn Sie bereits Dateien gespeichert haben! Sie werden Sie verlieren!
|
||||
dont touch my data setup de Meine Daten nicht verändern
|
||||
download setup de Herunterladen
|
||||
easiest way under win2008r2 is to add role "active directory certificate services" and reboot. setup de Unter Win2008r2 geht das am einfachsten durch hinzufügen der Rolle "Active Directory-Zertifikatsdienste" und neu starten.
|
||||
edit current configuration setup de Gegenwärtige Konfiguration überarbeiten
|
||||
edit your existing header.inc.php setup de Bearbeiten Ihrer existierenden header.inc.php
|
||||
edit your header.inc.php setup de Bearbeiten Ihrer header.inc.php
|
||||
eg. "cn=users,dc=domain,dc=com" for ads domain "domain.com" setup de z.B. "CN=Users,DC=domain,DC=com" für die ADS Domaine "domain.com"
|
||||
eg. /egroupware or http://domain.com/egroupware, default: %1 setup de zB. /egroupware oder http://domain.com/egroupware, Vorgabe: %1
|
||||
egroupware administration manual setup de EGroupware Administrationsmanual (nur in englisch)
|
||||
egroupware api needs a database (schema) update from version %1 to %2! setup de EGroupware API benötigt eine Datenbank (Schema) Aktualisierung von Version %1 auf %2!
|
||||
@ -296,7 +300,7 @@ filesystem setup de Dateisystem
|
||||
filesystem (default) setup de Dateisystem (Vorgabe)
|
||||
force selectbox setup de Auswahl erzwingen
|
||||
give admin access to all installed apps setup de Admin Zugang zu allen installierten Anwendungen geben
|
||||
give ldap root dn and password, if you need to create an instance specific admin user, user- or group-context setup de Tragen Sie das LDAP root DN und Passwort ein, wenn Sie einen Instanzspeziefischen Adminbenutzer oder Gruppen-Kontext benötigen
|
||||
give ldap root dn and password, if you need to create an instance specific admin user, user- or group-context setup de Tragen Sie das LDAP root DN und Passwort ein, wenn Sie einen Instanzspezifischen Adminbenutzer oder Gruppen-Kontext benötigen
|
||||
gives further options setup de gibt zusätzliche Optionen
|
||||
go back setup de Zurück gehen
|
||||
go to setup de Gehen zu
|
||||
@ -326,7 +330,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup de
|
||||
if no acl records for user or any group the user is a member of setup de Wenn es keinen ACL-Eintrag für einen Benutzer oder eine Gruppe, der er angehört gibt
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup de Wenn safe_mode eingeschaltet ist, kann eGW verschiedene Einstellungen nicht mehr zur Laufzeit ändern, noch können wir nicht geladene Erweiterungen (php extensions) laden.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup de Wenn die Anwendung keine definierten Tabellen hat, wählen Sie überarbeiten. Das Problem sollte damit behoben werden.
|
||||
if using ads (active directory) authentication setup de Wenn Sie ADS (Active Directory) Authentifizierung benutzen
|
||||
if using ads (active directory) setup de Wenn Sie ADS (Active Directory) benutzen
|
||||
if using cas (central authentication service): setup de Wenn Sie CAS (Central Authentication Service) benutzen
|
||||
if using ldap setup de Wenn Sie LDAP verwenden
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup de Wenn Sie LDAP verwenden, wollen Sie Benutzerverzeichnisse und Kommandointerpreter verwalten ?
|
||||
@ -352,6 +356,7 @@ invalid argument '%1' !!! setup de Ungültiges Argument '%1' !!!
|
||||
invalid ip address setup de Ungültige IP Adresse
|
||||
invalid mcrypt algorithm/mode combination setup de Ungültige MCrypt Algorithmus/Modus Kombination
|
||||
invalid password setup de Ungültiges Passwort
|
||||
ip or url setup de IP oder URL
|
||||
is broken setup de ist kaputt
|
||||
is disabled setup de ist nicht aktiv
|
||||
is in the webservers docroot setup de ist im Dokumentenverzeichnis (Documentroot) des Webservers
|
||||
@ -364,14 +369,15 @@ ldap config setup de LDAP-Konfiguration
|
||||
ldap default homedirectory prefix (e.g. /home for /home/username) setup de LDAP-Vorgabewert für Benutzerverzeichnisse (z.B. /home für /home/username)
|
||||
ldap default shell (e.g. /bin/bash) setup de LDAP-Vorgabewert für Kommandointerpreter (shell) (z.B. /bin/bash)
|
||||
ldap dn="%1" with %2 entries deleted. setup de LDAP dn="%1" mit %2 Einträgen gelöscht.
|
||||
ldap encryption type setup de LDAP-Verschlüsselungstyp
|
||||
ldap groups context setup de LDAP-Kontext für Gruppe
|
||||
ldap host setup de LDAP-Host
|
||||
ldap import setup de LDAP-Import
|
||||
ldap root password setup de LDAP-Root-Passwort
|
||||
ldap rootdn setup de LDAP rootdn
|
||||
ldap encryption type setup de LDAP Verschlüsselungstyp
|
||||
ldap groups context setup de LDAP Kontext für Gruppe
|
||||
ldap host setup de LDAP Host
|
||||
ldap import setup de LDAP Import
|
||||
ldap root password setup de LDAP Root Passwort
|
||||
ldap rootdn setup de LDAP Root DN
|
||||
ldap search filter for accounts, default: "(uid=%user)", %domain=egw-domain setup de LDAP Suchfilter für Benutzerkonten, Vorgabe "(uid=%user)", %domain=eGW Domain
|
||||
leave empty to keep current. setup de Leer lassen um das existierende Password zu behalten.
|
||||
leave empty to use default setup de leer lassen um Standard zu benutzen
|
||||
limit access setup de Zugang beschränken
|
||||
limit access to setup to the following addresses, networks or hostnames (e.g. 127.0.0.1,10.1.1,myhost.dnydns.org) setup de Zugang zu Setup auf die folgenden IP Adressen, Netzwerke oder Hostnamen beschränken (z.B. 127.0.0.1,10.1.1,myhost.dnydns.org)
|
||||
list availible values setup de Listen der verfügbaren Werte
|
||||
@ -410,6 +416,7 @@ mount backup directory to %1 setup de Datensicherungsverzeichnis unter %1 mounte
|
||||
multi-language support setup setup de Mehr-Sprachen Unterstützung einrichten
|
||||
name of database setup de Name der Datenbank
|
||||
name of db user egroupware uses to connect setup de Name des Datenbank-Benutzers den EGroupware verwendet
|
||||
needs extra configuration on dc and webserver! setup de Benötigt extra Konfiguration auf Domain Controller und Webserver!
|
||||
never setup de niemals
|
||||
new setup de Neu
|
||||
next run setup de nächste Ausführung
|
||||
@ -439,6 +446,7 @@ one month setup de ein Monat
|
||||
one week setup de eine Woche
|
||||
only add languages that are not in the database already setup de Nur Sprachen hinzufügen, die noch nicht in der Datenbank sind
|
||||
only add new phrases setup de Nur neue Begriffe hinzufügen
|
||||
optional, if only authentication and anonymous search is enabled setup de optional, wenn nur Authentifizierung UND anonymes Suchen erlaubt ist
|
||||
or setup de oder
|
||||
or %1continue to the header admin%2 setup de oder %1mit der Headerverwaltung weiter machen%2
|
||||
or http://webdav.domain.com (webdav) setup de oder http://webdav.domain.com (für WebDAV)
|
||||
@ -495,6 +503,8 @@ rejected lines setup de Zurückgewiesene Zeilen
|
||||
remove setup de Entfernen
|
||||
remove all setup de Alle Entfernen
|
||||
rename setup de Umbenennen
|
||||
required to change passwords setup de erforderlich um Passwörter zu ändern
|
||||
requires "reset password" privilege, to change passwords! setup de Benötigt "Passwort zurücksetzen" Recht, um Passwörter zu ändern!
|
||||
requires reinstall or manual repair setup de Erfordert Neuinstallation oder manuelle Reparatur
|
||||
requires upgrade setup de Erfordert Aktualisierung
|
||||
resolve setup de Lösen
|
||||
@ -647,6 +657,8 @@ use cookies to pass sessionid setup de SitzungsId in einem Cookie speichern
|
||||
use mcrypt to crypt session-data: {off(default) | on},[mcrypt-init-vector(default randomly generated)],[mcrypt-version] setup de benutze mcrypt zur Verschlüsselung der Sitzungsdaten: {off(Vorgabe) | on},[mcrypt Initialisierung(Vorgabe ist zufällig erzeugt)],[mcrypt Version]
|
||||
use persistent db connections: {on(default) | off} setup de benutze permanente Datenbankverbindung: {on(Vorgabe) | off}
|
||||
use pure html compliant code (not fully working yet) setup de Vollständig HTML kompatiblen Code verwenden (nicht vollständig implementiert)
|
||||
use space to separate multiple setup de Leerzeichen benutzen um mehrere anzugeben
|
||||
use tls or ssl encryption setup de Benutze TLS oder SSL Verschlüsselung
|
||||
user setup de Benutzer
|
||||
user account prefix setup de Präfix für Benutzernamen
|
||||
user for smtp-authentication (leave it empty if no auth required) setup de Benutzer für SMTP-Authentifizierung (leer lassen wenn keine notwendig ist)
|
||||
|
@ -41,6 +41,7 @@ admin first name setup en Admin first name
|
||||
admin last name setup en Admin last name
|
||||
admin password setup en Admin password
|
||||
admin password to header manager setup en Admin password to header manager
|
||||
admin user setup en Admin user
|
||||
admin user for header manager setup en Admin user for header manager
|
||||
admin username setup en Admin username
|
||||
admins setup en Admins
|
||||
@ -168,6 +169,7 @@ configuration user setup en Configuration user
|
||||
configure now setup en Configure now
|
||||
confirm to delete this backup? setup en Confirm to delete this backup?
|
||||
contain setup en Contain
|
||||
context to create users setup en Context to create users
|
||||
continue setup en Continue
|
||||
continue to the header admin setup en Continue to the Header Admin
|
||||
convert setup en Convert
|
||||
@ -243,9 +245,11 @@ domain-name setup en Domain name
|
||||
don't change, if you already stored files! you will loose them! setup en Don't change, if you already stored files! You will loose them!
|
||||
dont touch my data setup en Don't touch my data
|
||||
download setup en Download
|
||||
easiest way under win2008r2 is to add role "active directory certificate services" and reboot. setup en Easiest way under win2008r2 is to add role "Active Directory Certificate Services" and reboot.
|
||||
edit current configuration setup en Edit current configuration
|
||||
edit your existing header.inc.php setup en Edit your existing header.inc.php
|
||||
edit your header.inc.php setup en Edit your header.inc.php
|
||||
eg. "cn=users,dc=domain,dc=com" for ads domain "domain.com" setup en eg. "CN=Users,DC=domain,DC=com" for ADS domain "domain.com"
|
||||
eg. /egroupware or http://domain.com/egroupware, default: %1 setup en eg. /egroupware or http://domain.com/egroupware, default: %1
|
||||
egroupware administration manual setup en EGroupware administration manual
|
||||
egroupware api needs a database (schema) update from version %1 to %2! setup en EGroupware API needs a database (schema) update from version %1 to %2!
|
||||
@ -327,7 +331,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup en
|
||||
if no acl records for user or any group the user is a member of setup en If no ACL records for user or any group the user is a member of
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup en If safe_mode is turned on, eGW is not able to change certain settings on runtime, nor can we load any not yet loaded module.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup en If the application has no defined tables, selecting upgrade should remedy the problem
|
||||
if using ads (active directory) authentication setup en If using ADS (Active Directory) authentication
|
||||
if using ads (active directory) setup en If using ADS (Active Directory) authentication
|
||||
if using cas (central authentication service): setup en if using cas (Central Authentication Service):
|
||||
if using ldap setup en If using LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup en If using LDAP, do you want to manage home directory and login shell attributes?
|
||||
@ -353,6 +357,7 @@ invalid argument '%1' !!! setup en Invalid argument '%1' !
|
||||
invalid ip address setup en Invalid IP address!
|
||||
invalid mcrypt algorithm/mode combination setup en Invalid Mcrypt Algorithm/Mode combination
|
||||
invalid password setup en Invalid password!
|
||||
ip or url setup en IP or URL
|
||||
is broken setup en is broken
|
||||
is disabled setup en is disabled
|
||||
is in the webservers docroot setup en is in the web servers docroot
|
||||
@ -373,6 +378,7 @@ ldap root password setup en LDAP root password
|
||||
ldap rootdn setup en LDAP rootdn
|
||||
ldap search filter for accounts, default: "(uid=%user)", %domain=egw-domain setup en LDAP search filter for accounts, default: "(uid=%user)", %domain=eGW-domain
|
||||
leave empty to keep current. setup en Leave empty to keep current.
|
||||
leave empty to use default setup en leave empty to use default
|
||||
limit access setup en Limit access
|
||||
limit access to setup to the following addresses, networks or hostnames (e.g. 127.0.0.1,10.1.1,myhost.dnydns.org) setup en Limit access to setup to the following addresses, networks or host names (e.g. 127.0.0.1,10.1.1,myhost.dnydns.org)
|
||||
list availible values setup en List available values
|
||||
@ -411,6 +417,7 @@ mount backup directory to %1 setup en Mount backup directory to %1
|
||||
multi-language support setup setup en Multi language support setup
|
||||
name of database setup en Name of database
|
||||
name of db user egroupware uses to connect setup en Name of db user EGroupware uses to connect
|
||||
needs extra configuration on dc and webserver! setup en Needs extra configuration on DC and webserver!
|
||||
never setup en Never
|
||||
new setup en New
|
||||
next run setup en Next run
|
||||
@ -440,6 +447,7 @@ one month setup en One month
|
||||
one week setup en One week
|
||||
only add languages that are not in the database already setup en Only add languages that are not in the database already
|
||||
only add new phrases setup en Only add new phrases
|
||||
optional, if only authentication and anonymous search is enabled setup en optional, if only authentication AND anonymous search is enabled
|
||||
or setup en or
|
||||
or %1continue to the header admin%2 setup en or %1Continue to the Header Admin%2
|
||||
or http://webdav.domain.com (webdav) setup en or http://webdav.domain.com (WebDAV)
|
||||
@ -496,6 +504,8 @@ rejected lines setup en Rejected lines
|
||||
remove setup en Remove
|
||||
remove all setup en Remove all
|
||||
rename setup en Rename
|
||||
required to change passwords setup en required to change passwords
|
||||
requires "reset password" privilege, to change passwords! setup en Requires "Reset Password" privilege, to change passwords!
|
||||
requires reinstall or manual repair setup en Requires reinstall or manual repair
|
||||
requires upgrade setup en Requires upgrade
|
||||
resolve setup en Resolve
|
||||
@ -648,6 +658,8 @@ use cookies to pass sessionid setup en Use cookies to pass session ID
|
||||
use mcrypt to crypt session-data: {off(default) | on},[mcrypt-init-vector(default randomly generated)],[mcrypt-version] setup en Use mcrypt to crypt session-data: {off(default) | on},[mcrypt-init-vector(default randomly generated)],[mcrypt-version]
|
||||
use persistent db connections: {on(default) | off} setup en Use persistent db connections: {on(default) | off}
|
||||
use pure html compliant code (not fully working yet) setup en Use pure HTML compliant code
|
||||
use space to separate multiple setup en use space to separate multiple
|
||||
use tls or ssl encryption setup en Use TLS or SSL encryption
|
||||
user setup en User
|
||||
user account prefix setup en User account prefix
|
||||
user for smtp-authentication (leave it empty if no auth required) setup en User for SMTP-authentication (leave it empty if no auth required)
|
||||
|
@ -317,7 +317,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup es
|
||||
if no acl records for user or any group the user is a member of setup es-es Si no hay registros ACL ni grupo para el usuario, entonces es miembro de
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup es-es Si está activado safe_mode, eGW no puede cambiar ciertas opciones en modo de ejecución, ni puede cargar ningún módulo que aún no sea cargable.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup es-es Si la aplicación no ha definido tablas, seleccionando actualizar debería de remediar el problemas
|
||||
if using ads (active directory) authentication setup es-es Si se usa identificación del Directorio Activo
|
||||
if using ads (active directory) setup es-es Si se usa identificación del Directorio Activo
|
||||
if using cas (central authentication service): setup es-es Si se usa CAS (Sistema de identificación centralizado):
|
||||
if using ldap setup es-es Si usa LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup es-es Si usa LDAP ¿desea administrar los atributos del directorio personal y línea de comandos?
|
||||
|
@ -110,7 +110,7 @@ grant access setup et Luba Ligipääs
|
||||
group setup et grupp
|
||||
host information setup et Hosti informatsioon
|
||||
hostname/ip of database server setup et Hostinimi/IP või andmebaasi server
|
||||
if using ads (active directory) authentication setup et kui kasutad ADS (Active Directory) audentimist
|
||||
if using ads (active directory) setup et kui kasutad ADS (Active Directory) audentimist
|
||||
if using ldap setup et kui kasutad LDAP
|
||||
image type selection order setup et Piltide tüübi sisestamise järjekord
|
||||
import has been completed! setup et Importimine on lõpetatud!
|
||||
|
@ -214,7 +214,7 @@ however, the application may still work setup fa کاربرد ممکن از هن
|
||||
if no acl records for user or any group the user is a member of setup fa اگر هیچ لیست حق دسترسی برای کاربر یا هیچ گروهی نباشد کابر عضوی خواهد بود از
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup fa اگر safe_mode روشن باشد، گروه افزار نمی تواند تغییرات را در زمان اجرا اعمال کند و همچنین نمی توانیم پیمانه های بارگذاری نشده را بارگذاری کنیم
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup fa اگر کاربرد جداول تعریف شده ای نداشته باشد
|
||||
if using ads (active directory) authentication setup fa اگر از تصدیق بر اساس ADS(Active Directory) استفاده میکنید
|
||||
if using ads (active directory) setup fa اگر از تصدیق بر اساس ADS(Active Directory) استفاده میکنید
|
||||
if using ldap setup fa اگر از LDAP استفاده می کنید
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup fa اگر از LDAP استفاده می کنید ، آیا می خواهید مشخصات پوشه خانه و پوسته ورود را تنظیم نمائید؟
|
||||
if you did not receive any errors, your applications have been setup fa اگر شما هیچ پیام خطائی دریافت نکردید کاربرد شما
|
||||
|
@ -281,7 +281,7 @@ however, the application may still work setup fi Sovellus voi toimia tästä huo
|
||||
if no acl records for user or any group the user is a member of setup fi Jos käyttäjällä tai käyttäjän ryhmillä ei ole ACL-tietueita, käyttäjä on tämän ryhmän jäsen:
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup fi Jos safe_mode on päällä, eGW ei voi muuttaa kaikkia asetuksia ajon aikana, eikä ladata uusia moduuleita.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup fi Jos sovelluksella ei ole määriteltyjä tauluja, päivittämisen pitäisi korjata ongelma
|
||||
if using ads (active directory) authentication setup fi Jos käytetään ADS (Active Directory) -tunnistusta
|
||||
if using ads (active directory) setup fi Jos käytetään ADS (Active Directory) -tunnistusta
|
||||
if using cas (central authentication service): setup fi Jos käytetään CAS (Central Authentication Service):
|
||||
if using ldap setup fi Jos käytetään LDAP-tunnistusta
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup fi Jos käytät LDAP-tunnistusta, haluatko hallita kotihakemisto- ja shellattribuutteja?
|
||||
|
@ -279,7 +279,7 @@ however, the application may still work setup fr Malgré tout l'application pour
|
||||
if no acl records for user or any group the user is a member of setup fr Si aucun enregistrement d'ACL pour un utilisateur ou groupe l'utilisateur est un membre de
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup fr Si safe_mode est activé, eGroupWare sera incapable de modifier certaines options ou d'activer certains modules.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup fr Si l'application n'a pas défini de tables, choisir mise à jour devrait résoudre le problème
|
||||
if using ads (active directory) authentication setup fr Si vous utilisez l'authentification ADS (Active Directory)
|
||||
if using ads (active directory) setup fr Si vous utilisez l'authentification ADS (Active Directory)
|
||||
if using cas (central authentication service): setup fr Si vous utilisez l'authentification CAS (Central Authentication Service) :
|
||||
if using ldap setup fr Si vous utilisez LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup fr Si vous utilisez LDAP, voulez-vous gérer les attributs répertoire d'accueil et shell de connexion?
|
||||
|
@ -183,7 +183,7 @@ hostname/ip of database server setup lv Datubāzes zrvera hostvārds/IP
|
||||
hour (0-24) setup lv stundas (0-24)
|
||||
however, the application may still work setup lv Kaut gan aplikācija joprojām var strādāt
|
||||
if no acl records for user or any group the user is a member of setup lv Ja nav ACL ierakstu lietotājam vai kādai grupai, lietotājs pieder
|
||||
if using ads (active directory) authentication setup lv Ja lieto ADS (aktīvā direktorija) autentifikāciju
|
||||
if using ads (active directory) setup lv Ja lieto ADS (aktīvā direktorija) autentifikāciju
|
||||
if using ldap setup lv Ja lieto LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup lv Ja lieto LDAP, vai vēlies pārvaldīt mājasdirektoriju un pieteikuma ailes atribūtus?
|
||||
if you did not receive any errors, your applications have been setup lv Ja nesaņēmi kļūdu paziņojumus, tava aplikācija ir
|
||||
|
@ -296,7 +296,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup nl
|
||||
if no acl records for user or any group the user is a member of setup nl Als er ACL records voor de gebruiker of een willekeurige groep zijn is de gebruiker lid van
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup nl Indien safe_mode ingeschakeld is kan eGW bepaalde instellingen niet tijdens runtime wijzen, bovendien kunnen we geen enkele nog niet geladen module laden.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup nl Indien de toepassing geen tabellen heeft gedefinieerd is het kiezen voor upgrade de oplossing voor dit problemen
|
||||
if using ads (active directory) authentication setup nl Indien ADS (Active Directory) authenticatie gebruikt wordt
|
||||
if using ads (active directory) setup nl Indien ADS (Active Directory) authenticatie gebruikt wordt
|
||||
if using cas (central authentication service): setup nl indien cas gebruikt wordt (Centrale Authenticatie Service)
|
||||
if using ldap setup nl Indien LDAP gebruikt wordt
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup nl Indien LDAP gebruikt wordt, wilt u dan de homedirectory en loginshell attributen beheren?
|
||||
|
@ -199,7 +199,7 @@ however, the application may still work setup no Det kan hende programmet fortsa
|
||||
if no acl records for user or any group the user is a member of setup no Om inga åtkomstregler finns för användaren eller de grupper användaren är medlem av
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup no Om Safe Mode är aktiverat kan inte eGW ändra vissa inställningar medans den kör, eller ladda en modul som inte redan är laddad.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup no Om applikationen saknar definerade tabeller bör du välja att uppgradera den.
|
||||
if using ads (active directory) authentication setup no Dersom det benyttes ADS (Active Directory) autentisering.
|
||||
if using ads (active directory) setup no Dersom det benyttes ADS (Active Directory) autentisering.
|
||||
if using ldap setup no Om LDAP används
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup no Om LDAP används, vill du hantera attribut för hemktalog och programskal?
|
||||
if you did not receive any errors, your applications have been setup no Om du inte såg några fel så har dina applikationer blivit
|
||||
|
@ -314,7 +314,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup pl
|
||||
if no acl records for user or any group the user is a member of setup pl Jeśli brak uprawnień dostępu (ACL) dla użytkownika lub jakiejkolwiek grupy, której użytkownik jest członkiem
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup pl Jeśli tryb bezpieczny (safe_mode) jest aktywny, eGW nie może zmieniać różnych ustawień poprzez runtime ani nie można załadować do tej pory niezaładowanych modułów.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup pl Jeśli aplikacja nie ma zdefiniowanych tabel, wybór aktualizacji rozwiąże problem.
|
||||
if using ads (active directory) authentication setup pl Jeśli używana autoryzacja ADS (Active Directory)
|
||||
if using ads (active directory) setup pl Jeśli używana autoryzacja ADS (Active Directory)
|
||||
if using cas (central authentication service): setup pl Jeśli używany CAS (Central Authentication Service):
|
||||
if using ldap setup pl Jeśli używany LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup pl Jeżeli używasz LDAP, czy chciałbyś administrować katalogiem domowym i atrybutami powłoki?
|
||||
|
@ -289,7 +289,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup pt
|
||||
if no acl records for user or any group the user is a member of setup pt-br Caso não exista registro de permissões ou grupo para o usuário ele é membro do
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup pt-br Se o modo de segurança estiver ligado, o eGroupware não será capaz de modificar automáticamente determinados valores de configuração, não será possível carregar módulos que ainda não estejam carregados.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup pt-br Se o aplicativo não têm tabelas definidas, selecionar atualizar deve resolver o problema
|
||||
if using ads (active directory) authentication setup pt-br Se estiver usando autenticação por ADS (Active Directory)
|
||||
if using ads (active directory) setup pt-br Se estiver usando autenticação por ADS (Active Directory)
|
||||
if using ldap setup pt-br Se estiver usando LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup pt-br Se estiver usando LDAP, você deseja definir atributos de diretório base e do interpretador de comandos?
|
||||
if you did not receive any errors, your applications have been setup pt-br Se não foi exibido nenhum erro, suas aplicações foram
|
||||
|
@ -212,7 +212,7 @@ however, the application may still work setup pt No entanto, a aplicação pode
|
||||
if no acl records for user or any group the user is a member of setup pt Se não existirem registos ACL do utilizador ou grupo, o utilizador é um membro de
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup pt Se o modo de segurança estiver activo, o eGroupWare não pode alterar determinadas configurações em execução, nem pode carregar módulos não carregados.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup pt Se a aplicação não tiver tabelas definidas, actualizar deve resolver o problema
|
||||
if using ads (active directory) authentication setup pt Se estiver a utilizar a autenticação ADS (Directoria Activa)
|
||||
if using ads (active directory) setup pt Se estiver a utilizar a autenticação ADS (Directoria Activa)
|
||||
if using ldap setup pt Se estiver a utilizar LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup pt Se estiver a utilizar LDAP, deseja definir atributos da directoria principal e atributos da Shell de acesso ?
|
||||
if you did not receive any errors, your applications have been setup pt Se não foi exibido nenhum erro, as suas aplicações foram
|
||||
|
@ -284,7 +284,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup ru
|
||||
if no acl records for user or any group the user is a member of setup ru Если нет записей ACL для пользователя или группы, пользователь входит в
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup ru Если безопасный режим включен, у eGW нет возможностии менять некоторые настройки при запуске так же как и нет возможности запускать любые еще не загруженные модули.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup ru Если приложение не имеет заранее определенных таблиц, выбор модернизации скорее всего вызовет ряд проблем
|
||||
if using ads (active directory) authentication setup ru Используя ADS (Active Directory) идентификацию
|
||||
if using ads (active directory) setup ru Используя ADS (Active Directory) идентификацию
|
||||
if using ldap setup ru Используя LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup ru При использовании LDAP,желаете ли вы управлять атрибутами домашних папок и параметрами входа?
|
||||
if you did not receive any errors, your applications have been setup ru Если вы не получили уведомлений об ошибках,ваше приложение успешно
|
||||
|
@ -313,7 +313,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup sk
|
||||
if no acl records for user or any group the user is a member of setup sk Ak pre používateľa neexistujú ACL záznamy, používateľom je členom
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup sk Ak je bezpečný režim zapnutý, eGW nedokáže zmeniť niektoré veci za behu, ani nahrať nejaký nenahratý modul.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup sk Ak aplikácia nemá tabuľky definícií, voľba "aktualizácia" by mala problém vyriešiť
|
||||
if using ads (active directory) authentication setup sk Ak používate ADS (ActiveDirectory) autentifikáciu
|
||||
if using ads (active directory) setup sk Ak používate ADS (ActiveDirectory) autentifikáciu
|
||||
if using cas (central authentication service): setup sk Ak používate cas (Centrálnu Autentifikačnú Službu):
|
||||
if using ldap setup sk Ak používate LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup sk Ak používate LDAP, chcete spravovať domovský adresár a atribúty login shell?
|
||||
|
@ -295,7 +295,7 @@ http auth types (comma-separated) to use without login-page, eg. "ntlm" setup sl
|
||||
if no acl records for user or any group the user is a member of setup sl Če ni ACL zapisov za uporabnika ali katerokoli skupino, katere član je
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup sl Če je vključen način "safe_mode", eGW med delovanjem ne more spremeniti nekaterih nastavitev niti ne more naložiti novih modulov.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup sl Če aplikacija nima definiranih tabel, potem bi nadgrajevanje moralo rešiti težave.
|
||||
if using ads (active directory) authentication setup sl Če uporabljate ADS (Aktivni Direktorij ) overovljenje
|
||||
if using ads (active directory) setup sl Če uporabljate ADS (Aktivni Direktorij ) overovljenje
|
||||
if using cas (central authentication service): setup sl Če uporabljate cas (Central Authentication Service):
|
||||
if using ldap setup sl Če uporabljate LDAP
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup sl Če uporabljate LDAP, ali želite upravljati domači direktorij in lastnosti prijavne lupine?
|
||||
|
@ -268,7 +268,7 @@ however, the application may still work setup sv Applikationen kanske ändå fun
|
||||
if no acl records for user or any group the user is a member of setup sv Om inga åtkomst regler finns för användaren eller de grupper användaren är medlem av
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup sv Om Safe Mode är aktiverat kan inte eGW ändra vissa inställningar medans den kör, eller ladda en modul som inte redan är laddad.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup sv Om applikationen saknar definerade tabeller bör du välja att uppgradera den.
|
||||
if using ads (active directory) authentication setup sv Om AD (Active Directory) autenticering används
|
||||
if using ads (active directory) setup sv Om AD (Active Directory) autenticering används
|
||||
if using ldap setup sv Om LDAP används
|
||||
if using ldap, do you want to manage homedirectory and loginshell attributes? setup sv Om LDAP används, vill du hantera attribut för hemktalog och programskal?
|
||||
if you did not receive any errors, your applications have been setup sv Om du inte såg några fel så har dina applikationer blivit
|
||||
|
@ -276,7 +276,7 @@
|
||||
<select name="newsettings[account_repository]">
|
||||
<option value="sql"{selected_account_repository_sql}>SQL</option>
|
||||
<option value="ldap"{selected_account_repository_ldap}>LDAP</option>
|
||||
<!--<option value="contacts"{selected_account_repository_contacts}>Contacts - EXPERIMENTAL</option>-->
|
||||
<option value="ads"{selected_account_repository_ads}>Active Directory</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@ -396,7 +396,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<tr class="row_off">
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
|
||||
@ -405,8 +405,11 @@
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<td>{lang_LDAP_host}:</td>
|
||||
<td><input name="newsettings[ldap_host]" value="{value_ldap_host}" /></td>
|
||||
<td>
|
||||
{lang_LDAP_host} {lang_IP_or_URL}: (ldap|ldaps|tls)://IP[:port]/<br/>
|
||||
({lang_use_space_to_separate_multiple}):
|
||||
</td>
|
||||
<td><input name="newsettings[ldap_host]" value="{value_ldap_host}" size="40" /></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
@ -479,11 +482,65 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
|
||||
<tr class="th">
|
||||
<td colspan="2"><b>{lang_If_using_ADS_(Active_Directory)}:</b></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>{lang_Host/IP_Domain_controler} ({lang_use_space_to_separate_multiple}):</td>
|
||||
<td><input name="newsettings[ads_host]" value="{value_ads_host}" size="40" /></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>{lang_Domain_name}:</td>
|
||||
<td><input name="newsettings[ads_domain]" value="{value_ads_domain}" size="40" /></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>
|
||||
{lang_Admin_user}:<br/>
|
||||
({lang_optional,_if_only_authentication_AND_anonymous_search_is_enabled})<br/>
|
||||
{lang_Requires_"Reset_Password"_privilege,_to_change_passwords!}
|
||||
</td>
|
||||
<td><input name="newsettings[ads_admin_user]" value="{value_ads_admin_user}" size="40" /></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>{lang_Password}:</td>
|
||||
<td><input type="password" name="newsettings[ads_admin_passwd]" value="{value_ads_admin_passwd}" size="40" /></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>
|
||||
{lang_Use_TLS_or_SSL_encryption} ({lang_required_to_change_passwords}):<br/>
|
||||
{lang_Needs_extra_configuration_on_DC_and_webserver!}<br/>
|
||||
({lang_Easiest_way_under_win2008r2_is_to_add_role_"Active_Directory_Certificate_Services"_and_reboot.})
|
||||
</td>
|
||||
<td>
|
||||
<select name="newsettings[ads_connection]">
|
||||
<option value="">{lang_No}</option>
|
||||
<option value="tls"{selected_ads_connection_tls}>TLS</option>
|
||||
<option value="ssl"{selected_ads_connection_ssl}>SSL</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>
|
||||
{lang_Context_to_create_users}:<br/>
|
||||
{lang_eg._"CN=Users,DC=domain,DC=com"_for_ADS_domain_"domain.com"}<br/>
|
||||
({lang_leave_empty_to_use_default})
|
||||
</td>
|
||||
<td><input name="newsettings[ads_context]" value="{value_ads_context}" size="80" /></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
|
||||
<tr class="th">
|
||||
<td colspan="2"><b>{lang_If_using_CAS_(Central_Authentication_Service):}</b></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<tr class="row_on">
|
||||
<td>{lang_CAS_server_host_name:<br />Example:_sso-cas.univ-rennes1.fr}</td>
|
||||
<td><input name="newsettings[cas_server_host_name]" value="{value_cas_server_host_name}" size="40" /></td>
|
||||
</tr>
|
||||
@ -493,7 +550,7 @@
|
||||
<td><input name="newsettings[cas_server_port]" value="{value_cas_server_port}" size="40" /></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<tr class="row_on">
|
||||
<td>{lang_CAS_server_uri:}</td>
|
||||
<td><input name="newsettings[cas_server_uri]" value="{value_cas_server_uri}" size="40" /></td>
|
||||
</tr>
|
||||
@ -508,7 +565,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<tr class="row_on">
|
||||
<td>{lang_SSL_validation:}</td>
|
||||
<td>
|
||||
<select name="newsettings[cas_ssl_validation]">
|
||||
@ -528,18 +585,6 @@
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
|
||||
<tr class="th">
|
||||
<td colspan="2"><b>{lang_If_using_ADS_(Active_Directory)_authentication}:</b></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>{lang_Host/IP_Domain_controler}:</td>
|
||||
<td><input name="newsettings[ads_host]" value="{value_ads_host}" size="40" /></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>{lang_Domain_name}:</td>
|
||||
<td><input name="newsettings[ads_domain]" value="{value_ads_domain}" size="40" /></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
|
Loading…
Reference in New Issue
Block a user