[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 =head1 NAME 2 3 Net::LDAP::FAQ - Frequently Asked Questions about Net::LDAP 4 5 =head1 SYNOPSIS 6 7 perldoc Net::LDAP::FAQ 8 9 =head1 DESCRIPTION 10 11 This document serves to answer the most frequently asked questions on both the 12 perl-ldap Mailing List and those sent to Graham Barr. 13 14 The latest version of this FAQ can be found at 15 16 http://ldap.perl.org/FAQ.html 17 18 =head1 GENERAL 19 20 =head2 What is perl-ldap ? 21 22 perl-ldap is the distribution name. The perl-ldap distribution contains 23 the Net::LDAP modules. 24 25 =head2 Why another perl LDAP implementation ? 26 27 perl-ldap's goal is to be as portable as possible. It does this by 28 being implemented completely in perl. So basically anywhere that perl 29 runs perl-ldap will run. This is not true for other implementations 30 which require a C compiler. 31 32 =head2 Where can I get it ? 33 34 Perl-ldap is available from CPAN. You will find it in the 35 authors/id/GBARR directory. Alternatively you can download 36 the latest version from 37 38 http://www.cpan.org/search?dist=perl-ldap 39 40 B<WARNING:> The perl-ldap module is stored on CPAN as a *.gz file. 41 Netscape on Windows systems sometimes has a problem storing the module 42 with the correct name, it will replace the *.tar.gz with *_tar.tar. 43 To correct the problem, with the pointer on the link, do a right click 44 and then select B<save link as> to save the file with the correct file 45 name. 46 47 =head2 Is there a web page for perl-ldap ? 48 49 Yes there is at http://ldap.perl.org/ 50 51 =head2 Is there a mailing list ? 52 53 Yes there is at perl-ldap@perl.org 54 55 You can subscribe to this list by mailing perl-ldap-subscribe@perl.org 56 57 =head2 Is the mailing list archived ? 58 59 Yes, at http://nntp.perl.org/group/perl.ldap 60 61 Archives with messages before we switched to using perl.org can be 62 found at 63 64 http://marc.theaimsgroup.com/?l=perl-ldap-dev 65 66 There is also an archive of the perl-ldap mailing list at 67 68 http://www.xray.mpe.mpg.de/mailing-lists/perl-ldap/ 69 70 which also has messages from before the move. 71 72 =head2 Is there any online documentation ? 73 74 Yes. perl-ldap has online documentation at 75 76 http://ldap.perl.org/ 77 78 which will have the latest documentation available. 79 80 =head2 Is there a public CVS repository ? 81 82 No, but there is a public SVN repository at 83 84 http://svn.mutatus.co.uk 85 86 =head2 Can I get perl-ldap from the public SVN repository? 87 88 Yes, any one can pull perl-ldap from the public SVN repository 89 on perl.ldap.org. 90 91 There are several ways this can be done. 92 93 =over 4 94 95 =item Web 96 97 You can download it from CPAN by following the release link: 98 99 The 2 lines in the following example should be put together as 100 one continuous line. Example; 101 102 http://search.cpan.org/CPAN/authors/id/G/GB/GBARR/perl-ldap-0.33.tar.gz 103 104 B<WARNING:> The perl-ldap module is stored on CPAN as a *.gz file. 105 Netscape on Windows systems sometimes has a problem storing the module 106 with the correct name, it will replace the *.tar.gz with *_tar.tar. 107 To correct the problem, with the pointer on the link, do a right click 108 and then select B<save link as> to save the file with the correct file 109 name. 110 111 =item SVN 112 113 You can download latest development version of perl-ldap from 114 svn.mutatus.co.uk by executing a anonymous SVN "checkout" command. 115 116 The 2 lines in the following example should be put together as 117 one continuous line. Example; 118 119 svn co http://svn.mutatus.co.uk/repos/perl-ldap/trunk 120 121 =item Web page 122 123 Most of the time there is a URL link on the perl-ldap 124 home page on ldap.perl.org that points to the latest released 125 version of perl-ldap. Due to the fact that humans must 126 update the web page to point to a new release it sometimes does 127 not get updated as quickly as it should. 128 129 B<WARNING:> The perl-ldap module is stored on CPAN as a *.gz file. 130 Netscape on Windows systems sometimes has a problem storing the module 131 with the correct name, it will replace the *.tar.gz with *_tar.tar. 132 To correct the problem, with the pointer on the link, do a right click 133 and then select B<save link as> to save the file with the correct file 134 name. 135 136 =back 137 138 =head2 What is SVN. 139 140 "SVN" is an abbreviation for "Subversion" (see http://subversion.tigris.org). 141 Subversion is a "Source Control" or "Revision Control" tool 142 designed to keep track of source changes made by groups of 143 developers working on the same files, allowing them to 144 stay in sync with each other as each individual chooses. 145 146 =head1 LDAP AND DIRECTORY TERMINOLOGY. 147 148 In order to help the user understand the perl-ldap module better 149 some key LDAP terminology is defined here. 150 151 =head2 What is a directory. 152 153 A directory is a special purpose hierarchical database that usually 154 contains typed information such as text strings, binary data, or X.509 155 certificates. 156 157 =head2 What is LDAP. 158 159 LDAP stands for Lightweight Directory Access Protocol. 160 The word I<Protocol> is the key word in the definition given in 161 the preceding sentence, LDAP is I<NOT> hardware or software. 162 It is a protocol that defines how a client and server will 163 communicate with one another. 164 165 The Lightweight Directory Access Protocol is defined in a series of 166 Requests For Comments, better known as RFCs. The RFCs can be found on 167 the Internet at http://www.ietf.org/ (the master repository) and many 168 other places. There's a link to all the LDAP-related RFCs at 169 Perl-LDAP's web site, http://ldap.perl.org/rfc.html. Some of the more 170 important RFC numbers are RFC 451i0 - 4519 for LDAP (previously called 171 LDAPv3) and the historic RFC 1777 for LDAPv2. 172 173 =head2 What is a LDAP Directory. 174 175 In the strictest terms of the definition there is no such thing as a 176 LDAP directory. To be practical about this situation every day 177 directory professionals refer to their directory as " a LDAP 178 directory" because it is easy to say and it does convey the type of 179 protocol used to communicate with their directory. Using this 180 definition a LDAP directory is a directory whose server software 181 conforms to the Lightweight Directory Access Protocol when 182 communicating with a client. 183 184 =head2 What is an Entry. 185 186 The traditional directory definition of a directory object 187 is called an Entry. Entries are composed of attributes that 188 contain the information to be recorded about the object. 189 190 (An entry in LDAP is somewhat analogous to a record in a table in an 191 SQL database, but don't get too hung up about this analogy!) 192 193 Entries are held in an upside-down tree structure. Entries can 194 therefore contain subordinate entries, and entries B<must> have one 195 direct superior entry. 196 197 Entries with subordinate entries are called 'non-leaf' entries. 198 199 Entries without subordinate entries are called 'leaf' entries. 200 201 An entry's direct superior entry is called the entry's 'parent'. 202 203 'Non-leaf' entries are also said to have 'child' entries. 204 205 =head2 What is an attribute. 206 207 The entry(s) in a directory are composed of attributes that contain 208 information about the object. Each attribute has a type 209 and can contain one or more values. 210 211 For example: 212 213 cn=Road Runner 214 215 is an attribute with a type named "cn", and one value. 216 217 Each attribute is described by a 'syntax' which defines what kind of 218 information can be stored in the attributes values. Trying to store a 219 value that doesn't conform to the attribute's syntax will result in an 220 error. 221 222 For example: 223 224 jpegPhoto=unknown 225 226 is not permitted by the directory, because jpegPhotos may only contain 227 JPEG-formatted images. 228 229 Most syntaxes used in LDAP however describe text strings rather than 230 binary objects (like JPEGs or certificates.) 231 232 In LDAPv3 most of these syntaxes support Unicode encoded using 233 UTF-8. Because the Net::LDAP modules do not change the strings that 234 you pass in as attribute values (they get sent to the LDAP server 235 as-is) to use accented characters you simply need to encode your 236 strings in UTF-8. There are modules on CPAN that will help you here. 237 238 Note that LDAPv2 servers used something called T.61 instead of Unicode 239 and UTF-8. Most servers do not implement T.61 correctly, and it is 240 recommended that you use LDAPv3 instead. 241 242 Attributes may also be searched. The algorithms used to perform 243 different kinds of searches are described by the attribute's 'matching 244 rules'. Some matching rules are case-sensitive and some are 245 case-insensitive, for example. Sometimes matching rules aren't 246 defined for a particular attribute: there's no way to search for 247 jpegPhotos that contain a substring! 248 249 You can examine all of a server's attribute definitions by reading the 250 schema from the server. 251 252 =head2 What is an object class. 253 254 An object class is the name associated with a group of attributes that 255 B<must> be present in an entry, and the group of attributes that 256 B<may> also be present in an entry. 257 258 Object classes may be derived (subclassed) from other object classes. 259 For example the widely used 'inetOrgPerson' object class is derived 260 from 'organizationalPerson', which is itself derived from 'person' 261 which is itself derived from 'top'. 262 263 Every entry has an attribute called 'objectClass' that lists all the 264 names of object classes (and their superclasses) being used with the 265 entry. 266 267 You can examine all of a server's objectclass definitions by reading 268 the schema from the server. 269 270 =head2 What is a Distinguished Name (DN). 271 272 Every entry in a directory has a Distinguished Name, or DN. It is a 273 unique Entry identifier throughout the complete directory. No two 274 Entries can have the same DN within the same directory. 275 276 Examples of DNs: 277 278 cn=Road Runner, ou=bird, dc=cartoon, dc=com 279 ou=bird, dc=cartoon, dc=com 280 dc=cartoon, dc=com 281 dc=com 282 283 =head2 What is a Relative Distinguished Name. 284 285 Every DN is made up of a sequence of Relative Distinguished Names, or 286 RDNs. The sequences of RDNs are separated by commas (,). In LDAPv2 287 semi-colons (;) were also allowed. There can be more than one 288 identical RDN in a directory, but they must have different parent 289 entries. 290 291 Technically, an RDN contains attribute-value assertions, or AVAs. When 292 an AVA is written down, the attribute name is separated from the 293 attribute value with an equals (=) sign. 294 295 Example of a DN: 296 297 cn=Road Runner,ou=bird,dc=cartoon,dc=com 298 299 RDNs of the proceeding DN: 300 RDN => cn=Road Runner 301 RDN => ou=bird 302 RDN => dc=cartoon 303 RDN => dc=com 304 305 RDNs can contain multiple attributes, though this is somewhat 306 ususual. They are called multi-AVA RDNs, and each AVA is separated in 307 the RDN from the others with a plus sign (+). 308 309 Example of a DN with a multi-AVA RDN: 310 311 cn=Road Runner+l=Arizona,ou=bird,dc=cartoon,dc=com 312 313 =head2 Where is an entry's name held? 314 315 Entries do B<not> contain their DN. When you retrieve an entry from 316 a search, the server will tell you the DN of each entry. 317 318 On the other hand, entries B<do> contain their RDN. Recall that the RDN 319 is formed from one or more attribute-value assertions (AVAs); each entry 320 must contain all the attributes and values in the RDN. 321 322 For example the entry: 323 324 cn=Road Runner+l=Arizona,ou=bird,dc=cartoon,dc=com 325 326 B<must> contain a 'cn' attribute containing at least the value 327 "Road Runner", B<and> an 'l' attribute containing at least the value 328 "Arizona". 329 330 The attributes used in the RDN may contain additional values, but the 331 entry still only has one DN. 332 333 =head2 What is a search base. 334 335 A search base is a Distinguished Name that is the 336 starting point of search queries. 337 338 Example of a DN: 339 340 cn=Road Runner,ou=bird,dc=cartoon,dc=com 341 342 Possible search base(s) for the proceeding DN: 343 344 Base => cn=Road Runner,ou=bird,dc=cartoon,dc=com 345 Base => ou=bird,dc=cartoon,dc=com 346 Base => dc=cartoon,dc=com 347 Base => dc=com 348 349 Setting the search base to the lowest possible branch of 350 the directory will speed up searches considerably. 351 352 =head2 What is the difference between a LDAP server and a relational database. 353 354 The most basic difference is that a directory server is a 355 specialized database designed to provide fast searches. While a relational 356 database is optimized for transactions (where a series of operations is 357 counted as 1, thus if one of the steps fails, the RDBMS can roll-back to 358 the state it was in before you started). 359 360 Directories also typically are hierarchical in nature (RDBMS is typically 361 flat, but you can implement a hierarchy using tables and queries), 362 networkable, distributed and replicated. 363 364 LDAP provides an open-standard to a directory service. 365 366 Typically we use LDAP for email directories (all popular email clients 367 provide an LDAP client now) and authorization services (authentication and 368 access control). 369 370 You could use a RDBMS for these types of queries but there's no 371 set standard, in particular over TCP/IP to connect to databases over the 372 network. There's language specific protocols (like Perl's DBI and Java's 373 JDBC) that hide this problem behind an API abstraction, but that's not a 374 replacement for a standard access protocol. 375 376 LDAP is starting to be used on roles traditionally played by RDBMS in 377 terms of general data management because it's easier to setup a LDAP 378 server (once you understand the basic nomenclature) and you don't need 379 a DBA to write your queries and more importantly all LDAP servers speak 380 the same essential protocol, thus you don't have to fuss with a 381 database driver trying to connect it to the Internet. Once you have an 382 LDAP server up and running, it's automatically available over the 'net. 383 It's possible to connect to a LDAP server from a variety of mechanisms, 384 including just about every possible programming language. 385 386 More information on this topic can be found on the following URLs; 387 388 http://www.openldap.org/faq/data/cache/378.html 389 390 http://www.isode.com/whitepapers/ic-6055.html 391 392 =head2 What is the difference between a ldap reference and a ldap referral? 393 394 A referral is returned when the B<entire> operation must be resent to 395 another server. 396 397 A continuation reference is returned when B<part> of the operation must be 398 resent to another server. 399 400 See RFC 2251 section 4.5.3 for more details. 401 402 =head1 PERL-LDAP INSTALLATION 403 404 =head2 How do I install perl-ldap ? 405 406 To install the modules that are in the perl-ldap distribution follow the 407 same steps that you would for most other distributions found on CPAN, that 408 is 409 410 # replace 0.33 with the version you have 411 412 gunzip perl-ldap-0.33.tar.gz 413 tar xvf perl-ldap-0.33.tar 414 cd perl-ldap-0.33 415 416 perl Makefile.PL 417 make 418 make test 419 make install 420 421 =head2 But I do not have make, how can I install perl-ldap ? 422 423 Well as luck would have it the modules in perl-ldap do not do anything 424 complex, so a simple copy is enough to install. First run 425 426 perl -V 427 428 This will output information about the version of perl you have 429 installed. Near the bottom you will find something like 430 431 @INC: 432 /usr/local/perl/perl5.005/lib/5.00502/sun4-solaris 433 /usr/local/perl/perl5.005/lib/5.00502 434 /usr/local/perl/perl5.005/lib/site_perl/5.005/sun4-solaris 435 /usr/local/perl/perl5.005/lib/site_perl/5.005 436 . 437 438 This is a list of directories that perl searches when it is looking for 439 a module. The directory you need is the site_perl directory, but without 440 the system architecture name, in this case it is 441 C</usr/local/perl/perl5.005/lib/site_perl/5.005>. The files required 442 can then be installed with 443 444 # replace 0.33 with the version you have 445 446 gunzip perl-ldap-0.33.tar.gz 447 tar xvf perl-ldap-0.33.tar 448 cd perl-ldap-0.33/lib 449 450 cp * /usr/local/perl/perl5.005/lib/site_perl/5.005 451 452 =head2 How can I load Perl-LDAP into an ActiveState Perl installation. 453 454 There are several ways that Perl-LDAP can be installed into an 455 ActiveState Perl tree. 456 457 =over 4 458 459 =item 1. 460 461 The ActiveState ppm command can be used to install Perl-LDAP. 462 When a new version of Perl-LDAP is released, it takes ActiveState 463 a period of time to get the new release into the ActiveState ppm 464 system. 465 466 =item 2. 467 468 If the user has nmake installed, the user can do a normal perl 469 module install using nmake instead of make. 470 471 =item 3. 472 473 If the user does not have nmake or make, the user can install 474 Perl-LDAP using the install-nomake script by issuing the 475 following command. 476 477 perl install-nomake 478 479 The install-nomake script can be used on any system that does not 480 have make installed. 481 482 =back 483 484 =head2 What other modules will I need ? 485 486 perl-ldap does use other modules. Some are required, but some are 487 optional (ie required to use certain features) 488 489 =over 4 490 491 =item Convert::ASN1 492 493 This module is required for perl-ldap to work. 494 495 You can obtain the latest release from 496 http://search.cpan.org/search?module=Convert::ASN1 497 498 =item Authen::SASL 499 500 This module is optional. You only need to install Authen::SASL 501 if you want to use the SASL authentication method. 502 503 You can obtain the latest release from 504 http://search.cpan.org/search?module=Authen::SASL 505 506 =item Digest::MD5 507 508 This module is optional. It also requires a C compiler when installing. 509 You only need to install Digest::MD5 if you want to use the SASL 510 DIGEST-MD5 authentication method. 511 512 You can obtain the latest release from 513 http://search.cpan.org/search?module=Digest::MD5 514 515 =item URI::ldap 516 517 This module is optional. You only need to install URI::ldap if you are 518 going to need to parse ldap referrals. L<Net::LDAP> does not do this 519 automatically yet, so this module is not used by perl-ldap. 520 521 You can obtain the latest release from 522 http://search.cpan.org/search?module=URI::ldap 523 524 =item OpenSSL and IO::Socket::SSL for Net::LDAPS 525 526 If you want to use Net::LDAP::LDAPS you will need this module 527 and the OpenSSL software package. 528 529 You can obtain the latest release of IO::Socket::SSL from 530 http://search.cpan.org/search?module=IO::Socket::SSL 531 532 You can obtain the latest release of OpenSSL from 533 http://www.openssl.org/ 534 535 If you are using a Linux system, many of the distributions 536 have RPM packages that you can install. Use your favorite 537 web search engine to find the package that you need. 538 539 =item XML::SAX and XML::SAX::Writer 540 541 If you want to use Net::LDAP::DSML you will need these modules. 542 543 You can obtain the latest releases from 544 http://search.cpan.org/search?module=XML::SAX 545 http://search.cpan.org/search?module=XML::SAX::Writer 546 547 548 =item ResourcePool::Factory::Net::LDAP 549 550 If you want to use failover the ResourcePool::Factory::Net::LDAP 551 perl module provides methods to do this. 552 553 You can obtain the latest release from 554 http://search.cpan.org/search?module=ResourcePool::Factory::Net::LDAP 555 556 =back 557 558 =head1 USING NET::LDAP 559 560 =head2 How do I connect to my server ? 561 562 The connection to the server is created when you create a new Net::LDAP 563 object, e.g. 564 565 $ldap = Net::LDAP->new($server); 566 567 =head2 Net::LDAP-E<gt>new sometimes returns undef, why ? 568 569 The constructor will return undef if there was a problem connecting 570 to the specified server. Any error message will be available in $@ 571 572 =head2 What is the proper format of the bind DN. 573 574 The DN used to bind to a directory is a FULLY QUALIFIED DN. The exact 575 structure of the DN will depend on what data has been stored in the 576 server. 577 578 The following are valid examples. 579 580 uid=clif,ou=People,dc=umich,dc=edu 581 582 cn=directory manager,ou=admins,dc=umich,dc=edu 583 584 In some servers the following would be a valid fully qualified DN of 585 the directory manager. 586 587 cn=directory manager 588 589 =head2 How can I tell when the server returns an error, bind() always returns 590 true ? 591 592 Most methods in Net::LDAP return a L<Net::LDAP::Message> 593 object, or a sub-class of that. This object will hold the results 594 from the server, including the result code. 595 596 So, for example, to determine the result of the bind operation. 597 598 $mesg = $ldap->bind( $dn, password => $passwd ); 599 600 if ( $mesg->code ) { 601 # Handle error codes here 602 } 603 604 =head2 How can I set the LDAP version of a connection to my ldap server? 605 606 This is done by adding the version option when connecting or binding 607 to the LDAP server. 608 609 For example; 610 611 $ldap = Net::LDAP->new( $server, version => 3 ); 612 613 or 614 615 $mesg = $ldap->bind( $dn, password => $passwd, version => 3 ); 616 617 Valid version numbers are 2 and 3. 618 As of perl-ldap 0.27 the default LDAP version is 3. 619 620 =head2 I did a search on my directory using the 'search' method. Where did 621 the results go ? 622 623 Your search results are stored in a 'search object'. 624 Consider the following: 625 626 use Net::LDAP; 627 628 $ldap = Net::LDAP->new('ldap.acme.com') or die "$@"; 629 $mesg = $ldap->search( 630 base => "o=acme.com", 631 filter => "uid=jsmith", 632 ); 633 634 $mesg is a search object. It is a reference blessed into the 635 L<Net::LDAP::Search> package. By calling methods on this object you 636 can obtain information about the result and also the individual 637 entries. 638 639 The first thing to check is if the search was successful. This is done 640 with with the method $mesg-E<gt>code. This method will return the 641 status code that the server returned. A success will yield a zero 642 value, but there are other values, some of which could also be 643 considered a success. See L<Net::LDAP::Constant> 644 645 use Net::LDAP::Util qw(ldap_error_text); 646 647 die ldap_error_text($mesg->code) 648 if $mesg->code; 649 650 There are two ways in which you can access the entries. You can access 651 then with an index or you can treat the container like a stack and 652 shift each entry in turn. For example 653 654 # as an array 655 656 # How many entries were returned from the search 657 my $max = $mesg->count; 658 659 for( my $index = 0 ; $index < $max ; $index++) { 660 my $entry = $mesg->entry($index); 661 # ... 662 } 663 664 # or as a stack 665 666 while( my $entry = $mesg->shift_entry) { 667 # ... 668 } 669 670 In each case $entry is an entry object. It is a reference blessed into 671 the L<Net::LDAP::Entry> package. By calling methods on this object you 672 can obtain information about the entry. 673 674 For example, to obtain the DN for the entry 675 676 $dn = $entry->dn; 677 678 To obtain the attributes that a given entry has 679 680 @attrs = $entry->attributes; 681 682 And to get the list of values for a given attribute 683 684 @values = $entry->get( 'sn' ); 685 686 And to get the first of the values for a given attribute 687 688 $values = $entry->get( 'cn' ); 689 690 One thing to remember is that attribute names are case 691 insensitive, so 'sn', 'Sn', 'sN' and 'SN' are all the same. 692 693 So, if you want to print all the values for the attribute C<'ou'> then this 694 is as simple as 695 696 foreach ($entry->get_value( 'ou' )) { 697 print $_,"\n"; 698 } 699 700 Now if you just want to print all the values for all the attributes you 701 can do 702 703 foreach my $attr ($entry->attributes) { 704 foreach my $value ($entry->get_value($attr)) { 705 print $attr, ": ", $value, "\n"; 706 } 707 } 708 709 =head2 How do I limit the scope of a directory search. 710 711 You limit the scope of a directory search by setting the 712 scope parameter of search request. 713 Consider the following: 714 715 use Net::LDAP; 716 717 $ldap = Net::LDAP->new('ldap.acme.com') or die "$@"; 718 $mesg = $ldap->search( 719 base => "o=acme.com", 720 scope => 'sub', 721 filter => "uid=jsmith", 722 ); 723 724 Values for the scope parameter are as follows. 725 726 =over 4 727 728 =item base 729 730 Search only the base object. 731 732 =item one 733 734 Search the entries immediately below the base object. 735 736 =item sub 737 738 Search the whole tree below the base object. 739 This is the default. 740 741 =back 742 743 =head1 GETTING SEARCH RESULTS 744 745 There are two ways of retrieving the results of a requested 746 LDAP search; inline and by using a callback subroutine. 747 748 =head2 USING THE INLINE APPROACH 749 750 Using the inline approach involves requesting the data and 751 then waiting for all of the data to be returned before the 752 user starts processing the data. 753 754 Example: 755 756 use Net::LDAP; 757 758 $ldap = Net::LDAP->new('ldap.acme.com') or die "$@"; 759 $mesg = $ldap->search( 760 base => "o=acme.com", 761 scope => 'sub', 762 filter => "sn=smith", 763 ); 764 # 765 # At this point the user can get the returned data as an array 766 # or as a stack. 767 # In this example we will use an array 768 769 # How many entries were returned from the search 770 my $max = $mesg->count; 771 772 for( my $index = 0 ; $index < $max ; $index++) 773 { 774 my $entry = $mesg->entry($index); 775 my $dn = $entry->dn; # Obtain DN of this entry 776 777 @attrs = $entry->attributes; # Obtain attributes for this entry. 778 foreach my $var (@attrs) 779 { 780 #get a list of values for a given attribute 781 $attr = $entry->get_value( $var, asref => 1 ); 782 if ( defined($attr) ) 783 { 784 foreach my $value ( @$attr ) 785 { 786 print "$var: $value\n"; # Print each value for the attribute. 787 } 788 } 789 } 790 } 791 792 As you can see the example is straight forward, but there is one 793 drawback to this approach. You must wait until all entries for the 794 request search to be returned before you can process the data. If 795 there several thousand entries that match the search filter this 796 could take quite a long time period. 797 798 =head2 USING THE CALLBACK SUBROUTINE APPROACH 799 800 Using the callback approach involves requesting the data be sent 801 to a callback subroutine as each entry arrives at the client. 802 803 A callback is just a subroutine that is passed two parameters when 804 it is called, the mesg and entry objects. 805 806 Example: 807 808 use Net::LDAP; 809 810 $ldap = Net::LDAP->new('ldap.acme.com') or die "$@"; 811 $mesg = $ldap->search( 812 base => "o=acme.com", 813 scope => 'sub', 814 filter => "sn=smith", 815 callback => \&callback, 816 ); 817 # 818 # At this point the user needs to check the status of the 819 # ldap search. 820 # 821 822 if ( $mesg->code ) 823 { 824 $errstr = $mesg->code; 825 print "Error code: $errstr\n"; 826 $errstr = ldap_error_text($errstr); 827 print "$errstr\n"; 828 } 829 830 831 sub callback 832 { 833 my ( $mesg, $entry) = @_; 834 835 # 836 # First you must check to see if something was returned. 837 # Last execution of callback subroutine will have no 838 # defined entry and mesg object 839 # 840 if ( !defined($entry) ) 841 { 842 print "No records found matching filter $match.\n" 843 if ($mesg->count == 0) ; # if mesg is not defined nothing will print. 844 return; 845 } 846 847 my $dn = $entry->dn; # Obtain DN of this entry 848 849 @attrs = $entry->attributes; # Obtain attributes for this entry. 850 foreach my $var (@attrs) 851 { 852 #get a list of values for a given attribute 853 $attr = $entry->get_value( $var, asref => 1 ); 854 if ( defined($attr) ) 855 { 856 foreach my $value ( @$attr ) 857 { 858 print "$var: $value\n"; # Print each value for the attribute. 859 } 860 } 861 } 862 # 863 # For large search requests the following 2 lines of code 864 # may be very important, they will reduce the amount of memory 865 # used by the search results. 866 # 867 # If the user is not worried about memory useage then the 2 lines 868 # of code can be omitted. 869 # 870 $mesg->pop_entry; 871 872 } # End of callback subroutine 873 874 As you can see the example is straight forward and it does not waste 875 time waiting for all of the entries to be returned. However if the 876 pop_entry method is not used the callback approach can allocate a 877 lot of memory to the search request. 878 879 =head1 USING NET::LDAPS 880 881 =head2 Using an SSL network connection, how do I connect to my server? 882 883 This class is a subclass of Net::LDAP so all the normal 884 Net::LDAP methods can be used with a Net::LDAPS object; 885 see the documentation for Net::LDAP to find out how to 886 query a directory server using the LDAP protocol. 887 888 The connection to the server is created when you create a new Net::LDAPS 889 object, e.g. 890 891 $ldaps = Net::LDAPS->new($server, 892 port => '10000', 893 verify => 'require', 894 capath => '/usr/local/cacerts/', 895 ); 896 897 Starting with version 0.28 perl-ldap also supports URIs in the new method. 898 So, the above can also be expressed as: 899 900 $ldaps = Net::LDAP->new("ldaps://$server", 901 port => '10000', 902 verify => 'require', 903 capath => '/usr/local/cacerts/', 904 ); 905 906 There are additional options to the new method with LDAPS URIs 907 and the LDAPS new method and several additional methods are 908 included in the LDAPS object class. 909 910 For further information and code examples read the LDAPS 911 module documentation; perldoc Net::LDAPS 912 913 =head1 USING LDAP GROUPS. 914 915 =head2 What are LDAP groups. 916 917 LDAP groups are object classes that contain an attribute that can 918 store multiple DN values. Two standard object classes are 919 'groupOfNames' (which has a 'member' attribute) and 920 'groupOfUniqueNames' (which has a 'uniqueMember' attribute.) 921 922 According to the RFCs a group can be a member of another group, 923 but some LDAP server vendors restrict this flexibility by not 924 allowing nested groups in their servers. 925 926 Two scripts for working with groups are available in the contrib 927 directory. They are isMember.pl and printMembers.pl. 928 929 =head2 How do you format a filter to search for entries whose 'member' 930 attribute has a particular value? 931 932 Asking for (member=*) is OK - the directory uses the equality matching 933 rule which is defined for the member attribute. 934 935 Asking for (member=c*) is not OK - there is no defined substring 936 matching rule for the member attribute. That's because the member 937 values are *not* strings, but distinguished names. There is no 938 substring matching rule for DNs, see RFC 2256 section 5.50. 939 940 What you have to do is get the results of (member=*) and then select 941 the required results from the returned values. You need to do this 942 using knowledge of the string representation of DNs defined in RFC 943 2253, which is important because the same DN can have different string 944 representations. So you need to perform some canonicalization if you 945 want to be correct. 946 947 948 =head1 USING DSML. 949 950 =head2 How can I access DSML features from PERL-LDAP. 951 952 Directory Service Markup Language (DSML) is the XML 953 standard for representing directory service information in 954 XML. 955 956 Support for DSML is included in PERL-LDAP starting with version 957 .20. 958 959 At the moment this module only reads and writes DSML entry 960 entities. It cannot process any schema entities because 961 schema entities are processed differently than elements. 962 963 Eventually this module will be a full level 2 consumer and 964 producer enabling you to give you full DSML conformance. 965 966 The specification for DSML is at http://www.oasis-open.org/specs/ 967 968 For further information and code examples read the DSML 969 module documentation; perldoc Net::LDAP::DSML 970 971 =head1 USING CONTROLS AND VIRTUAL LISTS. 972 973 =head2 How do I access the Control features. 974 975 Support for LDAP version 3 Control objects is included in 976 perl-ldap starting with version .20. 977 978 For further information and code examples read the Control 979 module documentation; perldoc Net::LDAP::Control 980 981 =head2 How do I access the Virtual List features. 982 983 Support for Virtual Lists is included in perl-ldap starting 984 with version .20. 985 986 For further information and code examples read the Control 987 module documentation; perldoc Net::LDAP::Control 988 989 =head1 GENERAL QUESTIONS. 990 991 =head2 Are there any other code examples. 992 993 Yes, there is an Examples pod file. To view the pod 994 do the following command; perldoc Net::LDAP::Examples 995 996 There is user contributed software in the contrib directory 997 that is supplied with the PERL-LDAP distribution. This is an 998 excellent source of information on how to use the PERL-LDAP module. 999 1000 =head2 Are there any performance issues with perl-ldap ? 1001 1002 In the vast majority of use cases (one user has suggested 9 out of 10) 1003 there are no performance issues with perl-ldap. 1004 1005 Where you may wish to use perl-ldap to perform, for example, a very 1006 large number of queries (e.g. 10,000) in succession you may find a 1007 noticeable performance difference between perl-ldap and non pure-perl 1008 modules. This is not because of perl-ldap itself but because of the 1009 pure-perl Convert::ASN1 module that it depends on. 1010 1011 You should make up your own mind, based upon your own situation 1012 (performance requirements, hardware etc.) as to whether you should use 1013 perl-ldap or not. The figures quoted in this answer are only 1014 indicative, and will differ for different people. 1015 1016 =head2 Can I contribute perl scripts that use perl-ldap 1017 to the contrib section? 1018 1019 Any one can submit a perl script that uses perl-ldap for inclusion 1020 in the contrib section. Graham Barr will determine if the script 1021 will be included and will do the initial check in of the script 1022 to the SVN system on http://svn.mutatus.co.uk. Graham will make you 1023 the owner/developer of the script. 1024 1025 There are a couple of requirements for consideration. 1026 1027 You must supply a one line description of your script to be included 1028 in the contrib readme file. 1029 1030 Inside the script will be the pod documentation for the script. 1031 No auxiliary documentation will be allowed. For examples of how 1032 to do this see the tklkup script currently in the contrib section. 1033 1034 =head2 Is it possible to get a complete entry, DN and attributes 1035 without specifying the attributes name? 1036 1037 Yes, just specify you want a list of no attributes back. The RFC says 1038 that this tells the server to return all readable attributes back 1039 (there may be access controls to prevent some from being returned.) 1040 1041 So in the search method, just set (for LDAPv2): 1042 1043 attrs => [ ] 1044 1045 If you are using LDAPv3, you can specify an attribute called "*" 1046 instead, which lets you ask for additional (i.g. operational) attributes 1047 in the same search. 1048 1049 attrs => [ "*" ] 1050 1051 To get all operational attributes in a search, some servers allow 1052 the use of the "+" pseudo attribute. So that with these servers 1053 1054 attrs => [ "*", "+" ] 1055 1056 will return the most information from the server. 1057 1058 =head2 How do I put a JPEG photo into a entry in the directory. 1059 1060 Follow the following code example, replacing the (...) with 1061 whatever is relevant to your setup. 1062 1063 use Net::LDAP; 1064 use Net::LDAP::Util qw(ldap_error_text); 1065 use CGI; 1066 1067 local $/ = undef; 1068 my $jpeg = <$filename>; 1069 1070 my $ldap = Net::LDAP->new(...); 1071 my $res = $ldap->bind(...); 1072 $res = $ldap->modify(..., 1073 add => [ 'jpegPhoto' => [ $jpeg ] ]); 1074 $res = $ldap->unbind(); 1075 1076 1077 =head2 How do I add a jpeg photo into a entry in the directory via html-forms. 1078 1079 Follow the following code example, replacing the (...) with 1080 whatever is relevant to your setup. 1081 1082 use Net::LDAP; 1083 use Net::LDAP::Util qw(ldap_error_text); 1084 use CGI; 1085 1086 my $q = new CGI; 1087 1088 print $q->header; 1089 print $q->start_html(-title => 'Change JPEG photo'); 1090 1091 if ($q->param('Update')) { 1092 my $filename = $q->param('jpeg'); 1093 local $/ = undef; 1094 my $jpeg = <$filename>; 1095 1096 my $ldap = Net::LDAP->new(...); 1097 my $res = $ldap->bind(...); 1098 $res = $ldap->modify(..., 1099 add => [ 'jpegPhoto' => [ $jpeg ] ]); 1100 $res = $ldap->unbind(); 1101 } else { 1102 print $q->start_multipart_form(); 1103 print $q->filefield(-name => 'jpeg', -size => 50); 1104 print $q->submit('Update'); 1105 print $q->end_form(); 1106 } 1107 1108 print $q->end_html(); 1109 1110 =head2 What happens when you delete an attribute that does not exist. 1111 1112 It is an error to delete an attribute that doesn't exist. When you 1113 get the error back the server ignores the entire modify operation 1114 you sent it, so you need to make sure the error doesn't happen. 1115 1116 Another approach, if you are using LDAPv3 (note beginning with version .27 1117 Net::LDAP uses LDAPv3 by default) is to use a 'replace' with your 1118 attribute name and no values. 1119 In LDAPv3, this is defined to always work even if that attribute 1120 doesn't exist in the entry. 1121 1122 ie: 1123 1124 my $mesg = $ldap->modify( $entry, replace => { %qv_del_arry } ); 1125 1126 But make sure you are using LDAPv3, because that is defined to B<not> work 1127 in LDAPv2. (A nice incompatibility between LDAPv2 and LDAPv3.) 1128 1129 =head2 How can I delete a referral from an LDAP tree. 1130 1131 Since this is a proprietary feature, you will have to check your 1132 server's documentation. You might find that you need to use a control. If 1133 there is a control called something like managedsait, that's the one you 1134 should probably use. For proper operation you will need the oid number 1135 for managedsait; 2.16.840.1.113730.3.4.2 and do not specify a value for 1136 type. 1137 1138 The code required will look similar to the following code snippet. 1139 1140 $mesg = $ldap->delete("ref=\"ldap://acme/c=us,o=bricks\",o=clay", 1141 control => {type => "2.16.840.1.113730.3.4.2"} ); 1142 1143 =head2 How do I add an ACI/ACL entry to a directory server with 1144 Perl-LDAP. 1145 1146 ACIs and ACLs are proprietary features in LDAP. The following code 1147 snippet works with a Netscape directory server. You will need the 1148 specify the correct DN (-DN-) and correct attribute(s) (-nom attr-). 1149 1150 my $aci = '(target="ldap:///-DN-")(targetattr="-nom attr-")(version 3.0; 1151 acl "-nom acl-"; deny(all) userdn = "ldap:///self";)' ; 1152 1153 $ldap->modify($dn_modif, add => {'aci' => $aci }); 1154 1155 =head2 How do I avoid file type and data type mis-matching when loading 1156 data from a Win32 system. 1157 1158 When loading a binary attribute with data read from a file on a Win32 1159 system, it has been noted that you should set "binmode" on the file 1160 before reading the file contents into the data array. 1161 1162 Another possible solution to this problem is to convert the 1163 binary data into a base64 encoded string and then store the encoded string 1164 in the file. Then when reading the file, decode the base64 encoded 1165 string back to binary and then use perl ldap to store the data 1166 in the directory. 1167 1168 =head2 How do I create a Microsoft Exchange 5.x user. 1169 1170 This is a solution provide by a perl-ldap user. 1171 1172 This code works with ActiveState Perl running on WinNT 4. Please note that 1173 this requires the Win32::Perms module, and needs valid NT account info to 1174 replace the placeholders. 1175 1176 use Net::LDAP; 1177 use Net::LDAP::Util; 1178 use Win32::Perms; 1179 1180 #Constants taken from ADSI Type Library 1181 $ADS_RIGHT_EXCH_ADD_CHILD = 1; 1182 $ADS_RIGHT_EXCH_DELETE = 0x10000; 1183 $ADS_RIGHT_EXCH_DS_REPLICATION = 64; 1184 $ADS_RIGHT_EXCH_DS_SEARCH = 256; 1185 $ADS_RIGHT_EXCH_MAIL_ADMIN_AS = 32; 1186 $ADS_RIGHT_EXCH_MAIL_RECEIVE_AS = 16; 1187 $ADS_RIGHT_EXCH_MAIL_SEND_AS = 8; 1188 $ADS_RIGHT_EXCH_MODIFY_ADMIN_ATT = 4; 1189 $ADS_RIGHT_EXCH_MODIFY_SEC_ATT = 128; 1190 $ADS_RIGHT_EXCH_MODIFY_USER_ATT = 2; 1191 1192 $EXCH_USER_RIGHTS = $ADS_RIGHT_EXCH_MAIL_RECEIVE_AS | 1193 $ADS_RIGHT_EXCH_MAIL_SEND_AS | 1194 $ADS_RIGHT_EXCH_MODIFY_USER_ATT; 1195 1196 $exch = Net::LDAP->new('server', debug =>0) || die $@; 1197 1198 $exch->bind( 'cn=admin_user,cn=nt_domain,cn=admin', version =>3, 1199 password=>'password'); 1200 1201 $myObj = Win32::Perms->new(); 1202 $Result = $myObj->Owner('nt_domain\user_name'); 1203 $myObj->Group('nt_domain\Everyone'); 1204 $myObj->Allow('nt_domain\user_name', 1205 $EXCH_USER_RIGHTS,OBJECT_INHERIT_ACE); 1206 $BinarySD = $myObj->GetSD(SD_RELATIVE); 1207 $TextSD = uc(unpack( "H*", $BinarySD )); 1208 Win32::Perms::ResolveSid('nt_domain\user_name', $sid); 1209 $mysid = uc(unpack("H*",$sid)); 1210 1211 $result = $exch->add ( dn => 1212 'cn=user_name,cn=container,ou=site,o=organisation', 1213 attr => [ 'objectClass' => ['organizationalPerson'], 1214 'cn' => 'directory_name', 1215 'uid' => 'mail_nickname', 1216 'mail' => 'smtp_address', 1217 'assoc-nt-account' => [ $mysid ], 1218 'nt-security-descriptor' => [ $TextSD ], 1219 'mailPreferenceOption' => 0 1220 ] 1221 ); 1222 1223 1224 print ldap_error_name($result->code); 1225 1226 =head2 Ho do I reset a user's password ... 1227 1228 =head3 Z<>... in most LDAP servers ? 1229 1230 Most LDAP servers use the standard userPassword attribute as the 1231 attribute to set when you want to change a user's password. 1232 1233 They usually allow to set the password either using the regular 1234 modify operation on the userPassword attribute or using the 1235 extended LDAP Password Modify operation defined in RFC3062. 1236 1237 The recommended method is the extended Password Modify operation, 1238 which offers a standardized way to set user passwords but 1239 unfortunately is not available on all LDAP servers. 1240 1241 Whether the extended Password Modify operation is available can be 1242 found out by searching the attribute supportedExtension for the 1243 value 1.3.6.1.4.1.4203.1.11.1 in the RootDSE object. 1244 1245 If the extended Password Modify operation is not avaiable the 1246 alternative is the regular modification of the userPassword attribute. 1247 1248 But this method has some drawbacks: 1249 1250 =over 4 1251 1252 =item * 1253 1254 Depending on the type of the server the arguments to the modify 1255 operations may vary. Some want the modify done with replace, 1256 some want it done by explicitely deleting the old password 1257 and add of the new one. 1258 This may even depend on whether you change the password for the bound 1259 user or as an administrator for another user. 1260 1261 =item * 1262 1263 With the modify operation some servers expect the client to 1264 do the hashing of the password on the client side. I.e. all 1265 clients that set passwords need to agree on the algorithm 1266 and the format of the hashed password. 1267 1268 =item * 1269 1270 Some LDAP servers do not allow setting the password if the 1271 connection is not sufficiently secured. I.e. require SSL or TLS 1272 support to set the password (which is heavily recommended anyway ;-) 1273 1274 =back 1275 1276 Here is an example of how to change your own password (for brevity's 1277 sake error checking is left out): 1278 1279 use Net::LDAP; 1280 1281 my $ldap = Net::LDAP->new('ldaps://server.domain') or die "$@"; 1282 my $mesg = $ldap->bind('cn=Joe User,dc=perl,dc=ldap,dc=org', 1283 password => 'oldPW'); 1284 1285 my $rootdse = $ldap->root_dse(); 1286 1287 if ($rootdse->supported_extension('1.3.6.1.4.1.4203.1.11.1') { 1288 1289 require Net::LDAP::Extension::SetPassword; 1290 1291 $mesg = $ldap->set_password(user => 'cn=Joe User,dc=perl,dc=ldap,dc=org', 1292 oldpasswd => 'oldPW', 1293 newpasswd => 'newPW'); 1294 } 1295 else { 1296 $mesg = $ldap->modify('cn=Joe User,dc=perl,dc=ldap,dc=org', 1297 changes => [ 1298 delete => [ userPassword => $oldPW ] 1299 add => [ userPassword => $newPW ] ]); 1300 } 1301 1302 $ldap->unbind(); 1303 1304 =head3 Z<>... in MS Active Directory ? 1305 1306 With Active Directory a user's password is stored in the unicodePwd 1307 attribute and changed using the regular modify operation. 1308 1309 ADS expects this password to be encoded in Unicode - UTF-16 to be exact. 1310 Before the unicode conversion is done the password needs to be 1311 surrounded by double quotes which do not belong to the user's password. 1312 1313 For the password modify operation to succeed SSL is required. 1314 1315 When changing the password for the user bound to the directory 1316 ADS expects it to be done by deleting the old password and 1317 adding the new one. 1318 When doing it as a user with administrative priviledges replacing 1319 the unicodePwd's value with a new one is allowed too. 1320 1321 Here's an example that demonstrates setting your own password 1322 (again almost no error checking): 1323 1324 use Net::LDAP; 1325 use Unicode::Map8; 1326 use Unicode::String qw(utf16); 1327 1328 # build the conversion map from your local character set to Unicode 1329 my $charmap = Unicode::Map8->new('latin1') or die; 1330 1331 # surround the PW with double quotes and convert it to UTF-16 1332 # byteswap() was necessary in experiments on i386 Linux, YMMV 1333 my $oldUniPW = $charmap->tou('"'.$oldPW.'"')->byteswap()->utf16(); 1334 my $newUniPW = $charmap->tou('"'.$newPW.'"')->byteswap()->utf16(); 1335 1336 my $ldap = Net::LDAP->new('ldaps://ads.domain.controller') or die "$@"; 1337 1338 my $mesg = $ldap->bind('cn=Joe User,dc=your,dc=ads,dc=domain', 1339 password => 'oldPW'); 1340 1341 $mesg = $ldap->modify('cn=Joe User,dc=your,dc=ads,dc=domain', 1342 changes => [ 1343 delete => [ unicodePwd => $oldUniPW ] 1344 add => [ unicodePwd => $newUniPW ] ]); 1345 1346 $ldap->unbind(); 1347 1348 1349 =head2 How can I simulate server failover. 1350 1351 Perl-LDAP does not do server failover, however there are several 1352 programming options for getting around this situation. 1353 1354 Here is one possible solution. 1355 1356 unless ( $ldaps = 1357 Net::LDAPS->new($ldapserverone, 1358 port=>636,timeout=>5) ) 1359 { 1360 $ldaps = Net::LDAPS->new($ldapservertwo, 1361 port=>636,timeout=>20) || 1362 return 1363 "Can't connect to $ldapserverone or $ldapservertwo via LDAPS: $@"; 1364 } 1365 1366 As of version 0.27 of perl-ldap the above can be expressed much simpler: 1367 1368 $ldaps = Net::LDAPS->new([ $ldapserverone, $ldapservertwo ], 1369 port=>636, timeout=>5) or die "$@"; 1370 1371 1372 =head1 Using X.509 certificates. 1373 1374 =head2 How do I store X.509 certificates in the directory? 1375 1376 The first problem here is that there are many different formats to hold 1377 certificates in, for example PEM, DER, PKCS#7 and PKCS#12. The directory 1378 B<only> uses the DER format (more correctly, it only uses the BER format) 1379 which is a binary format. 1380 1381 Your first job is to ensure that your certificates are therefore in DER/BER 1382 format. You could use OpenSSL to convert from PEM like this: 1383 1384 openssl x509 -inform PEM -in cert.pem -outform DER -out cert.der 1385 1386 Consult the OpenSSL documentation to find out how to perform other 1387 conversions. 1388 1389 To add a certificate to the directory, just slurp in the DER/BER 1390 certificate into a scalar variable, and add it to the entry's 1391 userCertificate attribute. How you do that will depend on which version of 1392 LDAP you are using. 1393 1394 To slurp in the certificate try something like this: 1395 1396 my $cert; 1397 { 1398 local $/ = undef; # Slurp mode 1399 open CERT, "cert.der" or die; 1400 binmode CERT; 1401 $cert = <CERT>; 1402 close CERT; 1403 } 1404 # The certificate is now in $cert 1405 1406 For LDAPv2, because most directory vendors ignore the string representation 1407 of certificates defined in RFC 1778, you should add this value to the 1408 directory like this: 1409 1410 $res = $ldap->modify("cn=My User, o=My Company,c=XY", 1411 add => [ 1412 'userCertificate' => [ $cert ] 1413 ]); 1414 die "Modify failed (" . ldap_error_name($res->code) . ")\n" 1415 if $res->code; 1416 1417 For LDAPv3, you must do this instead: 1418 1419 $res = $ldap->modify("cn=My User, o=My Company, c=XY", 1420 add => [ 1421 'userCertificate;binary' => [ $cert ] 1422 ]); 1423 die "Modify failed (" . ldap_error_name($res->code) . ")\n" 1424 if $res->code; 1425 1426 Of course, the entry you are trying to add the certificate to must use 1427 object classes that permit the userCertificate attribute, otherwise the 1428 modify will fail with an object class violation error. The inetOrgPerson 1429 structural object class permits userCertificates, as does the 1430 strongAuthenticationUser auxiliary object class. Others might also. 1431 1432 =head1 ADDITIONAL DIRECTORY AND LDAP RESOURCES. 1433 1434 =head2 URLs. 1435 1436 Directory Services Mark Language (DSML) 1437 http://www.oasis-open.org/specs/ 1438 1439 eMailman LDAP information 1440 http://www.emailman.com/ldap/ 1441 1442 Rafael Corvalan's LDAP shell 1443 http://sf.net/projects/ldapsh 1444 1445 LDAPS, also known as LDAPGURU. 1446 I<This web site has a nasty habit of resizing the browser 1447 to cover the WHOLE screen.> 1448 http://www.ldaps.com 1449 1450 Jeff Hodges's Kings Mountain LDAP 1451 http://www.kingsmountain.com/ldapRoadmap.shtml 1452 1453 Mark Wahl's LDAP World at Innosoft. 1454 http://www.innosoft.com/ldapworld/ 1455 (outdated: last update was in 1998) 1456 1457 Open Source LDAP Directory Server. 1458 http://www.openldap.org/ 1459 1460 CriticalPath 1461 http://www.cp.net/ 1462 1463 IBM Directory Server 1464 http://www-306.ibm.com/software/network/directory/server/ 1465 1466 Innosoft 1467 http://www.innosoft.com 1468 (acquired by Sun) 1469 1470 Isode (was MessagingDirect) 1471 http://www.isode.com/ 1472 1473 Netscape Directory Developers Area 1474 http://developer.netscape.com/directory/ 1475 1476 Nexor's X.500 and Internet Directories 1477 http://www.nexor.com/info/directory.htm/ 1478 1479 Novell's eDirectory 1480 http://www.novell.com/ 1481 1482 Novell's LDAPzone 1483 http://ldapzone.com/ 1484 1485 Octet String 1486 http://www.octetstring.com/ 1487 1488 SUN JAVA JNDI (Java Naming and Directory Interface) 1489 http://www.java.sun.com/jndi/ 1490 1491 Sun One, formerly Iplanet. 1492 http://wwws.sun.com/software/ 1493 1494 Eine deutsche LDAP Website 1495 A german LDAP Website 1496 http://verzeichnisdienst.de/ldap/Perl/index.html 1497 1498 The 2 following URLs deal mainly with Microsoft's 1499 Active Directory. 1500 1501 Directory Works 1502 http://directoryworks.com/ 1503 1504 ActiveX LDAP Client 1505 http://www.polonia-online.com/ldap/ 1506 1507 =head2 BOOKS 1508 1509 Developing LDAP and ADSI Clients for Microsoft(R) Exchange. 1510 By Sven B. Schreiber. ISBN: 0201657775 1511 1512 Implementing LDAP. 1513 By Mark Wilcox. ISBN: 1861002211 1514 1515 LDAP: Programming Directory-Enabled Applications With 1516 Lightweight Directory Access Protocol. 1517 By Tim Howes, Mark Smith. ISBN: 1578700000 1518 1519 LDAP Programming; Directory Management and Integration. 1520 By Clayton Donley. ISBN: 1884777910 1521 1522 LDAP Programming with Java. 1523 By Rob Weltman, Tony Dahbura. ISBN: 0201657589 1524 1525 LDAP System Administration. 1526 By Gerald Carter. ISBN: 1565924916 1527 1528 Managing Enterprise Active Directory Services. 1529 By Robbie Allen, Richard Puckett. ISBN: 0672321254 1530 1531 Solaris and LDAP Naming Services. 1532 By Tom Bialaski, Michael Haines. ISBN: 0-13-030678-9 1533 1534 Understanding and Deploying LDAP Directory Services (2ed). 1535 By Tim Howes, Mark Smith, Gordon Good. 1536 ISBN: 0672323168 1537 1538 LDAP Directories Explained. 1539 By Brian Arkills. ISBN 0-201-78792-X 1540 1541 =head1 AUTHORS 1542 1543 Any good FAQ is made up of many authors, everyone that contributes 1544 information to the perl-ldap mail list is a potential author. 1545 1546 An attempt to maintain this FAQ is being done by Chris Ridd 1547 E<lt>chris.ridd@isode.comE<gt> and Peter Marschall <peter@adpm.de>. 1548 It was previously updated by Clif Harden E<lt>charden@pobox.comE<gt>. 1549 1550 The original author of this FAQ was Graham Barr E<lt>gbarr@pobox.comE<gt> 1551 1552 Please report any bugs, or post any suggestions, to the 1553 perl-ldap mailing list E<lt>perl-ldap@perl.orgE<gt>. 1554 1555 =head1 COPYRIGHT 1556 1557 Copyright (c) 1999-2004 Graham Barr. All rights reserved. This document is 1558 distributed, and may be redistributed, under the same terms as Perl itself. 1559 1560 =cut
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |