Front page | perl.ldap |
Postings from April 2003
Re: Subclass proposal: Net::LDAP::Simple
Thread Previous
|
Thread Next
From:
Jim Harle
Date:
April 28, 2003 11:27
Subject:
Re: Subclass proposal: Net::LDAP::Simple
Message ID:
Pine.WNT.4.44.0304281116450.1868-100000@HARLE0941524
Marco,
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
one.
--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 perlmonks.org 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__
>
> 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 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) ;
>
> DESCRIPTION
> 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) ;
>
> 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/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.
>
> REDEFINED METHODS
> 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.
>
> NEW METHODS
> 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
>
> AUTHOR
> Marco Marongiu, <bronto@crs4.it>
>
> SEE ALSO
> Net::LDAP.
>
> --
> Marco Marongiu Email: bronto@crs4.it
> CRS4 Research Center Phone: +39 070 2796 336
> NCS Division Fax: +39 070 2796 216
> NSM Group WWW: http://bugs.unica.it:4444/
>
>
Thread Previous
|
Thread Next