Added Net::LDAP to the distribution for easier installs.
This commit is contained in:
parent
f51b335d74
commit
223c014813
47 changed files with 15060 additions and 2 deletions
556
lib/Net/LDAP/Examples.pod
Normal file
556
lib/Net/LDAP/Examples.pod
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
=head1 NAME
|
||||
|
||||
Net::LDAP::Examples - PERL LDAP by Example
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The following examples are of course PERL code, found to work
|
||||
with the Net::LDAP modules.
|
||||
|
||||
The intent of this document is to give the reader a I<cut and paste>
|
||||
jump start to getting an LDAP application working.
|
||||
|
||||
Below you will find snippets of code that should work as-is with only
|
||||
a small amount of work to correct any variable assignments and LDAP
|
||||
specifics, e.g. Distinguished Name Syntax, related to the user's
|
||||
own implementation.
|
||||
|
||||
The I<S>tandard I<O>perating I<P>roceedure that is followed here is:
|
||||
|
||||
=over 8
|
||||
|
||||
=item 1 Package - use Net::LDAP
|
||||
|
||||
=item 2 Initialization - new
|
||||
|
||||
=item 3 Binding - bind
|
||||
|
||||
=item 4 Operation - add modify moddn search
|
||||
|
||||
=item 4.1 Processing - displaying data from a search
|
||||
|
||||
=item 5 Error - displaying error information
|
||||
|
||||
=item 6 Unbinding - unbind
|
||||
|
||||
=back
|
||||
|
||||
Look to each of these for a snippet of code to meet your needs.
|
||||
|
||||
|
||||
B<What is not covered in these examples at this time:>
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<abandon> and I<compare> methods
|
||||
|
||||
=item I<callback> subroutines
|
||||
|
||||
=back
|
||||
|
||||
=head1 CODE
|
||||
|
||||
=head2 PACKAGE - Definitions
|
||||
|
||||
use Net::LDAP qw(:all); # use for all code
|
||||
|
||||
use Net::LDAP::Util qw(ldap_error_name
|
||||
ldap_error_text) ; # use for Error handling
|
||||
|
||||
|
||||
=head2 INITIALIZING
|
||||
|
||||
$ldap = Net::LDAP->new("yourLDAPhost.yourCompany.com") or die "$@";
|
||||
|
||||
=head2 BINDING
|
||||
|
||||
$mesg = $ldap->bind( version => 3 ); # use for searches
|
||||
|
||||
$mesg = $ldap->bind("$userToAuthenticate",
|
||||
password => "$passwd",
|
||||
version => 3 ); # use for changes/edits
|
||||
|
||||
# see your LDAP administrator for information concerning the
|
||||
# user authentication setup at your site.
|
||||
|
||||
|
||||
=head2 OPERATION - Generating a SEARCH
|
||||
|
||||
sub LDAPsearch
|
||||
{
|
||||
my ($ldap,$searchString,$attrs,$base) = @_ ;
|
||||
|
||||
# if they don't pass a base... set it for them
|
||||
|
||||
if (!$base ) { $base = "o=mycompany, c=mycountry"; }
|
||||
|
||||
# if they don't pass an array of attributes...
|
||||
# set up something for them
|
||||
|
||||
if (!$attrs ) { $attrs = ['cn','mail' ]; }
|
||||
|
||||
my $result = $ldap->search (
|
||||
base => "$base",
|
||||
scope => "sub",
|
||||
filter => "$searchString",
|
||||
attrs => $attrs
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
my @Attrs = (); # request all available attributes
|
||||
# to be returned.
|
||||
|
||||
my $result = LDAPsearch($ldap,"sn=*",\@Attrs);
|
||||
|
||||
|
||||
=head2 PROCESSING - Displaying SEARCH Results
|
||||
|
||||
#------------
|
||||
#
|
||||
# Accessing the data as if in a structure
|
||||
# i.e. Using the "as_struct" method
|
||||
#
|
||||
|
||||
my $href = $result->as_struct;
|
||||
|
||||
# get an array of the DN names
|
||||
|
||||
my @arrayOfDNs = keys %$href ; # use DN hashes
|
||||
|
||||
# process each DN using it as a key
|
||||
|
||||
foreach (@arrayOfDNs) {
|
||||
print $_,"\n";
|
||||
my $valref = $$href{$_};
|
||||
|
||||
# get an array of the attribute names
|
||||
# passed for this one DN.
|
||||
my @arrayOfAttrs = sort keys %$valref; #use Attr hashes
|
||||
|
||||
my $attrName;
|
||||
foreach $attrName (@arrayOfAttrs) {
|
||||
|
||||
# skip any binary data: yuck!
|
||||
next if ( $attrName =~ /;binary$/ );
|
||||
|
||||
# get the attribute value (pointer) using the
|
||||
# attribute name as the hash
|
||||
my $attrVal = @$valref{$attrName} ;
|
||||
print "\t $attrName: @$attrVal \n";
|
||||
}
|
||||
print "#-------------------------------\n";
|
||||
# End of that DN
|
||||
}
|
||||
#
|
||||
# end of as_struct method
|
||||
#
|
||||
#--------
|
||||
|
||||
|
||||
#------------
|
||||
#
|
||||
# handle each of the results independently
|
||||
# ... i.e. using the walk through method
|
||||
#
|
||||
my @entries = $result->entries;
|
||||
|
||||
my $entr ;
|
||||
foreach $entr ( @entries )
|
||||
{
|
||||
print "DN: ",$entr->dn,"\n";
|
||||
#my @attrs = sort $entr->attributes;
|
||||
|
||||
my $attr;
|
||||
foreach $attr ( sort $entr->attributes ){
|
||||
#skip binary we can't handle
|
||||
next if ( $attr =~ /;binary$/ );
|
||||
print " $attr : ",$entr->get_value($attr),"\n";
|
||||
}
|
||||
|
||||
|
||||
#print "@attrs\n";
|
||||
print "#-------------------------------\n";
|
||||
}
|
||||
|
||||
#
|
||||
# end of walk through method
|
||||
#------------
|
||||
|
||||
|
||||
|
||||
=head2 OPERATION - Modifying entries
|
||||
|
||||
#
|
||||
# Modify
|
||||
#
|
||||
# for each of the modifies below you'll need to supply
|
||||
# a full DN (Distinguished Name) for the $dn variable.
|
||||
# example:
|
||||
# cn=Jo User,ou=person,o=mycompany,c=mycountry
|
||||
#
|
||||
# I would recommend doing a search (listed above)
|
||||
# then use the dn returned to populate the $dn variable.
|
||||
|
||||
|
||||
#
|
||||
# Do we only have one result returned from the search?
|
||||
|
||||
if ( $result->count != 1 ) { exit ; } # Nope.. exit
|
||||
|
||||
my $dn = $entries[0]->dn; # yes.. get the DN
|
||||
|
||||
|
||||
#######################################
|
||||
#
|
||||
# MODIFY using a HASH
|
||||
#
|
||||
|
||||
my %ReplaceHash = ( keyword => "x", proxy => "x" );
|
||||
|
||||
my $result = LDAPmodifyUsingHash($ldap,$dn, \%ReplaceHash );
|
||||
|
||||
sub LDAPmodifyUsingHash
|
||||
{
|
||||
my ($ldap,$dn,$whatToChange ) = @_ ;
|
||||
my $result = $ldap->modify($dn,
|
||||
replace => { %$whatToChange }
|
||||
);
|
||||
return ($result );
|
||||
}
|
||||
|
||||
|
||||
#######################################
|
||||
#
|
||||
# MODIFY using a ARRAY List
|
||||
#
|
||||
|
||||
my @ReplaceArrayList = [ 'keyword', "xxxxxxxxxx" ,
|
||||
'proxy' , "yyyyyyyyyy" ];
|
||||
|
||||
my $result = LDAPmodifyUsingArrayList($ldap,$dn, \@ReplaceArrayList );
|
||||
|
||||
sub LDAPmodifyUsingArrayList
|
||||
{
|
||||
my ($ldap,$dn,$whatToChange ) = @_ ;
|
||||
my $result = $ldap->modify($dn,
|
||||
changes => [
|
||||
replace => @$whatToChange
|
||||
]
|
||||
);
|
||||
return ($result );
|
||||
}
|
||||
|
||||
|
||||
#######################################
|
||||
#
|
||||
# MODIFY using a ARRAY
|
||||
#
|
||||
|
||||
my @ReplaceArray = ( 'keyword', "xxxxxxxxxx" ,
|
||||
'proxy' , "yyyyyyyyyy" );
|
||||
|
||||
my $result = LDAPmodifyUsingArray($ldap,$dn, \@ReplaceArray );
|
||||
|
||||
sub LDAPmodifyUsingArray
|
||||
{
|
||||
my ($ldap,$dn,$whatToChange ) = @_ ;
|
||||
my $result = $ldap->modify($dn,
|
||||
changes => [
|
||||
replace => [ @$whatToChange ]
|
||||
]
|
||||
);
|
||||
return ($result );
|
||||
}
|
||||
|
||||
|
||||
#######################################
|
||||
#
|
||||
# MODIFY an existing record using 'Changes'
|
||||
# (or combination of add/delete/replace)
|
||||
#
|
||||
|
||||
|
||||
my @whatToChange ;
|
||||
my @ReplaceArray ;
|
||||
my @DeleteArray ;
|
||||
my @AddArray ;
|
||||
|
||||
push @AddArray, 'cn',"me myself";
|
||||
push @ReplaceArray, 'sn','!@#$%^&*()__+Hello THere';
|
||||
push @ReplaceArray, 'cn',"me myself I";
|
||||
push @DeleteArray, 'cn',"me myself";
|
||||
|
||||
|
||||
|
||||
|
||||
if ( $#ReplaceArray > 0 ) {
|
||||
push @whatToChange, 'replace' ;
|
||||
push @whatToChange, \@ReplaceArray ;
|
||||
}
|
||||
if ( $#DeleteArray > 0 ) {
|
||||
push @whatToChange, 'delete' ;
|
||||
push @whatToChange, \@DeleteArray ;
|
||||
}
|
||||
if ( $#AddArray > 0 ) {
|
||||
push @whatToChange, 'add' ;
|
||||
push @whatToChange, \@AddArray ;
|
||||
}
|
||||
|
||||
$result = LDAPmodify($ldap,$dn, \@whatToChange );
|
||||
|
||||
|
||||
sub LDAPmodify
|
||||
{
|
||||
my ($ldap,$dn,$whatToChange) = @_ ;
|
||||
|
||||
my $result = $ldap->modify($dn,
|
||||
changes => [
|
||||
@$whatToChange
|
||||
]
|
||||
);
|
||||
return ($result );
|
||||
}
|
||||
|
||||
|
||||
|
||||
=head2 OPERATION - Changing the RDN
|
||||
|
||||
my $newRDN = "cn=Joseph User";
|
||||
|
||||
my $result = LDAPrdnChange($ldap,$dn,$newRDN,"archive");
|
||||
|
||||
|
||||
sub LDAPrdnChange
|
||||
{
|
||||
my ($ldap,$dn,$whatToChange,$action) = @_ ;
|
||||
|
||||
my $branch ;
|
||||
|
||||
#
|
||||
# if the archive action is selected, move this
|
||||
# entry to another place in the directory.
|
||||
#
|
||||
if ( $action =~ /archive/i ) {
|
||||
$branch = "ou=newbranch,o=mycompany,c=mycountry";
|
||||
}
|
||||
|
||||
#
|
||||
# use the 'deleteoldrdn' to keep from getting
|
||||
# multivalues in the NAMING attribute.
|
||||
# in most cases that would be the 'CN' attribute
|
||||
#
|
||||
my $result = $ldap->moddn($dn,
|
||||
newrdn => $whatToChange,
|
||||
deleteoldrdn => '1',
|
||||
newsuperior => $branch
|
||||
);
|
||||
|
||||
return ($result );
|
||||
|
||||
}
|
||||
|
||||
|
||||
=head2 OPERATION - Adding a new Record
|
||||
|
||||
|
||||
my $DNbranch = "ou=bailiwick, o=mycompany, c=mycountry";
|
||||
|
||||
#
|
||||
# check with your Directory Schema or Administrator
|
||||
# for the correct objectClass... I'm sure it'll be different
|
||||
#
|
||||
my $CreateArray = [
|
||||
objectClass => ["top","person","organizationalPerson"],
|
||||
cn => "Jane User",
|
||||
uid => "0000001",
|
||||
sn => "User",
|
||||
mail => "JaneUser@mycompany.com"
|
||||
];
|
||||
|
||||
#
|
||||
# create the new DN to look like this
|
||||
# " cn=Jo User + uid=0000001 , ou=bailiwick, o=mycompany, c=mycountry "
|
||||
#
|
||||
# NOTE: this DN MUST be changed to meet your implementation
|
||||
#
|
||||
|
||||
my $NewDN = "@$CreateArray[2]=".
|
||||
"@$CreateArray[3]+".
|
||||
"@$CreateArray[4]=".
|
||||
"@$CreateArray[5],".
|
||||
$DNbranch;
|
||||
|
||||
LDAPentryCreate($ldap,$NewDN,$CreateArray);
|
||||
|
||||
#
|
||||
# CreateArray is a reference to an anonymous array
|
||||
# you have to dereference it in the subroutine it's
|
||||
# passed to.
|
||||
#
|
||||
|
||||
sub LDAPentryCreate
|
||||
{
|
||||
|
||||
my ($ldap,$dn,$whatToCreate) = @_ ;
|
||||
my $result = $ldap->add( $dn, attrs => [ @$whatToCreate ] );
|
||||
return ($result );
|
||||
|
||||
}
|
||||
|
||||
|
||||
=head2 ERROR - Retrieving and Displaying ERROR information
|
||||
|
||||
use Net::LDAP::Util qw( ldap_error_name
|
||||
ldap_error_text) ;
|
||||
|
||||
if ( $result->code ) {
|
||||
#
|
||||
# if we've got an error... record it
|
||||
#
|
||||
LDAPerror("Searching",$result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub LDAPerror
|
||||
{
|
||||
my ($from,$mesg) = @_;
|
||||
print "Return code: ",$mesg->code ;
|
||||
print "\tMessage: ", ldap_error_name($mesg->code);
|
||||
print " :", ldap_error_text($mesg->code);
|
||||
print "MessageID: ",$mesg->mesg_id;
|
||||
print "\tDN: ",$mesg->dn;
|
||||
|
||||
#---
|
||||
# Programmer note:
|
||||
#
|
||||
# "$mesg->error" DOESN'T work!!!
|
||||
#
|
||||
#print "\tMessage: ", $mesg->error;
|
||||
#-----
|
||||
|
||||
}
|
||||
|
||||
|
||||
=head2 UNBIND
|
||||
|
||||
$ldap->unbind;
|
||||
|
||||
=head1 LDAP SCHEMA RETRIEVAL
|
||||
|
||||
The following code snippet shows how to retrieve schema information.
|
||||
|
||||
The first procedure is to initialize a new LDAP object using the
|
||||
same procedures as listed at the beginning of this document.
|
||||
|
||||
The second procedure is to bind to your directory server. Some
|
||||
servers may require authentication to retrieve the schema from the
|
||||
directory server. This procedure is listed at the beginning of
|
||||
this document too.
|
||||
|
||||
After a successful bind you are ready to retrieve the schema
|
||||
information. You do this by initializing a schema object.
|
||||
|
||||
$schema = $ldap->schema();
|
||||
|
||||
In this case Net::LDAP will attempt to determine the dn under which
|
||||
the schema can be found. First it will look for the attribute
|
||||
C<subschemasubentry> in the root DSE. If that cannot be found then
|
||||
it will default to the assumption of C<cn=schema>
|
||||
|
||||
Alternatively you can specify the dn where the schema is to be found
|
||||
with
|
||||
|
||||
$schema = $ldap->schema(dn => $dn);
|
||||
|
||||
Once we have a dn to search for, Net::LDAP will fetch the schema entry with
|
||||
|
||||
$mesg = $self->search(
|
||||
base => $dn,
|
||||
scope => 'base',
|
||||
filter => '(objectClass=*)',
|
||||
);
|
||||
|
||||
Once the schema object has been initialized, schema methods
|
||||
are used to retrieve the data. There are a number of ways this
|
||||
can be done. Information on the schema methods can be found
|
||||
in the Net::LDAP::Schema pod documentation.
|
||||
|
||||
The following is a code snippet showing how to get and display
|
||||
information about returned attributes.
|
||||
|
||||
#
|
||||
# Get the attributes
|
||||
#
|
||||
|
||||
@attributes = $schema->attributes();
|
||||
#
|
||||
# Display the attributes
|
||||
#
|
||||
|
||||
foreach ( @attributes)
|
||||
{
|
||||
print "attributeType\n";
|
||||
|
||||
#
|
||||
# Get and display the oid number of the objectclass.
|
||||
#
|
||||
$oid = $schema->name2oid( "$_" );
|
||||
|
||||
#
|
||||
# Get the various items associated with
|
||||
# this attribute.
|
||||
#
|
||||
@attribute_items = $schema->items( "$oid" );
|
||||
#
|
||||
# Read returned item names and display their associated data.
|
||||
#
|
||||
foreach $value ( @attribute_items )
|
||||
{
|
||||
# We know we are dealing with an attribute, ignore type.
|
||||
next if ( $value eq 'type'); # Type holds oc or at
|
||||
#
|
||||
# Read the data for this item of this oid.
|
||||
#
|
||||
@item = $schema->item( $oid, $value );
|
||||
#
|
||||
# Some item names have no data, the name itself is data.
|
||||
# This type of item has 1 as data.
|
||||
#
|
||||
if ( defined(@item) && $item[0] == 1 )
|
||||
{
|
||||
print "\t$value\n";
|
||||
next;
|
||||
}
|
||||
if ( defined(@item) && $#item >= 0 )
|
||||
{
|
||||
print "\t$value: @item\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
The process is the basically the same for getting objectClass
|
||||
information. Where schema->attributes() is used, substitute
|
||||
schema->objectclasses(). From that point on the process is
|
||||
the same for both objectClasses and attributes.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known, but there may be some
|
||||
|
||||
=head1 AUTHOR (of this document)
|
||||
|
||||
Russell Biggs <rgb@ticnet.com>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
All rights to this document are hereby relinquished to Graham Barr.
|
||||
|
||||
=for html <hr>
|
||||
|
||||
I<$Id$>
|
||||
|
||||
=cut
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue