Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java	(révision 0)
@@ -0,0 +1,219 @@
+package com.xpn.xwiki.plugin.ldap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.xpn.xwiki.XWikiContext;
+
+/**
+ * Access to LDAP configurations.
+ * 
+ * @version $Id: $
+ */
+public final class XWikiLDAPConfig
+{
+    /**
+     * LDAP properties names suffix in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_SUFFIX = "ldap_";
+
+    /**
+     * LDAP port property name in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_PORT = CFG_LDAP_SUFFIX + "port";
+
+    /**
+     * LDAP group mapping properties names suffix in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_GROUPMAPPING_SUFFIX = CFG_LDAP_PORT + "group_mapping_";
+
+    /**
+     * LDAP properties names suffix in XWikiPreferences.
+     */
+    public static final String PROP_LDAP_SUFFIX = "xwiki.authentication.ldap.";
+
+    /**
+     * LDAP port property name in XWikiPreferences.
+     */
+    public static final String PROP_LDAP_PORT = "ldap_port";
+
+    /**
+     * Mapping fields separator.
+     */
+    public static final String USERMAPPING_SEP = ",";
+
+    /**
+     * Character user to link XWiki field name and LDAP field name in user mappings property.
+     */
+    public static final String USERMAPPING_XWIKI_LDAP_LINK = "=";
+
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPConfig.class);
+
+    /**
+     * Unique instance of {@link XWikiLDAPConfig}.
+     */
+    private static XWikiLDAPConfig instance;
+
+    /**
+     * Protected constructor. Use {@link #getInstance()}.
+     */
+    private XWikiLDAPConfig()
+    {
+
+    }
+
+    /**
+     * @return unique instance of {@link XWikiLDAPConfig}.
+     */
+    public static XWikiLDAPConfig getInstance()
+    {
+        if (instance == null) {
+            instance = new XWikiLDAPConfig();
+        }
+
+        return instance;
+    }
+
+    /**
+     * First try to retrieve value from XWiki Preferences and then from xwiki.cfg Syntax ldap_*name*
+     * (for XWiki Preferences) will be changed to ldap.*name* for xwiki.cfg.
+     * 
+     * @param name the name of the property.
+     * @param def default value.
+     * @param context the XWiki context.
+     * @return the value of the property.
+     */
+    public String getLDAPParam(String name, String def, XWikiContext context)
+    {
+        String param = def;
+
+        try {
+            param = context.getWiki().getXWikiPreference(name, context);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        if (param == null || "".equals(param)) {
+            try {
+                param =
+                    context.getWiki().Param(
+                        StringUtils.replace(name, CFG_LDAP_SUFFIX, PROP_LDAP_SUFFIX));
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        if (param == null) {
+            param = def;
+        }
+
+        return param;
+    }
+
+    /**
+     * Get LDAP port from configuration.
+     * 
+     * @param context the XWiki context.
+     * @return the LDAP port.
+     */
+    public int getLDAPPort(XWikiContext context)
+    {
+        int port;
+
+        try {
+            port = context.getWiki().getXWikiPreferenceAsInt(CFG_LDAP_PORT, context);
+        } catch (Exception e) {
+            port = (int) context.getWiki().ParamAsLong(PROP_LDAP_PORT, 0);
+        }
+
+        return port;
+    }
+
+    /**
+     * Get mapping between XWiki users and LDAP users.
+     * 
+     * @param context the XWiki context.
+     * @return the mapping between XWiki users and LDAP users.
+     */
+    public Map getGroupMappings(XWikiContext context)
+    {
+        Map groupMappings = new HashMap();
+
+        int pos = 1;
+        String grouplistmapping = getLDAPParam(CFG_LDAP_GROUPMAPPING_SUFFIX + pos, "", context);
+        while (grouplistmapping != null && grouplistmapping.length() > 0) {
+            int splitt = grouplistmapping.indexOf('=');
+
+            if (splitt < 1) {
+                LOG.error("Error parsing ldap_group_mapping attribute in xwiki.cfg: "
+                    + grouplistmapping);
+            } else {
+                String xwikigroup = grouplistmapping.substring(0, splitt);
+                String ldapgroup = grouplistmapping.substring(splitt + 1);
+
+                groupMappings.put(ldapgroup, xwikigroup);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Groupmapping found: " + xwikigroup + " " + ldapgroup);
+                }
+            }
+
+            ++pos;
+            grouplistmapping = getLDAPParam(CFG_LDAP_GROUPMAPPING_SUFFIX + pos, null, context);
+        }
+
+        return groupMappings;
+    }
+
+    /**
+     * Get mapping between XWiki groups and LDAP groups.
+     * 
+     * @param attrListToFill the list to fill with extracted LDAP fields to use in LDAP search.
+     * @param context the XWiki context.
+     * @return the mapping between XWiki groups and LDAP groups.
+     */
+    public Map getUserMappings(List attrListToFill, XWikiContext context)
+    {
+        Map userMappings = new HashMap();
+
+        String ldapFieldMapping = getLDAPParam("ldap_fields_mapping", null, context);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Ready to create user from LDAP with fields " + ldapFieldMapping);
+        }
+
+        if (ldapFieldMapping != null && ldapFieldMapping.length() > 0) {
+            String[] fields = ldapFieldMapping.split(USERMAPPING_SEP);
+
+            for (int j = 0; j < fields.length; j++) {
+                String[] field = fields[j].split(USERMAPPING_XWIKI_LDAP_LINK);
+                if (2 == field.length) {
+                    String xwikiattr = field[0].replace(" ", "");
+                    String ldapattr = field[1].replace(" ", "");
+
+                    userMappings.put(ldapattr, xwikiattr);
+
+                    attrListToFill.add(ldapattr);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Found field mapping: " + xwikiattr
+                            + USERMAPPING_XWIKI_LDAP_LINK + ldapattr);
+                    }
+                } else {
+                    LOG.error("Error parsing ldap_fields_mapping attribute in xwiki.cfg: "
+                        + fields[j]);
+                }
+            }
+        }
+
+        return userMappings;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java	(révision 0)
@@ -0,0 +1,31 @@
+package com.xpn.xwiki.plugin.ldap;
+
+/**
+ * Represent an LDAP attribute.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPSearchAttribute
+{
+    /**
+     * Attribute name.
+     */
+    public String attrName;
+
+    /**
+     * Attribute value.
+     */
+    public String attrValue;
+
+    /**
+     * Create attribute instance.
+     * 
+     * @param name attribute name.
+     * @param value attribute value.
+     */
+    public XWikiLDAPSearchAttribute(String name, String value)
+    {
+        attrName = name;
+        attrValue = value;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java	(révision 0)
@@ -0,0 +1,365 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.plugin.ldap;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.novell.ldap.LDAPAttribute;
+import com.novell.ldap.LDAPAttributeSet;
+import com.novell.ldap.LDAPConnection;
+import com.novell.ldap.LDAPEntry;
+import com.novell.ldap.LDAPException;
+import com.novell.ldap.LDAPJSSESecureSocketFactory;
+import com.novell.ldap.LDAPSearchConstraints;
+import com.novell.ldap.LDAPSearchResults;
+import com.novell.ldap.LDAPSocketFactory;
+import com.xpn.xwiki.XWikiContext;
+
+import java.security.Security;
+
+/**
+ * LDAP communication tool.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPConnection
+{
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPConnection.class);
+
+    /**
+     * The LDAP connection.
+     */
+    private LDAPConnection connection;
+
+    /**
+     * Open a LDAP connection.
+     * 
+     * @param ldapUserName the user name to connect to LDAP server.
+     * @param password the password to connect to LDAP server.
+     * @param context the XWiki context.
+     * @return true if connection succeed, false otherwise.
+     */
+    public boolean open(String ldapUserName, String password, XWikiContext context)
+    {
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+        
+        // open LDAP
+        int ldapPort = config.getLDAPPort(context);
+        String ldapHost = config.getLDAPParam("ldap_server", "127.0.0.1", context);
+        String bindDNFormat = config.getLDAPParam("ldap_bind_DN", "", context);
+        String bindPasswordFormat = config.getLDAPParam("ldap_bind_pass", "{1}", context);
+
+        Object[] arguments = {ldapUserName, password};
+
+        // allow to use the given user and password also as the LDAP bind user and password
+        String bindDN = MessageFormat.format(bindDNFormat, arguments);
+        String bindPassword = MessageFormat.format(bindPasswordFormat, arguments);
+
+        boolean bind;
+        if ("1".equals(config.getLDAPParam("ldap_ssl", "0", context))) {
+            String keyStore = config.getLDAPParam("ldap_ssl.keystore", "", context);
+            
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Connecting to LDAP using SSL");
+            }
+            
+            bind = open(ldapHost, ldapPort, bindDN, bindPassword, keyStore, true);
+        } else {
+            bind = open(ldapHost, ldapPort, bindDN, bindPassword, null, false);
+        }
+
+        return bind;
+    }
+
+    /**
+     * Open LDAP connection.
+     * 
+     * @param ldapHost the host of the server to connect to.
+     * @param ldapPort the port of the server to connect to.
+     * @param loginDN  the user DN to connect to LDAP server.
+     * @param password the password to connect to LDAP server.
+     * @param pathToKeys the patch to SSL keystore to use.
+     * @param ssl if true connect using SSL.
+     * @return true if the connection succeed, false otherwise.
+     */
+    public boolean open(String ldapHost, int ldapPort, String loginDN, String password,
+        String pathToKeys, boolean ssl)
+    {
+        int port = ldapPort;
+
+        if (port <= 0) {
+            port = ssl ? LDAPConnection.DEFAULT_SSL_PORT : LDAPConnection.DEFAULT_PORT;
+        }
+
+        int ldapVersion = LDAPConnection.LDAP_V3;
+
+        try {
+            if (ssl) {
+                // Dynamically set JSSE as a security provider
+                Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+
+                if (pathToKeys != null && pathToKeys.length() > 0) {
+                    // Dynamically set the property that JSSE uses to identify
+                    // the keystore that holds trusted root certificates
+
+                    System.setProperty("javax.net.ssl.trustStore", pathToKeys);
+                    // obviously unnecessary: sun default pwd = "changeit"
+                    // System.setProperty("javax.net.ssl.trustStorePassword", sslpwd);
+                }
+
+                LDAPSocketFactory ssf = new LDAPJSSESecureSocketFactory();
+
+                // Set the socket factory as the default for all future connections
+                // LDAPConnection.setSocketFactory(ssf);
+
+                // Note: the socket factory can also be passed in as a parameter
+                // to the constructor to set it for this connection only.
+                this.connection = new LDAPConnection(ssf);
+            } else {
+                this.connection = new LDAPConnection();
+            }
+
+            // connect to the server
+            this.connection.connect(ldapHost, port);
+
+            // authenticate to the server
+            this.connection.bind(ldapVersion, loginDN, password.getBytes("UTF8"));
+
+            if (!this.connection.isConnected() || !this.connection.isConnectionAlive()) {
+                if (ssl) {
+                    LOG
+                        .error("Connection to LDAP through SSL failed. Beyond other causes, verify that the SSL certificate is found in the keystore.");
+                } else {
+                    LOG.error("Connection to LDAP failed.");
+                }
+
+                return false;
+            }
+
+            if (!this.connection.isBound()) {
+                LOG.debug("Binding to LDAP failed, - ok if Annonymous Access");
+            }
+
+            return true;
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("LDAP bind failed.", e);
+        } catch (LDAPException e) {
+            LOG.error("LDAP bind failed.", e);
+        }
+
+        return false;
+    }
+
+    /**
+     * Close LDAP connection.
+     */
+    public void close()
+    {
+        try {
+            if (this.connection != null) {
+                this.connection.disconnect();
+            }
+        } catch (LDAPException e) {
+            LOG.debug("LDAP close failed.", e);
+        }
+    }
+
+    public boolean verifyPWD(String user_dn, String pwd)
+    {
+        try {
+            LDAPAttribute attr = new LDAPAttribute("userPassword", pwd);
+            return this.connection.compare(user_dn, attr);
+        } catch (LDAPException e) {
+            if (e.getResultCode() == LDAPException.NO_SUCH_OBJECT) {
+                LOG.error("Unable to locate user_dn:" + user_dn, e);
+            } else if (e.getResultCode() == LDAPException.NO_SUCH_ATTRIBUTE) {
+                LOG.error("Unable to verify password because userPassword attribute not found.",
+                    e);
+            } else {
+                LOG.error("Unable to verify password", e);
+            }
+        }
+        
+        return false;
+    }
+
+    // LDAPConnection.SCOPE_SUB oder LDAPConnection.SCOPE_BASE
+    public List searchLDAP(String baseDN, String query, String[] attr, int ldap_scope)
+    {
+        List attributes = new ArrayList();
+
+        try {
+            LDAPSearchConstraints cons = new LDAPSearchConstraints();
+            cons.setTimeLimit(1000);
+
+            // filter return all attributes return attrs and values time out value
+            LDAPSearchResults searchResults =
+                this.connection.search(baseDN, ldap_scope, query, attr, false, cons);
+
+            if (!searchResults.hasMore()) {
+                return null;
+            }
+
+            LDAPEntry nextEntry = searchResults.next();
+            String foundDN = nextEntry.getDN();
+            attributes.add(new XWikiLDAPSearchAttribute("dn", foundDN));
+
+            LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
+
+            for (Iterator attributeIt = attributeSet.iterator(); attributeIt.hasNext();) {
+                LDAPAttribute attribute = (LDAPAttribute) attributeIt.next();
+                String attributeName = attribute.getName();
+
+                Enumeration allValues = attribute.getStringValues();
+
+                if (allValues != null) {
+                    while (allValues.hasMoreElements()) {
+
+                        String value = (String) allValues.nextElement();
+                        attributes.add(new XWikiLDAPSearchAttribute(attributeName, value));
+                    }
+                }
+            }
+        } catch (LDAPException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("LDAP Search failed", e);
+            }
+
+            attributes = null;
+        }
+
+        return attributes;
+    }
+
+    /**
+     * Get all members of a given group based on the groupDN. If the group contains subgroups get
+     * these members as well. Retrieve an identifier for each member.
+     * 
+     * @param groupDN The group to retrieve the members of and scan for subgroups.
+     * @param uidattr The attribute containing the identifier for a user (default=cn).
+     * @param members is the result: maps dn to member id.
+     * @param subgroups returns all the subgroubs identified.
+     * @return whether the groupDN is actually a group.
+     */
+    public boolean getGroupMembers(String groupDN, String uidattr, Map members, List subgroups)
+    {
+        // break out if there is a look of groups
+        if (subgroups != null && subgroups.contains(groupDN)) {
+            return true;
+        }
+
+        if (uidattr == null || uidattr.length() == 0) {
+            uidattr = "cn";
+        }
+
+        String[] attrs = new String[] {"objectClass", uidattr, "member"};
+
+        List list = searchLDAP(groupDN, null, attrs, LDAPConnection.SCOPE_BASE);
+
+        if (list == null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Failed locating group " + groupDN);
+            }
+
+            return false;
+        }
+
+        boolean isGroup = false;
+        String id = null;
+
+        for (Iterator seachAttributeIt = list.iterator(); seachAttributeIt.hasNext();) {
+            XWikiLDAPSearchAttribute seachAttribute =
+                (XWikiLDAPSearchAttribute) seachAttributeIt.next();
+
+            String key = seachAttribute.attrName;
+            if (key.equalsIgnoreCase("objectClass")) {
+                String objectName = seachAttribute.attrValue;
+                if (objectName.equalsIgnoreCase("group")
+                    || objectName.equalsIgnoreCase("groupOfNames")
+                    || objectName.equalsIgnoreCase("groupOfUniqueNames")
+                    || objectName.equalsIgnoreCase("dynamicGroup")
+                    || objectName.equalsIgnoreCase("dynamicGroupAux")
+                    || objectName.equalsIgnoreCase("groupWiseDistributionList")) {
+                    isGroup = true;
+                }
+            }
+
+            if (key.equalsIgnoreCase(uidattr)) {
+                id = seachAttribute.attrValue;
+            }
+        }
+
+        if (!isGroup) {
+            // not a group but actually a member
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("This object is NOT a group object: " + groupDN);
+            }
+
+            // add all new members
+            if (id == null) {
+                LOG.error("Could not find attribute " + uidattr + " for LDAP dn " + groupDN);
+                id = "";
+            }
+
+            if (!members.containsKey(groupDN)) {
+                members.put(groupDN, id);
+            }
+
+            return false;
+        }
+
+        // remember this group
+        if (subgroups != null) {
+            subgroups.add(groupDN);
+        }
+
+        for (Iterator searchAttributeIt = list.iterator(); searchAttributeIt.hasNext();) {
+            XWikiLDAPSearchAttribute searchAttribute =
+                (XWikiLDAPSearchAttribute) searchAttributeIt.next();
+
+            String key = searchAttribute.attrName;
+            if (key.equalsIgnoreCase("member") || key.equalsIgnoreCase("uniqueMember")) {
+
+                // or subgroup
+                String member = searchAttribute.attrValue;
+
+                // we check for subgroups recursive call to scan all subgroups and identify members
+                // and their uid
+                getGroupMembers(member, uidattr, members, subgroups);
+            }
+        }
+
+        return true;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java	(révision 0)
@@ -0,0 +1,816 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.user.impl.LDAP;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.securityfilter.realm.SimplePrincipal;
+
+import com.novell.ldap.LDAPConnection;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.cache.api.XWikiCache;
+import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPConfig;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPConnection;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPSearchAttribute;
+import com.xpn.xwiki.user.api.XWikiGroupService;
+import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
+import java.security.Principal;
+import java.util.HashMap;
+
+/**
+ * This class provides an authentication method that validates a user trough LDAP against a
+ * directory. It just gives LDAP users access if they belong to a particular group and creates XWiki
+ * users if they have never logged in before Furthermore, it synchronizes membership to XWiki groups
+ * based on membership to LDAP groups.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPAuthServiceImpl extends XWikiAuthServiceImpl
+{
+    /**
+     * simple cache for LDAP groups and their members - cache entries are to expire after 6h and
+     * there is no size limit.
+     */
+    protected static XWikiCache cache;
+
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPAuthServiceImpl.class);
+
+    /**
+     * Initialize groups cache.
+     * 
+     * @param context the XWiki context containing {@link XWikiCacheService}.
+     * @throws XWikiException error when creating the cache.
+     */
+    private static void initGroupCache(XWikiContext context) throws XWikiException
+    {
+        if (cache == null) {
+            cache = context.getWiki().getCacheService().newCache("ldap.group");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl#authenticate(java.lang.String,
+     *      java.lang.String, com.xpn.xwiki.XWikiContext)
+     */
+    public Principal authenticate(String userName, String password, XWikiContext context)
+        throws XWikiException
+    {
+        // 1. check Superadmin
+        // 2. check if ldap authentication is off => authenticate against db
+        // 3. bind to LDAP => if failed try db
+        // 4. if group param, verify group membership (& get DN)
+        // 4. if no group locate dn_ldap attribute on user
+        // 5. if no dn search for user
+        // 6. compare pwd
+        // 7. if flag check if !user exists => create user
+        // 8. if flag update user attributes
+        // 9. if flag update Xwiki groupmembership
+        // on Error try local DB login
+
+        Principal principal = null;
+
+        // Check if cache is initialized
+        initGroupCache(context);
+
+        // message to the user: nousername, nopassword, wrongpassword, wronguser, loginfailed
+        // context.put("message", "nopassword");
+
+        if ((userName == null) || (userName.length() == 0)) {
+            return null;
+        }
+        String ldapUserName = userName.replaceAll(" ", "");
+        if ((password == null) || (password.trim().length() == 0)) {
+            return null;
+        }
+
+        // strip possible "XWiki."
+        // ATTENTION: Possible incompatibility to before now user is NEVER located with
+        // "XWiki.username" in LDAP
+        int i = ldapUserName.indexOf(".");
+        if (i != -1) {
+            ldapUserName = ldapUserName.substring(i + 1);
+        }
+
+        // If we have the context then we are using direct mode
+        // then we should specify the database
+        // This is needed for virtual mode to work
+
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        XWikiLDAPConnection connector = new XWikiLDAPConnection();
+
+        try {
+            principal = checkSuperadmin(ldapUserName, password, context);
+            if (principal != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Superadmin logged in.");
+                }
+
+                return principal;
+            }
+
+            // check if LDAP is activated in xwiki.cfg
+            String ldapActiv = config.getLDAPParam("ldap", "0", context);
+            if (!ldapActiv.equalsIgnoreCase("1")) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("LDAP authentication failed: LDAP not activ");
+                }
+
+                return null;
+            }
+
+            // Open LDAP connection
+            if (!connector.open(ldapUserName, password, context)) {
+                LOG.error("Bind to LDAP server failed.");
+                return null;
+            }
+
+            String uidattr = config.getLDAPParam("ldap_UID_attr", "cn", context);
+
+            // verify group
+            String ldapUserDn = null;
+            String userGroup = config.getLDAPParam("ldap_user_group", "", context);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Checking if the user belongs to the user group: " + userGroup);
+            }
+
+            if (userGroup.length() > 0) {
+                Map groupMembers = getGroupMembers(connector, userGroup, context);
+
+                // check if user is in the list
+                ldapUserDn = findInGroup(ldapUserName, groupMembers, "cn");
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user dn in user group:" + ldapUserDn);
+                }
+
+                // if a usergroup is specified THEN the user MUST be in the group to validate in
+                // LDAP
+                if (ldapUserDn == null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("LDAP authentication failed: user not in LDAP user group");
+                    }
+
+                    // no valid LDAP user from the group
+                    return null;
+                }
+            }
+
+            if (ldapUserDn == null) {
+                // get DN from existing XWiki user
+                ldapUserDn = getLDAPDN(ldapUserName, context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user dn with the user object: " + ldapUserDn);
+                }
+            }
+
+            // parse field mappings
+            List attributeNameList = new ArrayList();
+            Map userMappings = config.getUserMappings(attributeNameList, context);
+
+            List searchAttributes = null;
+
+            // if we still don't have a dn, search for it. Also get the attributes, we might need
+            // them
+            if (ldapUserDn == null) {
+                // search for the user in LDAP
+                String query = "(" + uidattr + "=" + ldapUserName + ")";
+                String baseDN = config.getLDAPParam("ldap_base_DN", "", context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Searching for the user in LDAP: user:" + ldapUserName + " base:"
+                        + baseDN + " query:" + query + " uid:" + uidattr);
+                }
+
+                String[] attributeNameTable = null;
+                int lsize = attributeNameList.size();
+                if (lsize > 0) {
+                    attributeNameTable = (String[]) attributeNameList.toArray(new String[lsize]);
+                }
+
+                searchAttributes =
+                    connector.searchLDAP(baseDN, query, attributeNameTable,
+                        LDAPConnection.SCOPE_SUB);
+
+                for (Iterator it = searchAttributes.iterator(); it.hasNext();) {
+                    XWikiLDAPSearchAttribute searchAttribute =
+                        (XWikiLDAPSearchAttribute) it.next();
+
+                    if ("dn".equals(searchAttribute.attrName)) {
+                        ldapUserDn = searchAttribute.attrValue;
+
+                        break;
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found Attributes in LDAP " + searchAttributes.size());
+                    LOG.debug("Found user dn=" + ldapUserDn);
+                }
+            }
+
+            // NOW verify password
+            if ("1".equals(config.getLDAPParam("ldap_validate_password", "0", context))) {
+                if (!connector.verifyPWD(ldapUserDn, password)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG
+                            .debug("LDAP authentication failed: could not validate the password: wrong password for "
+                                + ldapUserDn);
+                    }
+
+                    return null;
+                }
+            } else {
+                LOG.debug("Password is already supposed to be verified when bound to LDAP");
+            }
+
+            // check if we have to create the user
+            String xwikiuser = findUser(ldapUserName, context);
+
+            boolean createuser = false;
+            if (xwikiuser == null
+                || config.getLDAPParam("ldap_update_user", "0", context).equals("1")) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("LDAP attributes will be used to update XWiki attributes.");
+                }
+
+                // get attributes from LDAP if we don't already have them
+                if (searchAttributes == null) {
+                    String[] attributeNameTable = null;
+                    int lsize = attributeNameList.size();
+                    if (lsize > 0) {
+                        attributeNameTable =
+                            (String[]) attributeNameList.toArray(new String[lsize]);
+                    }
+
+                    // didn't get attributes before, so do it now
+                    searchAttributes =
+                        connector.searchLDAP(ldapUserDn, null, attributeNameTable,
+                            LDAPConnection.SCOPE_BASE);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Found Attributes in LDAP " + searchAttributes.size());
+                    }
+                }
+
+                // create user
+                if (xwikiuser == null) {
+                    LOG.debug("Creating new XWiki user based on LDAP attribues located at "
+                        + ldapUserDn);
+                    createUserFromLDAP(ldapUserName, userMappings, searchAttributes, context);
+                    LOG.debug("New XWiki user created: " + ldapUserName);
+                    createuser = true;
+                } else {
+                    LOG.debug("Updating existing user with LDAP attribues located at "
+                        + ldapUserDn);
+                    updateUserFromLDAP(ldapUserName, userMappings, searchAttributes, context);
+                }
+            }
+
+            // from now on we can enter the application
+            principal = getUserPrincipal(ldapUserName, context);
+            if (principal == null) {
+                LOG.debug("Could not create authenticated principal.");
+                return null;
+            }
+
+            // got valid group mappings
+            Map groupMappings = config.getGroupMappings(context);
+
+            // update group membership, join and remove from given groups
+            // sync group membership for this user
+            if (groupMappings.size() > 0) {
+                // flag if always sync or just on create of the user
+                String syncmode = config.getLDAPParam("ldap_mode_group_sync", "", context);
+
+                if ((syncmode.equalsIgnoreCase("create") && createuser)
+                    || syncmode.equalsIgnoreCase("always")) {
+                    syncGroupsMembership(ldapUserName, ldapUserDn, groupMappings, connector,
+                        context);
+                }
+
+            }
+        } catch (Exception e) {
+            LOG.error("LDAP authentication failed.", e);
+        } finally {
+            connector.close();
+
+            // one last option
+            if (principal == null) {
+                String trylocal = config.getLDAPParam("ldap_trylocal", "0", context);
+
+                if ("1".equals(trylocal)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Trying authentication against XWiki DB");
+                    }
+
+                    // try local user
+                    // Use XWiki password
+                    if (checkPassword(findUser(ldapUserName, context), password, context)) {
+                        principal = getUserPrincipal(ldapUserName, context);
+
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("XWiki DB login succeeded");
+                        }
+                    } else {
+                        context.put("message", "loginfailed");
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("XWiki DB login failed");
+                        }
+                    }
+                }
+            }
+        }
+
+        return principal;
+    }
+
+    protected void syncGroupsMembership(String userName, String userDn, Map groupMappings,
+        XWikiLDAPConnection connector, XWikiContext context)
+        throws XWikiCacheNeedsRefreshException, XWikiException
+    {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Updating group membership for the user: " + userName);
+        }
+
+        // ASSUMING the implementation still returns the actual list. In this case
+        // manipulations to the list are for real.
+        // get the list of groups the user already belongs to
+        Collection userGroups =
+            context.getWiki().getGroupService(context).getAllGroupsNamesForMember(userName, 0, 0,
+                context);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("The user belongs to following XWiki groups: ");
+            for (Iterator it = userGroups.iterator(); it.hasNext();) {
+                LOG.debug(it.next().toString());
+            }
+        }
+
+        // retrieve list of all groups
+        List allxwikigroups =
+            context.getWiki().getGroupService(context).getAllMatchedGroups(null, false, 0, 0,
+                null, context);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("All defined XWiki groups: ");
+            for (Iterator it = allxwikigroups.iterator(); it.hasNext();) {
+                LOG.debug(it.next().toString());
+            }
+        }
+
+        // go through mapped groups to locate the user
+        for (Iterator itGroupMap = groupMappings.entrySet().iterator(); itGroupMap.hasNext();) {
+            Map.Entry entry = (Map.Entry) itGroupMap.next();
+
+            String ldapGroupName = (String) entry.getKey();
+            String xwikiGroupName = (String) entry.getValue();
+
+            // check if group is in list of all groups
+            if (!allxwikigroups.contains(xwikiGroupName)) {
+                LOG.error("XWiki group not found:" + xwikiGroupName);
+                continue;
+            }
+
+            Map groupMembers = getGroupMembers(connector, ldapGroupName, context);
+
+            if (groupMembers.containsKey(userDn)) {
+                // add to group if not there
+                if (!userGroups.contains(xwikiGroupName)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG
+                            .debug("Adding user " + userName + " to xwiki group "
+                                + xwikiGroupName);
+                    }
+
+                    addUserToGroup(userName, xwikiGroupName, context);
+                    // c.add(xwikigroupname);
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Finished adding user " + userName + " to xwiki group "
+                            + xwikiGroupName);
+                    }
+                    // is supposed to equivalent to
+                    // context.getWiki().getGroupService(context).addUserToGroup(user,
+                    // context.getDatabase(), xwikigroupname, context);
+                }
+            } else {
+                // remove from group if there
+                if (userGroups.contains(xwikiGroupName)) {
+                    removeUserFromGroup(userName, xwikiGroupName, context);
+                    // c.remove(xwikigroupname);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Finished removing xwiki group " + xwikiGroupName
+                            + " from user " + userName);
+                    }
+                }
+            }
+        }
+
+        /*
+         * This may not be necessary, but the group service does have a cache, and I've found that
+         * adding or removing entries sometimes don't take effect if I don't do this.
+         */
+        context.getWiki().getGroupService(context).flushCache();
+    }
+
+    /**
+     * Get group members from cache or update it from LDAP if it is not already in cached.
+     * 
+     * @param connector the LDAP communication tool.
+     * @param groupname the name of the group.
+     * @param uidattr
+     * @param context the XWiki context.
+     * @return the memebers of the group.
+     * @throws XWikiCacheNeedsRefreshException error when getting group memebers from cache.
+     */
+    protected Map getGroupMembers(XWikiLDAPConnection connector, String groupname,
+        XWikiContext context) throws XWikiCacheNeedsRefreshException
+    {
+        Map groupMembers = null;
+
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        String uidattr = config.getLDAPParam("ldap_UID_attr", "cn", context);
+
+        synchronized (cache) {
+            groupMembers = (Map) cache.getFromCache(groupname, getCacheExpiration(context));
+        }
+
+        if (groupMembers == null) {
+            groupMembers = new HashMap();
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieving Members of the group: " + groupname);
+            }
+
+            if (connector.getGroupMembers(groupname, uidattr, groupMembers, new ArrayList())) {
+                synchronized (cache) {
+                    cache.putInCache(groupname, groupMembers);
+                }
+            }
+        }
+
+        return groupMembers;
+    }
+
+    /**
+     * Retrieve the time in ms until a entry in the cache is to expire - helper.
+     */
+    protected int getCacheExpiration(XWikiContext context)
+    {
+        try {
+            return context.getWiki().getXWikiPreferenceAsInt("ldap_groupcache_expiration",
+                context);
+        } catch (Exception e) {
+            return (int) context.getWiki().ParamAsLong(
+                "xwiki.authentication.ldap.groupcache_expiration", 21800);
+        }
+    }
+
+    protected void addUserToGroup(String userName, String groupName, XWikiContext context)
+    {
+        try {
+            String fullWikiUserName = "XWiki." + userName;
+
+            String groupClassName = context.getWiki().getGroupClass(context).getName();
+
+            // Get document representing group
+            XWikiDocument groupDoc = context.getWiki().getDocument(groupName, context);
+
+            // Add a member object to document
+            BaseObject memberobj = groupDoc.newObject(groupClassName, context);
+            memberobj.setStringValue("member", fullWikiUserName);
+
+            // Save modifications
+            context.getWiki().saveDocument(groupDoc, context);
+
+            // Update group cache
+            XWikiGroupService gservice = context.getWiki().getGroupService(context);
+            gservice.addUserToGroup(fullWikiUserName, context.getDatabase(), groupName, context);
+
+        } catch (Exception e) {
+            LOG.error(String.format("Failed to add a user [{0}] to a group [{1}]", new String[] {
+            userName, groupName}), e);
+        }
+    }
+
+    protected void removeUserFromGroup(String userName, String groupName, XWikiContext context)
+    {
+        try {
+            String fullWikiUserName = "XWiki." + userName;
+
+            String groupClassName = context.getWiki().getGroupClass(context).getName();
+
+            // Get the XWiki document holding the objects comprising the group membership list
+            XWikiDocument groupDoc = context.getWiki().getDocument(groupName, context);
+
+            // Get and remove the specific group membership object for the user
+            BaseObject groupObj = groupDoc.getObject(groupClassName, "member", fullWikiUserName);
+            groupDoc.removeObject(groupObj);
+
+            // Save modifications
+            context.getWiki().saveDocument(groupDoc, context);
+
+            // XWikiGroupService gservice = context.getWiki().getGroupService(context);
+            // gservice.addUserToGroup(fullwikiname, context.getDatabase(), groupname, context);
+
+        } catch (Exception e) {
+            LOG.error(
+                "Failed to remove a user from a group " + userName + " group: " + groupName, e);
+        }
+    }
+
+    protected SimplePrincipal checkSuperadmin(String username, String password,
+        XWikiContext context)
+    {
+        SimplePrincipal principal = null;
+
+        String superadmin = "superadmin";
+        if (username.equals(superadmin)) {
+            String superadminpassword = context.getWiki().Param("xwiki.superadminpassword");
+            if ((superadminpassword != null) && (superadminpassword.equals(password))) {
+                principal = new SimplePrincipal("XWiki.superadmin");
+            }
+        }
+
+        return principal;
+    }
+
+    protected Principal getUserPrincipal(String userName, XWikiContext context)
+    {
+        Principal principal = null;
+
+        // First we check in the local database
+        String user = null;
+        try {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Finding user " + userName);
+            }
+
+            user = findUser(userName, context);
+            if (user != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user " + userName);
+                }
+
+                principal = new SimplePrincipal(user);
+            }
+        } catch (Exception e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Failed creating a Principal for user " + user, e);
+            }
+        }
+
+        if (context.isVirtual()) {
+            if (principal == null) {
+                // Then we check in the main database
+                String database = context.getDatabase();
+
+                try {
+                    context.setDatabase(context.getMainXWiki());
+
+                    try {
+                        user = findUser(userName, context);
+                        if (user != null) {
+                            principal = new SimplePrincipal(context.getDatabase() + ":" + user);
+                        }
+                    } catch (Exception e) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Failed creating a Principal for user " + user, e);
+                        }
+                    }
+                } finally {
+                    context.setDatabase(database);
+                }
+            }
+        }
+
+        return principal;
+    }
+
+    /**
+     * Sets attributes on the user object based on attribute values provided by the LDAP.
+     * 
+     * @param userName
+     * @param mappings
+     * @param attributes
+     * @param context
+     * @throws XWikiException
+     */
+    protected void updateUserFromLDAP(String userName, Map mappings, List attributes,
+        XWikiContext context) throws XWikiException
+    {
+        BaseClass userClass = context.getWiki().getUserClass(context);
+
+        String fullWikiUserName = "XWiki." + userName;
+        XWikiDocument doc = context.getWiki().getDocument(fullWikiUserName, context);
+        BaseObject bobj = doc.getObject(userClass.getName());
+
+        for (Iterator it = attributes.iterator(); it.hasNext();) {
+            XWikiLDAPSearchAttribute lattr = (XWikiLDAPSearchAttribute) it.next();
+
+            String lval = lattr.attrValue;
+            String xattr = (String) mappings.get(lattr.attrName);
+
+            if (xattr != null) {
+                if (xattr.equals("name")) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Ignoring a mapping for name since the name is already set to "
+                            + userName);
+                    }
+                } else {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Setting XWiki field " + xattr + " (from LDAP attribute: "
+                            + lattr.attrName + ") Value:" + lval);
+                    }
+
+                    bobj.setStringValue(xattr, lval);
+                }
+            }
+        }
+
+        context.getWiki().saveDocument(doc, context);
+    }
+
+    /**
+     * Create an XWiki user and set all mapped attributes from LDAP to XWiki attributes.
+     * 
+     * @param mappings
+     * @param attributes
+     * @param context
+     * @throws XWikiException
+     */
+    protected void createUserFromLDAP(String userName, Map mappings, List attributes,
+        XWikiContext context) throws XWikiException
+    {
+        BaseClass userClass = context.getWiki().getUserClass(context);
+
+        Map map = new HashMap();
+        for (Iterator it = attributes.iterator(); it.hasNext();) {
+            XWikiLDAPSearchAttribute lattr = (XWikiLDAPSearchAttribute) it.next();
+
+            String lval = lattr.attrValue;
+            String xattr = (String) mappings.get(lattr.attrName);
+            if (xattr == null) {
+                continue;
+            }
+            map.put(xattr, lval);
+            LOG.debug("Mapping " + xattr + " to " + lval);
+        }
+        // Mark user active
+        map.put("active", "1");
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Creating User: " + userName);
+        }
+
+        context.getWiki().createUser(userName, map, userClass.getName(),
+            "#includeForm(\"XWiki.XWikiUserTemplate\")", "edit", context);
+    }
+
+    /**
+     * Locates the user in the Map: either the user is a value or the key starts with the LDAP
+     * syntax.
+     * 
+     * @param user
+     * @param groupMembers
+     * @param uid
+     * @return
+     */
+    protected String findInGroup(String user, Map groupMembers, String uid)
+    {
+        String result = null;
+
+        String ldapuser = null;
+        if (uid == null || uid.length() == 0) {
+            uid = "cn";
+        }
+        ldapuser = uid + "=" + user.toLowerCase();
+
+        for (Iterator it = groupMembers.keySet().iterator(); it.hasNext();) {
+            String u = (String) it.next();
+            // implementing it case-insensitive for now
+            if (user.equalsIgnoreCase((String) groupMembers.get(u))
+                || u.toLowerCase().startsWith(ldapuser)) {
+                return u;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Tries to retrieve the DN from the users object.
+     * 
+     * @param susername
+     * @param context
+     * @return
+     */
+    protected String getLDAPDN(String susername, XWikiContext context)
+    {
+        String dn = null;
+
+        if (context != null) {
+            // First we check in the local database
+            try {
+                String user = findUser(susername, context);
+                if (user != null && user.length() != 0) {
+                    dn = readLDAPDN(user, context);
+                }
+            } catch (Exception e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Faild finding LDAP DN stored in the user object.", e);
+                }
+                // ignore
+            }
+
+            if (context.isVirtual()) {
+                if (dn == null || dn.length() == 0) {
+                    // Then we check in the main database
+                    String db = context.getDatabase();
+                    try {
+                        context.setDatabase(context.getWiki().getDatabase());
+                        try {
+                            String user = findUser(susername, context);
+                            if (user != null && user.length() != 0) {
+                                dn = readLDAPDN(user, context);
+                            }
+                        } catch (Exception e) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug(
+                                    "Faild finding LDAP DN stored in the user object (virtual).",
+                                    e);
+                            }
+                            // ignore
+                        }
+                    } finally {
+                        context.setDatabase(db);
+                    }
+                }
+            }
+        }
+        return dn;
+    }
+
+    protected String readLDAPDN(String userName, XWikiContext context)
+    {
+        String dn = null;
+
+        try {
+            XWikiDocument doc = context.getWiki().getDocument(userName, context);
+
+            BaseClass userClass = context.getWiki().getUserClass(context);
+
+            // We only allow empty password from users having a XWikiUsers object.
+            if (doc.getObject(userClass.getName()) != null) {
+                dn = doc.getStringValue(userClass.getName(), "ldap_dn");
+            }
+
+        } catch (Throwable e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieving the ldap_dn attribute from the XWikiUsers object failed.",
+                    e);
+            }
+        }
+
+        return dn;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java
___________________________________________________________________
Nom : svn:eol-style
   + native

