You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(200) |
Jun
(129) |
Jul
(184) |
Aug
(204) |
Sep
(106) |
Oct
(79) |
Nov
(72) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(83) |
Feb
(123) |
Mar
(84) |
Apr
(184) |
May
(106) |
Jun
(111) |
Jul
(104) |
Aug
(91) |
Sep
(59) |
Oct
(99) |
Nov
(100) |
Dec
(37) |
2002 |
Jan
(148) |
Feb
(88) |
Mar
(85) |
Apr
(151) |
May
(80) |
Jun
(110) |
Jul
(85) |
Aug
(43) |
Sep
(64) |
Oct
(89) |
Nov
(59) |
Dec
(42) |
2003 |
Jan
(129) |
Feb
(104) |
Mar
(162) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Mark W. <mew...@un...> - 2000-08-15 19:02:13
|
You'll only be able to compare the password if the server's ACLS allow you to do so. to do a compare: $mesg = $ldap->compare($dn,"userpassword",_properly_encoded_password); if ($mesg->code() == 6) { auth success } Mark On Tue, 15 Aug 2000, Howard, Michael J wrote: > I am unable to bind to my LDAP directory using the traditional method of > retreiving a dn through an anonymous connection, and then binding using the dn > and password. So instead, I am trying to authenticate into a website by > comparing username/password login values with the values of a uid: and > userpassword: attributes stored in my LDAP directory. I can successfully > retreive the uid, however, I cannot retreive the password. This seems logical, > because it would be a security issue, however, is there a way I can compare > these values to the value of the userpassword attribute? Any help with the > syntax for doing something like this is much appreciated. > > Here is what I have so far. > > $ldap = Net::LDAP->new('[LDAP SERVER]') or die "$@"; > > $ldap->bind; > > my $result = $ldap->search( > base => "[BASE]", > scope => "sub", > filter => "(&(uid = $user) (userpassword = $sent_pw))", > ); > > if ($result->count != 1) { > #Authentication Failed > return "Failed - User does not exist in the LDAP server"; > } > else { > #Successfull Authentication > return 0; > } > > Thanks, > > Michael Howard > Information Sciences and Engineering > Pacific Northwest National Laboratory > (509) 375-6981 ISB2 528 > > > > |
From: Mark W. <mew...@un...> - 2000-08-15 19:00:52
|
If the password is bad, it will return an error code of 49 "BAD Credentials": my $mesg =$ldap->bind(...); die ("failed to bind with ",$mesg->code(),"\n") if $mesg->code(); will always fail unless successful bind. under .20, it will also auto-catch blank passwords (which would force anonymous bind). Mark On Tue, 15 Aug 2000, Joshua Lavalleur wrote: > When I try to perform an authenticated bind to the server how can I get it > to die if the user name or password is bad instead of going anonymous? > > -Josh > > |
From: Joshua L. <Jos...@ip...> - 2000-08-15 18:04:03
|
When I try to perform an authenticated bind to the server how can I get it to die if the user name or password is bad instead of going anonymous? -Josh |
From: Howard, M. J <Mic...@pn...> - 2000-08-15 17:57:38
|
I am unable to bind to my LDAP directory using the traditional method of retreiving a dn through an anonymous connection, and then binding using the dn and password. So instead, I am trying to authenticate into a website by comparing username/password login values with the values of a uid: and userpassword: attributes stored in my LDAP directory. I can successfully retreive the uid, however, I cannot retreive the password. This seems logical, because it would be a security issue, however, is there a way I can compare these values to the value of the userpassword attribute? Any help with the syntax for doing something like this is much appreciated. Here is what I have so far. $ldap = Net::LDAP->new('[LDAP SERVER]') or die "$@"; $ldap->bind; my $result = $ldap->search( base => "[BASE]", scope => "sub", filter => "(&(uid = $user) (userpassword = $sent_pw))", ); if ($result->count != 1) { #Authentication Failed return "Failed - User does not exist in the LDAP server"; } else { #Successfull Authentication return 0; } Thanks, Michael Howard Information Sciences and Engineering Pacific Northwest National Laboratory (509) 375-6981 ISB2 528 |
From: Allen, R. <ra...@ci...> - 2000-08-15 16:47:47
|
If your LDAP server supports (check the RootDSE) the TreeDelete control you can use that to delete an entire tree full of subtrees. Robbie Allen > -----Original Message----- > From: Mark Wilcox [mailto:mew...@un...] > Sent: Tuesday, August 15, 2000 8:26 AM > To: Tom Sherrod > Cc: per...@li... > Subject: Re: deleting entries... > > > > You must delete all children entries first before you can delete any > parent entries. > > Mark > On Tue, 15 Aug 2000, Tom Sherrod wrote: > > > I'm attempting to delete an entry that contains sub entries that > > contain sub entries and receiving this error: > > LDAP_NOT_ALLOWED_ON_NONLEAF > > > > I've found that if I go down to the bottom, I could delete, > by working my > > way back out. > > Is there a simpler way? Is there a way to tell from an > entry if there are > > sub trees besides checking for the error or searching down? > > > > Tom Sherrod to...@sa... > > > > > > > > |
From: Graham B. <gb...@po...> - 2000-08-15 16:28:50
|
OK, We have an offer to help professionally design a web-site and logo. For some examples of previous work see http://www.whatscookin.com/ http://www.voicenet.com/~dani3l/ http://www.paconvention.com/ The question is, what do we want ? And what should the logo look like ? This is really not my kind of area as people can tell from the existing site, so I am hoping others have ideas of what we want on the site/logo that we can pass on. Also, if anyone is feeling artistic then feel free to design a logo, all will be considered. As I am off on a business trip next week, I will collate all the ideas together this weekend and forward them. Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 16:18:55
|
On Mon, Aug 14, 2000 at 10:47:14PM +0100, John Berthels wrote: > The case I initially didn't catch is the one now represented by a leading > '_'. This refers to a node in the tree which is a straight array ref, not > blessed to Convert::ASN::parser The fact that some are blessed does not mean anything. I use it during a post-parse stage to mean "been here". > There are currently bugs relating to the fact that for the cTAG member, I > map '' -> '0' -> (chr 0). That is is a problem. The cTAG element is the tag packed. I would suggest outputing it as unpack("H*",$cTAG) and read it back with pack("H*",$input) that way '' will be out put as ,, and '0' will be output as ,30, > I also introduce missing array elts as undef - That will not be a problem. > If you like the idea I'll try and clean things up. Sure. > PS. Some time ago you suggested I check out the Devel:: modules. The > Devel::DProf module is cool. It shows up that > Net::LDAP::Schema::_get_one_word is a significant proportion (10-20%) of a > typical Schema load time. It is a one-liner used in two places, so > inlining is probably a good idea... are there any perl pragma's for this > yet or do we just cut and paste? Well its a bit more than one line, its 2 :) There is no way to get perl to inline yet, so we will have to copy the code. Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 16:02:34
|
On Tue, Aug 15, 2000 at 10:46:40AM -0500, Michael Thorne wrote: > I installed the Convert::ASN1, URI::ldap, Digest::MD5 > and Net::LDAP modules which went well but the files were > placed into > > /usr/lib/perl5/site_perl/5.005/Convert/ASN1/ > /usr/lib/perl5/site_perl/5.005/URI/ > /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Digest/ > /usr/lib/perl5/site_perl/5.005/i386-linux/Digest/ > and > /usr/lib/perl5/site_perl/5.005/Net/LDAP/ > > not /usr/lib/perl5/5.00503 which is where the traditional > modules (CGI, Math, Tie etc.) are located. > > Is this ok/correct? This is the correct place. Only modules that come with perl itself are installed in /usr/lib/perl5/5.00503 > Is the "site_perl" directory the standard way that perl > environments distinguish additional "site" modules from > "core" modules? site_perl allows you to upgrade your perl installation and share modules you have installed between both old and new installations. Graham. |
From: Michael T. <mt...@ag...> - 2000-08-15 15:49:04
|
Hi All, sorry for the light chaff but I'm fairly new to Linux and Perl. I've been tasked with getting LDAP services activated on our "dallaslinux" box, Red Hat 6.2, and having them work with our corporate office LDAP server. I've successfully installed the OpenLDAP software and can query corporate with the ldapsearch utility. My next step is installing Graham's module. I've followed the standard procedures and all things went well except of two issues which I'll follow up on shortly. I installed the Convert::ASN1, URI::ldap, Digest::MD5 and Net::LDAP modules which went well but the files were placed into /usr/lib/perl5/site_perl/5.005/Convert/ASN1/ /usr/lib/perl5/site_perl/5.005/URI/ /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Digest/ /usr/lib/perl5/site_perl/5.005/i386-linux/Digest/ and /usr/lib/perl5/site_perl/5.005/Net/LDAP/ not /usr/lib/perl5/5.00503 which is where the traditional modules (CGI, Math, Tie etc.) are located. Is this ok/correct? Is the "site_perl" directory the standard way that perl environments distinguish additional "site" modules from "core" modules? The first error was during the URI make test (pretty edited for email). PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t t/abs...............ok t/data..............Can't locate object method "media_type" via package "URI::_foreign" at t/data.t line 9. dubious Test returned status 255 (wstat 65280, 0xff00) Undefined subroutine &Test::Harness::WCOREDUMP called at /usr/lib/perl5/5.00503/Test/Harness.pm line 288. make: *** [test_dynamic] Error 255 I looked inside the URI.pm file line 288 is $u5 = URI->new("HTTP://WWW.perl.com:80")->canonical; which is 12 lines after the __END__ and I can find reference to "_foreign" at lines 54 and 55 but no "sub _foreign". What sub's I do find are sub _init sub _init_implementor sub _no_scheme_ok { 0 } sub _scheme Can anyone tell me what's going on here and what I need to do? The second "problem/error" (?) I've had during installation is with the Digest::MD5 module. $> make install ... Installing /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Digest/SHA1/SHA1.bs Files found in blib/arch --> Installing files in blib/lib into architecture dependend library tree! ... Is there anything I need to do/fix? If I need to "RFM" would you tell me which ones and the appropriate sections? If you'd like to review the install logs for all four of the modules you can find them at http://dallaslinux.dallas.agency.com/~mthorne/perl/installs.html Thanks in advance, Michael. ==================================================================== dB^) Dallas.TX.us THINK Think different Think Open Source Michael Thorne Technical Consultant t: 214.527.3434 f: 214.571.4040 e: mt...@ag... |
From: Mark W. <mew...@un...> - 2000-08-15 15:28:55
|
You must delete all children entries first before you can delete any parent entries. Mark On Tue, 15 Aug 2000, Tom Sherrod wrote: > I'm attempting to delete an entry that contains sub entries that > contain sub entries and receiving this error: > LDAP_NOT_ALLOWED_ON_NONLEAF > > I've found that if I go down to the bottom, I could delete, by working my > way back out. > Is there a simpler way? Is there a way to tell from an entry if there are > sub trees besides checking for the error or searching down? > > Tom Sherrod to...@sa... > > > |
From: Mark W. <mew...@un...> - 2000-08-15 15:28:08
|
I'm not saying that it would be better, I'm just saying that if the list agreed to it, I wouldn't put up too much of a fight :). Mark On Tue, 15 Aug 2000, Graham Barr wrote: > On Mon, Aug 14, 2000 at 04:21:43PM -0500, Mark Wilcox wrote: > > So to sum it up, I'm for the following methods: > > > > 1) connect > > would return an anonymous binded connection to the LDAP server > > What would it return if it could not connect or not bind. How would > you tell the difference. And how it is > > $ldap = Net::LDAP->connect( ... ); > > that much better than > > my $ldap = Net::LDAP->new ( ... ) and $msg = $ldap->bind; > > which you can determine if the connect or bind failed. > > > 2) read > > come back with a single entry > > Net::LDAP::Util > > ldap_read_entry(); > > > 3) list > > come back with an array of all entries under a particular DN > > ldap_list_entries() > > Graham. > > |
From: Tom S. <to...@un...> - 2000-08-15 14:29:40
|
I'm attempting to delete an entry that contains sub entries that contain sub entries and receiving this error: LDAP_NOT_ALLOWED_ON_NONLEAF I've found that if I go down to the bottom, I could delete, by working my way back out. Is there a simpler way? Is there a way to tell from an entry if there are sub trees besides checking for the error or searching down? Tom Sherrod to...@sa... |
From: Graham B. <gb...@po...> - 2000-08-15 11:02:56
|
On Mon, Aug 14, 2000 at 10:47:14PM +0100, John Berthels wrote: > PS. Some time ago you suggested I check out the Devel:: modules. The > Devel::DProf module is cool. It shows up that > Net::LDAP::Schema::_get_one_word is a significant proportion (10-20%) of a > typical Schema load time. It is a one-liner used in two places, so > inlining is probably a good idea... are there any perl pragma's for this > yet or do we just cut and paste? I have taken a hatchet to the parsing code and managed to reduce it's time taken. I replaced the nibble parser with a tokenizing parser with the following effect, approx. a 30% speedup. Each read data/schema.in 100 times [before] Total Elapsed Time = 4.576090 Seconds User+System Time = 4.576090 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 32.3 1.480 1.436 29000 0.0001 0.0000 Net::LDAP::Schema::_parse_item 22.4 1.029 2.406 11000 0.0001 0.0002 Net::LDAP::Schema::_parse_value 17.9 0.820 0.803 11000 0.0001 0.0001 Net::LDAP::Schema::_fixup_entry 11.7 0.536 3.736 100 0.0054 0.0374 Net::LDAP::Schema::_parse_schema 8.96 0.410 0.479 100 0.0041 0.0048 Net::LDAP::LDIF::_read_one 1.53 0.070 0.070 100 0.0007 0.0007 Net::LDAP::Entry::add 1.53 0.070 0.080 14 0.0050 0.0057 Convert::ASN1::BEGIN 1.29 0.059 0.107 1 0.0586 0.1071 Convert::ASN1::parser::yyparse 1.09 0.050 0.048 905 0.0001 0.0001 Convert::ASN1::parser::yylex 0.87 0.040 4.499 100 0.0004 0.0450 Net::LDAP::Schema::parse 0.44 0.020 0.030 3 0.0067 0.0100 main::BEGIN 0.44 0.020 0.117 245 0.0001 0.0005 Convert::ASN1::parser::compile_one 0.44 0.020 0.020 100 0.0002 0.0002 Net::LDAP::LDIF::new 0.22 0.010 0.010 300 0.0000 0.0000 Net::LDAP::Entry::get 0.22 0.010 0.010 2 0.0050 0.0050 SelectSaver::BEGIN [after] Total Elapsed Time = 3.198119 Seconds User+System Time = 3.188119 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 66.0 2.107 2.315 100 0.0211 0.0231 Net::LDAP::Schema::_parse_schema 13.1 0.420 0.468 100 0.0042 0.0047 Net::LDAP::LDIF::_read_one 7.21 0.230 0.208 11000 0.0000 0.0000 Net::LDAP::Schema::_fixup_entry 2.20 0.070 0.080 14 0.0050 0.0057 Convert::ASN1::BEGIN 2.13 0.068 0.106 1 0.0682 0.1062 Convert::ASN1::parser::yyparse 1.25 0.040 0.038 905 0.0000 0.0000 Convert::ASN1::parser::yylex 1.25 0.040 0.049 100 0.0004 0.0005 Net::LDAP::Entry::add 0.94 0.030 3.055 100 0.0003 0.0305 Net::LDAP::Schema::parse 0.63 0.020 0.030 4 0.0050 0.0075 main::BEGIN 0.31 0.010 0.010 100 0.0001 0.0001 Net::LDAP::LDIF::done 0.31 0.010 0.010 100 0.0001 0.0001 Net::LDAP::Entry::_build_attrs 0.31 0.010 0.010 100 0.0001 0.0001 Symbol::gensym 0.31 0.010 0.010 2 0.0050 0.0050 SelectSaver::BEGIN 0.31 0.010 0.010 2 0.0050 0.0050 lib::BEGIN 0.31 0.010 0.214 103 0.0001 0.0021 Net::LDAP::Entry::BEGIN Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 08:49:56
|
On Mon, Aug 14, 2000 at 04:21:43PM -0500, Mark Wilcox wrote: > So to sum it up, I'm for the following methods: > > 1) connect > would return an anonymous binded connection to the LDAP server What would it return if it could not connect or not bind. How would you tell the difference. And how it is $ldap = Net::LDAP->connect( ... ); that much better than my $ldap = Net::LDAP->new ( ... ) and $msg = $ldap->bind; which you can determine if the connect or bind failed. > 2) read > come back with a single entry Net::LDAP::Util ldap_read_entry(); > 3) list > come back with an array of all entries under a particular DN ldap_list_entries() Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 08:45:12
|
On Mon, Aug 14, 2000 at 10:55:34PM +0100, John Berthels wrote: > > What kind of wrapper functions ? give some examples > > Well, in many cases you know you are always talking to an LDAP server on > the localhost. In one particular case credentials for a privileged bind > were picked up from config. So I could do: > > my $l = ldap_bind(); # ->new and Anon ->bind to localhost > my $l = ldap_bind(1); # ->new and Priv. ->bind to localhost > > I had some procedural calls which took either an existing $l or undef as > first arg. If the handle was undef, they did a bind/unbind in themselves > in the function (failing on error). I appreciate this doesn't fit with the > OO paradigm. But it was convenient. To me these do not seem like the kind of thing a "generic" user would want and are specific to the way in which you use Net::LDAP. > However, a: > > my $l = Net::LDAP->connect() > or die( "Can't connect to local server : $!" ); > > which returned an anonymously bound handle to localhost (takes one or two > args to override host + port) would save a few lines per script. Why doo you think localhost is a common host ? I have personally never used localhost for anything other than testing. I would say in the most common case the server is remote. > I had some wrappers around ->search(). [Some are my thoughts, some others > I've seen on this list recently] > > ->search() > If "filter" unspecified, default to "(objectclass=*)" ? sounds reasonable-ish. > ->list( $dn, [ @attrs ] ) > Search with "base => $dn, scope => 'one'" (and above filter) > > ->read( $dn, [ @attrs ] ) > Search with "base => $dn, scope => 'sub'" (and above filter) > > ->exists( $dn ) > As for ->read but request minimal attributes ("1.1"?) it seems to me you just do not like the named arguments to ->search > ->ping() > As for ->exists but a constant "known good" dn...does base => "" work? This is one we do need. > for the lazy: > > my $l = Net::LDAP->connect(); connect() is going to appear, but it will require a hostname. > my $cn = $l->simple_read( $dn, "commonName" ); # First of multivalue > > my @entries = $l->simple_search( ...normal search options ); > > @entries empty implies error or no results. If I care I can examine $! or > something. Most of these seem to me as if they would really belong in a utility module. There is no reason for them to be called as methods, so perhaps just prefix them with ldap_ and add the to ::Util > In apps which can just quit on an LDAP error, I started to do: > > my $msg = $ldap->some_operation( some_args ); > ldap_die_if_error( "Doing some_operation", $msg ); > > my $msg = $ldap->some_other_op( other_args ); > ldap_die_if_error( "Doing some_other_op", $msg ); This comes back to what was suggested by someone else, having a handler to too at the results and possibly die. But how do you determine "error" ? > which feels icky in perl. > > [Maybe I just need to follow the examples and > > $msg->code() && die( "Doing op : " . $mesg->error() ); > > Ah well.] But, to some extent, that is icky too. Plus just checking ->code for true is not always what is wanted. It would be nice to do $msg = $ldap->search(...) or die "..." . $ldap->error; > Could we tweak this with parameters to '->new' or 'use'? > > # > # Methods die with descriptive text if any errors occur. > # > my $l = Net::LDAP->new( "foo", die_on_error => 1 ) > or die( "Can't connect : $!" ); Yes, if we can specify what an error is. Although if we just have onerror => sub { ... }, where sub is passed the message and it's return value is what is returned from the $ldap->method you could do onerror => sub { die ... } or onerror => sub { undef } > AND/OR > > # > # Request that methods not return Net::LDAP::Message's. Instead false on > # error, true on success. WARNING: Methods which return data will return > # an array of Net::LDAP::Entries - an empty search result cannot be > # distinguished from a failed one. (Could we set $@ ? Does this not work > # with async ops?) What would non-search methods do? > # I don't think so. What about callbacks, what about controls etc. Plus it confuses the API if each method is possible of returning different resutls depending on some other option. These belong as wrappers in a util function module. Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 08:43:16
|
On Tue, Aug 15, 2000 at 01:47:07PM +1000, David Bussenschutt wrote: > Hi again, > > Why not handle the 'expected'? What is expected ? > What happens when compare has (for example) an internal error and/or the > data was uncomparable for unknown reason? Is this handled at the moment? > It should in my opinion be this is what could/should cause an on_error > event in compare's case. It returns the error from the server. It is up to the application to determine what to do with that error. > And for that matter, by allowing a user-defined subroutine as an on_error, > you could allow the user(programmer) to define a callback for 'compare' > that dies/croaks/whatever whenever the user(programmer) desires (including > error code 5 or 6). Hm, maybe more thought is needed here. > By doing this the API is simpler, really ? > the bloat is negligable, Not really > the users are > happier, may be > the resultant code is easier to read... what more could you want? beauty is in the eye of the beholder. > I mean, the "|| die.." code will be written anyway so in the module is a > better place for it, so it doesn't have to be written over and over again! But it is not being written in the module, the user is having to write a sub to process the result. All you are doing is moving when the user processes the result. > As I understand it, this would also clear-up the problem the API currently > has with it's inability to determine if a search returned no results What inability ? $mesg->count will teel you how many results you got. > because there was nothing to return or because of an error performing the > search. You are referring to getting values from an entry, a separate module from the LDAP API module Graham. |
From: Graham B. <gb...@po...> - 2000-08-15 08:27:59
|
I think it's a great idea. If someone wants to implement it. You might want to have the option of the new entry only modifying the attributes that existed in both, or take a list of attributes to diff. Graham. On Mon, Aug 14, 2000 at 04:06:15PM -0500, Mark Wilcox wrote: > > > > A ->diff() method would be cool: > > > > my $old_entry = $l->read( $dn ); > > my $new_entry = $ldif->read(); > > my $changes_entry = $old_entry->diff( $new_entry ); > > $changes_entry->update( $l ); # Maps down to a ->modify() call > > I (and one other person on the list) started banging on a diff method a > while back. > > The basics are easy. It's hard when you have a multivalued. The old entry > contains: > ou=people,untfs,acs > > and lets say the person changes jobs, but the ou update only reflects this > new position change like this: > ou=coe > > and let's say that the person who made the change wants the new entry to > have an ou of: > ou=people,untfs,coe > > how would you know in your diff to either replace the existing multi-value > with the new single value, or to simply tag it on at the end? > > Mark > > > |
From: Graham B. <gb...@po...> - 2000-08-15 08:25:39
|
On Mon, Aug 14, 2000 at 10:54:53PM +0100, John Berthels wrote: > > > This email is highlighting more than one issue. Lets break it into parts and > > see what we can develop > > > > 1) Net::LDAP::Entry > > > > In the case of 1) lets list what we should be able to do with an Entry and > > what a newbie would probably expect. Then compare that with what an expert > > would expect/need. It may not be that different. > > Getting data simply > =================== > > This feels too indirect: > > my $msg = $l->search( ... ); > my @entries = $msg->entries(); > foreach my $entry ( @entries ) { > my $attrs = $entry->get( "cn" ); > my $cn = shift @$attrs; # Take first That is what we have now, but I am not sure it is what most would expect when the entry is single-valued, which is probably the most common case. It also leads to ugly code like my $cn = ($entry->get( "cn" ) || [])->[0]; which is even worse. After some thinking I am coming to the idea that is used by DBI. That is that there are several methods with different return type. For example DBI has fetchrow and fetchrow_arrayref, I am thinking we have get and get_arrayref. Get will always return a list of values, non-existant attributes will have to be tested with ->exists Graham. |
From: David B. <d.b...@ma...> - 2000-08-15 03:46:17
|
Hi again, Why not handle the 'expected'? When using this hypothetical "on_error", if the operation has an obvious "operation failed" return, then die/croak/\&callback/whatever and If the operation has return codes that don't meet that criteria, then don't. Eg, 'compare', should really consider both a true and a false return value as being valid "operation successful"... since to get either of those values then compare had to succeed in the compare. What happens when compare has (for example) an internal error and/or the data was uncomparable for unknown reason? Is this handled at the moment? It should in my opinion be this is what could/should cause an on_error event in compare's case. And for that matter, by allowing a user-defined subroutine as an on_error, you could allow the user(programmer) to define a callback for 'compare' that dies/croaks/whatever whenever the user(programmer) desires (including error code 5 or 6). By doing this the API is simpler, the bloat is negligable, the users are happier, the resultant code is easier to read... what more could you want? I mean, the "|| die.." code will be written anyway so in the module is a better place for it, so it doesn't have to be written over and over again! As I understand it, this would also clear-up the problem the API currently has with it's inability to determine if a search returned no results because there was nothing to return or because of an error performing the search. My 2c. What do others think? David. At 07:46 PM 8/14/00 -0500, you wrote: >Problem with defining a default on_error is that some errors are expected. For example in >compare, the results will either be 5 for false or 6 for true (or is it vice/versa ?) > >mark > >David Bussenschutt wrote: > >> Bravo everyone, >> >> I can't add much more to the debate except to say I'm on the side of >> everyone that wants to make the Net::LDAP API simpler by default, but more >> powerful if desired. >> >> It seems to me that there are a lot of people out there doing : >> Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); >> >> How's this for another optional feature... >> >> my $a = Net::LDAP->new("ldap.server.org",on_error=>die); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); >> >> Obviously, the on_error value would apply to all >> binds/queries/searches/lists/reads performed >> using that connection handle. >> >> David. >> >> At 03:30 PM 8/14/00 +0100, Graham Barr wrote: >> >On Mon, Aug 14, 2000 at 02:45:44PM +0100, John Berthels wrote: >> >> >> >> > > This leads me to think that a high level interface might be useful. >> Here >> >> > > are a couple of suggestions on how this might differ from Net::LDAP. >> >> > > >> >> > > 1) The ->new method takes an optional username/password and does a >> >> > > Net::LDAP->new and a ->bind. Returns object or under if anything fails. >> >> > >> >> > IMO, this is bad. I even want to move the connect out of new and into a >> >> > separate method so that errors can be returned with more ease. >> >> >> >> I agree that it would be bad for the Net::LDAP API. >> >> >> >> However, for an 'easy to use' interface (Net::LDAP::For::Dummies) I just >> >> want a handle for a connection I can do things with. If the API fails to >> >> create it (for any reason) then fine, return undef and put some >> >> descriptive text in $! but don't make me do 2 or 3 calls to get the >> >> handle. In the common case it will 'just work'. >> > >> >I am all for having some way for Net::LDAP to have "common use" functions. >> But >> >having a separate API "for dummies" no. >> > >> >> > > i.e. you could write: >> >> > > >> >> > > #!/usr/bin/perl -w >> >> > > use Net::LDAP::Cooked; # or whatever >> >> > > >> >> > > my $l = Net::LDAP::Cooked->new( "local.ldap.server" ) >> >> > > or die( "Can't connect : $!" ); >> >> > > my @staff = $l->list( "ou=staff, o=myorg" ) >> >> > > or die( "Can't list staff : $!" ); >> >> > >> >> > I think this is coming back to having someway, other than inheritance >> (maybe) >> >> > to extend Net::LDAP. >> >> >> >> Yes. Exactly. I suspect that lots of people writing apps using Net::LDAP >> >> have similar code in their apps. I want to pull that similar code into a >> >> companion module for Net::LDAP for standard code reuse reasons. >> > >> >Right, then lets define a way to do that. >> > >> >> > > foreach my $person( @staff ) { >> >> > > my $name = $person->get( "cn" ); >> >> > > my $phone = $person->get( "telephoneNumber" ); >> >> > >> >> > For the ::Entry I would prefer to keep one module and have it work as >> >> > expected. >> >> >> >> Again - expected by who? >> > >> >A perl programmer. >> > >> >> It may be possible to define an ::Entry API which >> >> satisfies both camps, but if not then why not have two? The 'hard core' >> >> users don't have the impact of the additional fluff and the 'just want it >> >> to work' users don't have to go through additional levels of indirection >> >> to get to their data. >> > >> >I don't think the two camps are that different in terms of >> 'understandability' >> >just in what level they want access to. >> > >> >> > And I think the above it the "expected" behaviour. Which would mean >> >> > that get returns a list and we add exists. Then we split out the >> >> > extra option code I added into another method, say get_nooptions >> >> > which always returns a hashref >> >> >> >> Something like this would be fine. The only negatives for this would be >> >> bloating the module and which camp was annoyed by having to use the longer >> >> name :-) >> > >> >It would not be bloat as all of it is there now. It just seems the API >> >is hard for some to understand. I belive we should be able to get a >> >single API ot ::Entry that is both powerful enough for the hard core >> >user and simple enough for the beginner. >> > >> >> > > The kinds of things going on here would be: >> >> > > >> >> > > - additional methods which reduce the need to construct arguments to >> >> > > ->search. e.g. ->list, ->read, ->exists >> >> > >> >> > What are ->read and ->exist and called on what object ? >> >> >> >> my $entry = $ldap->read( $dn ); # Call search with scope 0 and filter >> >> >> >> ->exists( $dn ) is true if the entry is in the Directory. At first sight >> >> seems the same as ->read( $dn ) but could be more efficient since it need >> >> not pull back all attributes. Both are syntactic sugar around ->search(). >> >> >> >> The previous discussions around $ldap->alive() (or $ldap->ping()) fit >> >> right in here too. Syntactic sugar. This is perl after all :-) >> > >> >Right. We need a way to add extensions. This can be done in many ways. >> > >> >1) Inheritance >> >2) MI >> >3) allowing others to import into Net::LDAP with a register module. >> > >> >> > > - avoid Net::LDAP::Message returns, give back arrays of >> >> > > Net::LDAP::Cooked::Entry >> >> > >> >> > I would rather just keep one Entry object. >> >> >> >> Fair enough, but see above regarding two audiences. >> > >> >I think we can keep both happy. >> > >> >> > > So, is this something which would be useful to people (or would have >> been >> >> > > useful to them when starting with Net::LDAP) or does it just hide >> too much >> >> > > from the user and is likely to confuse them? >> >> > >> >> > Confusion is one thing that concerns me. Because you teach them one >> >> > theng then they have to learn something else if they want to go >> >> > beyond its boundaries. I would prefer to make the API as natural/easy >> >> > as possible. >> >> >> >> This is a very good point. The documentation of all this would have to be >> >> done very carefully. To some extent I think that this might be alleviated >> >> by having the two APIs appear less related. "Oh...you're using >> >> Net::LDAP::Simple. Thats OK, but to do *that* you need to read up on >> >> Net::LDAP". >> > >> >Two documents, yes. Two APIs, I would rather not. >> > >> >We could just make these methods avaliable via the AUTOLOADer or have the >> >user type >> > >> > use Net::LDAP::Extn qw(:simple); >> > >> >to get Net::LDAP::Extn to import some subs into Net::LDAP or just have >> >Net::LDAP::Simple inherit from Net::LDAP and provide these subs. >> > >> >But some of these may be of use to 'hard core' users too, which is why >> >I don't really like the ::Simple appraoch as we will see more and more >> >::Simple being the main API. >> > >> >> This is why I was thinking inheritance might be bad, since it might appear >> >> to mix the two. >> > >> >Yes. >> > >> >> > > If this is something worth doing, should we add bloat to Net::LDAP to >> >> > > support things like this or should we create a wrapper module. >> >> > >> >> > bloat is something I want to avoid if possible. >> >> >> >> This is the main reason I was thinking about a second API, rather than >> >> trying to make one API all things to all people. >> >> >> >> > > If we create a wrapper module should it live within the Net::LDAP >> >> > > namespace or somewhere else? >> >> > >> >> > probably within. >> >> >> >> Agreed. (But its your namespace :-) >> > >> >But my preference is a way to provide extensions to Net::LDAP, but still >> >(maybe) via a Net::LDAP method. The other option is to provide subs >> >in Net::LDAP::Util >> > >> >> > > Should it inherit from Net::LDAP and add/override methods or should >> it be >> >> > > a seperate object? >> >> > >> >> > What would it gain from being a separate module ? I would say it >> >> > should inherit, if we have it at all. I would prefer to get the current >> >> > module "fixed" rather than create another module just to provide a >> different >> >> > API. >> >> >> >> My real question is whether it is better to extend Net::LDAP to make it >> >> easier for novice users (or those who like convenience) or instead to >> >> recognise that there are different types of users and so implement a new >> >> API to meet a different need. I think Net::LDAP is nice, clean and >> >> precise. I like that. I also find myself replicating wrapper functions >> >> from app to app and wishing that they lived in the distribution. >> > >> >What kind of wrapper functions ? give some examples >> > >> >Well we need to define a way for people to make these things easy. >> > >> >> As I see it, the downsides of extending Net::LDAP are bloat and >> >> conflicting design goals. The downsides of a new API are that it is a >> >> little more work. >> > >> >And the fact you end up with two APIs and people asking questions which to >> >use etc... >> > >> >I am sure it is possible to meet the demands of both camps without creating >> >a completely new API. >> > >> >This email is highlighting more than one issue. Lets break it into parts and >> >see what we can develop >> > >> > 1) Net::LDAP::Entry >> > 2) Extending Net::LDAP with common methods >> > >> >In the case of 1) lets list what we should be able to do with an Entry and >> >what a newbie would probably expect. Then compare that with what an expert >> >would expect/need. It may not be that different. >> > >> >Graham. >> > >> > >> > >> >> -------------------------------------------------------------------- >> David Bussenschutt Email: D.B...@ma... >> Senior Computing Support Officer & Systems Administrator/Programmer >> Location: Griffith University. Information Technology Services >> Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 >> -------------------------------------------------------------------- > > > > -------------------------------------------------------------------- David Bussenschutt Email: D.B...@ma... Senior Computing Support Officer & Systems Administrator/Programmer Location: Griffith University. Information Technology Services Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 -------------------------------------------------------------------- |
From: Mark W. <mew...@un...> - 2000-08-15 00:46:00
|
Problem with defining a default on_error is that some errors are expected. For example in compare, the results will either be 5 for false or 6 for true (or is it vice/versa ?) mark David Bussenschutt wrote: > Bravo everyone, > > I can't add much more to the debate except to say I'm on the side of > everyone that wants to make the Net::LDAP API simpler by default, but more > powerful if desired. > > It seems to me that there are a lot of people out there doing : > Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); > > How's this for another optional feature... > > my $a = Net::LDAP->new("ldap.server.org",on_error=>die); > my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); > my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); > my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); > > Obviously, the on_error value would apply to all > binds/queries/searches/lists/reads performed > using that connection handle. > > David. > > At 03:30 PM 8/14/00 +0100, Graham Barr wrote: > >On Mon, Aug 14, 2000 at 02:45:44PM +0100, John Berthels wrote: > >> > >> > > This leads me to think that a high level interface might be useful. > Here > >> > > are a couple of suggestions on how this might differ from Net::LDAP. > >> > > > >> > > 1) The ->new method takes an optional username/password and does a > >> > > Net::LDAP->new and a ->bind. Returns object or under if anything fails. > >> > > >> > IMO, this is bad. I even want to move the connect out of new and into a > >> > separate method so that errors can be returned with more ease. > >> > >> I agree that it would be bad for the Net::LDAP API. > >> > >> However, for an 'easy to use' interface (Net::LDAP::For::Dummies) I just > >> want a handle for a connection I can do things with. If the API fails to > >> create it (for any reason) then fine, return undef and put some > >> descriptive text in $! but don't make me do 2 or 3 calls to get the > >> handle. In the common case it will 'just work'. > > > >I am all for having some way for Net::LDAP to have "common use" functions. > But > >having a separate API "for dummies" no. > > > >> > > i.e. you could write: > >> > > > >> > > #!/usr/bin/perl -w > >> > > use Net::LDAP::Cooked; # or whatever > >> > > > >> > > my $l = Net::LDAP::Cooked->new( "local.ldap.server" ) > >> > > or die( "Can't connect : $!" ); > >> > > my @staff = $l->list( "ou=staff, o=myorg" ) > >> > > or die( "Can't list staff : $!" ); > >> > > >> > I think this is coming back to having someway, other than inheritance > (maybe) > >> > to extend Net::LDAP. > >> > >> Yes. Exactly. I suspect that lots of people writing apps using Net::LDAP > >> have similar code in their apps. I want to pull that similar code into a > >> companion module for Net::LDAP for standard code reuse reasons. > > > >Right, then lets define a way to do that. > > > >> > > foreach my $person( @staff ) { > >> > > my $name = $person->get( "cn" ); > >> > > my $phone = $person->get( "telephoneNumber" ); > >> > > >> > For the ::Entry I would prefer to keep one module and have it work as > >> > expected. > >> > >> Again - expected by who? > > > >A perl programmer. > > > >> It may be possible to define an ::Entry API which > >> satisfies both camps, but if not then why not have two? The 'hard core' > >> users don't have the impact of the additional fluff and the 'just want it > >> to work' users don't have to go through additional levels of indirection > >> to get to their data. > > > >I don't think the two camps are that different in terms of > 'understandability' > >just in what level they want access to. > > > >> > And I think the above it the "expected" behaviour. Which would mean > >> > that get returns a list and we add exists. Then we split out the > >> > extra option code I added into another method, say get_nooptions > >> > which always returns a hashref > >> > >> Something like this would be fine. The only negatives for this would be > >> bloating the module and which camp was annoyed by having to use the longer > >> name :-) > > > >It would not be bloat as all of it is there now. It just seems the API > >is hard for some to understand. I belive we should be able to get a > >single API ot ::Entry that is both powerful enough for the hard core > >user and simple enough for the beginner. > > > >> > > The kinds of things going on here would be: > >> > > > >> > > - additional methods which reduce the need to construct arguments to > >> > > ->search. e.g. ->list, ->read, ->exists > >> > > >> > What are ->read and ->exist and called on what object ? > >> > >> my $entry = $ldap->read( $dn ); # Call search with scope 0 and filter > >> > >> ->exists( $dn ) is true if the entry is in the Directory. At first sight > >> seems the same as ->read( $dn ) but could be more efficient since it need > >> not pull back all attributes. Both are syntactic sugar around ->search(). > >> > >> The previous discussions around $ldap->alive() (or $ldap->ping()) fit > >> right in here too. Syntactic sugar. This is perl after all :-) > > > >Right. We need a way to add extensions. This can be done in many ways. > > > >1) Inheritance > >2) MI > >3) allowing others to import into Net::LDAP with a register module. > > > >> > > - avoid Net::LDAP::Message returns, give back arrays of > >> > > Net::LDAP::Cooked::Entry > >> > > >> > I would rather just keep one Entry object. > >> > >> Fair enough, but see above regarding two audiences. > > > >I think we can keep both happy. > > > >> > > So, is this something which would be useful to people (or would have > been > >> > > useful to them when starting with Net::LDAP) or does it just hide > too much > >> > > from the user and is likely to confuse them? > >> > > >> > Confusion is one thing that concerns me. Because you teach them one > >> > theng then they have to learn something else if they want to go > >> > beyond its boundaries. I would prefer to make the API as natural/easy > >> > as possible. > >> > >> This is a very good point. The documentation of all this would have to be > >> done very carefully. To some extent I think that this might be alleviated > >> by having the two APIs appear less related. "Oh...you're using > >> Net::LDAP::Simple. Thats OK, but to do *that* you need to read up on > >> Net::LDAP". > > > >Two documents, yes. Two APIs, I would rather not. > > > >We could just make these methods avaliable via the AUTOLOADer or have the > >user type > > > > use Net::LDAP::Extn qw(:simple); > > > >to get Net::LDAP::Extn to import some subs into Net::LDAP or just have > >Net::LDAP::Simple inherit from Net::LDAP and provide these subs. > > > >But some of these may be of use to 'hard core' users too, which is why > >I don't really like the ::Simple appraoch as we will see more and more > >::Simple being the main API. > > > >> This is why I was thinking inheritance might be bad, since it might appear > >> to mix the two. > > > >Yes. > > > >> > > If this is something worth doing, should we add bloat to Net::LDAP to > >> > > support things like this or should we create a wrapper module. > >> > > >> > bloat is something I want to avoid if possible. > >> > >> This is the main reason I was thinking about a second API, rather than > >> trying to make one API all things to all people. > >> > >> > > If we create a wrapper module should it live within the Net::LDAP > >> > > namespace or somewhere else? > >> > > >> > probably within. > >> > >> Agreed. (But its your namespace :-) > > > >But my preference is a way to provide extensions to Net::LDAP, but still > >(maybe) via a Net::LDAP method. The other option is to provide subs > >in Net::LDAP::Util > > > >> > > Should it inherit from Net::LDAP and add/override methods or should > it be > >> > > a seperate object? > >> > > >> > What would it gain from being a separate module ? I would say it > >> > should inherit, if we have it at all. I would prefer to get the current > >> > module "fixed" rather than create another module just to provide a > different > >> > API. > >> > >> My real question is whether it is better to extend Net::LDAP to make it > >> easier for novice users (or those who like convenience) or instead to > >> recognise that there are different types of users and so implement a new > >> API to meet a different need. I think Net::LDAP is nice, clean and > >> precise. I like that. I also find myself replicating wrapper functions > >> from app to app and wishing that they lived in the distribution. > > > >What kind of wrapper functions ? give some examples > > > >Well we need to define a way for people to make these things easy. > > > >> As I see it, the downsides of extending Net::LDAP are bloat and > >> conflicting design goals. The downsides of a new API are that it is a > >> little more work. > > > >And the fact you end up with two APIs and people asking questions which to > >use etc... > > > >I am sure it is possible to meet the demands of both camps without creating > >a completely new API. > > > >This email is highlighting more than one issue. Lets break it into parts and > >see what we can develop > > > > 1) Net::LDAP::Entry > > 2) Extending Net::LDAP with common methods > > > >In the case of 1) lets list what we should be able to do with an Entry and > >what a newbie would probably expect. Then compare that with what an expert > >would expect/need. It may not be that different. > > > >Graham. > > > > > > > > -------------------------------------------------------------------- > David Bussenschutt Email: D.B...@ma... > Senior Computing Support Officer & Systems Administrator/Programmer > Location: Griffith University. Information Technology Services > Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 > -------------------------------------------------------------------- |
From: David B. <d.b...@ma...> - 2000-08-14 22:55:40
|
Bravo everyone, I can't add much more to the debate except to say I'm on the side of everyone that wants to make the Net::LDAP API simpler by default, but more powerful if desired. It seems to me that there are a lot of people out there doing : Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); How's this for another optional feature... my $a = Net::LDAP->new("ldap.server.org",on_error=>die); my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); Obviously, the on_error value would apply to all binds/queries/searches/lists/reads performed using that connection handle. David. At 03:30 PM 8/14/00 +0100, Graham Barr wrote: >On Mon, Aug 14, 2000 at 02:45:44PM +0100, John Berthels wrote: >> >> > > This leads me to think that a high level interface might be useful. Here >> > > are a couple of suggestions on how this might differ from Net::LDAP. >> > > >> > > 1) The ->new method takes an optional username/password and does a >> > > Net::LDAP->new and a ->bind. Returns object or under if anything fails. >> > >> > IMO, this is bad. I even want to move the connect out of new and into a >> > separate method so that errors can be returned with more ease. >> >> I agree that it would be bad for the Net::LDAP API. >> >> However, for an 'easy to use' interface (Net::LDAP::For::Dummies) I just >> want a handle for a connection I can do things with. If the API fails to >> create it (for any reason) then fine, return undef and put some >> descriptive text in $! but don't make me do 2 or 3 calls to get the >> handle. In the common case it will 'just work'. > >I am all for having some way for Net::LDAP to have "common use" functions. But >having a separate API "for dummies" no. > >> > > i.e. you could write: >> > > >> > > #!/usr/bin/perl -w >> > > use Net::LDAP::Cooked; # or whatever >> > > >> > > my $l = Net::LDAP::Cooked->new( "local.ldap.server" ) >> > > or die( "Can't connect : $!" ); >> > > my @staff = $l->list( "ou=staff, o=myorg" ) >> > > or die( "Can't list staff : $!" ); >> > >> > I think this is coming back to having someway, other than inheritance (maybe) >> > to extend Net::LDAP. >> >> Yes. Exactly. I suspect that lots of people writing apps using Net::LDAP >> have similar code in their apps. I want to pull that similar code into a >> companion module for Net::LDAP for standard code reuse reasons. > >Right, then lets define a way to do that. > >> > > foreach my $person( @staff ) { >> > > my $name = $person->get( "cn" ); >> > > my $phone = $person->get( "telephoneNumber" ); >> > >> > For the ::Entry I would prefer to keep one module and have it work as >> > expected. >> >> Again - expected by who? > >A perl programmer. > >> It may be possible to define an ::Entry API which >> satisfies both camps, but if not then why not have two? The 'hard core' >> users don't have the impact of the additional fluff and the 'just want it >> to work' users don't have to go through additional levels of indirection >> to get to their data. > >I don't think the two camps are that different in terms of 'understandability' >just in what level they want access to. > >> > And I think the above it the "expected" behaviour. Which would mean >> > that get returns a list and we add exists. Then we split out the >> > extra option code I added into another method, say get_nooptions >> > which always returns a hashref >> >> Something like this would be fine. The only negatives for this would be >> bloating the module and which camp was annoyed by having to use the longer >> name :-) > >It would not be bloat as all of it is there now. It just seems the API >is hard for some to understand. I belive we should be able to get a >single API ot ::Entry that is both powerful enough for the hard core >user and simple enough for the beginner. > >> > > The kinds of things going on here would be: >> > > >> > > - additional methods which reduce the need to construct arguments to >> > > ->search. e.g. ->list, ->read, ->exists >> > >> > What are ->read and ->exist and called on what object ? >> >> my $entry = $ldap->read( $dn ); # Call search with scope 0 and filter >> >> ->exists( $dn ) is true if the entry is in the Directory. At first sight >> seems the same as ->read( $dn ) but could be more efficient since it need >> not pull back all attributes. Both are syntactic sugar around ->search(). >> >> The previous discussions around $ldap->alive() (or $ldap->ping()) fit >> right in here too. Syntactic sugar. This is perl after all :-) > >Right. We need a way to add extensions. This can be done in many ways. > >1) Inheritance >2) MI >3) allowing others to import into Net::LDAP with a register module. > >> > > - avoid Net::LDAP::Message returns, give back arrays of >> > > Net::LDAP::Cooked::Entry >> > >> > I would rather just keep one Entry object. >> >> Fair enough, but see above regarding two audiences. > >I think we can keep both happy. > >> > > So, is this something which would be useful to people (or would have been >> > > useful to them when starting with Net::LDAP) or does it just hide too much >> > > from the user and is likely to confuse them? >> > >> > Confusion is one thing that concerns me. Because you teach them one >> > theng then they have to learn something else if they want to go >> > beyond its boundaries. I would prefer to make the API as natural/easy >> > as possible. >> >> This is a very good point. The documentation of all this would have to be >> done very carefully. To some extent I think that this might be alleviated >> by having the two APIs appear less related. "Oh...you're using >> Net::LDAP::Simple. Thats OK, but to do *that* you need to read up on >> Net::LDAP". > >Two documents, yes. Two APIs, I would rather not. > >We could just make these methods avaliable via the AUTOLOADer or have the >user type > > use Net::LDAP::Extn qw(:simple); > >to get Net::LDAP::Extn to import some subs into Net::LDAP or just have >Net::LDAP::Simple inherit from Net::LDAP and provide these subs. > >But some of these may be of use to 'hard core' users too, which is why >I don't really like the ::Simple appraoch as we will see more and more >::Simple being the main API. > >> This is why I was thinking inheritance might be bad, since it might appear >> to mix the two. > >Yes. > >> > > If this is something worth doing, should we add bloat to Net::LDAP to >> > > support things like this or should we create a wrapper module. >> > >> > bloat is something I want to avoid if possible. >> >> This is the main reason I was thinking about a second API, rather than >> trying to make one API all things to all people. >> >> > > If we create a wrapper module should it live within the Net::LDAP >> > > namespace or somewhere else? >> > >> > probably within. >> >> Agreed. (But its your namespace :-) > >But my preference is a way to provide extensions to Net::LDAP, but still >(maybe) via a Net::LDAP method. The other option is to provide subs >in Net::LDAP::Util > >> > > Should it inherit from Net::LDAP and add/override methods or should it be >> > > a seperate object? >> > >> > What would it gain from being a separate module ? I would say it >> > should inherit, if we have it at all. I would prefer to get the current >> > module "fixed" rather than create another module just to provide a different >> > API. >> >> My real question is whether it is better to extend Net::LDAP to make it >> easier for novice users (or those who like convenience) or instead to >> recognise that there are different types of users and so implement a new >> API to meet a different need. I think Net::LDAP is nice, clean and >> precise. I like that. I also find myself replicating wrapper functions >> from app to app and wishing that they lived in the distribution. > >What kind of wrapper functions ? give some examples > >Well we need to define a way for people to make these things easy. > >> As I see it, the downsides of extending Net::LDAP are bloat and >> conflicting design goals. The downsides of a new API are that it is a >> little more work. > >And the fact you end up with two APIs and people asking questions which to >use etc... > >I am sure it is possible to meet the demands of both camps without creating >a completely new API. > >This email is highlighting more than one issue. Lets break it into parts and >see what we can develop > > 1) Net::LDAP::Entry > 2) Extending Net::LDAP with common methods > >In the case of 1) lets list what we should be able to do with an Entry and >what a newbie would probably expect. Then compare that with what an expert >would expect/need. It may not be that different. > >Graham. > > > -------------------------------------------------------------------- David Bussenschutt Email: D.B...@ma... Senior Computing Support Officer & Systems Administrator/Programmer Location: Griffith University. Information Technology Services Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 -------------------------------------------------------------------- |
From: Mark W. <mew...@un...> - 2000-08-14 21:24:14
|
> However, a: > > my $l = Net::LDAP->connect() > or die( "Can't connect to local server : $!" ); > > which returned an anonymously bound handle to localhost (takes one or two > args to override host + port) would save a few lines per script. I'd rather have this action as part of new, but I can live with this if it makes it easier on people. > > I had some wrappers around ->search(). [Some are my thoughts, some others > I've seen on this list recently] > > ->search() > If "filter" unspecified, default to "(objectclass=*)" ? No, if you don't specify a filter, it should error out. It's ok to pursue lazy programming, but not bad programming. IMHO a blank search shouldn't be allowed. > > ->list( $dn, [ @attrs ] ) > Search with "base => $dn, scope => 'one'" (and above filter) This is ok. > > ->read( $dn, [ @attrs ] ) > Search with "base => $dn, scope => 'sub'" (and above filter) ditto. > > ->exists( $dn ) > As for ->read but request minimal attributes ("1.1"?) Should be boolean. The scope set to base, attributes set to "cn" and then search. if found return 1, else return 0. > > ->ping() > As for ->exists but a constant "known good" dn...does base => "" work? base=> "" will get you the DSE in LDAP v3. But an LDAP server might not allow Access to the DSE. Perhaps we can default to the DSE, or user can specify an DN. > > > for the lazy: > > my $l = Net::LDAP->connect(); > my $cn = $l->simple_read( $dn, "commonName" ); # First of multivalue no, a read from an LDAP connection should come back with an Entry object. what you want should be a method in the Entry class. To me this makes things a lot more complicated to the new user. Perhaps I've been doing this too long :). It's beginning to look more and more like Java's JNDI API, which is designed to provide easy access to multiple directory services. While it does work, it's bleh! to work with. In particular if you have done any work with a true LDAP API like Netscape's directory SDK. You end up with double the statements and more objects than you can count. Whoever, thought that would be easier, was smoking something. So to sum it up, I'm for the following methods: 1) connect would return an anonymous binded connection to the LDAP server 2) read come back with a single entry 3) list come back with an array of all entries under a particular DN > > jb > > BTW - isn't "the one thing Larry Wall would like to change about perl5" > making the return code of 'system()' be true on success? :-) Yes, but he isn't dealing with the LDAP protocol :). Under LDAP, 0 is good. As per a discussion we had a month or so ago, it's still up in the air in the LDAP community as to whether your API's errors should be a reflection of the LDAP error codes, or seperated. > > > > > > > > > |
From: Mark W. <mew...@un...> - 2000-08-14 21:08:44
|
> > A ->diff() method would be cool: > > my $old_entry = $l->read( $dn ); > my $new_entry = $ldif->read(); > my $changes_entry = $old_entry->diff( $new_entry ); > $changes_entry->update( $l ); # Maps down to a ->modify() call I (and one other person on the list) started banging on a diff method a while back. The basics are easy. It's hard when you have a multivalued. The old entry contains: ou=people,untfs,acs and lets say the person changes jobs, but the ou update only reflects this new position change like this: ou=coe and let's say that the person who made the change wants the new entry to have an ou of: ou=people,untfs,coe how would you know in your diff to either replace the existing multi-value with the new single value, or to simply tag it on at the end? Mark |
From: Mark W. <mew...@un...> - 2000-08-14 21:03:31
|
To delete: $ldap->modify( $dn, delete => {'jpegphoto'} ); to replace: $ldap->modify( $dn, replace => {'jpegphoto' => new_binary_data} ); Mark On Mon, 14 Aug 2000, Chelsie Pentz wrote: > Hi all, > Does anyone know how to delete or replace an existing picture in the > repository? It doesn't seem to be the same syntax as modifing the other > attributes. > > Thanks, > Chelsie > > |
From: John B. <jj...@be...> - 2000-08-14 20:53:54
|
> We could just make these methods avaliable via the AUTOLOADer or have the > user type > > use Net::LDAP::Extn qw(:simple); > > to get Net::LDAP::Extn to import some subs into Net::LDAP or just have > Net::LDAP::Simple inherit from Net::LDAP and provide these subs. > > But some of these may be of use to 'hard core' users too, which is why > I don't really like the ::Simple appraoch as we will see more and more > ::Simple being the main API. OK. I suppose I shouldn't worry about pulling in too much 'fluff' until I can measure it is a slowdown. "Premature optimisation is the root of all evil". The only reason we might want to decide these things now is to avoid breaking scripts which assume everything is in by default if we later want to move it out. But as you have said previously, API is subject to change until further notice. > What kind of wrapper functions ? give some examples Well, in many cases you know you are always talking to an LDAP server on the localhost. In one particular case credentials for a privileged bind were picked up from config. So I could do: my $l = ldap_bind(); # ->new and Anon ->bind to localhost my $l = ldap_bind(1); # ->new and Priv. ->bind to localhost I had some procedural calls which took either an existing $l or undef as first arg. If the handle was undef, they did a bind/unbind in themselves in the function (failing on error). I appreciate this doesn't fit with the OO paradigm. But it was convenient. However, a: my $l = Net::LDAP->connect() or die( "Can't connect to local server : $!" ); which returned an anonymously bound handle to localhost (takes one or two args to override host + port) would save a few lines per script. I had some wrappers around ->search(). [Some are my thoughts, some others I've seen on this list recently] ->search() If "filter" unspecified, default to "(objectclass=*)" ? ->list( $dn, [ @attrs ] ) Search with "base => $dn, scope => 'one'" (and above filter) ->read( $dn, [ @attrs ] ) Search with "base => $dn, scope => 'sub'" (and above filter) ->exists( $dn ) As for ->read but request minimal attributes ("1.1"?) ->ping() As for ->exists but a constant "known good" dn...does base => "" work? for the lazy: my $l = Net::LDAP->connect(); my $cn = $l->simple_read( $dn, "commonName" ); # First of multivalue my @entries = $l->simple_search( ...normal search options ); @entries empty implies error or no results. If I care I can examine $! or something. In apps which can just quit on an LDAP error, I started to do: my $msg = $ldap->some_operation( some_args ); ldap_die_if_error( "Doing some_operation", $msg ); my $msg = $ldap->some_other_op( other_args ); ldap_die_if_error( "Doing some_other_op", $msg ); which feels icky in perl. [Maybe I just need to follow the examples and $msg->code() && die( "Doing op : " . $mesg->error() ); Ah well.] Could we tweak this with parameters to '->new' or 'use'? # # Methods die with descriptive text if any errors occur. # my $l = Net::LDAP->new( "foo", die_on_error => 1 ) or die( "Can't connect : $!" ); eval { $l->bind(); my @entries = $l->search( ... ); # do stuff with entries. empty @entries implies successful # search, empty results. $l->unbind(); } die $@ if $@; AND/OR # # Request that methods not return Net::LDAP::Message's. Instead false on # error, true on success. WARNING: Methods which return data will return # an array of Net::LDAP::Entries - an empty search result cannot be # distinguished from a failed one. (Could we set $@ ? Does this not work # with async ops?) What would non-search methods do? # my $l = Net::LDAP->new( "foo", return_data_not_message => 1 ); $l->bind() or die( "Can't bind : $!" ); my @entries = $l->list( "ou=staff, o=myorg" ); die( "Well, no data or bad connection : $!" ) unless @entries; > This email is highlighting more than one issue. Lets break it into parts and > see what we can develop > > 1) Net::LDAP::Entry OK. I'll chase ::Entry in a different mail. > 2) Extending Net::LDAP with common methods The above covers my thoughts on this topic. I'd appreciate some views from the list here, since if its just me I'll stop bothering you all, write my own layer and keep it to myself. :-) regards, jb BTW - isn't "the one thing Larry Wall would like to change about perl5" making the return code of 'system()' be true on success? :-) |