From: Jim H. <ha...@us...> - 2001-12-11 17:59:04
|
2 things: I'm not sure if this works from your code my $struct = $result->as_struct; if( my $newbase = ( %$struct )[0] ) If it does, that's fine, but if( my $newbase = $result->dn ) is clearer. That said, the following is definitely an issue: my @bindparmz = ( base => $newbase, password => $password, ); $bindresult = $ldh2->bind( @bindparmz); you should replace 'base' with 'dn' --Jim Harle On Tue, 11 Dec 2001, Steven Lembark wrote: > > Trying to authenticate user/pass in mod_perl againsed an LDAP server. > Existing code uses one bind/search to look up the uid, gets back the > DN from the first query and attempts to perform a bind with domain > of the returned DN and password = $password. Problem at this point > is that the second bind always succeeds. > > Customer is running a Netscape LDAP server, don't know the version > (unless there is a simple way to ask). > > The code fragment below is supposed to work for them, but I don't > have access to Nescape's LDAP Developers' Toolkit in order to > compile perldap-1.4; would prefer to use Net::LDAP if it will work. > > Question: Is there any reasonable way to accomplish the steps > shown below using Net::LDAP rather than Mozilla::LDAP? Or am I > just screwing up the second bind? > > thanx. > sl > > ######################################################################## > # Mozilla::LDAP version > ######################################################################## > > # !/usr/bin/perl -w > > use Mozilla::LDAP::Conn; > use Mozilla::LDAP::Utils; > use Mozilla::LDAP::Entry; > > $user="$ARGV[0]"; > $password="$ARGV[1]"; > $GROUPDN = "ou=groups, o=FOO"; > $BASEDN = "ou=people, o=FOO"; > > $conn = new Mozilla::LDAP::Conn(white, 389); # Anonymous bind > > die "Could't connect to LDAP server $host" unless $conn; > > $entry = $conn->search("o=FOO", samelevel, "(uid=$user)", 0, (uid)); > > if (! $entry) > { > print "No such userid: $user\n"; > exit(1); > } > > $dn = $entry->getDN(); > > $search = "(&(cn=proxy)(uniquemember=$dn))"; > > $entry = $conn->search($GROUPDN, "samelevel", "$search"); > > if ($entry) > { > $ret = $conn->simpleAuth($dn, $password); > if ($ret) > { > { > #print "$user was accepted\n"; > $conn->close if $conn; > exit(0); > } > } > else > { > print "$user rejected for Invalid Password\n"; # Authentication Failed > $conn->close if $conn; > exit(1); > } > } > > ######################################################################## > # Net::LDAP version > ######################################################################## > > # !/usr/local/bin/perl -w > > ######################################################################## > # housekeeping > ######################################################################## > > use strict; > > $\ = "\n"; > $, = "\n"; > $| = 1; > > use Carp; > use Net::LDAP qw( :all ); > use Net::LDAP::LDIF; > > # use to pretty-print the results. > > use Data::Dumper; > local $Data::Dumper::Terse = 1; > local $Data::Dumper::Indent = 1; > local $Data::Dumper::Deepcopy = 1; > > ######################################################################## > # globals > ######################################################################## > > my $host = 'ldap.foo.com'; > my $port = getservbyname( 'ldap', 'tcp' ) || 389; > my $base = q{ou=people, o=FOO}; > > ######################################################################## > # real work begins here > ######################################################################## > > my $ldh = Net::LDAP->new( $host, port => $port ) > or croak "Failed LDAP->new"; > > print "LDH for anonymous bind: ", Dumper $ldh; > > my $bindresult = $ldh->bind; > > croak "Roadkill: bind: $bindresult->code()" > if $bindresult->code(); > > for my $username ( qw( jowbloe jondow ) ) > { > my @searchparmz = > ( > base => $base, > scope => 'one', > filter => qq{(uid=\L$username)}, > attrs => [ 'uid' ], > ); > > print "\nSearching on:", Dumper \@searchparmz; > > if( my $result = $ldh->search(@searchparmz) ) > { > croak "Roadkill: search: " . $result->code if $result->code; > > my $struct = $result->as_struct; > > print "\nYields:", Dumper $struct; > > # snag the DN out of the returned query, it'll be the only > # key for this query. > > if( my $newbase = ( %$struct )[0] ) > { > # might not need the second ldh, re-binding may > # work but also might not. need to test this > # after the rest of it works. > > if( my $ldh2 = Net::LDAP->new( $host, port => $port ) ) > { > print "LDH for password bind: ", Dumper $ldh2; > > # it is unlikely that anyone has picked either of > # these as a password. > # > # it should be impossible to return a successful > # bind with both. > > for my $password ( qw(foo bar) ) > { > # take the base returned from the first query, > # try to bind it with the supplied password. > # this should -- I think? -- only succeed if > # the password is valid. > > my @bindparmz = > ( > base => $newbase, > password => $password, > ); > > print "\nBinding with:", Dumper \@bindparmz; > > $bindresult = $ldh2->bind( @bindparmz ); > > croak "Roadkill: bind: " . $bindresult->code() > if $bindresult->code(); > > if( my $result = $ldh->search(@searchparmz) ) > { > print "Final result: ", Dumper $result->as_struct; > } > else > { > warn "Secondary query failed"; > } > } > } > else > { > warn "Failed to allocate second LDAP handle"; > } > } > else > { > warn "No employee number found"; > } > } > else > { > warn "No Search Result Returned"; > } > } > > # keep the shell happy > > 0 > > __END__ > > -- > Steven Lembark 2930 W. Palmer > Workhorse Computing Chicago, IL 60647 > +1 800 762 1582 > |