diff --git a/CHANGES.rst b/CHANGES.rst index 686ee55..1ee3446 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,17 @@ Changelog - Drop support for Plone 4.1. [hvelarde] +- Fix plugin activation for AD; correctly add mandatory schema items; activate + group management plugin for non-AD (to allow modifying group memberships via + Plone). + [adaugherity] +- Properly store settings made via control panel so that the control panel, + ZMI, and portal_setup export all show the same data. Added some more fields + to portal_setup import/export, including extra_user_filter, group mappings, + and plugin type (AD/non-AD). + [adaugherity] +- Misc. minor bugfixes and documentation improvements. + [adaugherity] 1.3.2 (2015-03-02) diff --git a/README.rst b/README.rst index 0f25fa5..fab50d9 100644 --- a/README.rst +++ b/README.rst @@ -21,17 +21,24 @@ Plone can use both users and groups from an Active Directory system. Writing to Active Directory is not supported. With Active Directory you can use two different properties as login name: -`userPrincipalName` and `sAMAccountName`. `sAMAccountName` is the plain account -name without any domain information and is only unique within a single domain. -If your environment only uses a single AD domain this option is the best -choice. For environments with multiple names the `userPrincipalName` attribute -can be used since this includes both account name and domain information. - +``userPrincipalName`` and ``sAMAccountName``. ``sAMAccountName`` is the plain +account name without any domain information and is only unique within a single +domain. If your environment only uses a single AD domain this option is the +best choice. For environments with multiple names the ``userPrincipalName`` +attribute can be used since this includes both account name and domain +information. Since Plone does not support binary user ids it is not possible to use the -`objectGUID` attribute as user ids. Instead you can use either `sAMAccountName` -or `userPrincipalName`. The same criteria for choosing a login name also -apply to selecting the user id attribute. +``objectGUID`` attribute as user ids. Instead you can use either +``sAMAccountName`` or ``userPrincipalName``. The same criteria for choosing a +login name also apply to selecting the user id attribute. + +Newer versions of Active Directory may also work using the standard LDAP +plugin, which supports limited writing to AD, including modifying group +memberships. If your group objects have ``member`` attributes containing the +user's full DN, the standard LDAP plugin should work for you. Note that this +will not support nested groups. + Standard LDAP ------------- diff --git a/plone/app/ldap/engine/storage.py b/plone/app/ldap/engine/storage.py index f8dd999..dfe1ea9 100644 --- a/plone/app/ldap/engine/storage.py +++ b/plone/app/ldap/engine/storage.py @@ -28,6 +28,10 @@ class LDAPConfiguration(OrderedContainer): group_scope = SCOPE_SUBTREE password_encryption = "crypt" default_user_roles = "Member" + extra_user_filter = "" + local_groups = False + implicit_mapping = False + group_mappings = {} read_only = False activated_plugins = [] cache = '' diff --git a/plone/app/ldap/ploneldap/exportimport.py b/plone/app/ldap/ploneldap/exportimport.py index 6025244..2911e05 100644 --- a/plone/app/ldap/ploneldap/exportimport.py +++ b/plone/app/ldap/ploneldap/exportimport.py @@ -10,6 +10,7 @@ from xml.dom.minidom import parseString from zope.component import getUtility from zope.pagetemplate.pagetemplatefile import PageTemplateFile +import ast import logging ldap_props = ['_login_attr', @@ -19,6 +20,7 @@ 'users_scope', '_local_groups', '_implicit_mapping', + '_groups_mappings', 'groups_base', 'groups_scope', '_binduid', @@ -128,6 +130,7 @@ def importData(self, context, out): def extractData(self, root, pas, out): plug_id = str(root.getAttribute('id')) update = root.getAttribute('update') == 'True' + meta_type = root.getAttribute('meta_type') settings = {} interfaces = [] @@ -234,6 +237,12 @@ def extractData(self, root, pas, out): # base configuration config = getUtility(ILDAPConfiguration) + if meta_type in [u"Plone Active Directory plugin", + u"ActiveDirectory Multi Plugin"]: + config.ldap_type = u"AD" + else: + config.ldap_type = u"LDAP" + config.login_attribute = settings['_login_attr'] config.userid_attribute = settings['_uid_attr'] config.rdn_attribute = settings['_rdnattr'] @@ -244,8 +253,15 @@ def extractData(self, root, pas, out): config.bind_dn = settings['_binduid'] config.bind_password = settings['_bindpwd'] config.user_object_classes = ','.join(settings['_user_objclasses']) + config.extra_user_filter = settings['_extra_user_filter'] config.password_encryption = settings['_pwd_encryption'] config.default_user_roles = ','.join(settings['_roles']) + config.implicit_mapping = settings['_implicit_mapping'] + config.local_groups = settings['_local_groups'] + try: + config.group_mappings = ast.literal_eval(settings['_groups_mappings']) + except (ValueError, SyntaxError, KeyError): + config.group_mappings = {} config.read_only = settings['read_only'] config.activated_plugins = interfaces config.cache = cache diff --git a/plone/app/ldap/ploneldap/util.py b/plone/app/ldap/ploneldap/util.py index a393f25..7b83e97 100644 --- a/plone/app/ldap/ploneldap/util.py +++ b/plone/app/ldap/ploneldap/util.py @@ -78,6 +78,7 @@ def createLDAPPlugin(id="ldap-plugin"): bindpwd=config.bind_password or "", encryption=config.password_encryption, roles=config.default_user_roles or "", + local_groups=config.local_groups, read_only=config.read_only, obj_classes=config.user_object_classes) @@ -86,6 +87,10 @@ def createLDAPPlugin(id="ldap-plugin"): directlyProvides(plugin, IManagedLDAPPlugin) enablePASInterfaces() enableCaching(config.cache) + luf=plugin._getLDAPUserFolder() + luf.manage_changeProperty('_extra_user_filter', config.extra_user_filter) + luf.manage_changeProperty('_implicit_mapping', config.implicit_mapping) + luf.manage_changeProperty('_groups_mappings', config.group_mappings) def configureLDAPServers():