LDAP against AD working, now want to change JID="mail"

Hello All,

Big fan. First time post. I have a proof of concept running on our existing OpenFire server, which we have liked a lot for a lot of years, but I think we just outgrew it. I would now like to migrate our 30 users to ejabberd. I have this working with LDAP authentication against AD on Windows 2008. The layout is Windows 2008 AD, centOS 5.8 up to date with latest stable, ejabberd-2.1.8-2.el5 installed from RPM demo epel, erlang-R12B-5.10.el5 installed from epel, erlang-esasl-0.1-5.el5 installed from epel. If I base the authentication on "sAMAccountName" it works fine, but we use "mail" as our format of our JID's. Example person is Jim Smith and he would be jim@example.org not smith@example.org.

Our other five systems use LDAP against AD just fine using "username" as the login but not "firstname" as the login, as we expect that. But how to get it to use "firstname" as the login?, so we figured it out, we have OpenFire using "givenName" against LDAP & that works. Now to get that working with ejabberd. I have tried most all the LDAP kung fu I know & I am still not there. Most every version of my LDAP query returns 0 results. Has any one else got something similar to this working? Any one else have any advice on how to use either "givenName" or "mail" to match against AD?

One specific note about "mail", when Adium.app or Pidgin.exe or whatever app' we use goes to login, I can see in the verbose output from "tethereal" that it is attempting to login as "firstname" and not "first name@example.org", like I would expect it to. I'm not sure if this is closer to the main issue I am having or not. Someone who knows this quite well might consider that point if they believe that syntax is my issue.

As soon as I crack this riddle (and I know that I will) I'll pull the trigger and change the ejabberd ports back to the defaults, stop OpenFire, start ejabberd, and I'm done.

Thank you so much !

Anonymous
www.domain.com

Give the auth config that you

Give the auth config that you expect to work, and what errors it gives when a user tries to log in.
I'm sure you know what you are doing, and your HRM makes their best to hire only people having unique names across your organization... :) Or have I misunderstood your intentions? If so, please use less refined, and more strict, formal and unambiguous language.

Mike, Fantastic reply! I mean

Mike,

Fantastic reply! I mean that. Just what i had hope for & expected here. And I laughed too. You make some good points. I wish HRM would only uniquely named people, both firstname & surname, because, dang it, what happened when the second "smith" gets hired here? :)

{ldap_base, "OU=company name,dc=example,dc=com"}.
{ldap_uids, [{"givenName"}]}.
{ldap_filter, "(memberOf=Company Jabber Users)"}.

This ought to give a unique list of results about 30 entries. We expect results that look like this:
rob@example.com
bob@example.com
richard@example.com
richard.smith@example.com
sue@example.com
susan@example.com
suzanne@example.com
susie@example.com
und.so.weiter@example.com

Right now ejabberd seems to be passing its query to the AD server perfectly & getting a response but ..... it is not matching up on:

JID = richard@example.com
mail = richard@example.com

And when I say "mail", I am referring to the name of the LDAP field named "mail".

One clarification, in the above LDAP configuration example that I pasted in, I used "givenName", which is one of my many many many tests, but I (of course) have tried "mail". Neither work. I will say that this same LDAP configuration over in OpenFire using "givenName" works like a charm. I expected same here but I know understand that there is some other logic or expectations inside of that system & this system that differ. I actually considering reading the source code for that one & this one to see if I could spot the different expectations but I failed at that. Alas, I throw myself on the mercy of this forum for assistance. Here is hoping.

Thanks again.

Anonymous

in ejabberd auth section, you

in ejabberd auth section, you can only define the user id part of JID (i.e., in "user_id@xmpp_domain", you only can define "user_id" part). The "xmpp_domain" part is authomatically added from the virtual host name configured in ejabberd. So, when you use "ldap_uids" parameter, you must make sure that it will return only user parts. That's why there is {ldap_uids, [{ldap_uidattr, ldap_uidattr_format}]} syntax (see LDAP authentication in the guide). The "givenName" attribute looks like fits perfectly to the simplier syntax, while "mail" will need to strip the "@example.com" out.

When a user tries to log in (and the server part of JID indicates that this server must process the authentication), the jid that is sent to server is split to get user part, and then the following happens: server performs a series of LDAP queries, one for each entry in "ldap_uids" list:

  • if this entry is simple {ldap_uidattr}, then this query is formed: "(&(<ldap_filter>)(<ldap_uidattr>=logging_on_user_part))".
  • otherwise, the query looks like "(&(<ldap_filter>)(<ldap_uidattr>=<ldap_uidattr_format with %u substituted with logging_on_user_part>))".

Each such query is performed using the credentials defined by "ldap_rootdn" and "ldap_password", under the "ldap_base". If a query returns a result, then ejabberd uses the returned distinguished name to try to bind to LDAP using the password that user has sent during logon. If this bind attempt succeeds, then logon is successful. If no binds were successful, then logon fails. (I omit some advanced options to keep things simple.)

Also, when the server needs the complete user list (such as when using webadmin), it makes queries like those above, but with "*" instead of "logging_on_user_part".

I don't know why your server fails using "givenName", but it may be traced by setting log level to 5 and running ejabberd in live mode. There you may see the XML exchange, as well as LDAP queries and results.

Thank you, Mike, appreciate

Thank you, Mike, appreciate it.

I am edging closer. Still not there though.

Here is a snippet from my configuration:
{auth_method, ldap}.
{ldap_servers, ["host.example.com"]}.
{ldap_encrypt, none}.
{ldap_port, 389}.
{ldap_rootdn, "ldap@example.com"}.
{ldap_password, "***************"}.
{ldap_base, "OU=company,dc=example,dc=com"}.
{ldap_uids, [{"givenName", "%u", "uid", "mail"}]}.
{ldap_filter, "(memberOf=Company Jabber Users)"}.

For comparison, this query works:

ldapsearch -h host.example.com -x -W -D "ldap@example.com" -v -b "ou=company,DC=domain,DC=com" "(&(mail=richard@example.com)(memberOf=*))" -vvvvv

I would like to get this to work next:

ldapsearch -h host.example.com -x -W -D "ldap@example.com" -v -b "ou=company,DC=domain,DC=com" "(&(mail=richard@example.com)(memberOf=company jabber users))" -vvvvv

Then, last, enter that configuration to ejabberd.cfg & ride in to the sunset, a cowboy, a hero.

Thank you again, Anonymous

{ldap_uids, [{"givenName",

{ldap_uids, [{"givenName", "%u", "uid", "mail"}]}.
is incorrect. You need to make it look something like
{ldap_uids, [{"givenName"}, {"mail", "%u@example.com"}]}.
Here, we tell ejabberd to try to match uid part of JID to the whole "givenName" attribute, or to the first part (up to and excluding "@") of "mail" attribute.
Though I don't understand what "uid" stands for in your example. If your LDAP users have "uid" attribute, that you want to use as yet another alternative, then you would need to add ', {"uid"}' before ']}' (without single quotes, of course).

Thanks so much, Mike, We are

Thanks so much, Mike,

We are super close. Thanks so much for getting us to the verge of it. I think we will get it. Please see two frames that I captured with "tethereal" just now using what I hope/think is your correct example from the last post. I can't spot the tiny nuance here, can you? It says in the bottom of the second frame 0 results, but I that is not so, but don't know why it is not finding that one result.

Thanks again. Anonymous

Frame 1 (250 bytes on wire, 250 bytes captured)
    Arrival Time: Apr 17, 2012 22:40:03.196905000
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 250 bytes
    Capture Length: 250 bytes
    [Frame is marked: False]
    [Protocols in frame: eth:ip:tcp:ldap]
Ethernet II, Src: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90), Dst: HewlettP_8d:c9:be (00:17:a4:8d:c9:be)
    Destination: HewlettP_8d:c9:be (00:17:a4:8d:c9:be)
        Address: HewlettP_8d:c9:be (00:17:a4:8d:c9:be)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Source: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90)
        Address: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
    Type: IP (0x0800)
Internet Protocol, Src: 10.10.10.148 (10.10.10.148), Dst: 10.10.10.244 (10.10.10.244)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 236
    Identification: 0x4413 (17427)
    Flags: 0x04 (Don't Fragment)
        0... = Reserved bit: Not set
        .1.. = Don't fragment: Set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 64
    Protocol: TCP (0x06)
    Header checksum: 0x2871 [correct]
        [Good: True]
        [Bad : False]
    Source: 10.10.10.148 (10.10.10.148)
    Destination: 10.10.10.244 (10.10.10.244)
Transmission Control Protocol, Src Port: 41696 (41696), Dst Port: ldap (389), Seq: 1, Ack: 1, Len: 184
    Source port: 41696 (41696)
    Destination port: ldap (389)
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 185    (relative sequence number)]
    Acknowledgement number: 1    (relative ack number)
    Header length: 32 bytes
    Flags: 0x18 (PSH, ACK)
        0... .... = Congestion Window Reduced (CWR): Not set
        .0.. .... = ECN-Echo: Not set
        ..0. .... = Urgent: Not set
        ...1 .... = Acknowledgment: Set
        .... 1... = Push: Set
        .... .0.. = Reset: Not set
        .... ..0. = Syn: Not set
        .... ...0 = Fin: Not set
    Window size: 46
    Checksum: 0xce66 [incorrect, should be 0xbc6b (maybe caused by "TCP checksum offload"?)]
        [Good Checksum: False]
        [Bad Checksum: True]
    Options: (12 bytes)
        NOP
        NOP
        Timestamps: TSval 351322431, TSecr 55890048
    [PDU Size: 184]
Lightweight-Directory-Access-Protocol
    LDAPMessage searchRequest(4) "OU=some company name,dc=example,dc=org" wholeSubtree
        messageID: 4
        protocolOp: searchRequest (3)
            searchRequest
                baseObject: OU=some company name,dc=example,dc=org
                scope: wholeSubtree (2)
                derefAliases: neverDerefAliases (0)
                sizeLimit: 0
                timeLimit: 0
                typesOnly: False
                Filter: (&(|(givenName=richard)(mail=richard@example.org))(memberOf=Company Jabber Users))
                    filter: and (0)
                        and: (&(|(givenName=richard)(mail=richard@example.org))(memberOf=Company Jabber Users))
                            and: 2 items
                                Filter: (|(givenName=richard)(mail=richard@example.org))
                                    and: or (1)
                                        or: (|(givenName=richard)(mail=richard@example.org))
                                            or: 2 items
                                                Filter: (givenName=richard)
                                                    or: equalityMatch (3)
                                                        equalityMatch
                                                            attributeDesc: givenName
                                                            assertionValue: richard
                                                Filter: (mail=richard@example.org)
                                                    or: equalityMatch (3)
                                                        equalityMatch
                                                            attributeDesc: mail
                                                            assertionValue: richard@example.org
                                Filter: (memberOf=Company Jabber Users)
                                    and: equalityMatch (3)
                                        equalityMatch
                                            attributeDesc: memberOf
                                            assertionValue: Company Jabber Users
                attributes: 2 items
                    AttributeDescriptionList: mail
                    AttributeDescriptionList: givenName

Frame 2 (88 bytes on wire, 88 bytes captured)
    Arrival Time: Apr 17, 2012 22:40:03.197064000
    [Time delta from previous captured frame: 0.000159000 seconds]
    [Time delta from previous displayed frame: 0.000159000 seconds]
    [Time since reference or first frame: 0.000159000 seconds]
    Frame Number: 2
    Frame Length: 88 bytes
    Capture Length: 88 bytes
    [Frame is marked: False]
    [Protocols in frame: eth:ip:tcp:ldap]
Ethernet II, Src: HewlettP_8d:c9:be (00:17:a4:8d:c9:be), Dst: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90)
    Destination: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90)
        Address: b6:d0:d8:4e:61:90 (b6:d0:d8:4e:61:90)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
    Source: HewlettP_8d:c9:be (00:17:a4:8d:c9:be)
        Address: HewlettP_8d:c9:be (00:17:a4:8d:c9:be)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Type: IP (0x0800)
Internet Protocol, Src: 10.10.10.244 (10.10.10.244), Dst: 10.10.10.148 (10.10.10.148)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 74
    Identification: 0x5afb (23291)
    Flags: 0x04 (Don't Fragment)
        0... = Reserved bit: Not set
        .1.. = Don't fragment: Set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 128
    Protocol: TCP (0x06)
    Header checksum: 0xd22a [correct]
        [Good: True]
        [Bad : False]
    Source: 10.10.10.244 (10.10.10.244)
    Destination: 10.10.10.148 (10.10.10.148)
Transmission Control Protocol, Src Port: ldap (389), Dst Port: 41696 (41696), Seq: 1, Ack: 185, Len: 22
    Source port: ldap (389)
    Destination port: 41696 (41696)
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 23    (relative sequence number)]
    Acknowledgement number: 185    (relative ack number)
    Header length: 32 bytes
    Flags: 0x18 (PSH, ACK)
        0... .... = Congestion Window Reduced (CWR): Not set
        .0.. .... = ECN-Echo: Not set
        ..0. .... = Urgent: Not set
        ...1 .... = Acknowledgment: Set
        .... 1... = Push: Set
        .... .0.. = Reset: Not set
        .... ..0. = Syn: Not set
        .... ...0 = Fin: Not set
    Window size: 258
    Checksum: 0xb0cf [correct]
        [Good Checksum: True]
        [Bad Checksum: False]
    Options: (12 bytes)
        NOP
        NOP
        Timestamps: TSval 55914679, TSecr 351322431
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 1]
        [The RTT to ACK the segment was: 0.000159000 seconds]
    [PDU Size: 22]
Lightweight-Directory-Access-Protocol
    LDAPMessage searchResDone(4) success [0 results]
        messageID: 4
        protocolOp: searchResDone (5)
            searchResDone
                resultCode: success (0)
                matchedDN:
                errorMessage:
        [Response To: 1]
        [Time: 0.000159000 seconds]

The problem is

The problem is here:
{ldap_filter, "(memberOf=Company Jabber Users)"}.
If you look into the real values of "memberOf" attribute in AD, you will see that they contain full distinguished names, like "CN=Company Jabber Users,OU=company name,dc=example,dc=com". Also note that LDAP doesn't allow using wildcards in DN attributes, so you must use the full DN in your filter, and not something like (memberOf=*Company Jabber Users*).

Mike, Huge! Just huge. Thank

Mike,

Huge!

Just huge.

Thank you so much, sir.

Anonymous

Hi Mike, We need favorable

Hi Mike,

We need favorable help from you..My Query is with AD authentication using mail attribute from Ejabberd.It works fine when i use SamAccountName as JID.But i can't login into web admin console when i use mail as JID.Here is my config

{auth_method, ldap}.
{ldap_servers, ["example.com"]}.
{ldap_port, 389}.
{ldap_rootdn, "CN=krishna,OU=Chennai_Users,DC=example,DC=com"}.
{ldap_password, "**************"}.
%%{ldap_uids, [{"sAMAccountName"}]}.
{ldap_uids, [{"mail", "%u@example.com"}]}.
{ldap_base, "dc=example,dc=com"}.
{ldap_filter, "(&(objectCategory=user)(!(objectCategory=computer)))"}.

In My AD mail attribute looks like below
mail = krishna.gopal@example.local

In ACL includes access to user
{acl, admin, {user, "krishna.gopal", "example.com"}}.

Kindly correct me if anything wrong with my configuration

Thanks

Krishna

Krishna_vernalis

Krishna_vernalis wrote:

{ldap_uids, [{"mail", "%u@example.com"}]}.
...
In My AD mail attribute looks like below
mail = krishna.gopal@example.local

Then
{ldap_uids, [{"mail", "%u@example.local"}]}.

Hi Mike, Thanks for your

Hi Mike,

Thanks for your time..your solution works for me.

Also i would like to know that is possible to query all rosters which is present in server from client tool and then add required rosters manually by end_user.

Thanks You again.

Regards
Krishna..

Hi Mike, Looking for your

Hi Mike,

Looking for your updates..

In Exodus we find Search Option.Using through can search rosters in server.But sometimes search doesn't work..

Please suggest if anything want to do in server side.

Thanks

Syndicate content