srinivas_rocks has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks,

I have been working with LDAP server configurations from some time and now I want to integrate the LDAP in my project.

I want to use LDAP to authenticate the users when they login to my portal.

I found Net::LDAP as a good perl module that can be used to serve my purpose.

I was successful in executing search statements and here is the code

#! /usr/bin/perl use Net::LDAP; $ldap = Net::LDAP->new ( "<ip address>" ) or die "Connection Failed $@ +"; $mesg = $ldap->bind ( "<user name>", password => "<password>", version => 3 ); $base = "dc=example,dc=com"; $mesg = $ldap->search ( # perform a search base => $base, filter => "(objectclass=*)" ); $mesg->code && die $mesg->error; foreach $entry ($mesg->all_entries) { $entry->dump; }
for the above code I got the following correct output:
--------------------------------------------------------------------- +--- dn:dc=example,dc=com dc: example description: Root LDAP entry for objectClass: dcObject organizationalUnit ou: rootobject ---------------------------------------------------------------------- +-- dn:ou=People,dc=example,dc=com ou: People description: All people in organisation objectClass: organizationalUnit ---------------------------------------------------------------------- +-- dn:uid=srinivas,ou=People,dc=example,dc=com uid: srinivas cn: srinivas objectClass: account posixAccount top shadowAccount userPassword: {crypt}$1$zYwJ/asE$DsYRb6CXjzJihNyTV2lC9. shadowLastChange: 13986 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 503 gidNumber: 100 homeDirectory: /home/srinivas
now when I am trying to execute compare function whose code is
$mesg = $ldap->compare( $base, attr => "uid", value => "srinivas" ); $mesg->code && die $mesg->error; foreach $entry ($mesg->all_entries) { $entry->dump; }
I am getting following error when I execute the above script
No such attribute at line 34, <DATA> line 259.
Can any one suggest whether there are any additional attributed that are to be added or any other why that I can compare my username and password for authentication. Any suggestion will be helpful.

Thanks in Advance.


Replies are listed 'Best First'.
Re: Need help on Net::LDAP
by mr_mischief (Monsignor) on Apr 30, 2008 at 15:39 UTC
    This is really more LDAP-specific than Perl-specific, but it's a bit of both as it has to do with how you're attempting to use the API provided by the module.

    The compare method of Net::LDAP requires the distinguished name of the entry you're trying to compare against. You're comparing against your $base (is it still "dc=example,dc=com" (your LDAP base) at this point?) instead of the particular distinguished name you want "uid=srinivas,ou=People,dc=example,dc=com". There's no such attribute "uid" in entry "dc=example,dc=com", in case that's where you're looking.

    What you probably mean to do is to do a search of entries for "uid=srinivas,ou=People,dc=example,dc=com" and then compare your hashed password to the hashed password there (and possibly also check the uid attribute as a sanity check).

    BTW, you didn't just post an actual MD5 hashed Unix system account password to a public forum, did you? If so, you might want to change the password on that account and any others you have that use the same password. It takes some time to run a brute-force crack against MD5, but lots of people have nothing better to do than to put a cluster of four systems at work on it while they go about other things.

      No, s/he posted a base-64 encoded unix crypted (yeah, I know it is redundant, but that is the LDAP spec) password. So it would not take as much time.

      Update: I may be wrong on this - it appears the data I was using may not be entirely reliable. However, the encouragement below still stands.

      srinivas_rocks, I would also encourage you to change the password on the displayed account.


        What do you mean by redundant?

        Walking the road to enlightenment... I found a penguin and a camel on the way.....
        Fancy a Just ask!!!
Re: Need help on Net::LDAP
by jhourcle (Prior) on Apr 30, 2008 at 16:19 UTC

    The typical process for testing authentication in LDAP is:

    1. Bind as an application user account
    2. Search for the user's dn based on their uid (may have additional restrictions, eg, we had a 'hostname' multivalue attribute that listed which machines the user was allowed on, so I'd search for the equivalent of &(uid=username)(hostname=machine))
    3. Attempt to bind as the user w/ their password

    It seems like it's a lot of work -- eg, you could just form the DN from the uid and the base, but this prevents you from being able to handle hierarchies in your tree. (eg, you might have 2 groups of accounts under different OUs). You also can't read the userPassword attribute unless you're either bound as that user, or you give your application user extra access ... which is dangerous. You'd also have to parse the userPassword, which could be:

    • {hashtype}hashedpassword
    • plaintext

    As the password encryption is done when the password's written, it's entirely possible for there to be more than one type of encryption used in the LDAP server. (including plaintext passwords, which is all the more reason to not have application users able to read the attribute directly). Every time toy upgrade your LDAP server, you'd have the change of it using a new encryption, and your authentication checks suddenly failing if you're attempting to parse userPasssword.

Re: Need help on Net::LDAP
by ghenry (Vicar) on May 03, 2008 at 20:08 UTC

    The standard way is to test for a successful bind.

    Also, don't use crypt, as it's platform dependant. Use {SSHA}

    Walking the road to enlightenment... I found a penguin and a camel on the way.....
    Fancy a Just ask!!!
      Hi All,

      Thanks a lot for sharing your knowledge. I was looking out for authenticating users with LDAP server from my CGI page

      Here is a brief overview on the integration:

      1. Connect to ldap server.

      2. Bind to LDAP server as anonymous.

      3. Search in LDAP server with the username that is entered in CGI page.

      4. With the obtained results we can confirm 2 things. One whether the user is present or not and if present we can get the dn of that user.

      5. With the obtained dn repeat steps 1 and 2. While binding, use the password that is provided by user in CGI page

      6. If bind is successfully, then the authentication is successful.

      Hope the above information will be helpful for any one who is looking at same scenerio.

      Looking for same support from all you guys.