Ldap sessionhandler driver now uses Horde_Ldap
authorMichael M Slusarz <slusarz@curecanti.org>
Mon, 31 May 2010 23:40:02 +0000 (17:40 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Wed, 2 Jun 2010 03:32:15 +0000 (21:32 -0600)
framework/Core/lib/Horde/Core/Binder/Ldap.php
framework/Core/lib/Horde/Core/Binder/SessionHandler.php
framework/Core/lib/Horde/Core/Factory/Ldap.php [new file with mode: 0644]
framework/Core/package.xml
framework/SessionHandler/lib/Horde/SessionHandler/Ldap.php
framework/SessionHandler/package.xml
horde/config/conf.xml

index f8b8ae5..354f98b 100644 (file)
@@ -7,7 +7,7 @@ class Horde_Core_Binder_Ldap implements Horde_Injector_Binder
 {
     public function create(Horde_Injector $injector)
     {
-        return new Horde_Ldap();
+        return new Horde_Core_Factory_Ldap($injector);
     }
 
     public function equals(Horde_Injector_Binder $binder)
index f100558..d3dbf6d 100644 (file)
@@ -23,6 +23,8 @@ class Horde_Core_Binder_SessionHandler implements Horde_Injector_Binder
             $params['db'] = $injector->getInstance('Horde_Db')->getOb('horde', 'sessionhandler');
         } elseif (strcasecmp($driver, 'Memcache') === 0) {
             $params['memcache'] = $injector->getInstance('Horde_Memcache');
+        } elseif (strcasecmp($driver, 'Ldap') === 0) {
+            $params['ldap'] = $injector->getInstances('Horde_Ldap')->getOb('horde', 'sessionhandler');
         }
 
         $logger = $injector->getInstance('Horde_Log_Logger');
diff --git a/framework/Core/lib/Horde/Core/Factory/Ldap.php b/framework/Core/lib/Horde/Core/Factory/Ldap.php
new file mode 100644 (file)
index 0000000..bbfff51
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+/**
+ * A Horde_Injector:: based factory for creating Horde_Ldap objects.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Core
+ */
+
+/**
+ * A Horde_Injector:: based factory for creating Horde_Ldap objects.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Core
+ */
+class Horde_Core_Factory_Ldap
+{
+    /**
+     * Instances.
+     *
+     * @var array
+     */
+    private $_instances = array();
+
+    /**
+     * The injector.
+     *
+     * @var Horde_Injector
+     */
+    private $_injector;
+
+    /**
+     * Constructor.
+     *
+     * @param Horde_Injector $injector  The injector to use.
+     */
+    public function __construct(Horde_Injector $injector)
+    {
+        $this->_injector = $injector;
+    }
+
+    /**
+     * Return the LDAP instance.
+     *
+     * @param string $app   The application.
+     * @param string $type  The type.
+     *
+     * @return Horde_Ldap  The singleton instance.
+     * @throws Horde_Exception
+     * @throws Horde_Ldap_Exception
+     */
+    public function getOb($app = 'horde', $type = null)
+    {
+        $sig = $app . '|' . $type;
+
+        if (isset($this->_instances[$sig])) {
+            return $this->_instances[$sig];
+        }
+
+        $pushed = ($app == 'horde')
+            ? false
+            : $GLOBALS['registry']->pushApp($app);
+
+        $config = $this->getConfig($type);
+
+        /* Determine if we are using the base LDAP config. */
+        if (isset($config['driverconfig']) &&
+            ($config['driverconfig'] == 'horde')) {
+            $this->_instances[$sig] = $this->getOb();
+            return $this->_instances[$sig];
+        }
+
+        try {
+            $this->_instances[$sig] = new Horde_Ldap($config);
+        } catch (Horde_Exception $e) {
+            if ($pushed) {
+                $GLOBALS['registry']->popApp();
+            }
+            throw $e;
+        }
+
+        if ($pushed) {
+            $GLOBALS['registry']->popApp();
+        }
+
+        return $this->_instances[$sig];
+    }
+
+    /**
+     */
+    public function getConfig($type)
+    {
+        return Horde::getDriverConfig($type, 'ldap');
+    }
+
+}
index 6ef3630..292879e 100644 (file)
@@ -116,6 +116,7 @@ Application Framework.
        <file name="KolabServer.php" role="php" />
        <file name="KolabSession.php" role="php" />
        <file name="KolabStorage.php" role="php" />
+       <file name="Ldap.php" role="php" />
        <file name="LoginTasks.php" role="php" />
        <file name="Share.php" role="php" />
        <file name="Vfs.php" role="php" />
@@ -306,6 +307,7 @@ Application Framework.
    <install name="lib/Horde/Core/Factory/KolabServer.php" as="Horde/Core/Factory/KolabServer.php" />
    <install name="lib/Horde/Core/Factory/KolabSession.php" as="Horde/Core/Factory/KolabSession.php" />
    <install name="lib/Horde/Core/Factory/KolabStorage.php" as="Horde/Core/Factory/KolabStorage.php" />
+   <install name="lib/Horde/Core/Factory/Ldap.php" as="Horde/Core/Factory/Ldap.php" />
    <install name="lib/Horde/Core/Factory/LoginTasks.php" as="Horde/Core/Factory/LoginTasks.php" />
    <install name="lib/Horde/Core/Factory/Share.php" as="Horde/Core/Factory/Share.php" />
    <install name="lib/Horde/Core/Factory/Vfs.php" as="Horde/Core/Factory/Vfs.php" />
index aebee03..7d811c5 100644 (file)
 class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
 {
     /**
-     * Handle for the current database connection.
+     * Horde_Ldap object.
      *
-     * @var resource
+     * @var Horde_Ldap
      */
-    protected $_conn;
+    protected $_ldap;
 
     /**
      * Constructor.
      *
      * @param array $params  Parameters:
      * <pre>
-     * 'dn' - (string) The bind DN.
-     * 'hostspec' - (string) The hostname of the ldap server.
-     * 'password' - (string) The bind password.
-     * 'port' - (integer) The port number of the ldap server.
-     * 'version' - (integer) [OPTIONAL] TODO
+     * 'dn' - (string) [REQUIRED] TODO
+     * 'ldap' - (Horde_Ldap) [REQUIRED] The Horde_Ldap object.
      * </pre>
      *
      * @throws InvalidArgumentException
      */
     public function __construct(array $params = array())
     {
-        foreach (array('dn', 'hostspec', 'password', 'port') as $val) {
+        foreach (array('dn', 'ldap') as $val) {
             if (!isset($params[$val])) {
                 throw new InvalidArgumentException('Missing ' . $val . ' parameter.');
             }
         }
 
+        $this->_ldap = $params['ldap'];
+        unset($params['ldap']);
+
         parent::__construct($params);
     }
 
@@ -57,16 +57,10 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
      */
     protected function _open($save_path = null, $session_name = null)
     {
-        $this->_conn = @ldap_connect($this->_params['hostspec'], $this->_params['port']);
-
-        // Set protocol version if necessary.
-        if (isset($this->_params['version']) &&
-            !@ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION, $this->_params['version'])) {
-            throw new Horde_SessionHandler_Exception(sprintf('Set LDAP protocol version to %d failed: [%d] %s', $this->_params['version'], ldap_errno($conn), ldap_error($conn)));
-        }
-
-        if (!@ldap_bind($this->_conn, $this->_params['dn'], $this->_params['password'])) {
-            throw new Horde_SessionHandler_Exception('Could not bind to LDAP server.');
+        try {
+            $this->_ldap->bind();
+        } catch (Horde_Ldap_Exception $e) {
+            throw new Horde_SessionHandler_Exception($e);
         }
     }
 
@@ -75,9 +69,7 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
      */
     protected function _close()
     {
-        if (!@ldap_close($this->_conn) && $this->_logger) {
-            $this->_logger->log('Could not unbind from LDAP server.', 'INFO');
-        }
+        $this->_ldap->done();
     }
 
     /**
@@ -89,12 +81,19 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
      */
     protected function _read($id)
     {
-        $sr = @ldap_search($this->_conn, $this->_params['dn'], "(cn=$id)");
-        $info = @ldap_get_entries($this->_conn, $sr);
+        try {
+            $result = $this->_ldap->search(null, "(cn=$id)");
+            if ($result->count()) {
+                $entry = reset();
+                return $entry['session'][0];
+            }
+        } catch (Horde_Ldap_Exception $e) {
+            if ($this->_logger) {
+                $this->_logger->log($e, 'ERR');
+            }
+        }
 
-        return ($info['count'] > 0)
-            ? $info[0]['session'][0]
-            : '';
+        return '';
     }
 
     /**
@@ -112,9 +111,10 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
             'session' => $session_data
         );
         $dn = "cn=$id," . $this->_params['dn'];
-        @ldap_delete($this->_conn, $dn);
 
-        return @ldap_add($this->_conn, $dn, $update);
+        $this->_ldap->delete($dn);
+
+        return $this->_ldap->add(Horde_Ldap_Entry::createFresh($dn, $update));
     }
 
     /**
@@ -128,7 +128,7 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
     {
         $dn = "cn=$id," . $this->_params['dn'];
 
-        return @ldap_delete($this->_conn, $dn);
+        return $this->_ldap->delete($dn);
     }
 
     /**
@@ -140,24 +140,20 @@ class Horde_SessionHandler_Ldap extends Horde_SessionHandler_Driver
      */
     public function gc($maxlifetime = 300)
     {
-        $sr = @ldap_search($this->_conn, $this->_params['dn'],
-                           '(objectClass=phpsession)', array('+', 'cn'));
-        $info = @ldap_get_entries($this->_conn, $sr);
-
-        if ($info['count'] > 0) {
-            for ($i = 0; $i < $info['count']; ++$i) {
-                $id = $info[$i]['cn'][0];
-                $dn = "cn=$id," . $this->_params['dn'];
-                $ldapstamp = $info[$i]['modifytimestamp'][0];
-                $year = substr($ldapstamp, 0, 4);
-                $month = substr($ldapstamp, 4, 2);
-                $day = substr($ldapstamp, 6, 2);
-                $hour = substr($ldapstamp, 8, 2);
-                $minute = substr($ldapstamp, 10, 2);
-                $modified = gmmktime($hour, $minute, 0, $month, $day, $year);
-                if (time() - $modified >= $maxlifetime) {
-                    @ldap_delete($this->_conn, $dn);
-                }
+        $info = $this->_ldap->search(null, '(objectClass=phpsession)', array('attributes' => array('+', 'cn')));
+
+        foreach ($info as $val) {
+            $id = $val['cn'][0];
+            $dn = "cn=$id," . $this->_params['dn'];
+            $ldapstamp = $val['modifytimestamp'][0];
+            $year = substr($ldapstamp, 0, 4);
+            $month = substr($ldapstamp, 4, 2);
+            $day = substr($ldapstamp, 6, 2);
+            $hour = substr($ldapstamp, 8, 2);
+            $minute = substr($ldapstamp, 10, 2);
+            $modified = gmmktime($hour, $minute, 0, $month, $day, $year);
+            if (time() - $modified >= $maxlifetime) {
+                $this->_ldap->delete($dn);
             }
         }
 
index 8bba041..2e5d5e1 100644 (file)
     <channel>pear.horde.org</channel>
    </package>
    <package>
+    <name>Ldap</name>
+    <channel>pear.horde.org</channel>
+   </package>
+   <package>
     <name>Log</name>
     <channel>pear.horde.org</channel>
    </package>
index e7e3e97..db994a6 100644 (file)
     </case>
     <case name="Ldap" desc="LDAP">
      <configsection name="params">
-      <configstring name="hostspec" desc="The hostname of the LDAP server">
-      localhost</configstring>
-      <configinteger name="port" required="false" desc="Port LDAP is running
-      on, if non-standard">389</configinteger>
-      <configstring name="dn" required="false" desc="The DN used to bind
-      to the LDAP server"/>
-      <configstring name="password" required="false" desc="The password used
-      to bind to the LDAP server"/>
-      <configenum name="version" desc="LDAP Protocol Version">3
-       <values>
-        <value desc="LDAPv2 (Deprecated)">2</value>
-        <value desc="LDAPv3">3</value>
-       </values>
-      </configenum>
+      <configldap switchname="driverconfig">
+      </configldap>
      </configsection>
     </case>
     <case name="Memcache" desc="Memcache only">