LDAP

LDAP
"The Lightweight Directory Access Protocol, or LDAP, is an application protocol for querying and modifying directory services running over TCP/IP." [Wiki: LDAP]

LDAP default port is 389. 

The default port for LDAP over SSL is 636


 * DN is Distinguished Name
 * RDN is Relative Distinguished Name
 * DC is domain component

An entry is defined as a set of attributes, and an attribute is a set of values, and sets need not be ordered.

LDAP Browsers
Java based LDAP Browser/Editor http://www.mcs.anl.gov/~gawor/ldap/

JXplorer http://www.jxplorer.org/

phpLDAPadmin - Web-based LDAP browser to manage your LDAP server http://phpldapadmin.sourceforge.net/

Softerra LDAP Browser http://www.softerra.com/download.htm

Ldapvi - Lets users update LDAP entries with a text editor http://directory.fsf.org/database/applications/ldapvi.html

Tutorials
(My favorite) YoLinux LDAP Tutorial: Deploying OpenLDAP - Directory Installation and configuration (V1.2 / 2.x) http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP.html

Introduction to LDAP http://quark.humbug.org.au/publications/ldap/ldap_tut.html

The SLAPD and SLURPD Administrators Guide (University of Michigan) http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/

OpenLDAP Tutorial http://www.acay.com.au/~oscarp/tutor/

LDAP Tutorial - Exercise with OpenLDAP v2.0.11 on Linux http://www.ceenet.org/workshops/lectures2001/Peter%20Gietz/tutorial.html

SWiK Search for OpenLDAP tutorials http://swik.net/OpenLDAP+Tutorial

LDAP-mini-HOWTO http://www.grennan.com/ldap-HOWTO.html

OpenLDAP with Linux and Windows http://www.linuxjournal.com/article/5689

LDAP for Rocket Scientists http://www.zytrax.com/books/ldap/

Building an Address Book with OpenLDAP http://www.onlamp.com/pub/a/onlamp/2003/03/27/ldap_ab.html

An Introduction to LDAP http://www.onlamp.com/pub/a/onlamp/2001/08/16/ldap.html

Integrating LDAP and Kerberos: Part One (Kerberos) http://www.linux-mag.com/microsites.php?site=linuxonblades&sid=main&p=4738

LDAP Authentication - LinuxWiki http://linuxwiki.riverworth.com/index.php?title=LDAP_Authentication

Installation
CentOS 5 Installation

Install packages: yum install openldap openldap-clients openldap-servers

Edit configuration: vi /etc/openldap/slapd.conf include        /etc/openldap/schema/core.schema include        /etc/openldap/schema/cosine.schema include        /etc/openldap/schema/inetorgperson.schema

pidfile        /var/run/openldap/slapd.pid argsfile       /var/run/openldap/slapd.args

database       bdb suffix         "o=t0e" rootdn         "cn=Manager,o=t0e" rootpw         test directory      /var/lib/ldap/t0e index          cn,sn,st  eq,pres,sub

Create directory: mkdir /var/lib/ldap/t0e chown ldap.ldap /var/lib/ldap/t0e

Test configuration: slaptest

Start ldap service: service ldap restart
 * 1) slapd -d -1  # debug mode

Add entries: ldapadd -f MYFILE.ldif -xv -D "cn=Manager,o=t0e" -h 127.0.0.1 -w test ldapadd -xv -D "cn=Manager,o=t0e" -h 127.0.0.1 -w test <<EOL

See all entries: ldapsearch -vLx -h 127.0.0.1 -b "o=stooges" ldapsearch -vLx -h 127.0.0.1 -b "o=stooges" "(sn=Fine)"

ldif example
dn: o=t0e objectClass: top objectClass: organization o: t0e description: The Three Stooges

dn: cn=Manager,o=t0e objectClass: organizationalRole cn: Manager description: LDAP Directory Administrator

dn: ou=GroupA,o=t0e ou: GroupA objectClass: top objectClass: organizationalUnit description: Members of GroupA

dn: ou=GroupB,o=t0e ou: GroupB objectClass: top objectClass: organizationalUnit description: Members of GroupB

dn: cn=Kenneth Burgener,ou=GroupA,o=t0e ou: GroupA o: t0e cn: Kenneth Burgener objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson mail: kenneth@kennethburgener.org givenname: Kenneth sn: Burgener uid: kenneth homePostalAddress: PO Box 2008$Orem UT 84059 postalAddress: PO Box 2008 l: Orem st: UT postalcode: 84059 telephoneNumber: (800)555-1212 homePhone: 800-555-1313 facsimileTelephoneNumber: 800-555-1414 userPassword: mypass title: Account Executive destinationindicator: /bios/images/lfine.jpg

LDAP Authentication
LDAP authentication takes three forms:
 * 1) No authentication: Read access granted to all. The Stooges and Delta house examples in the YoLinux LDAP Tutorial are of this form.
 * 2) Basic authentication: Client must bind with a DN and password. (Described in this tutorial)
 * 3) Secure authentication: Secure encrypted or authenticated connection.

Single Logon
access to attrs=userPassword by self write by dn="uid=root,ou=users,dc=oeey,dc=com" write by * auth

access to * by * auth

defaultaccess  none                         - Deny anonymous viewing and access

access to attr=userPassword                 - Deny anonymous viewing of passwords by dn="cn=DeanWormer,o=delta" write  - LDAP root not denied by self write                        - Allow user to update his password by * auth                            - Allow access to bind to LDAP (i.e. login requires access to password but still not allowed to view it)

access to * by dn="cn=DeanWormer,o=delta" write  - LDAP root has full access by dn="cn=fratbrother,o=delta" read  - Required for first example. Allow this user to read the database. (Except passwords which are denied above) by users read                        - Required in second example where user logs in with his own password to read LDAP database. Reading of passwords other than his own is denied. by self write by * auth

userPassword: fratsecret userPassword: {CRYPT}frzelFSD.VhkI

Password created with the command:

perl -e 'print("userPassword: {CRYPT}".crypt("fratsecret","frat-salt")."\n");' userPassword: {CRYPT}frzelFSD.VhkI

Unique user login ids and passwords
"This method of LDAP database protection is a little more sophisticated because it requires a password (LDAP attribute: userPassword) for each user. Read access is granted to the users in the slapd.conf file by the statement "by users read". The "by users read" is suited for an LDAP address directory which would be accessed by email clients. It gives the user access to query and download the appropriate email data to their address books. It might not be appropriate for a pure authentication server because it allows one to see all the users of the system possibly exposing too much private data. One has to evaluate their own security needs. "

Access/Administration based on organizational group access
File: /etc/openldap/slapd.conf ..   ...    defaultaccess   none access to attr=userPassword by dn="cn=DeanWormer,o=delta" write by self write by * auth access to dn=".*,ou=1963,o=delta" by dn="cn=Admin1963,o=delta" write by self write by users read by * auth access to * by dn="cn=DeanWormer,o=delta" write by dn="cn=fratbrother,o=delta" read by self write by users read by * auth

Access based on an attribute value
File: /etc/openldap/slapd.conf ... access to dn=".*,o=stooges" filter="departmentNumber=dept100" by self write by dn="cn=Admin100,o=stooges" write

Reference
Reference: Linux LDAP Tutorial: Add a login, password protection and security to your OpenLDAP directory

Search and Compare
The Search operation is used to both search for and read entries. Its parameters are:

baseObject
 * The DN (Distinguished Name) of the entry at which to start the search,

scope
 * BaseObject (search just the named entry, typically used to read one entry), singleLevel (entries immediately below the base DN), or wholeSubtree (the entire subtree starting at the base DN).

filter
 * How to examine each entry in the scope. E.g. (&(objectClass=person)(|(givenName=John)(mail=john*))) - search for persons who either have given name John or an e-mail address starting with john.

derefAliases
 * Whether and how to follow alias entries (entries which refer to other entries),

attributes
 * Which attributes to return in result entries.

sizeLimit, timeLimit
 * Max number of entries, and max search time.

typesOnly
 * Return attribute types only, not attribute values.

memberof overlay
Load module: moduleload memberof.la overlay memberof

Note: ignore the "null module" warning if you run debug. That just means it was a built in module.

conf: include /usr/share/openldap/schema/core.schema include /usr/share/openldap/schema/cosine.schema

authz-regexp "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth" "cn=Manager,dc=example,dc=com" database       bdb suffix         "dc=example,dc=com" rootdn         "cn=Manager,dc=example,dc=com" rootpw         secret directory      /var/lib/ldap2.4 checkpoint 256 5 index  objectClass   eq        index   uid           eq,sub

overlay memberof

ldif: cat memberof.ldif dn: dc=example,dc=com objectclass: domain dc: example

dn: ou=Group,dc=example,dc=com objectclass: organizationalUnit ou: Group

dn: ou=People,dc=example,dc=com objectclass: organizationalUnit ou: People

dn: uid=test1,ou=People,dc=example,dc=com objectclass: account uid: test1

dn: cn=testgroup,ou=Group,dc=example,dc=com objectclass: groupOfNames cn: testgroup member: uid=test1,ou=People,dc=example,dc=com

Search: SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 version: 1
 * 1) ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=test1)" -b dc=example,dc=com memberOf

dn: uid=test1,ou=People,dc=example,dc=com memberOf: cn=testgroup,ou=Group,dc=example,dc=com

ldapsearch -h ldap -x -b "dc=shop,dc=lan" '(uid=jordan)' memberOf ldapsearch -h ldap -x -b "dc=shop,dc=lan" '(uid=jordan)' memberOf uid

References:
 * OpenLDAP Software 2.4 Administrator's Guide - Reverse Group Membership Maintenance - http://www.openldap.org/doc/admin24/guide.html#Reverse%20Group%20Membership%20Maintenance
 * ldap - How do I configure Reverse Group Membership Maintenance on an openldap server? (memberOf) - Server Fault - http://serverfault.com/questions/73213/how-do-i-configure-reverse-group-membership-maintenance-on-an-openldap-server

Schema
"The schema defines the attribute types that directory entries can contain."

OpenSSH LDAP
yum install openssh-ldap

/etc/openldap/ include        /usr/share/doc/openssh-ldap-6.2p2/openssh-lpk-openldap.schema

diff: objectClass: ldapPublicKey sshPublicKey: ssh-rsa ....

kenneth.diff: dn: uid=kenneth,ou=users,dc=oeey,dc=net objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount objectClass: ldapPublicKey givenName: Kenneth sn: Burgener cn: kenneth uid: kenneth mail: kenneth@serenitysolution.com description: Kenneth Burgener shadowLastChange: 15146 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 10 gidNumber: 10 homeDirectory: /home/kenneth sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvMct4Ut8wZDEMnDyRz6TiAbYGLX5YilVdpuU5ZGbLxOjEfmhvo1PFHy+BT0q3kyKzaY6Ia+3\ RGlvS/N6GrF/nZeIX+VE6CGuK+X5ZYALghPNh3JXnqdwlOr/gEfuz/xvE2mk0Cqy1oJzRqDumNzcIDyiEZQ0C4O4udHpmX/7X0/fCN6vszmkdJPJqiJOL/sxuG\ 8YCgY+WoOnNnRv9AF77QAR7eoAIKFQcJ6hnpD5Woy5YT1quQwkWlSsFTTtBWWoGCaKr/AcuUcyvB1AQXDMePqdzXYesgexP69ILMnisTP2CIeMIERLAdUjXOaZ\ pFU9fuWNu1VSSbIwQwMhzCWyyQ== kenneth@t0e.org

/etc/ssh/ldap.conf BASE   dc=oeey,dc=net URI    ldap://ldap.oeey.net SSL    no

Test with: /usr/libexec/openssh/ssh-ldap-helper -d -s kenneth

Add second key: ldapmodify -x -D cn=admin,dc=oeey,dc=net -w mypassword < k.mod.diff

dn: uid=kenneth,ou=users,dc=oeey,dc=net add: sshPublicKey sshPublicKey: ssh-rsa ...
 * 1) k.mod.diff

References:
 * Another I.T. blog: HOWTO : Configure OpenSSH to Fetch Public Keys from OpenLDAP for Authentication on CentOS - http://itdavid.blogspot.com/2013/11/howto-configure-openssh-to-fetch-public.html

--- SSL ---

cp rootCA.crt /etc/pki/tls/certs/ cp /etc/pki/tls/certs/rootCA.crt /etc/openldap/cacerts

/etc/ssh/ldap.conf BASE   dc=oeey,dc=net URI    ldaps://ldap.oeey.net TLS_CACERTDIR /etc/openldap/cacerts

/etc/stunnel/stunnel.conf: cert = /etc/stunnel/oeey.net.pem [ldaps] accept=636 connect=389

Create serial CA: http://www.openldap.org/lists/openldap-technical/201109/msg00203.html cd /etc/openldap/cacerts/ ln -s ca.pem `openssl x509 -noout -hash -in ca.pem`.0

This will avoid this: ldap_simple_bind Can't contact LDAP server reconnecting to LDAP server...
 * 1) /usr/libexec/openssh/ssh-ldap-helper -d -s kenneth

SSL_accept: 14094418: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

Test: /usr/libexec/openssh/ssh-ldap-helper -d -s kenneth

echo "" | openssl s_client -connect ldap.oeey.net:636

echo "" | openssl s_client -connect ldap.oeey.net:636 -showcerts -CAfile /etc/openldap/cacerts/ca.cert.pem

/etc/ssl/certs -> /etc/pki/tls/certs

Thunderbird
MailNews:Mozilla LDAP Address Book Schema - MozillaWiki

Linux Magazine - LDAP Authentication

 * 1) Linux Magazine: LDAP Authentication, Part One - http://www.linux-mag.com/id/3722/
 * 2) Linux Magazine: LDAP Authentication, Part Two - http://www.linux-mag.com/id/4124/
 * 3) Linux Magazine: LDAP Authentication, Part Three - http://www.linux-mag.com/id/4129/

Terms
LDAP uses a number of acronyms to refer to types of structures within its directories. These include:
 * domain component (DC)
 * distinguished name (DN)
 * common name (CN)
 * organizational unit (OU).

Example describing user account: dn: cn=Fred Jones,dc=keylabs,dc=com

Backend database:
 * To actually store data, LDAP must use some sort of database as a backend. One common backend is the Berkeley DB package (http://www.sleepycat.com), but others are available. To the LDAP client, the backend package is invisible except if it negatively affects the LDAP server’s performance.

OpenLDAP:
 * The most common Linux package is OpenLDAP, available from http://www.openldap.org


 * OpenLDAP is an open source suite of LDAP (Lightweight Directory Access Protocol) applications and development tools. LDAP is a set of protocols for accessing directory services (usually phone book style information, but other information is possible) over the Internet, similar to the way DNS (Domain Name System) information is propagated over the Internet.

Package openldap:
 * The openldap package contains configuration files, libraries, and documentation for OpenLDAP. (source: yum info openldap)

Pacakge openldap-clients:
 * The openldap-clients package contains the client programs needed for accessing and modifying OpenLDAP directories. (source: yum info openldap-clients)

Pacakge openldap-servers:
 * The openldap-servers package contains the slapd and slurpd servers, migration scripts, and related files. (source: yum info openldap-servers)

Server Installation
Installation: yum install openldap openldap-clients openldap-servers

Basic LDAP Configuration
 * The LDAP server itself (slapd) is controlled through a file called slapd.conf, which is usually stored in /etc/openldap. Two other LDAP configuration files, both called ldap.conf, control LDAP client operations. The /etc/ldap.conf file is used by LDAP’s Name Service Switch (NSS) interfaces, while /etc/openldap/ldap.conf specifies defaults for various LDAP client programs. For now, concentrate on slapd.conf.

/etc/openldap/slapd.conf /etc/ldap.conf # only found on clients using NSS /etc/openldap/ldap.conf

Basic Setup:
 * chances are your default configuration will work reasonably well once you’ve entered a few site-specific items. The first of these is to load an LDAP schema (a set of rules) for handling Linux account information.

Authentication Schema: (/etc/openldap/slapd.conf)
 * include /etc/openldap/schema/nis.schema
 * required for LDAP to function solely as a network authentication server

Make test certificate: cd /etc/pki/tls/certs rm -f slapd.pem make slapd.pem chown ldap:ldap slapd.pem
 * 1) Enter in details
 * 2) Set common name to ldap hostname

Configure Server: (/etc/openldap/slapd.conf)

TLSCertificateFile /etc/pki/tls/certs/slapd.pem TLSCertificateKeyFile /etc/pki/tls/certs/slapd.pem TLSCipherSuite HIGH security ssf=128 password-hash {SSHA}
 * 1) uncomment lines 51, 52
 * 1) add lines 53:

access to attrs=userPassword by self write by dn="uid=root,ou=users,dc=t0e,dc=org" write by * auth
 * 1) add lines 83: (update dn to match site)
 * 2) I also like "users" over "Users" or "People"
 * 3) ACLs:
 * 4) line 1 - users can change their own passwords
 * 5) line 2 - root can overwrite any password
 * 6) line 3 - users can authenticate against password

access to * by * read
 * 1) everyone can read the whole directory tree

access to attrs=userPassword filter=(!(shadowexpire=0)) by self write by dn="uid=root,ou=users,dc=oeey,dc=com" write by * auth

access to * filter=(!(shadowexpire=0)) by * read

suffix "dc=t0e,dc=org" rootdn "cn=admin,dc=t0e,dc=org" rootpw test12
 * 1) change line 99:
 * 2) I Like "admin" over "Manager"
 * 1) rootpw test
 * 2) rootpw {SSHA}JwdTsA21MtN9h9Hu3RDYPNAoPhm9SiKj

Notes:
 * rootdn is user who will administer the system. Conventionally either Manager or admin.
 * You can use the slappasswd command to generate the root password

ACLS:
 * The first block of lines specifies rules for access to the userPassword attribute, which holds user passwords, as you might have guessed. Specifically, users may write their own passwords (by self write), root may overwrite any password, and all users may authenticate against passwords (by*auth).
 * The second block of lines gives all users read access to the rest of the information in the directory (much as all users may read /etc/passwd).
 * When specifying LDAP ACLs, order is important; earlier entries take precedence over later ones. Thus, the earlier ACL for userPassword, which doesn’t specify any read access, takes precedence over the later global read access ACL. This configuration prevents each user from reading his or her — or anyone’s — password.

Enable LDAPS: /etc/sysconfig/ldap SLAPD_LDAPS=yes

Start service: service ldap restart

Ports: TCP port 389 # LDAP TCP port 636 # LDAPS
 * LDAP binds to port 389, which is usually adequate for use with Linux clients.
 * Some other clients, though, may require LDAP to be bound to port 636 for secure LDAP (LDAPS) operation.

Check Config
Check config syntax: slaptest

Note: Initially will complain about missing DB_CONFIG. We will take care of that next

LDIF Local Management
LDIF:
 * LDAP relies on the LDAP Data Interchange Format (LDIF) to describe information stored in its directories. LDIF is a text format that LDAP can parse, extracting the relevant data for inclusion in the backend database.

Account Migration:
 * One useful approach to setting up a new LDAP server as an account maintenance system is to migrate an existing Linux account database. The tools to do this are available as scripts from http://www.padl.com/OSS/MigrationTools.html.

wget http://www.padl.com/download/MigrationTools.tgz tar -zvxf MigrationTools.tgz cd MigrationTools-47

Edit vim migrate_common.ph: $DEFAULT_MAIL_DOMAIN = "keylabs.com"; $DEFAULT_BASE = "dc=keylabs,dc=com"; $NAMINGCONTEXT{'passwd'}           = "ou=People";
 * 1) Default DNS domain
 * 1) Default base
 * 1) Match to be either People (or Users) depending on what you use elsewhere

Copy passwd and group file, and remove all but "user" accounts and groups: cp /etc/passwd passwd cp /etc/group group

sample passwd: kenneth:x:500:500::/home/kenneth:/bin/bash mike:x:501:501::/home/mike:/bin/bash

sample group: kenneth:x:500: mike:x:501:

Genearte LDIF: sudo ./migrate_passwd.pl passwd passwd.ldif sudo ./migrate_group.pl group group.ldif
 * 1) sudo ./migrate_passwd.pl /etc/passwd passwd.ldif
 * 2) sudo ./migrate_group.pl /etc/group group.ldif

create basic_passwd.ldif (or add lines to the start of passwd.ldif): dn: dc=keylabs,dc=com objectClass: domain dc: keylabs

dn: ou=People,dc=keylabs,dc=com objectClass: organizationalUnit ou: People

passwd.ldif: dn: uid=kenneth,ou=People,dc=lab uid: kenneth cn: kenneth objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: {crypt}$1$kU24pyY6$7R02lZjyg5XM9iUIQpj5e/ shadowLastChange: 15143 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 500 gidNumber: 500 homeDirectory: /home/kenneth

create basic_group.ldif (or add lines to the start of the group.ldif): dn: ou=Group,dc=keylabs,dc=com objectClass: organizationalUnit ou: Group

group.ldif: dn: cn=kenneth,ou=Group,dc=lab objectClass: posixGroup objectClass: top cn: kenneth userPassword: {crypt}x gidNumber: 500

Note: to add opther users to a group, add 'memberUid: kenneth' lines to the group definition memberUid: kenneth

Shut down ldap server: service ldap stop

Avoid DB Config error message: cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG chown ldap:ldap /var/lib/ldap/DB_CONFIG

Import LDIF: sudo slapadd -v -l basic_passwd.ldif sudo slapadd -v -l basic_group.ldif sudo slapadd -v -l passwd.ldif sudo slapadd -v -l group.ldif

Fix permissions: chown ldap:ldap /var/lib/ldap/*

Start ldap server: service ldap start

List contents of LDAP: (good for backup purposes) slapcat slapcat -l [OUTFILE].ldif
 * 1) slapcat - SLAPD database to LDIF utility
 * 2) The LDIF generated by this tool is suitable for use with slapadd (not ldapadd)

If you get this error: bdb_db_open: Warning - No DB_CONFIG file found in directory /var/lib/ldap: (2) Expect poor performance for suffix dc=keylabs,dc=com.

cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG chown ldap:ldap /var/lib/ldap/DB_CONFIG

Account maintenance:
 * you could use the ldapadd utility instead of slapadd; however, ldapadd requires you to have configured LDAP for account maintenance, as described shortly.

Get Accounts: Once your system is configured to use LDAP for authentication, you’ll be able to type 'getent passwd' to obtain a complete list of accounts to help avoid LDAP uid and uidNumber collisions getent passwd

If you want to set a password at account-creation time, you can use 'slappasswd' to generate an encrypted value slappasswd

Backup Database
sudo slapcat -l backup.ldif

Note: Make sure to backup config files in /etc/openldap

Restore Database
Perform steps in "Rebuild Database", but use the backup.ldif for slapadd

sudo slapadd -v -l backup.ldif

Note: Make sure to restore config files in /etc/openldap

Rebuild Database
If you need to clear and rebuild the database: service ldap stop mv /var/lib/ldap /var/lib/ldap-old mkdir /var/lib/ldap chmod 700 /var/lib/ldap chown ldap:ldap /var/lib/ldap cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG chown ldap:ldap /var/lib/ldap/DB_CONFIG chown ldap:ldap /var/lib/ldap/* service ldap start
 * 1) slapadd ...
 * 2) slapadd ...
 * 3) slapadd ...

Client Configuration
Install base ldap libraries and configuration files: yum install openldap

/etc/openldap/ldap.conf: BASE		dc=keylabs,dc=com URI		ldaps://ldap.keylabs.com TLS_CACERT	/etc/pki/tls/certs/slapd.pem

The /etc/pki/tls/certs/slapd.pem just contains the public key "-BEGIN CERTIFICATE-". Grab from the LDAP server.

LDIF Remote Management
These tools can be used locally and remotely.

Installation: yum install openldap-clients

Tools: ldapadd ldapmodify ldappasswd ldapdelete ldapsearch

Note: '-x' Use simple authentication instead of SASL. (from /etc/openldap.ldap.conf)

set the BASE, URI, and TLS_CACERT options in this file: /etc/openldap/ldap.conf BASE		dc=oeey,dc=com URI		ldaps://ldap.oeey.com TLS_CACERT	/etc/pki/tls/certs/slapd.pem

URI		ldap://ldap.oeey.com URI		ldap://ldap.oeey.com:389 URI		ldap://ldap.oeey.com

To ignore SALP certs: TLS_REQCERT allow

On the client install the following: yum install openldap openldap-clients

URI Bind: ldapadd -H ldaps://ldap.lab -D cn=admin,dc=lab -W -f mike.ldif
 * 1) URI bind

ldap_sasl_interactive_bind_s: No such attribute (16)
 * 1) error when not using simple bind:

ldap_sasl_interactive_bind_s: Confidentiality required (13) additional info: confidentiality required
 * 1) error when trying non SSL connection:

ldapadd
Add user: ldapadd -x -D cn=manager,dc=oeey,dc=com -W -f acct.ldif
 * 1)  -x  Use simple authentication instead of SASL.

ldapdelete
Delete user: ldapdelete -x -D cn=manager,dc=oeey,dc=com -W uid=mike,ou=People,dc=oeey,dc=com

ldappasswd
Change user's password: ldappasswd -x -D cn=manager,dc=oeey,dc=com -S -W uid=kenneth,ou=People,dc=oeey,dc=com

-S          # Prompt for new password -s [passwd] # Set the new password to [passwd] -x          # Use simple authentication instead of SASL

ldapwhoami
Quick check to validate login

ldapwhoami - LDAP who am i? tool

ldapwhoami -x -D uid=kenneth,ou=Users,dc=oeey,dc=com -W

ldapwhoami -x -D uid=kenneth,ou=Users,dc=oeey,dc=com -w mypassword

ldapmodify
Add user to group: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W

dn: cn=jira,ou=groups,dc=oeey,dc=com add: memberUid memberUid: kenneth

Disable User: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W

dn: uid=mike,ou=users,dc=oeey,dc=com add: shadowexpire shadowexpire: 0

Enable User: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W

dn: uid=mike,ou=users,dc=oeey,dc=com delete: shadowexpire

Move User: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W

dn: uid=sgray,ou=users,dc=oeey,dc=com changetype: modrdn newrdn: uid=sgray deleteoldrdn: 0 newsuperior: ou=disabled,dc=oeey,dc=com

Rename User: dn: uid=sgray,ou=users,dc=oeey,dc=com changetype: modrdn newrdn: uid=stan deleteoldrdn: 1

dn: uid=sgray,ou=users,dc=oeey,dc=com changetype: moddn newRDN: uid=stan deleteOldRDN: 1

Delete User: dn: uid=sgray,ou=users,dc=oeey,dc=com changetype: delete

Modify Attribute: dn: uid=sgray,ou=users,dc=oeey,dc=com changetype: modify replace: description description: This is the new description for John Doe

Add Atribute: dn: uid=sgray,ou=users,dc=oeey,dc=com add: mailAlternateAddress mailAlternateAddress: jdoe@example.com

ldapsearch
ldapsearch -x  # use connection details in /etc/openldap/ldap.conf ldapsearch -x -b dc=oeey,dc=com

ldapsearch -H ldap://ldap.oeey.com -b dc=oeey,dc=com -x ldapsearch -H ldaps://ldap.oeey.com -b dc=oeey,dc=com -x

ldapsearch -x -b dc=oeey,dc=com '(loginShell=/bin/bash)' dn cn
 * 1) list all bash users, listing 'dn' and 'cn'

ldapsearch -x -b ou=users,dc=oeey,dc=com
 * 1) list all user objects (including base 'user' object)

ldapsearch -x -b ou=users,dc=oeey,dc=com "(uid=*)" uid
 * 1) list all user objects only with an uid, and list the uid

memberOf:
 * ldap - How do I configure Reverse Group Membership Maintenance on an openldap server? (memberOf) - Server Fault - http://serverfault.com/questions/73213/how-do-i-configure-reverse-group-membership-maintenance-on-an-openldap-server-m
 * Howto verify that a member is part of a secondary group in OpenLDAP | Dimaj's Blog - http://blog.dimaj.net/2010/07/howto-verify-that-a-member-is-part-of-a-secondary-group-in-openldap/
 * slapo-memberof and RHEL/Centos.. - http://www.openldap.org/lists/openldap-technical/200909/msg00023.html
 * "I'm a happy user of the stock OpenLDAP in RHEL/CENTOS 5 which is based on OpenLDAP 2.3.27 however now I need slapo-memberof. Do I need to upgrade to OpenLDAP 2.4 to use this? Does anyone have this functioning under RHEL/CENTOS?"
 * OpenLDAP Software 2.4 Administrator's Guide: Overlays - http://www.openldap.org/doc/admin24/overlays.html

PAM and NSS
PAM is a security tool; it tells login tools, such as the text-mode login process or the GUI GNOME Display Manager (GDM) or KDE Display Manager (KDM), that the password a user types is (or is not) correct for the specified username. PAM also handles some additional tasks, such as changing passwords when a user runs the passwd utility.

NSS handles less sensitive account data, such as the path to a user’s home directory, his or her default shell, and so on.

If you configure PAM but not NSS to use LDAP, only users who have local account data stored in /etc/passwd and /etc/shadow will be able to log in. These files could lack passwords, but they’d have to host the normal NSS data.

If you configure NSS but not PAM to use LDAP, then Linux will believe it has accounts for the users defined on the LDAP server, but those users won’t be able to log in. Thus, to use an LDAP server for authentication, you must normally reconfigure both PAM and NSS to use LDAP. Either alone could be useful in some limited circumstances, but in most cases you must configure both to use LDAP.

Install NSS LDAP package: yum install nss_ldap

/etc/ldap.conf host ldap.keylabs.com base dc=keylabs,dc=com

/etc/nsswitch.conf passwd: files  ldap shadow: files  ldap group:  files  ldap

Get Accounts: Once your system is configured to use LDAP for authentication, you’ll be able to type 'getent passwd' to obtain a complete list of accounts to help avoid LDAP uid and uidNumber collisions getent passwd getent group

/etc/pam.d/system-auth add the following lines immediately before their respective pam_unix.so lines: auth       sufficient    pam_ldap.so try_first_pass auth       sufficient    pam_unix.so nullok try_first_pass

account    sufficient    pam_ldap.so account     sufficient    pam_unix.so  # changed from required

password   sufficient    pam_ldap.so use_authtok debug password   sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok

session    required      pam_ldap.so use_first_pass session    required      pam_mkhomedir.so skel=/etc/skel umask=0027 session    required      pam_unix.so

PAM modules are stored here: /lib/security/

To allow only local LDAP users to login, add the following to the top of the account section: (see 'man pam_localuser') account    required      pam_localuser.so

To allow only users in a group to login, add the following:

/etc/login.group.allowed: root wheel login git

auth       required      pam_listfile.so onerr=fail item=group sense=allow file=/etc/login.group.allowed

To allow only certain users to login, add the following: auth       required      pam_listfile.so \ onerr=fail item=user sense=allow file=/etc/loginusers

Bind timeout in /etc/ldap.conf: timelimit 120
 * 1) Search timelimit
 * 2) timelimit 30

bind_timelimit 120
 * 1) Bind/connect timelimit
 * 2) bind_timelimit 30


 * 1) Reconnect policy: hard (default) will retry connecting to
 * 2) the software with exponential backoff, soft will fail
 * 3) immediately.
 * 4) bind_policy hard

NOTE: Setting bind_timelimit to a lower number will also help if the LDAP server is offline, as this controls the connect timeout.

Disable Users
Add filter: access to * filter=(!(shadowexpire=0)) by * read

Test login: ldapwhoami -x -D uid=mike,ou=users,dc=oeey,dc=com -W

Disable User: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W dn: uid=mike,ou=users,dc=oeey,dc=com add: shadowexpire shadowexpire: 0

Enable User: ldapmodify -x -D cn=admin,dc=oeey,dc=com -W dn: uid=mike,ou=users,dc=oeey,dc=com delete: shadowexpire

References:
 * Re: How to disable or enable an ldap user account - http://www.openldap.org/lists/openldap-technical/200810/msg00106.html

SASL
Couldn't ever get this to work. See SASL

Maybe have to change /etc/sysconfig/saslauthd: ??? MECH=ldap
 * 1) Mechanism to use when checking passwords.  Run "saslauthd -v" to get a list
 * 2) of which mechanism your installation was compiled with the ablity to use.
 * 3) MECH=pam

OpenLDAP Software 2.4 Administrator's Guide: Using SASL - http://www.openldap.org/doc/admin24/sasl.html

OpenLDAP, OpenSSL, SASL and KerberosV HOWTO - http://www.bayour.com/LDAPv3-HOWTO.html

Apache
yum install mod_authz_ldap

/etc/httpd/conf.d/authz_ldap.conf LoadModule authz_ldap_module modules/mod_authz_ldap.so





AuthzLDAPAuthoritative on     AuthzLDAPMethod ldap

AuthzLDAPServer ldap.oeey.com AuthzLDAPUserBase ou=users,dc=oeey,dc=com AuthzLDAPUserKey uid AuthzLDAPUserScope base

AuthType basic AuthName "svn" require valid-user





See mod_authz_ldap - http://authzldap.othello.ch/configuration.html

Sample Jira Access

 * * LDAP Host: ldap://localhost:389
 * * BaseDN: ou=Users,dc=example,dc=com
 * Bind DN:
 * Bind Password:
 * * Search Attribute: uid
 * Sample user to authenticate: kenneth
 * Sample user's password:

LDAP: ldap://localhost:389/dc=apollo,dc=biipr,dc=com User DN pattern: uid={0},cn=users

python-ldap
Yum installation of python-ldap package: yum install python-ldap

Installation of python-ldap package: (could not get to work) yum install gcc openldap-devel wget http://pypi.python.org/packages/source/p/python-ldap/python-ldap-2.3.13.tar.gz#md5=895223d32fa10bbc29aa349bfad59175 tar -zvxf python-ldap-2.3.13.tar.gz cd python-ldap-2.3.13 python setup.py install # FAILED BUILD


 * LDAP Programming in Python | Linux Journal - http://www.linuxjournal.com/article/6988
 * python-ldap: LDAP client API for Python - http://www.python-ldap.org/
 * Python Package Index : python-ldap 2.3.13 - http://pypi.python.org/pypi/python-ldap/

Simple Example: import ldap server = 'ldap://ldap.keylabs.com' con = ldap.initialize(server) dn='uid=joe,ou=People,dc=keylabs,dc=com' pw='test12' con.simple_bind_s( dn, pw )
 * 1) !/usr/bin/env python

Login Example: import sys import ldap user_dn='uid=joe,ou=People,dc=keylabs,dc=com' user_pw='test12q' server = 'ldap://ldap.keylabs.com' l = ldap.initialize(server)
 * 1) !/usr/bin/env python

try: #l.start_tls_s l.bind_s(user_dn, user_pw) except ldap.INVALID_CREDENTIALS: print "Your username or password is incorrect." sys.exit except ldap.LDAPError, e:   if type(e.message) == dict and e.message.has_key('desc'): print e.message['desc'] else: print e   sys.exit

print "Login Successful"

Linux Magazine - Integrating LDAP and Kerberos

 * 1) Linux Magazine: Integrating LDAP and Kerberos: Part One (Kerberos) - http://www.linux-mag.com/id/4738/
 * 2) Linux Magazine: Integrating LDAP and Kerberos: Part Two (LDAP) - http://www.linux-mag.com/id/4765/


 * Linux Magazine: Using Perl and LDAP - http://www.linux-mag.com/id/6071/
 * Linux Magazine: Intro to Linux Pluggable Authentication Modules - http://www.linux-mag.com/id/7887/

Python LDAP Applications
A series of articles by Matt Butcher about python-ldap:
 * Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory. This also covers SASL.
 * Python LDAP Applications: Part 2 - LDAP Operations
 * Python LDAP Applications: Part 3 - More LDAP Operations and the LDAP URL Library
 * Python LDAP Applications: Part 4 - LDAP Schema

LDAP Programming in Python | Linux Journal - http://www.linuxjournal.com/article/6988

http://www.grotan.com/ldap/python-ldap-samples.html - python-ldap sample code

python-ldap
Source Installation: yum install gcc openldap-devel wget http://pypi.python.org/packages/source/p/python-ldap/python-ldap-2.3.13.tar.gz#md5=895223d32fa10bbc29aa349bfad59175 tar -zvxf python-ldap-2.3.13.tar.gz cd python-ldap-2.3.13 python setup.py install # FAILED BUILD!

Yum Installation: yum install python-ldap

LDAP Programming in Python | Linux Journal - http://www.linuxjournal.com/article/6988

python-ldap: LDAP client API for Python - http://www.python-ldap.org/

Python Package Index : python-ldap 2.3.13 - http://pypi.python.org/pypi/python-ldap/

import ldap server = 'ldap://ldap.keylabs.com' con = ldap.initialize(server) dn='uid=joe,ou=People,dc=keylabs,dc=com' pw='test12' con.simple_bind_s( dn, pw )

import sys import ldap user_dn='uid=kenneth,ou=People,dc=keylabs,dc=com' user_pw='test12' server = 'ldaps://ldap.keylabs.com' l = ldap.initialize(server)

try: #l.start_tls_s l.bind_s(user_dn, user_pw) except ldap.INVALID_CREDENTIALS: print "Your username or password is incorrect." sys.exit except ldap.LDAPError, e:   if type(e.message) == dict and e.message.has_key('desc'): print e.message['desc'] else: print e   sys.exit

print "Login Successful"

If you get this error, try "ldaps://..." for the server AttributeError: CONFIDENTIALITY_REQUIRED instance has no attribute 'message'

If you get this error, make sure /etc/openldap/ldap.conf is configured. See "Client Configuration" section. AttributeError: SERVER_DOWN instance has no attribute 'message'

Windows LDAP
applied procrastination: python-ldap authentication and you - http://appliedprocrastination.blogspot.com/2009/03/python-ldap-authentication-and-you.html

Here's how I managed to make my python client code running on a Debian/Ubuntu box authenticate against a Windows Active Directory LDAP server:

1) Obtain the server's cert: openssl s_client -showcerts -connect myserver.com:636 > their_server.pem

2) Edit the resulting file to isolate just the cert you want. In my case, the file had two certs embedded in it, plus some identifying cruft. Preceding the first, desired cert was a block that looked like this: 0 s:/C=US/ST=MyState/L=MyCity/O=My Company Inc./OU=Information Technology/OU=For Intranet Use Only/CN=my.host.com, followed by -BEGIN CERTIFICATE-. Next came VeriSign's cert. Delete everything but the CERTIFICATE block for your server, including the BEGIN and END lines, and save to /etc/ssl/certs/myserver.pem -- you can save to any location, really.

And here's the code:
 * 1) !/usr/bin/env python

import ldap ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,"/etc/ssl/certs/myserver.pem") l = ldap.initialize("ldaps://myserver.com:636") l.set_option(ldap.OPT_PROTOCOL_VERSION, 3) l.simple_bind_s("username@DOMAIN","password")
 * 1) ldap.set_option(ldap.OPT_DEBUG_LEVEL,4095)

Build from Source
BerkelyDB: (http://www.oracle.com/technetwork/database/berkeleydb/downloads/index-082944.html) mkdir -p ~/src ; cd ~/src wget http://download.oracle.com/berkeley-db/db-4.4.20.NC.tar.gz tar -zvxf db-4.4.20.NC.tar.gz cd db-4.4.20.NC/build_unix/ ../dist/configure --prefix=/opt/db make sudo make install
 * 1) Install compatible version of BerkeleyDB:

mkdir -p ~/src ; cd ~/src yum install db4 db4-devel # BerklyDB wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-stable/openldap-stable-20100719.tgz tar -zvxf openldap-stable-20100719.tgz cd openldap-2.4.23 CPPFLAGS=-I/opt/db/include LDFLAGS=-L/opt/db/lib ./configure --enable-overlays=yes --enable-memberof=yes --prefix=/opt/ldap make make install
 * 1) Build OpenLDAP:
 * 1) ./configure --enable-overlays=yes --enable-memberof=yes --prefix=/opt/ldap

default /opt/ldap/etc/openldap/slapd.conf: include		/opt/ldap/etc/openldap/schema/core.schema pidfile		/opt/ldap/var/run/slapd.pid argsfile	/opt/ldap/var/run/slapd.args database	bdb suffix		"dc=my-domain,dc=com" rootdn		"cn=Manager,dc=my-domain,dc=com" rootpw		secret directory	/opt/ldap/var/openldap-data index		objectClass	eq

Enable memberOf
How to enable 'memberof': Reverse Group Membership overlay no|yes|mod [no]

new /opt/ldap/etc/openldap/slapd.conf: include		/opt/ldap/etc/openldap/schema/core.schema include		/opt/ldap/etc/openldap/schema/cosine.schema include		/opt/ldap/etc/openldap/schema/inetorgperson.schema include		/opt/ldap/etc/openldap/schema/nis.schema pidfile		/opt/ldap/var/run/slapd.pid argsfile	/opt/ldap/var/run/slapd.args database	bdb suffix		"dc=t0e,dc=org" rootdn		"cn=Manager,dc=t0e,dc=org" rootpw		secret directory	/opt/ldap/var/openldap-data index		objectClass	eq overlay		memberof

Environment Configuration: cd /opt/ldap/etc/openldap PATH=/opt/ldap/sbin:/opt/ldap/bin:$PATH export LD_LIBRARY_PATH=/opt/db/lib

Check configuration: sbin/slaptest  # check for config issues

Clear database: (stop ldap first) rm -rf var/openldap-data/*

Fix DB_CONFIG: cp etc/openldap/DB_CONFIG.example var/openldap-data/DB_CONFIG

Start server: libexec/slapd -d 9

basic.ldif: dn: dc=t0e,dc=org objectClass: domain dc: t0e

dn: ou=users,dc=t0e,dc=org objectClass: organizationalUnit ou: users

dn: uid=kenneth,ou=users,dc=t0e,dc=org uid: kenneth cn: kenneth objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: e1NTSEF9bUlSOVZtTHZaTGFsTWQrZWdFZWxudVppa2oyV2Q0cEU= shadowLastChange: 15143 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 500 gidNumber: 500 homeDirectory: /home/kenneth

dn: ou=groups,dc=t0e,dc=org objectClass: organizationalUnit ou: groups

dn: cn=kenneth,ou=groups,dc=t0e,dc=org objectClass: posixGroup objectClass: top cn: kenneth userPassword: {crypt}x gidNumber: 500

dn: cn=jirausers,ou=groups,dc=t0e,dc=org objectclass: groupofnames cn: jirausers description: Users allowed to use Jira member: uid=kenneth,ou=groups,dc=t0e,dc=org
 * 1) member: uid=stan,ou=groups,dc=t0e,dc=org

Stop server and add basic items: killall slapd slapadd slapadd -v -l basic.ldif

Restart server: libexec/slapd -d 9

List database: slapcat

Change user's password: ldappasswd -x -D cn=Manager,dc=t0e,dc=org -w secret uid=kenneth,ou=users,dc=t0e,dc=org -s test12

Verify login worked: ldapwhoami -x -D uid=kenneth,ou=users,dc=t0e,dc=org -w test12

Add LDIF stuff: ldapadd -x -D cn=Manager,dc=t0e,dc=org -w secret ldapmodify -x -D cn=Manager,dc=t0e,dc=org -w secret

Search: ldapsearch -x -b dc=t0e,dc=org ldapsearch -x -b dc=t0e,dc=org memberof=cn=git,ou=groups,dc=t0e,dc=org

Member of - test: ldapsearch -x -b dc=t0e,dc=org '(uid=kenneth)' memberOf
 * 1) check that 'memberOf' tag is included

Member of - list users: ldapsearch -x -b dc=t0e,dc=org "(memberOf=cn=jirausers,ou=groups,dc=t0e,dc=org)"

References:
 * LDAP Guide - Reverse Group Membership Maintenance - http://www.linuxtopia.org/online_books//network_administration_guides/ldap_administration/overlays_Reverse_Group_Membership_Maintenance.html

Build Libraries
-- Libraries have been installed in: /opt/db/lib

If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the `LD_RUN_PATH' environment variable during linking - use the `-Wl,--rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. --

Build Issues
Issue: configure: error: BDB/HDB: BerkeleyDB not available

Solution: yum install db4 db4-devel

Issues: configure: error: BerkeleyDB version incompatible with BDB/HDB backends

Solution:
 * /* require 4.4 or later */
 * Install a newer version of db4 or older bersion of openldap

Examples
Thunderbird contact example: dn: cn=Kenneth Burgener,mail=kenneth.burgener@oeey.com objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson objectclass: mozillaAbPersonAlpha givenName: Kenneth sn: Burgener cn: Kenneth Burgener mail: kenneth.burgener@oeey.com nsAIMid: kenneth.burgener@oeey.com modifytimestamp: 0Z telephoneNumber: (801) 852-0770 x113 homePhone: (801) 607-5789 mobile: (801) 830-8921 street: 274 West Center Street l: Orem st: UT postalCode: 84057 mozillaWorkUrl: http://www.oeey.com

Moe Howard example from YOLinux dn: cn=Moe Howard, ou=MemberGroupA, o=stooges homePhone: 800-555-1313 givenName: Moe mobile: 800-555-1318 postalCode: 75226 objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson userPassword:: bW9lc2VjcmV0 facsimileTelephoneNumber: 800-555-3318 ou: MemberGroupA uid: moe mail: MHoward@isp.com cn: Moe Howard initials: Bob telephoneNumber: (800)555-1213 pager: 800-555-1319 manager: cn=Larry Howard,ou=MemberGroupA,o=stooges destinationIndicator: /bios/images/mhoward.jpg o: stooges st: TX l: Dallas postalAddress: 216 South Fitzhugh Ave. sn: Howard homePostalAddress: 16 Cherry Ln.$Plano TX 78888 title: Manager of Product Development

LDAP Mail

 * HOWTO: Postfix, Dovecot, Jamm, OpenLDAP, SSL, and SASL - http://wanderingbarque.com/howtos/mailserver/mailserver.html

LDAP GUI Management and Administration
Softerra LDAP Administrator & Browser: Directory Management Tool for Windows - http://www.ldapbrowser.com/
 * Excellent tool!
 * "Why you need LDAP Administrator":
 * Can you visually and intuitively modify your LDAP directory without using command line utilities but still having all the advantages and power of Windows GUI?
 * Can you access OpenLDAP, Netscape/iPlanet, Novell eDirectory, Oracle Internet Directory, Lotus Domino or Microsoft Active Directory with just one tool?
 * Can you quickly manage and navigate throughout your directory regardless of its huge size and hierarchical complexity?
 * Have you got a tool that uses LDIF import and export as efficiently to maintain your directory in good working order eliminating all sorts of data corruption risks (for you'll always be able to restore information from backup)?

JXplorer - an open source ldap browser - http://jxplorer.org/
 * Good, but major flaw: LDAPS fails frequently due to unaccepted certificate. Haven't found a way to override.
 * JXplorer is an open source ldap browser originally developed by Computer Associates' eTrust Directory development lab. It is a standards compliant general purpose ldap browser that can be used to read and search any ldap directory, or any X500 directory with an ldap interface. It is available for immediate free download under a standard OSI-style open source licence.

LDAP Admin: Overview - http://ldapadmin.sourceforge.net/
 * "Ldap Admin is free Windows administration tool for LDAP directory management. This application lets you browse, search, modify, create and delete objects on LDAP server. It also supports more complex operations such as directory copy and move between remote servers and extends the common edit functions to support specific object types (such as groups and accounts)."

Web Interface
LDAP Account Manager - https://www.ldap-account-manager.org/lamcms/

Users and Computers — Zentyal 3.4 Documentation - http://doc.zentyal.org/en/directory.html

Easy-to-use LDAP editor - Software Recommendations Stack Exchange - http://softwarerecs.stackexchange.com/questions/1055/easy-to-use-ldap-editor
 * LDAP Admin - Windows
 * jXplorer - Java Based
 * Apache Directory Studio - Java based

GOsa - https://oss.gonicus.de/labs/gosa

Password Change Web Application
pwm - Open Source Password Self Service for LDAP directories - Google Project Hosting - http://code.google.com/p/pwm/