cancel
Showing results for 
Search instead for 
Did you mean: 

Alfresco ignores LDAP referrals

simon
Champ in-the-making
Champ in-the-making
Hi,

We use Alfresco Enterprise 1.2 and are still trying to fix the LDAP authentification.

We have internal and external users (employees and clients) that should access the Alfresco system. Both user groups are maintained in a different LDAP (Active Directory and OpenLDAP).

Alfresco only supports ONE LDAP at the moment so we tried to find a workaround for this problem. Best solution seems to use LDAP referrals.

Alfresco is configured to use host 1 (OpenLDAP in our case), host 1 has a referal to some OU in host 2 (our Active Directory):

[img]http://www.jnsa.org/mpki/ts/image_ref.png[/img]
Image found on jnsa.org

When we use Linux to authenticate cn=B1 against host 1, the request is redirected to the second host and resolved there. Alfresco doesn't seem to do this, it never forwards the request to host 2.

Could someone help me out here? Is this supported in Alfresco and if so, how should we configure it. If not… are there any plans in the near future?

PS: Java seems to support this: Referral.

Thanks!
11 REPLIES 11

andy
Champ on-the-rise
Champ on-the-rise
Hi Simon

Your approach should work, as far as I can tell….

See
http://java.sun.com/j2se/1.3/docs/guide/jndi/jndi-ldap-gl.html

You need an additional property on the LDAP connection
java.naming.referral  set to follow. I have not tried this. The default behaviour is "ignore".

BTW, the implementataion of authentication chaining went in the head build today.

Please let us know how you get on with this.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
Thanks Andy, your answer sounds better than I had expected. I'm not entirely sure how I should go on from here.

I suppose I'll need the context to start with, the InitialContext if I'm not mistaken. Is this the same context as the FacesContext?

I'll probably need something like this:

InitialContext initContext = new InitialContext();
initContext.addToEnvironment(Context.REFERRAL, "follow");

Secondly: where should I define this? Are there some examples of LDAP implementations (I suppose I won't find it in the source code)?

Lot's of questions but I hope you can put me on the right track…

andy
Champ on-the-rise
Champ on-the-rise
Hi Simon

Add this to the ldapInitialDirContextFactory bean in the
initialDirContextEnvironment property. The same place where you define the URL to your LDAP server. It can take any parameters you want to set for the LDAP context.

This context has nothing to do with the faces context.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
Andy,

I added the following parameter to the initialDirContextEnvironment property in the ldap-authentication-context.xml file as you proposed:

<entry key="java.naming.referral">
   <value>follow</value>
</entry>

I see no errors in the alfresco.log but it still doesn't work. We use a cn specified in host 1 and that still works but another cn in host 2 is not recognised. We don't see any requests from Alfresco to host 2 when we use tcpdump to trace the requests.

Alfresco talks to host 1, gets the referral URL back but doesn't seem to respond. Is the code for the java.naming.referral implemented in the Alfresco LDAP class? What else could we try?

Update: I don't see any feedback even when I make a typo, e.g. <entry key="java.naming.referralwrong"> and reboot the server.

Thanks again,
– Simon

andy
Champ on-the-rise
Champ on-the-rise
Hi Simon

The referral relies on the Sun implementation from com.sun.jndi.ldap.LdapCtxFactory. I understood it to be there from the docs.
There is one other setting that limits the depth of referrals
java.naming.ldap.referral.limit. Make sure this is set to 10 say.

Have you got the definition of your referral object? I will see if I can dig into this.

Can you try setting referral to throw? If may be that referral is used for queries and is not being used for bind/authentication in the Sun implementation.

It is possible that moving to digest-md5 authentication may solve the problem. The uid is used to trigger an ldap query in openldap to resolve to the user. This should follow referral. It may be that simple authentication can be redirected to an internal lookup in the same way, but that is a bit of a guess. I would have to see if I can get the form of the auth request.

e.g.



# SASL mappings for md5 digest authentication
# Extract the user id and use as the search key

authz-regexp
   uid=([^,]*),cn=digest-md5,cn=auth
   ldap:///dc=company,dc=com??one?(uid=$1)

authz-regexp
   uid=([^,]*),cn=company.com,cn=digest-md5,cn=auth
   ldap:///dc=company,dc=com??one?(uid=$1)


BTW, invalid environment variables will just be ignored.

Hope this helps

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
I added the java.naming.ldap.referral.limit property but I don't see how this could solve the problem. The default value of this property is 10 (so setting it to 10 shouldn't change it) and only have 2 referrals in our OpenLDAP to 2 different OU's in AD.

This is the definition of the referral object in our OpenLDAP:
dn: ou=Payroll,ou=User Accounts,dc=company,dc=be
objectClass: referral
objectClass: extensibleObject
ou: Payroll
ref: ldap://ldap.company.be/ou=Payroll,ou=User%20Accounts,dc=company,dc=be

We did the test with a ldapsearch command and get the referral to the AD. We get the full payroll list when the -C option (chase referrals) is specified. So it works on Linux, how could we fix this in Alfresco?
ldapsearch -x -b "ou=payroll,ou=user accounts,dc=company,dc=be"
# search result
search: 2
result: 10 Referral
matchedDN: ou=Payroll,ou=User Accounts,dc=company,dc=be
ref: ldap://ldap.company.be/ou=Payroll,ou=User%20Accounts,dc=company,dc=be

I did set the referral to throw but don't see any differences, where exactly should I see this? Should I enable another log4j item to show this?

I ran slapd (the OpenLDAP deamon) in debug mode and tried to login using my AD username and password:

ldap_pvt_gethostbyname_a: host=alfresco, r=0
connection_get(7): got connid=0
connection_read(7): checking for input on id=0
ber_get_next
ldap_read: want=1, got=1
  0000:  30                                                 0
ldap_read: want=1, got=1
  0000:  48                                                 H
ldap_read: want=72, got=72
  0000:  02 01 01 60 43 02 01 03  04 34 63 6e 3d 73 73 63   …`C….4cn=user
  0010:  68 6f 65 74 2c 6f 75 3d  70 61 79 72 6f 6c 6c 2c   account,ou=payroll,
  0020:  6f 75 3d 55 73 65 72 20  41 63 63 6f 75 6e 74 73   ou=User Accounts
  0030:  2c 64 63 3d 69 6d 65 63  2c 64 63 3d 62 65 80 08   ,dc=company,dc=be..
  0040:  xx xx xx xx xx xx xx xx                            passwsd
ber_get_next: tag 0x30 len 72 contents:
do_bind
ber_get_next
ldap_read: want=1 error=Resource temporarily unavailable
ber_get_next on fd 7 failed errno=11 (Resource temporarily unavailable)
ber_scanf fmt ({iat) ber:
ber_scanf fmt (o}) ber:
do_bind: version=3 dn="cn=useraccount,ou=payroll,ou=User Accounts,dc=company,dc=be" method=128
dn2entry_r: dn: "CN=USERACCOUNT,OU=PAYROLL,OU=USER ACCOUNTS,DC=COMPANY,DC=BE"
=> dn2id( "CN=USERACCOUNT,OU=PAYROLL,OU=USER ACCOUNTS,DC=COMPANY,DC=BE" )
=> ldbm_cache_open( "dn2id.dbb", 9, 600 )
<= ldbm_cache_open (opened 0)
<= dn2id NOID
dn2entry_r: dn: "OU=PAYROLL,OU=USER ACCOUNTS,DC=COMPANY,DC=BE"
=> dn2id( "OU=PAYROLL,OU=USER ACCOUNTS,DC=COMPANY,DC=BE" )
=> ldbm_cache_open( "dn2id.dbb", 9, 600 )
<= ldbm_cache_open (cache 0)
<= dn2id 13
=> id2entry_r( 13 )
=> ldbm_cache_open( "id2entry.dbb", 9, 600 )
<= ldbm_cache_open (opened 1)
=> str2entry
<= str2entry(ou=Payroll,ou=User Accounts,dc=company,dc=be) -> -1 (0x674750)
<= id2entry_r( 13 ) 0x674750 (disk)
====> cache_return_entry_r( 13 😞 created (0)
send_ldap_result: conn=0 op=0 p=3
send_ldap_response: msgid=1 tag=97 err=10
ber_flush: 82 bytes to sd 7
  0000:  30 50 02 01 01 61 4b 0a  01 0a 04 29 6f 75 3d 50   0P…aK….)ou=P
  0010:  61 79 72 6f 6c 6c 2c 6f  75 3d 55 73 65 72 20 41   ayroll,ou=User A
  0020:  63 63 6f 75 6e 74 73 2c  64 63 3d 69 6d 65 63 2c   ccounts,dc=company,
  0030:  64 63 3d 62 65 04 00 a3  19 04 17 6c 64 61 70 3a   dc=be……ldap:
  0040:  2f 2f 6c 64 61 70 73 65  72 76 2e 69 6d 65 63 2e   //ldap.company.
  0050:  62 65                                              be
ldap_write: want=82, written=82
  0000:  30 50 02 01 01 61 4b 0a  01 0a 04 29 6f 75 3d 50   0P…aK….)ou=P
  0010:  61 79 72 6f 6c 6c 2c 6f  75 3d 55 73 65 72 20 41   ayroll,ou=User A
  0020:  63 63 6f 75 6e 74 73 2c  64 63 3d 69 6d 65 63 2c   ccounts,dc=company,
  0030:  64 63 3d 62 65 04 00 a3  19 04 17 6c 64 61 70 3a   dc=be……ldap:
  0040:  2f 2f 6c 64 61 70 73 65  72 76 2e 69 6d 65 63 2e   //ldap.company.
  0050:  62 65                                              be
connection_get(7): got connid=0
connection_read(7): checking for input on id=0
ber_get_next
ldap_read: want=1, got=0

ber_get_next on fd 7 failed errno=0 (Success)
connection_read(7): input error=-2 id=0, closing.
connection_closing: readying conn=0 sd=7 for close
connection_close: conn=0 sd=7

The right referral is returned to Alfresco but there is no traffic afterwards. Not from Alfresco to the OpenLDAP server, not to the AD server (where the referral is pointing to). So Alfresco sends my username, OpenLDAP replies with a referral and all communication stops… The results are exactly the same when I set the referral parameter to "follow".

PS: How can we obtain the corrected source code so we can import empty groups? Do the nightly build versions contain the LDAP classes?

andy
Champ on-the-rise
Champ on-the-rise
Hi Simon

An easter Egg ??

I think the redirection for authentication is an issue with  com.sun.jndi.ldap.LdapCtxFactory. It is not alfresco that gets and should be following the referral. However, you could try putting both URLS in the ldap context for authentication. This should try both, in order, without resorting to referral.

This is covered in one of the tutorials that I have managed to track down.
See http://java.sun.com/products/jndi/tutorial/ldap/misc/url.html

Note that I have not tried this yet ….

The groups fix is in the 1.2.1 enterprise code, and so not in the nightly build.
See: http://forums.alfresco.com/viewtopic.php?t=1421

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
However, you could try putting both URLS in the LDAP context for authentication.

Nice, this seem to work. One little issue with DIGEST-MD5 and OpenLDAP but this has nothing to do with Alfresco so I won't bother you with that.

Alfresco supports multiple LDAPs! The referrals still don'twork but the multiple LDAP URL solves the problem. I may look into the referral issue later on, for now the problem is solved.

We need mixed groups (members from OpenLDAP and AD in one and the same group) so it's not all working yet but we are confident that we'll solve this last roadblock.

Where can I get the 1.2.1 Enterprise version? Should I send Alfresco an e-mail?

Manny thanks Andy!

andy
Champ on-the-rise
Champ on-the-rise
Hi Simon

That is good news.

I think that referral is going to work for queries but not for authentication.
I have seen examples for queries. I will put this on the list of things to check. The issue is likely to be having compatible models. It would be good to know how the groups and people objects match up across the two LDAP servers. I can see how we can make type-driven generic support for groups and people extraction but there is little point if you are going to have compatible models.

Any thoughts?

Regards

Andy