[commits] [Wiki] changed: ExistingLDAPHowTo

Wiki Guest wikiguest at horde.org
Tue Aug 13 13:45:18 UTC 2013


guest [87.149.38.146]  Tue, 13 Aug 2013 13:45:18 +0000

Modified page: http://wiki.horde.org/ExistingLDAPHowTo
New Revision:  15
Change log:  made ldap-ACL more consistant with the sample configuration

@@ -1,465 +1,305 @@
+[[toc]]
+
  + LDAP !HowTo
-
-

  Written by Ben Chavet (ben [at] horde [dot] org)
-
-
-
-[[toc]]
-
-

  ----
-
-

  This document is intended to help administrators configure various  
parts of horde to use an **existing** LDAP directory.  Please feel  
free to fill in any gaps or to clarify any existing information  
presented here.
-
-

  ----
-
-

  ++ Document Standards
-
-

  In this document, we assume the following, please adjust accordingly  
for your LDAP directory
-
-

  * The directory is already populated with posix user account information.
-
  * User information is stored in {{ou=Users,dc=example,dc=com}}.
-
  * {{cn=horde,ou=DSA,dc=example,dc=com}} is used by horde to bind to  
the LDAP directory.
-
  * The LDAP directory is secured, with no anonymous binding.
-
-

  ----
-
-

  ++ Authenticating with LDAP
-
-

  +++ Horde Setup
-
-

  The Horde authentication setup should look something like the following:
-
-

  [[image auth_horde_setup.png]]

-
-
-* **The hostname of the LDAP server** - This is the address of your  
LDAP server.  If it is running on the same machine as horde, then  
//localhost// is fine here.  Otherwise enter the hostname or IP  
address of the server.  If you have a master and one or more slave  
LDAP servers, you can provide failover here by entering all of your  
LDAP servers separated by a space.
-
-
+* **The hostname of the LDAP server** - This is the address of your  
LDAP server.  If it is running on the same machine as horde, then  
//localhost// is fine here.  Otherwise enter the hostname or IP  
address of the server.  If you have a master and one or more slave  
LDAP servers, you can provide failover here by entering all of your  
LDAP servers separated by a space.  For ldaps, use ldaps://<hostname>  
in this field.

  * **The base DN for the LDAP server** - This is the subtree that  
horde will search through to find user information.
-
-

  * **The DN used to bind to the LDAP server** - Because our LDAP  
directory does not allow anonymous binding, we must provide the  
binding account here.  If your LDAP directory allows anonymous  
binding, this can be left blank.
-
-

  * **The password used to bind to the LDAP server** - The password  
associated with the binding account.  Leave this blank if binding  
anonymously.
-
-

  * **LDAP Protocol Version** - This should almost always be //LDAPv3//.
-
-

  * **The username search key** - This is the field that stores the username.
-
-

  * **How to specify a filter for the user lists** - Unless you have  
to use some fancy filters to find users, //One or more objectclass  
filters// should work fine here.

-
-
-* **The objectclass filter used to search for users. Can be a single  
objectclass or a list** - This is simply a list of objectClass values  
that represent valid users.  We are piggybacking on an existing LDAP  
directory used to authenticate users on a POSIX system, so we know  
that a //posixAccount// object is a valid user account.
-
-
+* **The objectclass filter used to search for users. Can be a single  
objectclass or a list** - This is simply a list of objectClass values  
that represent valid users.  We are piggybacking on an existing LDAP  
directory used to authenticate users on a POSIX system, so we know  
that a //posixAccount// object is a valid user account. Note: If the  
objectclass for your users is "shadowAccount", this should NOT be  
"objectclass=shadowAccount" just "shadowAccount"

  +++ Directory Permissions
-
-

  These are the **minimum** LDAP directory permissions needed by horde  
to authenticate against LDAP
-
-

  <code>
-
  access to dn.children="ou=Users,dc=example,dc=com"
-
          attrs=entry,objectClass,uid
-
          by dn="cn=horde,ou=DSA,dc=example,dc=com" read
-
          by self read
-
          by * none
-
-

  access to dn.children="ou=Users,dc=example,dc=com"
-
          attrs=userPassword
-
          by self write
-
          by anonymous auth
-
          by * none
-
  </code>
-
-

  ----

+++ Managing Posix Accounts

+With a little tweaking, Horde can be used to do basic user management  
for a Posix system, such as adding and removing users.

-++ Managing Posix Accounts
++++ !NextFreeUnixId Object

+We have to have a place to keep track of the next user id number.  If  
you are already using LDAP for user management, chances are, you  
already have an object doing this, and you can skip this section.  If  
you do not, we need to create one with the following //ldif// file:

+<code>
+dn: cn=NextFreeUnixId,dc=example,dc=com
+homeDirectory: /dev/null
+objectClass: inetOrgPerson
+objectClass: posixAccount
+objectClass: top
+uid: NextFreeUnixId
+gidNumber: 1000
+uidNumber: 1000
+sn: NextFreeUnixId
+cn: NextFreeUnixId
+</code>

-With a little tweaking, Horde can be used to do basic user management  
for a Posix system, such as adding and removing users.
-
+And add this object to the directory:

+<code>
+ldapadd -x -h localhost -D "cn=root,dc=example,dc=com" -f filename.ldif -W
+</code>

  +++ Configure !AuthLDAP Hook
-
-

  <code type="php">
-
  if (!function_exists('_horde_hook_authldap')) {
-
      function _horde_hook_authldap($userID, $credentials = null)
-
      {
-
-        $entry['dn'] = 'uid=' . $userID . ',ou=horde,dc=chavet,dc=net';
-
+        $entry['dn'] = 'uid=' . $userID . ',ou=horde,dc=example,dc=com';
          if (isset($credentials) && isset($credentials['user_fullname'])) {
-
              $entry['cn'] = $credentials['user_fullname'];
-
          } else {
-
              $entry['cn'] = $userID;
-
          }
-
          $entry['sn'] = $userID;
-
          $entry['objectclass'][0] = 'top';
-
          $entry['objectclass'][1] = 'posixAccount';
-
          $entry['objectclass'][2] = 'shadowAccount';
-
+        $entry['objectclass'][3] = 'inetOrgPerson';
          $entry['uid'] = $userID;
+        $entry['homeDirectory'] = '/home/' . $userID;
+        $entry['gidNumber'] = 100;

-
+        // get the next available uid and increment it if we're adding a user
+        if (isset($credentials)) {
+            $ds =  
@ldap_connect($GLOBALS['conf']['auth']['params']['hostspec']);
+            @ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION,  
$GLOBALS['conf']['auth']['params']['version']);
+            @ldap_bind($ds,  
$GLOBALS['conf']['auth']['params']['binddn'],  
$GLOBALS['conf']['auth']['params']['password']);
+            $searchResults = @ldap_search($ds, 'dc=example,dc=com',  
'cn=NextFreeUnixId');
+            $information = @ldap_get_entries($ds, $searchResults);
+            ldap_modify($ds, 'cn=NextFreeUnixId,dc=example,dc=com',  
array('uidnumber' => $information[0]['uidnumber'][0] + 1));
+            @ldap_close($ds);
+            $entry['uidNumber'] = $information[0]['uidnumber'][0];
+        }

          // need to check for new users (password) and edited users  
(user_pass_2)
-
          if (isset($credentials) && isset($credentials['password'])) {
-
              $entry['userPassword'] =  '{MD5}' .  
base64_encode(mHash(MHASH_MD5, $credentials['password']));
-
          } else if (isset($credentials) &&  
isset($credentials['user_pass_2'])) {
-
              $entry['userPassword'] =  '{MD5}' .  
base64_encode(mHash(MHASH_MD5, $credentials['user_pass_2']));
-
          }
-
          return $entry;
-
      }
-
  }
-
  </code>

-
+Another example for this code using a ou to store the next available  
uid information can be found at:   
http://heinous.org/wiki/Horde_Notes#Authentication

  +++ Directory Permissions
-
-

  If you are using Horde to manage your user accounts, the horde  
account needs more priveleges in order to make the proper changes.
-
-

  <code>
+access to dn.base="cn=NextFreeUnixId,dc=example,dc=com"
+        by dn="cn=horde,ou=DSA,dc=example,dc=com" write
+        by * none

  access to dn.children="ou=Users,dc=example,dc=com"
-
          attrs=entry,objectClass,uid
-
          by dn="cn=horde,ou=DSA,dc=example,dc=com" write
-
          by self read
-
          by * none
-
-

  access to dn.children="ou=Users,dc=example,dc=com"
-
          attrs=userPassword
-
          by dn="cn=horde,ou=DSA,dc=example,dc=com" write
-
          by self write
-
          by anonymous auth
-
          by * none
-
  </code>
-
-

  ----
-
-

  ++ Storing Preferences with LDAP
-
-

  +++ Horde Setup
-
-

  Storing Horde preferences in the LDAP directory adds a large number  
of attribute entries to every user DN.  If this is something you do  
not want, you should look into using some other preference backend.
-
-

  To use LDAP to store Horde preferences, set the preference system to  
use LDAP as its backend.  The field values here are very simular to  
the Horde configuration.
-
-

  [[image ldap_pref_config.png]]

-
-
-* **The hostname of the LDAP server** - This is the address of your  
LDAP server.  If you have a master and one or more slave LDAP servers,  
you can provide failover here by entering all of your LDAP servers  
separated by a space.
-
-
+* **The hostname of the LDAP server** - This is the address of your  
LDAP server.  If you have a master and one or more slave LDAP servers,  
you can provide failover here by entering all of your LDAP servers  
separated by a space.  For ldaps, use ldaps://<hostname> in this field.

  * **The port of the LDAP server** - This is the port that your LDAP  
server is listening on.  Most commonly, this will be 389.
-
-

  * **LDAP Protocol Version** - This should almost always be //LDAPv3//.
-
-

  * **The base DN for the LDAP server** - This is the subtree that  
horde will search through to find user preference information.
-
-

  * **The DN of the root (administrative) account to bind for write  
operations** - This is not actually asking for the LDAP root account,  
this is just the DN that horde uses to bind to the LDAP directory.   
This account should have write priveleges to the preference fields, as  
shown below.
-
-

  * **The password of the root DN for bind authentication** - The  
password associated with the binding account.
-
-

  * **The username search key** - This is the field that stores the username.
-
-

  +++ Directory Permissions

-
-
-These are the **minimum** LDAP directory permissions needed by horde  
to store user preferences.
-
-
+These are the suggested LDAP directory permissions needed by Horde to  
store user preferences.  The explicit write permission for the Horde  
DN can be omitted if the LDAP driver is configured to bind to LDAP as  
the logged-in user.  However it remains necessary if you use a "root"  
DN.  The "attrs=@hordePerson" syntax means this rule applies to all  
attributes included in the "hordePerson" objectClass.

  <code>
-
-TODO
-
+# Access to Horde attributes
+access to attrs="@hordePerson"
+        by dn="cn=horde,ou=DSA,dc=example,dc=com" write
+        by self write
+        by users none
+        by * none
  </code>
-
-

  ----
-
-

  ++ LDAP Based Address Book
-
-

  +++ Turba Setup

-
+Patch {{/etc/openldap/schema/core.schema}} with  
{{/horde/turba/scripts/ldap/core.schema.patch}}

  Turba ships with an example LDAP address book, so we will use that  
here as our base.  This example assumes that we are providing an  
address book containing all of the users who have access to this horde  
installation.
-
-

  <code type="php">
-
-$cfgSourses['localldap'] = array(
-
+$cfgSources['localldap'] = array(
      'title' => _("Shared Directory"),
-
      'type' => 'ldap',
-
      'params' => array(
-
          'server' => 'localhost',
-
          'port' => 389,
-
          'root' => 'ou=Users,dc=example,dc=com',
-
          'bind_dn' => 'cn=horde,ou=Users,dc=example,dc=com',
-
          'bind_password' => '********',
-
          'sizelimit' => 200,
-
-        'filter' => '(&(uid=*)(objectClass=posixAccount))',
-
          'dn' => array('cn'),
-
          'objectclass' => array('top',
-
                                 'person',
-
                                 'organizationalPerson',
-
-                               'inetOrgPerson'),
-
+                               'inetOrgPerson',
+                               'turbaContact',
+                         ),
          'charset' => 'iso-8859-1',
-
          'checkrequired' => false,
-
          'version' => 3
-
      ),
-
      'map' => array(
-
          '__key' => 'dn',
-
-        'name' => 'displayName',
-
+        'name' => 'cn',
          'email' => 'mail',
-
          'workPhone' => 'telephonenumber',
-
          'cellPhone' => 'mobile',
-
          'office' => 'roomNumber',
-
          'employeeType' => 'employeeType',
-
          'pgpPublicKey' => 'userCertificate',
-
          'freebusyUrl' => 'calFBURL',
-
      ),
-
      'search' => array(
-
          'name',
-
          'email',
-
          'homePhone',
-
          'workPhone',
-
          'cellPhone',
-
          'homeAddress'
-
      ),
-
      'public' => true,
-
      'readonly' => true,
-
      'admin' => array(),
-
      'export' => true
-
  );
-
  </code>
-
-

  The amount of information you can store is not by any means limited  
by what we have configured here.  Any number of LDAP fields can be  
added to the {{'map'}} array.
-
-

  +++ Directory Configuration
-
-

  In order to use the //calFBURL// field, we have to include the  
rfc2739 schema in our LDAP configuration file.
-
-

  * Copy {{horde/turba/scripts/ldap/rfc2739.schema}} to your server's  
schema directory.  This is commonly {{/etc/openldap/schema/}}.
-
-

  * Add the following to your LDAP configuration file  
({{/etc/openldap/slapd.conf}})
-
-

  <code>
-
  include /etc/openldap/schema/rfc2739.schema
-
  </code>
-
-

  +++ Directory Permissions

+These are the **minimum** LDAP permissions required for the address  
book we defined above.  If you included extra fields, be sure to add  
them here.

+<code>
+access to dn.children="ou=Users,dc=example,dc=com"
+         
attrs=entry,cn,objectClass,mail,telephoneNumber,mobile,roomNumber,employeeType,userCertificate,calFBURL,displayName
+        by dn="cn=horde,ou=Users,dc=example,dc=com" read
+        by self read
+        by * none
+</code>

-These are the **minimum** LDAP permissions required for the address  
book we defined above.  If you included extra fields, be sure to add  
them here.
+----

+++ Pass LDAP credentials to IMP

+To pass credentials used to log in Horde to IMP, modify the file  
{{./horde/imp/config/servers.php}} (from your webroot). Here is the  
explanation given in the file :

-<code>
+> hordeauth :
+> If this parameter is present and true, then IMP will attempt to use  
the user's existing credentials (the username/password they used to  
log in to Horde) to log in to this source. If this  parameter is  
'full', the username will be used unmodified; otherwise everything  
after and including the first @ in the username will be stripped off  
before attempting authentication.

-access to dn.children="ou=Users,dc=example,dc=com"

-         
attrs=entry,objectClass,mail,telephoneNumber,mobile,roomNumber,employeeType,userCertificate,calFBURL,displayName
+Added by Jonathan Gibert (jokot3 [47] gmail [d°7] com). March 26, 2007.

-        by dn="cn=horde,ou=DSA,dc=example,dc=com" read
+----

-        by self read
+++ See Also

-        by * none
+* NewLDAPHowTo
+* LdapPref

-</code>



More information about the commits mailing list