bronto has asked for the wisdom of the Perl Monks concerning the following question:

Hello all

I am writing some different applications that I'll use to manage entries on a directory server. Each application will manage a subtree (mostly), and each application will do about the same job on different subtrees, with different objectclasses and attributes but in the same way.

The module of choice for doing this is, of course, Net::LDAP, but it's interface seems to me a bit verbose in an environment like this one, so I'm planning to write a subclass, which I would like to call Net::LDAP::Simple, that simplifies the Net::LDAP interface.

Net::LDAP::Simple would offer a simpler interface to directory searches, giving back the matching entries directly (no $mesg->code checks); the add and delete methods will work on arrays of entries and some more shortcut methods will be added

That said, I'd like to hear from you about the module documentation below. I'd like to have suggestions about it before beginning to write code, so I'm looking forward to hear from you. Thanks in advance.


NAME Net::LDAP::Simple - Simplified interface for Net::LDAP SYNOPSIS 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 param +eter # searchattrs are the attributes that are used by the simplesear +ch() # 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 bas +e $entries = $ldap->search(base => 'ou=People,dc=me', filter => $filter) ; $entries = $ldap->simplesearch('bronto') ; # uses new()'s search +attrs # Now elaborate results: foreach my $entry (@$entries) { modify_something_in_this($entry) ; } # You often want to rewrite the entire entry (slow, but if it's +just # what you want...) foreach my $entry (@$entries) { die "Error rewriting entry" unless defined $ldap->rewrite($ent +ry) ; } # but you also can do this: my @result = $ldap->rewrite(@$entries) ; unless (@result == @$entries) { print "Error rewriting 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) ; # Sometime you want to copy an entry in a new one # in the same subtree... $ldap->copy($entry,$newrdn) ; # or on another subtree... $ldap->copy($entry,$newrdn,$subtree) ; # And you can even move it with $ldap->move, the syntax is the s +ame. DESCRIPTION Net::LDAP::Simple is a simplified interface to the fantastic Graha +m Barr's Net::LDAP. Net::LDAP is a great module for working with dir +ectory 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 sa +me 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 t +he base subtree; * perform the search getting a Net::LDAP::Search object; * verify that the search was successful using the code() or is_e +rror() method on the search object; * if the search was successful, extract the entries from the Sea +rch 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 aga +inst 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 un +def, and you can check what the error was with the error() method ( +or the error code with errcode) ; CONSTRUCTOR new(%parms) Creates a Net::LDAP::Simple object. Accepts all the parameters + that are legal to Net::LDAP::new but the directory server name/addr +ess 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 conn +ecting 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 simplesearc +h method); searchbool boolean operator in case that more than one attribute is specified with searchattrs; default is '|' (boolean or); a +llowed boolean operators are | and &. searchmatch By default, an 'approx' search is performed by simplesearc +h(); for those directory servers that doesn't support the ~= op +erator it is possible to request a substring search specifying th +e value 'substr' for the searchmatch parameter. searchextras A list of attributes that should be returned in addition o +f the default ones. REDEFINED METHODS All Net::LDAP methods are supported via inheritance. Method specif +ic in Net::LDAP::Simple or that override inherited methods are documente +d below. add You can use it the same way you'd use Net::LDAP::add, or you c +an pass it an array of Net::LDAP::Entry objects; returns a list o +f Net::LDAP::Entry objects that successfully made it on the dire +ctory server. You can check if every entry has been added by compari +ng 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 t +akes advantage of the defaults set with new(): uses new()'s base parameter if you don't specify another base, and adds searchex +tras 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 succes +s, or undef on error. Passing a simple string to "search" simply proxyies the call t +o the method "simplesearch". NEW METHODS rename($entry,$newrdn) Renames an entry; $entry can be a Net::LDAP::Entry or a DN, $n +ewrdn is a new value for the RDN. copy($entry,$newrdn [,$subtree]) Copies an entry; if you specify an optional third parameter th +e entry is copied on the specified subtree. move($entry,$newrdn [,$subtree]) Moves an entry; if you specify an optional third parameter the + entry is moved to the specified subtree. rewrite(@entries) Rewrites an entry entirely. Every attribute value is rewritten + even if it is unchanged. rewrite takes a list of Net::LDAP::Entry o +bjects as arguments. simplesearch($searchstring) Searches entries using the new()'s search* and base parameters +. Takes a search string as argument. AUTHOR Marco Marongiu, <bronto@CENSORED> SEE ALSO the Net::LDAP manpage.

The very nature of Perl to be like natural language--inconsistant and full of dwim and special cases--makes it impossible to know it all without simply memorizing the documentation (which is not complete or totally correct anyway).
--John M. Dlugosz