1389 lines
49 KiB
Groff
Executable File
1389 lines
49 KiB
Groff
Executable File
.\" Automatically generated by Pod::Man version 1.15
|
|
.\" Fri Oct 4 06:36:42 2002
|
|
.\"
|
|
.\" Standard preamble:
|
|
.\" ======================================================================
|
|
.de Sh \" Subsection heading
|
|
.br
|
|
.if t .Sp
|
|
.ne 5
|
|
.PP
|
|
\fB\\$1\fR
|
|
.PP
|
|
..
|
|
.de Sp \" Vertical space (when we can't use .PP)
|
|
.if t .sp .5v
|
|
.if n .sp
|
|
..
|
|
.de Ip \" List item
|
|
.br
|
|
.ie \\n(.$>=3 .ne \\$3
|
|
.el .ne 3
|
|
.IP "\\$1" \\$2
|
|
..
|
|
.de Vb \" Begin verbatim text
|
|
.ft CW
|
|
.nf
|
|
.ne \\$1
|
|
..
|
|
.de Ve \" End verbatim text
|
|
.ft R
|
|
|
|
.fi
|
|
..
|
|
.\" Set up some character translations and predefined strings. \*(-- will
|
|
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
|
.\" double quote, and \*(R" will give a right double quote. | will give a
|
|
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used
|
|
.\" to do unbreakable dashes and therefore won't be available. \*(C` and
|
|
.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<>
|
|
.tr \(*W-|\(bv\*(Tr
|
|
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
|
.ie n \{\
|
|
. ds -- \(*W-
|
|
. ds PI pi
|
|
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
|
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
|
. ds L" ""
|
|
. ds R" ""
|
|
. ds C` ""
|
|
. ds C' ""
|
|
'br\}
|
|
.el\{\
|
|
. ds -- \|\(em\|
|
|
. ds PI \(*p
|
|
. ds L" ``
|
|
. ds R" ''
|
|
'br\}
|
|
.\"
|
|
.\" If the F register is turned on, we'll generate index entries on stderr
|
|
.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and
|
|
.\" index entries marked with X<> in POD. Of course, you'll have to process
|
|
.\" the output yourself in some meaningful fashion.
|
|
.if \nF \{\
|
|
. de IX
|
|
. tm Index:\\$1\t\\n%\t"\\$2"
|
|
..
|
|
. nr % 0
|
|
. rr F
|
|
.\}
|
|
.\"
|
|
.\" For nroff, turn off justification. Always turn off hyphenation; it
|
|
.\" makes way too many mistakes in technical documents.
|
|
.hy 0
|
|
.if n .na
|
|
.\"
|
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
|
.bd B 3
|
|
. \" fudge factors for nroff and troff
|
|
.if n \{\
|
|
. ds #H 0
|
|
. ds #V .8m
|
|
. ds #F .3m
|
|
. ds #[ \f1
|
|
. ds #] \fP
|
|
.\}
|
|
.if t \{\
|
|
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
|
. ds #V .6m
|
|
. ds #F 0
|
|
. ds #[ \&
|
|
. ds #] \&
|
|
.\}
|
|
. \" simple accents for nroff and troff
|
|
.if n \{\
|
|
. ds ' \&
|
|
. ds ` \&
|
|
. ds ^ \&
|
|
. ds , \&
|
|
. ds ~ ~
|
|
. ds /
|
|
.\}
|
|
.if t \{\
|
|
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
|
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
|
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
|
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
|
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
|
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
|
.\}
|
|
. \" troff and (daisy-wheel) nroff accents
|
|
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
|
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
|
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
|
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
|
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
|
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
|
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
|
.ds ae a\h'-(\w'a'u*4/10)'e
|
|
.ds Ae A\h'-(\w'A'u*4/10)'E
|
|
. \" corrections for vroff
|
|
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
|
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
|
. \" for low resolution devices (crt and lpr)
|
|
.if \n(.H>23 .if \n(.V>19 \
|
|
\{\
|
|
. ds : e
|
|
. ds 8 ss
|
|
. ds o a
|
|
. ds d- d\h'-1'\(ga
|
|
. ds D- D\h'-1'\(hy
|
|
. ds th \o'bp'
|
|
. ds Th \o'LP'
|
|
. ds ae ae
|
|
. ds Ae AE
|
|
.\}
|
|
.rm #[ #] #H #V #F C
|
|
.\" ======================================================================
|
|
.\"
|
|
.IX Title "FAQ 1"
|
|
.TH FAQ 1 "perl v5.6.1" "2002-07-15" "User Contributed Perl Documentation"
|
|
.UC
|
|
.SH "NAME"
|
|
Net::LDAP::FAQ \- Frequently Asked Questions about Net::LDAP
|
|
.SH "SYNOPSIS"
|
|
.IX Header "SYNOPSIS"
|
|
.Vb 1
|
|
\& perldoc Net::LDAP::FAQ
|
|
.Ve
|
|
.SH "DESCRIPTION"
|
|
.IX Header "DESCRIPTION"
|
|
This document serves to answer the most frequently asked questions on both the
|
|
perl-ldap Mailing List and those sent to Graham Barr.
|
|
.PP
|
|
The latest version of this \s-1FAQ\s0 can be found at
|
|
http://perl-ldap.sourceforge.net/FAQ.html
|
|
.SH "GENERAL"
|
|
.IX Header "GENERAL"
|
|
.Sh "What is perl-ldap ?"
|
|
.IX Subsection "What is perl-ldap ?"
|
|
perl-ldap is the distribution name. The perl-ldap distribution contains
|
|
the Net::LDAP modules.
|
|
.Sh "Why another perl \s-1LDAP\s0 implementation ?"
|
|
.IX Subsection "Why another perl LDAP implementation ?"
|
|
perl-ldap's goal is to be as portable as possible. It does this by
|
|
being implemented completely in perl. So basically anywhere that perl
|
|
runs perl-ldap will run. This is not true for other implementations
|
|
which require a C compiler.
|
|
.Sh "Where can I get it ?"
|
|
.IX Subsection "Where can I get it ?"
|
|
Perl-ldap is available from \s-1CPAN\s0. You will find it in the
|
|
authors/id/GBARR directory. Alternatively you can download
|
|
the latest version from
|
|
http://www.cpan.org/search?dist=perl-ldap
|
|
.PP
|
|
\&\fB\s-1WARNING:\s0\fR The perl-ldap module is stored on \s-1CPAN\s0 as a *.gz file.
|
|
Netscape on Windows systems sometimes has a problem storing the module
|
|
with the correct name, it will replace the *.tar.gz with *_tar.tar.
|
|
To correct the problem, with the pointer on the link, do a right click
|
|
and then select \fBsave link as\fR to save the file with the correct file
|
|
name.
|
|
.Sh "Is there a web page for perl-ldap ?"
|
|
.IX Subsection "Is there a web page for perl-ldap ?"
|
|
Yes there is at http://perl-ldap.sourceforge.net/
|
|
.Sh "Is there a mailing list ?"
|
|
.IX Subsection "Is there a mailing list ?"
|
|
Yes there is at perl-ldap-dev@lists.sourceforge.net
|
|
.PP
|
|
You can subscribe to this list at
|
|
http://lists.sourceforge.net/mailman/listinfo/perl-ldap-dev
|
|
.Sh "Is the mailing list archived ?"
|
|
.IX Subsection "Is the mailing list archived ?"
|
|
Archives of messages since we switched to using sourceforge can be
|
|
found at
|
|
.PP
|
|
.Vb 1
|
|
\& http://www.geocrawler.com/lists/3/SourceForge/3482/0/
|
|
.Ve
|
|
Please be aware that the geocrawler system munges
|
|
code that is in the email messages. In particular,
|
|
apostrophes (') are turned into back ticks (`) and
|
|
newlines escapes (\en) are removed (and probably other
|
|
escapes as well).
|
|
.PP
|
|
There is also an archive of the perl-ldap mailing list at
|
|
http://www.xray.mpe.mpg.de/mailing-lists/perl-ldap/
|
|
which also has messages from before the move to sourceforge.
|
|
The xray archive does not munge email messages.
|
|
.Sh "Is there any online documentation ?"
|
|
.IX Subsection "Is there any online documentation ?"
|
|
Yes. perl-ldap has online documentation at
|
|
http://perl-ldap.sourceforge.net/
|
|
which will have the latest documentation available.
|
|
.Sh "Is there a public \s-1CVS\s0 repository ?"
|
|
.IX Subsection "Is there a public CVS repository ?"
|
|
Yes, it is located at sourceforge.net
|
|
.Sh "Can I get perl-ldap from the public \s-1CVS\s0 repository?"
|
|
.IX Subsection "Can I get perl-ldap from the public CVS repository?"
|
|
Yes, any one can pull perl-ldap from the public \s-1CVS\s0 repository
|
|
on sourceforge.net.
|
|
.PP
|
|
There are several ways this can be done.
|
|
.PP
|
|
Web;
|
|
.PP
|
|
You can download it from SourceForge by following the release link:
|
|
.PP
|
|
The 2 lines in the following example should be put together as
|
|
one continuous line. Example;
|
|
.PP
|
|
.Vb 1
|
|
\& http://download.sourceforge.net/perl-ldap/perl-ldap-0.20.tar.gz
|
|
.Ve
|
|
\&\fB\s-1WARNING:\s0\fR The perl-ldap module is stored on \s-1CPAN\s0 as a *.gz file.
|
|
Netscape on Windows systems sometimes has a problem storing the module
|
|
with the correct name, it will replace the *.tar.gz with *_tar.tar.
|
|
To correct the problem, with the pointer on the link, do a right click
|
|
and then select \fBsave link as\fR to save the file with the correct file
|
|
name.
|
|
.PP
|
|
\&\s-1CVS\s0;
|
|
.PP
|
|
You can download latest version of perl-ldap from SourceForge by
|
|
executing a anonymous \s-1CVS\s0 \*(L"get\*(R" command. When the password is
|
|
requested press the enter key.
|
|
.PP
|
|
The 2 lines in the following example should be put together as
|
|
one continuous line. Example;
|
|
.PP
|
|
.Vb 1
|
|
\& cvs -d:pserver:anonymous@cvs.perl-ldap.sourceforge.net:/cvsroot/perl-ldap
|
|
.Ve
|
|
Web page;
|
|
.PP
|
|
Most of the time there is a \s-1URL\s0 link on the perl-ldap
|
|
home page on sourceforge that points to the latest released
|
|
version of perl-ldap. Due to the fact that humans must
|
|
update the web page to point to a new release it sometimes does
|
|
not get updated as quickly as it should.
|
|
.PP
|
|
\&\fB\s-1WARNING:\s0\fR The perl-ldap module is stored on \s-1CPAN\s0 as a *.gz file.
|
|
Netscape on Windows systems sometimes has a problem storing the module
|
|
with the correct name, it will replace the *.tar.gz with *_tar.tar.
|
|
To correct the problem, with the pointer on the link, do a right click
|
|
and then select \fBsave link as\fR to save the file with the correct file
|
|
name.
|
|
.Sh "What is \s-1CVS\s0."
|
|
.IX Subsection "What is CVS."
|
|
\&\*(L"\s-1CVS\s0\*(R" is an acronym for the \*(L"Concurrent Versions System\*(R".
|
|
\&\s-1CVS\s0 is a \*(L"Source Control\*(R" or \*(L"Revision Control\*(R" tool
|
|
designed to keep track of source changes made by groups of
|
|
developers working on the same files, allowing them to
|
|
stay in sync with each other as each individual chooses.
|
|
.SH "LDAP AND DIRECTORY TERMINOLOGY."
|
|
.IX Header "LDAP AND DIRECTORY TERMINOLOGY."
|
|
In order to help the user understand the perl-ldap module better
|
|
some key \s-1LDAP\s0 terminology is defined here.
|
|
.Sh "What is a directory."
|
|
.IX Subsection "What is a directory."
|
|
A directory is a special purpose database that usually contains
|
|
typed information such as text strings, binary data, or X.509
|
|
certificates.
|
|
.Sh "What is \s-1LDAP\s0."
|
|
.IX Subsection "What is LDAP."
|
|
\&\s-1LDAP\s0 stands for Lightweight Directory Access Protocol.
|
|
The word \fIProtocol\fR is the key word in the definition given in
|
|
the preceding sentence, \s-1LDAP\s0 is \fI\s-1NOT\s0\fR hardware or software.
|
|
It is a protocol that defines how a client and server will
|
|
communicate with one another.
|
|
.PP
|
|
The Lightweight Directory Access Protocol is defined in a
|
|
series of Requests For Comments, better known as \fIRFC\fR\|(s).
|
|
The RFCs can be found on the Internet. A very good
|
|
source for all of the \s-1LDAP\s0 RFCs can be found in the
|
|
OpenLDAP, http://www.OpenLDAP.org/ , software bundle that can
|
|
be downloaded free of charge from the Internet. Some of the
|
|
more important \s-1RFC\s0 numbers are \s-1RFC\s0 1777 for LDAPv2 and \s-1RFC\s0 2251
|
|
for LDAPv3.
|
|
.Sh "What is a \s-1LDAP\s0 Directory."
|
|
.IX Subsection "What is a LDAP Directory."
|
|
In the strictest terms of the definition there is no such
|
|
thing as a \s-1LDAP\s0 directory. To be practical about this
|
|
situation every day directory professionals refer to their
|
|
directory as \*(L" a \s-1LDAP\s0 directory\*(R" because it is easy to
|
|
say and it does convey the type of protocol used to
|
|
communicate with their directory. Using this definition
|
|
a \s-1LDAP\s0 directory is a directory whose server software
|
|
conforms to the Lightweight Directory Access Protocol when
|
|
communicating with a client.
|
|
.Sh "What is an Entry."
|
|
.IX Subsection "What is an Entry."
|
|
The traditional directory definition of a directory object
|
|
is called an Entry. Entries are composed of attributes
|
|
that contain the information to be recorded about an object.
|
|
.PP
|
|
Another non-traditional definition of a directory object
|
|
is called a record. Some directory professionals prefer
|
|
to use this definition because of the confusion that sometimes
|
|
results when using the term Entry.
|
|
.Sh "What is a Distinguished Name."
|
|
.IX Subsection "What is a Distinguished Name."
|
|
Every entry in a directory, whether it is X.500 or \s-1LDAP\s0, has
|
|
a Distinguished Name, or \s-1DN\s0. It is a unique Entry identifier
|
|
through out the complete directory. No two Entries can have the
|
|
same \s-1DN\s0 within the same directory.
|
|
.PP
|
|
Example of a \s-1DN:\s0
|
|
.PP
|
|
.Vb 4
|
|
\& cn=Road Runner, ou=bird, dc=carton, dc=com
|
|
\& ou=bird, dc=carton, dc=com
|
|
\& dc=carton, dc=com
|
|
\& dc=com
|
|
.Ve
|
|
.Sh "What is a Relative Distinguished Name."
|
|
.IX Subsection "What is a Relative Distinguished Name."
|
|
Every Entry in a directory, whether it is X.500 or \s-1LDAP\s0, has
|
|
a Distinguished Name which is made up of a sequence of Relative
|
|
Distinguished Names, or RDNs. The sequences of RDNs are separated
|
|
by commas (,) or semi-colons (;). There can be more than one
|
|
identical \s-1RDN\s0 in a directory, but they must be in different
|
|
bases, or branches, of the directory.
|
|
.PP
|
|
Example of a \s-1DN:\s0
|
|
.PP
|
|
.Vb 1
|
|
\& cn=Road Runner,ou=bird,dc=carton,dc=com
|
|
.Ve
|
|
.Vb 5
|
|
\& RDNs of the proceeding DN:
|
|
\& RDN => cn=Road Runner
|
|
\& RDN => ou=bird
|
|
\& RDN => dc=carton
|
|
\& RDN => dc=com
|
|
.Ve
|
|
The RDNs are delimited by a comma.
|
|
.Sh "What is a Naming \s-1RDN\s0."
|
|
.IX Subsection "What is a Naming RDN."
|
|
Example of a \s-1DN:\s0
|
|
.PP
|
|
.Vb 1
|
|
\& cn=Road Runner,ou=bird,dc=carton,dc=com
|
|
.Ve
|
|
.Vb 1
|
|
\& Naming RDN of the proceeding DN:
|
|
.Ve
|
|
.Vb 1
|
|
\& cn=Road Runner
|
|
.Ve
|
|
Most of the time when directory professionals refer
|
|
to the \s-1RDN\s0 of an entry, this is the \s-1RDN\s0 that they
|
|
are referring to.
|
|
.Sh "What is a search base."
|
|
.IX Subsection "What is a search base."
|
|
A search base is a Distinguished Name that is the
|
|
starting point of search queries.
|
|
.PP
|
|
Example of a \s-1DN:\s0
|
|
.PP
|
|
.Vb 1
|
|
\& cn=Road Runner,ou=bird,dc=carton,dc=com
|
|
.Ve
|
|
Possible search \fIbase\fR\|(s) for the proceeding \s-1DN:\s0
|
|
.PP
|
|
.Vb 4
|
|
\& Base => cn=Road Runner,ou=bird,dc=carton,dc=com
|
|
\& Base => ou=bird,dc=carton,dc=com
|
|
\& Base => dc=carton,dc=com
|
|
\& Base => dc=com
|
|
.Ve
|
|
Setting the search base to the lowest possible branch of
|
|
the directory will speed up searches considerably.
|
|
.Sh "What is an attribute."
|
|
.IX Subsection "What is an attribute."
|
|
The \fIentry\fR\|(s) in a directory are composed of attributes that contain
|
|
information about the object. Each attribute has a type
|
|
and can contain one or more values. The attribute type is
|
|
associated with a syntax that defines what kind of information
|
|
can be stored in the attributes values and controls how
|
|
directory operations on the attribute behave. What attributes
|
|
are required and allowed in a entry is controlled by content
|
|
rules that are defined on a per-server basis or by a special
|
|
attribute in each entry called an objectClass.
|
|
.Sh "What is the difference between a \s-1LDAP\s0 server and a relational database"
|
|
.IX Subsection "What is the difference between a LDAP server and a relational database"
|
|
The most basic difference is that a directory server is a
|
|
specialized database designed to provide fast searches. While a relational
|
|
database is optimized for transactions (where a series of operations is
|
|
counted as 1, thus if one of the steps fails, the \s-1RDBMS\s0 can roll-back to
|
|
the state it was in before you started).
|
|
.PP
|
|
Directories also typically are hierarchical in nature (\s-1RDBMS\s0 is typically
|
|
flat, but you can implement a hierarchy using tables and queries),
|
|
network-able, distributed and replicated.
|
|
.PP
|
|
\&\s-1LDAP\s0 provides an open-standard to a directory service.
|
|
.PP
|
|
Typically we use \s-1LDAP\s0 for email directories (all popular email clients
|
|
provide an \s-1LDAP\s0 client now) and authorization services (authentication and
|
|
access control).
|
|
.PP
|
|
You could use a \s-1RDBMS\s0 for these types of queries but there's not a
|
|
set standard, in particular over \s-1TCP/IP\s0 to connect to databases over the
|
|
network. There's language specific protocols (like Perl's \s-1DBI\s0 and Java's
|
|
\&\s-1JDBC\s0) that hide this problem behind an \s-1API\s0 abstraction, but that's not a
|
|
replacement for a standard access protocol.
|
|
.PP
|
|
\&\s-1LDAP\s0 is starting to be used on roles traditionally played by \s-1RDBMS\s0 in
|
|
terms of general data management because it's easier to setup a \s-1LDAP\s0
|
|
server (once you understand the basic nomenclature) and you don't need
|
|
a \s-1DBA\s0 to write your queries and more importantly all \s-1LDAP\s0 servers speak
|
|
the same essential protocol, thus you don't have to fuss with a
|
|
database driver trying to connect it to the Internet. Once you have an
|
|
\&\s-1LDAP\s0 server up and running, it's automatically available over the 'net.
|
|
It's possible to connect to a \s-1LDAP\s0 server from a variety of mechanisms,
|
|
including just about every possible programming language.
|
|
.PP
|
|
More information on this topic can be found on the following URLs;
|
|
.PP
|
|
.Vb 1
|
|
\& http://www.openldap.org/faq/data/cache/378.html
|
|
.Ve
|
|
.Vb 1
|
|
\& http://www.messagingdirect.com/publications/IC-6055.html
|
|
.Ve
|
|
.Sh "What is the difference between a ldap reference and a ldap referral?"
|
|
.IX Subsection "What is the difference between a ldap reference and a ldap referral?"
|
|
A referral is returned when the \fBentire\fR operation must be resent to
|
|
another server.
|
|
.PP
|
|
A continuation reference is returned when \fBpart\fR of the operation must be
|
|
resent to another server.
|
|
.PP
|
|
See \s-1RFC\s0 2251 section 4.5.3 for more details.
|
|
.SH "PERL-LDAP INSTALLATION"
|
|
.IX Header "PERL-LDAP INSTALLATION"
|
|
.Sh "How do I install perl-ldap ?"
|
|
.IX Subsection "How do I install perl-ldap ?"
|
|
To install the modules that are in the perl-ldap distribution follow the
|
|
same steps that you would for most other distributions found on \s-1CPAN\s0, that
|
|
is
|
|
.PP
|
|
.Vb 1
|
|
\& # replace 0.13 with the version you have
|
|
.Ve
|
|
.Vb 3
|
|
\& gunzip perl-ldap-0.13.tar.gz
|
|
\& tar xvf perl-ldap-0.13.tar
|
|
\& cd perl-ldap-0.13
|
|
.Ve
|
|
.Vb 4
|
|
\& perl Makefile.PL
|
|
\& make
|
|
\& make test
|
|
\& make install
|
|
.Ve
|
|
.Sh "But I do not have make, how can I install perl-ldap ?"
|
|
.IX Subsection "But I do not have make, how can I install perl-ldap ?"
|
|
Well as luck would have it the modules in perl-ldap do not do anything
|
|
complex, so a simple copy is enough to install. First run
|
|
.PP
|
|
.Vb 1
|
|
\& perl -V
|
|
.Ve
|
|
This will output information about the version of perl you have
|
|
installed. Near the bottom you will find something like
|
|
.PP
|
|
.Vb 6
|
|
\& @INC:
|
|
\& /usr/local/perl/perl5.005/lib/5.00502/sun4-solaris
|
|
\& /usr/local/perl/perl5.005/lib/5.00502
|
|
\& /usr/local/perl/perl5.005/lib/site_perl/5.005/sun4-solaris
|
|
\& /usr/local/perl/perl5.005/lib/site_perl/5.005
|
|
\& .
|
|
.Ve
|
|
This is a list of directories that perl searches when it is looking for
|
|
a module. The directory you need is the site_perl directory, but without
|
|
the system architecture name, in this case it is
|
|
\&\f(CW\*(C`/usr/local/perl/perl5.005/lib/site_perl/5.005\*(C'\fR. The files required
|
|
can then be installed with
|
|
.PP
|
|
.Vb 1
|
|
\& # replace 0.13 with the version you have
|
|
.Ve
|
|
.Vb 3
|
|
\& gunzip perl-ldap-0.13.tar.gz
|
|
\& tar xvf perl-ldap-0.13.tar
|
|
\& cd perl-ldap-0.13/lib
|
|
.Ve
|
|
.Vb 1
|
|
\& cp * /usr/local/perl/perl5.005/lib/site_perl/5.005
|
|
.Ve
|
|
.Sh "What other modules will I need ?"
|
|
.IX Subsection "What other modules will I need ?"
|
|
perl-ldap does use other modules. Some are required, but some are
|
|
optional (ie required to use certain features)
|
|
.Ip "Convert::ASN1" 4
|
|
.IX Item "Convert::ASN1"
|
|
This module is required for perl-ldap to work.
|
|
.Sp
|
|
You can obtain the latest release from
|
|
http://search.cpan.org/search?module=Convert::ASN1
|
|
.Ip "Digest::MD5" 4
|
|
.IX Item "Digest::MD5"
|
|
This module is optional. It also requires a C compiler when installing.
|
|
You only need to install Digest::MD5 if you want to use the \s-1SASL\s0
|
|
authentication method.
|
|
.Sp
|
|
You can obtain the latest release from
|
|
http://search.cpan.org/search?module=Digest::MD5
|
|
.Ip "\s-1URI:\s0:ldap" 4
|
|
.IX Item "URI::ldap"
|
|
This module is optional. You only need to install \s-1URI:\s0:ldap if you are
|
|
going to need to parse ldap referrals. the Net::LDAP manpage does not do this
|
|
automatically yet, so this module is not used by perl-ldap.
|
|
.Sp
|
|
You can obtain the latest release from
|
|
http://search.cpan.org/search?module=URI::ldap
|
|
.Ip "OpenSSL and \s-1IO:\s0:Socket::SSL for Net::LDAPS" 4
|
|
.IX Item "OpenSSL and IO::Socket::SSL for Net::LDAPS"
|
|
If you want to use Net::LDAP::LDAPS you will need this module
|
|
and the OpenSSL software package.
|
|
.Sp
|
|
You can obtain the latest release of \s-1IO:\s0:Socket::SSL from
|
|
http://search.cpan.org/search?module=IO::Socket::SSL
|
|
.Sp
|
|
You can obtain the latest release of OpenSSL from
|
|
http://www.openssl.org/
|
|
.Sp
|
|
If you are using a Linux system, many of the distributions
|
|
have \s-1RPM\s0 packages that you can install. Use your favorite
|
|
web search engine to find the package that you need.
|
|
.Ip "\s-1XML:\s0:Parser" 4
|
|
.IX Item "XML::Parser"
|
|
If you want to use Net::LDAP::DSML you will need this module.
|
|
.Sp
|
|
You can obtain the latest release from
|
|
http://search.cpan.org/search?module=XML::Parser
|
|
.SH "USING NET::LDAP"
|
|
.IX Header "USING NET::LDAP"
|
|
.Sh "How do I connect to my server ?"
|
|
.IX Subsection "How do I connect to my server ?"
|
|
The connection to the server is created when you create a new Net::LDAP
|
|
object, e.g.
|
|
.PP
|
|
.Vb 1
|
|
\& $ldap = Net::LDAP->new($server);
|
|
.Ve
|
|
.Sh "Net::LDAP->new sometimes returns undef, why ?"
|
|
.IX Subsection "Net::LDAP->new sometimes returns undef, why ?"
|
|
The constructor will return undef if there was a problem connecting
|
|
to the specified server. Any error message will be available in $@
|
|
.Sh "How can I tell when the server returns an error, \fIbind()\fP always returns true ?"
|
|
.IX Subsection "How can I tell when the server returns an error, bind() always returns true ?"
|
|
Most methods in Net::LDAP return a the Net::LDAP::Message manpage
|
|
object, or a sub-class of that. This object will hold the results
|
|
from the server, including the result code.
|
|
.PP
|
|
So, for example, to determine the result of the bind operation.
|
|
.PP
|
|
.Vb 1
|
|
\& $mesg = $ldap->bind( $dn, password => $passwd );
|
|
.Ve
|
|
.Vb 3
|
|
\& if ( $mesg->code ) {
|
|
\& # Handle error codes here
|
|
\& }
|
|
.Ve
|
|
.Sh "How can I set the ldap version of a connection to my ldap server?"
|
|
.IX Subsection "How can I set the ldap version of a connection to my ldap server?"
|
|
This is done by adding the version option when binding to the ldap
|
|
server.
|
|
.PP
|
|
For example;
|
|
.PP
|
|
.Vb 1
|
|
\& $mesg = $ldap->bind( $dn, password => $passwd, version => 3 );
|
|
.Ve
|
|
Valid version numbers are 2 and 3.
|
|
.Sh "I did a search on my directory using the 'search' method. Where did the results go ?"
|
|
.IX Subsection "I did a search on my directory using the 'search' method. Where did the results go ?"
|
|
Your search results are stored in a 'search object' container.
|
|
Consider the following:
|
|
.PP
|
|
.Vb 1
|
|
\& use Net::LDAP;
|
|
.Ve
|
|
.Vb 5
|
|
\& $ldap = Net::LDAP->new('ldap.acme.com') or die "$@";
|
|
\& $mesg = $ldap->search(
|
|
\& base => "o=acme.com",
|
|
\& filter => "uid=jsmith",
|
|
\& );
|
|
.Ve
|
|
$mesg is a search object container. It is a reference blessed into the
|
|
the Net::LDAP::Search manpage package. By calling methods on
|
|
this object you can obtain information about the result and also the
|
|
individual entries.
|
|
.PP
|
|
The first thing to check is if the search was successful. This is done with
|
|
with the method \f(CW$mesg\fR->code. This method will return the status code
|
|
that the server returned. A success will yield a zero value, but there are
|
|
other values, some of which could also be considered a success.
|
|
See the Net::LDAP::Constant manpage
|
|
.PP
|
|
.Vb 1
|
|
\& use Net::LDAP::Util qw(ldap_error_text);
|
|
.Ve
|
|
.Vb 2
|
|
\& die ldap_error_text($mesg->code)
|
|
\& if $mesg->code;
|
|
.Ve
|
|
There are two ways in which you can access the entries. You can access
|
|
then with an index or you can treat the container like a stack and
|
|
shift each entry in turn. For example
|
|
.PP
|
|
.Vb 1
|
|
\& # as an array
|
|
.Ve
|
|
.Vb 2
|
|
\& # How many entries were returned from the search
|
|
\& my $max = $mesg->count;
|
|
.Ve
|
|
.Vb 4
|
|
\& for( my $index = 0 ; $index < $max ; $index++) {
|
|
\& my $entry = $mesg->entry($index);
|
|
\& # ...
|
|
\& }
|
|
.Ve
|
|
.Vb 1
|
|
\& # or as a stack
|
|
.Ve
|
|
.Vb 3
|
|
\& while( my $entry = $mesg->shift_entry) {
|
|
\& # ...
|
|
\& }
|
|
.Ve
|
|
In each case \f(CW$entry\fR is an entry object container. It is a reference blessed
|
|
into the the Net::LDAP::Entry manpage package. By calling methods on this object
|
|
you can obtain information about the entry.
|
|
.PP
|
|
For example, to obtain the \s-1DN\s0 for the entry
|
|
.PP
|
|
.Vb 1
|
|
\& $dn = $entry->dn;
|
|
.Ve
|
|
To obtain the attributes that a given entry has
|
|
.PP
|
|
.Vb 1
|
|
\& @attrs = $entry->attributes;
|
|
.Ve
|
|
And to get the list of values for a given attribute
|
|
.PP
|
|
.Vb 1
|
|
\& @values = $entry->get( 'sn' );
|
|
.Ve
|
|
And to get the first of the values for a given attribute
|
|
.PP
|
|
.Vb 1
|
|
\& $values = $entry->get( 'cn' );
|
|
.Ve
|
|
One thing to remember is that attribute names are case
|
|
insensitive, so 'sn', 'Sn', 'sN' and '\s-1SN\s0' are all the same.
|
|
.PP
|
|
So, if you want to print all the values for the attribute \f(CW\*(C`'ou'\*(C'\fR then this
|
|
is as simple as
|
|
.PP
|
|
.Vb 3
|
|
\& foreach ($entry->get_value( 'ou' )) {
|
|
\& print $_,"\en";
|
|
\& }
|
|
.Ve
|
|
Now if you just want to print all the values for all the attributes you
|
|
can do
|
|
.PP
|
|
.Vb 5
|
|
\& foreach my $attr ($entry->attributes) {
|
|
\& foreach my $value ($entry->get_value($attr)) {
|
|
\& print $attr, ": ", $value, "\en";
|
|
\& }
|
|
\& }
|
|
.Ve
|
|
.Sh "How do I limit the scope of a directory search."
|
|
.IX Subsection "How do I limit the scope of a directory search."
|
|
You limit the scope of a directory search by setting the
|
|
scope parameter of search request.
|
|
Consider the following:
|
|
.PP
|
|
.Vb 1
|
|
\& use Net::LDAP;
|
|
.Ve
|
|
.Vb 6
|
|
\& $ldap = Net::LDAP->new('ldap.acme.com') or die "$@";
|
|
\& $mesg = $ldap->search(
|
|
\& base => "o=acme.com",
|
|
\& scope => 'sub',
|
|
\& filter => "uid=jsmith",
|
|
\& );
|
|
.Ve
|
|
Values for the scope parameter are as follows.
|
|
.PP
|
|
.Vb 1
|
|
\& base Search only the base object.
|
|
.Ve
|
|
.Vb 2
|
|
\& one Search the entries immediately below the base
|
|
\& object.
|
|
.Ve
|
|
.Vb 2
|
|
\& sub Search the whole tree below the base object.
|
|
\& This is the default.
|
|
.Ve
|
|
.SH "GETTING SEARCH RESULTS"
|
|
.IX Header "GETTING SEARCH RESULTS"
|
|
There are two ways of retrieving the results of a requested
|
|
\&\s-1LDAP\s0 search; inline and by using a callback subroutine.
|
|
.Sh "\s-1USING\s0 \s-1THE\s0 \s-1INLINE\s0 \s-1APPROACH\s0"
|
|
.IX Subsection "USING THE INLINE APPROACH"
|
|
Using the inline approach involves requesting the data and
|
|
then waiting for all of the data to be returned before the
|
|
user starts processing the data.
|
|
.PP
|
|
Example:
|
|
.PP
|
|
.Vb 1
|
|
\& use Net::LDAP;
|
|
.Ve
|
|
.Vb 10
|
|
\& $ldap = Net::LDAP->new('ldap.acme.com') or die "$@";
|
|
\& $mesg = $ldap->search(
|
|
\& base => "o=acme.com",
|
|
\& scope => 'sub',
|
|
\& filter => "sn=smith",
|
|
\& );
|
|
\& #
|
|
\& # At this point the user can get the returned data as an array
|
|
\& # or as a stack.
|
|
\& # In this example we will use an array
|
|
.Ve
|
|
.Vb 2
|
|
\& # How many entries were returned from the search
|
|
\& my $max = $mesg->count;
|
|
.Ve
|
|
.Vb 4
|
|
\& for( my $index = 0 ; $index < $max ; $index++)
|
|
\& {
|
|
\& my $entry = $mesg->entry($index);
|
|
\& my $dn = $entry->dn; # Obtain DN of this entry
|
|
.Ve
|
|
.Vb 14
|
|
\& @attrs = $entry->attributes; # Obtain attributes for this entry.
|
|
\& foreach my $var (@attrs)
|
|
\& {
|
|
\& #get a list of values for a given attribute
|
|
\& $attr = $entry->get_value( $var, asref => 1 );
|
|
\& if ( defined($attr) )
|
|
\& {
|
|
\& foreach my $value ( @$attr )
|
|
\& {
|
|
\& print "$var: $value\en"; # Print each value for the attribute.
|
|
\& }
|
|
\& }
|
|
\& }
|
|
\& }
|
|
.Ve
|
|
As you can see the example is straight forward, but there is one
|
|
drawback to this approach. You must wait until all entries for the
|
|
request search to be returned before you can process the data. If
|
|
there several thousand entries that match the search filter this
|
|
could take quite a long time period.
|
|
.Sh "\s-1USING\s0 \s-1THE\s0 \s-1CALLBACK\s0 \s-1SUBROUTINE\s0 \s-1APPROACH\s0"
|
|
.IX Subsection "USING THE CALLBACK SUBROUTINE APPROACH"
|
|
Using the callback approach involves requesting the data be sent
|
|
to a callback subroutine as each entry arrives at the client.
|
|
.PP
|
|
A callback is just a subroutine that is passed two parameters when
|
|
it is called, the mesg and entry objects.
|
|
.PP
|
|
Example:
|
|
.PP
|
|
.Vb 1
|
|
\& use Net::LDAP;
|
|
.Ve
|
|
.Vb 11
|
|
\& $ldap = Net::LDAP->new('ldap.acme.com') or die "$@";
|
|
\& $mesg = $ldap->search(
|
|
\& base => "o=acme.com",
|
|
\& scope => 'sub',
|
|
\& filter => "sn=smith",
|
|
\& callback => \e&callback,
|
|
\& );
|
|
\& #
|
|
\& # At this point the user needs to check the status of the
|
|
\& # ldap search.
|
|
\& #
|
|
.Ve
|
|
.Vb 7
|
|
\& if ( $mesg->code )
|
|
\& {
|
|
\& $errstr = $mesg->code;
|
|
\& print "Error code: $errstr\en";
|
|
\& $errstr = ldap_error_text($errstr);
|
|
\& print "$errstr\en";
|
|
\& }
|
|
.Ve
|
|
.Vb 3
|
|
\& sub callback
|
|
\& {
|
|
\& my ( $mesg, $entry) = @_;
|
|
.Ve
|
|
.Vb 11
|
|
\& #
|
|
\& # First you must check to see if something was returned.
|
|
\& # Last execution of callback subroutine will have no
|
|
\& # defined entry and mesg object
|
|
\& #
|
|
\& if ( !defined($entry) )
|
|
\& {
|
|
\& print "No records found matching filter $match.\en"
|
|
\& if ($mesg->count == 0) ; # if mesg is not defined nothing will print.
|
|
\& return;
|
|
\& }
|
|
.Ve
|
|
.Vb 1
|
|
\& my $dn = $entry->dn; # Obtain DN of this entry
|
|
.Ve
|
|
.Vb 22
|
|
\& @attrs = $entry->attributes; # Obtain attributes for this entry.
|
|
\& foreach my $var (@attrs)
|
|
\& {
|
|
\& #get a list of values for a given attribute
|
|
\& $attr = $entry->get_value( $var, asref => 1 );
|
|
\& if ( defined($attr) )
|
|
\& {
|
|
\& foreach my $value ( @$attr )
|
|
\& {
|
|
\& print "$var: $value\en"; # Print each value for the attribute.
|
|
\& }
|
|
\& }
|
|
\& }
|
|
\& #
|
|
\& # For large search requests the following 2 lines of code
|
|
\& # may be very important, they will reduce the amount of memory
|
|
\& # used by the search results.
|
|
\& #
|
|
\& # If the user is not worried about memory useage then the 2 lines
|
|
\& # of code can be omitted.
|
|
\& #
|
|
\& $mesg->pop_entry;
|
|
.Ve
|
|
.Vb 1
|
|
\& } # End of callback subroutine
|
|
.Ve
|
|
As you can see the example is straight forward and it does not waste
|
|
time waiting for all of the entries to be returned. However if the
|
|
pop_entry method is not used the callback approach can allocate a
|
|
lot of memory to the search request.
|
|
.SH "USING NET::LDAPS"
|
|
.IX Header "USING NET::LDAPS"
|
|
.Sh "Using a potentially encrypted (\s-1SSL\s0) network connection, how do I connect to my server?"
|
|
.IX Subsection "Using a potentially encrypted (SSL) network connection, how do I connect to my server?"
|
|
This class is a subclass of Net::LDAP so all the normal
|
|
Net::LDAP methods can be used with a Net::LDAPS object;
|
|
see the documentation for Net::LDAP to find out how to
|
|
query a directory server using the \s-1LDAP\s0 protocol.
|
|
.PP
|
|
The connection to the server is created when you create a new Net::LDAPS
|
|
object, e.g.
|
|
.PP
|
|
.Vb 5
|
|
\& $ldaps = Net::LDAPS->new($server,
|
|
\& port => '10000',
|
|
\& verify => 'require',
|
|
\& capath => '/usr/local/cacerts/',
|
|
\& );
|
|
.Ve
|
|
There are additional options to the \s-1LDAPS\s0 new method and
|
|
several additional methods are included in the \s-1LDAPS\s0 object class.
|
|
.PP
|
|
For further information and code examples read the \s-1LDAPS\s0
|
|
module documentation; perldoc Net::LDAPS
|
|
.SH "USING LDAP GROUPS."
|
|
.IX Header "USING LDAP GROUPS."
|
|
.Sh "What are \s-1LDAP\s0 groups."
|
|
.IX Subsection "What are LDAP groups."
|
|
\&\s-1LDAP\s0 groups are a collection of distinguished names (\s-1DN\s0) that are
|
|
listed in an attribute called member. One \fIimportant note\fR to
|
|
remember is that a group can be a collection of groups. This
|
|
does \fI\s-1NOT\s0\fR imply that the subgroups will be flattened into one
|
|
big group.
|
|
.PP
|
|
Two scripts for working with groups are available in the contrib
|
|
directory. They are isMember.pl and printMembers.pl.
|
|
.Sh "How do you format a filter to search for entries whose 'member' attribute has a particular value?"
|
|
.IX Subsection "How do you format a filter to search for entries whose 'member' attribute has a particular value?"
|
|
Asking for (member=*) is \s-1OK\s0 \- the directory uses the equality matching
|
|
rule which is defined for the member attribute.
|
|
.PP
|
|
Asking for (member=c*) is not \s-1OK\s0 \- there is no defined substring
|
|
matching rule for the member attribute. That's because the member
|
|
values are *not* strings, but distinguished names. There is no
|
|
substring matching rule for DNs, see \s-1RFC\s0 2256 section 5.50.
|
|
.PP
|
|
What you have to do is get the results of (member=*) and then select
|
|
the required results from the returned values. You need to do this
|
|
using knowledge of the string representation of DNs defined in \s-1RFC\s0
|
|
2253, which is important because the same \s-1DN\s0 can have different string
|
|
representations. So you need to perform some canonicalization if you
|
|
want to be correct.
|
|
.SH "USING DSML."
|
|
.IX Header "USING DSML."
|
|
.Sh "How can I access \s-1DSML\s0 features from \s-1PERL-LDAP\s0."
|
|
.IX Subsection "How can I access DSML features from PERL-LDAP."
|
|
Directory Service Markup Language (\s-1DSML\s0) is the \s-1XML\s0
|
|
standard for representing directory service information in
|
|
\&\s-1XML\s0.
|
|
.PP
|
|
Support for \s-1DSML\s0 is include in \s-1PERL-LDAP\s0 starting with version
|
|
\&.20.
|
|
.PP
|
|
At the moment this module only reads and writes \s-1DSML\s0 entry
|
|
entities. It cannot process any schema entities because
|
|
schema entities are processed differently than elements.
|
|
.PP
|
|
Eventually this module will be a full level 2 consumer and
|
|
producer enabling you to give you full \s-1DSML\s0 conformance.
|
|
.PP
|
|
The specification for \s-1DSML\s0 is at http://www.dsml.org
|
|
.PP
|
|
For further information and code examples read the \s-1DSML\s0
|
|
module documentation; perldoc Net::LDAP::DSML
|
|
.SH "USING CONTROLS AND VIRTUAL LISTS."
|
|
.IX Header "USING CONTROLS AND VIRTUAL LISTS."
|
|
.Sh "How do I access the Control features."
|
|
.IX Subsection "How do I access the Control features."
|
|
Support for \s-1LDAP\s0 version 3 Control objects is included in
|
|
perl-ldap starting with version .20.
|
|
.PP
|
|
For further information and code examples read the Control
|
|
module documentation; perldoc Net::LDAP::Control
|
|
.Sh "How do I access the Virtual List features."
|
|
.IX Subsection "How do I access the Virtual List features."
|
|
Support for Virtual Lists is included in perl-ldap starting
|
|
with version .20.
|
|
.PP
|
|
For further information and code examples read the Control
|
|
module documentation; perldoc Net::LDAP::Control
|
|
.SH "GENERAL QUESTIONS."
|
|
.IX Header "GENERAL QUESTIONS."
|
|
.Sh "Are there any other code examples."
|
|
.IX Subsection "Are there any other code examples."
|
|
Yes, there is an Examples pod file. To view the pod
|
|
do the following command; perldoc Net::LDAP::Examples
|
|
.PP
|
|
There is user contributed software in the contrib directory
|
|
that is supplied with the \s-1PERL-LDAP\s0 distribution. This is an
|
|
excellent source of information on how to use the \s-1PERL-LDAP\s0 module.
|
|
.Sh "Can I contribute perl scripts that use perl-ldap to the contrib section?"
|
|
.IX Subsection "Can I contribute perl scripts that use perl-ldap to the contrib section?"
|
|
Any one can submit a perl script that uses perl-ldap for inclusion
|
|
in the contrib section. Graham Barr will determine if the script
|
|
will be included and will do the initial check in of the script
|
|
to the \s-1CVS\s0 system on sourceforge. Graham will make you the
|
|
owner/developer of the script.
|
|
.PP
|
|
There are a couple of requirements for consideration.
|
|
.PP
|
|
You must supply a one line description of your script to be included
|
|
in the contrib readme file.
|
|
.PP
|
|
Inside the script will be the pod documentation for the script.
|
|
No auxiliary documentation will be allowed. For examples of how
|
|
to do this see the tklkup or schema scripts currently in the contrib
|
|
section.
|
|
.PP
|
|
If Graham decides to include your script in the contrib section, you
|
|
must register with sourceforge before your scripts will be put into
|
|
the contrib \s-1CVS\s0 system.
|
|
.Sh "Is possible to get a complete entry, dn and attributes without specifying the attributes name?"
|
|
.IX Subsection "Is possible to get a complete entry, dn and attributes without specifying the attributes name?"
|
|
Yes, just specify you want a list of no attributes back. The \s-1RFC\s0 says
|
|
that this tells the server to return all readable attributes back
|
|
(there may be access controls to prevent some from being returned.)
|
|
.PP
|
|
So in the search method, just set (for LDAPv2):
|
|
.PP
|
|
.Vb 1
|
|
\& attrs => [ ]
|
|
.Ve
|
|
If you are using LDAPv3, you can specify an attribute called \*(L"*\*(R"
|
|
instead, which lets you ask for additional (eg operational) attributes
|
|
in the same search.
|
|
.PP
|
|
.Vb 1
|
|
\& attrs => [ "*" ]
|
|
.Ve
|
|
.Sh "How do I put a jpeg photo into a entry in the directory."
|
|
.IX Subsection "How do I put a jpeg photo into a entry in the directory."
|
|
Follow the following code example, replacing the (...) with
|
|
whatever is relevant to your setup.
|
|
.PP
|
|
.Vb 3
|
|
\& use Net::LDAP;
|
|
\& use Net::LDAP::Util qw(ldap_error_text);
|
|
\& use CGI;
|
|
.Ve
|
|
.Vb 2
|
|
\& local $/ = undef;
|
|
\& my $jpeg = <$filename>;
|
|
.Ve
|
|
.Vb 5
|
|
\& my $ldap = new Net::LDAP(...);
|
|
\& my $res = $ldap->bind(...);
|
|
\& $res = $ldap->modify(...,
|
|
\& add => [ 'jpegPhoto' => [ $jpeg ] ]);
|
|
\& $res = $ldap->unbind();
|
|
.Ve
|
|
.Sh "How do I add a jpeg photo into a entry in the directory via html-forms."
|
|
.IX Subsection "How do I add a jpeg photo into a entry in the directory via html-forms."
|
|
Follow the following code example, replacing the (...) with
|
|
whatever is relevant to your setup.
|
|
.PP
|
|
.Vb 3
|
|
\& use Net::LDAP;
|
|
\& use Net::LDAP::Util qw(ldap_error_text);
|
|
\& use CGI;
|
|
.Ve
|
|
.Vb 1
|
|
\& my $q = new CGI;
|
|
.Ve
|
|
.Vb 2
|
|
\& print $q->header;
|
|
\& print $q->start_html(-title => 'Change JPEG photo');
|
|
.Ve
|
|
.Vb 4
|
|
\& if ($q->param('Update')) {
|
|
\& my $filename = $q->param('jpeg');
|
|
\& local $/ = undef;
|
|
\& my $jpeg = <$filename>;
|
|
.Ve
|
|
.Vb 11
|
|
\& my $ldap = new Net::LDAP(...);
|
|
\& my $res = $ldap->bind(...);
|
|
\& $res = $ldap->modify(...,
|
|
\& add => [ 'jpegPhoto' => [ $jpeg ] ]);
|
|
\& $res = $ldap->unbind();
|
|
\& } else {
|
|
\& print $q->start_multipart_form();
|
|
\& print $q->filefield(-name => 'jpeg', -size => 50);
|
|
\& print $q->submit('Update');
|
|
\& print $q->end_form();
|
|
\& }
|
|
.Ve
|
|
.Vb 1
|
|
\& print $q->end_html();
|
|
.Ve
|
|
.Sh "What happens when you delete an attribute that does not exist."
|
|
.IX Subsection "What happens when you delete an attribute that does not exist."
|
|
It is an error to delete an attribute that doesn't exist. When you
|
|
get the error back the server ignores the entire modify operation
|
|
you sent it, so you need to make sure the error doesn't happen.
|
|
.PP
|
|
Another approach, if you are using LDAPv3 (note Net::LDAP does not use
|
|
LDAPv3 by default) is to use a 'replace' with your attribute name and no
|
|
values. In LDAPv3, this is defined to always work even if that attribute
|
|
doesn't exist in the entry.
|
|
.PP
|
|
ie:
|
|
.PP
|
|
.Vb 1
|
|
\& my $mesg = $ldap->modify( $entry, replace => { %qv_del_arry } );
|
|
.Ve
|
|
But make sure you are using LDAPv3, because that is defined to *not* work
|
|
in LDAPv2. (A nice incompatibility between LDAPv2 and LDAPv3.)
|
|
.Sh "How can I delete a referral from an \s-1LDAP\s0 tree."
|
|
.IX Subsection "How can I delete a referral from an LDAP tree."
|
|
Since this is a proprietary feature, you will have to check your
|
|
server's documentation. You might find that you need to use a control. If
|
|
there is a control called something like managedsait, that's the one you
|
|
should probably use. For proper operation you will need the oid number
|
|
for managedsait; 2.16.840.1.113730.3.4.2 and do not specify a value for
|
|
type.
|
|
.PP
|
|
The code required will look similar to the following code snippet.
|
|
.PP
|
|
.Vb 2
|
|
\& $mesg = $ldap->delete("ref=\e"ldap://acme/c=us,o=bricks\e",o=clay",
|
|
\& control => {type => "2.16.840.1.113730.3.4.2"} );
|
|
.Ve
|
|
.Sh "How do I add an \s-1ACI/ACL\s0 entry to a directory server with Perl-LDAP."
|
|
.IX Subsection "How do I add an ACI/ACL entry to a directory server with Perl-LDAP."
|
|
The following code snippet works with a Netscape directory server and
|
|
should work with any other \s-1LDAP\s0 directory server. You will need the
|
|
specify the correct \s-1DN\s0 (\-DN-) and correct \fIattribute\fR\|(s) (\-nom attr-).
|
|
.PP
|
|
.Vb 2
|
|
\& my $aci = '(target="ldap:///-DN-")(targetattr="-nom attr-")(version 3.0;
|
|
\& acl "-nom acl-"; deny(all) userdn = "ldap:///self";)' ;
|
|
.Ve
|
|
.Vb 1
|
|
\& $ldap->modify($dn_modif, add => {'aci' => $aci });
|
|
.Ve
|
|
.Sh "How do I avoid file type and data type miss-matching when loading data from a Win32 system."
|
|
.IX Subsection "How do I avoid file type and data type miss-matching when loading data from a Win32 system."
|
|
When loading a binary attribute with data read from a file on a Win32
|
|
system, it has been noted that you should set \*(L"binmode\*(R" on the file
|
|
before reading the file contents into the data array.
|
|
.PP
|
|
Another possible solution to this problem is to convert the
|
|
binary data into a base64 encoded string and then store the encoded string
|
|
in the file. Then when reading the file, decode the base64 encoded
|
|
string back to binary and then use perl ldap to store the data
|
|
in the directory.
|
|
.Sh "How do I create a Microsoft Exchange user."
|
|
.IX Subsection "How do I create a Microsoft Exchange user."
|
|
This is a solution provide by a perl-ldap user.
|
|
.PP
|
|
This code works with ActiveState Perl running on WinNT 4. Please note that
|
|
this requires the Win32::Perms module, and needs valid \s-1NT\s0 account info to
|
|
replace the placeholders.
|
|
.PP
|
|
.Vb 3
|
|
\& use Net::LDAP qw(:all);
|
|
\& use Net::LDAP::Util;
|
|
\& use Win32::Perms;
|
|
.Ve
|
|
.Vb 11
|
|
\& #Constants taken from ADSI Type Library
|
|
\& $ADS_RIGHT_EXCH_ADD_CHILD = 1;
|
|
\& $ADS_RIGHT_EXCH_DELETE = 0x10000;
|
|
\& $ADS_RIGHT_EXCH_DS_REPLICATION = 64;
|
|
\& $ADS_RIGHT_EXCH_DS_SEARCH = 256;
|
|
\& $ADS_RIGHT_EXCH_MAIL_ADMIN_AS = 32;
|
|
\& $ADS_RIGHT_EXCH_MAIL_RECEIVE_AS = 16;
|
|
\& $ADS_RIGHT_EXCH_MAIL_SEND_AS = 8;
|
|
\& $ADS_RIGHT_EXCH_MODIFY_ADMIN_ATT = 4;
|
|
\& $ADS_RIGHT_EXCH_MODIFY_SEC_ATT = 128;
|
|
\& $ADS_RIGHT_EXCH_MODIFY_USER_ATT = 2;
|
|
.Ve
|
|
.Vb 3
|
|
\& $EXCH_USER_RIGHTS = $ADS_RIGHT_EXCH_MAIL_RECEIVE_AS |
|
|
\& $ADS_RIGHT_EXCH_MAIL_SEND_AS |
|
|
\& $ADS_RIGHT_EXCH_MODIFY_USER_ATT;
|
|
.Ve
|
|
.Vb 1
|
|
\& $exch = new Net::LDAP('server', debug =>0) || die $@;
|
|
.Ve
|
|
.Vb 2
|
|
\& $exch->bind( 'cn=admin_user,cn=nt_domain,cn=admin', version =>3,
|
|
\& password=>'password');
|
|
.Ve
|
|
.Vb 9
|
|
\& $myObj = Win32::Perms->new();
|
|
\& $Result = $myObj->Owner('nt_domain\euser_name');
|
|
\& $myObj->Group('nt_domain\eEveryone');
|
|
\& $myObj->Allow('nt_domain\euser_name',
|
|
\& $EXCH_USER_RIGHTS,OBJECT_INHERIT_ACE);
|
|
\& $BinarySD = $myObj->GetSD(SD_RELATIVE);
|
|
\& $TextSD = uc(unpack( "H*", $BinarySD ));
|
|
\& Win32::Perms::ResolveSid('nt_domain\euser_name', $sid);
|
|
\& $mysid = uc(unpack("H*",$sid));
|
|
.Ve
|
|
.Vb 11
|
|
\& $result = $exch->add ( dn =>
|
|
\& 'cn=user_name,cn=container,ou=site,o=organisation',
|
|
\& attr => [ 'objectClass' => ['organizationalPerson'],
|
|
\& 'cn' => 'directory_name',
|
|
\& 'uid' => 'mail_nickname',
|
|
\& 'mail' => 'smtp_address',
|
|
\& 'assoc-nt-account' => [ $mysid ],
|
|
\& 'nt-security-descriptor' => [ $TextSD ],
|
|
\& 'mailPreferenceOption' => 0
|
|
\& ]
|
|
\& );
|
|
.Ve
|
|
.Vb 1
|
|
\& print ldap_error_name($result->code);
|
|
.Ve
|
|
.Sh "How can I simiulate server failover."
|
|
.IX Subsection "How can I simiulate server failover."
|
|
Perl-LDAP does not do server failover, however there are several
|
|
programming options for getting around this situation.
|
|
.PP
|
|
Here is one possible solution.
|
|
.PP
|
|
.Vb 9
|
|
\& unless ( $ldaps =
|
|
\& Net::LDAPS->new($ldapserverone,
|
|
\& port=>636,timeout=>5) )
|
|
\& {
|
|
\& $ldaps = Net::LDAPS->new($ldapservertwo,
|
|
\& port=>636,timeout=>20) ||
|
|
\& return
|
|
\& "Can't connect to $ldapserverone or $ldapservertwo via LDAPS: $@";
|
|
\& }
|
|
.Ve
|
|
.SH "Using X.509 certificates."
|
|
.IX Header "Using X.509 certificates."
|
|
.Sh "How do I store X.509 certificates in the directory?"
|
|
.IX Subsection "How do I store X.509 certificates in the directory?"
|
|
The first problem here is that there are many different formats to hold
|
|
certificates in, for example \s-1PEM\s0, \s-1DER\s0, PKCS#7 and PKCS#12. The directory
|
|
*only* uses the \s-1DER\s0 format (more correctly, it only uses the \s-1BER\s0 format)
|
|
which is a binary format.
|
|
.PP
|
|
Your first job is to ensure that your certificates are therefore in \s-1DER/BER\s0
|
|
format. You could use OpenSSL to convert from \s-1PEM\s0 like this:
|
|
.PP
|
|
.Vb 1
|
|
\& openssl x509 -inform PEM -in cert.pem -outform DER -out cert.der
|
|
.Ve
|
|
Consult the OpenSSL documentation to find out how to perform other
|
|
conversions.
|
|
.PP
|
|
To add a certificate to the directory, just slurp in the \s-1DER/BER\s0
|
|
certificate into a scalar variable, and add it to the entry's
|
|
userCertificate attribute. How you do that will depend on which version of
|
|
\&\s-1LDAP\s0 you are using.
|
|
.PP
|
|
To slurp in the certificate try something like this:
|
|
.PP
|
|
.Vb 8
|
|
\& my $cert;
|
|
\& {
|
|
\& local $/ = undef; # Slurp mode
|
|
\& open CERT, "cert.der" or die;
|
|
\& $cert = <CERT>;
|
|
\& close CERT;
|
|
\& }
|
|
\& # The certificate is now in $cert
|
|
.Ve
|
|
For LDAPv2, because most directory vendors ignore the string representation
|
|
of certificates defined in \s-1RFC\s0 1778, you should add this value to the
|
|
directory like this:
|
|
.PP
|
|
.Vb 6
|
|
\& $res = $ldap->modify("cn=My User, o=My Company,c=XY",
|
|
\& add => [
|
|
\& 'userCertificate' => [ $cert ]
|
|
\& ]);
|
|
\& die "Modify failed (" . ldap_error_name($res->code) . ")\en"
|
|
\& if $res->code;
|
|
.Ve
|
|
For LDAPv3, you must do this instead:
|
|
.PP
|
|
.Vb 6
|
|
\& $res = $ldap->modify("cn=My User, o=My Company, c=XY",
|
|
\& add => [
|
|
\& 'userCertificate;binary' => [ $cert ]
|
|
\& ]);
|
|
\& die "Modify failed (" . ldap_error_name($res->code) . ")\en"
|
|
\& if $res->code;
|
|
.Ve
|
|
Of course, the entry you are trying to add the certificate to must use
|
|
object classes that permit the userCertificate attribute, otherwise the
|
|
modify will fail with an object class violation error. The inetOrgPerson
|
|
structural object class permits userCertificates, as does the
|
|
strongAuthenticationUser auxiliary object class. Others might also.
|
|
.SH "ADDITIONAL DIRECTORY AND LDAP RESOURCES."
|
|
.IX Header "ADDITIONAL DIRECTORY AND LDAP RESOURCES."
|
|
.Sh "\fIURL\fP\|(s)."
|
|
.IX Subsection "URL."
|
|
Directory Services Mark Language (\s-1DSML\s0)
|
|
http://www.dsml.org/
|
|
.PP
|
|
eMailman \s-1LDAP\s0 information
|
|
http://www.emailman.com/ldap/
|
|
.PP
|
|
Rafael Corvalan's \s-1LDAP\s0 shell
|
|
http://sf.net/projects/ldapsh
|
|
.PP
|
|
\&\s-1LDAPS\s0, also known as \s-1LDAPGURU\s0.
|
|
\&\fIThis web site has a nasty habit of resizing the browser
|
|
to cover the \s-1WHOLE\s0 screen.\fR
|
|
http://www.ldaps.com
|
|
.PP
|
|
Jeff Hodges's Kings Mountain \s-1LDAP\s0
|
|
http://www.kingsmountain.com/ldapRoadmap.shtml
|
|
.PP
|
|
Mark Wahl's \s-1LDAP\s0 World at Innosoft.
|
|
http://www.innosoft.com/ldapworld/
|
|
.PP
|
|
Open Source \s-1LDAP\s0 Directory Server.
|
|
http://www.openldap.org/
|
|
.PP
|
|
CriticalPath
|
|
http://www.cp.net/
|
|
.PP
|
|
Innosoft
|
|
http://www.innosoft.com
|
|
.PP
|
|
MessagingDirect
|
|
http://www.messagingdirect.com/
|
|
.PP
|
|
Netscape Directory Developers Area
|
|
http://developer.netscape.com/directory/
|
|
.PP
|
|
Nexor's X.500 and Internet Directories
|
|
http://www.nexor.com/info/directory.htm/
|
|
.PP
|
|
Novell's LDAPzone
|
|
http://ldapzone.com/
|
|
.PP
|
|
Octet String
|
|
http://www.octetstring.com/
|
|
.PP
|
|
\&\s-1SUN\s0 \s-1JAVA\s0 \s-1JNDI\s0 (Java Naming and Directory Interface)
|
|
http://www.java.sun.com/jndi/
|
|
.PP
|
|
Sun One, formerly IPlanet.
|
|
http://wwws.sun.com/software/
|
|
.PP
|
|
Eine deutsche \s-1LDAP\s0 Website
|
|
A german \s-1LDAP\s0 Website
|
|
http://verzeichnisdienst.de/ldap/Perl/index.html
|
|
.PP
|
|
The 2 following URLs deal mainly with Microsoft's
|
|
Active Directory.
|
|
.PP
|
|
Directory Works
|
|
http://directoryworks.com/
|
|
.PP
|
|
ActiveX \s-1LDAP\s0 Client
|
|
http://www.polonia-online.com/ldap/
|
|
.Sh "\fIBOOK\fP\|(s)"
|
|
.IX Subsection "BOOK"
|
|
Developing \s-1LDAP\s0 and \s-1ADSI\s0 Clients for \fIMicrosoft\fR\|(R) Exchange.
|
|
By Sven B. Schreiber. \s-1ISBN:\s0 0201657775
|
|
.PP
|
|
Implementing \s-1LDAP\s0.
|
|
By Mark Wilcox. \s-1ISBN:\s0 1861002211
|
|
.PP
|
|
\&\s-1LDAP\s0 : Programming Directory-Enabled Applications With
|
|
Lightweight Directory Access Protocol.
|
|
By Tim Howes, Mark Smith. \s-1ISBN:\s0 1578700000
|
|
.PP
|
|
\&\s-1LDAP\s0 Programming; Directory Management and Integration in Perl.
|
|
By Clayton Donley. \s-1ISBN:\s0 1884777910
|
|
.PP
|
|
\&\s-1LDAP\s0 Programming with Java.
|
|
By Rob Weltman, Tony Dahbura. \s-1ISBN:\s0 0201657589
|
|
.PP
|
|
Managing Enterprise Active Directory Services.
|
|
By Robbie Allen, Richard Puckett. \s-1ISBN:\s0 0672321254
|
|
.PP
|
|
Solaris and \s-1LDAP\s0 Naming Services.
|
|
By Tom Bialaski, Michael Haines. \s-1ISBN:\s0 0\-13\-030678\-9
|
|
.PP
|
|
Understanding and Deploying Ldap Directory Services.
|
|
By Tim Howes, Mark Smith, Gordon Good, Timothy A. Howe
|
|
\&\s-1ISBN:\s0 1578700701
|
|
.SH "\fIAUTHOR\fP\|(s)"
|
|
.IX Header "AUTHOR"
|
|
Any good \s-1FAQ\s0 is made up of many authors, everyone that contributes
|
|
information to the perl-ldap mail list is a potential author.
|
|
.PP
|
|
An attempt to maintain this \s-1FAQ\s0 is being done by Clif Harden
|
|
<charden@pobox.com>.
|
|
.PP
|
|
The original author of this \s-1FAQ\s0 was Graham Barr <gbarr@pobox.com>
|
|
.PP
|
|
Please report any bugs, or post any suggestions, to the
|
|
perl-ldap mailing list
|
|
<perl-ldap-dev@lists.sourceforge.net>.
|
|
.SH "COPYRIGHT"
|
|
.IX Header "COPYRIGHT"
|
|
Copyright (c) 1999\-2000 Graham Barr. All rights reserved. This document is
|
|
distributed, and may be redistributed, under the same terms as Perl itself.
|