Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

40
Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004

Transcript of Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Page 1: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Making Productive Use of

OpenLDAP

Presented to the CALUGby John UnekisAugust 11,2004

Page 2: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What Is OpenLDAP?

- LDAP is the Lightweight Directory Access Protocol

- Core LDAP Specification * RFC-2251 Lightweight Directory Access Protocol (v3) * RFC-2252 LDAPv3 Attribute Syntax Definitions * RFC-2253 UTF-8 String Representation of Distinguished Names * RFC-2254 The String Representation of LDAP Search Filters * RFC-2255 The LDAP URL Format * RFC-2256 A Summary of the X.500(96) User Schema for use with LDAPv3 - OpenLDAP is an open source implementation of LDAP

Page 3: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What Does OpenLDAP Do?

Internet

Linux

xinetd

Port 389

Port 80

etc.

httpd

slapdSomeSortaData

It makes data available over the web on port 389 using a standard query syntax

Page 4: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Where do I get OpenLDAP?

- For Redhat, Fedora, and Suse openldap comes bundled as an RPM

- For Debian, it comes as a .deb file

- For Slackware, it is bundled as a .tgz file

- You can also “do it” from source, obtained from http://www.openldap.org

Page 5: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What Do I Do With OpenLDAP?

- Present data such as email addresses, passwords, photos

- Make them available as a sort of “web service”

- Information becomes available on port 389 (636 if encrypted)

- Standard defines a syntax for queries

- Most browsers used to support this syntax

Page 6: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What Data Can OpenLDAP Handle?

- The default (under Fedora) is a GDBM database

- You can also map your /etc/passwd file, or a MySQL DB

- There are a series of include files that define the data objectsinclude /usr/local/etc/openldap/schema/core.schemainclude /usr/local/etc/openldap/schema/cosine.schemainclude /usr/local/etc/openldap/schema/inetorgperson.schemainclude /usr/local/etc/openldap/schema/nis.schemainclude /usr/local/etc/openldap/schema/nisdomainobject.schema

- Most are personnel oriented – email, phone, address, etc.

- You can also embed pointers to files – photos, documents, etc.

Page 7: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What Kind of Apps Use OpenLDAP?- The most typical use is email directories

- Outlook, Netscape, all the usual mail programs recognize LDAP directories

- Cell phones can also access phone numbers from an LDAP directory

- LDAP can be used for centralized authentication (see articles)http://www.linuxjournal.com/article.php?sid=6789 http://www.linuxjournal.com/article.php?sid=6876http://www.linuxjournal.com/article.php?sid=6936orhttp://www.mandrakesecure.net/en/docs/ldap-auth.php

- You can also integrate custom applications

- For example, a guard views an employee ID, and types the name into a web page, the page calls a CGI program which does an LDAP query, and retrieves the employees picture file, the picture is displayed so the guardcan verify the employees identity.

Page 8: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

So How Do We Set It Up?

- First, of course, install the package(s) for your distribution i.e. rpm -Uvh openldap-*-2.2.15.i386.rpm (you may need support like cyrus-sasl and glibc)

- If you use iptables, make sure to open port 389 (636 for ldaps)iptables -A INPUT -s 198.168.0.0 -p tcp --destination-port 389 -j ACCEPTiptables -A INPUT -s 198.168.0.0 -p udp --destination-port 389 -j ACCEPT

- If your site has a firewall, open port 389 to your box

- Configure /etc/openldap/slapd.conf

- Build an initial data base

- Start the service slapd on your machine

Page 9: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What's in /etc/openldap/slapd.conf (1)?# Sample access control policy:# Root DSE: allow anyone to read it# Subschema (sub)entry DSE: allow anyone to read it# Other DSEs:# Allow self write access# Allow authenticated users read access# Allow anonymous users to authenticate# Directives needed to implement policy:# access to dn.base="" by * read# access to dn.base="cn=Subschema" by * read# access to *# by self write# by users read# by anonymous auth## if no access controls are present, the default policy is:# Allow read by all## rootdn can always write!

Page 10: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

#include /etc/openldap/schema/core.schemainclude /etc/openldap/schema/cosine.schemainclude /etc/openldap/schema/inetorgperson.schemainclude /etc/openldap/schema/nis.schemainclude /etc/openldap/schema/redhat/autofs.schema

What's in /etc/openldap/slapd.conf (2)?The schemas:

-The schemas define a series of tags that identify data elements and syntax

- Records in the DB work like a “Christmas tree” First you build the base (tags like “C”, “DC”, “O”, and “OU”) then the branches (the individual “DN” or distinguished names) then hang the ornaments (tags like “address”, “title”, “mail” )

Page 11: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What's in /etc/openldap/slapd.conf (3)?

One Example

dc=com

dc=mydomain

o=mycompany

ou=accounting ou=security

cn=Bob Smith

cn=Geraldine Jones

Another Example

c=US

o=US Government

ou=USITC

ou=accounting ou=security

cn=Bob Smith

cn=Geraldine Jones

ou=DOJ

Page 12: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What's in /etc/openldap/slapd.conf (4)?######################################################################## ldbm and/or bdb database definitions#######################################################################

database ldbmsuffix "dc=my-domain,dc=com"rootdn "cn=Manager,dc=my-domain,dc=com"# Cleartext passwords, especially for the rootdn, should# be avoided. See slappasswd(8) and slapd.conf(5) for details.# Use of strong authentication encouraged.# rootpw secret# rootpw {crypt}ijFYNcSNctBYg

# The database directory MUST exist prior to running slapd AND # should only be accessible by the slapd and slap tools.# Mode 700 recommended.directory /var/lib/ldap

# Indices to maintain for this databaseindex objectClass eq,presindex ou,cn,mail,surname,givenname eq,pres,subindex uidNumber,gidNumber,loginShell eq,presindex uid,memberUid eq,pres,subindex nisMapName,nisMapEntry eq,pres,sub

The objectClass for a person is an inetorgPerson

Page 13: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What's in /etc/openldap/slapd.conf (5)?

# Replicas of this database#replogfile /var/lib/ldap/openldap-master-replog#replica host=ldap-1.example.com:389 tls=yes# bindmethod=sasl saslmech=GSSAPI# authcId=host/[email protected]

You could make your LDAP server sych/duplicate another server

One possible reason to do this would be to have local copies of the authentication server at remote sites

Page 14: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

What's in /etc/openldap/lapd.conf ?

- This is the config file for client commands on your box.

- If you want local ldap transactions to be performed against a different computer, put the hostname in this file

- There is also a timeout value in here which is useful to set to avoid accidental lockups on queries

Page 15: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Building The Initial Database

- Data is provided to the LDAP database in LDIF format rfc 2849 documents the format and fields

- OpenLDAP is obnoxiously unforgiving of syntax errors

- Error messages are sparse and cryptic, if you get them

- On your first couple of tries, watch for the initial build to hang

- For the intial build, there are two ingest routines slapadd runs with the slapd server off (recommended) ldapadd runs with through the server slapd

Page 16: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

dn: o=U.S. Government, c=USo: International Trade Commissionobjectclass: topobjectclass: organization

dn: ou=International Trade Commission, o=U.S. Government, c=USou: International Trade Commissionobjectclass: topobjectclass: organizationalUnit

dn: ou=Department of Energy, o=U.S. Government, c=USou: Department of Energyobjectclass: topobjectclass: organizationalUnit

dn: OU=Headquarters, OU=Department of Energy, ou=Department of Energy, o=U.S. Government, c=USou: Headquartersobjectclass: topobjectclass: organizationalUnit

Building The Base

This was part of the base of “directory.gov”

Page 17: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Another Example of a Base

dn: o=stoogesobjectClass: topobjectClass: organizationo: stoogesdescription: The Three Stooges

dn: cn=StoogeAdmin,o=stoogesobjectClass: organizationalRolecn: StoogeAdmindescription: LDAP Directory Administrator

dn: ou=MemberGroupA,o=stoogesou: MemberGroupAobjectClass: topobjectClass: organizationalUnitdescription: Members of MemberGroupA

dn: ou=MemberGroupB,o=stoogesou: MemberGroupBobjectClass: topobjectClass: organizationalUnitdescription: Members of MemberGroupB

From the website http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP.html

Page 18: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

- The most efficient way is to add records with the slapd service turned off slapadd -l <inputfile> -f <slapdconfigfile>

- This can also be done with the service running ldapadd -f entries.ldif -x -D "cn=Manager,dc=example,dc=com" -w secret

- The -c option to continue in case of a syntax error is highly recommended

- The LDIF format is unusual, it makes use of tags, but is also position sensitive- Each line begins with a tag, then a full colon, then ONE space, then data

- A space in column one denotes a continuation of the previous line

- Tabs are verbotten, and be very careful about hygeine errors like alphas in numeric fields

Putting Data in the File

Page 19: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Adding the Data Records

- LDAP files are typically used to store information on people

- The LDIF schemas give a lot of useful data elements

- Each LDIF record begins with a unique “distinguished name” usually a “common name” + the organization string i.e. dn: cn=Shemp howard, ou=MemberGroupB,o=stooges

- This is followed by several data elements, some mandatory

LDIF record requires:

* objectClass: organizationalPerson * objectClass: person (Inherited from object organizationalPerson) * objectClass: top (Inherited from object person) * sn (Surename/Last Name - Inherited from object person) * cn (Common Name - Inherited from object person)

Page 20: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

LDIF Data ElementsAn LDIF record may have:

* o (Organization Name) * displayName (RFC2798: Preferred name of a person to be used when displaying entries) * audio * businessCategory * carLicense * departmentNumber * employeeNumber * employeeType (i.e. "Contractor", "Employee", "Intern", "Temp", "External", "Unknown", etc...) * givenName * homePhone * homePostalAddress (After street number and name use line separator "$" in LDIF file: street$ st postalCode) * initials (MS/Outlook considers this to be the middle name) * jpegPhoto (See the OpenLDAP FAQ: Turn a jpeg into ldif format) * labeledURI * mail (e-Mail address) * manager (Specify dn entry of manager) * mobile * pager * photo * roomNumber * secretary (Specify dn entry of secretary) * uid * userCertificate * x500uniqueIdentifier * preferredLanguage * userSMIMECertificate (RFC2633: A PKCS#7 [RFC2315] SignedData) * userPKCS12 (PKCS #12 [PKCS12] provides a format for exchange of personal identity information.)

Page 21: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

LDIF Data Elements (cont'd)Also optional:# Attributes inherited from object organizationalPerson:

* ou (Organization unit) * title * x121Address * registeredAddress * destinationIndicator * preferredDeliveryMethod * telexNumber * teletexTerminalIdentifier * telephoneNumber (MS/Outlook considers this to be the "Business Phone") * internationaliSDNNumber * facsimileTelephoneNumber * postOfficeBox * postalAddress (MS/Outlook and Netscape both use this for the business address.) * physicalDeliveryOfficeName (MS/Outlook considers this to be the field "Office") * street (Don't use "street" because Netscape can't use it. Use "postalAddress".) * l (Locality/City/Town) * st (State/Province) * postalCode (Zip code)

# Attributes inherited from object person:

* userPassword * telephoneNumber (work phone) * seeAlso (URL for more info) * description

Page 22: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Example of Directory.Gov Recordsdn: cn=John Unekis,ou=Directors Office,ou=Information Services,ou=Operations,ou=International Trade Commission, o=U.S. Government, c=USmail: [email protected]: Johnsn: UnekistelephoneNumber: (202) 555-3189title: Sr. IT Project Managercn: John Unekis

dn: cn=Kristin Krake,ou=Directors Office,ou=Information Services,ou=Operations,ou=International Trade Commission, o=U.S. Government, c=USmail: [email protected]: Kristinsn: KraketelephoneNumber: (202) 555-2744title: Management Analyst 412-G cn: Kristin Krake

dn: cn=Kue Lin,ou=Directors Office,ou=Information Services,ou=Operations,ou=International Trade Commission, o=U.S. Government, c=USmail: [email protected]: Kuesn: LintelephoneNumber:title: Contractorcn: Kue Lin

(remember: data records are added with either slapadd or ldapadd)

Page 23: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Starting the slapd Service

- Under Redhat/Fedora, you could use the chkconfig command chkconfig –level 345 slapd on service will then be active at each of those runlevels

- Individual start/stop/restart operations could use the init script /etc/init.d/rc.d/slapd [start/stop/restart]

Page 24: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Accessing the LDAP Data- If your LDAP directory is an email directory most readers will accept it

- Authentication services with LDAP require an LDAP-capable client

- Supposedly ActiveDirectory will recognize LDAP (the author has not tried)

- For looking up general data, the ldap protocol works on most browsers i.e. ldap://208.188.34.109/cn=Larry Anderson,ou=MemberGroupA,o=stooges See http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc2255.html for URL format

- The ldapsearch command also works either locally, or with the -h option to a remote host, this allows ldap queries to be used in scripts or “c” programs

ldapsearch -h "ldap.domain-name" -L -b "o=domain-name" "(sn=Anderson)"

- Cgi-bin or tomcat java applets can be used to create interactive websites

Page 25: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Accessing OpenLDAP on a Website

User enters search data into HTML form

HTML form invokes cgi-binprogram, sends data as stdin

Cgi-bin program does LDAP lookup

Cgi-bin program uses stdout to send HTML with search results back to user

With CGI-BIN

User enters search data into HTML form

Tomcat invokes Javaprogram, sends data as stdin

Java program does LDAP lookup

Java program uses stdout to send HTML with search results back to user

With Java/Tomcat

Tomcat invokes Java server-side program to generate HTML form as stdout

Page 26: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Front Page From Former Directory.gov Website

Java source code attached as appendix

Page 27: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Updating/Modifying/Deleting Records- The LDIF format can have a “changetype:” field in the record which allows add/modify/delete

- Combine “changetype: modify” with a “replace: tag”and “tag: value” to replace an existing value

- Every change record requires a unique DN:i.e. dn: cn=Shemp howard, ou=MemberGroupB,o=stooges changetype: delete

or dn: cn=Shemp howard, ou=MemberGroupB,o=stooges changetype: modify replace: mail mail: [email protected]

- One technique is to batch the changes in an LDIF file

- Use ldapmodify to run the changes

Page 28: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

A Few Words on Performance- The default database under Fedora/Redhat is GDBM

- GDBM is a modest performance simple relational DB

- A 1.2GHz CPU, 384MB memory, 3x8GB SCSI-2 drives in RAID 5 gave: ~3 record insertions/second ~10 lookups/second

- To increase performance you could: Add RAM and increase the buffer size on the DB Partition the DB across multiple drives Try a RamDisk

Page 29: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Useful Resources

http://www.yolinux.com/TUTORIALS/LinuxTutorialaWebDap.html

Page 30: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Useful Resources

http://www.webalizer.org

Page 31: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Useful Resources

http://www.openldap.org

http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/

http://www.rudedog.org/auth_ldap/1.4/auth_ldap.html

http://www.iit.edu/~gawojar/ldap/

Page 32: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

Java Code that Ran Directory.gov under Tomcat

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<%@ page import="javax.naming.*, javax.naming.directory.*, java.util.Properties" %><%@ page import="java.util.Hashtable, java.util.Enumeration, java.io.*" %>

<%@ include file="bugspray.jsp" %>

<HTML><HEAD> <meta name="keywords" content="test, e-mail, people, addresses, telephone, find, phone, phones, locator, Federal, contact, directory, LDAP"> <meta name="ROBOTS" content="INDEX, NOFOLLOW"> <title>U.S. Federal White Pages Directory</title></HEAD><body bgcolor="#EEEEFF" text="#003366" link="#336699" vlink="#996666" alink="#FFCC66"><CENTER>

<table CELLSPACING=0 CELLPADDING=3><tr ALIGN=CENTER VALIGN=CENTER BGCOLOR=WHITE><td ALIGN=CENTER WIDTH="33%"><A HREF="/wpv2beta1.jsp"><img SRC="flag-eagle.jpg" ALT="White Pages Home" BORDER=0 ><BR>TOP LEVEL</A></td><td NOWRAP COLSPAN=4 BGCOLOR=WHITE><FONT COLOR="LIGHT BLUE">Welcome to the<br><H1>Federal White Pages</H1></td><td ALIGN=CENTER WIDTH="33%">

<%// this is commented out. To uncomment, remove the line above, the leading slases, and the second line below// <FONT size=-1><b><i>New!&nbsp;</i></b>Now you can add info to your own White Pages entry! <A HREF=register.jsp>Register</A> to get a password. Then you can <A href=edit.jsp>edit</a> your info.</FONT>%><%// <FONT size=-1><img SRC="cell.gif" ALT="Cell phone" BORDER=0 ALIGN="RIGHT"><b><i>New!&nbsp;</i></b>// We are wireless!! Bookmark "directory.gov" on your <A HREF="waptext.html">cell phone</A> to find & dial phone numbers from anywhere!</FONT>%>

</td></tr><tr><td COLSPAN=6 ALIGN="CENTER"><font size=-1>Use this <b>free service</b> to find e-mail addressesor phone numbers of Federal employees in <A HREF="agencycount.txt">22 Departments & agencies</A></td></tr><tr ALIGN=CENTER BGCOLOR=WHITE><TD><FONT SIZE=-1><B><A HREF="wpsecurity.html">Warning!</A></TD><TD><FONT SIZE=-1><B><A HREF="wpfaq.html">Questions?</A></TD><TD><FONT SIZE=-1><B><A HREF="MAILTO:[email protected]?Subject=WP_problem_report">Problems?</A></TD><TD><FONT SIZE=-1><B><A HREF="wpprivacy.html">Privacy</A></TD><TD><FONT SIZE=-1><B><A HREF="wpstats.html">Stats</A></TD><TD><FONT SIZE=-1><B><A HREF="wpabout.html">Who We Are</A></font></TD></tr></table>

Appendix – Source code from Directory.gov jsp files

Page 33: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

<% Attributes attribs = null; NamingEnumeration names = null; NamingEnumeration ne = null;

DirContext dctx = null;

Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=U.S. Government,c=US");

env.put("java.naming.security.authentication", "none"); env.put("java.naming.ldap.version", "3");

SearchControls ctls = new SearchControls();String[] returnAttrs = {"cn", "mail", "telephoneNumber", "title", "labeleduri", "pager", "description", "mobile", "facsimiletelephonenumber"};String[] returnNothing = {};

ctls.setReturningAttributes(returnAttrs);

String max; // Set maximum items returned from a search

if (request.getParameter("max") != null ) max = request.getParameter("max");

else max = "200";

if (max.equals("")) max = "200";if (Integer.valueOf(max).intValue() > 1000) max = "1000";ctls.setCountLimit(Integer.valueOf(max).longValue());

String context;String separator = "";

if (request.getParameter("context") != null) context = request.getParameter("context");

else context = "";

if (context.equals("")) separator = "" ; else separator = ", ";

SearchResult item;Attribute mail, phone, title;NamingEnumeration attrvals;String pstring, tstring, namestring, ns, ns2, nsfixed, sc;String href = "";String actualfilter = "";int ins = 0;

//set the search filter if it's provided in the requestString filter = "(|(CN=*)(OU=*))";if (request.getParameter("filter") != null && ((String)request.getParameter("filter")).trim() != "")

filter = request.getParameter("filter"); //set the simple name search values if provided in the request

String cnvals = "";if (request.getParameter("cnvals") != null )

cnvals = request.getParameter("cnvals");

//Combine info in filter and cnvals into "actualfilter" for actual search filterif (cnvals.equals("")) actualfilter = filter;else {

java.util.StringTokenizer st = new java.util.StringTokenizer(cnvals);actualfilter = "(&" + filter ;while (st.hasMoreTokens()) {

actualfilter = actualfilter + "(cn=*" + st.nextToken() + "*) "; }

actualfilter = actualfilter + ")";}

Page 34: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

//Decide whether to use subtree or one-level searchString scope = "ONELEVEL_SCOPE";

if (request.getParameter("scope") != null) scope = request.getParameter("scope");if (scope.equals("ONELEVEL_SCOPE")) ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);else if (scope.equals("SUBTREE_SCOPE")) ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

else if (cnvals.equals("")) ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);else ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

//See if children are wantedString children = "N";if ((request.getParameter("children") != null) && (request.getParameter("children").equals("Y")) )children = "Y";

try {dctx = new InitialDirContext(env);

names = (NamingEnumeration)dctx.search(context, actualfilter , ctls);ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);ctls.setReturningAttributes(returnNothing);

try {if ((names != null) && names.hasMore()) {

int i=0;%>

<FORM ACTION="/wpv2beta1.jsp" method="POST">Find <input type="text" size= 30 name="cnvals" value="<%= cnvals %>"><input type=hidden name="scope" size=30 value="SUBTREE_SCOPE" ><input type=hidden size= 35 name="context" value="<%= context %>"> <input type="Submit" name="" value="Search"></FORM><FONT SIZE=-1><EM>example: " beth ander " will find "Elizabeth Anderson", "Beth Sanderson" and "Elizabeth VanderPutten" </EM></FONT><HR>

<TABLE BORDER="1" CELLPADDING=7 CELLSPACING=0><CAPTION>List of Directory Entries in this Context</CAPTION><TR><TH>&nbsp;</TH><TH>Name--Click to drill down</TH><TH>Title</TH><TH>Phone</TH><TH>E-Mail / Web</TH></TR><%

while (names.hasMore()) { i++;item = (SearchResult)names.next();if (item.getName().equals("ou=Agencies")) {i = i-1; continue; }attribs = item.getAttributes();ns = ((String)item.getName()).replace('"',' ').trim();ns2 = ns;

// find location of "/" (an int) ; concat before ss + '\' + rest; loop sc = "/"; ins = ns.indexOf(sc, 0); while (ins > -1) {

nsfixed = ns.substring(0, ins) + "\\" + ns.substring(ins); // out.println("nsfixed=" + nsfixed + ": ns=" + ns);ns = nsfixed; ins = ns.indexOf(sc, ins + 2);

}

Page 35: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

try {if ( ns.toUpperCase().startsWith("OU=") )

{ href = "wpv2beta1.jsp?context=" + java.net.URLEncoder.encode(ns + separator + context) + "&scope=ONELEVEL_SCOPE" ;namestring = ns2;

if (children.equals("Y")) {namestring = namestring + " (Entries at next level: ";int ii = 0;

try { // getting count of items under an item ne = dctx.search(ns + separator + context, "(|(CN=*)(OU=*))", ctls );

while (ne.hasMore()) {ii++; ne.next();}} catch (SizeLimitExceededException sle) {namestring = namestring + " over "; } catch (NamingException nee) {out.println("exception at count:" + nee);}

namestring = namestring + " " + String.valueOf(ii) + ")";}

}else {href="wpv2beta1_detail.jsp?context=" + java.net.URLEncoder.encode(ns + separator + context);namestring = (String)(attribs.get("CN").getAll().next());}

} catch (Exception eek) {namestring = "Error";

// out.println("Exception in href processing. " + eek);}

%>

<TR><TD><%= i %></TD><TD><A HREF="<%= href %>"><%= namestring %></A></TD>

<% pstring = "&nbsp;";try {

title = attribs.get("title");attrvals = title.getAll();while (attrvals.hasMore()) pstring = pstring + " " + attrvals.next();}

catch (Exception e) { }%><TD><%= pstring %></TD>

<% pstring = "&nbsp;";try {

phone = attribs.get("telephonenumber");attrvals = phone.getAll();while (attrvals.hasMore()) pstring = pstring + " " + attrvals.next() + "<BR>";}

catch (Exception e) { }try {

phone = attribs.get("facsimiletelephonenumber");attrvals = phone.getAll();while (attrvals.hasMore()) pstring = pstring + " FAX: " + attrvals.next() + "<BR>";}

catch (Exception e) { }try {

phone = attribs.get("mobile");attrvals = phone.getAll();while (attrvals.hasMore()) pstring = pstring + " Mobile: " + attrvals.next() + "<BR>";}

catch (Exception e) { }%><TD><%= pstring %></TD>

Page 36: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

<%pstring = "&nbsp;";

try {mail = attribs.get("mail");attrvals = mail.getAll();while (attrvals.hasMore()) { tstring = (String)attrvals.next(); pstring = pstring + " <A HREF=MAILTO:" + tstring + ">" +

tstring + "</A>";}}

catch (Exception e) { }

try {mail = attribs.get("labeleduri");attrvals = mail.getAll();while (attrvals.hasMore()) { tstring = (String)attrvals.next(); pstring = pstring + "<BR>URL: <A HREF=" +

tstring.substring(0,tstring.indexOf(" ")) + ">" + tstring.substring(tstring.indexOf(" ")) + "</A>";}}

catch (Exception e) { }%><TD><%= pstring %></TD></TR>

<%} // End while clause} // End if clause

else { href="wpv2beta1_detail.jsp?context=" + java.net.URLEncoder.encode(context) ;out.println("No subordinate items in context <A HREF=" + href + ">" + context + "</A>. Click to view item attributes.");} // End else clause

} // End try

catch (SizeLimitExceededException es) {out.println("</TABLE><EM>NOTE: Number of items found exceeded search size limit.</EM><BR>");}

catch (NamingException e) { out.println("Another darn Naming error: " + e);

} // End catch NamingExceptioncatch (Exception ex) { out.println("Another darn General error: " + ex); } // End catch general exception

dctx.close();} // end trycatch (Exception e) { System.out.println("No person objects found in " + context); }

%>

</TABLE> <FONT SIZE=-1>This search used: scope= <%= scope %>, filter=<%= actualfilter %>, directory context=" <%= context %>".<BR></FONT><HR><BR><FORM action="/wpv2beta1.jsp" method="POST">

<TABLE><caption><h3>Basic Search</h3></caption><TR><TD>Part of directory to search (blank=entire directory)</TD> <TD><input type="text" size= 35 name="context" value="<%= context %>"></TD></TR><TR><TD>Names or parts of name to search for:(example: "beth anders")</TD> <TD><input type="text" size= 30 name="cnvals" value="<%= cnvals %>"></TD></TR><TR><TD COLSPAN=2 ALIGN=CENTER><input type="Submit" name="" value="Search"></TD></TR><TR><TD COLSPAN=2 ALIGN=CENTER><BR><HR><H4>Advanced Search Options</H4></TD></TR><TR><TD>Search filter<BR><A HREF=searchex.jsp>Examples</A></TD><TD><input type="text" name="filter" size=30 value="<%= filter %>"></TD></TR><%// <TR><TD>UserID (not used)</TD> <TD><input type="text" name="UserID"></TD></TR>// This is commented out// <TR><TD>Password (not used)</TD> <TD><input type="password" name="password"></TD></TR>%>

Page 37: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

<TR><TD>Search scope</TD> <TD><select name="scope" size="2"><option value="DEFAULT" selected>Default<option value="SUBTREE_SCOPE" >Entire subtree<option value="ONELEVEL_SCOPE" >Single level</select></TD></TR>

<TR><TD>Show number of entries below each item (can be VERY slow!)?</TD><TD><input type=radio name=children value=N checked >No<br><input type=radio name=children value=Y >Yes<br></TD></TR><TR><TD>Maximum items to be retrieved (there's a max of 1,000 anyhow, since more than that will blow out your browser.)</TD><TD><input type="text" name="max" size=4 value="200"></TD></TR></TABLE>

</FORM>

<%= SD %>, <%= m %>

</CENTER></BODY></HTML>

Page 38: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ page import="javax.naming.*, javax.naming.directory.*, java.util.Properties" %><%@ page import="java.util.Hashtable, java.util.Enumeration, java.io.*" %>

<%@ include file="bugspray.jsp" %>

<HTML><HEAD> <meta name="ROBOTS" content="NOINDEX"> <title>U.S. Federal White Pages Directory--Entry Detail</title></HEAD>

<body bgcolor="#EEEEFF" text="#003366" link="#336699" vlink="#996666" alink="#FFCC66">

<CENTER><table><tr ALIGN=CENTER><td COLSPAN=3><i><font size=-1>Please report <a href="MAILTO:[email protected]?Subject=WP_problem_report">problems with this service.</a></font></i></td></tr><tr ALIGN=CENTER VALIGN=CENTER><td ALIGN=CENTER WIDTH="33%"><A HREF="/"><img SRC="flag-eagle.jpg" ALT="Return to White Pages home" BORDER=0 ><BR>HOME</A></td><td NOWRAP>Welcome to the<br><font size=+2>Federal White Pages</font></td><td ALIGN=CENTER WIDTH="33%" ><font size=-1><img SRC="cell.gif" ALT="Cell phone" BORDER=0 ALIGN="RIGHT" CAPTION"White Pages Home"><b><i>New!&nbsp;</i></b>We are wireless!! Bookmark "directory.gov" on your <A HREF="waptext.html">cell phone</A> to find & dial phone numbers from anywhere!</FONT></td></tr></table>

<%

Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=U.S. Government,c=US");

env.put("java.naming.security.authentication", "none");// env.put("java.naming.security.principal", "cn=manager");// env.put("java.naming.security.credentials", "secret"); env.put("java.naming.ldap.version", "3");

DirContext dctx = null; String context = "ou=Agencies";

BasicAttributes ats;NamingEnumeration attribs = null;BasicAttribute at;NamingEnumeration attrvals;String pstring;if (request.getParameter("context") != null)

context = request.getParameter("context");

try {dctx = new InitialDirContext(env);

ats = (BasicAttributes)dctx.getAttributes(context);attribs = ats.getAll();

%>

Page 39: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.

<TABLE BORDER=1 CELLPADDING=7 CELLSPACING=0 ><Caption><H2>Details for This Directory Entry:</H2></Caption><TH>Attribute</TH><TH>Value(s)</TH><TR><TD>Entry name (RDN)</TD><TD><%= context %></TD><TR><% while (attribs.hasMore()) {

at = (BasicAttribute)attribs.next();%><TR><TD><%= at.getID() %></TD><%

pstring = "";try {attrvals = at.getAll(); if (attrvals.hasMore()) pstring = (String)attrvals.next();while (attrvals.hasMore()) pstring = pstring + "<BR>" + attrvals.next(); }catch (Exception e) { out.println("Barfing on value in " + at.getID() + e); }

%><TD><%= pstring %></TD>

<%} // End while clause

%>

</TR></TABLE><%= SD %>, <%= m %>

<%dctx.close();

} // End trycatch (NamingException e) {

out.println("Another darn Naming error: " + e);} // End catch NamingException

catch (Exception ex) { out.println("Another darn General error: " + ex); } // End catch general exception

%>

Page 40: Making Productive Use of OpenLDAP Presented to the CALUG by John Unekis August 11,2004.