Plone 2.5 and OpenLDAP Integration for Users and Groups

by Kevin last modified Dec 30, 2008 03:03 PM

How to have your Plone 2.5 site read from and write to your OpenLDAP Directory for users and groups on a Linux server

  • Install Zope 2.x.x (I used 2.9.3) and Plone 2.5 and create an instance of zope for yourself (this varies from distribution to distribution and other documents cover this in detail).
  • Install the products in the PloneLDAP bundle in your Zope instance. This will add the LDAPUserFolder, LDAPMultiPlugins and PloneLDAP products.
  • Start your zope instance and then, using the ZMI, add a plone instance (see other docs for details)
  • Restart your zope instance so that the new products will be available in the ZMI (varies from distribution to distribution; see other docs for this)
  • Navigate in the ZMI to the root of your Plone instance, then to the acl_users folder contained therein, and add an LDAP Multi Plugin to that folder.  You're presented with a form entitled: Add Plone LDAP Plugin to the PluggabbleAuthService."
  • Fill out the fields carefully: The first five (ID, Title, LDAP Server[:port], Use SSL, Read-only) should be self-explanatory---see plone docs for the first two and LDAP docs for the rest if they are not).  Note that you should consider security here.  Either use SSL or make sure it is a trusted network over which your data is traveling.  Most people would not want the contents of their Directory (especially if they contain lots of user credentials) traveling unencrypted over an untrusted network.
  • The next three fields are Login Name Attribute, User ID Attribute, and RDN Attribute.  What you choose for each of these will depend on your LDAP DIT that you're connecting this plone instance to and also the method of logging in to your plone instance that you've chosen for yourself.  My DIT looks generally as follows:
o=example.com
    ou=people
        uid=user1
        uid=user2
    ou=groups
        cn=group1
        cn=group2
  • from which, you might be able to deduce (accurately) that my user dn's in the DIT look like this: uid=username,ou=people,o=example.com
  • I wanted my users to login to plone as they login to other applications in the organization that authenticate against my Directory (that is to say, with the same credentials: username and password), and the uid attribute is what I use for the username in all these other applications, so I chose uid for the first of these three fields: Login Name Attribute.  I'm not absolutely certain that is how plone uses that field, but I'm pretty sure that's right.
  • I'm less sure about how plone uses the second of these three fields: User ID Attribute.  Given my circumstances, it only made sense to choose uid for that field also.
  • The third of these three fields is RDN Attribute, and I'm quite certain that I do understand how plone uses that field.  When adding a new user via the ZMI (the Users tab of the object we're considering now), whatever you choose here will be used by plone (concatenation-style) along with the next field (Users Base DN) to form the dn of the added user in the Directory.  For more details, read up on the Relative Distinguished Name concept of LDAP.  So again, given my circumstances and the form of my dn's, I chose uid here.  So I chose uid for all three of these fields, but your situation may differ from mine.
  • For the next field, Users Base DN, choose the node of your DIT where all your users are attached, and it should be listed in dn-type format.  For my circumstances, I filled this field with: ou=people,o=example.com
  • For the next field, Group Storage, I chose "Groups stored on LDAP server"
  • For the next field, Groups Base DN, choose the node of your DIT where all your groups are attached.  Note that your groups stored here must be of LDAP objectclass groupOfUniqueNames.  If you're new to LDAP and DIT-design, I recommend the following document to gain some familiarity with DIT-design and groups in particular: ldap-recipe.  Make sure you also follow and read the (very long but worthwhile) link that author refers you to when he writes: "STOP! Before you go on to read about Groups..." For my circumstances, I filled this field with: ou=groups,o=example.com
  • I left the Scopes fields at the default of SUBTREE.
  • The remaining four fields should be self-explanatory (make sure your Manager DN has the necessary privileges on the OpenLDAP server: read/write access to those portions of your Directory that will be linked with plone), so fill them out correctly and click the "Add" button.
  • Navigate to that new plugin by clicking on its ID as you named it above, then click on its Contents tab
  • Click on the acl_users folder contained therein.
  • Now your "ZMI path" (as I call it) at the top of the lower right frame of your ZMI should read: "LDAPUserFolder at /plone-ID/acl_users/pluginID/acl_users and the Configure tab should be selected (or on top).  Most of the configuration fields of this LDAPUserFolder are pulled from the configuration of your LDAP Multi Plugin that you configured above, but there are some new ones: Group mapping (Applies to LDAP group storage only), Manager DN Usage, User object classes.  Configure your LDAPUserFolder instance by filling out these additional fields (details below).
  • For the field entitled, Group mapping (Applies to LDAP group storage only), I chose "Manually map LDAP groups to Zope roles"
  • For the next new field, Manager DN Usage, I chose "Always."
  • The next new field (User object classes) is subtle, but very important.  You should fill it with all of the LDAP objectclasses that you will use in plone and that make up your user objects in your Directory.  That probably means you should fill it with all of the objectclasses that make up your user objects in your Directory.  Separate the entries by commas as is done with the default entry.
  • Click the "Apply Changes" button.
  • Click the LDAP Schema tab to bring it to the top.
  • There is an important relationship between this tab of this object and the Properties tab of the PlonePAS MemberData Tool at ZMI path /ploneID/portal_memberdata.  The default fields of the latter include the following properties (among others): email and fullname.  These property names are the targets of the "Map to Name (optional)" field of the LDAP Schema tab you're looking at now.  The LDAP Schema tab of your current ZMI path of LDAPUserFolder at /ploneID/acl_users/pluginID/acl_users has a four-column-table of (by default) three rows and these rows contain (by default) the LDAP Attribute Names of cn, sn, and uid with Friendly Names of Canonical Name, Last Name, and uid with no Mapped to Names and No for the Multi-valued column.
  • In order for plone to be properly connected to your LDAP Directory, you'll have to make some changes here.  Exactly what changes will depend on your circumstances, but I deleted cn from the table and added it again (using this tab), this time using the "Map to Name (optional)" field to map the LDAP attribute "cn" to the portal_memberdata property name "fullname".  I also added a new LDAP Attribute Name ("mail") to the table, using the "Map to Name (optional)" field to map it to the portal_memberdata property name "email".  Plone needs at least these two mappings in order to give you the most basic functionality that you're probably looking for.  Without these mappings, the User and Groups Administration page of the Plone Site Setup will see only uid and won't see the user's full name or his/her email address from the Directory, for which there are fields in Plone's User and Groups Administration page that you probably want filled with the content of those attributes from the Directory.
  • Additionally, depending on what LDAP objectclasses your DIT contains for the user object, you may need to add additional LDAP Attribute Names here (not necessarily mapping them to any portal_memberdata property names).  Specifically, if you wish to be able to add users to your Directory using the ZMI, then you will need to have an entry in this table for all of the required attributes called for by your user objects (which is determined by what objectclasses are used in making up your user objects).  For example, my user objects are made up of the following objectclasses: organizationalPerson, inetOrgPerson, krb5Principal, krb5KDCEntry, posixAccount, CourierMailAccount.  These objectclasses have the following required attributes (maybe some others too): cn, sn, krb5KeyVersionNumber, krb5PrincipalName, uidNumber, homeDirectory, gidNumber.  So I added all these LDAP Attribute Names to the table of the LDAP Schema tab (not all of them mapped to a property in portal_memberdata).
  • You may also want to add new property names (name them as you wish) in the portal_memberdata tool, and then add new (non-required) LDAP Attribute Names (homePhone, telephoneNumber, etc.) to your LDAP Schema using this tab, and mapping the LDAP Attribute Names to the names that you added to the portal_memberdata tool.  For example, I added the property names, "homephone" and "extension" to the portal_memberdata tool and then added LDAP Attribute Names, homePhone and telephoneNumber to the table, mapping them to the property names in doing so.
  • At the moment, plone apparently has no way of displaying any LDAP attributes beyond cn and mail (which are accessed as fullname and email in the portal_memberdata tool), but maybe soon that will change.
  • After configuring your LDAP Schema as desired, click on the Users tab and search for a user in your Directory.
  • Then click on the Groups tab and see if your Directory's groups are there.  They should be.
  • Some good tests to try in order to determine if all the linked functionality between Zope/Plone and your LDAP Directory that you want is actually present are as follows:
  1. try adding a user to your Directory from the Users tab of the LDAPUserFolder at ZMI path /ploneID/acl_users/pluginID/acl_users --- make sure that the user shows up in the DIT at the node you want.  If he doesn't, then your RDN or Users Base (or both) configurations are probably wrong;
  2. try deleting a user from your Directory using this tab;
  3. try adding a group to your Directory from the Groups tab of the LDAPUserFolder at ZMI path /ploneID/acl_users/pluginID/acl_users --- make sure that the groups shows up in the DIT at the node you want.  If not, then check your Groups Base configuration setting.
  4. try deleting a group from your Directory using this tab.
  • If those work, then you've probably got everything working as desired, and now two final steps:
  1. activating the plugins to work with plone itself (so far, everything we've done here has been in the ZMI).  For this, navigate to the /ploneID/acl_users/pluginID ZMI path.  The Activate tab should be on top, and you should put a check-mark in all of the boxes for which you want functionality in Plone.  I checked them all for my circumstances.
  2. adjusting the order in which acl_users plugins are referenced: for this, navigate in the ZMI to /ploneID/acl_users/plugins.  I don't know exactly which plugins are important to adjust here and which don't need to be adjusted, but I do know that you'll need to adjust at least one (maybe several) of the plugins of this Plugin Registry such that your LDAPMP is first in the list of plugins (whereas the default is to have source_users as the first in the list of plugins).  For my circumstances, I just clicked on all of the plugin types here and for any that showed my LDAPMP as available in the list of active plugins, I moved it to the top of the list.
  • I hope this helps some people.  Thanks very kindly to Wichert Akkerman (without whose help I could not have done this myself) and to all the developers of the Zope/Plone community for making Zope and Plone and all the other neat stuff that goes with them.
  • If you don't have everything working as desired, check Gmane for the thread on plone.user called "Plone 2.5 and LDAP" for more detail before posting to the list.  That thread has (I'm told) more than 50 posts in it, so there's alot of questions and answers contained therein that you should read before you ask a new one yourself.