Browse files

*** empty log message ***

  • Loading branch information...
1 parent 7aac9ed commit d35350c2912df1ac29a9893c466c6b1eac7a33b0 @gbarr gbarr committed Jul 30, 2000
View
30 CREDITS
@@ -0,0 +1,30 @@
+Although the Net::LDAP module was originally written by Graham Barr it
+has grown far beyond initial expectations and scope. In fact it has gone
+far beyond a lot of things.
+
+As Net::LDAP has grown into the perl-ldap distribution credit can no
+longer be given to any single individual, but instead belongs to a
+group of people who have contributed. Some more than others, but whos
+counting :)
+
+
+ ---------------
+ CAST AND CREW
+ ---------------
+
+To give due honor to those who have made perl-ldap what is is today, here
+are some of the people who have contributed, either in code, documentaion
+or just ideas/feedback. If I have missed anyone, please let me know.
+
+Graham Barr <gbarr@pobox.com>
+Russell Fulton <r.fulton@auckland.ac.nz>
+Rusty Biggs <rgb@ticnet.com>
+Clif Harden <c-harden@ti.com>
+Chris Ridd <Chris.Ridd@messagingdirect.com>
+Mark Wilcox <mewilcox@unt.edu>
+Robbie Allen <rallen@cisco.com>
+Bryan Thale <thale@rsch.comm.mot.com>
+Jim Harle <harle@usna.edu>
+Kurt D. Zeilenga <Kurt@OpenLDAP.org>
+Simon Wilcox <Simon_Wilcox@williamslea.com>
+
View
51 ChangeLog
@@ -1,3 +1,54 @@
+Change 553 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ More doc updates
+
+Change 552 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Net::LDAP::Entry
+ - Added some ability to handle options
+
+Change 551 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Net::LDAP::Control::*
+ - Added lots of docs
+ Net::LDAP::Control::VLV
+ - Added methods for moving the page
+
+Change 550 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Net::LDAP::Constant
+ - Added OID for Matched Values control
+
+Change 549 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Net::LDAP
+ - Modified bind() to require an auth argument if passed arguments
+ and also refuse to assect an empty password for password =>
+ anon binding must be dome with noauth => or anonymous =>
+
+Change 548 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ bin/ldapsearch.PL
+ - Use URI::ldap instead of URI::RUL::ldap
+ bin/ldapsearch.PL, bin/ldapdelete.PL, bin/ldapmodrdn.PL
+ - Made -wc clean
+
+Change 547 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Moved Convert::ASN1 into PREREQ_PM
+
+Change 546 on 2000/07/30 by <gbarr@pobox.com> (Graham Barr)
+
+ Added CREDITS and ISNTALL
+
+Change 545 on 2000/07/25 by <gbarr@pobox.com> (Graham Barr)
+
+ contrib/ updates from Clif Harden.
+
+Change 544 on 2000/07/04 by <gbarr@pobox.com> (Graham Barr)
+
+ Add C<use Net::LDAP::Control> to all controls
+
Change 543 on 2000/06/28 by <gbarr@pobox.com> (Graham Barr)
Net::LDAP::DSML
View
43 INSTALL
@@ -0,0 +1,43 @@
+If you are on a system where you can run the Makefile.PL and use make,
+then the package can be installed using the normal MakeMaker process,
+that is
+
+ gunzip perl-ldap-*.**.tar.gz
+ tar xvf perl-ldap-*.**
+ cd perl-ldap-*.**
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+If you are on a system where this is not possible you will need to perform
+the following, after ensuring that any dependant libraries are installed
+(see README)
+
+ perl -V
+
+This will output information about your perl installation. Near the end
+of this you will see something like
+
+ @INC:
+ /usr/local/lib/perl5/5.6.0/i686-linux
+ /usr/local/lib/perl5/5.6.0
+ /usr/local/lib/perl5/site_perl/5.6.0/i686-linux
+ /usr/local/lib/perl5/site_perl/5.6.0
+ /usr/local/lib/perl5/site_perl
+ .
+
+You need to find the site_perl directory with the perl version specified,
+in this case it is /usr/local/lib/perl5/site_perl/5.6.0
+
+You then need to copy the contents of the lib/ directory from the
+distribution with the equivalent of the following for your platform.
+
+ gunzip perl-ldap-*.**.tar.gz
+ tar xvf perl-ldap-*.**
+ cd perl-ldap-*.**/lib
+ cp -r * /usr/local/lib/perl5/site_perl/5.6.0
+
+To use the basics of perl-ldap there is only one dependancy,
+Convert::ASN1, all others are optional depending on if you want to use
+a given functionality. See the README file for a list.
View
6 MANIFEST
@@ -1,4 +1,6 @@
+CREDITS
ChangeLog
+INSTALL
MANIFEST
Makefile.PL
README
@@ -8,17 +10,16 @@ bin/ldapdelete.PL
bin/ldapmodrdn.PL
bin/ldapsearch.PL
contrib/checkauth.pl
+contrib/dot.tklkup
contrib/examples
contrib/isMember.pl
contrib/isMember.readme
contrib/printMembers.pl
contrib/printMembers.readme
contrib/schema
contrib/schema.README
-contrib/schema.tklkup
contrib/tklkup
contrib/tklkup.README
-contrib/tklkup.tklkup
data/00-cmp2.ldif
data/00-in.ldif
data/50-cmp.ldif
@@ -96,7 +97,6 @@ lib/Net/LDAP/Util.pm
lib/Net/LDAPS.pm
perl-ldap.ppd
t/00ldif-entry.t
-t/01url.t
t/02filter.t
t/50populate.t
t/51search.t
View
15 Makefile.PL
@@ -1,5 +1,5 @@
# The -*- perl -*- script writes the Makefile for perl-ldap
-# $Id: Makefile.PL,v 1.3 2000/06/29 06:07:51 gbarr Exp $
+# $Id: Makefile.PL,v 1.4 2000/07/30 21:03:50 gbarr Exp $
use 5.004;
use ExtUtils::MakeMaker;
@@ -48,11 +48,7 @@ sub check_module {
$ok;
}
-print "\nChecking for installed modules\n\n";
-
-check_module('Convert::ASN1',0.07) or print <<"EDQ","\n";
-Convert::ASN1 version 0.07 or later is essential for perl-ldap
-EDQ
+print "\nChecking for OPTIONAL modules\n\n";
check_module('URI',1.02) && check_module('URI::ldap',1.10) or print <<"EDQ","\n";
The URI::ldap module is needed ONLY IF you want to parse LDAP URLs
@@ -72,9 +68,9 @@ EDQ
print "\n",<<"EDQ","\n" if $missing;
****************************************************************************
-You are missing some modules that MAY be needed for the modules in perl-ldap
-to work correctly. Read the above messages and download any required
-modules from http://www.perl.com/CPAN
+You are missing some modules that MAY be needed for some of the features
+in perl-ldap to work correctly. Read the above messages and download
+any required modules from http://www.perl.com/CPAN
****************************************************************************
EDQ
@@ -97,6 +93,7 @@ WriteMakefile(
EXE_FILES => $opt_s ? [ values %PL_FILES ] : [],
PL_FILES => \%PL_FILES,
clean => {FILES => 'temp'},
+ PREREQ_PM => { 'Convert::ASN1' => 0.07 },
@ppd,
);
View
16 README
@@ -1,5 +1,9 @@
perl-ldap - A Client interface to LDAP servers
+Copyright (c) 1997-2000 Graham Barr. All rights reserved.
+This package is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
*******************************************************************************
This code should be considered very much as work-in-progress.
Any part of this release could be subject to change.
@@ -14,19 +18,17 @@ To subscribe goto
*******************************************************************************
-Copyright (c) 1997-2000 Graham Barr. All rights reserved.
-This package is free software; you can redistribute it and/or
-modify it under the same terms as Perl itself.
-
For the latest information see http://perl-ldap.sourceforge.net/
QUICK START GUIDE:
perl-ldap uses the following modules/distributions.
- Convert::ASN1 - required
- URI::ldap - optional, needed for URL parsing
- Digest::MD5 - optional, needed for SASL CRAM-MD5 auth
+ Convert::ASN1 - required
+ URI::ldap - optional, needed for URL parsing
+ Digest::MD5 - optional, needed for SASL CRAM-MD5 auth
+ IO::Socket::SSL - optional, needed for Net::LDAPS
+ XML::Parser - optional, needed for Net::LDAP::DSML
First ensure the above modules/distributions are installed then
build/test/install Net::LDAP by doing
View
8 bin/ldapdelete.PL
@@ -17,7 +17,7 @@ open OUT, ">$script" or die "open for writing $script: $!";
print OUT <<"!GROK!THIS!";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
- if \$running_under_some_shell;
+ if \$running_under_some_shell && \$running_under_some_shell;
!GROK!THIS!
# In the following, perl variables are not expanded during extraction.
@@ -28,11 +28,11 @@ print OUT <<'!NO!SUBS!';
#
# c.ridd@isode.com
#
-# $Id: ldapdelete.PL,v 1.1 2000/05/03 12:28:26 gbarr Exp $
+# $Id: ldapdelete.PL,v 1.2 2000/07/30 21:03:50 gbarr Exp $
#
# $Log: ldapdelete.PL,v $
-# Revision 1.1 2000/05/03 12:28:26 gbarr
-# Initial revision
+# Revision 1.2 2000/07/30 21:03:50 gbarr
+# *** empty log message ***
#
# Revision 1.1 1999/01/11 08:38:46 cjr
# Initial revision
View
8 bin/ldapmodrdn.PL
@@ -17,7 +17,7 @@ open OUT, ">$script" or die "open for writing $script: $!";
print OUT <<"!GROK!THIS!";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
- if \$running_under_some_shell;
+ if \$running_under_some_shell && \$running_under_some_shell;
!GROK!THIS!
# In the following, perl variables are not expanded during extraction.
@@ -28,11 +28,11 @@ print OUT <<'!NO!SUBS!';
#
# c.ridd@isode.com
#
-# $Id: ldapmodrdn.PL,v 1.1 2000/05/03 12:28:26 gbarr Exp $
+# $Id: ldapmodrdn.PL,v 1.2 2000/07/30 21:03:50 gbarr Exp $
#
# $Log: ldapmodrdn.PL,v $
-# Revision 1.1 2000/05/03 12:28:26 gbarr
-# Initial revision
+# Revision 1.2 2000/07/30 21:03:50 gbarr
+# *** empty log message ***
#
# Revision 1.1 1999/01/11 08:39:12 cjr
# Initial revision
View
23 bin/ldapsearch.PL
@@ -17,7 +17,7 @@ open OUT, ">$script" or die "open for writing $script: $!";
print OUT <<"!GROK!THIS!";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
- if \$running_under_some_shell;
+ if \$running_under_some_shell && \$running_under_some_shell;
!GROK!THIS!
# In the following, perl variables are not expanded during extraction.
@@ -28,11 +28,11 @@ print OUT <<'!NO!SUBS!';
#
# c.ridd@isode.com
#
-# $Id: ldapsearch.PL,v 1.1 2000/05/03 12:28:29 gbarr Exp $
+# $Id: ldapsearch.PL,v 1.2 2000/07/30 21:03:50 gbarr Exp $
#
# $Log: ldapsearch.PL,v $
-# Revision 1.1 2000/05/03 12:28:29 gbarr
-# Initial revision
+# Revision 1.2 2000/07/30 21:03:50 gbarr
+# *** empty log message ***
#
# Revision 1.3 1999/01/11 08:33:34 cjr
# Revised for 0.09 API
@@ -47,7 +47,7 @@ print OUT <<'!NO!SUBS!';
use strict;
use Carp;
use Net::LDAP;
-use URI::URL::ldap;
+use URI::ldap;
use Net::LDAP::LDIF;
use vars qw($opt_n $opt_v $opt_t $opt_u $opt_A $opt_B $opt_L $opt_R $opt_d
$opt_F $opt_S $opt_f $opt_b $opt_b $opt_s $opt_a $opt_l $opt_z
@@ -60,7 +60,7 @@ my %derefs = ( 'never' => 0, 'search' => 1, 'find' => 2, 'always' => 3 );
# We only print attributes that we know are text
# This stuff is in lieu of a workable Schema module
-my @textsyntax = qw(
+my @textsyntax = grep /^\w/, (<<'EOS' =~ /(#.*|\S+)/g); # qw() with comments
# RFC 2251
modifiersName modifyTimestamp
creatorsName createTimestamp
@@ -90,7 +90,7 @@ my @textsyntax = qw(
collectivePostalAddress collectiveTelephoneNumber
collectiveFacsimileTelephoneNumber
supportedLDAPVersion
- );
+EOS
my %istext; # keys are canonicalised attribute names.
foreach (@textsyntax) { $istext{lc($_)} = 1; };
@@ -148,7 +148,7 @@ my $filter = shift || die "$0: missing filter\n";
# other server, unless the referral indicates it should. This prevents you
# revealing your password (etc) to random servers.
-my $initial = URI::URL::ldap->new;
+my $initial = URI->new("ldap:");
$initial->host($opt_h);
$initial->dn($opt_b);
$initial->port($opt_p) if $opt_p;
@@ -163,7 +163,7 @@ my $ldif = Net::LDAP::LDIF->new if $opt_L;
my $first_record = 1;
while (@urls) {
- my $url = URI::URL::ldap->new(shift @urls);
+ my $url = URI::ldap->new(shift @urls);
my %exts = $url->extensions;
my $ldap;
my %openargs;
@@ -207,7 +207,10 @@ while (@urls) {
$searchargs{base} = $opt_b if $opt_b;
$searchargs{base} = $url->dn if $url->dn;
$searchargs{scope} = $opt_s if $opt_s;
- $searchargs{scope} = $url->scope if $url->scope;
+# Version of URI::ldap in URI-1.07 will always return a scope
+# waiting for next release so we can use ->_scope which will
+# return undef when there is no scope specified in the URL
+# $searchargs{scope} = $url->scope if $url->scope;
$searchargs{scope} = $scopes{$searchargs{scope}} if $searchargs{scope};
$searchargs{deref} = $derefs{$opt_a} if $opt_a;
$searchargs{sizelimit} = $opt_z if $opt_z;
View
37 contrib/dot.tklkup
@@ -0,0 +1,37 @@
+#
+# Initialization file for tklkp and schema. This file should reside
+# in the user home directory as .tklkup.
+#
+# Set up which side you want the Attributes pane to be displayed
+# on.
+#
+hand: left
+#
+#
+# Set up the additional search attributes you want listed on
+# the Select Additional Attributes button.
+#
+attribute: uid
+attribute: cn
+attribute: sn
+attribute: rfc822mailbox
+attribute: uidNumber
+attribute: gidNumber
+attribute: telephonenumber
+attribute: facsimiletelephonenumber
+attribute: givenname
+attribute: fullname
+attribute: firstname
+#
+# Set up the Directory Servers you want listed on
+# the Select Directory Server button.
+#
+server: ldap.switchboard.com
+server: ldap.umich.edu
+#
+# Set up the directory search base(s) you want listed on
+# the Select Search Base button.
+#
+base: ou=Information Technology Division, ou=People, o=University of Michigan, c=US
+base: ou=Alumni Association, ou=People, o=University of Michigan, c=US
+
View
338 contrib/tklkup
@@ -12,7 +12,7 @@
# module and the PERL TK module.
# Both modules are available from the CPAN.org system.
#
-# $Id: tklkup,v 1.1 2000/05/03 12:28:40 gbarr Exp $
+# $Id: tklkup,v 1.2 2000/07/30 21:03:50 gbarr Exp $
#
# Purpose: This program is designed to retrieve data from a LDAP
# directory and display on the graphical user interface
@@ -21,7 +21,30 @@
#
# Revisions:
# $Log: tklkup,v $
-# Revision 1.1 2000/05/03 12:28:40 gbarr
+# Revision 1.2 2000/07/30 21:03:50 gbarr
+# *** empty log message ***
+#
+# Revision 1.6 2000/06/18 04:08:16 clif
+# Changed several pod commands to enhance the lookup
+# and feel of the pod documentation.
+#
+# Revision 1.5 2000/06/08 01:12:27 clif
+# Correct wording in the pod documentation.
+#
+# Revision 1.4 2000/05/27 21:34:12 clif
+# Added the README.tklkup file as a internal pod document.
+#
+# Revision 1.3 2000/05/27 18:35:38 clif
+# Removed leading dashes form Net::LDAP options. These dashes had been
+# depricated.
+#
+# Revision 1.2 2000/05/27 18:29:35 clif
+# Added radio button for selection of version 2 or 3 ldap. Version
+# 3 was maded the default version.
+# Added code to make the binary user certificate data base64 encoded
+# for display purposes.
+#
+# Revision 1.1 2000/01/23 03:00:20 clif
# Initial revision
#
#
@@ -30,6 +53,254 @@
#
#
+=head1 NAME
+
+tklkup - A script to do LDAP directory lookups.
+
+=head1 SYNOPSIS
+
+
+This script is used to lookup information from a LDAP
+directory server. It is GUI based with several buttons for
+selecting directory servers, search bases, and attributes.
+
+This script has been tested on Solaris and RedHat 6.0 Linux,
+but should work with any system that has PERL and the required
+modules installed in it.
+
+There are 2 files associated with the tklkup program in this
+tar file; dot.tklkup, and tklkup.
+
+About the files.
+
+=over 4
+
+=item dot.tklkup
+
+dot.tklkup - This is the initialization file that should be put
+into each users home directory as I<.tklkup>.
+
+This file will have to be setup properly before the user
+can expect the tklkup script to work properly. The odds of this
+initialization file being setup correctly for anyone is I<ZERO>.
+However the script can be run with this file to get a feel
+for how the script will look.
+
+It allows the user to customize how tklkup will look for them.
+If the .tklkup files does not exist in a users home
+directory the program has a set of built-in defaults
+that it will use.
+
+To be used this file must have user read permission.
+
+There are 4 commands that can be used with this file;
+hand, attribute, server, and base.
+
+ hand -> values: left or right. Defines where the
+ attribute label box will be place.
+
+ attribute -> attribute upon which the data search will be
+ based. One attribute per line.
+
+ server -> name of the directory server that you wish
+ to conduct the data search. One server per line.
+
+ base -> directory search base from which to start the
+ data search. One search base per line.
+
+-------------------------------------------------------------------
+
+=item tklkup
+
+tklkup - PERL executable file.
+
+You may need to change the first line of the PERL tklkup script
+to point to your file pathname of perl.
+
+When executed tklkup will display a window on your
+computer. The graphical user interface, GUI, has
+several sections to it.
+
+Exit button. At the top of the GUI is the "Exit"
+button. When a mouse click is done on the "Exit" button
+the program will terminate.
+
+The SET LDAP VERSION "RadioButton" diamond will select the
+LDAP protocol version. When selected the "RadioButton"
+diamond will be red in color. This indicates that the
+ldap connection will use the version I<3> protocol. To use
+ldap version I<2> protocol press the "RadioButton" diamond
+so that it becomes a gray color.
+
+The SELECT DIRECTORY SERVER button will activate a
+drop down menu. From the menu the user will select the
+"RadioButton" that corresponds to the directory server the
+user wishes to use. When selected the "RadioButton" diamond
+will turn red in color. This menu is a designed to be a
+"I<tear off>" menu, selecting the "---------------" line will
+cause the pull down menu to become a separate window that
+is still somewhat controlled by the GUI. The
+DIRECTORY SERVER text box will display the directory name
+that is selected. If the GUI is icon-ed or exited, the tear
+off window will follow the actions of the GUI. All other
+actions like moving or closing just the torn off window
+must be done by the user's window manager.
+
+The SELECT SEARCH BASE button will activate a
+drop down menu. From the menu the user will select the
+"RadioButton" that corresponds to the search base the
+user wishes to use in the directory search. When selected
+the "RadioButton" diamond will turn red in color. The
+DIRECTORY SEARCH BASE text box will display the directory
+search base that is selected. This menu is a designed to
+be a "I<tear off>" menu, selecting the "---------------" line
+will cause the pull down menu to become a separate window
+that is still somewhat controlled by the GUI. If the GUI
+is icon-ed or exited, the tear off window will follow the
+actions of the GUI. All other actions like moving or
+closing just the torn off window must be done by the
+user's window manager.
+
+The SELECT ADDITIONAL ATTRIBUTES button will activate a
+drop down menu. From the menu the user will select the
+"RadioButton" that corresponds to the attribute the
+user wishes to use in the directory search. When selected
+the "RadioButton" diamond will turn red in color. This menu
+is a designed to be a "I<tear off>" menu, selecting the
+"---------------" line will cause the pull down menu to
+become a separate window that is still somewhat controlled
+by the GUI. If the GUI is icon-ed or exited, the tear off
+window will follow the actions of the GUI. All other
+actions like moving or closing just the torn off window
+must be done by the user's window manager.
+
+The Clear Attribute Data button will clear out the text
+that appears in the Attribute Data text box.
+
+The Attribute Data text box is where the user will enter
+the data to be searched for.
+
+The Clear Data button will clear out the text that
+appears in the Directory Data text box.
+
+The Directory Data text box is where the results of the
+directory search will be displayed. With the cursor
+in the Directory Data text box you have access to additional
+functions when you depress the mouse "action" button.
+When the "action" mouse button is depressed a small text box
+with 4 additional functions will be displayed inside the
+Directory Data text box. These 4 functions are;
+
+ File -> This function exits the program. You can not edit
+ the Directory Data text box because it is created
+ as a read only text box.
+
+ Edit -> This function gives the user 3 additional functions;
+ Copy -> I do not know what this function does.
+ Select All -> Highlights/Selects all of the text in
+ the Directory Data text box.
+ Unselect All -> Unselects all of the text in
+ the Directory Data text box.
+ Select/Unselect are used in-conjunction with the
+ Copy function.
+
+ Search -> This function gives the user 4 additional
+ functions.
+ Find, Find Next, Find Previous -> These functions
+ find text in the Directory Data text box.
+ Replace -> This function allows you to replace the
+ text that is selected. However this is just
+ a fake replacement as you can not edit the
+ Directory Data text box because it is created
+ as a read only text box.
+
+ View -> This function gives the user 3 additional
+ functions.
+ Goto Line -> When selected will prompt the
+ user for a line number, the line number being
+ the line number the user wishes to see.
+ What Line -> When selected will tell the user
+ what line number the cursor is on.
+ Wrap -> When selected will prompt the user
+ to choose how to do line wrapping in the
+ Directory Data text box.
+
+
+Associated with the Directory Data text box is the "RadioButton"
+that determines how often the data in the directory text
+box is cleared. If the "RadioButton" is selected, colored
+red, the directory data text box will be cleared out before
+each directory query. If the "RadioButton" is not selected
+the directory data text box will NOT be cleared out until
+the Clear Data button in clicked or the CLEAR DIRECTORY DATA
+ON EACH QUERY "RadioButton" is selected.
+
+-------------------------------------------------------------------
+
+=item REQUIREMENTS
+
+
+To use this program you will need the following.
+
+
+At least PERL version 5.004. You can get a stable version of PERL
+from the following URl;
+ http://cpan.org/src/index.html
+
+Perl Tk800.015 module. You can get this from the following URl;
+ ftp://ftp.duke.edu/pub/CPAN/modules/by-module/Tk/
+
+Perl LDAP module. You can get this from the following URl;
+ ftp://ftp.duke.edu/pub/CPAN/modules/by-module/Net/
+
+Depending on the modules loaded in your PERL system, you may need to
+load the following 2 PERL modules.
+
+Perl Convert-Berr module. You can get this from the following URl;
+ ftp://ftp.duke.edu/pub/CPAN/modules/by-module/Convert/
+
+Perl Digest-MD5 module. You can get this from the following URl;
+ ftp://ftp.duke.edu/pub/CPAN/modules/by-module/MD5/
+
+Bundled inside each PERL module is instructions on how to install the
+module into your PERL system.
+
+-------------------------------------------------------------------
+
+=item INSTALLING THE SCRIPT
+
+Install the tklkup script anywhere you wish, I suggest
+/usr/local/bin/tklkup.
+
+Install the dot.tklkup file in each users home directory
+as .tklkup. It is possible to use a central copy and
+create a link in the user home directory to the central copy.
+
+-------------------------------------------------------------------
+
+=back
+
+Since the script is in PERL, feel free to modify it if it does not
+meet your needs. This is one of the main reasons I did it in PERL.
+If you make an addition to the code that you feel other individuals
+could use let me know about it. I may incorporate your code
+into my code.
+
+=head1 AUTHOR
+
+Clif Harden <charde@utdallas.edu>
+If you find any errors in the code please let me know at
+charden@utdallas.edu.
+
+=head1 COPYRIGHT
+
+Copyright (c) 1999-2000 Clif Harden. All rights reserved. This program is
+free software; you can redistribute it and/or modify it under the same
+terms as Perl itself.
+
+=cut
+
+use MIME::Base64;
use Net::LDAP qw(:all);
use Net::LDAP::Filter;
use Net::LDAP::Util qw(ldap_error_name ldap_error_text);
@@ -48,6 +319,8 @@ my $adata = "";
my $uid = "";
my $info = "";
my $slist;
+my $setVersion;
+my $clear;
#--------------------------------------------------------
# Handle the command line parameter(s)
@@ -237,6 +510,17 @@ $slist->pack(-fill => "both", -expand => 1 );
$slist->insert("end", $LDAP_SERVER);
#
+# Create a LDAP version Radiobutton that will set up variable
+# setVersion to set the LDAP version before each directory query.
+#
+
+$setVersion = $sframe -> Checkbutton(-text => "SET LDAP VERSION, LDAP V3 DEFAULT", -variable => \$setVersion, -onvalue => 1, -offvalue => 0 )
+ -> pack(-anchor => sw );
+
+$setVersion->select();
+
+
+#
# Create search base list box.
#
@@ -541,9 +825,20 @@ sub search
{
my $error;
+my $version;
if ( $clear ) { &clear(); }
+if ( $setVersion )
+{
+$version = 3;
+}
+else
+{
+$version = 2;
+}
+
+
my %opt = (
'd' => 0
);
@@ -587,7 +882,7 @@ if ( $error == 1 )
}
my $ldap = new Net::LDAP($LDAP_SERVER,
- -timeout => 1,
+ timeout => 1,
) or $error = 1;
if ( $error == 1 )
@@ -596,7 +891,7 @@ if ( $error == 1 )
return;
}
-$ldap->ldapbind(-password => "", -dn => "") or $error = 1;
+$ldap->ldapbind(password => "", dn => "", version => $version ) or $error = 1;
if ( $error == 1 )
{
@@ -608,10 +903,10 @@ my $wanted = [ map { defined($ldap2ph{$_}) ? ($_)
: defined($ph2ldap{$_}) ? ($ph2ldap{$_}) : ()} @wanted ];
$mesg = $ldap->search(
- -base => $LDAP_SEARCH_BASE,
- -filter => $f,
- -attrs => $wanted,
- -callback => \&print_entry,
+ base => $LDAP_SEARCH_BASE,
+ filter => $f,
+ attrs => $wanted,
+ callback => \&print_entry,
) or $error = 1;
@@ -683,16 +978,39 @@ sub print_entry {
#
# Format data and print data into List Box
#
+ if ( /;binary$/ )
+ {
+ $encoded = encode_base64($a);
+ $dstring = sprintf "%${max}s: Binary data on next line(s), base64 encoded.\n%s\n\n",$_,$encoded;
+ $list->insert("end", "$dstring");
+ }
+ else
+ {
$dstring = sprintf "%${max}s: %s\n",$_,$a;
$list->insert("end", "$dstring");
+ }
+
+# $dstring = sprintf "%${max}s: %s\n",$_,$a;
+# $list->insert("end", "$dstring");
}
}
else {
#
# Format data and print data into List Box
#
- $dstring = sprintf "%${max}s: %s\n",$_,$attr;
- $list->insert("end", "$dstring");
+ if ( /;binary$/ )
+ {
+ $encoded = encode_base64($attr);
+ $dstring = sprintf "%${max}s: Binary data on next line(s), base64 encoded.\n%s\n\n",$_,$encoded;
+ $list->insert("end", "$dstring");
+ }
+ else
+ {
+ $dstring = sprintf "%${max}s: %s\n",$_,$attr;
+ $list->insert("end", "$dstring");
+ }
+# $dstring = sprintf "%${max}s: %s\n",$_,$attr;
+# $list->insert("end", "$dstring");
}
}
}
View
13 lib/Net/LDAP.pm
@@ -19,6 +19,7 @@ use Net::LDAP::Constant qw(LDAP_SUCCESS
LDAP_FILTER_ERROR
LDAP_LOCAL_ERROR
LDAP_PARAM_ERROR
+ LDAP_INAPPROPRIATE_AUTH
);
$VERSION = 0.19_01;
@@ -147,10 +148,13 @@ my %ptype = qw(
kerberos41 krbv41
kerberos42 krbv42
sasl sasl
+ noauth anon
+ anonymous anon
);
sub bind {
my $ldap = shift;
+ my $acnt = @_;
my $arg = &_dn_options;
require Net::LDAP::Bind;
@@ -166,16 +170,21 @@ sub bind {
version => $ldap->version,
);
- my($auth_type,$passwd) = (simple => "");
+ my($auth_type,$passwd) = $acnt ? () : (simple => '');
keys %ptype; # Reset iterator
while(my($param,$type) = each %ptype) {
if (exists $arg->{$param}) {
- ($auth_type,$passwd) = ($type,$arg->{$param});
+ ($auth_type,$passwd) = $type eq 'anon' ? (simple => '') : ($type,$arg->{$param});
+ return $mesg->set_error(LDAP_INAPPROPRIATE_AUTH, "No password, did you mean noauth or anonymous ?")
+ if $type eq 'simple' and $passwd eq '';
last;
}
}
+ return $mesg->set_error(LDAP_INAPPROPRIATE_AUTH, "No AUTH supplied")
+ unless $auth_type;
+
if ($auth_type eq 'sasl') {
# if ($version < 3) {
# # FIXME: Need V3 for SASL
View
6 lib/Net/LDAP.pod
@@ -213,8 +213,10 @@ is assumed.
=item noauth
+=item anonymous
+
Bind without any password, the value passed with this option is ignored. This
-is the default if no password option is given.
+is the default if no arguments are given.
=item password
@@ -636,6 +638,6 @@ terms as Perl itself.
=for html <hr>
-I<$Id: LDAP.pod,v 1.3 2000/05/09 16:09:49 gbarr Exp $>
+I<$Id: LDAP.pod,v 1.4 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
2 lib/Net/LDAP/Constant.pm
@@ -93,6 +93,8 @@ sub LDAP_CONTROL_VLVRESPONSE () { "2.16.840.1.113730.3.4.10" }
sub LDAP_CONTROL_PAGED () { "1.2.840.113556.1.4.319" }
+sub LDAP_CONTROL_MATCHEDVALS () { "1.2.826.0.1.3344810.2.2" }
+
sub LDAP_CONTROL_MANAGEDSAIT () { "2.16.840.1.113730.3.4.2" }
sub LDAP_CONTROL_PERSISTENTSEARCH () { "2.16.840.1.113730.3.4.3" }
sub LDAP_CONTROL_ENTRYCHANGE () { "2.16.840.1.113730.3.4.7" }
View
157 lib/Net/LDAP/Control.pm
@@ -1,4 +1,4 @@
-# $Id: Control.pm,v 1.3 2000/05/22 20:59:50 gbarr Exp $
+# $Id: Control.pm,v 1.4 2000/07/30 21:03:50 gbarr Exp $
# Copyright (c) 1999-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
@@ -7,18 +7,19 @@ package Net::LDAP::Control;
use Net::LDAP::Constant qw(/^LDAP_CONTROL/);
use vars qw($VERSION);
+use strict;
-$VERSION = "0.03";
+$VERSION = "0.04";
my %Pkg2Type = (
- Net::LDAP::Control::Sort => LDAP_CONTROL_SORTREQUEST,
- Net::LDAP::Control::SortResult => LDAP_CONTROL_SORTRESULT,
+ 'Net::LDAP::Control::Sort' => LDAP_CONTROL_SORTREQUEST,
+ 'Net::LDAP::Control::SortResult' => LDAP_CONTROL_SORTRESULT,
- Net::LDAP::Control::VLV => LDAP_CONTROL_VLVREQUEST,
- Net::LDAP::Control::VLVResponse => LDAP_CONTROL_VLVRESPONSE,
+ 'Net::LDAP::Control::VLV' => LDAP_CONTROL_VLVREQUEST,
+ 'Net::LDAP::Control::VLVResponse' => LDAP_CONTROL_VLVRESPONSE,
- Net::LDAP::Control::Paged => LDAP_CONTROL_PAGED,
+ 'Net::LDAP::Control::Paged' => LDAP_CONTROL_PAGED,
#LDAP_CONTROL_MANAGEDSAIT
#LDAP_CONTROL_PERSISTENTSEARCH
@@ -34,6 +35,13 @@ my %Type2Pkg = reverse %Pkg2Type;
sub register {
my($class,$oid) = @_;
+
+ require Carp and Carp::croak("$oid is already registered to $Type2Pkg{$oid}")
+ if exists $Type2Pkg{$oid} and $Type2Pkg{$oid} ne $class;
+
+ require Carp and Carp::croak("$class is already registered to $Pkg2Type{$class}")
+ if exists $Pkg2Type{$class} and $Pkg2Type{$class} ne $oid;
+
$Type2Pkg{$oid} = $class;
$Pkg2Type{$class} = $oid;
}
@@ -51,9 +59,9 @@ sub new {
return bless \%args;
}
- if ($pkg eq __PACKAGE__ && exists $Type2Pkg{$args{type}}) {
+ if ($pkg eq __PACKAGE__ and exists $Type2Pkg{$args{type}}) {
$pkg = $Type2Pkg{$args{type}};
- eval "require $pkg";
+ eval "require $pkg" or die $@;
}
delete $args{error};
@@ -67,8 +75,10 @@ sub from_asn {
my $asn = shift;
my $class = ref($self) || $self;
- $class = $Resgistry{$asn->{type}}
- if ($class eq __PACKAGE__ && exists $Resgistry{$asn->{type}});
+ if ($class eq __PACKAGE__ and exists $Type2Pkg{$asn->{type}}) {
+ $class = $Type2Pkg{$asn->{type}};
+ eval "require $class" or die $@;
+ }
delete $asn->{error};
@@ -78,13 +88,23 @@ sub from_asn {
sub to_asn {
my $self = shift;
$self->value; # Ensure value is there
- $self->{critical} = 0 unless exists $self->{critical};
+ delete $self->{critical} unless $self->{critical};
$self;
}
-sub type { shift->{type} }
-sub critical { shift->{critical} || 0 }
-sub value { shift->{value} || undef }
+sub critical {
+ my $self = shift;
+ $self->{critical} = shift if @_;
+ $self->{critical} || 0;
+}
+
+sub value {
+ my $self = shift;
+ $self->{value} = shift if @_;
+ $self->{value} || undef
+}
+
+sub type { shift->{type} }
sub valid { ! exists shift->{error} }
sub error { shift->{error} }
sub init { shift }
@@ -101,6 +121,7 @@ Net::LDAP::Control - LDAPv3 control object base class
=head1 SYNOPSIS
use Net::LDAP::Control;
+ use Net::LDAP::Constant qw( LDAP_CONTROL_MATCHEDVALS );
$ctrl = Net::LDAP::Control->new(
type => "1.2.3.4",
@@ -110,61 +131,135 @@ Net::LDAP::Control - LDAPv3 control object base class
$mesg = $ldap->search( @args, control => [ $ctrl ]);
+ $ctrl = Net::LDAP::Control->new( type => LDAP_CONTROL_MATCHEDVALS );
+
=head1 DESCRIPTION
C<Net::LDAP::Control> is a base-class for LDAPv3 control objects.
+=cut
+
+##
+## Need more blurb in here about controls
+##
+
=head1 CONSTRUCTORS
=over 4
=item new ARGS
+ARGS is a list of name/value pairs, valid arguments are.
+
=over 4
+=item critical
+
+A booloean value, if TRUE and the control is unrecognized by the server or
+is inappropriate for the requested operation then the server will return
+an error and the operation will not be performed.
+
+If FALSE and the control is unrecognized by the server or
+is inappropriate for the requested operation then the server will ignore
+the control and perform the requested operation as if the control was
+not given.
+
+If absent, FALSE is assume.
+
=item type
+A dotted-decimal representation of an OBJECT IDENTIFIER which
+uniquely identifies the control. This prevents conflicts between
+control names.
+
+This may be ommitted if the contructor is being called on a sub-class of
+Net::LDAP::Control which has registered to be associated with an OID.
+If the contructor is being called on the Net::LDAP::Control
+package, then this argument must be given. If the given OID has been
+registered by a package, then the returned object will be of the type
+registered to handle that OID.
+
=item value
-=item critical
+Optional information associated with the control. It's format is specific
+to the particular control.
=back
-=item from_asn HASHREF
+=item from_asn ASN
+
+ASN is a HASH reference, normally extracted from a PDU. It will contain
+a C<type> element and optionally C<critical> and C<value> elements. On
+return ASN will be blessed into a package. If C<type> is a registered
+OID, then ASN will be blessed into the registered package, if not then ASN
+will be blessed into Net::LDAP::Control.
+
+This constructor is used internally by Net::LDAP and assumes that HASH
+passed contains a valid control. It should be used with B<caution>.
=back
=head1 METHODS
-Net::LDAP::Control provides the following methods in the base class.
+In addition to the methods listed below, each of the named parameters
+to C<new> is also avaliable as a method. C<type> will return the OID of
+the control object. C<value> and C<critical> are set/get methods and will
+return the current value for each attribute if called without arguments,
+but may also be called with arguments to set new values.
=over 4
+=item error
+
+If there has been an error returns a description of the error, otherwise it will
+return C<undef>
+
=item init
-init will be called as the last step in both contructors. What it does will depend
+C<init> will be called as the last step in both contructors. What it does will depend
on the sub-class. It must always return the object.
-=item error
+=item register OID
-Returns true if there has been an error.
+C<register> is provided for sub-class implementors. It should be called as a class method
+on a sub-class of Net::LDAP::Control with the OID that the class will handle. Net::LDAP::Control
+will remember this class and OID pair and use it in the following
+situations.
-=item valid
+=over 4
+
+=item *
+
+C<new> is called as a class method on the Net::LDAP::Control package and OID is passed
+as the type. The returned object will be blessed into the package that registered
+the OID.
-Returns true if the object is valid and can be encoded.
+=item *
-=item type [ OID ]
+C<new> is called as a class method on a registered package and the C<type> is not
+specified. The C<type> will be set to the OID registered by that package.
-=item value [ VALUE ]
+=item *
-=item critical [ CRITICAL ]
+C<from_asn> is called to construct an object from ASN. The returned object will be
+blessed into the package which was registered to handle the OID in the ASN.
+
+=back
=item to_asn
-Returns the asn structure for encoding. This method will be called by L<Net::LDAP|Net::LDAP>
-when the control is used. The base class implementaion of this method will call the C<value>
-method without arguments to allow a sub-class to encode it's value. Sub-classes should not need
-to override this method.
+Returns a structure suitable for passing to Convert::ASN1 for
+encoding. This method will be called by L<Net::LDAP|Net::LDAP> when the
+control is used.
+
+The base class implementation of this method will call the C<value> method
+without arguments to allow a sub-class to encode it's value. Sub-classes
+should not need to override this method.
+
+=item valid
+
+Returns true if the object is valid and can be encoded. The default implementation
+for this method is to return TRUE if there is no error, but sub-classes may override that.
=back
@@ -187,6 +282,6 @@ terms as Perl itself.
=for html <hr>
-I<$Id: Control.pm,v 1.3 2000/05/22 20:59:50 gbarr Exp $>
+I<$Id: Control.pm,v 1.4 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
107 lib/Net/LDAP/Control/Paged.pm
@@ -1,11 +1,12 @@
-# $Id: Paged.pm,v 1.2 2000/05/22 20:59:50 gbarr Exp $
+# $Id: Paged.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $
# Copyright (c) 2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package Net::LDAP::Control::Paged;
use vars qw(@ISA $VERSION);
+use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
$VERSION = "0.01";
@@ -58,3 +59,107 @@ sub value {
1;
+__END__
+
+=head1 NAME
+
+Net::LDAP::Control::Paged - LDAPv3 Paged results control object
+
+=head1 SYNOPSIS
+
+ use Net::LDAP;
+ use Net::LDAP::Control::Paged;
+ use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
+
+ $ldap = Net::LDAP->new( "ldap.mydomain.eg" );
+
+ $page = Net::LDAP::Control::Paged->new( size => 100 );
+
+ @args = ( base => "cn=subnets,cn=sites,cn=configuration,$BASE_DN",
+ scope => "subtree",
+ filter => "(objectClass=subnet)",
+ callback => \&process_entry, # Call this sub for each entry
+ control => [ $page ],
+ );
+
+ my $cookie;
+ while(1) {
+ # Perform search
+ my $mesg = $ldap->search( @args );
+
+ # Only continue on LDAP_SUCCESS
+ $mesg->code and last;
+
+ # Get cookie from paged control
+ my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last;
+ $cookie = $resp->cookie or last;
+
+ # Set cookie in paged control
+ $page->cookie($cookie);
+ }
+
+ if ($cookie) {
+ # We had an abnormal exit, so let the server know we do not want any more
+ $page->cookie($cookie);
+ $page->size(0);
+ $ldap->search( @args );
+ }
+
+=head1 DESCRIPTION
+
+C<Net::LDAP::Control::Paged> provides an interface for the creation and manipulatrion
+of objects that represent the C<pagedResultsControl> as described by RFC-2696.
+
+=head1 CONSTRUCTOR ARGUMENTS
+
+In addition to the constructor arguments described in
+L<Net::LDAP::Control|Net::LDAP::Control> the following are provided.
+
+=over 4
+
+=item cookie
+
+The value to use as the cookie. This is not normally set when an object is
+created, but is set from the cookie value returned bu the server. This associates
+a search with a previous search, so the server knows to return the page
+of entries following the entries it returned the previous time.
+
+=item size
+
+The page size that is required. This is the maximum number of entries that the
+server will return to the search request.
+
+=back
+
+=head1 METHODS
+
+As with L<Net::LDAP::Control|Net::LDAP::Control> each constructor argument
+described above is also avaliable as a method on the object which will
+return the current value for the attribute if called without an argument,
+and set a new value for the attribute if called with an argument.
+
+=head1 SEE ALSO
+
+L<Net::LDAP|Net::LDAP>,
+L<Net::LDAP::Control|Net::LDAP::Control>,
+http://info.internet.isi.edu/in-notes/rfc/files/rfc2696.txt
+
+=head1 AUTHOR
+
+Graham Barr <gbarr@pobox.com>
+
+Please report any bugs, or post any suggestions, to the perl-ldap mailing list
+<perl-ldap-dev@lists.sourceforge.net>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2000 Graham Barr. All rights reserved. This program is
+free software; you can redistribute it and/or modify it under the same
+terms as Perl itself.
+
+=for html <hr>
+
+I<$Id: Paged.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
+
+=cut
+
View
42 lib/Net/LDAP/Control/Sort.pm
@@ -1,11 +1,12 @@
-# $Id: Sort.pm,v 1.3 2000/05/22 20:59:50 gbarr Exp $
+# $Id: Sort.pm,v 1.4 2000/07/30 21:03:50 gbarr Exp $
# Copyright (c) 1999-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package Net::LDAP::Control::Sort;
use vars qw(@ISA $VERSION);
+use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
$VERSION = "0.01";
@@ -142,38 +143,37 @@ include a sort result control. This control is handled by L<Net::LDAP::Control::
=item order
-C<order> may be a string or a reference to an array. If it is a string it is split
-on whitespace, otherwise the contents of the array is used.
+A string which defines how entries may be sorted. It consists of
+multiple directives, spearated by whitespace. Each directive describes how
+to sort entries using a single attribute. If two entries have identical
+attributes, then the next directive in the list is used.
-Each element in the array specifies a sorting order as follows
+Each directive specifies a sorting order as follows
-attributeType:orderingRule
The leading C<-> is optional, and if present indicates that the sorting order should
-be reversed. attributeType is the attribute name to sort by. orderingRule is optional and
-indicates the rule to use for the sort and should be valid for the given attributeType.
+be reversed. C<attributeType> is the attribute name to sort by. C<orderingRule> is optional and
+indicates the rule to use for the sort and should be valid for the given C<attributeType>.
Any one attributeType should only appear once in the sorting list.
-=back
-
+B<Examples>
-=head1 METHODS
+ "cn" sort by cn using the default ordering rule for the cn attribute
+ "-cn" sort by cn using the reverse of the default ordering rule
+ "age cn" sort by age first, then by cn using the default ordering rules
+ "cn:1.2.3.4" sort by cn using the ordering rule defined as 1.2.3.4
-Net::LDAP::Control::Sort provides the following methods in addition to
-those defined by L<Net::LDAP::Control|Net::LDAP::Control>
-
-=over 4
-
-=item order [ ORDER ]
+=back
-ORDER may be a string or a list. If it is a string then it is split on whitespace
-and treated as if a list had been passed. See C<order> above for a description
-of the format for each element.
-If no arguments are passed then a list is returned of the current ordering elements.
+=head1 METHODS
-=back
+As with L<Net::LDAP::Control|Net::LDAP::Control> each constructor argument
+described above is also avaliable as a method on the object which will
+return the current value for the attribute if called without an argument,
+and set a new value for the attribute if called with an argument.
=head1 SEE ALSO
@@ -196,6 +196,6 @@ terms as Perl itself.
=for html <hr>
-I<$Id: Sort.pm,v 1.3 2000/05/22 20:59:50 gbarr Exp $>
+I<$Id: Sort.pm,v 1.4 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
51 lib/Net/LDAP/Control/SortResult.pm
@@ -1,11 +1,12 @@
-# $Id: SortResult.pm,v 1.2 2000/05/09 16:09:49 gbarr Exp $
+# $Id: SortResult.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $
# Copyright (c) 1999-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package Net::LDAP::Control::SortResult;
use Net::LDAP::ASN qw(SortResult);
+use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
@@ -56,7 +57,8 @@ Net::LDAP::Control::SortResult - LDAPv3 sort result control object
=head1 SYNOPSIS
use Net::LDAP::Control::Sort;
- use Net::LDAP::Constant qw( LDAP_CONTROL_SORTRESULT );
+ use Net::LDAP::Constant qw(LDAP_CONTROL_SORTRESULT);
+ use Net::LDAP::Util qw(ldap_error_name);
$sort = Net::LDAP::Control::Sort->new(
order => "cn -age"
@@ -66,7 +68,20 @@ Net::LDAP::Control::SortResult - LDAPv3 sort result control object
($resp) = $mesg->control( LDAP_CONTROL_SORTRESULT );
- print "Results are sorted\n" if $resp and !$resp->result;
+ if ($resp) {
+ if ($resp->result) {
+ my $attr = $resp->attr;
+ print "Problem sorting, ",ldap_error_name($resp->result);
+ print " ($attr)" if $attr;
+ print "\n";
+ }
+ else {
+ print "Results are sorted\n";
+ }
+ }
+ else {
+ print "Server does not support sorting\n";
+ }
=head1 DESCRIPTION
@@ -75,36 +90,36 @@ It provides a class for manipulating the LDAP sort request control C<1.2.840.113
A sort result control will be returned by the server in response to a search with a sort
control. If a sort result control is not returned then the user may assume that the
-server does not support sorting and the resutls are not sorted.
+server does not support sorting and the results are not sorted.
=head1 CONSTRUCTOR ARGUMENTS
=over 4
-=item result
-
=item attr
+If C<result> indicates that there was a problem with sorting and that problem was
+due to one of the attributes specified in the sort control. C<attr> is set to
+the name of the attribute causing the problem.
-=back
-
-
-=head1 METHODS
+=item result
-Net::LDAP::Control::SortResult provides the following methods in addition to
-those defined by L<Net::LDAP::Control|Net::LDAP::Control>
+This is the result code that describes if the sort operation was sucessful. If will
+be one of the result codes describes below.
-=over 4
+=back
-=item result [ RESULT ]
-=item attr [ ATTR ]
+=head1 METHODS
-=back
+As with L<Net::LDAP::Control|Net::LDAP::Control> each constructor argument
+described above is also avaliable as a method on the object which will
+return the current value for the attribute if called without an argument,
+and set a new value for the attribute if called with an argument.
=head1 RESULT CODES
-Possible results from a sort request are listed below. See L<Net::LDAP::Constant> for
+Possible results from a sort request are listed below. See L<Net::LDAP::Constant|Net::LDAP::Constant> for
a definition of each.
=over 4
@@ -154,6 +169,6 @@ terms as Perl itself.
=for html <hr>
-I<$Id: SortResult.pm,v 1.2 2000/05/09 16:09:49 gbarr Exp $>
+I<$Id: SortResult.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
274 lib/Net/LDAP/Control/VLV.pm
@@ -1,11 +1,12 @@
-# $Id: VLV.pm,v 1.2 2000/05/22 20:59:50 gbarr Exp $
+# $Id: VLV.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $
# Copyright (c) 2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package Net::LDAP::Control::VLV;
use vars qw(@ISA $VERSION);
+use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
$VERSION = "0.01";
@@ -69,7 +70,9 @@ sub content {
}
return $self->{asn}{byoffset}{contentCount} = shift;
}
- exists $self->{asn}{byoffset} and $self->{asn}{byoffset}{contentCount};
+ exists $self->{asn}{byoffset}
+ ? $self->{asn}{byoffset}{contentCount}
+ : undef;
}
sub assert {
@@ -79,7 +82,9 @@ sub assert {
delete $self->{asn}{byoffset};
return $self->{asn}{assertionValue} = shift;
}
- exists $self->{asn}{assertionValue} and $self->{asn}{assertionValue};
+ exists $self->{asn}{assertionValue}
+ ? $self->{asn}{assertionValue}
+ : undef;
}
sub context {
@@ -119,7 +124,9 @@ sub offset {
}
return $self->{asn}{byoffset}{offset} = shift;
}
- exists $self->{asn}{byoffset} and $self->{asn}{byoffset}{offset};
+ exists $self->{asn}{byoffset}
+ ? $self->{asn}{byoffset}{offset}
+ : undef;
}
sub value {
@@ -138,50 +145,259 @@ sub value {
: $self->{value} = $VirtualListViewRequest->encode($self->{asn});
}
-
-1;
-
-__END__
-
-
-##
-## These are not finished
-##
-
-sub up {
+sub scroll {
my $self = shift;
- my $n = shift or return;
+ my $n = shift;
my $asn = $self->{asn};
-
- return unless exists $asn->{byoffset};
-
- if (($asn->{byoffset}{offset} -= $n) < 1) {
- $asn->{byoffset}{offset} = 1;
+ my $byoffset = $asn->{byoffset}
+ or return undef;
+ my $offset = $byoffset->{offset} + $n;
+ my $content;
+
+ if ($offset < 1) {
+ $asn->{afterCount} += $asn->{beforeCount};
+ $asn->{beforeCount} = 0;
+ $offset = $byoffset->{offset} = 1;
}
- if (($asn->{byoffset}{offset} - $asn->{beforeCount}) < 1) {
+ elsif ($byoffset->{content} and $asn->{afterCount}+$offset >$byoffset->{content}) {
+ if ($offset > $byoffset->{content}) {
+ $offset = $byoffset->{offset} = $byoffset->{content};
+ $asn->{beforeCount} += $asn->{afterCount};
+ $asn->{afterCount} = 0;
+ }
+ else {
+ my $tmp = $byoffset->{content} - $offset;
+ $asn->{beforeCount} += $tmp;
+ $asn->{afterCount} -= $tmp;
+ $byoffset->{offset} = $offset;
+ }
+ }
+ else {
+ $byoffset->{offset} = $offset;
}
+ $offset;
}
-sub down {
+sub scroll_page {
my $self = shift;
- my $n = shift or return;
+ my $n = shift;
my $asn = $self->{asn};
+ my $page_size = $asn->{beforeCount} + $asn->{afterCount} + 1;
- return unless exists $asn->{byoffset};
+ $self->scroll( $page_size * $n);
}
-sub page_up {
+sub start {
my $self = shift;
my $asn = $self->{asn};
- $self->up( $asn->{beforeCount} + $asn->{afterCount} + 1);
+ $asn->{afterCount} += $asn->{beforeCount};
+ $asn->{beforeCount} = 0;
+ $self->offset(1);
}
-sub page_down {
+sub end {
my $self = shift;
my $asn = $self->{asn};
- $self->down( $asn->{beforeCount} + $asn->{afterCount} + 1);
+ my $content = $self->content || 0;
+
+ $asn->{beforeCount} += $asn->{afterCount};
+ $asn->{afterCount} = 0;
+ $self->offset($content);
}
1;
+__END__
+
+=head1 NAME
+
+Net::LDAP::Control::VLV - LDAPv3 Virtual List View control object
+
+=head1 SYNOPSIS
+
+ use Net::LDAP;
+ use Net::LDAP::Control::VLV;
+ use Net::LDAP::Constant qw( LDAP_CONTROL_VLVRESPONSE );
+
+ $ldap = Net::LDAP->new( "ldap.mydomain.eg" );
+
+ # Get the first 20 entries
+ $vlv = Net::LDAP::Control::VLV->new(
+ before => 0, # No entries from before target entry
+ after => 19, # 19 entries after target entry
+ content => 0, # List size unknown
+ offset => 1, # Target entry is the first
+ );
+ $sort = Net::LDAP::Control::Sort->new( sort => 'cn' );
+
+ @args = ( base => "o=Ace Industry, c=us",
+ scope => "subtree",
+ filter => "(objectClass=inetOrgPerson)",
+ callback => \&process_entry, # Call this sub for each entry
+ control => [ $vlv, $sort ],
+ );
+
+ $mesg = $ldap->search( @args );
+
+ # Get VLV response control
+ ($resp) = $mesg->control( LDAP_CONTROL_VLVRESPONSE ) or die;
+ $vlv->response( $resp );
+
+ # Set the control to get the last 20 entries
+ $vlv->end;
+
+ $mesg = $ldap->search( @args );
+
+ # Get VLV response control
+ ($resp) = $mesg->control( LDAP_CONTROL_VLVRESPONSE ) or die;
+ $vlv->response( $resp );
+
+ # Now get the previous page
+ $vlv->scroll_page( -1 );
+
+ $mesg = $ldap->search( @args );
+
+ # Get VLV response control
+ ($resp) = $mesg->control( LDAP_CONTROL_VLVRESPONSE ) or die;
+ $vlv->response( $resp );
+
+ # Now page with first entry starting with "B" in the middle
+ $vlv->before(9); # Change page to show 9 before
+ $vlv->after(10); # Change page to show 10 after
+ $vlv->assert("B"); # assert "B"
+
+ $mesg = $ldap->search( @args );
+
+=head1 DESCRIPTION
+
+C<Net::LDAP::Control::VLV> provides an interface for the creation and
+manipulation of objects that represent the Virtual List View as described
+by draft-ietf-ldapext-ldapv3-vlv-03.txt.
+
+When using a Virtual List View control in a search, it must be accompanied by a sort
+control. See L<Net::LDAP::Control::Sort|Net::LDAP::Control::Sort>
+
+=cut
+
+##
+## Need some blurb here to describe the VLV control. Maybe extract some simple
+## describtion from the draft RFC
+##
+
+=head1 CONSTRUCTOR ARGUMENTS
+
+In addition to the constructor arguments described in
+L<Net::LDAP::Control|Net::LDAP::Control> the following are provided.
+
+=over 4
+
+=item after
+
+Set the number of entries the server should return from the list after
+the target entry.
+
+=item assert
+
+Set the assertion value user to locate the target entry. This value should
+be a legal value to compare with the first attribute in the sort control
+that is passed with the VLV control. The target entry is the first entry
+in the list which is greater than or equal the assert value.
+
+=item before
+
+Set the number of entries the server should return from the list before
+the target entry.
+
+=item content
+
+Set the number of entries in the list. On the first search this value
+should be set to zero. On subsequent searches it should be set to the
+length of the list, as returned by the server in the VLVResponse control.
+
+=item context
+
+Set the context identifier. On the first search this value should be
+set to zero. On subsequent searches it should be set to the context
+value returned by the server in the VLVResponse control.
+
+=item offset
+
+Set the offset of the target entry.
+
+=back
+
+=head2 METHODS
+
+As with L<Net::LDAP::Control|Net::LDAP::Control> each constructor argument
+described above is also avaliable as a method on the object which will
+return the current value for the attribute if called without an argument,
+and set a new value for the attribute if called with an argument.
+
+The C<offset> and C<assert> attributes are mutually exclusive. Setting
+one or the other will cause previous values set by the other to
+be forgotten. The C<content> attribute is also associated with the
+C<offset> attribute, so setting C<assert> will cause any C<content>
+value to be forgotten.
+
+=over 4
+
+=item end
+
+Set the target entry to the end of the list. This method will change the C<before>
+and C<after> attributes so that the target entry is the last in the page.
+
+=item response VLV_RESPONSE
+
+Set the attributes in the control as per VLV_RESPONSE. VLV_RESPONSE should be a control
+of type L<Net::LDAP::Control::VLVResponse|Net::LDAP::Control::VLVResponse> returned
+from the server. C<response> will populate the C<context>, C<offset> and C<content>
+attibutes of the control with the values from VLV_RESPONSE. Because this sets the
+C<offset> attribute, any previous setting of the C<assert> attribute will be forgotten.
+
+=item scroll NUM
+
+Move the target entry by NUM entries. A positive NUM will move the target entry towards
+the end of the list and a negative NUM will move the target entry towards the
+start of the list. Returns the index of the new target entry, or C<undef> if the current target
+is identified by an assertion.
+
+C<scroll> may change the C<before> and C<after> attributes if the scroll value would
+cause the page to go off either end of the list. But the page size will be maintained.
+
+=item scroll_page NUM
+
+Scroll by NUM pages. This method simple calculates the current page size and calls
+C<scroll> with C<NUM * $page_size>
+
+=item start
+
+Set the target entry to the start of the list. This method will change the C<before> and C<after>
+attributes to the the target entry is the first entry in the page.
+
+=back
+
+=head1 SEE ALSO
+
+L<Net::LDAP|Net::LDAP>,
+L<Net::LDAP::Control|Net::LDAP::Control>,
+L<Net::LDAP::Control::Sort|Net::LDAP::Control::Sort>,
+L<Net::LDAP::Control::VLVResponse|Net::LDAP::Control::VLVResponse>
+
+=head1 AUTHOR
+
+Graham Barr <gbarr@pobox.com>
+
+Please report any bugs, or post any suggestions, to the perl-ldap mailing list
+<perl-ldap-dev@lists.sourceforge.net>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2000 Graham Barr. All rights reserved. This program is
+free software; you can redistribute it and/or modify it under the same
+terms as Perl itself.
+
+=for html <hr>
+
+I<$Id: VLV.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
+
View
126 lib/Net/LDAP/Control/VLVResponse.pm
@@ -5,6 +5,7 @@
package Net::LDAP::Control::VLVResponse;
use vars qw(@ISA $VERSION);
+use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
$VERSION = "0.01";
@@ -21,17 +22,10 @@ sub init {
else {
my $asn = $self->{asn} = {};
- $asn->{contentCount} = $self->{content} || 0;
- $asn->{afterCount} = $self->{position} || 0;
- if (exists $self->{assert}) {
- $asn->{assertionValue} = $self->{assert};
- }
- else {
- $asn->{byoffset} = {
- offset => $self->{offset} || 0,
- contentCount => $self->{content} || 0
- };
- }
+ $asn->{targetPosition} = $self->{target} || 0;
+ $asn->{contentCount} = $self->{content} || 0;
+ $asn->{virtualListViewResult} = $self->{result} || 0;
+ $asn->{context} = $self->{context} || undef;
}
$self;
@@ -92,3 +86,113 @@ sub value {
1;
+__END__
+
+=head1 NAME
+
+Net::LDAP::Control::VLVResponse -- LDAPv3 Virtual List View server response
+
+=head1 SYNOPSIS
+
+See L<Net::LDAP::Control::VLV|Net::LDAP::Control::VLV>
+
+=head1 DESCRIPTION
+
+C<Net::LDAP::Control::VLVResponse> is a sub-class of L<Net::LDAP::Control|Net::LDAP::Control>.
+It provides a class for manipulating the LDAP Virtual List View Response control
+C<>
+
+If the server supports Virtual List Views, then the response from a search operation will
+include a VLVResponse control.
+
+=head1 CONSTRUCTOR ARGUMENTS
+
+In addition to the constructor arguments described in
+L<Net::LDAP::Control|Net::LDAP::Control> the following are provided.
+
+=over 4
+
+=item content
+
+An estimate of the number of entries in the complete list. This value should
+be used in any subsequent Virtual List View control using the same list.
+
+=item context
+
+An arbitary value which is used to associate subsequent requests with the
+request which this control is a response for. This value should be copied
+by the client into the Virtual List View control for any subsequent
+search that uses the same list.
+
+=item result
+
+A result code indicating the result of the Virtual List View request. This
+may be any of the codes listed below.
+
+=item target
+
+The list offset of the target entry.
+
+=back
+
+=head1 METHODS
+
+As with L<Net::LDAP::Control|Net::LDAP::Control> each constructor argument
+described above is also avaliable as a method on the object which will
+return the current value for the attribute if called without an argument,
+and set a new value for the attribute if called with an argument.
+
+=head1 RESULT CODES
+
+Possible results from a sort request are listed below. See L<Net::LDAP::Constant|Net::LDAP::Constant> for
+a definition of each.
+
+=over 4
+
+=item LDAP_SUCCESS
+
+=item LDAP_OPERATIONS_ERROR
+
+=item LDAP_TIMELIMIT_EXCEEDED
+
+=item LDAP_ADMIN_LIMIT_EXCEEDED
+
+=item LDAP_INSUFFICIENT_ACCESS
+
+=item LDAP_BUSY
+
+=item LDAP_UNWILLING_TO_PERFORM
+
+=item LDAP_OTHER
+
+=item LDAP_SORT_CONTROL_MISSING
+
+=item LDAP_INDEX_RANGE_ERROR
+
+=back
+
+=head1 SEE ALSO
+
+L<Net::LDAP|Net::LDAP>,
+L<Net::LDAP::Control|Net::LDAP::Control>,
+http://info.internet.isi.edu/in-notes/rfc/files/rfc2696.txt
+
+=head1 AUTHOR
+
+Graham Barr <gbarr@pobox.com>
+
+Please report any bugs, or post any suggestions, to the perl-ldap mailing list
+<perl-ldap-dev@lists.sourceforge.net>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2000 Graham Barr. All rights reserved. This program is
+free software; you can redistribute it and/or modify it under the same
+terms as Perl itself.
+
+=for html <hr>
+
+I<$Id: VLVResponse.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
+
+=cut
+
View
44 lib/Net/LDAP/Entry.pm
@@ -22,8 +22,7 @@ sub new {
# Build attrs cache, created when needed
sub _build_attrs {
- my $self = shift;
- $self->{attrs} = { map { (lc($_->{type}),$_->{vals}) } @{$self->{asn}{attributes}} };
+ +{ map { (lc($_->{type}),$_->{vals}) } @{$_[0]->{asn}{attributes}} };
}
# If we are passed an ASN structure we really do nothing
@@ -67,14 +66,21 @@ sub get_attribute {
sub get {
my $self = shift;
my $type = lc(shift);
+ my %opt = @_;
- my $attrs = $self->{attrs} || _build_attrs($self);
-
- return unless exists $attrs->{$type};
+ if ($opt{alloptions}) {
+ my %ret = map {
+ $_->{type} =~ /^\Q$type\E(.*)/ ? (lc($1), $_->{vals}) : ()
+ } @{$self->{asn}{attributes}};
+ return %ret ? \%ret : undef;
+ }
+ else {
+ foreach my $attr (@{$self->{asn}{attributes}}) {
+ return $attr->{vals} if $type eq lc $attr->{type};
+ }
+ }
- wantarray
- ? @{$attrs->{$type}}
- : $attrs->{$type};
+ return;
}
@@ -90,7 +96,7 @@ sub changetype {
sub add {
my $self = shift;
my $cmd = $self->{'changetype'} eq 'modify' ? [] : undef;
- my $attrs = $self->{attrs} || _build_attrs($self);
+ my $attrs = $self->{attrs} ||= _build_attrs($self);
while (my($type,$val) = splice(@_,0,2)) {
$type = lc $type;
@@ -112,7 +118,7 @@ sub add {
sub replace {
my $self = shift;
my $cmd = $self->{'changetype'} eq 'modify' ? [] : undef;
- my $attrs = $self->{attrs} || _build_attrs($self);
+ my $attrs = $self->{attrs} ||= _build_attrs($self);
while(my($type, $val) = splice(@_,0,2)) {
$type = lc $type;
@@ -153,7 +159,7 @@ sub delete {
}
my $cmd = $self->{'changetype'} eq 'modify' ? [] : undef;
- my $attrs = $self->{attrs} || _build_attrs($self);
+ my $attrs = $self->{attrs} ||= _build_attrs($self);
while(my($type,$val) = splice(@_,0,2)) {
$type = lc $type;
@@ -214,7 +220,7 @@ sub dump {
my($attr,$val);
my $l = 0;
- for (keys %{ $self->{attrs} || _build_attrs($self) }) {
+ for (keys %{ $self->{attrs} ||= _build_attrs($self) }) {
$l = length if length > $l;
}
@@ -235,8 +241,18 @@ sub dump {
sub attributes {
my $self = shift;
- carp("attributes called with arguments") if @_;
- map { $_->{type} } @{$self->{asn}{attributes}};
+ my %opt = @_;
+
+ if ($opt{nooptions}) {
+ my %done;
+ return map {
+ $_->{type} =~ /^([^;]+)/;
+ $done{lc $1}++ ? () : ($1);
+ } @{$self->{asn}{attributes}};
+ }
+ else {
+ return map { $_->{type} } @{$self->{asn}{attributes}};
+ }
}
sub asn {
View
56 lib/Net/LDAP/Entry.pod
@@ -53,6 +53,14 @@ LDIF file with the L<Net::LDAP::LDIF|Net::LDAP::LDIF> module.
=head1 CONSTRUCTOR
+=over 4
+
+=item new
+
+Create a new entry object with the changetype set to C<'add'>
+
+=back
+
=head1 METHODS
=over 4
@@ -117,16 +125,58 @@ update will be sent back to the same server.
The result will be an object of type L<Net::LDAP::Message|Net::LDAP::Message> as returned
by the add, modify or delete method called on CLIENT.
-=item attributes
+=item attributes ( [ OPTIONS ] )
Return a list of attributes that this entry has.
-=item get ( ATTR )
+OPTIONS is a list of name/value pairs, valid options are :-
+
+=over 4
+
+=item nooptions
+
+If TRUE, return a list of the attribute names excluding any options. For example for the entry
+
+ name: Graham Barr
+ name;en-us: Bob
+ jpeg;binary: **binary data**
+
+the return list would be C<( 'name', 'jpeg' )>.
+
+=back
+
+=item get ( ATTR [, OPTIONS ] )
Get the values for the attribute ATTR. The result will be a reference
to an array, if that attribute exists. If the attribute does not exist
the C<undef> will be returned.
+OPTIONS is a list of name/value pairs, valid options are :-
+
+=over 4
+
+=item alloptions
+
+If TRUE then the result will be a hash reference. The keys of the hash
+will be the options and the hash value will be the values for those attributes.
+For example if an entry had
+
+ name: Graham Barr
+ name;en-us: Bob
+
+Then a get for attribute "name" with alloptions set would return
+
+ {
+ '' => [ 'Graham Barr' ],
+ ';en-us' => [ 'Bob' ]
+ }
+
+=back
+
+B<NOTE>: In the interest of performance the array references returned by C<get>
+are references to structures held inside the entry object. These values
+should B<not> be modified directly.
+
=item changetype ( [ TYPE ] )
If called without arguments it returns the type of operation that would
@@ -177,6 +227,6 @@ terms as Perl itself.
=for html <hr>
-I<$Id: Entry.pod,v 1.2 2000/05/09 16:09:49 gbarr Exp $>
+I<$Id: Entry.pod,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
6 lib/Net/LDAP/RFC.pod
@@ -41,11 +41,15 @@ http://info.internet.isi.edu/in-notes/rfc/files/rfc2255.txt
http://info.internet.isi.edu/in-notes/rfc/files/rfc2256.txt
+=item RFC-2696 - LDAP Control Extension for Simple Paged Results Manipulation
+
+http://info.internet.isi.edu/in-notes/rfc/files/rfc2696.txt
+
=back
=for html <hr>
-I<$Id: RFC.pod,v 1.1 2000/05/03 12:29:15 gbarr Exp $>
+I<$Id: RFC.pod,v 1.2 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
8 lib/Net/LDAP/Util.pm
@@ -10,7 +10,11 @@ Net::LDAP::Util - Utility functions
=head1 SYNOPSIS
- use Net::LDAP::Util qw(ldap_error_text);
+ use Net::LDAP::Util qw(ldap_error_text ldap_error_name);
+
+ $mesg = $ldap->search( .... );
+
+ die "Error ",ldap_error_name($mesg->code) if $mesg->code;
=head1 DESCRIPTION
@@ -109,7 +113,7 @@ terms as Perl itself.
=for html <hr>
-I<$Id: Util.pm,v 1.2 2000/05/22 20:59:50 gbarr Exp $>
+I<$Id: Util.pm,v 1.3 2000/07/30 21:03:50 gbarr Exp $>
=cut
View
30 t/00ldif-entry.t
@@ -5,7 +5,7 @@ BEGIN {
}
-print "1..2\n";
+print "1..8\n";
use Net::LDAP::LDIF;
@@ -37,3 +37,31 @@ $ldif->write_cmd($e);
$ldif->done;
print "not " if compare($cmpfile,$outfile);
print "ok 2\n";
+
+$e->add('name' => 'Graham Barr');
+$e->add('name;en-us' => 'Bob');
+
+print "not " unless join(":",sort $e->attributes) eq