Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

basic question about binding without knowing the DN

23 views
Skip to first unread message

Mark Inaba

unread,
Apr 14, 2011, 1:22:32 PM4/14/11
to perl...@perl.org
hello perl-ldap mailing list,

i'm wondering if i'm trying to do the impossible, even though it seems like this might be a common situation.
i'm trying to verify a user/password by having the user bind to an ldap server. the problem is that just given a username, i can't guess the DN because the DN's components have values that could be many things:
example:
CN=mark,OU=paris,OU=short,...,DC=partA,DC=foo,DC=com
CN=mike,OU=new york,OU=tall,...,DC=partB,DC=foo,DC=com

it seems that all of this is necessary for me to bind (i can't just use CN=mark,DC=foo,DC=com and try a password against all matches sigh)
so if i get another user, i don't know what sort of OU values his/her DN will have. also, the DC's might be different too.

here's the wrinkles that make it harder:
1) anon bind is turned off, so i can't search around for promising matches and use their DN
2) they don't want a generic 'read' account to log in because they don't want the password in a file.
but i might be ok if:
a) though if script is not called by user i might be able to convince them to use o-r.
b) if the final server is sasl aware, i might be able to use an encrypted string in the script

but here's why i think it MIGHT be possible... using the windows program: ldap.exe
i noticed that i'm able to bind filling in only the fields:
USER: mark
PASSWORD: mypassword
DOMAIN: parta.foo.com

so unless the application knows some secret settings...how does it authenticate me without my telling it my full DN?
if i new that i think i could write my perl script that checks every user against
DOMAIN: parta.foo.com and partb.foo.com

thanks for any help :)
-mark (not in paris...alas..)
Please consider the environment before printing this email.

Visit our website at http://www.nyse.com

****************************************************

Note: The information contained in this message and any attachment to it is privileged, confidential and protected from disclosure. If the reader of this message is not the intended recipient, or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by replying to the message, and please delete it from your system. Thank you. NYSE Euronext.

Miller, Don C.

unread,
Apr 14, 2011, 2:38:18 PM4/14/11
to Mark Inaba, perl...@perl.org
Mark, Active Directory allows authentication via DN,
DOMAIN\sAMAccountName or userPrincipalName. We use DOMAIN\sAMAccountName
(ex parta\mark) for a few of our apps so we don't have to look for the
user's DN with a functional account.

Don

Chris Ridd

unread,
Apr 14, 2011, 2:39:04 PM4/14/11
to Mark Inaba, perl...@perl.org

On 14 Apr 2011, at 18:22, Mark Inaba wrote:

> hello perl-ldap mailing list,
>
> i'm wondering if i'm trying to do the impossible, even though it seems like this might be a common situation.
> i'm trying to verify a user/password by having the user bind to an ldap server. the problem is that just given a username, i can't guess the DN because the DN's components have values that could be many things:
> example:
> CN=mark,OU=paris,OU=short,...,DC=partA,DC=foo,DC=com
> CN=mike,OU=new york,OU=tall,...,DC=partB,DC=foo,DC=com
>
> it seems that all of this is necessary for me to bind (i can't just use CN=mark,DC=foo,DC=com and try a password against all matches sigh)
> so if i get another user, i don't know what sort of OU values his/her DN will have. also, the DC's might be different too.
>
> here's the wrinkles that make it harder:
> 1) anon bind is turned off, so i can't search around for promising matches and use their DN
> 2) they don't want a generic 'read' account to log in because they don't want the password in a file.
> but i might be ok if:
> a) though if script is not called by user i might be able to convince them to use o-r.
> b) if the final server is sasl aware, i might be able to use an encrypted string in the script
>
> but here's why i think it MIGHT be possible... using the windows program: ldap.exe
> i noticed that i'm able to bind filling in only the fields:
> USER: mark
> PASSWORD: mypassword
> DOMAIN: parta.foo.com
>
> so unless the application knows some secret settings...how does it authenticate me without my telling it my full DN?

There's another way to bind in LDAP, using something called SASL. One SASL mechanism uses Kerberos, and on Windows this can take advantage of the ticket you get from your Windows AD when you log in to your machine.

You could also use other SASL mechanisms - things like "CRAM-MD5", "DIGEST-MD5", or "SCRAM-SHA-1". These take a SASL ID instead of a DN, which look something like "us...@domain.com", and if you omit the "@domain.com" part the LDAP server will often default something.

If you look at your server's logs you might now be able to work out how your client is binding.

Chris

Dan Cutler

unread,
Apr 14, 2011, 2:55:12 PM4/14/11
to Mark Inaba, perl...@perl.org
Mark,

Wow. I remember having the EXACT same thoughts some years ago.

As it turns out, the process that happens when a user logs in is somewhat "shielded" from the average user. Once you find out what is really happening, you'll gain some great insights into LDAP processes.

It is quite typical to not allow anonymous searches. This usually a good idea.

Behind the scenes, "authenticating" requires three things:

An LDAP server that houses you "account"
An identifier called a "DN" (aka Distinguished Name) that represents the unique identifier of your account
A valid password.

What can be quite puzzling is the DN.

Nearly every LDAP authentication script I write follows a process like this:

Collect the user's login name and passwd:
Bind to the directory using a known "system account" and "system" password.
Search the directory for this user (the login name is unique) and return its "DN".
If the DN is found, use it as a parameter and bind again as the actual user (you).

Does this help?

--Dan

-----Original Message-----
From: Mark Inaba [mailto:min...@nyx.com]
Sent: Thursday, April 14, 2011 1:23 PM
To: 'perl...@perl.org'
Subject: basic question about binding without knowing the DN

Dan Cutler

unread,
Apr 14, 2011, 4:54:49 PM4/14/11
to Mark Inaba, perl...@perl.org
Mark,

"AD" = Active Directory. This is Microsoft's version of an LDAP server.

I've literally been where you are; don't give up, rewards are great ;-)

The simple answer is unfortunately "not so simple".

From my perspective, the "owner" of the directory should give you a read-only system account so that you can determine the DN of users (ie do searches).

Since you need to provide a "base" to do a serach, you'll want to fetch the root_dse to get the naming contexts. This value will be the base DN to start your search from using the read only account.

ie:
use Net::LDAP;
use Net::LDAP::RootDSE;
use Data::Dumper;

my $user = "juser"; # a user's login
my $ldap = Net::LDAP->new(...)
my $mesg = $ldap->bind; #using your RO system account

my $dse = $ldap->root_dse(); # root dse is like "system settings"

# Try this
# perl Dumper $dse - to see all sorts of "settings".

#the get your base for searches...
my $base_to_start_all_searches = $dse->get_value('namingContexts');

# do you search :
# my $result = $ldap->search( base => $base_to_start_all_searches,
scope => 'sub',
filter => "(sAMAccountName=$user)");

# * "sAMAccountName" is a MS field, your actual field will vary depending on LDAP server...

foreach my $entr ($search->entries) {
my $user_dn = $entr->dn();
}

As for the whole SASL issue...

This is a little tricky.
Its difficult to set up (particularly if you are going from say Linux to Windoze).

I personally use LDAPS from Linux to AD (MS LDAP) to get to the good stuff (like being able to set initial passwords from a script running on Linux).

From a "security perspective", storing a login/pw is not the best solution however its also not a horribly bad one either. As long as the "system account" that you use to bind with can't do anything but bind and do searches, this is preferable to convincing the owner of the directory to open it for anonymous binds. So while not ideal, its better than other alternatives.

In either case, you should use LDAPS (ie wire encryption) so that eavesdroppers, will not see anything useful.

This is a whole other topic for another day...

-----Original Message-----
From: Mark Inaba [mailto:min...@nyx.com]

Sent: Thursday, April 14, 2011 3:27 PM
To: Dan Cutler
Subject: RE: basic question about binding without knowing the DN

hi dan,

so i was wondering if a user can bind with a subset of the DN...like foo.com. i'm wondering how in the world
ldap.exe does it. another poster mentioned something about AD, but i don't know how AD fits into LDAP (except that it's the middle two letters reversed..)

Mark Inaba

unread,
Apr 18, 2011, 5:15:20 PM4/18/11
to Dan Cutler, perl...@perl.org
hi,

great rewards if i persevere? this ldap is starting to sound like a religion :) well, at least there's no hazing involved.

oh you mention Data::Dumper, i spent some time last week trying to write a recursive reference displayer using 'ref' and threw it away when i discovered dumper. i'm sure it gave me some character somehow.

oh, AD *IS* the ldap server? ahh i was worried it was a third party talking to an ldap server with secret information built into it...apparantly the entire data is built into it. i'm not sure what the server is i'm talking to..it ping replies like a windows server (ttl 122) so that fits...

i currently have 3 accounts
1) a generic sounding account with a generic soundig password
2) a personal account in one branch of the ldap tree.
3) a slightly different account in another branch of the ldap tree

the trouble is when we use it on the production ldap server, the ldap guy doesn't want to have the user/pass in my script.
he thought it might be doable to have the users themselves authenticate themselves via my script by having my script try to 'bind' with their user/pass. the trouble is i've seen users with DN's all over the landscape.

is there no way to say my DN is 'cn=minaba,DC=foo,DC=com' in the bind request and have the ldap server itself know who i mean? what determines just how many X=y pairs are needed to make a bindable DN? is that configured by the administrator or is it every non-leaf/DC,CN,OU that i'm a part of? i'm still perplexed how ldap.exe can
magically bind me with only the following info neither of which is my DN:
user: minaba
pass: *******
domain: earth.foo.com

user: marsinaba
pass: *******
domain: mars.foo.com
(and they both work! how!? did he give me an app that already has the reader account in the settings? i looked but didn't see anything..but gui's...i never know if i've seen the entire confituration...grepping a .conf seems much easier :)

hmm LDAPS and SASL... i guess LDAPS would protect me from sniffers and SASL would protect me from vi'ers (assuming i have to keep the script world readable and i have to use a reader/test/bind account.) i hope i'll be able to use both, but the dev ldap doesn't have encrpytion so i'll have to wait till i can target our prod ldap server..wherever that is...

thanks much for your help! i guess if i can't find what makes the ldap.exe magical, i'll just sit on my current script version that uses a reader account and cross the bridges as they appear...

-mark

Duncan Brannen

unread,
Apr 19, 2011, 3:33:24 AM4/19/11
to Mark Inaba, perl...@perl.org

Hi Mark,

On 18/04/2011 22:15, Mark Inaba wrote:
>
> is there no way to say my DN is 'cn=minaba,DC=foo,DC=com' in the bind request and have the ldap server itself know who i mean? what determines just how many X=y pairs are needed to make a bindable DN? is that configured by the administrator or is it every non-leaf/DC,CN,OU that i'm a part of? i'm still perplexed how ldap.exe can
> magically bind me with only the following info neither of which is my DN:
> user: minaba
> pass: *******
> domain: earth.foo.com
>
> user: marsinaba
> pass: *******
> domain: mars.foo.com

You can do

$ad->bind( 'min...@earth.foo.com',password=>'MyPassword') or die "$@";

$ad->bind( 'mars...@mars.foo.com',password=>'HisPassword') or die "$@";

Which might help you.

Cheers,
Duncan

Mark Inaba

unread,
Apr 19, 2011, 9:05:10 AM4/19/11
to Duncan Brannen, perl...@perl.org
hi duncan,

it worked!
it seems a more elegant form than a seemingly arbitrary string of order sensitive descriptors (i guess it's just a path though).
after i clean up my script it'll look like i spent 30 minutes writing it :)
thanks so much.

(thanks to all who responded, it was comforting to know others had been puzzled by this before, though i guesss they had reader accounts to do the advance scouting for their binds)

-mark

0 new messages