[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Omaha.pm] Learning perl - working with LDAP



On Fri, Feb 24, 2012 at 10:36 AM, Bill Brush <bbrush@gmail.com> wrote:
Hello everyone.  I just recently started down the path of learning
Perl, and I'm working on my first script (program?  which is the
correct term for Perl?).

Anyway, I'm basing it on the example here:
http://www.developer.com/open/article.php/10930_3106601_3/Searching-Active-Directory-with-Perl.htm

Getting down to the details of the code, I want to throw out some
lines and how I interpret them to make sure I'm reading them right.

This line seems to be the money line of the example:

my $results = $ad->search(base=>$base,filter=>$filter,attrs=>$attrs);

The way I read that is:

my $results  =  (the output of this command will be stored in $results)

$ad->search   (Use the search method in the previously created object $ad)

(base=>$base,filter=>$filter,attrs=>$attrs)  (The search method has 3
inputs required [base,filter, attrs] which are stored in the 3
variables.  Base corresponds to the LDAP context where the search will
be performed, filter gives the criteria of the objects selected, and
attrs gives the attributes to be returned.  Presumably these could
have been written out explicitly rather than stored in variables, but
this is infinitely more readable and flexible.)

So am I reading that command correctly?

Yes.
 
Another question about the example script is minor, but I haven't
found the answer elsewhere.  The author uses the operator .= (dot
equal).  What does that do?
 
$x = 'x';
$x .= 'X';

is short had for

$x = $x . 'X';

both store 'xX' after execution.
 
A final question is more of a code style and efficiency question.  The
author uses a FOR-NEXT loop to cycle through the alphabet.  Wouldn't a
While (letter<z) or Until (letter =z) loop structure be more concise?
I'm trying to understand if there's an advantage to the author's
method that I'm not grasping.

I would propose rather than incrementing a letter index you could just use
'a'..'z' range operator.

This is how I would code the example.

#!/usr/bin/perl
use Modern::Perl;
use Net::LDAP;

# Connect and bind
my $ad = Net::LDAP->new("ad.wjgilmore.com") || die "Could not connect!";
$ad->bind( 'ad-web@ad.wjgilmore.com', password => 'secret' );

# build the alphabetical toc
my $toc = "\n\n" . join( ' ', a .. z ) . " \n";

# Perform LDAP queries, build directory pages
my $base = 'OU=People,OU=staff,DC=ad,DC=wjgilmore,DC=com';
for my $letter ( a .. z ) {

    # Filter on the staff membership and
    # first letter of samaccountname attribute
    my $filter = "(&(memberof=CN=staff,OU=groups,DC=ad,DC=wjgilmore,DC=com)(samaccountname=$letter*))";

    # Which attributes should be returned?
    my $attrs = "sn, givenname, mail";

    # Execute the search
    my $results = $ad->search( base => $base, filter => $filter, attrs => $attrs );
   
    # Check for errors!
    $results->code && die $results->error;
   
    # Build the directory
    my $directory;
    for my $entry ( $results->entries ) {
        $directory .= sprintf '%s %s (%s)%s', $entry->get_value('givenname'), $entry->get_value('sn'),
            $entry->get_value('mail'), "\n";
    }

    # Write the file
    open( FILE, '>', "/www/wjgilmore/directory/$letter.html" );
    say FILE $toc, $directory;
    close FILE;
}

# Unbind from the server
$ad->unbind;
# END

--
Ted Katseres
      ||=O=||