Displaying search results from NET::LDAP

Given the script below.
$entry->dump; would give me plenty of info. But I only want the CN. Can I do that without parsing? How can I list all the methods of $entry? I am assuming it is an object.
#! /usr/bin/perl

use warnings;
use CGI::Pretty qw(:all);
use strict;
use CGI::Carp::Fatals;
use Net::LDAP;
use DBI;

my $cgi=new CGI;

print header();
print start_html(-title=>'User Account Listing', -style=>{'src'=>'$url'},);

my ($bind, $mesg, $bindError, @entries, $entry);
my $base = "<base here>";
my $ldap = Net::LDAP->new("172.16.0.2", version => 3, port => 389) or die("failed $!");
print "Failed connecting" if(!$ldap);
$bind = $ldap->bind("<DN here>", password => "<pass here>") or die("failed $!; ".$bind->error);
if ( $bind->code ) {
        $bindError = LDAPerror( "Bind: ", $bind );
}

$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base);
@entries = $mesg->entries;
foreach $entry (@entries) {
        $entry->dump;
        print hr;
}

print end_html;

Open in new window

LVL 2
itniflAsked:
Who is Participating?
 
jwillekeConnect With a Mentor Commented:
Below is code that will bring back the cn only.
-jim
##!/usr/bin/perl

use warnings;
use strict;

use Net::LDAP;

# use Net::LDAPS;
use IO::Socket;
use IO::Socket::INET;

my $base  = "ou=people,DC=yourdomain,DC=com";
my @attrs = ( "cn");

my $ldapconnect =
  Net::LDAP->new( "ldap.yourdomain.com", version => 3, port => 389 );

print "\n";

my $bind =
  $ldapconnect->bind( "cn=admin,DC=yourdomain,DC=com",
    password => "secret" );
if ( $bind->code ) {
    LDAPerror( "Bind: ", $bind );
}
print "\n";


my $results = LDAPsearch( $ldapconnect, "(objectClass=*)", \@attrs, $base );
DisplayResults($results);

sub LDAPsearch {
    my ( $ldap, $searchString, $attrs, $base ) = @_;

    # if they don't pass a base... set it for them

    if ( !$base ) { $base = "o=mycompany, c=mycountry"; }

    # if they don't pass an array of attributes...
    # set up something for them

    if ( !$attrs ) { $attrs = [ 'cn', 'mail' ]; }

    my $sr = $ldap->search(
        base   => "$base",
        scope  => "sub",
        filter => "$searchString",
        attrs  => $attrs
    );
}

sub DisplayResults {
    my ($results) = @_;

    #------------
    #
    # Accessing the data as if in a structure
    #  i.e. Using the "as_struct"  method
    #

    my $href = $results->as_struct;

    # get an array of the DN names

    my @arrayOfDNs = keys %$href;    # use DN hashes

    # process each DN using it as a key

    foreach (@arrayOfDNs) {
        print $_, "\n";
        my $valref = $$href{$_};

        # get an array of the attribute names
        # passed for this one DN.
        my @arrayOfAttrs = sort keys %$valref;    #use Attr hashes

        my $attrName;
        foreach $attrName (@arrayOfAttrs) {

            # skip any binary data: yuck!
            next if ( $attrName =~ /;binary$/ );

            # get the attribute value (pointer) using the
            # attribute name as the hash
            my $attrVal = @$valref{$attrName};
            print "\t $attrName: @$attrVal \n";
        }
        print "#-------------------------------\n";

        # End of that DN
    }

    #
    #  end of as_struct method
    #
    #--------

    #------------
    #
    # handle each of the results independently
    # ... i.e. using the walk through method
    #

    my @entries = $results->entries;

    my $entr;
    foreach $entr (@entries) {
        print "DN: ", $entr->dn, "\n";

        my $attr;
        foreach $attr ( sort $entr->attributes ) {

            # skip binary we can't handle
            next if ( $attr =~ /;binary$/ );
            print "  $attr : ", $entr->get_value($attr), "\n";
        }

        print "#-------------------------------\n";
    }

    #
    # end of walk through method
    #------------

    sub LDAPerror {
        my $unknown = "not known";

        my ( $from, $mesg ) = @_;
        print "Return code: ", $mesg->code;
        print "\tMessage: ",   $mesg->error_name;
        print " :",            $mesg->error_text;
        print "MessageID: ",   $mesg->mesg_id;
        my $dn = $mesg->dn;
        if ( !$dn ) { $dn = $unknown; }
        print "\tDN: ", $dn;

        #---
        # Programmer note:
        #
        #  "$mesg->error" DOESN'T work!!!
        #
        #print "\tMessage: ", $mesg->error;
        #-----
    }

    sub addAdUser {
        my ( $ldap, $dn, $cn, $sn, $displayName, $givenName ) = @_;
        $ldap->add(
            $dn,
            attr => [
                'cn'          => $cn,
                'sn'          => $sn,
                'displayName' => $displayName,
                'givenName'   => $givenName,
                'objectclass' =>
                  [ "top", "person", "organizationalPerson", "user" ]
            ]
        );
    }
}

Open in new window

0
 
tdlewisCommented:
The result of $ldap->search is an object of class Net::LDAP::Search.

See http://search.cpan.org/~gbarr/perl-ldap-0.4001/lib/Net/LDAP/Search.pod
0
 
tdlewisCommented:
Also, each entry is an object of class Net::LDAP::Entry

See http://search.cpan.org/~gbarr/perl-ldap-0.4001/lib/Net/LDAP/Entry.pod
0
Improve Your Query Performance Tuning

In this FREE six-day email course, you'll learn from Janis Griffin, Database Performance Evangelist. She'll teach 12 steps that you can use to optimize your queries as much as possible and see measurable results in your work. Get started today!

 
jwillekeCommented:
Try
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base,  attrs  => "CN");

-jim
0
 
itniflAuthor Commented:
No didn't work...
0
 
itniflAuthor Commented:
I can see you are passing the @attrs array as this: \@attrs. That's passing it as a reference, and not a copy. If I do like this:
my @attrs=("cn");
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>\@attrs);

It works!
But if I do like this:
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>@attrs);
or
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>"cn");
or
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>"CN");

it doesn't work! Why?
0
 
jwillekeCommented:
Well, this is a quirk of mine as I always think of LDAP as an hierarchy of objects within objects.

In our case, a search result is a containers of DNs and entries...
.. an entry is a container of attribute name-value pairs.

So putting them into a hash allows working with them as a similar data structure.

I have a hash entries keyed by DNs
and hash Attributes keyed by attrName(s)

I am sure there are other ways to do this and I am not even close to a Perl guru, I do most things in Java and I know LDAP.
-jim
0
 
itniflAuthor Commented:
Ok, that didn't really answer why:
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>\@attrs);
works, and
$mesg = $ldap->search(filter=>"(objectClass=*)", base=>$base, attrs=>"cn");
doesn't.

But OK.
0
 
itniflAuthor Commented:
Thanks!
0
 
jwillekeCommented:
Well the specifics on
attrs=>"cn" does not work as attrs must be an array of attributesNames to call in a search, even if it is only one attributeName.

-jim
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.