2 commits - lib/kolab_sync_logger.php lib/kolab_sync.php lib/plugins

Aleksander Machniak machniak at kolabsys.com
Wed Jan 8 10:43:25 CET 2014


 lib/kolab_sync.php                         |   30 +++++++++++++++++++++--
 lib/kolab_sync_logger.php                  |   28 +++++++++++++++++++++
 lib/plugins/kolab_auth/kolab_auth.php      |   37 +++++++++++++++++++++--------
 lib/plugins/kolab_auth/kolab_auth_ldap.php |   23 ++++++++++++++----
 4 files changed, 102 insertions(+), 16 deletions(-)

New commits:
commit 2595d7863134dc887135455802b3b6374efd4224
Author: Aleksander Machniak <alec at alec.pl>
Date:   Wed Jan 8 10:42:10 2014 +0100

    Use HTTP error 503 on LDAP/IMAP errors (Bug #2726), update kolab_auth plugin

diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php
index 4f0a5b2..740d6d3 100644
--- a/lib/kolab_sync.php
+++ b/lib/kolab_sync.php
@@ -191,6 +191,11 @@ class kolab_sync extends rcube
                     'valid' => $auth['valid'],
                 ));
             }
+
+            // LDAP server failure... send 503 error
+            if ($auth['kolab_ldap_error']) {
+                self::server_error();
+            }
         }
         else {
             $auth['pass'] = $password;
@@ -198,7 +203,7 @@ class kolab_sync extends rcube
 
         // Authenticate - get Roundcube user ID
         if ($auth['valid'] && !$auth['abort']
-            && ($userid = $this->login($auth['user'], $auth['pass'], $auth['host']))
+            && ($userid = $this->login($auth['user'], $auth['pass'], $auth['host'], $err))
         ) {
             // set real username
             $this->username = $auth['user'];
@@ -209,6 +214,11 @@ class kolab_sync extends rcube
             'host' => $auth['host'],
             'user' => $auth['user'],
         ));
+
+        // IMAP server failure... send 503 error
+        if ($err == rcube_imap_generic::ERROR_BAD) {
+            self::server_error();
+        }
     }
 
 
@@ -251,7 +261,7 @@ class kolab_sync extends rcube
     /**
      * Authenticates a user in IMAP and returns Roundcube user ID.
      */
-    private function login($username, $password, $host)
+    private function login($username, $password, $host, &$error = null)
     {
         if (empty($username)) {
             return null;
@@ -303,6 +313,7 @@ class kolab_sync extends rcube
         // authenticate user in IMAP
         $storage = $this->get_storage();
         if (!$storage->connect($host, $username, $password, $port, $ssl)) {
+            $error = $storage->get_error_code();
             return null;
         }
 
@@ -417,6 +428,19 @@ class kolab_sync extends rcube
 
 
     /**
+     * Send HTTP 503 response.
+     * We send it on LDAP/IMAP server error instead of 401 (Unauth),
+     * so devices will not ask for new password.
+     */
+    public static function server_error()
+    {
+        header("HTTP/1.1 503 Service Temporarily Unavailable");
+        header("Retry-After: 120");
+        exit;
+    }
+
+
+    /**
      * Function to be executed in script shutdown
      */
     public function shutdown()
diff --git a/lib/plugins/kolab_auth/kolab_auth.php b/lib/plugins/kolab_auth/kolab_auth.php
index 7ff5761..79b1018 100644
--- a/lib/plugins/kolab_auth/kolab_auth.php
+++ b/lib/plugins/kolab_auth/kolab_auth.php
@@ -155,24 +155,27 @@ class kolab_auth extends rcube_plugin
 
         if (!empty($role_plugins)) {
             foreach ($role_plugins as $role_dn => $plugins) {
-                $role_plugins[self::parse_ldap_vars($role_dn)] = $plugins;
+                $role_dn = self::parse_ldap_vars($role_dn);
+                if (!empty($role_plugins[$role_dn])) {
+                    $role_plugins[$role_dn] = array_unique(array_merge((array)$role_plugins[$role_dn], $plugins));
+                } else {
+                    $role_plugins[$role_dn] = $plugins;
+                }
             }
         }
 
         if (!empty($role_settings)) {
             foreach ($role_settings as $role_dn => $settings) {
-                $role_settings[self::parse_ldap_vars($role_dn)] = $settings;
+                if (!empty($role_settings[$role_dn])) {
+                        $role_settings[$role_dn] = array_merge((array)$role_settings[$role_dn], $settings);
+                } else {
+                    $role_settings[$role_dn] = $settings;
+                }
             }
         }
 
         foreach ($_SESSION['user_roledns'] as $role_dn) {
-            if (isset($role_plugins[$role_dn]) && is_array($role_plugins[$role_dn])) {
-                foreach ($role_plugins[$role_dn] as $plugin) {
-                    $this->require_plugin($plugin);
-                }
-            }
-
-            if (isset($role_settings[$role_dn]) && is_array($role_settings[$role_dn])) {
+            if (!empty($role_settings[$role_dn]) && is_array($role_settings[$role_dn])) {
                 foreach ($role_settings[$role_dn] as $setting_name => $setting) {
                     if (!isset($setting['mode'])) {
                         $setting['mode'] = 'override';
@@ -194,7 +197,7 @@ class kolab_auth extends rcube_plugin
 
                     $dont_override = (array) $rcmail->config->get('dont_override');
 
-                    if (!isset($setting['allow_override']) || !$setting['allow_override']) {
+                    if (empty($setting['allow_override'])) {
                         $rcmail->config->set('dont_override', array_merge($dont_override, array($setting_name)));
                     }
                     else {
@@ -208,6 +211,19 @@ class kolab_auth extends rcube_plugin
                             $rcmail->config->set('dont_override', $_dont_override);
                         }
                     }
+
+                    if ($setting_name == 'skin') {
+                        if ($rcmail->output->type == 'html') {
+                            $rcmail->output->set_skin($setting['value']);
+                            $rcmail->output->set_env('skin', $setting['value']);
+                        }
+                    }
+                }
+            }
+
+            if (!empty($role_plugins[$role_dn])) {
+                foreach ((array)$role_plugins[$role_dn] as $plugin) {
+                    $this->require_plugin($plugin);
                 }
             }
         }
@@ -340,6 +356,7 @@ class kolab_auth extends rcube_plugin
         $ldap = self::ldap();
         if (!$ldap || !$ldap->ready) {
             $args['abort'] = true;
+            $args['kolab_ldap_error'] = true;
             $message = sprintf(
                     'Login failure for user %s from %s in session %s (error %s)',
                     $user,
diff --git a/lib/plugins/kolab_auth/kolab_auth_ldap.php b/lib/plugins/kolab_auth/kolab_auth_ldap.php
index b9b3e4a..2f2ca14 100644
--- a/lib/plugins/kolab_auth/kolab_auth_ldap.php
+++ b/lib/plugins/kolab_auth/kolab_auth_ldap.php
@@ -207,7 +207,7 @@ class kolab_auth_ldap extends rcube_ldap_generic
     /**
      * Search records (simplified version of rcube_ldap::search)
      *
-     * @param mixed   $fields   The field name of array of field names to search in
+     * @param mixed   $fields   The field name or 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*),
@@ -221,6 +221,10 @@ class kolab_auth_ldap extends rcube_ldap_generic
      */
     function search($fields, $value, $mode=1, $required = array(), $limit = 0)
     {
+        if (empty($fields)) {
+            return array();
+        }
+
         $mode = intval($mode);
 
         // use AND operator for advanced searches
@@ -236,8 +240,13 @@ class kolab_auth_ldap extends rcube_ldap_generic
         }
 
         foreach ((array)$fields as $idx => $field) {
-            $val = is_array($value) ? $value[$idx] : $value;
-            if ($attrs = (array) $this->fieldmap[$field]) {
+            $val   = is_array($value) ? $value[$idx] : $value;
+            $attrs = (array) $this->fieldmap[$field];
+
+            if (empty($attrs)) {
+                $filter .= "($field=$wp" . rcube_ldap_generic::quote_string($val) . "$ws)";
+            }
+            else {
                 if (count($attrs) > 1)
                     $filter .= '(|';
                 foreach ($attrs as $f)
@@ -254,7 +263,13 @@ class kolab_auth_ldap extends rcube_ldap_generic
         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]) {
+
+            $attrs = (array) $this->fieldmap[$field];
+
+            if (empty($attrs)) {
+                $req_filter .= "($field=*)";
+            }
+            else {
                 if (count($attrs) > 1)
                     $req_filter .= '(|';
                 foreach ($attrs as $f)


commit 37cf49f505c4b888650f50265ab41f1985dce7fd
Author: Aleksander Machniak <alec at alec.pl>
Date:   Wed Jan 8 08:37:05 2014 +0100

    Add user/device info to the error/warning log lines

diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php
index a845d0c..4f0a5b2 100644
--- a/lib/kolab_sync.php
+++ b/lib/kolab_sync.php
@@ -352,6 +352,8 @@ class kolab_sync extends rcube
             return;
         }
 
+        $this->logger->set_username($username);
+
         $user_debug = $this->config->get('activesync_user_debug');
         $user_log   = $user_debug || $this->config->get('activesync_user_log');
 
diff --git a/lib/kolab_sync_logger.php b/lib/kolab_sync_logger.php
index 95fd519..d0fa790 100644
--- a/lib/kolab_sync_logger.php
+++ b/lib/kolab_sync_logger.php
@@ -97,6 +97,26 @@ class kolab_sync_logger extends Zend_Log
             $message = var_export($message, true);
         }
 
+        // add user/request information to the log
+        if ($mode <= self::WARN) {
+            $device = array();
+            $params = array('cmd' => 'Cmd', 'device' => 'DeviceId', 'type' => 'DeviceType');
+
+            if (!empty($this->username)) {
+                $device['user'] = $this->username;
+            }
+
+            foreach ($params as $key => $val) {
+                if ($val = $_GET[$val]) {
+                    $device[$key] = $val;
+                }
+            }
+
+            if (!empty($device)) {
+                $message = @json_encode($device) . ' ' . $message;
+            }
+        }
+
         $date    = date($format);
         $logline = sprintf("[%s]: [%s] %s\n", $date, $method, $message);
 
@@ -112,4 +132,12 @@ class kolab_sync_logger extends Zend_Log
             trigger_error($message, E_USER_ERROR);
         }
     }
+
+    /**
+     * Set current user name to add into error log
+     */
+    public function set_username($username)
+    {
+        $this->username = $username;
+    }
 }




More information about the commits mailing list