develooper Front page | perl.ldap | Postings from April 2003

Re: Subclass proposal: Net::LDAP::Simple

Thread Previous | Thread Next
Jim Harle
April 28, 2003 11:27
Re: Subclass proposal: Net::LDAP::Simple
Message ID:
  I like the utility of doing connect, bind and base in the same call, and
would like to see that built into the main Net::LDAP. I would guess that
90% of my scripts only do one bind and use the same base for all searches.
The other 10% do require multiple bind's or multiple vases, however.

  I think that the other simplifications don't warrant having a new
subclass.  They don't save much code for people who 'know what they are
doing' and are too limited for use by newbies.  I suspect that what trips
up newbies most is the idea that searches need to be able to bring back a
list of entries, not just a single one and also that attributes are
(potentially) multi-valued.  Graham made the latter easier a few years ago
when he introduced get_value instead of get.

   It isn't clear from your doc whether simplesearch can take a list of
attributes to return.  If it can't then it encourages excessive traffic
between the client and server.

  On the other hand, I may have just gotten used to doing things in a
given way and can no longer recognize a real simplification when I see

 --Jim Harle

On Mon, 28 Apr 2003, Marco Marongiu wrote:

> Hello there, my name is Marco Marongiu. I am brand new on this list so
> if I am violating any rule or convention here I apologize. I am writing
> here after exchanging a couple of e-mails with Graham Barr.
> A couple of weeks I asked some opinions on the site about
> the idea of subclassing Net::LDAP to get a simplified interface. I am
> sorry I didn't think about posting *here* the same RFC, but here we go...
> What do I mean "simplified"? I'll try to show it by means of two examples.
> Example 1: you have to retrieve a number of entries in a subtree based
> on the contents of certain attributes, say cn, uid, loginName. The
> attributes remain the same, but you change the search string. You'll use
> a filter like (|(cn~=marco)(|(uid~=marco)(loginName~=marco)); then
> you'll pass the filter to the search method, along with the base (the
> same for all searches) and all the other parameters you need. After
> that, you need to check the returned Search object for errors and, in
> case of success, extract the entries to do the job; then start over with
> another similar filter and so on.
> I'd like to have a method to which I pass a "query string" and it does
> all the job for me, returning a reference to an array of entries for
> success or undef on failure -and, of course, I'd like to have a chance
> of seeing what actually made my search go wrong.
> Example 2: You have to read a bunch of entries from a directory server,
> modifying some attributes and then update them on another server -to fix
> the ideas you can think of reading entries from an iPlanet DS with NIS
> gateway and putting them into some Windows Active Directory server. The
> algorithm is about the same as above: search, check return message,
> extract entries, modify them, push them one by one on the other server,
> check the return message each time.
> I'd like to have a method that allows me to add an array of entries, and
> that returns a reference to an array containing the entries that made it
> in the directory server; in case of problems (input array has different
> length than the output) I'd like to have a chance to see what happened.
> In short: I don't want to go and check the return code if I don't have
> to, and I'd be happy if I had "array operations" on entries.
> I thought that it could be a good idea to create a subclass that offered
> such a simplified interface, and that Net::LDAP::Simple could be a name
> that fit. Then I read the (excellent) Sam Tregar's book "Writing Perl
> modules for CPAN" and he warned to ask for namespace owner's consensus
> before publishing anything. That's why I am here.
> I wouldn't post the module to CPAN if I won't have enough consensus or
> if you'll send me reasonable objections. But, in that case, I beg you to
> suggest a different, appropriate namespace.
> Enough talking. Below is the content of the manpage. If it is allowed on
> the list, I'll post the gzipped tarball too, it's less than 9kB. Just
> let me know.
> Thanks in advance for any suggestions and sorry for not contacting you
> before.
> Marco
> __END__
>      Net::LDAP::Simple - Simplified interface for Net::LDAP
>        use Net::LDAP::Simple;
>        # connect and bind to a directory server
>        # bindDN and bindpw are optional, if you don't specify them an
>        # anonymous bind is performed
>        # base is the base subtree for searches, it is an optional parameter
>        # searchattrs are the attributes that are used by the simplesearch()
>        # method.
>        eval {
>          my $ldap =
>            Net::LDAP::Simple->new(host => 'localhost',
>                                   bindDN => 'cn=admin,ou=People,dc=me',
>                                   bindpw => 'secret',
>                                   base   => 'ou=People,dc=me',
>                                   searchattrs => [qw(cn uid loginname)],
>                                   %parms) ; # params for Net::LDAP::new
>        } ;
>        if ($@) {
>          die "Can't connect to ldap server: $@" ;
>        }
>        my $filter = '(|(loginname=~bronto)(|(cn=~bronto)(uid=~bronto)))' ;
>        my $entries ;
>        # These all return the same array of Net::LDAP::Entry objects
>        $entries = $ldap->search(filter => $filter) ; # uses new()'s base
>        $entries = $ldap->search(base   => 'ou=People,dc=me',
>                                 filter => $filter) ;
>        $entries = $ldap->simplesearch('bronto') ; # uses new()'s searchattrs
>        # Now elaborate results:
>        foreach my $entry (@$entries) {
>          modify_something_in_this($entry) ;
>        }
>        # You often want to update a set of entries
>        foreach my $entry (@$entries) {
>          die "Error updating entry" unless defined $ldap->update($entry) ;
>        }
>        # but you can also do this:
>        my $result = $ldap->update(@$entries) ;
>        unless (@$result == @$entries) {
>          print "Error updating entries: ",$ldap->error,
>                "; code ",$ldap->errcode,".\n\n" ;
>        }
>        # Add an entry, or an array of them, works as above:
>        die $ldap->error unless $ldap->add($entry) ;
>        # rename an entry: sometimes you simply want to change a name
>        # and nothing else...
>        $ldap->rename($entry,$newrdn) ;
>      Net::LDAP::Simple is a simplified interface to the fantastic Graham
>      Barr's Net::LDAP. Net::LDAP is a great module for working with
>      directory servers, but it's a bit overkill when you want to do
>      simple short scripts or have big programs that always do the same
>      job again and again, say: open an authenticated connection to a
>      directory server, search entries against the same attributes each
>      time and in the same way (e.g.: approx search against the three
>      attributes cn, uid and loginname). With Net::LDAP this would mean:
>      *   connect to the directory server using new();
>      *   authenticate with bind() ;
>      *   compose a search filter, and pass it to search(), along with the
>          base subtree;
>      *   perform the search getting a Net::LDAP::Search object;
>      *   verify that the search was successful using the code() or
>          is_error() method on the search object;
>      *   if the search was successful, extract the entries from the
>          Search object, for example with entries or shift_entry.
>      With Net::LDAP::Simple this is done with:
>      *   connect, authenticate, define default search subtree and
>          simple-search attributes with the new() method;
>      *   pass the simplesearch method a search string to be matched
>          against the attributes defined with searchattrs in new() and
>          check the return value: if it was successful you have a
>          reference to an array of Net::LDAP::Entry objects, if it was
>          unsuccessful you get undef, and you can check what the error was
>          with the error() method (or the error code with errcode) ;
>      new(%parms)
>          Creates a Net::LDAP::Simple object. Accepts all the parameters
>          that are legal to Net::LDAP::new but the directory server
>          name/address is specified via the "host" parameter. Specific
>          Net::LDAP::Simple parameters are therefore:
>          host
>              the name or IP address of the directory server we are
>              connecting to. Mandatory.
>          bindDN
>              bind DN in case of authenticated bind
>          bindpw
>              bind password in case of authenticated bind
>          base
>              base subtree for searches. ***(Mandatory or optional?)
>          searchattrs
>              attributes to use for simple searches (see the simplesearch
>              method);
>          searchbool
>              boolean operator in case that more than one attribute is
>              specified with searchattrs; default is '|' (boolean or);
>              allowed boolean operators are | and &.
>          searchmatch
>              By default, an 'approx' search is performed by
>              simplesearch(); for those directory servers that doesn't
>              support the ~= operator it is possible to request a
>              substring search specifying the value 'substr' for the
>              searchmatch parameter.
>          searchextras
>              A list of attributes that should be returned in addition of
>              the default ones.
>      All Net::LDAP methods are supported via inheritance. Method specific
>      in Net::LDAP::Simple or that override inherited methods are
>      documented below.
>      add If you pass it a scalar DN as first parameter, it will proxy the
>          method call to Net::LDAP::add and it will behave the sane way
>          returning a Net::LDAP::Message object. Or you can pass it one or
>          more Net::LDAP::Entry objects, and it will return a reference to
>          an array of Net::LDAP::Entry objects that successfully made it
>          on the directory server. You can check if every entry has been
>          added by comparing the length of the input list against the
>          length of the output list. Use the error and/or errorcode
>          methods to see what went wrong.
>      delete
>          Works the same way as "add", but it deletes entries instead :-)
>      search
>          search works exactly as Net::LDAP::search() does, however it
>          takes advantage of the defaults set with new(): uses new()'s
>          base parameter if you don't specify another base, and adds
>          searchextras to default attributes unless you specify an "attrs"
>          parameter.
>          Another change in the search() interface is the return value:
>          now search() returns a reference to an array of entries for
>          success, or undef on error.
>          Passing a plain string to "search" just proxyies the call to the
>          method "simplesearch".
>          NOTE: Actually, I am undecided if this is a good thing. I am
>          pondering if search should simply be inherited by the
>          superclass... I'd like to have some feedback about that.
>      rename($entry,$newrdn)
>          Renames an entry; $entry can be a Net::LDAP::Entry or a DN,
>          $newrdn is a new value for the RDN. Returns $entry for success,
>          undef on failure.
>      update(@entries)
>          update takes a list of Net::LDAP::Entry objects as arguments and
>          commits changes on the directory server. Returns a reference to
>          an array of updated entries.
>      simplesearch($searchstring)
>          Searches entries using the new()'s search* and base parameters.
>          Takes a search string as argument. Returns a list of entries on
>          success, undef on error.
>      error
>          Returns last error's name
>      errcode
>          Returns last error's code
>      Marco Marongiu, <>
>      Net::LDAP.
> --
> Marco Marongiu                         Email:
> CRS4 Research Center                   Phone: +39 070 2796 336
> NCS Division                           Fax:   +39 070 2796 216
> NSM Group                              WWW:

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About