I used the JNDIRealm coming with the 4.1.7 beta version to authenticate against iPlanet LDAP server, and found that the JNDIRealm successfully authenticated a non-existing user. The following is the log output: ------------------- begin quoting logs ----------------------------------- 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: lookupUser(sfsdf) 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: dn=employeenumber=sfsdf, ou=people, dc=pb, dc=com 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: validating credentials by binding as the user 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: binding as employeenumber=sfsdf, ou=people, dc=pb, dc=com 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: Username sfsdf successfully authenticated 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: getRoles(employeenumber=sfsdf, ou=people, dc=pb, dc=com) 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: Searching role base 'ou=groups,dc=pb,dc=com' for attribute 'cn' 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: With filter expression '(uniquemember=employeenumber=sfsdf, ou=people, dc=pb, dc=com)' 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: Returning 0 roles 2002-07-25 12:12:15 JNDIRealm[/phonebook-app]: Username sfsdf does NOT have role Gateway Admin 2002-07-25 12:15:21 JNDIRealm[/phonebook-app]: Closing directory context --------------------- end of quoting log ------------------------------- Notice that the user doesn't exist in the directory at all, so it should fail at the binding step. Here is my config for the JNDIRealm in the server.xml: --------------- start quoting xml ------------------------------------- <Context path="/phonebook-app" docBase="phonebook-app" debug="99" reloadable="true"> <Logger className="org.apache.catalina.logger.FileLogger" prefix="jdgw_log." suffix=".txt" timestamp="true"/> <Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" connectionName="uid=admin,ou=administrators,ou=topologymanagement,o=nets caperoot" connectionPassword="iplanetsa" connectionURL="ldap://localhost:389" contextFactory="com.netscape.jndi.ldap.LdapContextFactory" roleBase="ou=groups,dc=pb,dc=com" roleName="cn" roleSearch="(uniquemember={0})" roleSubtree="false" userPattern="employeenumber={0}, ou=people, dc=pb, dc=com" /> </Context> -------------------------- end quoting xml -------------------------------- If you want to test again the iPlanet directory server, I think you can download a free one from their web site. Please let me know if this is not a bug. Thanks.
I suspect this is an issue with using the Netscape LDAP provider (com.netscape.jndi.ldap.LdapContextFactory) rather than with the type of directory server. Could you try again using the Sun provider? Also detailed logs from the iPlanet directory server for both providers would help. I'll try to get hold of the Netscape provider and see if I can replicate against OpenLDAP.
Created attachment 2506 [details] JNDIRealm patch to support iPlanet/Netscape LDAP provider
I downloaded the iPlanet/Netscape/Mozilla Directory SDK 4.1 from Sun and replicated the problem, which is due to a failure of this LDAP provider (com.netscape.jndi.ldap.LdapContextFactory) to conform to the JNDI specification. Section 6.6.2 of the JNDI 1.2 spec on the timeliness of modifications to the context environment says that changes to an environment property should be effective the next time an operation using that property is envoked. JNDIRealm relies on this to authenticate by binding as the user - it changes the principal and password properties and then carries out a search operation with the new environment. This all works as expected when using the default LDAP provider from Sun. The iPlanet implementation, on the other hand, seems to ignore any change to environment properties when the changed property pertains to the connection. (This discrepancy is hinted at in the section on JNDI Environmental Properties in the Netscape documentation). Thus it never even attempts to rebind as the user. This should really be fixed by whoever is now maintaining the Netscape provider, but I have a feeling that may not be trivial. So I've just attached a patch to JNDIRealm to work around the problem. This invokes reconnect() on the context to force an immediate rebind both when switching from administrator to user credentials for authentication and when switching from user to administrator credentials to search for user entries and role information. One, perhaps slight, downside is that the context must now be an LdapContext instead of the more generic DirectoryContext. On the other hand the realm is slightly more efficient than before when using the Sun LDAP provider. With the Netscape provider, it works correctly, but is rather inefficient since this provider closes the LDAP connection and creates a new one when reconnect() is invoked instead of keeping the same connection and rebinding with the new credentials.
Since this seems to be a bug with iPlanet - marking as WONTFIX. A javadoc comment will be been added to JNDIRealm to point to this bug as a warning for iPlanet users.