Huh?
I do Net::LDAP stuff against AD all the time using port 389. No special
encryption modules or anything. Heck, I even use Net::LDAP to create
users in AD!

A couple of notes on using Net::LDAP against AD:

1. AD DOES allow anonymous reads. It DOES NOT allow anonymous searches.
This behavior can be changed.

2. To change a password via any LDAP client, AD requires an encrypted
connection.

3. Port 389 connects you to the normal domain LDAP server. This gives
you read/write access to all objects IN THAT DOMAIN. Port 3268 connects
you to the "global catalog" (GC) LDAP server. This gives you READ/WRITE
access to objects IN THE DOMAIN, and READ-ONLY to objects in all other
domains in the forest. Also, objects accessed via a GC do not contain
all attributes, only a subset. Exactly which ones are, as they say in
the text books, an exercise left to the reader. 

-----Original Message-----
From: Tim Musson [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 28, 2003 7:20 AM
To: Graham Barr
Subject: Re: [Fwd: howto perl-ldap AD authentication with SASL/GSSAPI
mechanism?]


Hey Graham, or Ben :-)

My MUA believes you used Ximian Evolution 1.4.4 
to write the following on Wednesday, August 27, 2003 at 3:06:04 PM.

GB> I have spent a week trying to search Active Directory via Net::LDAP.

GB> I finally found the xray mailing list (geo crawler does not seem to 
GB> have information for this year?) via your CPAN information. I have 
GB> spent all day reading posts (many of them yours), which has led me 
GB> to believe that I need to use Simon' s module
GB> (perl-cyrus-sasl-0.02.tar.gz) to use GSSAPI to bind to AD. I am 
GB> going to start down this path, but I realize that many people are 
GB> trying to do this. Unfortunately, I have yet to find a decent howto 
GB> on it. Perhaps you can point me in the right direction?

GB> Also, I saw the post
GB> (http://www.xray.mpe.mpg.de/mailing-lists/perl-ldap/2003-01/msg00116
GB> .html)
GB> that suggested putting Active Directory info in your Net:LDAP book.
GB> I would buy it if it contained this information, especially the hard
GB> to track down authentication piece. Several people at my company
GB> have been trying to do this (AD via perl).

I also had to do this, and have written a script taking things from the
Net::LDAP::Examples link on http://perl-ldap.sourceforge.net/.

I broke most everything into subroutines because I needed to do 3
different queries to 3 different LDAP sources (syncing them...).

The one thing I had the hardest time with is you don't use port 389 for
LDAP access (I think AD does some very proprietary LDAP *type* things on
389). The MS web site has a document about it, and my AD admins followed
it and set up port 3268 for LDAP queries. Another thing about AD LDAP is
that by default there is no anonymous access at all. We decided it was
not needed, and set up an ID with rights...

The last odd AD/LDAP thing I can think of off the top of my head is they
use CN instead of UID...

,----- [ Here is my code (that works), I am *very* open to suggestions
:-) ] #!perl use strict; use warnings; use Net::LDAP; use
Net::LDAP::Util qw( ldap_error_name 
                        ldap_error_text ) ;     # use for Error handling

# Tim Musson, 2003/08
my $LogLevel=2;    # 0=no log
                   # 2=search parms & Returned: #
                   # 5=everything, even array-hash contents!
my $ldapDebug='0'; # set to 0 to disable debug output
                   # set to 12 to get debug output...
                   # set to 16 to just get aditional print output from
here # =====================================================
getAD(); # I have multiples of this, and type of sub call in my
script... # =====================================================
sub getAD {
    my ( @Attrs );
    @Attrs = ( 'cn', 'sAMAccountName', 'department', ); # request these
attrs
    # @Attrs = ('1.1'); # retrieve no attributes...
    # @Attrs = (); # request all available attributes to be returned.
    my %SearchParmsHash = (
      Server => "LDAPad.domain.tld",
        Port =>  3268,
      AuthDN => "CN=LDAP4L00kups,OU=ServiceAccounts,DC=domain,DC=tld",
          pw => "ldap-pw",
SearchString => "CN=Muss*",
       Attrs => [EMAIL PROTECTED],
        Base => "DC=domain,DC=tld",
    );
    PrintParms( \%SearchParmsHash ) if $LogLevel>=2;
    Search( \%SearchParmsHash );
}
# =====================================================
sub Search {
    my $parm = shift @_;
    my $ldap = Net::LDAP->new( $parm->{Server},
                                port     => $parm->{Port},
                                debug    => $ldapDebug,
                                version  => 3,
                              ) or die "$@"; # INITIALIZE
    my $mesg = $ldap->bind( $parm->{AuthDN},
                            password => "$parm->{pw}",
                          ); # BIND
    my $result = LDAPsearch( $ldap,
                             $parm->{SearchString},
                             $parm->{Attrs},
                             $parm->{Base},
                           ); # SEARCH!

    $ldap->unbind; # CLEAN UP

    my $count = $result->count;
    print "Returned: $count\n" if $LogLevel>=2;
    WalkThrough( $result ); # OUTPUT
}
# =====================================================
sub LDAPsearch {
    my ( $ldap, $SearchString, $attrs, $Base ) = @_ ;

    my $result = $ldap->search ( base   => $Base,
                                 filter => $SearchString,
                                 attrs  => $attrs,
                               );
}
# =====================================================
sub WalkThrough {
# This works, but is not what mine looks like (I do my compare here)
    my $result = shift @_;
    my @entries = $result->entries;
    my $entr;
    foreach $entr ( @entries ) {
        print "DN: ",$entr->dn,"\n";

        my $attr;
        foreach $attr ( sort $entr->attributes ) {
            next if ( $attr =~ /;binary$/ ); # skip binary
            print "  $attr : ",$entr->get_value( $attr ),"\n";
        }
    }
    if ( $result->code ) { # Display ERROR information 
        LDAPerror( $result );
    }
}
# =====================================================
sub PrintParms {
    my $parm = shift @_;
    my $Attrs = $parm->{Attrs};
    print "
      Server: $parm->{Server}:$parm->{Port}
      AuthDN: $parm->{AuthDN}  ($parm->{pw})
        Base: $parm->{Base}  |  SearchString: $parm->{SearchString}
       Attrs: $parm->{Attrs} ==> @{$Attrs}

";
}
# =====================================================
sub LDAPerror { #LL=1
    my ( $mesg ) = @_;
    print "\nReturn code: ", $mesg->code ;
    print "\n    Message: ", ldap_error_name( $mesg->code );
    print "\n           : ", ldap_error_text( $mesg->code );
    print   "  MessageID: ", $mesg->mesg_id;
    print "\n         DN: ", $mesg->dn, "\n\n";
}
# =====================================================
`-----

-- 
Tim Musson
Flying with The Bat! eMail v1.62q
Windows 2000 5.0.2195 (Service Pack 3)
If you drink, don't park.  Accidents cause people.


Reply via email to