When connecting to AD in readOnly mode we need to use the configuration used for "External LDAP as the user store in READ ONLY mode", which is commented in usermgmt.xml by default.
We also need to set values for admin role to connect to Active Directory Server
<AdminRole>admin</AdminRole>
<AdminUser>
<UserName>support</UserName>
<Password>XXXXXX</Password>
</AdminUser>
In here we need to specify a user who exists in our active directory server. He need not be the administrator user of the AD server. This user will be the admin user of the carbon server. We need not to specify the password here. It can be left as 'XXXX'.
This admin user must be in the user search base ("UserSearchBase") that is configured in user store manager configuration.
In the UserStore configuration also we need to update the properties to match the connecting active directory server.
<UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager">
<Property name="ReadOnly">true</Property>
<Property name="MaxUserNameListLength">100</Property>
<Property name="ConnectionURL">ldap://10.100.3.131:389</Property>
<Property name="ConnectionName">CN=Administrator,CN=Users,DC=wso2,DC=test</Property>
<Property name="ConnectionPassword">pass#word1</Property>
<Property name="passwordHashMethod">PLAIN_TEXT</Property>
<Property name="UserSearchBase">CN=Users,DC=wso2,DC=test</Property>
<Property name="UserNameListFilter">(objectClass=person)</Property>
<Property name="UserNameAttribute">cn</Property>
<Property name="ReadLDAPGroups">true</Property>
<Property name="GroupSearchBase">CN=Users,DC=wso2,DC=test</Property>
<Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
<Property name="GroupNameAttribute">cn</Property>
<Property name="MembershipAttribute">member</Property>
<Property name="UserRolesCacheEnabled">true</Property>
<Property name="ReplaceEscapeCharactersAtUserLogin">true</Property>
<Property name="maxFailedLoginAttempt">0</Property>
<Property name="Referral">throw</Property>
<Property name="DomainName">wso2</Property>
</UserStoreManager>UserRolesCacheEnabled
i)
ConnectionURL
This should have the format of
ldap://<AD host-ip>:<AD_listen_port>
In failing to connect to AD server you might get this error [E1]
If you need to validate the listen port you can use portqry utility which is a command-line tool troubleshoot TCP/IP connectivity issues. Use following command to validate if the port is open and listening:
portqry -n <hostIP> -p udp -e 389
If it resolves the port to the LDAP service, it sends an unformatted user datagram to UDP port 389 on the target system. More Infor [1]
ii)
ConnectionName
This should specify an account that can browse and search your active directory user and group bases. Also this need to be given using relative distinguished names. For an example my ConnectionName is 'CN=Administrator,CN=Users,DC=wso2,DC=test'. How this was worked out is: DC is to demote DNS Name (prefixed as Domain Component). So my DNS name is wso2.test. This makes up
DC=wso2,DC=test.
Then in my domain Component, Users directory resides in the root and I have 'Administrator' user in there. So the user account and the folder highrachy to reach it can be made up as:
CN=Administrator,CN=Users
So this makes us:
ConnectionName=CN=Administrator,CN=Users,DC=wso2,DC=test
You are most likely to get this error [E2] when there is a misconfiguration in this.
iii)
ConnectionPassword
Is the password of above user (Administrator's password in my case)
iv)
UserSearchBase
This also should be specified using distinguished name. It should be the folder which should be searched for the users.
v)
UserNameAttribute
The attribute used to name users
vi)
GroupSearchBase
Distinguished name of the object that holds the groups. In my case it is 'Users'.
v) ReadLDAPGroups
- This property is related to <AdminRole> configurations.
1. If "ReadLDAPGroups" is set to true, This role can be a role from AD, If this role is in the group search based ("GroupSearchBase"). Then <AdminUser> must be assigned to this role from the AD level.
2. If "ReadLDAPGroups" is set to false. Then this role can be an internal role of Carbon.Then while starting server, role is created as internal role and assigned <AdminUser> to it. This mapping kept internally in the user mgt database
[1] -
http://support.microsoft.com/kb/816103
[E1] -
[2013-06-18 13:54:18,002] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} - Error obtaining connection for the second time10.100.3.131:10389
javax.naming.CommunicationException: 10.100.3.131:10389 [Root exception is java.net.ConnectException: Connection timed out]
at com.sun.jndi.ldap.Connection.<init>(Connection.java:223)
at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:136)
at com.sun.jndi.ldap.LdapClientFactory.createPooledConnection(LdapClientFactory.java:64)
.
.
.
.
.
Caused by: java.net.ConnectException: Connection timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at com.sun.jndi.ldap.Connection.createSocket(Connection.java:365)
at com.sun.jndi.ldap.Connection.<init>(Connection.java:200)
... 47 more
[2] -
2013-06-18 15:29:11,484] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} - Error obtaining connection. [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3087)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3033)
.
.