Ldap – Active Directory: Thunderbird LDAP autocompletion not working with Kerberos auth

active-directorydomain-controllerkerberosldapthunderbird

The Problem:

I'm trying to configure an LDAP mail autocompletion – a built-in functionality of Mozilla Thunderbird 17.0.5 @ Windows 7 x64 in 2008R2 domain environment. The OS is a fresh, out-of-the-box install on VBox. It seems I cannot get it working with Kerberos authentication (native SSPI).

I've configured the LDAP parameters correctly – I've managed to verify that using "simple" authentication mode in Thunderbird (in which application asks user to manually enter domain credentials). In that mode TB autocompletion works.

Yet whenever I switch to Kerberos authentication, I get no autocompletion results. VBox shows some network activity after each letter I type in the address field, yet no result is returned.

This works the same on both the standard user accounts and the domain admin accounts.

The Question:

As far as I can see, it can be either some problem of Thunderbird or a domain/kerberos issue.

Basing on google results, this functionality of Thunderbird isn't really popular, yet most of what I've read seems to proove that this should work in any default-configured domain environment. Since the domain controllers were set up by former employee, It is possible that some feature of the domain was reconfigured or disabled. I've never touched the built-in Kerberos.

Can anyone advise me, what shall I look for?

The Debug:

I've attempted to debug the Thunderbird client and got a log that I'm posting at the bottom. The log shows no error, and though I know almost nothing about internal workings of Kerberos, as I understand, the client is attempting to authenticate (InitializeSecurityContext: succeeded) but never seems to recieve any answer. Yet TB returns no errors either.

Moreover, it seems that the log is pretty much the same regardless of whether I configure a correct Bind DN name (username@mydomain.com is the correct one) or some completely random letters.

If I launch Thunderbird after klist purge, it seems system properly gets the new tickets (krbtgt\domain.mydomain.com and LDAP\dc02.domain.mydomain.com).

Tunderbird Log:

0[e0f140]:   nsAuthSSPI::Init
0[e0f140]:   InitSSPI
0[e0f140]: Using SPN of [ldap/mydomain.com]
0[e0f140]: AcquireCredentialsHandle() succeeded.
0[e0f140]: entering nsAuthSSPI::GetNextToken()
0[e0f140]: InitializeSecurityContext: continue.
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed; total pending operations now = 0
1428[e13ac0]: entering nsAuthSSPI::GetNextToken()
1428[e13ac0]: InitializeSecurityContext: succeeded.
1428[e13ac0]: pending operation added; total pending operations now = 1
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed; total pending operations now = 0
1428[e13ac0]: pending operation added; total pending operations now = 1
0[e0f140]:   nsAuthSSPI::Init
0[e0f140]: Using SPN of [ldap/mydomain.com]
0[e0f140]: AcquireCredentialsHandle() succeeded.
0[e0f140]: entering nsAuthSSPI::GetNextToken()
0[e0f140]: InitializeSecurityContext: continue.
0[e0f140]: pending operation added; total pending operations now = 2
1428[e13ac0]: pending operation removed; total pending operations now = 1
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed; total pending operations now = 0
1428[e13ac0]: entering nsAuthSSPI::GetNextToken()
1428[e13ac0]: InitializeSecurityContext: succeeded.
1428[e13ac0]: pending operation added; total pending operations now = 1
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed
1428[e13ac0]: nsLDAPConnection::RemovePendingOperation(): operation removed; total pending operations now = 0
1428[e13ac0]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=balsams*)(userPrincipalName=balsams*)(sn=balsams*)(cn=balsams*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=balsam*)(userPrincipalName=balsam*)(sn=balsam*)(cn=balsam*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=balsa*)(userPrincipalName=balsa*)(sn=balsa*)(cn=balsa*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=bals*)(userPrincipalName=bals*)(sn=bals*)(cn=bals*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=bal*)(userPrincipalName=bal*)(sn=bal*)(cn=bal*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=bals*)(userPrincipalName=bals*)(sn=bals*)(cn=bals*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=balsa*)(userPrincipalName=balsa*)(sn=balsa*)(cn=balsa*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: nsLDAPOperation::SearchExt(): called with aBaseDn = 'OU=MyContainer,DC=mydomain,DC=com'; aFilter = '(&(objectClass=person)(|(mail=balsam*)(userPrincipalName=balsam*)(sn=balsam*)(cn=balsam*)))'; aAttributes = a,sn,mail; aSizeLimit = 100
0[e0f140]: pending operation added; total pending operations now = 1
1428[e13ac0]: pending operation removed; total pending operations now = 0
0[e0f140]: unbinding
0[e0f140]: unbound
0[e0f140]: unbinding
0[e0f140]: unbound

Best Answer

It works! The answer was pretty simple after all, though I found it by a blind shot:

The  Bind DN  field must be empty!

Once you set the Bind DN property to empty, it works!

Note there are still some additional obstacles:

  • Tou cannot use your domain name (eg. mydomain.com) as LDAP server address. You need to specifically use a single DC name (ie. dc03.mydomain.com). Since TB config file is a javscript code, I'll try to add several DC's to some array and randomise the ldap_2.servers.MyCompany.uri on each start.
  • The built-in LDAP queries for contacts matching are not best-suited for Active Directory. You may use following variables to customize filter strings:
    • ldap_2.servers.MyCompany.autoComplete.filterTemplate is an autocomplete match query, eg. (|(mail=%v*)(userPrincipalName=%v*)(sn=%v*)(cn=%v*)), the %v stands for all the letters you've already typed in the address box,
    • ldap_2.servers.MyCompany.autoComplete.nameFormat is a "nice name" for the email address (ie. name and surname), you have to provide LDAP field names in square brackets, ie.: [givenName] [sn]
    • ldap_2.servers.MyCompany.autoComplete.commentFormat is an additional column in the autocomplete dropdown list, may be used for some additional info like organisation unit - if you store it in your AD LDAP.