mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-11 16:38:39 +01:00
backport of Univention support to 14.1:
r49257: support for Univention LDAP schemas r49263: mail plugin for UCS r49274: UCS mail plugin: fix typo in name of alias attribute, quota in MB and reading of enabled attribute r49275: setting sambaPrimaryGroupSID and univentionObject with univentionObjectType r49276: automatic install in UCS enviroment r49298: setting univentionMailHomeServer attribute to trigger directory listener to create INBOX and create configured folders in mail app r49299: using univention-directory-manager cli to create not accounts to get Kerberos stuff addded
This commit is contained in:
commit
01e85bcee9
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
if (php_sapi_name() !== 'cli') // security precaution: forbit calling post_install as web-page
|
if (php_sapi_name() !== 'cli') // security precaution: forbit calling post_install as web-page
|
||||||
{
|
{
|
||||||
die('<h1>rpm_post_install.php must NOT be called as web-page --> exiting !!!</h1>');
|
die('<h1>post_install.php must NOT be called as web-page --> exiting !!!</h1>');
|
||||||
}
|
}
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
$config = array(
|
$config = array(
|
||||||
@ -55,6 +55,8 @@ $config = array(
|
|||||||
'ldap_context' => 'ou=accounts,$base',
|
'ldap_context' => 'ou=accounts,$base',
|
||||||
'ldap_search_filter' => '(uid=%user)',
|
'ldap_search_filter' => '(uid=%user)',
|
||||||
'ldap_group_context' => 'ou=groups,$base',
|
'ldap_group_context' => 'ou=groups,$base',
|
||||||
|
'ldap_encryption_type' => '',
|
||||||
|
'sambaadmin/sambaSID'=> '', // SID for sambaadmin
|
||||||
'mailserver' => '',
|
'mailserver' => '',
|
||||||
'smtpserver' => 'localhost,25',
|
'smtpserver' => 'localhost,25',
|
||||||
'smtp' => '', // see setup-cli.php --help config
|
'smtp' => '', // see setup-cli.php --help config
|
||||||
@ -88,8 +90,11 @@ function set_distro_defaults($distro=null)
|
|||||||
global $config;
|
global $config;
|
||||||
if (is_null($distro))
|
if (is_null($distro))
|
||||||
{
|
{
|
||||||
$distro = file_exists('/etc/SuSE-release') ? 'suse' : (file_exists('/etc/debian_version') ? 'debian' :
|
$distro = file_exists('/etc/SuSE-release') ? 'suse' :
|
||||||
(file_exists('/etc/mandriva-release') ? 'mandriva' : 'rh'));
|
(file_exists('/etc/mandriva-release') ? 'mandriva' :
|
||||||
|
(file_exists('/etc/lsb-release') && preg_match('/^DISTRIB_ID="Univention"$/mi',
|
||||||
|
file_get_contents('/etc/lsb-release')) ? 'univention' :
|
||||||
|
(file_exists('/etc/debian_version') ? 'debian' : 'rh')));
|
||||||
}
|
}
|
||||||
switch (($config['distro'] = $distro))
|
switch (($config['distro'] = $distro))
|
||||||
{
|
{
|
||||||
@ -141,6 +146,9 @@ function set_distro_defaults($distro=null)
|
|||||||
$config['ldap_context'] = 'ou=People,$base';
|
$config['ldap_context'] = 'ou=People,$base';
|
||||||
$config['ldap_group_context'] = 'ou=Group,$base';
|
$config['ldap_group_context'] = 'ou=Group,$base';
|
||||||
break;
|
break;
|
||||||
|
case 'univention':
|
||||||
|
set_univention_defaults();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$config['distro'] = 'rh';
|
$config['distro'] = 'rh';
|
||||||
// fall through
|
// fall through
|
||||||
@ -293,6 +301,7 @@ if (!file_exists($config['header']) || filesize($config['header']) < 200) // def
|
|||||||
foreach(array(
|
foreach(array(
|
||||||
'domain','ldap_suffix','ldap_host','ldap_admin','ldap_admin_pw', // non-egw params: only used for create
|
'domain','ldap_suffix','ldap_host','ldap_admin','ldap_admin_pw', // non-egw params: only used for create
|
||||||
'ldap_base','ldap_root_dn','ldap_root_pw','ldap_context','ldap_search_filter','ldap_group_context', // egw params
|
'ldap_base','ldap_root_dn','ldap_root_pw','ldap_context','ldap_search_filter','ldap_group_context', // egw params
|
||||||
|
'ldap_encryption_type', 'sambaadmin/sambaSID',
|
||||||
) as $name)
|
) as $name)
|
||||||
{
|
{
|
||||||
if (strpos($value=$config[$name],'$') !== false)
|
if (strpos($value=$config[$name],'$') !== false)
|
||||||
@ -551,7 +560,7 @@ function usage($error=null)
|
|||||||
foreach($config as $name => $default)
|
foreach($config as $name => $default)
|
||||||
{
|
{
|
||||||
if (in_array($name, array('postfix','cyrus'))) continue; // do NOT report deprecated options
|
if (in_array($name, array('postfix','cyrus'))) continue; // do NOT report deprecated options
|
||||||
if (in_array($name,array('config_passwd','db_pass','admin_passwd','ldap_root_pw')))
|
if (in_array($name,array('config_passwd','db_pass','admin_passwd','ldap_root_pw')) && strlen($config[$name]) == 16)
|
||||||
{
|
{
|
||||||
$default = '<16 char random string>';
|
$default = '<16 char random string>';
|
||||||
}
|
}
|
||||||
@ -724,3 +733,98 @@ function fix_perms()
|
|||||||
system('/bin/chmod 700 /tmp/egw_cache');
|
system('/bin/chmod 700 /tmp/egw_cache');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Univention UCS specific defaults
|
||||||
|
*
|
||||||
|
* Defaults are read from ucr registry and /etc/*.secret files
|
||||||
|
*/
|
||||||
|
function set_univention_defaults()
|
||||||
|
{
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
set_distro_defaults('debian');
|
||||||
|
$config['distro'] = 'univention';
|
||||||
|
|
||||||
|
// mysql settings
|
||||||
|
$config['db_root_pw'] = _ucr_secret('mysql');
|
||||||
|
|
||||||
|
// check if ucs ldap server is configured
|
||||||
|
if (_ucr_get('ldap/server/ip'))
|
||||||
|
{
|
||||||
|
// ldap settings, see http://docs.univention.de/developer-reference-3.2.html#join:secret
|
||||||
|
$config['ldap_suffix'] = $config['ldap_base'] = _ucr_get('ldap/base');
|
||||||
|
$config['ldap_host'] = 'tls://'._ucr_get('ldap/server/ip').':'._ucr_get('ldap/server/port');
|
||||||
|
$config['ldap_admin'] = $config['ldap_root'] = 'cn=admin,$suffix';
|
||||||
|
$config['ldap_admin_pw'] = $config['ldap_root_pw'] = _ucr_secret('ldap');
|
||||||
|
$config['ldap_context'] = 'cn=users,$base';
|
||||||
|
$config['ldap_group_context'] = 'cn=groups,$base';
|
||||||
|
$config['ldap_search_filter'] = '(uid=%user)';
|
||||||
|
|
||||||
|
// ldap password hash (our default blowfish_crypt seems not to work)
|
||||||
|
$config['ldap_encryption_type'] = 'sha512_crypt';
|
||||||
|
|
||||||
|
$config['account_min_id'] = 1200; // UCS use 11xx for internal users/groups
|
||||||
|
|
||||||
|
$config['account-auth'] = 'univention,ldap';
|
||||||
|
|
||||||
|
// set sambaadmin sambaSID
|
||||||
|
$config['sambaadmin/sambaSID'] = exec('/usr/bin/univention-ldapsearch -x "(objectclass=sambadomain)" sambaSID|sed -n "s/sambaSID: \(.*\)/\1/p"');
|
||||||
|
|
||||||
|
// mailserver, see setup-cli.php --help config
|
||||||
|
if (($mailserver = exec('/usr/bin/univention-ldapsearch -x "(univentionAppID=mailserver_*)" univentionAppInstalledOnServer|sed -n "s/univentionAppInstalledOnServer: \(.*\)/\1/p"')) &&
|
||||||
|
_ucr_get('mail/cyrus/imap') == 'yes' && ($domains=_ucr_get('mail/hosteddomains')))
|
||||||
|
{
|
||||||
|
if (!is_array($domains)) $domains = explode("\n", $domains);
|
||||||
|
$domain = array_shift($domains);
|
||||||
|
$config['smtpserver'] = "$mailserver,465,,,yes,tls";
|
||||||
|
$config['smtp'] = 'no,emailadmin_smtp_ldap_univention';
|
||||||
|
$config['mailserver'] = "$mailserver,993,$domain,email,tls";
|
||||||
|
$config['imap'] = /*'cyrus,'._ucr_secret('cyrus')*/','.',emailadmin_imap_cyrus';
|
||||||
|
$config['folder'] = 'INBOX/Sent,INBOX/Trash,INBOX/Drafts,INBOX/Templates,INBOX/Spam';
|
||||||
|
if (($sieve_port = _ucr_get('mail/cyrus/sieve/port')))
|
||||||
|
{
|
||||||
|
$config['sieve'] = "$mailserver,$sieve_port,starttls";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from Univention registry
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _ucr_get($name)
|
||||||
|
{
|
||||||
|
static $values=null;
|
||||||
|
if (!isset($values))
|
||||||
|
{
|
||||||
|
$output = $matches = null;
|
||||||
|
exec('/usr/sbin/ucr dump', $output);
|
||||||
|
foreach($output as $line)
|
||||||
|
{
|
||||||
|
if (preg_match("/^([^:]+): (.*)\n?$/", $line, $matches))
|
||||||
|
{
|
||||||
|
$values[$matches[1]] = $matches[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $values[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read one Univention secret/password eg. _ucr_secret('mysql')
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string|boolean
|
||||||
|
*/
|
||||||
|
function _ucr_secret($name)
|
||||||
|
{
|
||||||
|
if (!file_exists($filename = '/etc/'.basename($name).'.secret'))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return trim(file_get_contents($filename));
|
||||||
|
}
|
||||||
|
@ -110,16 +110,17 @@ class emailadmin_hooks
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$account = new emailadmin_account($params);
|
$account = new emailadmin_account($params);
|
||||||
if ($account->acc_imap_type != 'emailadmin_imap' && ($imap = $account->imapServer(true)) &&
|
|
||||||
is_a($imap, 'emailadmin_imap') && get_class($imap) != 'emailadmin_imap')
|
|
||||||
{
|
|
||||||
$imap->$method($data);
|
|
||||||
}
|
|
||||||
if ($account->acc_smtp_type != 'emailadmin_smtp' && ($smtp = $account->smtpServer(true)) &&
|
if ($account->acc_smtp_type != 'emailadmin_smtp' && ($smtp = $account->smtpServer(true)) &&
|
||||||
is_a($smtp, 'emailadmin_smtp') && get_class($smtp) != 'emailadmin_smtp')
|
is_a($smtp, 'emailadmin_smtp') && get_class($smtp) != 'emailadmin_smtp')
|
||||||
{
|
{
|
||||||
$smtp->$method($data);
|
$smtp->$method($data);
|
||||||
}
|
}
|
||||||
|
if ($account->acc_imap_type != 'emailadmin_imap' && $account->acc_admin_username &&
|
||||||
|
$account->acc_admin_password && ($imap = $account->imapServer(true)) &&
|
||||||
|
is_a($imap, 'emailadmin_imap') && get_class($imap) != 'emailadmin_imap')
|
||||||
|
{
|
||||||
|
$imap->$method($data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception $e) {
|
catch(Exception $e) {
|
||||||
_egw_log_exception($e);
|
_egw_log_exception($e);
|
||||||
|
@ -1018,6 +1018,7 @@ class emailadmin_imapbase
|
|||||||
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_sent]='Sent';
|
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_sent]='Sent';
|
||||||
//if (!empty($this->icServer->acc_folder_template) && !isset($_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_template]))
|
//if (!empty($this->icServer->acc_folder_template) && !isset($_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_template]))
|
||||||
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_template]='Templates';
|
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_template]='Templates';
|
||||||
|
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_junk]='Junk';
|
||||||
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_specialUseFolders));//.'<->'.array2string($this->icServer));
|
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_specialUseFolders));//.'<->'.array2string($this->icServer));
|
||||||
self::$specialUseFolders = $_specialUseFolders[$this->icServer->ImapServerId];
|
self::$specialUseFolders = $_specialUseFolders[$this->icServer->ImapServerId];
|
||||||
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$_specialUseFolders, $expiration=60*60*24*5);
|
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$_specialUseFolders, $expiration=60*60*24*5);
|
||||||
@ -2158,11 +2159,17 @@ class emailadmin_imapbase
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$rv = $this->icServer->createMailbox($newFolderName);
|
$opts = array();
|
||||||
|
// if new created folder is a specal-use-folder, mark it as such, so other clients know to use it too
|
||||||
|
if (isset(self::$specialUseFolders[$newFolderName]))
|
||||||
|
{
|
||||||
|
$opts['special_use'] = self::$specialUseFolders[$newFolderName];
|
||||||
|
}
|
||||||
|
$rv = $this->icServer->createMailbox($newFolderName, $opts);
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
error_log(__METHOD__.' ('.__LINE__.') '.' create Folder '.$newFolderName.'->'.$e->getMessage().' Namespace:'.array2string($this->icServer->getNameSpaces()).function_backtrace());
|
error_log(__METHOD__.' ('.__LINE__.') '.' create Folder '.$newFolderName.'->'.$e->getMessage().' ('.$e->details.') Namespace:'.array2string($this->icServer->getNameSpaces()).function_backtrace());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@ -2459,7 +2466,8 @@ class emailadmin_imapbase
|
|||||||
//subscribed folders may be used in getFolderStatus
|
//subscribed folders may be used in getFolderStatus
|
||||||
egw_cache::setCache(egw_cache::INSTANCE,'email','subscribedFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$subscribedFoldersForCache,$expiration=60*60*1);
|
egw_cache::setCache(egw_cache::INSTANCE,'email','subscribedFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$subscribedFoldersForCache,$expiration=60*60*1);
|
||||||
//echo "<br>FolderNameSpace To Process:";_debug_array($foldersNameSpace);
|
//echo "<br>FolderNameSpace To Process:";_debug_array($foldersNameSpace);
|
||||||
$autoFolderObjects = array();
|
$autoFolderObjects = $folders = array();
|
||||||
|
$autofolder_exists = array();
|
||||||
foreach( array('personal', 'others', 'shared') as $type) {
|
foreach( array('personal', 'others', 'shared') as $type) {
|
||||||
if(isset($foldersNameSpace[$type])) {
|
if(isset($foldersNameSpace[$type])) {
|
||||||
if($_subscribedOnly) {
|
if($_subscribedOnly) {
|
||||||
@ -2520,12 +2528,23 @@ class emailadmin_imapbase
|
|||||||
$folders[$folderName] = $folderObject;
|
$folders[$folderName] = $folderObject;
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__.' ('.__LINE__.') '.':'.$folderObject->folderName);
|
//error_log(__METHOD__.' ('.__LINE__.') '.':'.$folderObject->folderName);
|
||||||
|
if (!isset(self::$specialUseFolders)) $this->getSpecialUseFolders ();
|
||||||
|
if (isset(self::$specialUseFolders[$folderName]))
|
||||||
|
{
|
||||||
|
$autofolder_exists[$folderName] = self::$specialUseFolders[$folderName];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_array($autoFolderObjects) && !empty($autoFolderObjects)) {
|
if (is_array($autoFolderObjects) && !empty($autoFolderObjects)) {
|
||||||
uasort($autoFolderObjects,array($this,"sortByAutoFolderPos"));
|
uasort($autoFolderObjects,array($this,"sortByAutoFolderPos"));
|
||||||
}
|
}
|
||||||
|
// check if some standard folders are missing and need to be created
|
||||||
|
if (count($autofolder_exists) < count(self::$autoFolders) && $this->check_create_autofolders($autofolder_exists))
|
||||||
|
{
|
||||||
|
// if new folders have been created, re-read folders ignoring the cache
|
||||||
|
return $this->getFolderObjects($_subscribedOnly, $_getCounters, $_alwaysGetDefaultFolders, false); // false = do NOT use cache
|
||||||
|
}
|
||||||
if (is_array($folders)) uasort($folders,array($this,"sortByDisplayName"));
|
if (is_array($folders)) uasort($folders,array($this,"sortByDisplayName"));
|
||||||
//$folders2return = array_merge($autoFolderObjects,$folders);
|
//$folders2return = array_merge($autoFolderObjects,$folders);
|
||||||
//_debug_array($folders2return); #exit;
|
//_debug_array($folders2return); #exit;
|
||||||
@ -2542,12 +2561,33 @@ class emailadmin_imapbase
|
|||||||
return $folders2return[$this->icServer->ImapServerId];
|
return $folders2return[$this->icServer->ImapServerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all automatic folders exist and create them if not
|
||||||
|
*
|
||||||
|
* @param array $autofolders_exists existing folders, no need to check their existance again
|
||||||
|
* @return int number of new folders created
|
||||||
|
*/
|
||||||
|
function check_create_autofolders(array $autofolders_exists=array())
|
||||||
|
{
|
||||||
|
$num_created = 0;
|
||||||
|
foreach(self::$autoFolders as $folder)
|
||||||
|
{
|
||||||
|
$created = false;
|
||||||
|
if (!in_array($folder, $autofolders_exists) && $this->_getSpecialUseFolder($folder, true, $created) &&
|
||||||
|
$created && $folder != 'Outbox')
|
||||||
|
{
|
||||||
|
$num_created++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $num_created;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* search Value In FolderObjects
|
* search Value In FolderObjects
|
||||||
*
|
*
|
||||||
* Helper function to search for a specific value within the foldertree objects
|
* Helper function to search for a specific value within the foldertree objects
|
||||||
* @param string $needle
|
* @param string $needle
|
||||||
* @param array $haystack, array of folderobjects
|
* @param array $haystack array of folderobjects
|
||||||
* @return MIXED false or key
|
* @return MIXED false or key
|
||||||
*/
|
*/
|
||||||
static function searchValueInFolderObjects($needle, $haystack)
|
static function searchValueInFolderObjects($needle, $haystack)
|
||||||
@ -2682,18 +2722,21 @@ class emailadmin_imapbase
|
|||||||
* abstraction layer for getDraftFolder, getTemplateFolder, getTrashFolder and getSentFolder
|
* abstraction layer for getDraftFolder, getTemplateFolder, getTrashFolder and getSentFolder
|
||||||
* @param string $type the type to fetch (Drafts|Template|Trash|Sent)
|
* @param string $type the type to fetch (Drafts|Template|Trash|Sent)
|
||||||
* @param boolean $_checkexistance, trigger check for existance
|
* @param boolean $_checkexistance, trigger check for existance
|
||||||
|
* @param boolean& $created =null on return true: if folder was just created, false if not
|
||||||
* @return mixed string or false
|
* @return mixed string or false
|
||||||
*/
|
*/
|
||||||
function _getSpecialUseFolder($_type, $_checkexistance=TRUE)
|
function _getSpecialUseFolder($_type, $_checkexistance=TRUE, &$created=null)
|
||||||
{
|
{
|
||||||
static $types = array(
|
static $types = array(
|
||||||
'Drafts'=>array('prefName'=>'draftFolder','profileKey'=>'acc_folder_draft','autoFolderName'=>'Drafts'),
|
'Drafts' => array('profileKey'=>'acc_folder_draft','autoFolderName'=>'Drafts'),
|
||||||
'Template'=>array('prefName'=>'templateFolder','profileKey'=>'acc_folder_template','autoFolderName'=>'Templates'),
|
'Template' => array('profileKey'=>'acc_folder_template','autoFolderName'=>'Templates'),
|
||||||
'Trash'=>array('prefName'=>'trashFolder','profileKey'=>'acc_folder_trash','autoFolderName'=>'Trash'),
|
'Trash' => array('profileKey'=>'acc_folder_trash','autoFolderName'=>'Trash'),
|
||||||
'Sent'=>array('prefName'=>'sentFolder','profileKey'=>'acc_folder_sent','autoFolderName'=>'Sent'),
|
'Sent' => array('profileKey'=>'acc_folder_sent','autoFolderName'=>'Sent'),
|
||||||
'Junk'=>array('prefName'=>'junkFolder','profileKey'=>'acc_folder_junk','autoFolderName'=>'Junk'),
|
'Junk' => array('profileKey'=>'acc_folder_junk','autoFolderName'=>'Junk'),
|
||||||
'Outbox'=>array('prefName'=>'outboxFolder','profileKey'=>'acc_folder_outbox','autoFolderName'=>'Outbox'),
|
'Outbox' => array('profileKey'=>'acc_folder_outbox','autoFolderName'=>'Outbox'),
|
||||||
);
|
);
|
||||||
|
if ($_type == 'Templates') $_type = 'Template'; // for some reason self::$autofolders uses 'Templates'!
|
||||||
|
$created = false;
|
||||||
if (!isset($types[$_type]))
|
if (!isset($types[$_type]))
|
||||||
{
|
{
|
||||||
error_log(__METHOD__.' ('.__LINE__.') '.' '.$_type.' not supported for '.__METHOD__);
|
error_log(__METHOD__.' ('.__LINE__.') '.' '.$_type.' not supported for '.__METHOD__);
|
||||||
@ -2716,7 +2759,7 @@ class emailadmin_imapbase
|
|||||||
if ($_folderName && $_checkexistance && $_folderName !='none' && !$this->folderExists($_folderName,true)) {
|
if ($_folderName && $_checkexistance && $_folderName !='none' && !$this->folderExists($_folderName,true)) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->createFolder('', $_folderName, true);
|
if (($_folderName = $this->createFolder('', $_folderName, true))) $created = true;
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
|
@ -48,6 +48,11 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
*/
|
*/
|
||||||
const MAIL_ENABLE_ATTR = false;
|
const MAIL_ENABLE_ATTR = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value for MAIL_ENABLED to use local mail address
|
||||||
|
*/
|
||||||
|
const MAIL_ENABLED_USE_MAIL = '@mail';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute for aliases OR false to use mail
|
* Attribute for aliases OR false to use mail
|
||||||
*/
|
*/
|
||||||
@ -224,7 +229,8 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
// does schema support enabling/disabling mail via attribute
|
// does schema support enabling/disabling mail via attribute
|
||||||
if (static::MAIL_ENABLE_ATTR)
|
if (static::MAIL_ENABLE_ATTR)
|
||||||
{
|
{
|
||||||
$newData[static::MAIL_ENABLE_ATTR] = static::MAIL_ENABLED;
|
$newData[static::MAIL_ENABLE_ATTR] = static::MAIL_ENABLED == self::MAIL_ENABLED_USE_MAIL ?
|
||||||
|
$mailLocalAddress : static::MAIL_ENABLE_ATTR;
|
||||||
}
|
}
|
||||||
// does schema support an explicit mailbox name --> set it
|
// does schema support an explicit mailbox name --> set it
|
||||||
if (static::MAILBOX_ATTR)
|
if (static::MAILBOX_ATTR)
|
||||||
@ -232,6 +238,9 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
$newData[static::MAILBOX_ATTR] = self::mailbox_addr($_hookValues);
|
$newData[static::MAILBOX_ATTR] = self::mailbox_addr($_hookValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allow extending classes to add extra data
|
||||||
|
$this->addAccountExtra($_hookValues, $allValues[0], $newData);
|
||||||
|
|
||||||
if (!($ret = ldap_mod_replace($ds, $accountDN, $newData)) || $this->debug)
|
if (!($ret = ldap_mod_replace($ds, $accountDN, $newData)) || $this->debug)
|
||||||
{
|
{
|
||||||
error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".
|
error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".
|
||||||
@ -241,6 +250,18 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add additional values to addAccount and setUserData ($_hookValues['location'])
|
||||||
|
*
|
||||||
|
* @param array $_hookValues
|
||||||
|
* @param array $allValues existing data of account as returned by ldap query
|
||||||
|
* @param array $newData data to update
|
||||||
|
*/
|
||||||
|
function addAccountExtra(array $_hookValues, array $allValues, array &$newData)
|
||||||
|
{
|
||||||
|
unset($_hookValues, $allValues, $newData); // not used, but required by function signature
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all email addresses of an account
|
* Get all email addresses of an account
|
||||||
*
|
*
|
||||||
@ -377,7 +398,8 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
if (static::MAIL_ENABLE_ATTR)
|
if (static::MAIL_ENABLE_ATTR)
|
||||||
{
|
{
|
||||||
$accountStatus = isset($values[static::MAIL_ENABLE_ATTR]) &&
|
$accountStatus = isset($values[static::MAIL_ENABLE_ATTR]) &&
|
||||||
(static::MAIL_ENABLED && !strcasecmp($values[static::MAIL_ENABLE_ATTR][0], static::MAIL_ENABLED) ||
|
(static::MAIL_ENABLED === self::MAIL_ENABLED_USE_MAIL && !empty($values[static::MAIL_ENABLE_ATTR][0]) ||
|
||||||
|
static::MAIL_ENABLED && !strcasecmp($values[static::MAIL_ENABLE_ATTR][0], static::MAIL_ENABLED) ||
|
||||||
!static::MAIL_ENABLED && $values[static::ALIAS_ATTR ? static::ALIAS_ATTR : 'mail']['count'] > 0) ?
|
!static::MAIL_ENABLED && $values[static::ALIAS_ATTR ? static::ALIAS_ATTR : 'mail']['count'] > 0) ?
|
||||||
emailadmin_smtp::MAIL_ENABLED : '';
|
emailadmin_smtp::MAIL_ENABLED : '';
|
||||||
}
|
}
|
||||||
@ -567,7 +589,8 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
// does schema support enabling/disabling mail via attribute
|
// does schema support enabling/disabling mail via attribute
|
||||||
if (static::MAIL_ENABLE_ATTR)
|
if (static::MAIL_ENABLE_ATTR)
|
||||||
{
|
{
|
||||||
$newData[static::MAIL_ENABLE_ATTR] = $_accountStatus ? static::MAIL_ENABLED : array();
|
$newData[static::MAIL_ENABLE_ATTR] = $_accountStatus ?
|
||||||
|
(static::MAIL_ENABLED == self::MAIL_ENABLED_USE_MAIL ? $_mailLocalAddress : static::MAIL_ENABLED) : array();
|
||||||
}
|
}
|
||||||
// if we have no mail-enabled attribute, but require primary mail in aliases-attr
|
// if we have no mail-enabled attribute, but require primary mail in aliases-attr
|
||||||
// we do NOT write aliases, if mail is not enabled
|
// we do NOT write aliases, if mail is not enabled
|
||||||
@ -580,6 +603,9 @@ class emailadmin_smtp_ldap extends emailadmin_smtp
|
|||||||
{
|
{
|
||||||
$newData[static::MAILBOX_ATTR] = $_setMailbox;
|
$newData[static::MAILBOX_ATTR] = $_setMailbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->addAccountExtra(array('location' => 'setUserData'), $allValues[0], $newData);
|
||||||
|
|
||||||
if ($this->debug) error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".array2string($newData).')');
|
if ($this->debug) error_log(__METHOD__.'('.array2string(func_get_args()).") --> ldap_mod_replace(,'$accountDN',".array2string($newData).')');
|
||||||
|
|
||||||
return ldap_mod_replace($ldap, $accountDN, $newData);
|
return ldap_mod_replace($ldap, $accountDN, $newData);
|
||||||
|
102
emailadmin/inc/class.emailadmin_smtp_univention.inc.php
Normal file
102
emailadmin/inc/class.emailadmin_smtp_univention.inc.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware: Postfix with Univention mailAccount schema
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @package emailadmin
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @copyright (c) 2014 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @version $Id4$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Postfix with Univention mailAccount schema
|
||||||
|
*/
|
||||||
|
class emailadmin_smtp_univention extends emailadmin_smtp_ldap
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Capabilities of this class (pipe-separated): default, forward
|
||||||
|
*/
|
||||||
|
const CAPABILITIES = 'default|forward';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of schema, has to be in the right case!
|
||||||
|
*/
|
||||||
|
const SCHEMA = 'univentionMail';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute to enable mail for an account, OR false if existence of ALIAS_ATTR is enough for mail delivery
|
||||||
|
*/
|
||||||
|
const MAIL_ENABLE_ATTR = 'mailprimaryaddress';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute value to enable mail for an account, OR false if existense of attribute is enough to enable account
|
||||||
|
*/
|
||||||
|
const MAIL_ENABLED = self::MAIL_ENABLED_USE_MAIL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for aliases OR false to use mail
|
||||||
|
*/
|
||||||
|
const ALIAS_ATTR = 'mailalternativeaddress';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primary mail address required as an alias too: true or false
|
||||||
|
*/
|
||||||
|
const REQUIRE_MAIL_AS_ALIAS=false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for forwards OR false if not possible
|
||||||
|
*/
|
||||||
|
const FORWARD_ATTR = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute to only forward mail, OR false if not available
|
||||||
|
*/
|
||||||
|
const FORWARD_ONLY_ATTR = false;
|
||||||
|
/**
|
||||||
|
* Attribute value to only forward mail
|
||||||
|
*/
|
||||||
|
const FORWARD_ONLY = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = 'univentionmailuserquota';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal quota in MB is multiplicated with this factor before stored in LDAP
|
||||||
|
*/
|
||||||
|
const QUOTA_FACTOR = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log all LDAP writes / actions to error_log
|
||||||
|
*/
|
||||||
|
var $debug = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add additional values to addAccount
|
||||||
|
*
|
||||||
|
* @param array $_hookValues
|
||||||
|
* @param array $allValues
|
||||||
|
* @param array $newData
|
||||||
|
*/
|
||||||
|
function addAccountExtra(array $_hookValues, array $allValues, array &$newData)
|
||||||
|
{
|
||||||
|
unset($_hookValues); // not used, but required by function signature
|
||||||
|
|
||||||
|
if (empty($allValues['univentionmailhomeserver'][0]) && $newData[self::MAIL_ENABLE_ATTR])
|
||||||
|
{
|
||||||
|
$newData['univentionMailHomeServer'] = $this->host;
|
||||||
|
|
||||||
|
if (strpos($newData['univentionMailHomeServer'], '://'))
|
||||||
|
{
|
||||||
|
$newData['univentionMailHomeServer'] = parse_url($newData['univentionMailHomeServer'], PHP_URL_HOST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -53,7 +53,7 @@ class accounts_ldap
|
|||||||
*/
|
*/
|
||||||
var $user_context;
|
var $user_context;
|
||||||
/**
|
/**
|
||||||
* LDAP search filter for user accounts, eg. (uid=%name)
|
* LDAP search filter for user accounts, eg. (uid=%user)
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -82,16 +82,27 @@ class accounts_ldap
|
|||||||
'user' => array(
|
'user' => array(
|
||||||
'top','person','organizationalperson','inetorgperson','posixaccount','shadowaccount'
|
'top','person','organizationalperson','inetorgperson','posixaccount','shadowaccount'
|
||||||
),
|
),
|
||||||
'user-if-supported' => array( // these classes get added, only if the server supports them
|
'user-if-supported' => array( // these classes get added, if server supports them
|
||||||
'mozillaabpersonalpha','mozillaorgperson','evolutionperson'
|
'mozillaabpersonalpha', 'mozillaorgperson', 'evolutionperson',
|
||||||
|
'univentionperson', array('univentionobject', 'univentionObjectType' => 'users/user'),
|
||||||
),
|
),
|
||||||
'group' => array(
|
'group' => array(
|
||||||
'top','posixgroup','groupofnames'
|
'top','posixgroup','groupofnames'
|
||||||
|
),
|
||||||
|
'group-if-supported' => array( // these classes get added, if servers supports them
|
||||||
|
'univentiongroup', array('univentionobject', 'univentionObjectType' => 'groups/group'),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
* Classes allowing to set a mail-address for a group and specify the memberaddresses as forwarding addresses
|
* Classes allowing to set a mail-address for a group and specify the memberaddresses as forwarding addresses
|
||||||
*
|
*
|
||||||
|
* $objectclass => $forward
|
||||||
|
* $objectclass => [$forward, $extra_attr, $mail_attr, $keep_objectclass]
|
||||||
|
* $forward : name of attribute to set forwards for members mail addresses, false if not used/required
|
||||||
|
* $extra_attr : required attribute (eg. 'uid'), which need to be set, default none
|
||||||
|
* $mail_attr : name of attribute for mail-address, if not 'mail'
|
||||||
|
* $keep_objectclass : true to not remove objectclass, if not mail set
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
var $group_mail_classes = array(
|
var $group_mail_classes = array(
|
||||||
@ -99,6 +110,7 @@ class accounts_ldap
|
|||||||
'dbmailuser' => array('mailforwardingaddress','uid'),
|
'dbmailuser' => array('mailforwardingaddress','uid'),
|
||||||
'qmailuser' => array('mailforwardingaddress','uid'),
|
'qmailuser' => array('mailforwardingaddress','uid'),
|
||||||
'mailaccount' => 'mailalias',
|
'mailaccount' => 'mailalias',
|
||||||
|
'univentiongroup' => array(false, false, 'mailprimaryaddress', true),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,10 +212,7 @@ class accounts_ldap
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$old = ldap::result2array($old[0]);
|
$old = ldap::result2array($old[0]);
|
||||||
foreach($old['objectclass'] as $n => $class)
|
$old['objectclass'] = array_map('strtolower', $old['objectclass']);
|
||||||
{
|
|
||||||
$old['objectclass'][$n] = strtolower($class);
|
|
||||||
}
|
|
||||||
$key = false;
|
$key = false;
|
||||||
if ($is_group && ($key = array_search('namedobject',$old['objectclass'])) !== false ||
|
if ($is_group && ($key = array_search('namedobject',$old['objectclass'])) !== false ||
|
||||||
$is_group && ($old['cn'] != $data_utf8['account_lid'] || substr($old['dn'],0,3) != 'cn=') ||
|
$is_group && ($old['cn'] != $data_utf8['account_lid'] || substr($old['dn'],0,3) != 'cn=') ||
|
||||||
@ -243,13 +252,20 @@ class accounts_ldap
|
|||||||
{
|
{
|
||||||
$to_write['objectclass'] = $old ? $old['objectclass'] : array();
|
$to_write['objectclass'] = $old ? $old['objectclass'] : array();
|
||||||
}
|
}
|
||||||
if (!$old && !$is_group) // for new accounts add additional addressbook object classes, if supported by server
|
if (!$old) // for new accounts add additional addressbook object classes, if supported by server
|
||||||
{ // as setting them later might loose eg. password, if we are not allowed to read them
|
{ // as setting them later might loose eg. password, if we are not allowed to read them
|
||||||
foreach($this->requiredObjectClasses['user-if-supported'] as $additional)
|
foreach($this->requiredObjectClasses[$is_group?'group-if-supported':'user-if-supported'] as $additional)
|
||||||
{
|
{
|
||||||
|
$add = array();
|
||||||
|
if (is_array($additional))
|
||||||
|
{
|
||||||
|
$add = $additional;
|
||||||
|
$additional = array_shift($add);
|
||||||
|
}
|
||||||
if ($this->ldapServerInfo->supportsObjectClass($additional))
|
if ($this->ldapServerInfo->supportsObjectClass($additional))
|
||||||
{
|
{
|
||||||
$to_write['objectclass'][] = $additional;
|
$to_write['objectclass'][] = $additional;
|
||||||
|
if ($add) $to_write += $add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,20 +285,22 @@ class accounts_ldap
|
|||||||
$to_write = $this->_merge_group($to_write,$data_utf8);
|
$to_write = $this->_merge_group($to_write,$data_utf8);
|
||||||
$data['account_type'] = 'g';
|
$data['account_type'] = 'g';
|
||||||
|
|
||||||
$groupOfNames = in_array('groupofnames',$old ? $old['objectclass'] : $to_write['objectclass']);
|
$objectclass = $old ? $old['objectclass'] : $to_write['objectclass'];
|
||||||
if (!$old && $groupOfNames || $members)
|
if ($members || !$old && array_intersect(array('groupofnames','groupofuniquenames','univentiongroup'), $objectclass))
|
||||||
{
|
{
|
||||||
$to_write = array_merge($to_write,$this->set_members($members,
|
$to_write = array_merge($to_write, $this->set_members($members, $data['account_id'], $objectclass, $dn));
|
||||||
$data['account_id'],$groupOfNames,$dn));
|
|
||||||
}
|
}
|
||||||
// check if we should set a mail address and forwards for each member
|
// check if we should set a mail address and forwards for each member
|
||||||
foreach($this->group_mail_classes as $objectclass => $forward)
|
foreach($this->group_mail_classes as $objectclass => $forward)
|
||||||
{
|
|
||||||
if ($this->ldapServerInfo->supportsObjectClass($objectclass) &&
|
|
||||||
($old && in_array($objectclass,$old['objectclass']) || $data_utf8['account_email'] || $old['mail']))
|
|
||||||
{
|
{
|
||||||
$extra_attr = false;
|
$extra_attr = false;
|
||||||
if (is_array($forward)) list($forward,$extra_attr) = $forward;
|
$mail_attr = 'mail';
|
||||||
|
$keep_objectclass = false;
|
||||||
|
if (is_array($forward)) list($forward,$extra_attr,$mail_attr,$keep_objectclass) = $forward;
|
||||||
|
|
||||||
|
if ($this->ldapServerInfo->supportsObjectClass($objectclass) &&
|
||||||
|
($old && in_array($objectclass,$old['objectclass']) || $data_utf8['account_email'] || $old[$mail_attr]))
|
||||||
|
{
|
||||||
if ($data_utf8['account_email']) // setting an email
|
if ($data_utf8['account_email']) // setting an email
|
||||||
{
|
{
|
||||||
if (!in_array($objectclass,$old ? $old['objectclass'] : $to_write['objectclass']))
|
if (!in_array($objectclass,$old ? $old['objectclass'] : $to_write['objectclass']))
|
||||||
@ -291,8 +309,10 @@ class accounts_ldap
|
|||||||
$to_write['objectclass'][] = $objectclass;
|
$to_write['objectclass'][] = $objectclass;
|
||||||
}
|
}
|
||||||
if ($extra_attr) $to_write[$extra_attr] = $data_utf8['account_lid'];
|
if ($extra_attr) $to_write[$extra_attr] = $data_utf8['account_lid'];
|
||||||
$to_write['mail'] = $data_utf8['account_email'];
|
$to_write[$mail_attr] = $data_utf8['account_email'];
|
||||||
|
|
||||||
|
if ($forward)
|
||||||
|
{
|
||||||
if (!$members) $members = $this->members($data['account_id']);
|
if (!$members) $members = $this->members($data['account_id']);
|
||||||
$to_write[$forward] = array();
|
$to_write[$forward] = array();
|
||||||
foreach (array_keys($members) as $member)
|
foreach (array_keys($members) as $member)
|
||||||
@ -303,11 +323,13 @@ class accounts_ldap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
elseif($old) // remove the mail and forwards only for existing entries
|
elseif($old) // remove the mail and forwards only for existing entries
|
||||||
{
|
{
|
||||||
$to_write['mail'] = $to_write[$forward] = array();
|
$to_write[$mail_attr] = array();
|
||||||
|
if ($forward) $to_write[$forward] = array();
|
||||||
if ($extra_attr) $to_write[$extra_attr] = array();
|
if ($extra_attr) $to_write[$extra_attr] = array();
|
||||||
if (($key = array_search($objectclass,$old['objectclass'])))
|
if (!$keep_objectclass && ($key = array_search($objectclass,$old['objectclass'])))
|
||||||
{
|
{
|
||||||
$to_write['objectclass'] = $old['objectclass'];
|
$to_write['objectclass'] = $old['objectclass'];
|
||||||
unset($to_write['objectclass'][$key]);
|
unset($to_write['objectclass'][$key]);
|
||||||
@ -360,8 +382,6 @@ class accounts_ldap
|
|||||||
if ($err)
|
if ($err)
|
||||||
{
|
{
|
||||||
error_log(__METHOD__."() ldap_".($old ? 'modify' : 'add')."(,'$dn',".array2string($to_write).") --> ldap_error()=".ldap_error($this->ds));
|
error_log(__METHOD__."() ldap_".($old ? 'modify' : 'add')."(,'$dn',".array2string($to_write).") --> ldap_error()=".ldap_error($this->ds));
|
||||||
echo "ldap_".($old ? 'modify' : 'add')."(,$dn,".print_r($to_write,true).")\n";
|
|
||||||
echo ldap_error($this->ds);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,8 +430,23 @@ class accounts_ldap
|
|||||||
*/
|
*/
|
||||||
protected function _read_group($account_id)
|
protected function _read_group($account_id)
|
||||||
{
|
{
|
||||||
|
$mail_attr = 'mail';
|
||||||
|
$group = array();
|
||||||
|
if (!is_object($this->ldapServerInfo))
|
||||||
|
{
|
||||||
|
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($this->frontend->config['ldap_host']);
|
||||||
|
}
|
||||||
|
foreach($this->group_mail_classes as $objectclass => $attrs)
|
||||||
|
{
|
||||||
|
if ($this->ldapServerInfo->supportsObjectClass($objectclass))
|
||||||
|
{
|
||||||
|
$group['mailAllowed'] = $objectclass;
|
||||||
|
if (is_array($attrs) && $attrs[2]) $mail_attr = $attrs[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
$sri = ldap_search($this->ds, $this->group_context,'(&(objectClass=posixGroup)(gidnumber=' . abs($account_id).'))',
|
$sri = ldap_search($this->ds, $this->group_context,'(&(objectClass=posixGroup)(gidnumber=' . abs($account_id).'))',
|
||||||
array('dn','gidnumber','cn','objectclass','mail'));
|
array('dn', 'gidnumber', 'cn', 'objectclass', $mail_attr, 'memberuid'));
|
||||||
|
|
||||||
$ldap_data = ldap_get_entries($this->ds, $sri);
|
$ldap_data = ldap_get_entries($this->ds, $sri);
|
||||||
if (!$ldap_data['count'])
|
if (!$ldap_data['count'])
|
||||||
@ -419,8 +454,9 @@ class accounts_ldap
|
|||||||
return false; // group not found
|
return false; // group not found
|
||||||
}
|
}
|
||||||
$data = translation::convert($ldap_data[0],'utf-8');
|
$data = translation::convert($ldap_data[0],'utf-8');
|
||||||
|
unset($data['objectclass']['count']);
|
||||||
|
|
||||||
$group = array(
|
$group += array(
|
||||||
'account_dn' => $data['dn'],
|
'account_dn' => $data['dn'],
|
||||||
'account_id' => -$data['gidnumber'][0],
|
'account_id' => -$data['gidnumber'][0],
|
||||||
'account_lid' => $data['cn'][0],
|
'account_lid' => $data['cn'][0],
|
||||||
@ -428,21 +464,24 @@ class accounts_ldap
|
|||||||
'account_firstname' => $data['cn'][0],
|
'account_firstname' => $data['cn'][0],
|
||||||
'account_lastname' => lang('Group'),
|
'account_lastname' => lang('Group'),
|
||||||
'account_fullname' => lang('Group').' '.$data['cn'][0],
|
'account_fullname' => lang('Group').' '.$data['cn'][0],
|
||||||
'groupOfNames' => in_array('groupOfNames',$data['objectclass']),
|
'objectclass' => array_map('strtolower', $data['objectclass']),
|
||||||
'account_email' => $data['mail'][0],
|
'account_email' => $data[$mail_attr][0],
|
||||||
|
'members' => array(),
|
||||||
);
|
);
|
||||||
if (!is_object($this->ldapServerInfo))
|
|
||||||
|
if (isset($data['memberuid']))
|
||||||
{
|
{
|
||||||
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($this->frontend->config['ldap_host']);
|
unset($data['memberuid']['count']);
|
||||||
}
|
|
||||||
foreach(array_keys($this->group_mail_classes) as $objectclass)
|
foreach($data['memberuid'] as $lid)
|
||||||
{
|
{
|
||||||
if ($this->ldapServerInfo->supportsObjectClass($objectclass))
|
if (($id = $this->name2id($lid, 'account_lid', 'u')))
|
||||||
{
|
{
|
||||||
$group['mailAllowed'] = $objectclass;
|
$group['members'][$id] = $lid;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,7 +784,7 @@ class accounts_ldap
|
|||||||
'account_modified' => isset($allVals['modifytimestamp'][0]) ? self::accounts_ldap2ts($allVals['modifytimestamp'][0]) : null,
|
'account_modified' => isset($allVals['modifytimestamp'][0]) ? self::accounts_ldap2ts($allVals['modifytimestamp'][0]) : null,
|
||||||
'account_primary_group' => (string)-$allVals['gidnumber'][0],
|
'account_primary_group' => (string)-$allVals['gidnumber'][0],
|
||||||
);
|
);
|
||||||
error_log(__METHOD__."() ldap=".array2string($allVals)." --> account=".array2string($account));
|
//error_log(__METHOD__."() ldap=".array2string($allVals)." --> account=".array2string($account));
|
||||||
if ($param['active'] && !$this->frontend->is_active($account))
|
if ($param['active'] && !$this->frontend->is_active($account))
|
||||||
{
|
{
|
||||||
if (isset($totalcount)) --$totalcount;
|
if (isset($totalcount)) --$totalcount;
|
||||||
@ -755,7 +794,7 @@ class accounts_ldap
|
|||||||
// return objectclass(es)
|
// return objectclass(es)
|
||||||
if ($param['objectclass'])
|
if ($param['objectclass'])
|
||||||
{
|
{
|
||||||
$account['objectclass'] = $allVals['objectclass'];
|
$account['objectclass'] = array_map('strtolower', $allVals['objectclass']);
|
||||||
unset($account['objectclass']['count']);
|
unset($account['objectclass']['count']);
|
||||||
}
|
}
|
||||||
$accounts[$account['account_id']] = $account;
|
$accounts[$account['account_id']] = $account;
|
||||||
@ -1005,9 +1044,11 @@ class accounts_ldap
|
|||||||
$members = array();
|
$members = array();
|
||||||
if (isset($group[0]['memberuid']))
|
if (isset($group[0]['memberuid']))
|
||||||
{
|
{
|
||||||
|
unset($group[0]['memberuid']['count']);
|
||||||
|
|
||||||
foreach($group[0]['memberuid'] as $lid)
|
foreach($group[0]['memberuid'] as $lid)
|
||||||
{
|
{
|
||||||
if (($id = $this->name2id($lid)))
|
if (($id = $this->name2id($lid, 'account_lid', 'u')))
|
||||||
{
|
{
|
||||||
$members[$id] = $lid;
|
$members[$id] = $lid;
|
||||||
}
|
}
|
||||||
@ -1054,34 +1095,47 @@ class accounts_ldap
|
|||||||
*
|
*
|
||||||
* @param array $members array with uidnumber or uid's
|
* @param array $members array with uidnumber or uid's
|
||||||
* @param int $gid gidnumber of group to set
|
* @param int $gid gidnumber of group to set
|
||||||
* @param boolean $groupOfNames =null should we set the member attribute of groupOfNames (default detect it)
|
* @param array $objectclass =null should we set the member and uniqueMember attributes (groupOf(Unique)Names|univentionGroup) (default detect it)
|
||||||
* @param string $use_cn =null if set $cn is used instead $gid and the attributes are returned, not written to ldap
|
* @param string $use_cn =null if set $cn is used instead $gid and the attributes are returned, not written to ldap
|
||||||
|
* @param boolean $uniqueMember =null should we set the uniqueMember attribute (default detect it)
|
||||||
* @return boolean/array false on failure, array or true otherwise
|
* @return boolean/array false on failure, array or true otherwise
|
||||||
*/
|
*/
|
||||||
function set_members($members,$gid,$groupOfNames=null,$use_cn=null)
|
function set_members($members, $gid, array $objectclass=null, $use_cn=null)
|
||||||
{
|
{
|
||||||
//echo "<p>accounts_ldap::set_members(".print_r($members,true).",$gid)</p>\n";
|
//echo "<p>accounts_ldap::set_members(".print_r($members,true).",$gid)</p>\n";
|
||||||
if (!($cn = $use_cn) && !($cn = $this->id2name($gid))) return false;
|
if (!($cn = $use_cn) && !($cn = $this->id2name($gid))) return false;
|
||||||
|
|
||||||
// do that group is a groupOfNames?
|
// do that group is a groupOf(Unique)Names or univentionGroup?
|
||||||
if (is_null($groupOfNames)) $groupOfNames = $this->id2name($gid,'groupOfNames');
|
if (is_null($objectclass)) $objectclass = $this->id2name($gid,'objectclass');
|
||||||
|
|
||||||
$to_write = array('memberuid' => array());
|
$to_write = array('memberuid' => array());
|
||||||
foreach((array)$members as $key => $member)
|
foreach((array)$members as $key => $member)
|
||||||
{
|
{
|
||||||
|
$member_dn = $this->id2name($member, 'account_dn');
|
||||||
if (is_numeric($member)) $member = $this->id2name($member);
|
if (is_numeric($member)) $member = $this->id2name($member);
|
||||||
|
|
||||||
if ($member)
|
if ($member)
|
||||||
{
|
{
|
||||||
$to_write['memberuid'][] = $member;
|
$to_write['memberuid'][] = $member;
|
||||||
if ($groupOfNames) $to_write['member'][] = 'uid='.$member.','.$this->user_context;
|
if (in_array('groupofnames', $objectclass))
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($groupOfNames && !$to_write['member'])
|
|
||||||
{
|
{
|
||||||
|
$to_write['member'][] = $member_dn;
|
||||||
|
}
|
||||||
|
if (array_intersect(array('groupofuniquenames','univentiongroup'), $objectclass))
|
||||||
|
{
|
||||||
|
$to_write['uniquemember'][] = $member_dn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// hack as groupOfNames requires the member attribute
|
// hack as groupOfNames requires the member attribute
|
||||||
|
if (in_array('groupofnames', $objectclass) && !$to_write['member'])
|
||||||
|
{
|
||||||
$to_write['member'][] = 'uid=dummy'.','.$this->user_context;
|
$to_write['member'][] = 'uid=dummy'.','.$this->user_context;
|
||||||
}
|
}
|
||||||
|
if (array_intersect(array('groupofuniquenames','univentiongroup'), $objectclass) && !$to_write['uniquemember'])
|
||||||
|
{
|
||||||
|
$to_write['uniquemember'][] = 'uid=dummy'.','.$this->user_context;
|
||||||
|
}
|
||||||
if ($use_cn) return $to_write;
|
if ($use_cn) return $to_write;
|
||||||
|
|
||||||
// set the member email addresses as forwards
|
// set the member email addresses as forwards
|
||||||
@ -1091,12 +1145,15 @@ class accounts_ldap
|
|||||||
if (is_array($forward)) list($forward,$extra_attr) = $forward;
|
if (is_array($forward)) list($forward,$extra_attr) = $forward;
|
||||||
if ($extra_attr && ($uid = $this->id2name($gid))) $to_write[$extra_attr] = $uid;
|
if ($extra_attr && ($uid = $this->id2name($gid))) $to_write[$extra_attr] = $uid;
|
||||||
|
|
||||||
|
if ($forward)
|
||||||
|
{
|
||||||
$to_write[$forward] = array();
|
$to_write[$forward] = array();
|
||||||
foreach($members as $key => $member)
|
foreach($members as $key => $member)
|
||||||
{
|
{
|
||||||
if (($email = $this->id2name($member,'account_email'))) $to_write[$forward][] = $email;
|
if (($email = $this->id2name($member,'account_email'))) $to_write[$forward][] = $email;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!ldap_modify($this->ds,'cn='.ldap::quote($cn).','.$this->group_context,$to_write))
|
if (!ldap_modify($this->ds,'cn='.ldap::quote($cn).','.$this->group_context,$to_write))
|
||||||
{
|
{
|
||||||
echo "ldap_modify(,'cn=$cn,$this->group_context',".print_r($to_write,true)."))\n";
|
echo "ldap_modify(,'cn=$cn,$this->group_context',".print_r($to_write,true)."))\n";
|
||||||
|
82
phpgwapi/inc/class.accounts_univention.inc.php
Normal file
82
phpgwapi/inc/class.accounts_univention.inc.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* API - accounts Univention LDAP backend
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Ralf Becker <rb@stylite.de>
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage accounts
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Univention LDAP Backend for accounts
|
||||||
|
*
|
||||||
|
* This backend is mostly identical to LDAP backend and need to be configured in the same way.
|
||||||
|
* Only difference is that new users get created via univention-directory-manager CLI program,
|
||||||
|
* to generate necesary Kerberos stuff.
|
||||||
|
*/
|
||||||
|
class accounts_univention extends accounts_ldap
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Name of binary to call
|
||||||
|
*/
|
||||||
|
const DIRECTORY_MANAGER_BIN = '/usr/sbin/univention-directory-manager';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves / adds the data of one account
|
||||||
|
*
|
||||||
|
* If no account_id is set in data the account is added and the new id is set in $data.
|
||||||
|
*
|
||||||
|
* @param array $data array with account-data
|
||||||
|
* @return int|boolean the account_id or false on error
|
||||||
|
*/
|
||||||
|
function save(&$data)
|
||||||
|
{
|
||||||
|
if (!$data['account_id'] && $data['account_type'] !== 'g' && self::available())
|
||||||
|
{
|
||||||
|
$params = array(
|
||||||
|
'users/user','create',
|
||||||
|
'--binddn', $this->frontend->config['ldap_root_dn'],
|
||||||
|
'--bindpwd', 5=>$this->frontend->config['ldap_root_pw'],
|
||||||
|
'--position', $this->frontend->config['ldap_context'],
|
||||||
|
'--set', 'username='.$data['account_lid'],
|
||||||
|
'--set', 'firstname='.$data['account_firstname'],
|
||||||
|
'--set', 'lastname='.$data['account_lastname'],
|
||||||
|
);
|
||||||
|
if ($data['account_email'])
|
||||||
|
{
|
||||||
|
$params[] = '--set'; $params[] = 'mailPrimaryAddress='.$data['account_email'];
|
||||||
|
}
|
||||||
|
if (!empty($data['account_passwd']))
|
||||||
|
{
|
||||||
|
$params[] = '--set'; $params[] = 'password='.$data['account_passwd'];
|
||||||
|
}
|
||||||
|
$cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params));
|
||||||
|
$output_arr = $ret = $matches = null;
|
||||||
|
exec($cmd, $output_arr, $ret);
|
||||||
|
$output = explode("\n", $output_arr);
|
||||||
|
if ($ret || !preg_match('/^Object created: (uid=.*)$/mui', $output, $matches))
|
||||||
|
{
|
||||||
|
$params[5] = '********'; // mask out password!
|
||||||
|
$cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params));
|
||||||
|
throw new egw_exception_wrong_userinput($cmd."\nreturned\n".$output);
|
||||||
|
}
|
||||||
|
$data['account_dn'] = $matches[1];
|
||||||
|
$data['account_id'] = $this->name2id($matches[1], 'account_dn', 'u');
|
||||||
|
}
|
||||||
|
return parent::save($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if our function depending on an external binary is available
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function available()
|
||||||
|
{
|
||||||
|
return file_exists(self::DIRECTORY_MANAGER_BIN) && is_executable(self::DIRECTORY_MANAGER_BIN);
|
||||||
|
}
|
||||||
|
}
|
@ -82,10 +82,15 @@ class setup_cmd_config extends setup_cmd
|
|||||||
{
|
{
|
||||||
if (substr($name, 0, 4) == 'acc_') continue;
|
if (substr($name, 0, 4) == 'acc_') continue;
|
||||||
|
|
||||||
|
$app = 'phpgwapi';
|
||||||
|
if (strpos($name, '/') !== false)
|
||||||
|
{
|
||||||
|
list($app, $name) = explode('/', $name);
|
||||||
|
}
|
||||||
self::$egw_setup->db->insert(self::$egw_setup->config_table,array(
|
self::$egw_setup->db->insert(self::$egw_setup->config_table,array(
|
||||||
'config_value' => $value,
|
'config_value' => $value,
|
||||||
),array(
|
),array(
|
||||||
'config_app' => 'phpgwapi',
|
'config_app' => $app,
|
||||||
'config_name' => $name,
|
'config_name' => $name,
|
||||||
),__LINE__,__FILE__);
|
),__LINE__,__FILE__);
|
||||||
}
|
}
|
||||||
@ -194,6 +199,7 @@ class setup_cmd_config extends setup_cmd
|
|||||||
'--ldap-context' => 'ldap_context',
|
'--ldap-context' => 'ldap_context',
|
||||||
'--ldap-search-filter' => 'ldap_search_filter',
|
'--ldap-search-filter' => 'ldap_search_filter',
|
||||||
'--ldap-group-context' => 'ldap_group_context',
|
'--ldap-group-context' => 'ldap_group_context',
|
||||||
|
'--sambaadmin-sid' => 'sambaadmin/sambaSID',
|
||||||
'--allow-remote-admin' => 'allow_remote_admin',
|
'--allow-remote-admin' => 'allow_remote_admin',
|
||||||
'--install-id' => 'install_id',
|
'--install-id' => 'install_id',
|
||||||
'--ads-host' => 'ads_host',
|
'--ads-host' => 'ads_host',
|
||||||
@ -397,10 +403,14 @@ class setup_cmd_config extends setup_cmd
|
|||||||
{
|
{
|
||||||
if (is_array($data) && isset($data['allowed']))
|
if (is_array($data) && isset($data['allowed']))
|
||||||
{
|
{
|
||||||
if ($data['name'] == 'auth_type')
|
switch ($data['name'])
|
||||||
{
|
{
|
||||||
|
case 'auth_type':
|
||||||
$options[$data['name']] = self::auth_types();
|
$options[$data['name']] = self::auth_types();
|
||||||
continue;
|
continue 2;
|
||||||
|
case 'account_repository':
|
||||||
|
$options[$data['name']] = self::account_repositries();
|
||||||
|
continue 2;
|
||||||
}
|
}
|
||||||
foreach($data['allowed'] as $label => $value)
|
foreach($data['allowed'] as $label => $value)
|
||||||
{
|
{
|
||||||
@ -460,6 +470,37 @@ class setup_cmd_config extends setup_cmd
|
|||||||
return $auth_types;
|
return $auth_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read auth-types (existing auth backends) from filesystem and fix our $options array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
static function account_repositories()
|
||||||
|
{
|
||||||
|
static $account_repositories = array(
|
||||||
|
'sql' => 'SQL',
|
||||||
|
'ldap' => 'LDAP',
|
||||||
|
'ads' => 'Active Directory',
|
||||||
|
);
|
||||||
|
static $scan_done = null;
|
||||||
|
if (!$scan_done++)
|
||||||
|
{
|
||||||
|
// now add auth backends found in filesystem
|
||||||
|
foreach(scandir(EGW_INCLUDE_ROOT.'/phpgwapi/inc') as $file)
|
||||||
|
{
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match('/^class\.accounts_([a-z]+)\.inc\.php$/', $file, $matches) &&
|
||||||
|
!isset($account_repositories[$matches[1]]) &&
|
||||||
|
class_exists($class='accounts_'.$matches[1]) &&
|
||||||
|
(!is_callable($callable=$class.'::available') || call_user_func($callable)))
|
||||||
|
{
|
||||||
|
$account_repositories[$matches[1]] = ucfirst($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $account_repositories;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the defaults from the $options array
|
* Return the defaults from the $options array
|
||||||
*
|
*
|
||||||
|
@ -185,6 +185,17 @@ function auth_type_activesync($config)
|
|||||||
return _options_from(setup_cmd_config::auth_types(),$config['auth_type_activesync']);
|
return _options_from(setup_cmd_config::auth_types(),$config['auth_type_activesync']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make account-repository-types from setup_cmd_config available
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function account_repository($config)
|
||||||
|
{
|
||||||
|
return _options_from(setup_cmd_config::account_repositories(), $config['account_repository']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns options string
|
* Returns options string
|
||||||
*
|
*
|
||||||
|
@ -173,9 +173,7 @@
|
|||||||
<td>{lang_Select_where_you_want_to_store/retrieve_user_accounts}:</td>
|
<td>{lang_Select_where_you_want_to_store/retrieve_user_accounts}:</td>
|
||||||
<td>
|
<td>
|
||||||
<select name="newsettings[account_repository]">
|
<select name="newsettings[account_repository]">
|
||||||
<option value="sql"{selected_account_repository_sql}>SQL</option>
|
{hook_account_repository}
|
||||||
<option value="ldap"{selected_account_repository_ldap}>LDAP</option>
|
|
||||||
<option value="ads"{selected_account_repository_ads}>Active Directory</option>
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user