LDAP external auth

hello list!

I am attempting to use ExternalAuth to have RT authenticate against an LDAP database.

Our RT users have a sparate common name under our Group ou.

 cn=RTUsers,ou=Groups,dc=example,dc=com

I have devised an LDAP query that successfully retrieves information that could be used to log into RT.

ldapsearch -x -p 389 -h ldap01.example.com -b dc=example,dc=com -D “uid=dunphy,ou=People,dc=example,dc=com” -w ‘secret’ “(&(objectClass=top)(|(cn=RTUsers)))” “uniqueMember”

I am a little new at LDAP but from what I can see above I am performing a ‘simple’ bind with my ldap account and searching for the RTUsers group with a filter.

This is an example of what it finds:

extended LDIF

LDAPv3

base <dc=example,dc=com> with scope subtree

filter: (&(objectClass=top)(|(cn=RTUsers)))

requesting: uniqueMember

RTUsers, Groups, example.com

dn: cn=RTUsers,ou=Groups,dc=example,dc=com
uniqueMember: uid=user1,ou=People,dc=example,dc=com
uniqueMember: uid=user2,ou=People,dc=example,dc=com
uniqueMember: uid=user3,ou=People,dc=example,dc=com
uniqueMember: uid=user4t,ou=People,dc=example,dc=com

search result

search: 2
result: 0 Success

numResponses: 2

numEntries: 1

In the ldap server logs everything is looking good at this point:

[08/Nov/2011:18:30:54 -0500] conn=1735740 op=1 msgId=2 - SRCH base=“dc=example,dc=com” scope=2 filter=“(uid=jvazquez)” attrs=ALL
[08/Nov/2011:18:30:54 -0500] conn=1735740 op=1 msgId=2 - RESULT err=0 tag=101 nentries=1 etime=0
[08/Nov/2011:18:30:54 -0500] conn=1735740 op=2 msgId=3 - UNBIND

However, as you might have guessed I’m having a little difficulty translating this success on the command line into an RT config. :slight_smile:

This is what I have, currently, as my LDAP service:

                            # AN EXAMPLE LDAP SERVICE
                            'My_LDAP'       =>  {   ## GENERIC SECTION
                                                    # The type of service (db/ldap/cookie) 
                                                    'type'                      =>  'ldap',
                                                    # The server hosting the service
                                                    'server'                    =>  'ldap01.example.com',
                                                    ## SERVICE-SPECIFIC SECTION
                                                    # If you can bind to your LDAP server anonymously you should 
                                                    # remove the user and pass config lines, otherwise specify them here:
                                                    # The username RT should use to connect to the LDAP server 
                                                    'user'                      =>  'uid=myuser,ou=People,cn=example,cn=com',
                                                    # The password RT should use to connect to the LDAP server
                                                    'pass'                    =>  'secret',
                                                    # The LDAP search base
                                                    'base'                      =>  'ou=Groups,dc=example,dc=com',
                                                    # ALL FILTERS MUST BE VALID LDAP FILTERS ENCASED IN PARENTHESES!
                                                    # YOU **MUST** SPECIFY A filter AND A d_filter!!
                                                    # The filter to use to match RT-Users
                                                    'filter'                    =>  '"(&(objectClass=top)(|(cn=RTUsers))) uniqueMember"',
                                                    # A catch-all example filter: '(objectClass=*)'
                                                    # The filter that will only match disabled users
                                                    'd_filter'                  =>  '(objectClass=FooBarBaz)',
                                                    # A catch-none example d_filter: '(objectClass=FooBarBaz)'
                                                    # Should we try to use TLS to encrypt connections?
                                                    'tls'                       =>  0,
                                                    # SSL Version to provide to Net::SSLeay *if* using SSL
                                                    'ssl_version'               =>  3,
                                                    # What other args should I pass to Net::LDAP->new($host,@args)?
                                                    'net_ldap_args'             => [    version =>  3   ],
                                                    # Does authentication depend on group membership? What group name?
                                                    'group'                     =>  'RTUsers',
                                                    # What is the attribute for the group object that determines membership?
                                                    'group_attr'                =>  'cn',
                                                    ## RT ATTRIBUTE MATCHING SECTION
                                                    # The list of RT attributes that uniquely identify a user
						# This example shows what you *can* specify.. I recommend reducing this
                                                    # to just the Name and EmailAddress to save encountering problems later.
                                                    'attr_match_list'           => [    'Name',
                                                                                        'EmailAddress', 
                                                                                    ],
                                                    # The mapping of RT attributes on to LDAP attributes
                                                    'attr_map'                  =>  {   'Name' => 'uid',
                                                                                        'EmailAddress' => 'mail',
                                                                                    }
                                                },

But for some reason I am still trying to determine when I attempt to log in from the RT interface this is what results in the LDAP logs:

[08/Nov/2011:18:36:04 -0500] conn=1735759 op=0 msgId=1 - BIND dn=“uid=myuser,ou=People,cn=example,cn=com” method=128 version=3
[08/Nov/2011:18:36:04 -0500] conn=1735759 op=0 msgId=1 - RESULT err=32 tag=97 nentries=0 etime=0
[08/Nov/2011:18:36:04 -0500] conn=1735759 op=1 msgId=0 - RESULT err=80 tag=120 nentries=0 etime=0

Now error 32 is what constitutes a ‘no such object’ error. And error 80 indicates a password error. My theory is that because the object is not found password authentication is failing. I was hoping that someone with a knowledge of LDAP may be willing to assist.

Thank you and best regards,
tim

I have devised an LDAP query that successfully retrieves information
that could be used to log into RT.

ldapsearch -x -p 389 -h ldap01.example.com -b dc=example,dc=com -D
“uid=dunphy,ou=People,dc=example,dc=com” -w ‘secret’
“(&(objectClass=top)(|(cn=RTUsers)))” “uniqueMember”

This is an example of what it finds:

extended LDIF

LDAPv3

base <dc=example,dc=com> with scope subtree

filter: (&(objectClass=top)(|(cn=RTUsers)))

requesting: uniqueMember

RTUsers, Groups, example.com

dn: cn=RTUsers,ou=Groups,dc=example,dc=com
uniqueMember: uid=user1,ou=People,dc=example,dc=com
uniqueMember: uid=user2,ou=People,dc=example,dc=com
uniqueMember: uid=user3,ou=People,dc=example,dc=com
uniqueMember: uid=user4t,ou=People,dc=example,dc=com

search result

search: 2
result: 0 Success

numResponses: 2

numEntries: 1

So your query is returning a single object (numEntries: 1) that references
all the objects you want to use (you get a single group object).

With that in mind, you need to craft your query to return user objects.
You should look at the properties of
“uid=user1,ou=People,dc=example,dc=com” and use those to identify how to
filter your users. (I expect that there might be some entries in there to
reference the group the user is a member of, and you should build your
filter on that, and drop the “cn=RTUsers” in your filter, that is almost
certainly not what you want)

I hope this puts you in the right direction…
Jok

Thanks for the help Joachim… I look forward to having another go at this tomorrow.

best!
tim----- Original Message -----
From: “Joachim Thuau” Joachim.Thuau@spacex.com
To: “Tim Dunphy” bluethundr@jokefire.com, rt-users@lists.bestpractical.com
Sent: Tuesday, November 8, 2011 7:26:03 PM
Subject: Re: [rt-users] LDAP external auth

On 11/8/11 3:55 PM, “Tim Dunphy” bluethundr@jokefire.com wrote:

I have devised an LDAP query that successfully retrieves information
that could be used to log into RT.

ldapsearch -x -p 389 -h ldap01.example.com -b dc=example,dc=com -D
“uid=dunphy,ou=People,dc=example,dc=com” -w ‘secret’
“(&(objectClass=top)(|(cn=RTUsers)))” “uniqueMember”

This is an example of what it finds:

extended LDIF

LDAPv3

base <dc=example,dc=com> with scope subtree

filter: (&(objectClass=top)(|(cn=RTUsers)))

requesting: uniqueMember

RTUsers, Groups, example.com

dn: cn=RTUsers,ou=Groups,dc=example,dc=com
uniqueMember: uid=user1,ou=People,dc=example,dc=com
uniqueMember: uid=user2,ou=People,dc=example,dc=com
uniqueMember: uid=user3,ou=People,dc=example,dc=com
uniqueMember: uid=user4t,ou=People,dc=example,dc=com

search result

search: 2
result: 0 Success

numResponses: 2

numEntries: 1

So your query is returning a single object (numEntries: 1) that references
all the objects you want to use (you get a single group object).

With that in mind, you need to craft your query to return user objects.
You should look at the properties of
“uid=user1,ou=People,dc=example,dc=com” and use those to identify how to
filter your users. (I expect that there might be some entries in there to
reference the group the user is a member of, and you should build your
filter on that, and drop the “cn=RTUsers” in your filter, that is almost
certainly not what you want)

I hope this puts you in the right direction…
Jok

Hello Again Joachim (and anyone else on the list who may see this)!

I have an update on my RT::Authen::ExternalAuth situation. I have decided to abandon my idea of having an LDAP query which would search for the members of the RT group. Instead what I’ve decided to do is search for members of the ‘People’ ou individually. The distinguished name for which would be “uid=username,ou=People,cn=example,dc=com”. If the guys in the big chairs decide that I need to restrict the search to members of the RT group I will worry about that at another time. Right now my goal is to simply get RT to authenticate via LDAP.

So here is the ldap query that I am attempting to use in my RT config:

[ThatGuy@BAM-025715-TD:~] #ldapsearch -x -p 389 -h ldap01.example.com -D “uid=ThatGuy,ou=People,dc=example,dc=com” -w 'secret -b dc=example,dc=com “(&(uid=ThatGuy))” cn mail

extended LDIF

LDAPv3

base <dc=example,dc=com> with scope subtree

filter: (&(uid=ThatGuy))

requesting: cn mail

ThatGuy, People, example.com

dn: uid=ThatGuy,ou=People,dc=example,dc=com
cn: Tim ThatGuy
mail: tim.ThatGuy@example.com

search result

search: 2
result: 0 Success

numResponses: 2

numEntries: 1

That works well and this is what appears in the ldap logs:

[10/Nov/2011:10:33:33 -0500] conn=1738336 op=0 msgId=1 - BIND dn=“uid=ThatGuy,ou=People,dc=example,dc=com” method=128 version=3
[10/Nov/2011:10:33:33 -0500] conn=1738336 op=0 msgId=1 - RESULT err=0 tag=97 nentries=0 etime=0 dn=“uid=ThatGuy,ou=people,dc=example,dc=com”
[10/Nov/2011:10:33:33 -0500] conn=1738336 op=1 msgId=2 - SRCH base=“dc=example,dc=com” scope=2 filter=“(&(uid=ThatGuy))” attrs=“cn mail”
[10/Nov/2011:10:33:33 -0500] conn=1738336 op=1 msgId=2 - RESULT err=0 tag=101 nentries=1 etime=0
[10/Nov/2011:10:33:33 -0500] conn=1738336 op=2 msgId=3 - UNBIND

Here we see the bind, the result and the unbind and everything appears to go smoothly.

And this is how I’ve attempted to translate this into the config:

Set($ExternalSettings, {
# AN EXAMPLE LDAP SERVICE
‘My_LDAP’ => { ## GENERIC SECTION
# The type of service (db/ldap/cookie)
‘type’ => ‘ldap’,
# The server hosting the service
‘server’ => ‘ldap01.example.com’,
## SERVICE-SPECIFIC SECTION
# If you can bind to your LDAP server anonymously you should
# remove the user and pass config lines, otherwise specify them here:
# The username RT should use to connect to the LDAP server
‘user’ => ‘uid=ThatGuy,ou=People,cn=example,cn=com’,
# The password RT should use to connect to the LDAP server
‘pass’ => ‘secret’,
# The LDAP search base
‘base’ => ‘ou=People,dc=example,dc=com’,
# ALL FILTERS MUST BE VALID LDAP FILTERS ENCASED IN PARENTHESES!
# YOU MUST SPECIFY A filter AND A d_filter!!
# The filter to use to match RT-Users
‘filter’ => ‘(&(uid=)) cn mail’,
# A catch-all example filter: '(objectClass=
)’
# The filter that will only match disabled users
‘d_filter’ => ‘(objectClass=FooBarBaz)’,
# A catch-none example d_filter: ‘(objectClass=FooBarBaz)’
# Should we try to use TLS to encrypt connections?
‘tls’ => 0,
# SSL Version to provide to Net::SSLeay if using SSL
#‘ssl_version’ => 2,
# What other args should I pass to Net::LDAP->new($host,@args)?
‘net_ldap_args’ => [ version => 3 ],
# Does authentication depend on group membership? What group name?
#‘group’ => ‘RTUsers’,
# What is the attribute for the group object that determines membership?
#‘group_attr’ => ‘cn’,
## RT ATTRIBUTE MATCHING SECTION
# The list of RT attributes that uniquely identify a user
# This example shows what you can specify… I recommend reducing this
# to just the Name and EmailAddress to save encountering problems later.
‘attr_match_list’ => [ ‘Name’,
‘EmailAddress’,
],
# The mapping of RT attributes on to LDAP attributes
‘attr_map’ => { ‘Name’ => ‘uid’,
‘EmailAddress’ => ‘mail’,
}
},

And this is what you see in the logs:

[10/Nov/2011:11:09:17 -0500] conn=1738425 op=0 msgId=1 - BIND dn=“uid=ThatGuy,ou=People,cn=example,cn=com” method=128 version=3
[10/Nov/2011:11:09:17 -0500] conn=1738425 op=0 msgId=1 - RESULT err=32 tag=97 nentries=0 etime=0
[10/Nov/2011:11:09:17 -0500] conn=1738425 op=1 msgId=0 - RESULT err=80 tag=120 nentries=0 etime=0
[10/Nov/2011:11:09:17 -0500] conn=1738425 op=-1 msgId=-1 - closing from 10.40.27.251:39203 - A1 - Client aborted connection -
[10/Nov/2011:11:09:17 -0500] conn=1738425 op=-1 msgId=-1 - closed.

Apparently, I am able to perform an LDAP bind through the config, however, again what I am encountering is the ‘object could not be found’ error 32 and the resulting “invalid password” error 80. Also I notice the message closing from 10.40.27.251:39203 - A1 - Client aborted connection, and then there is no subsequent unbind.

I would really appreciate the input of anyone who might be able to help us get past this point.

Thank you and best regards,
TimFrom: “Tim Dunphy” bluethundr@jokefire.com
To: rt-users@lists.bestpractical.com
Sent: Tuesday, November 8, 2011 9:57:55 PM
Subject: Re: [rt-users] LDAP external auth

Thanks for the help Joachim… I look forward to having another go at this tomorrow.

best!
tim