Transcript Got LDAP?
PerLDAP
LDAP for the rest of us!
Leif Hedstrom
Agenda
• Why PerLDAP? History of PerLDAP • Introduction to Perl and Perl Objects • Installing PerLDAP • Overview of the PerLDAP architecture – API ( API.pm
) – Connections ( Conn.pm
) – Entries ( Entry.pm
) – Other ( Util.pm
, LDIF.pm
, and more) Netscape Training 4/25/2020 2
Agenda (cont.)
• Simple tasks (examples) – Authentication – Searching for entries – Modifying entries – Deleting an entry – Adding an entry • Case study: modattr.pl
• Future directions, contributions etc.
Netscape Training 4/25/2020 3
Why PerLDAP?
• Primary Goal: Easy to use!
• Why Perl? Powerful, feature rich, accepted “standard”, well known, easy to learn • Internal need at Netscape led to first implementation • C-API powerful, but too low level for simple tasks • But, PerLDAP is almost 100% “compatible” Netscape Training 4/25/2020 4
History
• Early 1997: Netscape IS needs tools for LDAP management • Continued development of a Perl module named Ldapp • Aug 1998: Code merge of Ldapp and Clayton Donley’s Perl API • Now: PerLDAP v1.2.2 released, v1.4 next Netscape Training 4/25/2020 5
Larry Wall on Perl5 Objects
• An
object
is simply a referenced thingy that happens to know which class it belongs to.
• A
class
is simply a package that happens to provide methods to deal with objects.
• A
method
expects an object reference (or a package name, for class methods) as it’s first argument.
is simply a subroutine that Netscape Training 4/25/2020 6
My comments on Perl5 Objects
• Not strictly Object Oriented – Not “real” inheritance (use @ISA) – Can not hide data (no private data) – No real datatypes, typically uses hash arrays – No difference on class and instance methods • Methods are regular Perl functions, instance pointer passed as first argument • Kludge?
Netscape Training 4/25/2020 7
Example: Perl5 object/module
package Netscape::Test; sub new { my ($class, $init) = @_; my $self = {}; # Hash array class “data” $self->{status} = “Some Value”; $self->init($init); # Call class initializer ...
Return bless $self, $class; } sub DESTROY { ...
} 1; Netscape Training 4/25/2020 8
Example: Using the new class
#!/usr/bin/perl5 use Netscape::Test; $tester = new Netscape::Test(); $tester2 = new Netscape::Test( {foo => “bar”}); $tester->doSomething(“argument”); print “Status is “, $tester->{status}, “\n”; delete $tester; Netscape Training 4/25/2020 9
Installing PerLDAP
• v1.2 is available in /tools/ns (for perl5.004) • Source from Mozilla (cvs) and DevEdge • Requires Perl v5.004 or later (get v5.005_03 if possible!) • Needs an ANSI C compiler, e.g. gcc • C-SDK v1.0 or v3.0, on Unix and Win/NT • Standard Perl installation, Makefile.PL
Netscape Training 4/25/2020 10
PerLDAP architecture
• Three layers – C-SDK, LDAP functionality – API.so/API.pm interfaces Perl and the SDK – Object Oriented “glue”, synchronous LDAP only, but next version might use asynchronous calls • You can write PerLDAP scripts that are similar/compatible with the plain C-API.
• Easier: Use the OO layer Netscape Training 4/25/2020 11
API.so and API.pm
• Implements the C-SDK functions, see PerLDAP Programmer’s Guide for details • Can be used directly from Perl scripts, by “use” of the API.pm module • Should be completely LDAP v2 and v3 capable, but many new v3 features are not well tested • Avoid using it unless you need the low level features. Better, write an OO module!
Netscape Training 4/25/2020 12
Getting a connection: Conn.pm
• Core module/object for handling a connection to an LDAP server • Main methods: – new Create new LDAP connection – search – searchURL – nextEntry – newEntry Perform an LDAP search Like search, but with a URL Retrieve subsequent entries Create an empty Entry object Netscape Training 4/25/2020 13
Conn.pm methods (cont.)
– delete Delete an LDAP entry – add Add a new entry – modifyRDN Change the RDN of an entry – update – close Commit changes made to entry Close the LDAP connections Netscape Training 4/25/2020 14
Conn.pm methods (cont.)
• Error handling – getErrorCode: – getErrorString: – printEror: Get the last error code Get the last error string Print the last error (stdout) – In general: Returns “null” or False on errors – No exception handling in Perl… ;-( Netscape Training 4/25/2020 15
Conn.pm methods (cont.)
• Other methods – simpleAuth: Perform a new bind operation – isURL: – getRes: – getLD: Is a string a proper LDAP URL?
Get internal result handle Get internal LDAP handle – setRebindProc: – setDefaultRebindProc: Rebind proc “simple” rebind Netscape Training 4/25/2020 16
Example: Getting connected
$conn = new Mozilla::LDAP::Conn(\%ld); die “Wow, you suck!” unless $conn; $conn = new Mozilla::LDAP::Conn({“host” => “ldap”, “port” => “389”, “bind” => $dn, “pswd” => $pswd}); $conn = new Mozilla::LDAP::Conn(“ldap”,”389”); $conn = new Mozilla::LDAP::Conn(“ldap”, “636”,$dn, $pwd, $certfile); Netscape Training 4/25/2020 17
Connection parameters
#1 #2 #3 #4 #5
host port bind pswd cert
=> LDAP host name => TCP port to connect to => DN to bind as => Password to authenticate => Path to CertDB file (#3 - #5 are optional, defaults to anonymous) Netscape Training 4/25/2020 18
Manage your entry: Entry.pm
• Returned by the Conn::search() and Conn::nextEntry() methods • Basically a Perl hash array (uses TieHash) • Attribute value is a pointer to an array, except DN which is a single value • You can use normal Perl functions to retrieve, delete and modify values • But, plenty of class/instance methods!
Netscape Training 4/25/2020 19
Entry.pm methods
• Manipulating attributes – addValue: – addDNValue: – removeValue: Add an attribute value Add a DN value Remove an attribute value – removeDNValue: Remove DN value – setValue: Replace the entire attribute – remove: – unRemove: Delete an entire attribute Undo remove/removeValue Netscape Training 4/25/2020 20
Entry.pm methods (cont.)
• Query methods – isModified: – isDeleted: – isAttr: Has attribute been touched?
Has the attribute been deleted?
Is the argument a valid attribute?
– hasValue: Does the attribute have value?
– hasDNValue: Like hasValue, but DN normalized – matchValue: Like hasValue, but use regexps – matchDNValue: Like matchValue, but DNs Netscape Training 4/25/2020 21
Entry.pm methods (cont.)
– size: Return the number of values in an attr.
– exists: Legacy code, use isAttr() instead • Other methods – printLDIF: Print entry in LDIF format – attrModified: Mark an attribute as modified – getDN: – setDN: – new: Get the entry DN Set the entry DN (use with add ) Create a new, empty, entry Netscape Training 4/25/2020 22
Entry.pm methods (cont.)
• TieHASH methods – STORE: Catch attribute modifications – FETCH:Catch attribute retrievals – DELETE: Catch deleting entire attributes – EXISTS: – FIRSTKEY: – NEXTKEY: Does the attribute/key exist?
Get the first attribute in entry Get next attribute in entry Netscape Training 4/25/2020 23
Examples: Entry.pm methods
print “CN is “, $entry->{cn}[0], “\n”; print “DN is “, $entry->{dn}, “\n”; print “DN is “, $entry->getDN(), “\n”; $entry->{sn} = [“Hedstrom”, “The Swede”]; $entry->setDN(“uid=leif,dc=ogre,dc=com”); $entry->setValue(“foo”, (“a”, “b”, “c”)); $entry->addValue(“mail”, “[email protected]”); $entry->removeValue(“cn”, “The Swede”); $entry->removeDNValue(“seeAlso”, $value); delete $entry->{description}; $entry->delete(“description”); if ($entry->hasValue(“mail”, “[email protected]”, 1)){ foreach $attr (keys(%{$entry})) { Netscape Training 4/25/2020 24
Other modules
• Utils.pm contains lots of useful little utilities • LDIF.pm to work with LDIF file. New version on the way, contributed by John Kristian (available as of v1.3.1) • Lots of useful modules on CPAN, like MIME::Base64 – perl5 -MCPAN -e shell Netscape Training 4/25/2020 25
Example: Authentication
#!/usr/bin/perl5 use Mozilla::LDAP::Conn; #setup global parameters, using Getopt $srch = “(uid=“ . $ENV{USER} . “); $c = new Mozilla::LDAP::Conn($host,$port); $entry = $c->search($base, “SUB”, $srch); if ($entry && !$c->nextEntry() { $dn = $entry->getDN(); die “Bummer dude!” unless $conn->simpleAuth($dn,$pwd); # We had a good authentication, go on!
} $c->close() if $c; Netscape Training 4/25/2020 26
Example: Simple searches
#!/usr/bin/perl5 use Mozilla::LDAP::Conn; #setup global parameters, using Getopt $c = new Mozilla::LDAP::Conn(\%ld); $entry = $c->search($base, “ONE”, $srch); while ($entry) { $entry->printLDIF(); $entry = $c->nextEntry(); } $c->close() if $c; Netscape Training 4/25/2020 27
Example: Modifying entries
#!/usr/bin/perl5 use Mozilla::LDAP::Conn; #setup global parameters, using Getopt $c = new Mozilla::LDAP::Conn(\%ld); $entry = $c->search($base, $sc, $srch); while ($entry) { $entry->setValue(“mailhost”)=[$host]; $c->update($entry); $entry = $c->nextEntry(); } $c->close() if $c; Netscape Training 4/25/2020 28
Example: Deleting entries
#!/usr/bin/perl5 use Mozilla::LDAP::Conn; #setup global parameters, using Getopt $srch = “(mailhost=tintin.netscape.com)”; $c = new Mozilla::LDAP::Conn(\%ld); $entry = $c->search($base, “SUB”, $srch); while ($entry) { $c->delete($entry->getDN()); $entry = $c->nextEntry(); } $c->close() if $c; Netscape Training 4/25/2020 29
Example: Adding an entry
#!/usr/bin/perl5 use Mozilla::LDAP::Conn; #setup global parameters, using Getopt $ent = Mozilla::LDAP::Conn::newEntry(); $ent->setDN(“uid=leif,dc=ogre,dc=com”); $ent->{objectclass} = [ “top”, “person” ]; $ent->addValue(“cn”, “Leif Hedstrom”); $ent->addValue(“sn”, “Hedstrom”); ...
$c = new Mozilla::LDAP::Conn(\%ld); $c->add($ent); $c->close() if $c; Netscape Training 4/25/2020 30
Case study: modattr.pl
#!/usr/bin/perl5 use Getopt::Std; use Mozilla::LDAP::Conn; use Mozilla::LDAP::Utils; use strict; no strict "vars"; $APPNAM = "modattr"; $USAGE = "$APPNAM [-dnvW] -b base -h host -D bind\ -w pswd -P cert attr=value filter"; if (!getopts('adnvWb:h:D:p:s:w:P:')) { print "usage: $APPNAM $USAGE\n"; exit; } %ld = Mozilla::LDAP::Utils::ldapArgs(); Mozilla::LDAP::Utils::userCredentials(\%ld) unless $opt_n; Netscape Training 4/25/2020 31
Case study: modattr.pl
$conn = new Mozilla::LDAP::Conn(\%ld); die "Couldn't connect to LDAP server $ld{host}" unless $conn; $conn->setDefaultRebindProc($ld{bind}, $ld{pswd}); ($change, $search) = @ARGV; if (($change eq "") || ($search eq "")) { print "usage: $APPNAM $USAGE\n"; exit; } ($attr, $value) = split(/=/, $change, 2); $entry = $conn->search($ld{root}, $ld{scope}, $search); while ($entry) { $changed = 0; if ($opt_d) { if (defined $entry->{$attr}) { Netscape Training 4/25/2020 32
Case study: modattr.pl
if ($value) { $changed = $entry->removeValue($attr, $value); if ($changed && $opt_v) { print "Removed value from ", $entry->getDN(), "\n" if $opt_v; } } else { delete $entry->{$attr}; print "Deleted attribute $attr for ", $entry->getDN(), "\n" if $opt_v; $changed = 1; } } else { print "No attribute values for: $attr\n"; } } else { Netscape Training 4/25/2020 33
Case study: modattr.pl
} if (!defined($value) || !$value) { print "No value provided for the attribute $attr\n"; } elsif ($opt_a) { $changed = $entry->addValue($attr, $value); if ($changed && $opt_v) { print "Added attribute to ", $entry->getDN(), "\n" if $opt_v; } } else { $entry->setValue($attr, $value); $changed = 1; print "Set attribute for ", $entry->getDN(), "\n" if $opt_v; } Netscape Training 4/25/2020 34
Case study: modattr.pl
} if ($changed && !$opt_n) { $conn->update($entry); conn->printError() if $conn->getErrorCode(); } $entry = $conn->nextEntry(); $conn->close() if $conn; Netscape Training 4/25/2020 35
Using modattr.pl
• Use “standard” LDAP arguments (-h etc.) • Use “-n” to see what would be done (safe) • Add an attribute value – modattr.pl -a cn=“Leif Hedstrom” (‘uid=leif)’ – modattr.pl -a mailHost=tintin ‘(uid=*)’ • Deleting an entire attribute – modattr.pl -d salary ‘(department=IS)’ Netscape Training 4/25/2020 36
Using modattr.pl (cont.)
• Deleting an individual attribute value – modattr.pl -d cn=“Leif Hedstrom” ‘(uid=leif)’ – modattr.pl -d l=“Bld 4” ‘(uid=*)’ • POD documentation is included with the script, for more details. – pod2text modattr.pl
– pod2html modattr.pl
Netscape Training 4/25/2020 37
Future directions
• v1.4 soon to be released, v1.3 is currently being developed (it’s a developers branch) • Tons of ideas: – Modules for LDAP v3 features like controls, persistent searches, SASL etc.
– Managing Netscape Console server info via PerLDAP – Managing LDAP servers, like schema, index Netscape Training 4/25/2020 38
Future directions (cont.)
– LDAP group management module – Configuration module (global configurations) – New argument parser, to handle all options as DS-4.0 clients does • Still need more help, the OpenSource model hasn’t really taken off with PerLDAP and the SDKs.
Netscape Training 4/25/2020 39
Resources
• http://www.mozilla.org/directory/ • http://www.perldap.org/ • http://www.perl.com/ • http://www.ogre.com/stuff/perl5/ • http://www.ogre.com/ldap/ • http://www.mozilla.org/directory/faq/perldap-faq.html
Netscape Training 4/25/2020 40