I've added some more debug code to the LDAP auth class.. Can you send me
a full log file to check it out..
If this does not give more info I suggest debugging..
Ludovic
Peter Murray wrote:
  -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 On 8/12/05 3:05 PM, Ludovic Dubost wrote:
  Right.. I had the feeling an email address would
not work.. The fact
 that there is no page yet in the wiki should not be a problem at this
 point..
      
 Okay -- we'll need to work around that at some point because most of my
 folks log in with an e-mail address (just a few of us have non-email
 UIDs in the LDAP directory).  First, though, I'd like to fix this
 challenge, then worry about that.
  I don't get why you get no message between
these two:
 DEBUG  LDAPAuthServiceImpl:Bind:451 - LDAP Bind successfull INFO
 MyFormAuthenticator:processLogin:142 - User peter login has failed
      
 'tis true, 'tis true.  For me it ranks right up there with trying to
 figure out how I got to line 142 of MyFormAuthenticator.
  There should be at least one.. when I look at the
code I put to give
  some debut messages
 What is your LDAP server by the way ?
      
 OpenLDAP (latest version -- just installed it).
 Peter
 - --
 Peter Murray                       
http://www.pandc.org/peter/work/
 Assistant Director, Multimedia Systems  tel:+1-614-728-3600;ext=338
 OhioLINK: the Ohio Library and Information Network   Columbus, Ohio
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.0 (Darwin)
 Comment: Using GnuPG with Thunderbird - 
http://enigmail.mozdev.org
 iD8DBQFC/i8r4+t4qSfPIHIRAlZ5AJ4jJUlPNWIiWrJWQhmdb20tlJ+zBwCgxJ13
 wp1UQgLQPAXQQkX0KTUVgz8=
 =02y/
 -----END PGP SIGNATURE----- 
 ------------------------------------------------------------------------
 --
 You receive this message as a subscriber of the xwiki-users(a)objectweb.org mailing list.
 To unsubscribe: mailto:xwiki-users-unsubscribe@objectweb.org
 For general help: mailto:sympa@objectweb.org?subject=help
 ObjectWeb mailing lists service home page: 
http://www.objectweb.org/wws
    
--
Ludovic Dubost
XPertNet: 
http://www.xpertnet.fr/
Blog: 
http://www.ludovic.org/blog/
XWiki: 
http://www.xwiki.com
Skype: ldubost AIM: nvludo Yahoo: ludovic
package com.xpn.xwiki.user.impl.LDAP;
import com.xpn.xwiki.user.impl.xwiki.*;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.doc.XWikiDocument;
import com.novell.ldap.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.lang.StringUtils;
import org.securityfilter.realm.SimplePrincipal;
import java.security.Principal;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.text.MessageFormat;
/**
 * Created by IntelliJ IDEA.
 * User: Alex
 * Date: 18 avr. 2005
 * Time: 16:18:50
 * To change this template use File | Settings | File Templates.
 */
public class LDAPAuthServiceImpl extends XWikiAuthServiceImpl {
    private static final Log log = LogFactory.getLog(LDAPAuthServiceImpl.class);
    public Principal authenticate(String username, String password, XWikiContext context)
throws XWikiException {
        Principal principal = null;
        if ((username==null)||(username.trim().equals("")))
            return null;
        if ((password==null)||(password.trim().equals("")))
            return 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;
            } else {
                return null;
            }
        }
        // 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
        if (context!=null) {
            String susername = username;
            int i = username.indexOf(".");
            if (i!=-1)
                susername = username.substring(i+1);
           String DN = getLDAP_DN(susername, context);
           if (DN != null && DN.length()!=0)
           {
               if (checkDNPassword(DN, susername, password, context))
               {
                   principal = GetUserPrincipal(susername, context);
               }
           }
           else
            {
               HashMap attributes = new HashMap();
               if (checkUserPassword(susername, password, attributes, context))
               {
                   principal = GetUserPrincipal(susername, context);
                   if (principal == null && attributes.size() > 0)
                   {
                       CreateUserFromLDAP(susername, attributes, context);
                       principal = GetUserPrincipal(susername, context);
                   }
               }
            }
        }
        return principal;
    }
    private void CreateUserFromLDAP(String susername, HashMap attributes, XWikiContext
context) throws XWikiException {
        String ldapFieldMapping = getParam("ldap_fields_mapping",context);
        if (ldapFieldMapping != null && ldapFieldMapping.length() > 0)
        {
            String[] fields = ldapFieldMapping.split(",");
            BaseClass bclass = context.getWiki().getUserClass(context);
            BaseObject bobj = new BaseObject();
            bobj.setClassName(bclass.getName());
            String name = null;
            String fullwikiname = null;
            for(int i = 0; i < fields.length; i++ )
            {
                String[] field = fields[i].split("=");
                if (2 == field.length)
                {
                   String fieldName = field[0];
                   if (attributes.containsKey(field[1]))
                   {
                       String fieldValue;
                       fieldValue = (String)attributes.get(field[1]);
                       if (fieldName.equals("name"))
                       {
                           name = fieldValue;
                           fullwikiname = "XWiki." + name;
                           bobj.setName(fullwikiname);
                       }
                       else
                       {
                           bobj.setStringValue(fieldName, fieldValue);
                       }
                   }
                }
            }
            if (name != null && name.length() > 0)
            {
                XWikiDocument doc = context.getWiki().getDocument(fullwikiname, context);
                doc.setParent("");
                doc.addObject(bclass.getName(), bobj);
doc.setContent("#includeForm(\"XWiki.XWikiUserTemplate\")");
                context.getWiki().ProtectUserPage(context, fullwikiname, "edit",
doc);
                context.getWiki().saveDocument(doc, null, context);
                context.getWiki().SetUserDefaultGroup(context, fullwikiname);
            }
        }
    }
    protected Principal GetUserPrincipal(String susername, XWikiContext context) {
        Principal principal = null;
        // First we check in the local database
        try {
            String user = findUser(susername, context);
            if (user!=null) {
                principal = new SimplePrincipal(user);
            }
        } catch (Exception e) {}
        if (context.isVirtual()) {
            if (principal==null) {
                // 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)
                            principal = new SimplePrincipal(context.getDatabase() +
":" + user);
                    } catch (Exception e) {}
                } finally {
                    context.setDatabase(db);
                }
            }
        }
        return principal;
    }
    public String getLDAP_DN(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 = readLDAP_DN(user, context);
                }
            } catch (Exception e) {}
            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 = readLDAP_DN(user, context);
                        } catch (Exception e) {}
                    } finally {
                        context.setDatabase(db);
                    }
                }
            }
        }
        return DN;
    }
    private String readLDAP_DN(String username, XWikiContext context) {
        String DN = null;
        try {
            XWikiDocument doc = context.getWiki().getDocument(username, context);
            // We only allow empty password from users having a XWikiUsers object.
            if (doc.getObject("XWiki.XWikiUsers")!=null) {
              DN = doc.getStringValue("XWiki.XWikiUsers", "ldap_dn");
            }
        } catch (Throwable e) {}
        return DN;
    }
    protected boolean checkUserPassword(String username, String password, HashMap
attributes, XWikiContext context) throws XWikiException {
        LDAPConnection lc = new LDAPConnection();
        boolean result = false;
        boolean notinLDAP = false;
        String foundDN = null;
        try {
            if (log.isDebugEnabled())
                 log.debug("LDAP Password check for user " + username);
            int ldapPort = getLDAPPort(context);
            int ldapVersion = LDAPConnection.LDAP_V3;
            String ldapHost = getParam("ldap_server", context);
            String bindDNFormat = getParam("ldap_bind_DN",context);
            String bindPasswordFormat = getParam("ldap_bind_pass",context);
            int checkLevel = GetCheckLevel(context);
            Object[] arguments = {
                username,
                password
             };
            String bindDN = MessageFormat.format(bindDNFormat, arguments);
            String bindPassword =  MessageFormat.format(bindPasswordFormat, arguments);
            String baseDN = getParam("ldap_base_DN",context);
            lc.connect( ldapHost, ldapPort );
            if (log.isDebugEnabled())
                 log.debug("LDAP Connect successfull to host " + ldapHost +
" and port " + ldapPort );
            // authenticate to the server
            result = Bind(bindDN, bindPassword, lc, ldapVersion);
            if (log.isDebugEnabled())
                 log.debug("LDAP Bind returned");
            if (result && checkLevel > 0)
            {
                if (log.isDebugEnabled())
                     log.debug("LDAP searching user");
                LDAPSearchResults searchResults =
                    lc.search(  baseDN,
                                LDAPConnection.SCOPE_SUB ,
                                "("+ getParam("ldap_UID_attr",context)
+
                                   "=" + username + ")",
                                null,          // return all attributes
                                false);        // return attrs and values
                if (searchResults.hasMore())
                {
                    if (log.isDebugEnabled())
                         log.debug("LDAP searching found user");
                    LDAPEntry nextEntry = searchResults.next();
                    foundDN = nextEntry.getDN();
                    if (log.isDebugEnabled())
                         log.debug("LDAP searching found DN: " + foundDN);
                    if (checkLevel > 1)
                    {
                        if (log.isDebugEnabled())
                             log.debug("LDAP comparing password");
                        LDAPAttribute attr = new LDAPAttribute(
                                                        "userPassword", password
);
                        result = lc.compare( foundDN, attr );
                    }
                    if (result)
                    {
                        if (log.isDebugEnabled())
                             log.debug("LDAP adding user attributes");
                        LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
                        Iterator allAttributes = attributeSet.iterator();
                        while(allAttributes.hasNext()) {
                            LDAPAttribute attribute =
                                        (LDAPAttribute)allAttributes.next();
                            String attributeName = attribute.getName();
                            Enumeration allValues = attribute.getStringValues();
                            if( allValues != null) {
                                while(allValues.hasMoreElements()) {
                                    if (log.isDebugEnabled())
                                         log.debug("LDAP adding user attribute "
+ attributeName);
                                    String Value = (String) allValues.nextElement();
                                    attributes.put(attributeName, Value);
                                }
                            }
                        }
                        attributes.put("dn", foundDN);
                    }
                }
                else {
                    if (log.isDebugEnabled())
                       log.debug("LDAP search user failed");
                    notinLDAP = true;
                }
                if (log.isInfoEnabled()) {
                    if (result)
                     log.info("LDAP Password check for user " + username +
" successfull");
                    else
                     log.info("LDAP Password check for user " + username +
" failed");
                }
            }
        }
        catch( LDAPException e ) {
            if (log.isInfoEnabled())
                log.info("LDAP Password check for user " + username + "
failed with exception " + e.getMessage());
            if ( e.getResultCode() == LDAPException.NO_SUCH_OBJECT ) {
                notinLDAP = true;
            } else if ( e.getResultCode() ==
                                        LDAPException.NO_SUCH_ATTRIBUTE ) {
                notinLDAP = true;
            }
        }
        catch (Throwable e) {
            notinLDAP = true;
            if (log.isErrorEnabled())
                 log.error("LDAP Password check for user " + username + "
failed with exception " + e.getMessage());
        }
        finally
        {
            if (log.isDebugEnabled())
                 log.debug("LDAP check in finally block");
            try {
                lc.disconnect();
            } catch (LDAPException e) {
                e.printStackTrace();
            }
        }
        if (notinLDAP)
        {
            if (log.isDebugEnabled())
                 log.debug("LDAP Password check reverting to XWiki");
            // Use XWiki password if user not in LDAP
            result = checkPassword(username, password, context);
            foundDN = null;
        }
        return result;
    }
    private String getParam(String name, XWikiContext context) {
        String param = "";
        try {
         param = context.getWiki().getXWikiPreference(name,context);
        } catch (Exception e) {}
        if (param == null || "".equals(param))
        {
            try{
             param = context.getWiki().Param("xwiki.authentication." +
StringUtils.replace(name, "ldap_","ldap."));
            } catch (Exception e) {}
        }
        if (param == null)
            param = "";
        return param;
    }
    protected int GetCheckLevel(XWikiContext context)
    {
        String checkLevel = getParam("ldap_check_level",  context);
        int val = 2;
        if ("1".equals(checkLevel))
            val = 1;
        else if ("0".equals(checkLevel))
            val = 0;
        return val;
    }
    private int getLDAPPort(XWikiContext context) {
        try {
         return context.getWiki().getXWikiPreferenceAsInt("ldap_port", context);
        } catch (Exception e) {
         return
(int)context.getWiki().ParamAsLong("xwiki.authentication.ldap.port",
LDAPConnection.DEFAULT_PORT);
        }
    }
    protected boolean checkDNPassword(String DN, String username, String password,
XWikiContext context) throws XWikiException {
        LDAPConnection lc = new LDAPConnection();
        boolean result = false;
        boolean notinLDAP = false;
        try {
            int ldapPort = getLDAPPort(context);
            int ldapVersion = LDAPConnection.LDAP_V3;
            String ldapHost = getParam("ldap_server", context);
            String bindDN = getParam("ldap_bind_DN",context);
            String bindPassword = getParam("ldap_bind_pass",context);
            String baseDN = getParam("ldap_base_DN",context);
            lc.connect( ldapHost, ldapPort );
            // authenticate to the server
            result = Bind(DN, password, lc, ldapVersion);
            if (log.isDebugEnabled()) {
                if (result)
                 log.debug("(debug) Password check for user " + DN + "
successfull");
                else
                 log.debug("(debug) Password check for user " + DN + "
failed");
            }
        }
        catch( LDAPException e ) {
            if ( e.getResultCode() == LDAPException.NO_SUCH_OBJECT ) {
                notinLDAP = true;
            } else if ( e.getResultCode() ==
                                        LDAPException.NO_SUCH_ATTRIBUTE ) {
                notinLDAP = true;
            }
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
        finally
        {
            try {
                lc.disconnect();
            } catch (LDAPException e) {
                e.printStackTrace();
            }
        }
        if (notinLDAP)
        {
            // Use XWiki password if user not in LDAP
            result = checkPassword(username, password, context);
        }
        return result;
    }
    private boolean Bind(String bindDN, String bindPassword, LDAPConnection lc, int
ldapVersion) throws UnsupportedEncodingException {
        boolean bound = false;
        if (log.isDebugEnabled())
             log.debug("LDAP Bind starting");
        if (bindDN != null && bindDN.length() > 0 && bindPassword !=
null)
        {
            try
            {
                lc.bind( ldapVersion, bindDN, bindPassword.getBytes("UTF8") );
                bound = true;
                if (log.isDebugEnabled())
                     log.debug("LDAP Bind successfull");
            }
            catch(LDAPException e) {
                if (log.isErrorEnabled())
                     log.error("LDAP Bind failed with Exception " +
e.getMessage());
            };
        } else {
            if (log.isDebugEnabled())
                 log.debug("LDAP Bind does not have binding info");
        }
        return bound;
    }
}