Bug 1066488 - management security realm: LDAP referrals not working
Summary: management security realm: LDAP referrals not working
Status: CLOSED CURRENTRELEASE
Alias: None
Product: JBoss Enterprise Application Platform 6
Classification: JBoss
Component: Security
Version: 6.2.1
Hardware: Unspecified
OS: Unspecified
urgent
urgent
Target Milestone: ER8
: EAP 6.3.0
Assignee: Darran Lofthouse
QA Contact: Josef Cacek
Nidhi
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2014-02-18 14:09 UTC by Tom Fonteyne
Modified: 2018-12-06 15:54 UTC (History)
10 users (show)

(edit)
Previous releases of JBoss EAP 6 carried a bug stating that all users and groups must be defined and searchable on the same LDAP server.

Any user or group entries that result in a referral will not be usable with JBoss EAP 6. 

This was because the LDAP searching within the security realms contained no logic for handling referrals if they were encountered while authenticating a user against LDAP or using LDAP to load their groups.

This issue has been corrected in this release and LDAP referrals work as expected.
Clone Of:
(edit)
Last Closed: 2014-06-28 15:27:59 UTC


Attachments (Terms of Use)
referral-ldifs (1.98 KB, application/x-zip)
2014-06-10 14:52 UTC, Tom Fonteyne
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
JBoss Issue Tracker WFLY-3072 Major Closed Support Referrals for security realms using LDAP for authentication or group loading. 2018-08-28 08:29 UTC
JBoss Issue Tracker WFLY-3477 Major Closed For LDAP referrals we also need the option to the use referral connection for the group search for group to principal 2018-08-28 08:29 UTC

Description Tom Fonteyne 2014-02-18 14:09:21 UTC
Description of problem:

LDAP referrals are not being followed for authentication

It is currently not possible to actually set
  java.naming.referral=follow

but all of the below was tested with a small modification of the code hardcoding the above setting


Version-Release number of selected component (if applicable):

6.2 CP01

How reproducible: always


Steps to Reproduce:
1. Setup two LDAP servers. I used 2x Sun DSEE 7
   Server 1:
     uid=tom,ou=people,dc=example,dc=com
     which is a member of the group:
     cn=JBossAdmin,ou=Groups,dc=example,dc=com

     A referral to the second LDAP server:
     version: 1
     dn: ou=RemoteLdap,dc=example,dc=com
     objectClass: organizationalUnit
     objectClass: referral
     objectClass: top
     ou: RemoteLdap
     ref: ldap://zen.usersys.redhat.com:391/dc=example,dc=com

   Server 2:
     uid=tomds3,ou=people,dc=example,dc=com
     which is a member of the group:
     cn=JBossAdmin,ou=Groups,dc=example,dc=com

2. configure the management section to use LDAP authentication

      <security-realm name="LdapsManagementRealm">
         <authentication>
            <ldap connection="ldapscon" base-dn="dc=example,dc=com" recursive="true">
               <username-filter attribute="uid"/>
            </ldap>
         </authentication>
      </security-realm>
....
      <outbound-connections>
            <ldap name="ldapscon" url="ldaps://zen.usersys.redhat.com:636/" search-dn="cn=Directory Manager" search-credential="12345678"/>
....
        <management-interfaces>
            <native-interface security-realm="LdapsManagementRealm">
                <socket interface="management" port="${jboss.management.native.port:9999}"/>
            </native-interface>
....

3. Use the CLI to login with
   tom/tom => works

4. tomds3/tomds3 => fails

Additional info:

Debugging showed it is fairly simple to see why this fails

org.jboss.as.domain.management.security.UserLdapCallbackHandler

215         if (distinguishedUserDN == null) {
216             if (result.isRelative() == true)
217                 distinguishedUserDN = result.getName() + ("".equals(baseDn) ? "" : "," + baseDn);
218             else
219                 throw MESSAGES.nameNotFound(result.getName());
220         }

During debug we see that at line 216 we had:

dn: was absolute: uid=tomds3, ou=People, dc=example,dc=com
name            : ldap://zen.usersys.redhat.com:391/uid=tomds3,%20ou=People,%20dc=example,dc=com
NameInNamespace : uid=tomds3, ou=People, dc=example,dc=com

and hence line 219 throw MESSAGES.nameNotFound(result.getName());

Test code was inserted similar to bz-1066470:

    private boolean authUser(SearchResult result) throws IOException, NamingException
    {
        LdapContext ctx;

        if (result.getName().startsWith("ldap"))
        {
            //TODO: the big question.... is this the right way of doing this ?
            String ref_url = result.getName().substring(0, result.getName().indexOf("/", 8));
            String ref_binddn = result.getNameInNamespace();

            System.out.println("Following referral to: " + ref_url);
            ctx = this.getLdapContext(ref_url, ref_binddn, userPassword);
        }
        else
        {
            ctx = this.getLdapContext(url, binddn, bindCredentials);
        }

        return (ctx != null);
    }

While this worked fine, it is not clear if this is the proper way of doing this.

Comment 1 JBoss JIRA Server 2014-04-02 17:09:07 UTC
Darran Lofthouse <darran.lofthouse@jboss.com> updated the status of jira WFLY-3072 to Coding In Progress

Comment 4 Nidhi 2014-05-14 02:59:23 UTC
Original note for use at 6.3.0 GA
---------------------------------

Cause: 

The LDAP searching within the security realms contains no logic for handling referrals if they are encountered when authenticating a user against LDAP or using LDAP to load their groups.

Consequence: 

All users and groups need to be defined and searchable on the same LDAP server, any user or group entries that result in a referral will not be usable with EAP 6.

Fix: 

Where the outbound LDAP connections are defined two new attributes have been added: -

 referrals (Default = IGNORE), this can also be set to FOLLOW or THROW.

If set to FOLLOW then if a referral is encountered during a search the DirContext we use will attempt to follow it automatically, this does assume that the same connection settings can be used to connect to the second server and that the name in the referral is actually reachable.

If set to THROW then the DirContext throws a LdapReferralException to indicate handling of a referral is required, the security realm handles this to identify an alternative connection to use for the referral.

 handles-referrals-for - This defines which referrals a connection can handle and is a space separated list if URIs.

This allows for a connection to be defined with a complete set of connection properties and specify a URI it can handle even if that URI address does not match the name it uses.  This could be used in situations where different credentials are needed to authenticate against the second server or for situations where the server returns a name in the referral that is not reachable from the EAP installation so an alternative address can be substituted.

Finally for principal to group style group loading a new attribute has been added called 'prefer-original-connection', each time a principal is loaded attributes are loaded from the groups that principal claims to be a member of, for each load we can either use the connection originally configured for the searching or the connection obtained due to the last referral, this attribute is used to control which one is preferred.

Result: 

LDAP referrals are now supported by the security realms and an EAP installation can now be configured to handle them.

Comment 5 Darran Lofthouse 2014-05-14 09:10:38 UTC
The fix for this is included in EAP 6.3

Comment 6 Ondrej Lukas 2014-05-29 10:50:14 UTC
LDAP Referrals for Security Realm can be accessed via new attributes mentioned in comment 4. Verified in EAP 6.3.0.ER5.

Comment 7 Tom Fonteyne 2014-06-10 12:58:46 UTC
the admin interface works for authentication.... and fails for group lookup.

The tests are 1:1 mappings I saw
e.g this scenario is not covered:

LDAP 1 on port 389:
- ou=RemoteLdap,dc=example,dc=com  being a referral to ldap://server:391/dc=example,dc=com

LDAP 2 on port 391:
- uid=tomds3,ou=users,dc=example,dc=com being a member of cn=JBossAdmin,ou=groups,dc=example,dc=com (group located on LDAP 2)

In the authorization step, the group search is done on LDAP-1 where "uid=tomds3,ou=users,dc=example,dc=com" would be a member => 0 found. 

hence re-opening

Comment 8 Darran Lofthouse 2014-06-10 14:12:21 UTC
I require full information in the scenario not working.

I will require the LDIFs for all entries concerned and the configuration being used for testing.

Comment 9 Tom Fonteyne 2014-06-10 14:22:11 UTC
copied from my original description but updated with RBAC and the new referral attribute:

server 1 is on 389, server 2 on 391

Steps to Reproduce:
1. Setup two LDAP servers. I used 2x Sun DSEE 7
   Server 1:
     uid=tom,ou=people,dc=example,dc=com
     which is a member of the group:
     cn=JBossAdmin,ou=Groups,dc=example,dc=com

     A referral to the second LDAP server:
     version: 1
     dn: ou=RemoteLdap,dc=example,dc=com
     objectClass: organizationalUnit
     objectClass: referral
     objectClass: top
     ou: RemoteLdap
     ref: ldap://zen.usersys.redhat.com:391/dc=example,dc=com

   Server 2:
     uid=tomds3,ou=people,dc=example,dc=com
     which is a member of the group:
     cn=JBossAdmin,ou=Groups,dc=example,dc=com

2. configure the management section to use LDAP authentication

            <security-realm name="LdapManagementRealm">
                <authentication>
                    <ldap connection="ldapcon" base-dn="dc=example,dc=com" recursive="true">
                        <username-filter attribute="uid"/>
                    </ldap>
                </authentication>
                <authorization>
                    <ldap connection="ldapcon">
                        <group-search group-name="SIMPLE" group-name-attribute="cn">
                            <group-to-principal search-by="DISTINGUISHED_NAME" base-dn="ou=Groups,dc=example,dc=com" recursive="true">
                                <membership-filter principal-attribute="uniqueMember"/>
                            </group-to-principal>
                        </group-search>
                    </ldap>
                </authorization>
            </security-realm>

....
      <ldap name="ldapcon" url="ldap://zen.usersys.redhat.com:389/" search-dn="cn=Directory Manager" search-credential="12345678" referrals="FOLLOW"/>

....
        <management-interfaces>
            <native-interface security-realm="LdapManagementRealm">
                <socket-binding native="management-native"/>
            </native-interface>

        <access-control provider="rbac">
            <role-mapping>
                <role name="SuperUser">
                    <include>
                        <group alias="JBossAdmin" name="JBossAdmin"/>
                    </include>
                </role>
            </role-mapping>
        </access-control>

Use the CLI:

login with "tom" user on ldap-1 and in JBossAdmin on ldap-1
=> all ok. Authenticated and received "superuser" rights

login with "tomds3" which exists on ldap-2 and in JBossAdmin on ldap-2
=> I get into the CLI, so authentication worked
=> I cannot do anything, e.g. type / and TAB, or : and TAB .. try a simple command => no rights.

Comment 10 Darran Lofthouse 2014-06-10 14:32:46 UTC
You most likely need to set referrals to THROW not FOLLOW, when set to FOLLOW it is not possible for us to detect the user queried has been referred to a different server so we have to start subsequent queries at the initial server, when set to THROW we actually cache where we were referred to allowing the group loading to continue from the server we were referred to.

Comment 11 Tom Fonteyne 2014-06-10 14:42:25 UTC
with THROW, on the cli:

Username: tomds3
Password: 
org.jboss.as.cli.CliInitializationException: Failed to connect to the controller
        at org.jboss.as.cli.impl.CliLauncher.initCommandContext(CliLauncher.java:284)
        at org.jboss.as.cli.impl.CliLauncher.main(CliLauncher.java:262)
        at org.jboss.as.cli.CommandLineMain.main(CommandLineMain.java:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.jboss.modules.Module.run(Module.java:312)
        at org.jboss.modules.Main.main(Main.java:460)
Caused by: org.jboss.as.cli.CommandLineException: Unable to authenticate against controller at orac.usersys.redhat.com:9999
        at org.jboss.as.cli.impl.CommandContextImpl.tryConnection(CommandContextImpl.java:989)
        at org.jboss.as.cli.impl.CommandContextImpl.connectController(CommandContextImpl.java:841)
        at org.jboss.as.cli.impl.CommandContextImpl.connectController(CommandContextImpl.java:817)
        at org.jboss.as.cli.impl.CliLauncher.initCommandContext(CliLauncher.java:282)
        ... 8 more
Caused by: javax.security.sasl.SaslException: Authentication failed: the server presented no authentication mechanisms
        at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:388)
        at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:242)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
        at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)
        at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
        at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)
        at org.xnio.ssl.JsseConnectedSslStreamChannel.handleReadable(JsseConnectedSslStreamChannel.java:180)
        at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
        at org.xnio.nio.NioHandle.run(NioHandle.java:90)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:198)
        at ...asynchronous invocation...(Unknown Source)
        at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:270)
        at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:251)
        at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:349)
        at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:337)
        at org.jboss.as.protocol.ProtocolConnectionUtils.connect(ProtocolConnectionUtils.java:80)
        at org.jboss.as.protocol.ProtocolConnectionUtils.connectSync(ProtocolConnectionUtils.java:99)
        at org.jboss.as.protocol.ProtocolConnectionManager$EstablishingConnection.connect(ProtocolConnectionManager.java:256)
        at org.jboss.as.protocol.ProtocolConnectionManager.connect(ProtocolConnectionManager.java:70)
        at org.jboss.as.protocol.mgmt.FutureManagementChannel$Establishing.getChannel(FutureManagementChannel.java:204)
        at org.jboss.as.cli.impl.CLIModelControllerClient.getOrCreateChannel(CLIModelControllerClient.java:160)
        at org.jboss.as.cli.impl.CLIModelControllerClient$2.getChannel(CLIModelControllerClient.java:120)
        at org.jboss.as.protocol.mgmt.ManagementChannelHandler.executeRequest(ManagementChannelHandler.java:123)
        at org.jboss.as.protocol.mgmt.ManagementChannelHandler.executeRequest(ManagementChannelHandler.java:98)
        at org.jboss.as.controller.client.impl.AbstractModelControllerClient.executeRequest(AbstractModelControllerClient.java:236)
        at org.jboss.as.controller.client.impl.AbstractModelControllerClient.execute(AbstractModelControllerClient.java:141)
        at org.jboss.as.controller.client.impl.AbstractModelControllerClient.executeForResult(AbstractModelControllerClient.java:127)
        at org.jboss.as.controller.client.impl.AbstractModelControllerClient.execute(AbstractModelControllerClient.java:71)
        at org.jboss.as.cli.impl.CommandContextImpl.tryConnection(CommandContextImpl.java:980)
        ... 11 more

and a fragment of the server log:

15:39:54,265 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-2) Assigning role 'SUPERUSER' for call with no assigned Subject (An IN-VM Call).
15:39:54,266 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-2) User 'null' Assigned Roles { 'SUPERUSER' }
15:39:54,268 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-3) Assigning role 'SUPERUSER' for call with no assigned Subject (An IN-VM Call).
15:39:54,269 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-3) User 'null' Assigned Roles { 'SUPERUSER' }
15:39:54,271 TRACE [org.jboss.as.server.moduleservice] (MSC service thread 1-13) serviceStopping: Controller for service jboss.module.spec.service."deployment.formlogin-LdapRealm.war".main@5a00255d
15:39:54,276 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-14) JBAS015877: Stopped deployment formlogin-LdapRealm.war (runtime-name: formlogin-LdapRealm.war) in 77ms
15:39:54,280 DEBUG [org.jboss.as.repository] (MSC service thread 1-8) ContentRepository stopped
15:39:54,281 DEBUG [org.jboss.as.server] (MSC service thread 1-10) DeploymentMountProvider stopped
15:39:54,283 INFO  [org.jboss.as] (MSC service thread 1-12) JBAS015950: JBoss EAP 6.3.0.Beta2 (AS 7.4.0.Final-redhat-SNAPSHOT) stopped in 55ms
15:39:54,288 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-9) Assigning role 'SUPERUSER' for call with no assigned Subject (An IN-VM Call).
15:39:54,288 TRACE [org.jboss.as.controller.access-control] (MSC service thread 1-9) User 'null' Assigned Roles { 'SUPERUSER' }

and the LDAP-2 server:

10/Jun/2014:15:39:51 +0100] conn=148 op=-1 msgId=-1 - fd=18 slot=18 LDAP connection from 10.33.1.90:50249 to 10.33.22.240
[10/Jun/2014:15:39:51 +0100] conn=148 op=0 msgId=1 - BIND dn="cn=Directory Manager" method=128 version=3
[10/Jun/2014:15:39:51 +0100] conn=148 op=0 msgId=1 - RESULT err=0 tag=97 nentries=0 etime=0 dn="cn=directory manager"
[10/Jun/2014:15:39:51 +0100] conn=148 op=1 msgId=2 - SRCH base="dc=example,dc=com" scope=0 filter="(objectClass=*)" attrs="dn"
[10/Jun/2014:15:39:51 +0100] conn=148 op=1 msgId=2 - RESULT err=0 tag=101 nentries=1 etime=0
[10/Jun/2014:15:39:51 +0100] conn=149 op=-1 msgId=-1 - fd=27 slot=27 LDAP connection from 10.33.1.90:50250 to 10.33.22.240
[10/Jun/2014:15:39:51 +0100] conn=149 op=0 msgId=1 - BIND dn="dc=example,dc=com" method=128 version=3
[10/Jun/2014:15:39:51 +0100] conn=149 op=0 msgId=1 - RESULT err=48 tag=97 nentries=0 etime=0
[10/Jun/2014:15:39:51 +0100] conn=149 op=1 msgId=0 - RESULT err=80 tag=120 nentries=0 etime=0

so it seems to try a BIND here with dn="dc=example,dc=com"

Comment 12 Darran Lofthouse 2014-06-10 14:45:48 UTC
Please attach the LDIFs for all entries involved from both servers, users and groups and I will review further.

Comment 13 Tom Fonteyne 2014-06-10 14:52:50 UTC
Created attachment 907299 [details]
referral-ldifs

ldifs attached:

tom.ldif + jbossadmin-389.ldif is for testing on the configured ldap server (e.g. no referral)

referral.ldif is an entry on the ldap-1 server (389)

tomds3.ldif + jbossadmin-391.ldif are for LDAP-2 server (391) so JBoss would have to handle the referral it got from LDAP-1

Comment 14 Darran Lofthouse 2014-06-10 19:01:45 UTC
Been debugging this one, looks like in this case FOLLOW is the better referral setting however there is a missing option for group to principal searching to use the referral connection - will add that and should have something available in the morning.

Comment 15 Darran Lofthouse 2014-06-13 14:33:48 UTC
One additional point, for an issue like this RBAC is not required to verify group loading, instead the command :whoami(verbose=true) will show the groups loaded just after authentication regardless of the access control settings.

Comment 16 Ondrej Lukas 2014-06-25 11:21:06 UTC
Verified in EAP 6.3.0.ER8. Group lookup is possible via setting prefer-original-connection attribute in principal-to-group/group-to-principal in ldap authorization of security realm. 

New attributes need to be documented. I will fill a new doc bz for adding information from comment 4 to the documentation.


Note You need to log in before you can comment on or make changes to this bug.