10 commits - lib/api lib/Auth lib/Auth.php lib/client lib/kolab_api_controller.php lib/kolab_client_api.php lib/kolab_client_task.php lib/locale lib/User.php

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Sun Jun 17 00:55:34 CEST 2012


 lib/Auth.php                          |   52 +++++-
 lib/Auth/LDAP.php                     |  270 ++++++++++++++++++++++++++++++----
 lib/User.php                          |   21 ++
 lib/api/kolab_api_service_domain.php  |   54 +++++-
 lib/api/kolab_api_service_domains.php |   35 ++++
 lib/client/kolab_client_task_main.php |   29 ++-
 lib/kolab_api_controller.php          |    4 
 lib/kolab_client_api.php              |    5 
 lib/kolab_client_task.php             |   14 +
 lib/locale/en_US.php                  |   10 +
 10 files changed, 430 insertions(+), 64 deletions(-)

New commits:
commit b087cc7edfc8657b9efd9a81835a86e73c3d5954
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:55:18 2012 +0100

    Add translations

diff --git a/lib/locale/en_US.php b/lib/locale/en_US.php
index 564803b..6b3e78a 100644
--- a/lib/locale/en_US.php
+++ b/lib/locale/en_US.php
@@ -47,6 +47,7 @@ $LANG['internalerror'] = 'Internal system error!';
 $LANG['loading'] = 'Loading...';
 $LANG['login.username'] = 'Username:';
 $LANG['login.password'] = 'Password:';
+$LANG['login.domain'] = 'Domain:';
 $LANG['login.login'] = 'Login';
 $LANG['loginerror'] = 'Incorrect username or password!';
 $LANG['MB'] = 'MB';
@@ -57,6 +58,7 @@ $LANG['menu.groups'] = 'Groups';
 $LANG['menu.kolab'] = 'Kolab';
 $LANG['menu.kolabsys'] = 'Kolab Systems';
 $LANG['menu.resources'] = 'Resources';
+$LANG['menu.roles'] = 'Roles';
 $LANG['menu.technology'] = 'Technology';
 $LANG['menu.users'] = 'Users';
 
@@ -72,13 +74,21 @@ $LANG['resource.delete.success'] = 'Successfully deleted Resource';
 $LANG['resource.edit'] = 'Edit Resource';
 $LANG['resource.edit.success'] = 'Successfully updated Resource';
 $LANG['resource.kolabtargetfolder'] = 'Target Folder';
+$LANG['resource.list'] = 'Resource (Collection) List';
 $LANG['resource.list.records'] = '$1 to $2 of $3';
 $LANG['resource.mail'] = 'Mail Address';
+$LANG['resource.member'] = 'Collection Members';
+$LANG['resource.norecords'] = 'No resource record(s) found!';
 $LANG['resource.other'] = 'Other';
 $LANG['resource.system'] = 'System';
 $LANG['resource.type_id'] = 'Resource Type';
 $LANG['resource.uniquemember'] = 'Collection Members';
 
+$LANG['role.add'] = 'Add Role';
+$LANG['role.list'] = 'Role List';
+$LANG['role.list.records'] = '$1 to $2 of $3';
+$LANG['role.norecords'] = 'No role records found!';
+
 $LANG['saving'] = 'Saving data...';
 
 $LANG['search'] = 'Search';


commit 90c89c546d3714a2bdee52f55d10dc6f63c8ac46
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:54:26 2012 +0100

    Pass along the domain name,
    Add domain name to the login form,
    Validate the capabilities not just for user and group menu structures

diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index 1740384..8394163 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -176,7 +176,7 @@ class kolab_client_task
             $login = $this->get_input('login', 'POST');
 
             if ($login['username']) {
-                $result = $this->api->login($login['username'], $login['password']);
+                $result = $this->api->login($login['username'], $login['password'], $login['domain']);
 
                 //console($result);
 
@@ -485,7 +485,7 @@ class kolab_client_task
         foreach ($this->menu as $idx => $label) {
             //console("$task: $task, idx: $idx, label: $label");
 
-            if (in_array($task, array('user', 'group'))) {
+            if (in_array($task, array('domain', 'group', 'resource', 'role', 'user'))) {
                 if (!array_key_exists($task . "." . $idx, $capabilities['actions'])) {
                     //console("$task.$idx not in \$capabilities['actions'], skipping", $capabilities['actions']);
                     continue;
@@ -671,6 +671,15 @@ class kolab_client_task
                 'name'  => 'login[password]',
                 'value' => ''));
 
+        $domain = kolab_html::label(array(
+                'for'   => 'login_domain',
+                'content' => $this->translate('login.domain')), true)
+            . kolab_html::select(array(
+                'type'  => 'select',
+                'id'    => 'login_domain',
+                'name'  => 'login[domain]',
+                'options' => array('kolabsys.com' => 'kolabsys.com', 'kanarip.com' => 'kanarip.com')));
+
         $button = kolab_html::input(array(
             'type'  => 'submit',
             'id'    => 'login_submit',
@@ -683,6 +692,7 @@ class kolab_client_task
             'action' => '?'),
             kolab_html::span(array('content' => $username))
             . kolab_html::span(array('content' => $password))
+            . kolab_html::span(array('content' => $domain))
             . $button);
 
         return $form;


commit 06a7d09fd449b0c0aadf03a923b4a1561b57f64e
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:54:05 2012 +0100

    Allow the domain name space to be passed on to authentication

diff --git a/lib/kolab_client_api.php b/lib/kolab_client_api.php
index 359fe73..dd70677 100644
--- a/lib/kolab_client_api.php
+++ b/lib/kolab_client_api.php
@@ -92,11 +92,12 @@ class kolab_client_api
      *
      * @return kolab_client_api_result Request response
      */
-    public function login($username, $password)
+    public function login($username, $password, $domain = null)
     {
         $query = array(
             'username' => $username,
-            'password' => $password
+            'password' => $password,
+            'domain' => $domain
         );
 
         $response = $this->post('system.authenticate', null, $query);


commit 5fed875f3ce92e4488f0e2ecff1d62699f5734e1
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:53:34 2012 +0100

    Allow the domain name space to be passed on to authentication

diff --git a/lib/kolab_api_controller.php b/lib/kolab_api_controller.php
index d96d4ac..e984c42 100644
--- a/lib/kolab_api_controller.php
+++ b/lib/kolab_api_controller.php
@@ -268,6 +268,8 @@ class kolab_api_controller
      */
     private function authenticate($request, $postdata)
     {
+        //console("Authenticating with postdata", $postdata);
+
         $valid = false;
 
         // destroy old session
@@ -278,7 +280,7 @@ class kolab_api_controller
         session_start();
 
         $_SESSION['user'] = new User();
-        $valid = $_SESSION['user']->authenticate($postdata['username'], $postdata['password']);
+        $valid = $_SESSION['user']->authenticate($postdata['username'], $postdata['password'], $postdata['domain']);
 
         // start new (PHP) session
         if ($valid) {


commit 11456a9f9618aedbdf67208100fa263996834a39
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:52:49 2012 +0100

    Apply effective rights on api tasks before inserting menu items into the main menu

diff --git a/lib/client/kolab_client_task_main.php b/lib/client/kolab_client_task_main.php
index 5af9754..8abb186 100644
--- a/lib/client/kolab_client_task_main.php
+++ b/lib/client/kolab_client_task_main.php
@@ -24,13 +24,13 @@
 
 class kolab_client_task_main extends kolab_client_task
 {
-    protected $menu = array(
-        'user.default'      => 'menu.users',
-        'group.default'     => 'menu.groups',
-        'resource.default'  => 'menu.resources',
-        'domain.default'    => 'menu.domains',
-        'role.default'      => 'menu.roles',
-        'about.default'     => 'menu.about',
+    protected $_menu = array(
+        'user'      => 'users',
+        'group'     => 'groups',
+        'resource'  => 'resources',
+        'domain'    => 'domains',
+        'role'      => 'roles',
+        'about'     => 'about',
     );
 
 
@@ -48,6 +48,21 @@ class kolab_client_task_main extends kolab_client_task
 
         // Create list of tasks for dashboard
         // @TODO: check capabilities
+        $capabilities = $this->capabilities();
+
+        $this->menu = Array();
+
+        foreach ($this->_menu as $task => $api_task) {
+            if ($task !== "about") {
+                if (!array_key_exists($api_task . '.list', $capabilities['actions'])) {
+                    //console("Skipping menu item $task for $api_task");
+                    continue;
+                }
+            }
+
+            $this->menu[$task . '.default'] = 'menu.' . $api_task;
+        }
+
         $this->output->assign('tasks', $this->menu);
 
         $this->output->assign('main_menu', $this->menu());


commit 1ac387f72636d716432722218fade7e82d39a03f
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:51:40 2012 +0100

    Apply effective rights to capabilities on API 'domains' service

diff --git a/lib/api/kolab_api_service_domains.php b/lib/api/kolab_api_service_domains.php
index 439e865..d322ef0 100644
--- a/lib/api/kolab_api_service_domains.php
+++ b/lib/api/kolab_api_service_domains.php
@@ -38,9 +38,38 @@ class kolab_api_service_domains extends kolab_api_service
      */
     public function capabilities($domain)
     {
-        return array(
-            'list' => 'r',
-        );
+        $auth = Auth::get_instance();
+        $conf = Conf::get_instance();
+
+        $domain_base_dn = $conf->get('domain_base_dn');
+
+        if (empty($domain_base_dn)) {
+            return array();
+        }
+
+        $effective_rights = $auth->list_rights($domain_base_dn);
+
+        $rights = array();
+
+        if (in_array('add', $effective_rights['entryLevelRights'])) {
+            $rights['list'] = "r";
+        }
+
+        if (in_array('delete', $effective_rights['entryLevelRights'])) {
+            $rights['list'] = "r";
+        }
+
+        if (in_array('modrdn', $effective_rights['entryLevelRights'])) {
+            $rights['list'] = "r";
+        }
+
+        if (in_array('read', $effective_rights['entryLevelRights'])) {
+            $rights['list'] = "r";
+        }
+
+        $rights['effective_rights'] = "r";
+
+        return $rights;
     }
 
     /**


commit 5de35c49682d7f7579a715eee57197c5eb74ed7d
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:50:58 2012 +0100

    Apply effective rights for capabilities
    Fix domain_add()

diff --git a/lib/api/kolab_api_service_domain.php b/lib/api/kolab_api_service_domain.php
index e00de8f..3d1b9dd 100644
--- a/lib/api/kolab_api_service_domain.php
+++ b/lib/api/kolab_api_service_domain.php
@@ -38,25 +38,61 @@ class kolab_api_service_domain extends kolab_api_service
      */
     public function capabilities($domain)
     {
-        return array(
-            'add' => 'w',
-            'edit' => 'w',
-            'delete' => 'w'
-        );
+        $auth = Auth::get_instance();
+        $conf = Conf::get_instance();
+
+        $domain_base_dn = $conf->get('domain_base_dn');
+
+        if (empty($domain_base_dn)) {
+            return array();
+        }
+
+        $effective_rights = $auth->list_rights($domain_base_dn);
+
+        //console("effective_rights", $effective_rights);
+
+        $rights = array();
+
+        if (in_array('add', $effective_rights['entryLevelRights'])) {
+            $rights['add'] = "w";
+        }
+
+        if (in_array('delete', $effective_rights['entryLevelRights'])) {
+            $rights['delete'] = "w";
+        }
+
+        if (in_array('modrdn', $effective_rights['entryLevelRights'])) {
+            $rights['edit'] = "w";
+        }
+
+        if (in_array('read', $effective_rights['entryLevelRights'])) {
+            $rights['find'] = "r";
+            $rights['find_by_any_attribute'] = "r";
+            $rights['find_by_attribute'] = "r";
+            $rights['find_by_attributes'] = "r";
+            $rights['info'] = "r";
+        }
+
+        $rights['effective_rights'] = "r";
+
+        return $rights;
     }
 
     public function domain_add($getdata, $postdata)
     {
-        if (empty($postdata['domain'])) {
-            return;
+        $conf = Conf::get_instance();
+        $dna = $conf->get('domain_name_attribute');
+
+        if (empty($dna)) {
+            $dna = 'associateddomain';
         }
 
-        if (empty($postdata['parent'])) {
+        if (empty($postdata[$dna])) {
             return;
         }
 
         $auth = Auth::get_instance();
-        $auth->domain_add($postdata['domain'], $postdata['parent']);
+        $auth->domain_add($postdata[$dna]);
     }
 
     public function domain_edit($getdata, $postdata)


commit e782da62218aebd55fdd5f2a4cb14aa6a18a7dd6
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:48:54 2012 +0100

    Correct auth_attrs setting -> auth_attributes
    Connect to the current domain
    Correct domain_root_dn() function
    Add function _domain_add_new()

diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index 7146f71..7007007 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -75,6 +75,8 @@ class LDAP
                     //console("Warning, user not authenticated yet");
                 }
             }
+        } else {
+            //console("LDAP::__construct() using domain $domain");
         }
 
         // Continue and default to the primary domain.
@@ -159,8 +161,9 @@ class LDAP
 
             $filter .= $user_filter;
 
-            $auth_attrs = $this->conf->get_list('auth_attrs');
+            $auth_attrs = $this->conf->get_list('auth_attributes');
 
+            //console("Using authentication attributes", $auth_attrs);
             if (count($auth_attrs) > 0) {
                 $filter .= '(|';
 
@@ -177,6 +180,8 @@ class LDAP
 
             $filter .= ')';
 
+            //console("LDAP::authenticate() using filter " . $filter);
+
             $subject_dn = $this->_get_user_dn($root_dn, $filter);
         } else {
             $subject_dn = $subject;
@@ -767,6 +772,7 @@ class LDAP
         $unique_attr = $this->unique_attribute();
         $attributes[$unique_attr] = $resource;
 
+        //console("\$this->domain: " . $this->domain);
         // Now that values have been re-generated where necessary, compare
         // the new resource attributes to the original resource attributes.
         $_resource = $this->entry_find_by_attribute(array($unique_attr => $attributes[$unique_attr]));
@@ -931,7 +937,7 @@ class LDAP
             return false;
         }
 
-        if (!$this->_connect()) {
+        if (!$this->_connect($domain)) {
             return false;
         }
 
@@ -943,33 +949,34 @@ class LDAP
             $this->_bind($conf->manager_bind_dn, $conf->manager_bind_pw);
         }
 
-        // TODO: Get domain_attr from config
-        $results = ldap_search($this->conn, $conf->get('domain_base_dn'), '(associatedDomain=' . $domain . ')');
-
-        if (!$result) {
-            // Not a multi-domain setup
-            $domain_name = $conf->get('kolab', 'primary_domain');
-            return $this->_standard_root_dn($domain_name);
+        $domain_name_attribute = $conf->get('domain_name_attribute');
+        if (empty($domain_name_attribute)) {
+            $domain_name_attribute = 'associateddomain';
         }
 
-        $domain = ldap_first_entry($this->conn, $results);
-        $domain_info = ldap_get_attributes($this->conn, $domain);
+        $result = self::normalize_result(
+                $this->_search(
+                        $conf->get('domain_base_dn'),
+                        '(' . $domain_name_attribute . '=' . $domain . ')'
+                    )
+            );
 
-//        echo "<pre>"; print_r($domain_info); echo "</pre>";
+        $result = $result[key($result)];
 
-        // TODO: Also very 389 specific
-        if (isset($domain_info['inetDomainBaseDN'][0])) {
-            $domain_rootdn = $domain_info['inetDomainBaseDN'][0];
-        }
-        else {
-            $domain_rootdn = $this->_standard_root_dn($domain_info['associatedDomain']);
+        if (is_array($result)) {
+            if (in_array('inetdomainbasedn', $result)) {
+                return $result['inetdomainbasedn'];
+            } else {
+                if (is_array($result[$domain_name_attribute])) {
+                    return $this->_standard_root_dn($result[$domain_name_attribute[0]]);
+                } else {
+                    return $this->_standard_root_dn($result[$domain_name_attribute]);
+                }
+            }
+        } else {
+            return $this->_standard_root_dn($domain);
         }
 
-        $this->_unbind();
-
-        //console("Using $domain_rootdn");
-
-        return $domain_rootdn;
     }
 
     public function search($base_dn, $search_filter = '(objectClass=*)', $attributes = array('*'))
@@ -1054,6 +1061,7 @@ class LDAP
 
         if (empty($base_dn)) {
             $base_dn = $this->domain_root_dn($this->domain);
+            //console("Using base_dn from domain " . $this->domain . ": " . $base_dn);
         }
 
         $result = self::normalize_result($this->_search($base_dn, $filter, array_keys($attribute)));
@@ -1762,9 +1770,217 @@ class LDAP
         $_new_attr = array($domain_name_attribute => array($domain_entry[$domain_dn][$domain_name_attribute], $domain));
 
         return $this->modify_entry($domain_dn, $_old_attr, $_new_attr);
+    }
+
+    private function _domain_add_new($domain)
+    {
+        //console("Auth::LDAP::_domain_add_new()", $domain);
+
+        $conf = Conf::get_instance();
+        $auth = Auth::get_instance();
+        $domain_base_dn = $conf->get('ldap', 'domain_base_dn');
+        $domain_name_attribute = $conf->get('ldap', 'domain_name_attribute');
 
+        if (is_array($domain)) {
+            $domain_name = array_shift($domain);
+        } else {
+            $domain_name = $domain;
+            $domain = (array)($domain);
+        }
+
+        $dn = $domain_name_attribute . '=' . $domain_name . ',' . $domain_base_dn;
+        $attrs = array(
+                'objectclass' => Array(
+                        'top',
+                        'domainrelatedobject'
+                    ),
+                $domain_name_attribute => array_merge((array)($domain_name), $domain),
+            );
+
+        $this->_add($dn, $attrs);
+
+        $inetdomainbasedn = $this->_standard_root_dn($domain_name);
+        $cn = str_replace(array(',', '='), array('\2C', '\3D'), $inetdomainbasedn);
+
+        $dn = "cn=" . $cn . ",cn=mapping tree,cn=config";
+        $attrs = array(
+                'objectclass' => Array(
+                        'top',
+                        'extensibleObject',
+                        'nsMappingTree',
+                    ),
+                'nsslapd-state' => 'backend',
+                'cn' => $inetdomainbasedn,
+                'nsslapd-backend' => str_replace('.', '_', $domain_name),
+            );
+
+        $this->_add($dn, $attrs);
+
+        $domain_filter = $conf->get('ldap', 'domain_filter');
+        $domain_filter = '(&(' . $domain_name_attribute . '=' . $conf->get('kolab', 'primary_domain') . ')' . $domain_filter . ')';
+        $domain_entry = self::normalize_result($this->_search($domain_base_dn, $domain_filter));
+        if (in_array('inetdomainbasedn', $domain_entry)) {
+            $_base_dn = $domain_entry['inetdomainbasedn'];
+        } else {
+            $_base_dn = $this->_standard_root_dn($conf->get('kolab', 'primary_domain'));
+        }
+
+        $result = @ldap_read($this->conn, "cn=" . str_replace('.', '_', $conf->get('kolab', 'primary_domain') . ",cn=ldbm database,cn=plugins,cn=config"), '(objectclass=*)', array('nsslapd-directory'));
+        $result = @ldap_get_entries($this->conn, $result);
+
+        $result = self::normalize_result($result);
+
+        //console("Result normalized", $result);
+
+        $result = $result[key($result)];
+        $directory = str_replace(str_replace('.', '_', $conf->get('kolab', 'primary_domain')), str_replace('.','_',$domain_name), $result['nsslapd-directory']);
+
+        $dn = "cn=" . str_replace('.', '_', $domain_name) . ",cn=ldbm database,cn=plugins,cn=config";
+        $attrs = Array(
+                'objectclass' => Array(
+                        'top',
+                        'extensibleobject',
+                        'nsbackendinstance',
+                    ),
+                'cn' => str_replace('.', '_', $domain_name),
+                'nsslapd-suffix' => $inetdomainbasedn,
+                'nsslapd-cachesize' => '-1',
+                'nsslapd-cachememsize' => '10485760',
+                'nsslapd-readonly' => 'off',
+                'nsslapd-require-index' => 'off',
+                'nsslapd-directory' => $directory,
+                'nsslapd-dncachememsize' => '10485760'
+            );
 
+        $this->_add($dn, $attrs);
+
+        // Query the ACI for the primary domain
+        $domain_filter = $conf->get('ldap', 'domain_filter');
+        $domain_filter = '(&(' . $domain_name_attribute . '=' . $conf->get('kolab', 'primary_domain') . ')' . $domain_filter . ')';
+        $domain_entry = self::normalize_result($this->_search($domain_base_dn, $domain_filter));
+        if (in_array('inetdomainbasedn', $domain_entry)) {
+            $_base_dn = $domain_entry['inetdomainbasedn'];
+        } else {
+            $_base_dn = $this->_standard_root_dn($conf->get('kolab', 'primary_domain'));
+        }
 
+        $result = @ldap_read($this->conn, $_base_dn, '(objectclass=*)', array('aci'));
+        $result = @ldap_get_entries($this->conn, $result);
+
+        $result = self::normalize_result($result);
+
+        $result = $result[key($result)];
+        $acis = $result['aci'];
+
+        foreach ($acis as $aci) {
+            if (stristr($aci, "SIE Group") === FALSE) {
+                continue;
+            }
+            $_aci = $aci;
+        }
+
+        $dn = $inetdomainbasedn;
+        $attrs = Array(
+                # TODO: Probably just use ldap_explode_dn()
+                'dc' => substr($dn, (strpos($dn, '=')+1), ((strpos($dn, ',')-strpos($dn, '='))-1)),
+                'objectclass' => Array(
+                        'top',
+                        'domain',
+                    ),
+                'aci' => Array(
+                        # Self-modification
+                        "(targetattr=\"carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || labeledURI || mobile || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier\")(version 3.0; acl \"Enable self write for common attributes\"; allow (write) userdn=\"ldap:///self\";)",
+
+                        # Directory Administrators
+                        "(targetattr =\"*\")(version 3.0;acl \"Directory Administrators Group\";allow (all) (groupdn=\"ldap:///cn=Directory Administrators," . $inetdomainbasedn . "\" or roledn=\"ldap:///cn=kolab-admin," . $inetdomainbasedn . "\");)",
+
+                        # Configuration Administrators
+                        "(targetattr=\"*\")(version 3.0; acl \"Configuration Administrators Group\"; allow (all) groupdn=\"ldap:///cn=Configuration Administrators,ou=Groups,ou=TopologyManagement,o=NetscapeRoot\";)",
+
+                        # Administrator users
+                        "(targetattr=\"*\")(version 3.0; acl \"Configuration Administrator\"; allow (all) userdn=\"ldap:///uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot\";)",
+
+                        # SIE Group
+                        $_aci,
+
+                        # Search Access,
+                        "(targetattr = \"*\") (version 3.0;acl \"Search Access\";allow (read,compare,search)(userdn = \"ldap:///" . $inetdomainbasedn . "\");)",
+
+                    ),
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "cn=Directory Administrators," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array(
+                        'top',
+                        'groupofuniquenames',
+                    ),
+
+                'cn' => 'Directory Administrators',
+                'uniquemember' => Array(
+                        'cn=Directory Manager'
+                    ),
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "ou=Groups," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array('top', 'organizationalunit'),
+                'ou' => 'Groups',
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "ou=People," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array('top', 'organizationalunit'),
+                'ou' => 'People',
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "ou=Special Users," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array('top', 'organizationalunit'),
+                'ou' => 'Special Users',
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "ou=Resources," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array('top', 'organizationalunit'),
+                'ou' => 'Resources',
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = "ou=Shared Folders," . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array('top', 'organizationalunit'),
+                'ou' => 'Shared Folders',
+            );
+
+        $this->_add($dn, $attrs);
+
+        $dn = 'cn=kolab-admin,ou=People,' . $inetdomainbasedn;
+        $attrs = Array(
+                'objectclass' => Array(
+                        'top',
+                        'ldapsubentry',
+                        'nsroledefinition',
+                        'nssimpleroledefinition',
+                        'nsmanagedroledefinition',
+                    ),
+                'cn' => 'kolab-admin'
+            );
+
+        $this->_add($dn, $attrs);
+
+        return TRUE;
     }
 
     /**
@@ -1917,6 +2133,8 @@ class LDAP
      */
     private function __search($base_dn, $search_filter = '(objectClass=*)', $attributes = array('*'))
     {
+        $conf = Conf::get_instance();
+
         if (!$this->_connect()) {
             return false;
         }
@@ -1925,7 +2143,11 @@ class LDAP
 
         //console("Searching $base_dn with filter: $search_filter, attempting to get attributes", $attributes);
 
-        $this->_bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
+        if (!empty($_SESSION['user'])) {
+            $this->_bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
+        } else {
+            $this->_bind($conf->get('ldap', 'service_bind_dn'), $conf->get('ldap', 'service_bind_pw'));
+        }
 
         if (!in_array($this->unique_attribute(), $attributes)) {
             $attributes[] = $this->unique_attribute();


commit c48cb04c58252934a028135ff489862713f21193
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:46:40 2012 +0100

    Auth::get_instance() and Auth::connect() should use the domain stored in the session, if available
    Correct domain name when user logs in with email address

diff --git a/lib/Auth.php b/lib/Auth.php
index 5176933..6af9f3c 100644
--- a/lib/Auth.php
+++ b/lib/Auth.php
@@ -40,8 +40,16 @@ class Auth {
     {
         $conf = Conf::get_instance();
 
-        if ($domain === NULL) {
-            $domain = $conf->get('primary_domain');
+        if (empty($domain)) {
+            if (!empty($_SESSION['user'])) {
+                $domain = $_SESSION['user']->get_domain();
+                //console("Auth::get_instance() using domain $domain from session");
+            } else {
+                $domain = $conf->get('primary_domain');
+                //console("Auth::get_instance() using default domain $domain");
+            }
+        } else {
+            //console("Auth::get_instance() using domain $domain");
         }
 
         if (!isset(self::$instance[$domain])) {
@@ -103,12 +111,13 @@ class Auth {
     public function authenticate($username, $password)
     {
         // TODO: Log authentication request.
-//         error_log("Authentication request for $username");
+        //console("Authentication request for $username");
 
         if (strpos($username, '@')) {
             // Case-sensitivity does not matter for strstr() on '@', which
             // has no case.
-            $user_domain = strstr($username, '@');
+            $user_domain = substr(strstr($username, '@'), 1);
+            //console("Auth::authenticate(): User domain: " . $user_domain);
 
             if (isset($this->_auth[$user_domain])) {
                 // We know this domain
@@ -120,6 +129,7 @@ class Auth {
                 //
                 // This will enable john at example.org to login using 'alias'
                 // domains as well, such as 'john at example.ch'.
+                //console("Attempting to find the primary domain name space for the user domain $user_domain");
                 $associated_domain = $this->primary_for_valid_domain($user_domain);
 
                 if ($associated_domain) {
@@ -149,8 +159,17 @@ class Auth {
 
     public function connect($domain = NULL)
     {
-        if ($domain === NULL) {
-            $domain = $this->conf->get('primary_domain');
+        if (empty($domain)) {
+            if (!empty($_SESSION['user'])) {
+                //console("Using domain from session");
+                $domain = $_SESSION['user']->get_domain();
+            } else {
+                //console("Using primary_domain");
+                $domain = $this->conf->get('primary_domain');
+            }
+            //console("Domain to connect to not set, using primary domain $domain");
+        } else {
+            //console("Domain to connect to set to $domain");
         }
 
         if ($domain) {
@@ -169,7 +188,10 @@ class Auth {
 
         if (!isset($this->_auth[$domain])) {
             require_once 'Auth/' . $auth_method . '.php';
+            //console("Creating Auth for $domain");
             $this->_auth[$domain] = new $auth_method($domain);
+        //} else {
+            //console("Auth for $domain already available");
         }
     }
 
@@ -284,7 +306,12 @@ class Auth {
 
     public function list_users($domain = NULL, $attributes = array(), $search = array(), $params = array())
     {
+        if (empty($domain)) {
+            $domain = $_SESSION['user']->get_domain();
+        }
+
         $this->connect($domain);
+
         if ($domain === NULL) {
             $domain = $this->conf->get('primary_domain');
         }
@@ -308,11 +335,12 @@ class Auth {
 
     public function list_resources($domain = NULL, $attributes = array(), $search = array(), $params = array())
     {
-        $this->connect($domain);
         if ($domain === NULL) {
             $domain = $this->conf->get('primary_domain');
         }
 
+        $this->connect($domain);
+
         $resources = $this->_auth[$domain]->list_resources($attributes, $search, $params);
 
         return $resources;
@@ -360,6 +388,8 @@ class Auth {
 
     public function resource_edit($resource, $attributes, $typeid = null)
     {
+        //console("Domain: " . $_SESSION['user']->get_domain());
+
         return $this->_auth[$_SESSION['user']->get_domain()]->resource_edit($resource, $attributes, $typeid);
     }
 
@@ -385,18 +415,16 @@ class Auth {
 
     public function search()
     {
-        $this->connect($domain);
-        if ($domain === NULL) {
-            $domain = $this->conf->get('primary_domain');
-        }
+        $this->connect();
 
-        $result = $this->_auth[$domain]->search(func_get_args());
+        $result = $this->_auth[$_SESSION['user']->get_domain()]->search(func_get_args());
 
         return $result;
     }
 
     public function user_add($attributes, $typeid = null)
     {
+        $this->connect($_SESSION['user']->get_domain());
         return $this->_auth[$_SESSION['user']->get_domain()]->user_add($attributes, $typeid);
     }
 


commit 73f71494f56f81f8e6d2d991aba64db9bae30dfb
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Jun 16 23:44:07 2012 +0100

    Authenticate user against the correct domain

diff --git a/lib/User.php b/lib/User.php
index ea6ae0d..e0a2076 100644
--- a/lib/User.php
+++ b/lib/User.php
@@ -45,12 +45,19 @@ class User
             'email_address' => $this->_auth_method->_get_email_address(),
             'username' => $this->username,
             'password' => $this->password,
+            'domain' => $this->get_domain()
         );
     }
 
-    public function authenticate($username, $password, $method = FALSE)
+    public function authenticate($username, $password, $domain = null, $method = FALSE)
     {
-        $this->auth = Auth::get_instance();
+        //console("Running with domain", $domain);
+
+        if (empty($domain)) {
+            $this->auth = Auth::get_instance();
+        } else {
+            $this->auth = Auth::get_instance($domain);
+        }
 
         $result = $this->auth->authenticate($username, $password);
 
@@ -59,8 +66,14 @@ class User
             $this->username = $username;
             $this->password = $password;
             $this->userid   = $result;
-            $this->domain   = $this->auth->domain;
-//            $this->_groups = $this->groups();
+
+            if (empty($domain)) {
+                $this->domain   = $this->auth->domain;
+            } else {
+                $this->domain = $domain;
+            }
+
+            //$this->_groups = $this->groups();
         }
 
         return $this->_authenticated;





More information about the commits mailing list