Make kolab_auth's LDAP class be based on new rcube_ldap_generic class.
Move kolab_auth_ldap into separate file. Some improvements, including performance improvement in kolab_delegate
This commit is contained in:
parent
65dfbee601
commit
e69e9b90ae
4 changed files with 486 additions and 160 deletions
|
@ -61,12 +61,12 @@ class kolab_auth extends rcube_plugin
|
|||
$rcmail->config->set('imap_debug', true);
|
||||
$rcmail->config->set('ldap_debug', true);
|
||||
$rcmail->config->set('smtp_debug', true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function startup($args) {
|
||||
public function startup($args)
|
||||
{
|
||||
// Arguments are task / action, not interested
|
||||
if (!empty($_SESSION['user_roledns'])) {
|
||||
$this->load_user_role_plugins_and_settings($_SESSION['user_roledns']);
|
||||
|
@ -75,7 +75,8 @@ class kolab_auth extends rcube_plugin
|
|||
return $args;
|
||||
}
|
||||
|
||||
public function load_user_role_plugins_and_settings($role_dns) {
|
||||
public function load_user_role_plugins_and_settings($role_dns)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
$this->load_config();
|
||||
|
||||
|
@ -151,7 +152,8 @@ class kolab_auth extends rcube_plugin
|
|||
}
|
||||
}
|
||||
|
||||
public function write_log($args) {
|
||||
public function write_log($args)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
|
||||
if (!$rcmail->config->get('kolab_auth_auditlog', false)) {
|
||||
|
@ -286,7 +288,7 @@ class kolab_auth extends rcube_plugin
|
|||
}
|
||||
|
||||
// Find user record in LDAP
|
||||
$record = $this->get_user_record($user, $host);
|
||||
$record = $ldap->get_user_record($user, $host);
|
||||
|
||||
if (empty($record)) {
|
||||
$args['abort'] = true;
|
||||
|
@ -309,8 +311,7 @@ class kolab_auth extends rcube_plugin
|
|||
// Login As...
|
||||
if (!empty($loginas) && $admin_login) {
|
||||
// Authenticate to LDAP
|
||||
$dn = rcube_ldap::dn_decode($record['ID']);
|
||||
$result = $ldap->bind($dn, $pass);
|
||||
$result = $ldap->bind($record['dn'], $pass);
|
||||
|
||||
if (!$result) {
|
||||
$args['abort'] = true;
|
||||
|
@ -318,32 +319,24 @@ class kolab_auth extends rcube_plugin
|
|||
}
|
||||
|
||||
// check if the original user has/belongs to administrative role/group
|
||||
$isadmin = false;
|
||||
$group = $rcmail->config->get('kolab_auth_group');
|
||||
$role_attr = $rcmail->config->get('kolab_auth_role');
|
||||
$role_dn = $rcmail->config->get('kolab_auth_role_value');
|
||||
$isadmin = false;
|
||||
$group = $rcmail->config->get('kolab_auth_group');
|
||||
$role_dn = $rcmail->config->get('kolab_auth_role_value');
|
||||
|
||||
// check role attribute
|
||||
if (!empty($role_attr) && !empty($role_dn) && !empty($record[$role_attr])) {
|
||||
$role_dn = $this->parse_vars($role_dn, $user, $host);
|
||||
foreach ((array)$record[$role_attr] as $role) {
|
||||
if ($role == $role_dn) {
|
||||
$isadmin = true;
|
||||
break;
|
||||
}
|
||||
$role_dn = $ldap->parse_vars($role_dn, $user, $host);
|
||||
if (in_array($role_dn, (array)$record[$role_attr])) {
|
||||
$isadmin = true;
|
||||
}
|
||||
}
|
||||
|
||||
// check group
|
||||
if (!$isadmin && !empty($group)) {
|
||||
$groups = $ldap->get_record_groups($record['ID']);
|
||||
foreach (array_keys($groups) as $g) {
|
||||
if ($group == rcube_ldap::dn_decode($g)) {
|
||||
$isadmin = true;
|
||||
break;
|
||||
}
|
||||
$groups = $ldap->get_user_groups($record['dn'], $user, $host);
|
||||
if (in_array($group, $groups)) {
|
||||
$isadmin = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Save original user login for log (see below)
|
||||
|
@ -358,7 +351,7 @@ class kolab_auth extends rcube_plugin
|
|||
|
||||
// user has the privilage, get "login as" user credentials
|
||||
if ($isadmin) {
|
||||
$record = $this->get_user_record($loginas, $host);
|
||||
$record = $ldap->get_user_record($loginas, $host);
|
||||
}
|
||||
|
||||
if (empty($record)) {
|
||||
|
@ -376,7 +369,7 @@ class kolab_auth extends rcube_plugin
|
|||
|
||||
// Store UID and DN of logged user in session for use by other plugins
|
||||
$_SESSION['kolab_uid'] = is_array($record['uid']) ? $record['uid'][0] : $record['uid'];
|
||||
$_SESSION['kolab_dn'] = $record['ID']; // encoded
|
||||
$_SESSION['kolab_dn'] = $record['dn'];
|
||||
|
||||
// Set user login
|
||||
if ($login_attr) {
|
||||
|
@ -485,80 +478,10 @@ class kolab_auth extends rcube_plugin
|
|||
return null;
|
||||
}
|
||||
|
||||
self::$ldap = new kolab_auth_ldap_backend(
|
||||
$addressbook,
|
||||
$rcmail->config->get('ldap_debug'),
|
||||
$rcmail->config->mail_domain($_SESSION['imap_host'])
|
||||
);
|
||||
require_once __DIR__ . '/kolab_auth_ldap.php';
|
||||
|
||||
$rcmail->add_shutdown_function(array(self::$ldap, 'close'));
|
||||
self::$ldap = new kolab_auth_ldap($addressbook);
|
||||
|
||||
return self::$ldap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches user data from LDAP addressbook
|
||||
*/
|
||||
private function get_user_record($user, $host)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
$filter = $rcmail->config->get('kolab_auth_filter');
|
||||
$filter = $this->parse_vars($filter, $user, $host);
|
||||
$ldap = self::ldap();
|
||||
|
||||
// reset old result
|
||||
$ldap->reset();
|
||||
|
||||
// get record
|
||||
$ldap->set_filter($filter);
|
||||
$results = $ldap->list_records();
|
||||
|
||||
if (count($results->records) == 1) {
|
||||
return $results->records[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares filter query for LDAP search
|
||||
*/
|
||||
private function parse_vars($str, $user, $host)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
$domain = $rcmail->config->get('username_domain');
|
||||
|
||||
if (!empty($domain) && strpos($user, '@') === false) {
|
||||
if (is_array($domain) && isset($domain[$host])) {
|
||||
$user .= '@'.rcube_utils::parse_host($domain[$host], $host);
|
||||
}
|
||||
else if (is_string($domain)) {
|
||||
$user .= '@'.rcube_utils::parse_host($domain, $host);
|
||||
}
|
||||
}
|
||||
|
||||
// replace variables in filter
|
||||
list($u, $d) = explode('@', $user);
|
||||
$dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string
|
||||
$replaces = array('%dc' => $dc, '%d' => $d, '%fu' => $user, '%u' => $u);
|
||||
|
||||
return strtr($str, $replaces);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for rcube_ldap addressbook
|
||||
*/
|
||||
class kolab_auth_ldap_backend extends rcube_ldap
|
||||
{
|
||||
function __construct($p, $debug=false, $mail_domain=null)
|
||||
{
|
||||
parent::__construct($p, $debug, $mail_domain);
|
||||
$this->fieldmap['uid'] = 'uid';
|
||||
}
|
||||
|
||||
function set_filter($filter)
|
||||
{
|
||||
if ($filter) {
|
||||
$this->prop['filter'] = $filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
403
plugins/kolab_auth/kolab_auth_ldap.php
Normal file
403
plugins/kolab_auth/kolab_auth_ldap.php
Normal file
|
@ -0,0 +1,403 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Kolab Authentication
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Aleksander Machniak <machniak@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2011-2013, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper class for rcube_ldap_generic
|
||||
*/
|
||||
class kolab_auth_ldap extends rcube_ldap_generic
|
||||
{
|
||||
|
||||
function __construct($p)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
|
||||
$this->debug = (bool) $rcmail->config->get('ldap_debug');
|
||||
$this->domain = $rcmail->config->get('username_domain');
|
||||
$this->fieldmap = $p['fieldmap'];
|
||||
$this->fieldmap['uid'] = 'uid';
|
||||
|
||||
$p['attributes'] = array_values($this->fieldmap);
|
||||
|
||||
// Connect to the server (with bind)
|
||||
parent::__construct($p);
|
||||
$this->_connect();
|
||||
|
||||
$rcmail->add_shutdown_function(array($this, 'close'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a connection to the LDAP server
|
||||
*/
|
||||
private function _connect()
|
||||
{
|
||||
$rcube = rcube::get_instance();
|
||||
|
||||
// try to connect + bind for every host configured
|
||||
// with OpenLDAP 2.x ldap_connect() always succeeds but ldap_bind will fail if host isn't reachable
|
||||
// see http://www.php.net/manual/en/function.ldap-connect.php
|
||||
foreach ((array)$this->config['hosts'] as $host) {
|
||||
// skip host if connection failed
|
||||
if (!$this->connect($host)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bind_pass = $this->config['bind_pass'];
|
||||
$bind_user = $this->config['bind_user'];
|
||||
$bind_dn = $this->config['bind_dn'];
|
||||
|
||||
if (empty($bind_pass)) {
|
||||
$this->ready = true;
|
||||
}
|
||||
else {
|
||||
if (!empty($bind_dn)) {
|
||||
$this->ready = $this->bind($bind_dn, $bind_pass);
|
||||
}
|
||||
else if (!empty($this->config['auth_cid'])) {
|
||||
$this->ready = $this->sasl_bind($this->config['auth_cid'], $bind_pass, $bind_user);
|
||||
}
|
||||
else {
|
||||
$this->ready = $this->sasl_bind($bind_user, $bind_pass);
|
||||
}
|
||||
}
|
||||
|
||||
// connection established, we're done here
|
||||
if ($this->ready) {
|
||||
break;
|
||||
}
|
||||
|
||||
} // end foreach hosts
|
||||
|
||||
if (!is_resource($this->conn)) {
|
||||
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Could not connect to any LDAP server, last tried $host"), true);
|
||||
|
||||
$this->ready = false;
|
||||
}
|
||||
|
||||
return $this->ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches user data from LDAP addressbook
|
||||
*/
|
||||
function get_user_record($user, $host)
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
$filter = $rcmail->config->get('kolab_auth_filter');
|
||||
$filter = $this->parse_vars($filter, $user, $host);
|
||||
$base_dn = $this->parse_vars($this->config['base_dn'], $user, $host);
|
||||
$scope = $this->config['scope'];
|
||||
|
||||
// get record
|
||||
if ($result = parent::search($base_dn, $filter, $scope, $this->attributes)) {
|
||||
if ($result->count() == 1) {
|
||||
$entries = $result->entries(true);
|
||||
$dn = key($entries);
|
||||
$entry = array_pop($entries);
|
||||
$entry = $this->field_mapping($dn, $entry);
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches user data from LDAP addressbook
|
||||
*/
|
||||
function get_user_groups($dn, $user, $host)
|
||||
{
|
||||
if (empty($dn) || empty($this->config['groups'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$base_dn = $this->parse_vars($this->config['groups']['base_dn'], $user, $host);
|
||||
$name_attr = $this->config['groups']['name_attr'] ? $this->config['groups']['name_attr'] : 'cn';
|
||||
$member_attr = $this->get_group_member_attr();
|
||||
$filter = "(member=$dn)(uniqueMember=$dn)";
|
||||
|
||||
if ($member_attr != 'member' && $member_attr != 'uniqueMember')
|
||||
$filter .= "($member_attr=$dn)";
|
||||
$filter = strtr("(|$filter)", array("\\" => "\\\\"));
|
||||
|
||||
$result = parent::search($base_dn, $filter, 'sub', array('dn', $name_attr));
|
||||
|
||||
if (!$result) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
foreach ($result as $entry) {
|
||||
$entry = rcube_ldap_generic::normalize_entry($entry);
|
||||
if (!$entry['dn']) {
|
||||
$entry['dn'] = $result->get_dn();
|
||||
}
|
||||
$groups[$entry['dn']] = $entry[$name_attr];
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific LDAP record
|
||||
*
|
||||
* @param string DN
|
||||
*
|
||||
* @return array Record data
|
||||
*/
|
||||
function get_record($dn)
|
||||
{
|
||||
if (!$this->ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($rec = $this->get_entry($dn)) {
|
||||
$rec = rcube_ldap_generic::normalize_entry($rec);
|
||||
$rec = $this->field_mapping($dn, $rec);
|
||||
}
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace LDAP record data items
|
||||
*
|
||||
* @param string $dn DN
|
||||
* @param array $entry LDAP entry
|
||||
*
|
||||
* return bool True on success, False on failure
|
||||
*/
|
||||
function replace($dn, $entry)
|
||||
{
|
||||
// fields mapping
|
||||
foreach ($this->fieldmap as $field => $attr) {
|
||||
if (array_key_exists($field, $entry)) {
|
||||
$entry[$attr] = $entry[$field];
|
||||
unset($entry[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mod_replace($dn, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search records (simplified version of rcube_ldap::search)
|
||||
*
|
||||
* @param mixed $fields The field name of array of field names to search in
|
||||
* @param mixed $value Search value (or array of values when $fields is array)
|
||||
* @param int $mode Matching mode:
|
||||
* 0 - partial (*abc*),
|
||||
* 1 - strict (=),
|
||||
* 2 - prefix (abc*)
|
||||
* @param boolean $select True if results are requested, False if count only
|
||||
* @param array $required List of fields that cannot be empty
|
||||
* @param int $limit Number of records
|
||||
*
|
||||
* @return array List or false on error
|
||||
*/
|
||||
function search($fields, $value, $mode=1, $required = array(), $limit = 0)
|
||||
{
|
||||
$mode = intval($mode);
|
||||
|
||||
// use AND operator for advanced searches
|
||||
$filter = is_array($value) ? '(&' : '(|';
|
||||
|
||||
// set wildcards
|
||||
$wp = $ws = '';
|
||||
if (!empty($this->config['fuzzy_search']) && $mode != 1) {
|
||||
$ws = '*';
|
||||
if (!$mode) {
|
||||
$wp = '*';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array)$fields as $idx => $field) {
|
||||
$val = is_array($value) ? $value[$idx] : $value;
|
||||
if ($attrs = (array) $this->fieldmap[$field]) {
|
||||
if (count($attrs) > 1)
|
||||
$filter .= '(|';
|
||||
foreach ($attrs as $f)
|
||||
$filter .= "($f=$wp" . rcube_ldap_generic::quote_string($val) . "$ws)";
|
||||
if (count($attrs) > 1)
|
||||
$filter .= ')';
|
||||
}
|
||||
}
|
||||
$filter .= ')';
|
||||
|
||||
// add required (non empty) fields filter
|
||||
$req_filter = '';
|
||||
|
||||
foreach ((array)$required as $field) {
|
||||
if (in_array($field, (array)$fields)) // required field is already in search filter
|
||||
continue;
|
||||
if ($attrs = (array) $this->fieldmap[$field]) {
|
||||
if (count($attrs) > 1)
|
||||
$req_filter .= '(|';
|
||||
foreach ($attrs as $f)
|
||||
$req_filter .= "($f=*)";
|
||||
if (count($attrs) > 1)
|
||||
$req_filter .= ')';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($req_filter)) {
|
||||
$filter = '(&' . $req_filter . $filter . ')';
|
||||
}
|
||||
|
||||
// avoid double-wildcard if $value is empty
|
||||
$filter = preg_replace('/\*+/', '*', $filter);
|
||||
|
||||
// add general filter to query
|
||||
if (!empty($this->config['filter'])) {
|
||||
$filter = '(&(' . preg_replace('/^\(|\)$/', '', $this->config['filter']) . ')' . $filter . ')';
|
||||
}
|
||||
|
||||
$base_dn = $this->parse_vars($this->config['base_dn'], $_SESSION['username']);
|
||||
$scope = $this->config['scope'];
|
||||
$attrs = array_values($this->fieldmap);
|
||||
$list = array();
|
||||
|
||||
if ($result = parent::search($base_dn, $filter, $scope, $attrs)) {
|
||||
$i = 0;
|
||||
foreach ($result as $entry) {
|
||||
if ($limit && $limit <= $i) {
|
||||
break;
|
||||
}
|
||||
$dn = $result->get_dn();
|
||||
$list[$dn] = $this->field_mapping($dn, $entry);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filter used in search()
|
||||
*/
|
||||
function set_filter($filter)
|
||||
{
|
||||
$this->config['filter'] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps LDAP attributes to defined fields
|
||||
*/
|
||||
protected function field_mapping($dn, $entry)
|
||||
{
|
||||
$entry['dn'] = $dn;
|
||||
|
||||
// fields mapping
|
||||
foreach ($this->fieldmap as $field => $attr) {
|
||||
if (isset($entry[$attr])) {
|
||||
$entry[$field] = $entry[$attr];
|
||||
}
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects group member attribute name
|
||||
*/
|
||||
private function get_group_member_attr($object_classes = array())
|
||||
{
|
||||
if (empty($object_classes)) {
|
||||
$object_classes = $this->config['groups']['object_classes'];
|
||||
}
|
||||
if (!empty($object_classes)) {
|
||||
foreach ((array)$object_classes as $oc) {
|
||||
switch (strtolower($oc)) {
|
||||
case 'group':
|
||||
case 'groupofnames':
|
||||
case 'kolabgroupofnames':
|
||||
$member_attr = 'member';
|
||||
break;
|
||||
|
||||
case 'groupofuniquenames':
|
||||
case 'kolabgroupofuniquenames':
|
||||
$member_attr = 'uniqueMember';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($member_attr)) {
|
||||
return $member_attr;
|
||||
}
|
||||
|
||||
if (!empty($this->config['groups']['member_attr'])) {
|
||||
return $this->config['groups']['member_attr'];
|
||||
}
|
||||
|
||||
return 'member';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares filter query for LDAP search
|
||||
*/
|
||||
function parse_vars($str, $user, $host = null)
|
||||
{
|
||||
if (!empty($this->domain) && strpos($user, '@') === false) {
|
||||
if ($host && is_array($this->domain) && isset($this->domain[$host])) {
|
||||
$user .= '@'.rcube_utils::parse_host($this->domain[$host], $host);
|
||||
}
|
||||
else if (is_string($this->domain)) {
|
||||
$user .= '@'.rcube_utils::parse_host($this->domain, $host);
|
||||
}
|
||||
}
|
||||
|
||||
// replace variables in filter
|
||||
list($u, $d) = explode('@', $user);
|
||||
$dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string
|
||||
$replaces = array('%dc' => $dc, '%d' => $d, '%fu' => $user, '%u' => $u);
|
||||
|
||||
return strtr($str, $replaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML-safe DN string encoding
|
||||
*
|
||||
* @param string $str DN string
|
||||
*
|
||||
* @return string Encoded HTML identifier string
|
||||
*/
|
||||
static function dn_encode($str)
|
||||
{
|
||||
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes DN string encoded with _dn_encode()
|
||||
*
|
||||
* @param string $str Encoded HTML identifier string
|
||||
*
|
||||
* @return string DN string
|
||||
*/
|
||||
static function dn_decode($str)
|
||||
{
|
||||
$str = str_pad(strtr($str, '-_', '+/'), strlen($str) % 4, '=', STR_PAD_RIGHT);
|
||||
return base64_decode($str);
|
||||
}
|
||||
}
|
|
@ -18,10 +18,10 @@
|
|||
<email>machniak@kolabsys.com</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2012-12-19</date>
|
||||
<date>2013-06-25</date>
|
||||
<version>
|
||||
<release>0.6</release>
|
||||
<api>0.1</api>
|
||||
<release>0.7</release>
|
||||
<api>0.2</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
|
@ -35,6 +35,10 @@
|
|||
<tasks:replace from="@name@" to="name" type="package-info"/>
|
||||
<tasks:replace from="@package_version@" to="version" type="package-info"/>
|
||||
</file>
|
||||
<file name="kolab_auth_ldap.php" role="php">
|
||||
<tasks:replace from="@name@" to="name" type="package-info"/>
|
||||
<tasks:replace from="@package_version@" to="version" type="package-info"/>
|
||||
</file>
|
||||
<file name="config.inc.php.dist" role="data"></file>
|
||||
<file name="LICENSE" role="data"></file>
|
||||
|
||||
|
|
|
@ -61,25 +61,24 @@ class kolab_delegation_engine
|
|||
$delegate = $this->delegate_get($delegate);
|
||||
}
|
||||
|
||||
$dn = $delegate['ID'];
|
||||
$list = $this->list_delegates();
|
||||
$user = $this->user();
|
||||
|
||||
$dn = $delegate['ID'];
|
||||
if (empty($delegate) || empty($dn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = $this->list_delegates();
|
||||
$user = $this->user();
|
||||
|
||||
// add delegate to the list
|
||||
$list = array_keys((array)$list);
|
||||
$list = array_filter($list);
|
||||
if (!in_array($dn, $list)) {
|
||||
$list[] = $dn;
|
||||
}
|
||||
$list = array_map(array('rcube_ldap', 'dn_decode'), $list);
|
||||
$user[$this->ldap_delegate_field] = $list;
|
||||
$list = array_map(array('kolab_auth_ldap', 'dn_decode'), $list);
|
||||
|
||||
// update user record
|
||||
$result = $this->user_update($user);
|
||||
$result = $this->user_update_delegates($list);
|
||||
|
||||
// Set ACL on folders
|
||||
if ($result && !empty($acl)) {
|
||||
|
@ -141,11 +140,11 @@ class kolab_delegation_engine
|
|||
// remove delegate from the list
|
||||
unset($list[$dn]);
|
||||
$list = array_keys($list);
|
||||
$list = array_map(array('rcube_ldap', 'dn_decode'), $list);
|
||||
$list = array_map(array('kolab_auth_ldap', 'dn_decode'), $list);
|
||||
$user[$this->ldap_delegate_field] = $list;
|
||||
|
||||
// update user record
|
||||
$result = $this->user_update($user);
|
||||
$result = $this->user_update_delegates($list);
|
||||
|
||||
// remove ACL
|
||||
if ($result && $acl_del) {
|
||||
|
@ -164,25 +163,28 @@ class kolab_delegation_engine
|
|||
*/
|
||||
public function delegate_get($dn)
|
||||
{
|
||||
$ldap = $this->ldap();
|
||||
// use internal cache so we not query LDAP more than once per request
|
||||
if (!isset($this->cache[$dn])) {
|
||||
$ldap = $this->ldap();
|
||||
|
||||
if (!$ldap) {
|
||||
return array();
|
||||
if (!$ldap || empty($dn)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get delegate
|
||||
$user = $ldap->get_record(kolab_auth_ldap::dn_decode($dn));
|
||||
|
||||
if (empty($user)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$delegate = $this->parse_ldap_record($user);
|
||||
$delegate['ID'] = $dn;
|
||||
|
||||
$this->cache[$dn] = $delegate;
|
||||
}
|
||||
|
||||
$ldap->reset();
|
||||
|
||||
// Get delegate
|
||||
$user = $ldap->get_record($dn, true);
|
||||
|
||||
if (empty($user)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$delegate = $this->parse_ldap_record($user);
|
||||
$delegate['ID'] = $dn;
|
||||
|
||||
return $delegate;
|
||||
return $this->cache[$dn];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,13 +202,13 @@ class kolab_delegation_engine
|
|||
return array();
|
||||
}
|
||||
|
||||
$ldap->reset();
|
||||
|
||||
$list = $ldap->search($this->ldap_login_field, $login, 1);
|
||||
|
||||
if ($list->count == 1) {
|
||||
$user = $list->next();
|
||||
return $this->parse_ldap_record($user);
|
||||
if (count($list) == 1) {
|
||||
$dn = key($list);
|
||||
$user = $list[$dn];
|
||||
|
||||
return $this->parse_ldap_record($user, $dn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,9 +250,8 @@ class kolab_delegation_engine
|
|||
public function list_delegates()
|
||||
{
|
||||
$result = array();
|
||||
|
||||
$ldap = $this->ldap();
|
||||
$user = $this->user();
|
||||
$ldap = $this->ldap();
|
||||
$user = $this->user();
|
||||
|
||||
if (empty($ldap) || empty($user)) {
|
||||
return array();
|
||||
|
@ -261,12 +262,11 @@ class kolab_delegation_engine
|
|||
|
||||
if (!empty($delegates)) {
|
||||
foreach ((array)$delegates as $dn) {
|
||||
$ldap->reset();
|
||||
$delegate = $ldap->get_record(rcube_ldap::dn_encode($dn), true);
|
||||
$data = $this->parse_ldap_record($delegate);
|
||||
$delegate = $ldap->get_record($dn);
|
||||
$data = $this->parse_ldap_record($delegate, $dn);
|
||||
|
||||
if (!empty($data) && !empty($data['name'])) {
|
||||
$result[$delegate['ID']] = $data['name'];
|
||||
$result[$data['ID']] = $data['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -282,18 +282,17 @@ class kolab_delegation_engine
|
|||
public function list_delegators()
|
||||
{
|
||||
$result = array();
|
||||
|
||||
$ldap = $this->ldap();
|
||||
$ldap = $this->ldap();
|
||||
|
||||
if (empty($ldap) || empty($this->ldap_dn)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$ldap->reset();
|
||||
$list = $ldap->search($this->ldap_delegate_field, rcube_ldap::dn_decode($this->ldap_dn), 1);
|
||||
$list = $ldap->search($this->ldap_delegate_field, $this->ldap_dn, 1);
|
||||
|
||||
while ($delegator = $list->iterate()) {
|
||||
$result[$delegator['ID']] = $this->parse_ldap_record($delegator);
|
||||
foreach ($list as $dn => $delegator) {
|
||||
$delegator = $this->parse_ldap_record($delegator, $dn);
|
||||
$result[$delegator['ID']] = $delegator;
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -427,11 +426,9 @@ class kolab_delegation_engine
|
|||
$fields = array_unique(array_filter(array_merge((array)$this->ldap_name_field, (array)$this->ldap_login_field)));
|
||||
$users = array();
|
||||
|
||||
$ldap->reset();
|
||||
$ldap->set_pagesize($max);
|
||||
$result = $ldap->search($fields, $search, $mode, true, false, (array)$this->ldap_login_field);
|
||||
$result = $ldap->search($fields, $search, $mode, (array)$this->ldap_login_field, $max);
|
||||
|
||||
foreach ($result->records as $record) {
|
||||
foreach ($result as $record) {
|
||||
$user = $this->parse_ldap_record($record);
|
||||
|
||||
if ($user['name']) {
|
||||
|
@ -447,7 +444,7 @@ class kolab_delegation_engine
|
|||
/**
|
||||
* Extract delegate identifiers and pretty name from LDAP record
|
||||
*/
|
||||
private function parse_ldap_record($data)
|
||||
private function parse_ldap_record($data, $dn = null)
|
||||
{
|
||||
$email = array();
|
||||
$uid = $data[$this->ldap_login_field];
|
||||
|
@ -496,12 +493,12 @@ class kolab_delegation_engine
|
|||
}
|
||||
|
||||
return array(
|
||||
'ID' => kolab_auth_ldap::dn_encode($dn),
|
||||
'uid' => $uid,
|
||||
'name' => $name,
|
||||
'realname' => $realname,
|
||||
'imap_uid' => $imap_uid,
|
||||
'email' => $email,
|
||||
'ID' => $data['ID'],
|
||||
'organization' => $organization,
|
||||
);
|
||||
}
|
||||
|
@ -520,8 +517,6 @@ class kolab_delegation_engine
|
|||
return array();
|
||||
}
|
||||
|
||||
$ldap->reset();
|
||||
|
||||
// Get current user record
|
||||
$this->cache['user'] = $ldap->get_record($this->ldap_dn, true);
|
||||
}
|
||||
|
@ -547,27 +542,28 @@ class kolab_delegation_engine
|
|||
/**
|
||||
* Update LDAP record of current user
|
||||
*
|
||||
* @param array User data
|
||||
* @param array List of delegates
|
||||
*/
|
||||
public function user_update($user)
|
||||
public function user_update_delegates($list)
|
||||
{
|
||||
$ldap = $this->ldap();
|
||||
$pass = $this->rc->decrypt($_SESSION['password']);
|
||||
|
||||
if (!$ldap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dn = rcube_ldap::dn_decode($this->ldap_dn);
|
||||
$pass = $this->rc->decrypt($_SESSION['password']);
|
||||
|
||||
// need to bind as self for sufficient privilages
|
||||
if (!$ldap->bind($dn, $pass)) {
|
||||
if (!$ldap->bind($this->ldap_dn, $pass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user[$this->ldap_delegate_field] = $list;
|
||||
|
||||
unset($this->cache['user']);
|
||||
// update user record
|
||||
return $ldap->update($this->ldap_dn, $user);
|
||||
|
||||
// replace delegators list in user record
|
||||
return $ldap->replace($this->ldap_dn, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue