Vous êtes sur la page 1sur 16

What is LDAP?

Lightweight Directory Access Protocol


Lightweight Directory - Directories are kind of like a database but not really. A directory
is a specialized database that is optimized for lookups. Unlike a traditional RDBMS, LDAP
is not designed to show complex relationships between relations. Imagine if 99% of your
actions on were going to be simple "selects", and you wanted anyone, anywhere to be
able to do these selects over the Internet. This is where LDAP excels. Examples of
directories are the TVGuide, the phone book, a library card catalog, and DNS.
"Give me the phone number of John Smith."
"Give me all the tv shows that are on tonight on the Sci-Fi channel."
Access Protocol - LDAP is an outgrowth of the x.500 standard. LDAP is an open standard,
unlike many other proprietary directory solutions. Most of the directory-like solutions
that were out on the market are now very similar to LDAP. Some of these solution
providers, Sun and Microsoft specifically, have designed JNDI and ADSI APIs so that you
can connect with any kind of directory service. This is kind of like ODBC or JDBC is to an
RDBMS.
Cool things you can do with LDAP
-Contact Management
-Users and Security
-Image storage
-Document Management
-Store business logic - actual code or SQL statements
-Your ideas?
How does LDAP work?
Client connects to server --> operations --> disconnect from server
These operations include:
1. binding to server
2. searching for an entry
3. comparing entries
4. adding an entry
5. modifying existing entries
6. removing an entry

What about LDAP heirarchies and schemas?
The directory schema is the outline of how the directory will be laid out and what kind of
information it will hold. You design your directorys schema by modifying some text
.conf files. Netscape has a gui to help you with this.
Example1: slapd.oc.conf objectclass conf file
Here is the file in which objectclasses are defined.
######################################################
objectclass person
oid 2.5.6.6
superior top
requires
sn,
cn
allows
description,
seeAlso,
telephoneNumber,
userPassword
Example 2: slapd.at.conf attribute conf file
Here is the file in which we define attributes of each objectclass are defined.
#######################################################
# X.500(93) User Schema for use with LDAP
# Taken from <draft-ietf-asid-ldapv3schema-x500-00.txt>
#######################################################
attribute objectClass 2.5.4.0 cis
attribute aliasedObjectName 2.5.4.1 dn
attribute knowledgeInformation 2.5.4.2 cis
attribute cn commonName 2.5.4.3 cis
attribute sn surName 2.5.4.4 cis
attribute serialNumber 2.5.4.5 cis
attribute c countryName 2.5.4.6 cis
...
The format of this file is:
attribute attribute-name [attribute-aliases] [attribute-oid] syntax
Example 3: building a directory
Uniqueness and Heirarchy. Each entry in the LDAP directory is expected to be unique
and heirarchical. All entries in an LDAP directory structure are uniquely identified through
their DN (distinguished name). Since the directory structure is potentially the entire
world, this means that each DN has to hold information that will make it unique in the
directory and in the world. The DN is therefore a kind of unique key. In addition, each
layer of the directory builds on the layer before it.
All this and more info goes into the LDIF file (LDAP Data Interchange Format). There are
a bunch of scripts and utilities to help you modify these files if you have a server.
You can make your own attributes. First you should make a new objectclass. Then add
your new attribute to the objectclass.
For example we would add to the slapd.oc.conf file:
airiusPerson
superior
inetOrgPerson
allowed
dateOfBirth,
preferredOS
airiusOrganization
superior
organization
allowed
buildingFloor,
vicePresident
OR
airiusEntry
allowed
dateOfBirth,
preferredOS,
buildingFloor,
vicePresident
More information can be found at "Customizing the Schema"
http://developer.netscape.com/docs/manuals/directory/deploy30/data.htm




How do you make an LDAP client?
There are SDKs in many languages including perl, C, C++ and Java, to help you make
an LDAP client. Go get the SDK for your language and use the functions that it provides
to connect to and operate on an LDAP server. More details below.
How do you make an LDAP server?
There are many options, including Sun, Netscape, Microsoft, Qualcomm,
OpenLDAP(free). If you don't want to install your own directory service, but just want to
play with LDAP, instructions for using publically available LDAP servers, such as bigfoot
and four11, are below.

Getting the client environment set up for perl
(1) Linux and perl 5.004 alone
a. Install perl
b. Install the LDAP SDK for C from http://developer.netscape.com/directory (binary)
c. Install the LDAP SDK for perl from http://www.mozilla.org
(you build) or Netscape (binary)
(2) Windows NT and perl
a. Install the non-ActiveState perl version
ftp://ftp.cs.colorado.edu/pub/perl/CPAN/ports/win32/Standard/x86/perl5.00402-
bindist04-bc.zip
b. Install the LDAP SDK for C from Netscape
c. Install the LDAP SDK for perl from Netscape
Getting the server environment set up
(1) Installing your own LDAP server
a. Linux: OpenLDAP http://www.openldap.org
b. Windows NT: Netscape Directory Server. Free evals from Netscape?
(2) Using a publically available LDAP server
This is generally easier to start with since you know it is set up properly and is
functioning correctly. Plus you don't really need anything special other than a standard
version 4 web browser.
Publically available LDAP servers:
ldap.bigfoot.com
ldap.four11.com (now Yahoo People?)
ldap.switchboard.com (used by AltaVista people searches?)
usdsa.psi.net
ldap.itd.umich.edu
mailhub.jpl.nasa.gov

How to connect your client to a server
We will use a publically available LDAP server in these examples, since that is very easy
and everyone can participate. There are 4 ways to get started:
(1) LDAP url from the browser (no perl or SDK required)
(2) sample perl scripts that come with the SDK (perl and SDK required)
(3) write a little perl client to connect (perl and SDK required)
(4) write a little perl client to connect through an URL (perl and SDK required)
(1) You can use an LDAP url with IE 4+or Netscape 4+.
In Netscape, you can put the search strings right on the URL line, but in Explorer, you
just put the ldap address, and you are prompted for the rest (Explorer is kind of lame for
this reason, and I do not recommend using it while you are trying to learn about LDAP).
Helpful info http://www.ogre.com/mirror/nscp/jsdk3/url.htm.
This is the format of an LDAP URL:
ldap[s]://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>
Component Description
<hostname> Name (or IP address in dotted format) of the LDAP server (for
example, ldap.netscape.com or 192.202.185.90).
<port> Port number of the LDAP server. If no port is specified, the
standard LDAP port (389) is used.
<base_dn> Distinguished name (DN) of an entry in the directory. This DN
identifies the entry that is starting point of the search. If this
component is empty, the search starts at the root DN.
<attributes> The attributes to be returned. To specify more than one attribute,
use commas to delimit the attributes (for example,
"mail,telephoneNumber").
If no attributes are specified in the URL, all attributes are returned.
<scope> The scope of the search, which can be one of these values:
base: retrieves information only about the distinguished name
(<base_dn>) specified in the URL.
one: retrieves information about entries one level below the
distinguished name (<base_dn>) specified in the URL. The base
entry is not included in this scope.
sub: retrieves information about entries at all levels below the
distinguished name (<base_dn>) specified in the URL. The base
entry is included in this scope.
If no scope is specified, the server performs a base search.
<filter> Search filter to apply to entries within the
specified scope of the search.
If no filter is specified, the server uses the filter (objectClass=*).
Example 1
ldap://ldap.bigfoot.com:389/o=airius.com?cn,mail,?sub?(cn=billybob thornton)
In this example we are asking for specific fields (cn, mail).
Bigfoot returns:
billybob thornton
Name billybob thornton
Email punkguyz@hotmail.com
Four11 returns:
Billybob Thornton
Email big_bad_bill@yahoo.com
Example 2:
ldap://ldap.bigfoot.com:389/o=airius.com??sub?(cn=billybob thornton)
In this example, we left attributes blank, so we will end up with all the fields, which is
interesting because then you can see that layer of the directory schema.
Bigfoot returns:
billybob thornton
Email punkguyz@hotmail.com
Name billybob thornton
Organization hotmail.com
First Name billybob
surname thornton
Four11 returns:
Billybob Thornton
City Fargo
c US
Email big_bad_bill@yahoo.com
First Name Billybob
Last Name Thornton
st ND
Name Billybob Thornton

(2) You can use the sample scripts that come with the LDAPSDK
Just use the qsearch program and customize the parameters appropriately.
C:\ldapsdk\perldap-1.0\examples>perl qsearch.pl h ldap.bigfoot.com -b
"o=airius.com" "cn=billybob thornton"
Searched for `cn=billybob thornton':
dn: cn="billybob thornton",mail=punkguyz@hotmail.com,c=US,o=hotmail.com
mail: punkguyz@hotmail.com
cn: billybob thornton
o: hotmail.com
surname: thornton

(3) You can write a little script to connect.
This is good for testing your install. I lifted this code from Mark Wilcox's book. Thanks
Mark.
SCRIPT VARIATION #1
This is the simplest test. Just search for your own email address in the bigfoot directory,
and return all the information that is listed for that record. In the RDBMS world this
would be kind of like a SELECT statement, i.e. SELECT * FROM directory WHERE
mail='megan@gate.net'
#!/usr/local/bin/perl
use Mozilla::LDAP::Conn;
my $host = "ldap.bigfoot.com";
my $port = 389;
my $dn = "";
my $password = "";
my $base = "o=airius.com";
my $scope = "subtree";
my $filter = "(mail=punkguyz\@hotmail.com)";
my $ldap = new Mozilla::LDAP::Conn($host,$port,$dn,$password)
|| die("Failed to open LDAP connection\n");
my $entry = $ldap->search($base, $scope, $filter);
if(! $entry)
{
print "Search failed. Try again.\n";
}
else
{
while($entry)
{
$entry->printLDIF();
$entry= $ldap->nextEntry();
}
}
SCRIPT VARIATION #2
This one shows an array of attribs being returned instead of the entire attributes list
being returned by default. This could be a substantial savings in a directory with large
records. In the RDBMS world, this operation is kind of like a "project" in which
you choose a few columns to display from a larger set of columns: SELECT
cn,mail,telephonenumber FROM directory WHERE mail='megan@gate.net'
The 0 means "do you want to return both values and attribute names or just the
attribute names?" 0 is the default and means that you want to return both.
In the RDBMS world, an attribute name is a column. And a value is the field value for
that attribute.
The @attribs is the list of attribs you are asking for.
#!/usr/local/bin/perl
use Mozilla::LDAP::Conn;
my $host = "ldap.bigfoot.com";
my $port = 389;
my $dn = "";
my $password = "";
my $base = "o=airius.com";
my $scope = "subtree";
my $filter = "(mail=punkguyz\@hotmail.com)";
my @attribs;
push (@attribs,"cn");
push (@attribs,"mail");
push (@attribs,"telephonenumber");
my $ldap = new Mozilla::LDAP::Conn($host,$port,$dn,$password)
|| die("Failed to open LDAP connection\n");
>> my $entry = $ldap->search($base,$scope,$filter,0,@attribs);
if(! $entry)
{
print "Search failed. Try again.\n";
}
else
{
while($entry)
{
$entry->printLDIF();
$entry= $ldap->nextEntry();
}
}

(4) You could use an LDAP url from within a perl script.
Use your @attribs array to build the url, then searchURL().
#!/usr/local/bin/perl
use Mozilla::LDAP::Conn;
use Mozilla::LDAP::Utils;
use Mozilla::LDAP::Entry;
my $host = "ldap.bigfoot.com";
my $port = 389;
my $dn = "";
my $password = "";
my $base = "o=airius.com";
my $filter = "(cn=BillyBob Thornton)";
my $scope = "sub";
my $url = "ldap://$host:$port/$base?";
my @attribs;
push (@attribs, "cn");
push (@attribs, "mail");
push (@attribs, "sn");
my $ldap = new Mozilla::LDAP::Conn($host,$port,$dn,$password)
|| die("Failed to open LDAP connection.\n");
my $attribute;
foreach $attribute(@attribs)
{
$url .= $attribute. ",";
}
$url .= "?".$scope;
$url .= "?".$filter;
print "url: $url\n";
my $entry = new Mozilla::LDAP::Entry();
if ($ldap->isURL($url))
{
$entry=$ldap->searchURL($url);
}
else
{
die("$url is not a valid LDAP URL\n");
}
if (! $entry)
{
print "Search failed. Try again.";
}
else
{
while ($entry)
{
$entry->printLDIF();
$entry = $ldap->nextEntry();
}
}



Bigfoot returns a nicely formatted list like this:
url: ldap://ldap.bigfoot.com:389/o=airius.com?cnmailsn?sub?(cn=BillyBob
Thornton)
dn: cn="billybob thornton",mail=punkguyz@hotmail.com,c=US,o=hotmail.com
mail: punkguyz@hotmail.com
cn: billybob thornton
o: hotmail.com
surname: thornton
You could even add a portion of code that accepted a filter from the commandline and
searched on that.
c:\> perl test.pl "(cn=billybob thornton)"
...
my $term = shift;
my $filter = $term;
...

More operations on the LDAP directory
1. Bind. You must be able to bind (authenticate) as "Directory Manager" in some
cases.
2. Search. We already did this.
3. Compare. We already did this.
4. Create. You create (add) a new entry using Mozilla::LDAP::Entry, and use
setDN() to set up the DN of the entry. Assign. You assign attributes to your new
entry in name-value pairs with $entry->addValue("cn", "BillyBob Thornton")
5. Modify. You can modify existing values using these same create/assign methods
also. If an entry has two values for an attribute, when you replace the attribute,
you will write over both values.
6. Delete. You can delete entries with the delete(dn) method.
Example 1: replacing one of many attributes
#!/usr/local/bin/perl
use Mozilla::LDAP::Conn;
>> my $host = "ldap.myldapserver.com";
my $port = 389;
>> my $dn = "Directory Manager";
>> my $password = "secret";
>> my $base = "uid=bthornton, ou=People,o=airius.com";
>> my $scope = "base";
>> my $filter = "uid=bthornton";
my @attribs;
attribs[0] = "cn";
my $goodValue = "William Robert Thornton";
my $badValue = "billybob thornton";
my $ldap = new Mozilla::LDAP::Conn($host,$port,$dn,$password)
|| die("Failed to open LDAP connection\n");
my $entry = $ldap->search($base, $scope, $filter,0,@attribs);
if(! $entry)
{
print "Search failed. Try again.\n";
}
else
{
my @cn = @{$entry->{cn}};
$entry->removeValue("cn",$badValue);
$entry->addValue("cn",$goodValue);
$ldap->update($entry);
if ($ldap->getErrorCode())
{
print $ldap->printError();
}
my $newEntry =
$ldap->search($base,$scope,$filter,0,@attribs);
if(! $newEntry)
{
die("Search failed. Try again.\n");
}
else
{
$newEntry->printLDIF();
}
}

Putting It All Together
1. Building an LDAP Gateway in Perl. You can write a cgi script take data from a
to search or update an LDAP gateway. You could even make it a pure client-side
(non-cgi) implementation since you can use javascript to build a URL based on
form input. GQ (http://biot.com/gq/) is a small GTK-based LDAP client which lets
you query any LDAP server with a graphical interface.
2. Hooking LDAP to an email client. Its even easier if the client is web based,
again because we can use the URL method.
3. LDAP for user authentication.
4. LDAP for holding snippets of business logic. If you put your SQL statements
in LDAP, you could call them from anywhere in the world.
5. LDAP for tax calculation. This is my idea that I think would be really cool.

Vous aimerez peut-être aussi