2 commits - plugins/kolab_auth

Thomas Brüderli bruederli at kolabsys.com
Tue Oct 14 15:36:24 CEST 2014


 plugins/kolab_auth/config.inc.php.dist    |   28 ++++----
 plugins/kolab_auth/kolab_auth.php         |  103 ++++++++++++++++++++++--------
 plugins/kolab_auth/localization/en_US.inc |    1 
 3 files changed, 91 insertions(+), 41 deletions(-)

New commits:
commit 8d13292b3833a4bff27865377fae75ae8905d015
Merge: 1e0b0cd 6c8d7d4
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Sat Oct 11 03:18:28 2014 +0200

    Merge branch 'master' of ssh://git.kolab.org/git/roundcubemail-plugins-kolab



commit 1e0b0cdf9d428de6d8c12e673b72cdcdb0aa79bd
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Sat Oct 11 03:14:45 2014 +0200

    Check effective rights for the login-as feature to improve the delegation model
    and allow controlling the administration privileges in LDAP (#1834).
    
    This deprecates the config options 'kolab_auth_group', 'kolab_auth_role_value'
    and 'kolab_auth_allowed_tasks'.
    
    Admin privileges (per Roundcube task) and the required effective rights
    are now defined in 'kolab_auth_admin_rights'.

diff --git a/plugins/kolab_auth/config.inc.php.dist b/plugins/kolab_auth/config.inc.php.dist
index 17c0915..b353d61 100644
--- a/plugins/kolab_auth/config.inc.php.dist
+++ b/plugins/kolab_auth/config.inc.php.dist
@@ -29,6 +29,9 @@ $config['kolab_auth_name']         = array('name', 'cn');
 $config['kolab_auth_email']        = array('email');
 $config['kolab_auth_organization'] = array('organization');
 
+// Role field (from fieldmap configuration)
+$config['kolab_auth_role'] = 'role';
+
 // Template for user names displayed in the UI.
 // You can use all attributes from the 'fieldmap' property of the 'kolab_auth_addressbook' configuration
 $config['kolab_auth_user_displayname'] = '{name} ({ou})';
@@ -40,20 +43,17 @@ $config['kolab_auth_admin_password'] = '';
 // Enable audit logging for abuse of administrative privileges.
 $config['kolab_auth_auditlog'] = false;
 
-// Role field (from fieldmap configuration)
-$config['kolab_auth_role'] = 'role';
-// The required value for the role attribute to contain should the user be allowed
-// to login as another user.
-$config['kolab_auth_role_value'] = '';
-
-// Administrative group name to which user must be assigned to
-// which adds privilege to login as another user.
-$config['kolab_auth_group'] = '';
-
-// List of tasks to which admin has access when logged in as another user.
-// To limit usage to Settings only use: array('settings'). Default: array() - all tasks.
-// When defined all non-authorized requests will be redirected to first task on the list.
-$config['kolab_auth_allowed_tasks'] = array();
+// As set of rules to define the required rights on the target entry
+// which allow an admin user to login as another user (the target).
+// The effective rights value refers to either entry level attribute level rights:
+//  * entry:[read|add|delete]
+//  * attrib:<attribute-name>:[read|write|delete]
+$config['kolab_auth_admin_rights'] = array(
+    // Roundcube task => required effective right
+    'settings'        => 'entry:read',
+    'mail'            => 'entry:delete',
+    'addressbook'     => 'entry:delete',
+);
 
 // Enable plugins on a role-by-role basis. In this example, the 'acl' plugin
 // is enabled for people with a 'cn=professional-user,dc=mykolab,dc=ch' role.
diff --git a/plugins/kolab_auth/kolab_auth.php b/plugins/kolab_auth/kolab_auth.php
index 86f1649..31f50ad 100644
--- a/plugins/kolab_auth/kolab_auth.php
+++ b/plugins/kolab_auth/kolab_auth.php
@@ -91,12 +91,12 @@ class kolab_auth extends rcube_plugin
         $rcmail = rcube::get_instance();
 
         // Check access rights when logged in as another user
-        if (!empty($_SESSION['kolab_auth_admin']) && $rcmail->task != 'login' && $rcmail->task != 'logout') {
-            $tasks = $rcmail->config->get('kolab_auth_allowed_tasks');
+        if (!empty($_SESSION['kolab_auth_admin']) && $args['task'] != 'login' && $args['task'] != 'logout') {
             // access to specified task is forbidden,
             // redirect to the first task on the list
-            if (!empty($tasks)) {
-                if (!in_array($rcmail->task, (array) $tasks)) {
+            if (!empty($_SESSION['kolab_auth_allowed_tasks'])) {
+                $tasks = (array)$_SESSION['kolab_auth_allowed_tasks'];
+                if (!in_array($args['task'], $tasks)) {
                     header('Location: ?_task=' . array_shift($tasks));
                     die;
                 }
@@ -451,24 +451,69 @@ class kolab_auth extends rcube_plugin
                 return $args;
             }
 
-            // check if the original user has/belongs to administrative role/group
             $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 = $ldap->parse_vars($role_dn, $user, $host);
-                if (in_array($role_dn, (array)$record[$role_attr])) {
-                    $isadmin = true;
+            $admin_rights = $rcmail->config->get('kolab_auth_admin_rights', array());
+
+            // @deprecated: fall-back to the old check if the original user has/belongs to administrative role/group
+            if (empty($admin_rights)) {
+                $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 = $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_user_groups($record['dn'], $user, $host);
+                    if (in_array($group, $groups)) {
+                        $isadmin = true;
+                    }
+                }
+
+                if ($isadmin) {
+                    // user has admin privileges privilage, get "login as" user credentials
+                    $target_entry = $ldap->get_user_record($loginas, $host);
+                    $allowed_tasks = $rcmail->config->get('kolab_auth_allowed_tasks');
                 }
             }
+            else {
+                // get "login as" user credentials
+                $target_entry = $ldap->get_user_record($loginas, $host);
+
+                if (!empty($target_entry)) {
+                    // get effective rights to determine login-as permissions
+                    $effective_rights = (array)$ldap->effective_rights($target_entry['dn']);
+
+                    if (!empty($effective_rights)) {
+                        $effective_rights['attrib'] = $effective_rights['attributeLevelRights'];
+                        $effective_rights['entry']  = $effective_rights['entryLevelRights'];
+
+                        // compare the rights with the permissions mapping
+                        $allowed_tasks = array();
+                        foreach ($admin_rights as $task => $perms) {
+                            $perms_ = explode(':', $perms);
+                            $type   = array_shift($perms_);
+                            $req    = array_pop($perms_);
+                            $attrib = array_pop($perms_);
+
+                            if (array_key_exists($type, $effective_rights)) {
+                                if ($type == 'entry' && in_array($req, $effective_rights[$type])) {
+                                    $allowed_tasks[] = $task;
+                                }
+                                else if ($type == 'attrib' && array_key_exists($attrib, $effective_rights[$type]) &&
+                                        in_array($req, $effective_rights[$type][$attrib])) {
+                                    $allowed_tasks[] = $task;
+                                }
+                            }
+                        }
 
-            // check group
-            if (!$isadmin && !empty($group)) {
-                $groups = $ldap->get_user_groups($record['dn'], $user, $host);
-                if (in_array($group, $groups)) {
-                    $isadmin = true;
+                        $isadmin = !empty($allowed_tasks);
+                    }
                 }
             }
 
@@ -480,22 +525,22 @@ class kolab_auth extends rcube_plugin
                 $origname = $user;
             }
 
-            $record = null;
+            if (!$isadmin || empty($target_entry)) {
+                $this->add_texts('localization/');
 
-            // user has the privilage, get "login as" user credentials
-            if ($isadmin) {
-                $record = $ldap->get_user_record($loginas, $host);
-            }
-
-            if (empty($record)) {
                 $args['abort'] = true;
+                $args['error'] = $this->gettext(array(
+                    'name' => 'loginasnotallowed',
+                    'vars' => array('user' => Q($loginas)),
+                ));
+
                 $message = sprintf(
                         'Login failure for user %s (as user %s) from %s in session %s (error %s)',
                         $user,
                         $loginas,
                         rcube_utils::remote_ip(),
                         session_id(),
-                        "No user record found for '" . $loginas . "'"
+                        "No privileges to login as '" . $loginas . "'"
                     );
 
                 rcube::write_log('userlogins', $message);
@@ -503,12 +548,16 @@ class kolab_auth extends rcube_plugin
                 return $args;
             }
 
+            // replace $record with target entry
+            $record = $target_entry;
+
             $args['user'] = $this->username = $loginas;
 
             // Mark session to use SASL proxy for IMAP authentication
             $_SESSION['kolab_auth_admin']    = strtolower($origname);
             $_SESSION['kolab_auth_login']    = $rcmail->encrypt($admin_login);
             $_SESSION['kolab_auth_password'] = $rcmail->encrypt($admin_pass);
+            $_SESSION['kolab_auth_allowed_tasks'] = $allowed_tasks;
         }
 
         // Store UID and DN of logged user in session for use by other plugins
@@ -662,7 +711,7 @@ class kolab_auth extends rcube_plugin
     public function render_page($args)
     {
         $rcmail  = rcube::get_instance();
-        $tasks   = $rcmail->config->get('kolab_auth_allowed_tasks');
+        $tasks   = (array)$_SESSION['kolab_auth_allowed_tasks'];
         $tasks[] = 'logout';
 
         // disable buttons in taskbar
diff --git a/plugins/kolab_auth/localization/en_US.inc b/plugins/kolab_auth/localization/en_US.inc
index 2a7b246..4882bdc 100644
--- a/plugins/kolab_auth/localization/en_US.inc
+++ b/plugins/kolab_auth/localization/en_US.inc
@@ -9,5 +9,6 @@
  */
 
 $labels['loginas'] = 'Login As';
+$labels['loginasnotallowed'] = 'No privileges to login as $user';
 
 ?>




More information about the commits mailing list