diff program/lib/Roundcube/rcube_ldap_generic.php @ 0:4681f974d28b

vanilla 1.3.3 distro, I hope
author Charlie Root
date Thu, 04 Jan 2018 15:52:31 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/program/lib/Roundcube/rcube_ldap_generic.php	Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,366 @@
+<?php
+
+/**
+ +-----------------------------------------------------------------------+
+ | Roundcube/rcube_ldap_generic.php                                      |
+ |                                                                       |
+ | This file is part of the Roundcube Webmail client                     |
+ | Copyright (C) 2006-2014, The Roundcube Dev Team                       |
+ | Copyright (C) 2012-2015, Kolab Systems AG                             |
+ |                                                                       |
+ | Licensed under the GNU General Public License version 3 or            |
+ | any later version with exceptions for skins & plugins.                |
+ | See the README file for a full license statement.                     |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Provide basic functionality for accessing LDAP directories          |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ |         Aleksander Machniak <machniak@kolabsys.com>                   |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Model class to access an LDAP directories
+ *
+ * @package    Framework
+ * @subpackage LDAP
+ */
+class rcube_ldap_generic extends Net_LDAP3
+{
+    /** private properties */
+    protected $cache = null;
+    protected $attributes = array('dn');
+    protected $error;
+
+    function __construct($config = null)
+    {
+        parent::__construct($config);
+
+        $this->config_set('log_hook', array($this, 'log'));
+    }
+
+    /**
+     * Establish a connection to the LDAP server
+     */
+    public function connect($host = null)
+    {
+        // Net_LDAP3 does not support IDNA yet
+        // also parse_host() here is very Roundcube specific
+        $host = rcube_utils::parse_host($host, $this->config['mail_domain']);
+        $host = rcube_utils::idn_to_ascii($host);
+
+        return parent::connect($host);
+    }
+
+    /**
+     * Get a specific LDAP entry, identified by its DN
+     *
+     * @param string $dn Record identifier
+     * @param array  $attributes Attributes to return
+     *
+     * @return array Hash array
+     */
+    function get_entry($dn, $attributes = array())
+    {
+        return parent::get_entry($dn, !empty($attributes) ? $attributes : $this->attributes);
+    }
+
+    /**
+     * Prints debug/error info to the log
+     */
+    public function log($level, $msg)
+    {
+        $msg = implode("\n", $msg);
+
+        switch ($level) {
+        case LOG_DEBUG:
+        case LOG_INFO:
+        case LOG_NOTICE:
+            if ($this->config['debug']) {
+                rcube::write_log('ldap', $msg);
+            }
+            break;
+
+        case LOG_EMERGE:
+        case LOG_ALERT:
+        case LOG_CRIT:
+            rcube::raise_error($msg, true, true);
+            break;
+
+        case LOG_ERR:
+        case LOG_WARNING:
+            $this->error = $msg;
+            rcube::raise_error($msg, true, false);
+            break;
+        }
+    }
+
+    /**
+     * Returns the last LDAP error occurred
+     *
+     * @return mixed Error message string or null if no error occurred
+     */
+    function get_error()
+    {
+        return $this->error;
+    }
+
+    /**
+     * @deprecated
+     */
+    public function set_debug($dbg = true)
+    {
+        $this->config['debug'] = (bool) $dbg;
+    }
+
+    /**
+     * @deprecated
+     */
+    public function set_cache($cache_engine)
+    {
+        $this->config['cache'] = $cache_engine;
+    }
+
+    /**
+     * @deprecated
+     */
+    public static function scope2func($scope, &$ns_function = null)
+    {
+        return self::scope_to_function($scope, $ns_function);
+    }
+
+    /**
+     * @deprecated
+     */
+    public function set_config($opt, $val = null)
+    {
+        $this->config_set($opt, $val);
+    }
+
+    /**
+     * @deprecated
+     */
+    public function add($dn, $entry)
+    {
+        return $this->add_entry($dn, $entry);
+    }
+
+    /**
+     * @deprecated
+     */
+    public function delete($dn)
+    {
+        return $this->delete_entry($dn);
+    }
+
+    /**
+     * Wrapper for ldap_mod_replace()
+     *
+     * @see ldap_mod_replace()
+     */
+    public function mod_replace($dn, $entry)
+    {
+        $this->_debug("C: Replace $dn: ".print_r($entry, true));
+
+        if (!ldap_mod_replace($this->conn, $dn, $entry)) {
+            $this->_error("ldap_mod_replace() failed with " . ldap_error($this->conn));
+            return false;
+        }
+
+        $this->_debug("S: OK");
+        return true;
+    }
+
+    /**
+     * Wrapper for ldap_mod_add()
+     *
+     * @see ldap_mod_add()
+     */
+    public function mod_add($dn, $entry)
+    {
+        $this->_debug("C: Add $dn: ".print_r($entry, true));
+
+        if (!ldap_mod_add($this->conn, $dn, $entry)) {
+            $this->_error("ldap_mod_add() failed with " . ldap_error($this->conn));
+            return false;
+        }
+
+        $this->_debug("S: OK");
+        return true;
+    }
+
+    /**
+     * Wrapper for ldap_mod_del()
+     *
+     * @see ldap_mod_del()
+     */
+    public function mod_del($dn, $entry)
+    {
+        $this->_debug("C: Delete $dn: ".print_r($entry, true));
+
+        if (!ldap_mod_del($this->conn, $dn, $entry)) {
+            $this->_error("ldap_mod_del() failed with " . ldap_error($this->conn));
+            return false;
+        }
+
+        $this->_debug("S: OK");
+        return true;
+    }
+
+    /**
+     * Wrapper for ldap_rename()
+     *
+     * @see ldap_rename()
+     */
+    public function rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true)
+    {
+        $this->_debug("C: Rename $dn to $newrdn");
+
+        if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) {
+            $this->_error("ldap_rename() failed with " . ldap_error($this->conn));
+            return false;
+        }
+
+        $this->_debug("S: OK");
+        return true;
+    }
+
+    /**
+     * Wrapper for ldap_list() + ldap_get_entries()
+     *
+     * @see ldap_list()
+     * @see ldap_get_entries()
+     */
+    public function list_entries($dn, $filter, $attributes = array('dn'))
+    {
+        $list = array();
+        $this->_debug("C: List $dn [{$filter}]");
+
+        if ($result = ldap_list($this->conn, $dn, $filter, $attributes)) {
+            $list = ldap_get_entries($this->conn, $result);
+
+            if ($list === false) {
+                $this->_error("ldap_get_entries() failed with " . ldap_error($this->conn));
+                return array();
+            }
+
+            $count = $list['count'];
+            unset($list['count']);
+
+            $this->_debug("S: $count record(s)");
+        }
+        else {
+            $this->_error("ldap_list() failed with " . ldap_error($this->conn));
+        }
+
+        return $list;
+    }
+
+    /**
+     * Wrapper for ldap_read() + ldap_get_entries()
+     *
+     * @see ldap_read()
+     * @see ldap_get_entries()
+     */
+    public function read_entries($dn, $filter, $attributes = null)
+    {
+        $this->_debug("C: Read $dn [{$filter}]");
+
+        if ($this->conn && $dn) {
+            $result = @ldap_read($this->conn, $dn, $filter, $attributes, 0, (int)$this->config['sizelimit'], (int)$this->config['timelimit']);
+            if ($result === false) {
+                $this->_error("ldap_read() failed with " . ldap_error($this->conn));
+                return false;
+            }
+
+            $this->_debug("S: OK");
+            return ldap_get_entries($this->conn, $result);
+        }
+
+        return false;
+    }
+
+    /**
+     * Turn an LDAP entry into a regular PHP array with attributes as keys.
+     *
+     * @param array $entry Attributes array as retrieved from ldap_get_attributes() or ldap_get_entries()
+     * @param bool  $flat  Convert one-element-array values into strings (not implemented)
+     *
+     * @return array Hash array with attributes as keys
+     */
+    public static function normalize_entry($entry, $flat = false)
+    {
+        if (!isset($entry['count'])) {
+            return $entry;
+        }
+
+        $rec = array();
+
+        for ($i=0; $i < $entry['count']; $i++) {
+            $attr = $entry[$i];
+            if ($entry[$attr]['count'] == 1) {
+                switch ($attr) {
+                    case 'objectclass':
+                        $rec[$attr] = array(strtolower($entry[$attr][0]));
+                        break;
+                    default:
+                        $rec[$attr] = $entry[$attr][0];
+                        break;
+                }
+            }
+            else {
+                for ($j=0; $j < $entry[$attr]['count']; $j++) {
+                    $rec[$attr][$j] = $entry[$attr][$j];
+                }
+            }
+        }
+
+        return $rec;
+    }
+
+    /**
+     * Compose an LDAP filter string matching all words from the search string
+     * in the given list of attributes.
+     *
+     * @param string  $value    Search value
+     * @param mixed   $attrs    List of LDAP attributes to search
+     * @param int     $mode     Matching mode:
+     *                          0 - partial (*abc*),
+     *                          1 - strict (=),
+     *                          2 - prefix (abc*)
+     * @return string LDAP filter
+     */
+    public static function fulltext_search_filter($value, $attributes, $mode = 1)
+    {
+        if (empty($attributes)) {
+            $attributes = array('cn');
+        }
+
+        $groups = array();
+        $value = str_replace('*', '', $value);
+        $words = $mode == 0 ? rcube_utils::tokenize_string($value, 1) : array($value);
+
+        // set wildcards
+        $wp = $ws = '';
+        if ($mode != 1) {
+            $ws = '*';
+            $wp = !$mode ? '*' : '';
+        }
+
+        // search each word in all listed attributes
+        foreach ($words as $word) {
+            $parts = array();
+            foreach ($attributes as $attr) {
+                $parts[] = "($attr=$wp" . self::quote_string($word) . "$ws)";
+            }
+            $groups[] = '(|' . join('', $parts) . ')';
+        }
+
+        return count($groups) > 1 ? '(&' . join('', $groups) . ')' : join('', $groups);
+    }
+}
+
+// for backward compat.
+class rcube_ldap_result extends Net_LDAP3_Result {}