cancel
Showing results for 
Search instead for 
Did you mean: 

LDAP and people synchronisation not working

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

We are trying to enable people (and group) synchronisation with LDAP. It's not working as expected, but you have probably guessed that by now. First we woul like to enable people synchronisation, group support will follow later but lets keep it as simple as possible for now.

The configuration is based on the documentation we found in the WIKI.

1. The Alfresco system is not available when all the configuration references for group synchro are commented out. There are no errors in the log and the even the login page is not available. This problem is solved when I uncomment the group configuration parameters, strange…

2.  Changed the ldap-authentication-context.xml file (the other sections in this file are left alone) like this:

<bean id="ldapPeopleExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource">
        <property name="personQuery">
            <value>(objectclass=Person)</value>
        </property>
        <property name="searchBase">
            <value>dc=company,dc=be</value>
        </property>
        <property name="userIdAttributeName">
            <value>cn</value>
        </property>
         <property name="LDAPInitialDirContextFactory">
            <ref bean="ldapInitialDirContextFactory" />
        </property>
        <property name="personService">
            <ref bean="personService"></ref>
        </property>
        <property name="namespaceService">
            <ref bean="namespaceService" />
        </property>
        <property name="defaultHomeFolder">
            <value>/app:company_home</value>
        </property>
        <property name="attributeMapping">
            <map>
                <entry key="cm:userName">
                    <value>cn</value>
                </entry>
                <entry key="cm:firstName">
                    <value>givenName</value>
                </entry>
                <entry key="cm:lastName">
                    <value>sn</value>
                </entry>
                <entry key="cm:email">
                    <value>mail</value>
                </entry>
                <entry key="cm:organizationId">
                    <value>cn</value>
                </entry>
            </map>
        </property>
    </bean>

3. Uncommented the relevant part in the scheduled-jobs-context.xml. Remember the "leave the group support for now":

<ref bean="ldapPeopleTrigger" />

4. Reboot the server and wait (startDelay parameter does its job).

5. Job starts running and outputs the following error:

15:42:30,371 ERROR [org.quartz.core.JobRunShell] Job DEFAULT.ldapPeopleJobDetail threw an unhandled Exception:
org.alfresco.repo.importer.ExportSourceImporterException: Failed to import
        at org.alfresco.repo.importer.ExportSourceImporter.doImport(ExportSourceImporter.java:165)
        at org.alfresco.repo.importer.ImporterJob.execute(ImporterJob.java:36)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:191)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:516)
Caused by: java.lang.NullPointerException
        at org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource.generateExport(Unknown Source)
        at org.alfresco.repo.importer.ExportSourceImporter.doImport(ExportSourceImporter.java:149)
        … 3 more
15:42:30,371 ERROR [org.quartz.core.ErrorLogger] Job (DEFAULT.ldapPeopleJobDetail threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.alfresco.repo.importer.ExportSourceImporterException: Failed to import]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:516)
* Nested Exception (Underlying Cause) —————
org.alfresco.repo.importer.ExportSourceImporterException: Failed to import
        at org.alfresco.repo.importer.ExportSourceImporter.doImport(ExportSourceImporter.java:165)
        at org.alfresco.repo.importer.ImporterJob.execute(ImporterJob.java:36)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:191)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:516)
Caused by: java.lang.NullPointerException
        at org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource.generateExport(Unknown Source)
        at org.alfresco.repo.importer.ExportSourceImporter.doImport(ExportSourceImporter.java:149)
        … 3 more

We traced the connections between the Alfresco server and Active Directory with tcpdump and could see "some" activity so there is "a" connection. Don't know what's transfered and if this is relevant or not.

Could the NullPointerException have anything to do with these settings in the ldap-authentication-context.xml file?
<property name="storeRef">
<value>${alfresco_user_store.store}</value>
</property>
<property name="path">
<value>/${alfresco_user_store.system_container.childname}/${alfresco_user_store.authorities_container.childname}</value>
</property>

Anyone experienced the same problems? We use the Enterprise 1.2 version on Linux.

Thanks!
24 REPLIES 24

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

Can you turn on debug for org.alfresco.repo.security.authentication.ldap
This will dump out what is transferred as it goes. (Somewhere like jakarta-tomcat-5.5.9\webapps\alfresco\WEB-INF\classes\log4j.xml )

Was an xml fle created in the temp directory with the user info?

If you have Person objects without the attribute set as userIdAttributeName this could be the cause of your problems. This attribute has to exists and is used as the primary key. I will improve the error. The other attributes do not have to exist.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
Thanks Andy.

1. We are using Alfresco Enterprise 1.2 but I don't find a log4j.xml, the only file I could find is the log4j.properties file in the same directory you proposed. This file doesn't have any LDAP references so should I just add this line somewhere in the log4j.properties file (the properties file has a different layout, nothing like an XML file)?! Is this a JBoss only setting and if so how do I specify this for Tomcat? I tried both lines but don't see any extra output at startup time:

org.alfresco.repo.security.authentication.ldap=info
log4j.logger.org.alfresco.repo.security.authentication.ldap=info

2. Which temp directory do you mean? I could not find any XML files in the Linux /tmp directory. Are there any other (Alfresco specific) temp directories where I should look?

3. The userIdAttributeName is mapped to the cn value in the ldap-authentication-context.xml file like this:

<property name="userIdAttributeName">
   <value>cn</value>
</property>

The cn value exists in the LDAP (the userIdAttributeName value doesn't), would this be enough?

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

Sorry, my fault on the logging file name.
You need debug level. It is all or nothing.

It may not have got round to creating the temp file.
In tomcat these are somewhere like C:\jakarta-tomcat-5.5.9\temp\Alfresco

Do ALL Person objects have the cn attribute? If one does not, it will fail.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
Thanks, the debug level solved that part of the problem. I got some new feedback in the log file by adding this line to the log4j.properties (Tomcat) file:
og4j.logger.org.alfresco.repo.security.authentication.ldap=debug
We restricted the searchBase property one more level and it works! It's not exactly what we would like but hey, we got some results today.

[img]http://www.zwookedu.net/fr/documentation/installerunserveurldapdetest/introduction/image/ldap_struct...[/img]
Image found on zwookedu.net

The searchBase was set to eleves (see image), this didn't work. The import did work when we restricted the searchBase to the classe1 (an OU with no sub OU's): the XML file is build and imported, nice.

Problem: We have multiple OU's on the same level: classe1 till classe4. It's not possible to import the classe1 AND classe2 accounts (but not the classe3 or 4 ones), the searchBase is to restrictive now. Lets say that classe3 and 4 contain external users that are not needed in the system. How could we solve this?

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

Define two jobs to import people, one restricted to classe1 and another restricted to classe2. The others will then be excluded.  There can be as many people import jobs as you need.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
That's great news, almost there.

I defined a second job to import the other OU and it works perfect! People synchronization works like it should now. Thanks for the help Andy, we wouldn't have fixed this without your support.

Next in line: group synchronization… yes… I'm sorry.  :roll:

We have a working group synchronization with OpenLDAP but the Active Directory setup won't work. Still need to tweak the configuration settings, I suppose there is something wrong with the parameter mapping.

Anyway, I'll get back to you when I don't find a way out but that'll be something for tomorrow.

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

Is it possible to define a second ldapInitialDirContextFactory? This would allow us to connect to a different LDAP server (AD and OpenLDAP). Theoretically this shouldn't be so different from defining multiple jobs in the ldap-authentication-context.xml file like multiple ldapPeopleExport sources, should it?

This would solve our referral problem as well (see other post).

Or would this give some problems during authentication (which LDAP to use)?

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

You can define mutiple ldapInitialDirContextFactories. Just give them different bean IDs. When you wire them up to anything pick the bean name for the configuration you want.

At the moment you can only have one authentication service.
If you use the new chaining implementation then I would expect you to define two LDAP authentication services, each with its own initial context bean. This will solve your problem, but not now. Authentication is only  able to use one LDAP server at the moment( ==> one config). At some point we will have domains and redirection based authentication.

Regards

Andy

simon
Champ in-the-making
Champ in-the-making
Perfect, another roadblock taken. I can now synchronize people information from multiple OU's in multiple LDAP's with different attributes, quite impressive.

Back to group synchronization. We build a small test LDAP with a scheme close to the one from the WIKI documentation to see how we should do this. We can now import groups from this LDAP (it's an OpenLDAP) in Alfresco. Our AD however has a somewhat more complicated structure.

This is an example of a group definition in our AD:

# pmptech-list, Groups, User Accounts, company, be
dn: CN=pmptech-list,OU=Groups,OU=User Accounts,DC=company,DC=be
objectClass: top
objectClass: group
cn: pmptech-list
description: DL PMPtech account responsibles
member: CN=user1,OU=Payroll,OU=User Accounts,DC=company,DC=be
member: CN=user2,OU=Payroll,OU=User Accounts,DC=company,DC=be
member: CN=user3,OU=Payroll,OU=User Accounts,DC=company,DC=be
member: CN=user4,OU=Payroll,OU=User Accounts,DC=company,DC=be
member: CN=user5,OU=Payroll,OU=User Accounts,DC=company,DC=be
distinguishedName: CN=pmptech-list,OU=Groups,OU=User Accounts,DC=company,DC=be
instanceType: 4
whenCreated: 20011121122819.0Z
whenChanged: 20050916053345.0Z
displayName: pmptech-list
uSNCreated: 27504
uSNChanged: 12094550
reportToOriginator: TRUE
proxyAddresses: MRS:pmptech-list@MRS
proxyAddresses: X400:c=BE;a= ;p=COMPANY;o=COMPANYsite;s=pmptech-list;
proxyAddresses: SMTP:pmptech-list@company.be
altRecipientBL: CN=pmptech,OU=Non-Personal,OU=User Accounts,DC=company,DC=be
extensionAttribute10: distribution list
mailNickname: pmptech-list
name: pmptech-list
objectGUID:: dqnJ9Vl7pU6WfYbpcpvvtw==
objectSid:: AQUAAAAAAAUVAAAA8RNXAE5+mlJOWu0JPSIAAA==
sAMAccountName: pmptech-list
sAMAccountType: 268435457
showInAddressBook: CN=Default Global Address List,CN=All Global Address Lists,
CN=Address Lists Container,CN=COMPANY,CN=Microsoft Exchange,CN=Services,CN=Confi
guration,DC=company,DC=be
showInAddressBook: CN=All Groups,CN=All Address Lists,CN=Address Lists Contain
er,CN=COMPANY,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=company,DC=be
showInAddressBook: CN=All COMPANY email addresses,CN=All Address Lists,CN=Address
  Lists Container,CN=COMPANY,CN=Microsoft Exchange,CN=Services,CN=Configuration,D
C=company,DC=be
showInAddressBook: CN=COMPANY distribution lists,CN=All Address Lists,CN=Address
Lists Container,CN=COMPANY,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC
=company,DC=be
legacyExchangeDN: /O=COMPANY/OU=COMPANYsite/cn=Recipients/cn=pmptech-list
groupType: 2
objectCategory: CN=Group,CN=Schema,CN=Configuration,DC=company,DC=be
dSCorePropagationData: 20050218134851.0Z
dSCorePropagationData: 20050218134818.0Z
dSCorePropagationData: 16010101000417.0Z
textEncodedORAddress: c=BE;a= ;p=COMPANY;o=COMPANYsite;s=pmptech-list;
mail: pmptech-list@company.be
msExchALObjectVersion: 24
msExchPoliciesIncluded: {BE7E3E03-C4B9-4B33-9502-5271919F02B4},{26491CFC-9E50-
4857-861B-0CB8DF22B5D7}
msExchPoliciesIncluded: {BE7E3E03-C4B9-4B33-9502-5271919F02B4},{3B6813EC-CE89-
42BA-9442-D87D4AA30DBC}

This is the configuration of the group import in the ldap-authentication-context.xml:

    <bean id="ldapGroupExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPGroupExportSource">
        <property name="groupQuery">
            <value>(objectclass=group)</value>
        </property>
        <property name="searchBase">
            <value>ou=Groups,ou=User Accounts,dc=company,dc=be</value>
        </property>
        <property name="userIdAttributeName">
            <value>cn</value>
        </property>
        <property name="groupIdAttributeName">
            <value>cn</value>
        </property>
        <property name="groupType">
            <value>group</value>
        </property>
        <property name="personType">
            <value>person</value>
        </property>
        <property name="LDAPInitialDirContextFactory">
            <ref bean="ldapInitialDirContextFactory" />
        </property>
        <property name="namespaceService">
            <ref bean="namespaceService" />
        </property>
        <property name="memberAttribute">
            <value>member</value>
        </property>
    </bean>

I get the same NullPointerException as above so I suppose there is some parameter mapping that's wrong. Debugging mode is on and no groups are imported.

The userIdAttributeName and groupIdAttributeName have the same value (cn), this bothers me. The person and group entries both use the cn as their primary key but they are defined in another OU. The WIKI example uses uid and cn but in our case there is no uid (in AD).

Any ideas?