Turns out that I should have just installed the openldap-servers and krb5-server packages (under Servers->Network Servers in the system-cdinstall-helper program) from the RHEL AS v4 disc 4 of 4. The rest of what I need (openldap, nss_ldap, openldap-clients, cyrus-sasl) are already installed.
LDAP stands for Lightweight Directory Access Protocol and is
described in RFC 2251
and RFC 3377
Its dn's (Distinguished Names) are described in
RFC 2253.
The documentation is here,
for example,
the OpenLDAP Software 2.3 Administrator's Guide.
The
Wikipedia article is pretty informative.
There are different LDAP implementations going by different names,
Some common terms,
|
|
|
|
|
|
|
|
|
|
|
|
_ldap._tcp.jasperfamily.org IN SRV 0 0 398 ldap.jasperfamily.org.
(not that I have this in my DNS - ZoneEdit doesn't provide for SRV records.
FreeDNS.afraid.org does, but it doesn't allow wildcarding, which I use.)
Besides LDAP, other SRV records are SIP (remember the 8x8 VOIP interview?), FTP, HTTP, HTTPS, etc.
I later used slappasswd to generate an encrypted password and went back and changed this /etc/openldap/slapd.conf file instead of having this in the clear, but I still used secret for the password. ;-)
Note that there are two ldap.conf files, /etc/ldap.conf that was provided by the nss_ldap package, and /etc/openldap/ldap.conf provided by the openldap package. I'm not sure why there's two. The /etc/ldap.conf file says This is the configuration file for the LDAP nameservice switch library and the LDAP PAM module. Also, the /etc/ldap.conf file is bigger.
I changed the following 2 lines in both ldap.conf files,
To start the slapd daemon now and after future reboots,
service ldap start
chkconfig ldap on (Creates /etc/rc.d/rc*.d/*ldap links)
dn: dc=jasperfamily,dc=org objectclass: dcObject objectclass: organization o: Jasper Family dc: jasperfamily dn: cn=Manager,dc=jasperfamily,dc=org objectclass: organizationalRole cn: Managerand ran
ldapadd -v -x -D "cn=Manager,dc=jasperfamily,dc=org" -W -f example.ldif(using my secret password) which added those two entries in my LDAP database, which by way, is at /var/lib/ldap.
A
ldapsearch -h ldap -x -b 'dc=jasperfamily,dc=org' '(objectclass=*)'command now returns
# extended LDIF # # LDAPv3 # basewith scope subtree # filter: (objectclass=*) # requesting: ALL # # jasperfamily.org dn: dc=jasperfamily,dc=org objectClass: dcObject objectClass: organization o: Jasper Family dc: jasperfamily # Manager, jasperfamily.org dn: cn=Manager,dc=jasperfamily,dc=org objectClass: organizationalRole cn: Manager # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2
/usr/kerberos/sbin/kdb5_util create -r JASPERFAMILY.ORG -s Loading random data Initializing database '/var/kerberos/krb5kdc/principal' for realm 'JASPERFAMILY.ORG', master key name 'K/M@JASPERFAMILY.ORG' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: (I entered r-3) Re-enter KDC database master key to verify:This created 5 files in /var/kerberos/krb5kdc,
kadmin.local Authenticating as principal root/admin@JASPERFAMILY.ORG with password. kadmin.local: addprinc admin/admin@JASPERFAMILY.ORG WARNING: no policy specified for admin/admin@JASPERFAMILY.ORG; defaulting to no policy Enter password for principal "admin/admin@JASPERFAMILY.ORG": global Re-enter password for principal "admin/admin@JASPERFAMILY.ORG": Principal "admin/admin@JASPERFAMILY.ORG" created. kadmin.local: quit
service krb5kdc start service kadmin start (not kadmind as service --status-all shows) chkconfig --level 2345 krb5kdc on (Creates /etc/rc.d/rc*.d/*krb5kdc links) chkconfig --level 2345 kadmin on (Creates /etc/rc.d/rc*.d/*kadmin links)Starting kadmin for the first time will write a kadm5.keytab file in the /var/kerberos/krb5/kdc directory.
krb5kdc listens on UDP ports 88 (kerberos) & 750 (kerberos-iv), and
kadmind listens on UDP port 464 (kpasswd) & TCP 749 (kerberos-adm),
so I had to authorize these ports in the
system-config-securityleveltool to tweak the SELinux firewall, allowing "88:udp, 464:udp, 749:tcp, 389:tcp" in the "Other ports:" field. Port 389 is the ldap port and is what slapd listens to.
kadmin -p admin/admin Authenticating as principal admin/admin with password. Password for admin/admin@JASPERFAMILY.ORG: global kadmin: addprinc root/admin WARNING: no policy specified for root/admin@JASPERFAMILY.ORG; defaulting to no policy Enter password for principal "root/admin@JASPERFAMILY.ORG": global Re-enter password for principal "root/admin@JASPERFAMILY.ORG": Principal "root/admin@JASPERFAMILY.ORG" created. kadmin: addprinc rick WARNING: no policy specified for rick@JASPERFAMILY.ORG; defaulting to no policy Enter password for principal "rick@JASPERFAMILY.ORG": r-3 Re-enter password for principal "rick@JASPERFAMILY.ORG": Principal "rick@JASPERFAMILY.ORG" created. kadmin.loocal: quit
system-config-authenticationgo to the "Authentication" tab, and click on the "Enable Kerberos Support" button. This changes the following 2 files,
According to this LDAPv3 How To, Cyrus SASL This is the layer between OpenLDAP and Kerberos. It gives you a secure way of AUTHENTICATING access to the LDAP server.
The best description of SASL though, was what I found in SASL Programmer's Guide. Basically, SASL is a way for an application writer (say FTP or mail client or LDAP) to authenticate without getting bogged down in the details of Kerberos IV versus Kerberos V, or CRAM MD5. All the application writer need do to work with these and any future authentication scheme that might get developed, is to code to the SASL spec. Ths SASL libraries will take care of the authentication details.
I've already installed the cyrus-sasl packages and have various sasl commands in /usr/bin and /usr/sbin.
There's a set of LDAP Migration Tools in the /usr/share/openldap/migration directory provided by the openldap-servers package. I used migrate_base to generate a base.ldif file that will populate my LDAP directory with a standard structure.
/usr/share/openldap/migration/migrate_base > base.ldifIn it was typical LDIF stanzas for jasperfamily.org and 12 second-level dn's.
|
|
|
|
To put them into my LDAP directory,
ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f base.ldifUh, oh. A problem. After a reboot, my LDAP/slapd daemon won't run. The lines in /var/log/messages say
Sep 12 10:50:14 linux2 slapd[3983]: sql_select option missing Sep 12 10:50:14 linux2 slapd[3983]: auxpropfunc error no mechanism available Sep 12 10:50:17 linux2 slapd[3988]: sql_select option missing Sep 12 10:50:17 linux2 slapd[3988]: auxpropfunc error no mechanism availableA check on the forums suggest
cd /etc/openldap chmod ldap:ldap ldap.conf slapd.confbut that didn't fix anything.
Somebody suggested starting slapd in debug mode with "slapd -d -1". This created 300 lines of stuff, apparently this is the problem.
slapd startup: initiated. bdb_db_open: dc=jasperfamily,dc=org bdb_db_open: dbenv_open(/var/lib/ldap) bdb(dc=jasperfamily,dc=org): Program version 4.2 doesn't match environment version bdb_db_open: dbenv_open failed: Invalid argument (22) backend_startup: bi_db_open(0) failed! (22) slapd shutdown: initiatedThe system DID die overnight and there are cases where the Berkely database (bdb) doesn't recover from crashes with these messages. Forums suggest
db_stat -ebut I can't figure out the full syntax. Another suggestion was to run
cd /var/lib/ldap db_recover -vwhich appears to have done something. Hey! Now slapd runs ok. Whew!
And now my ldapadd command runs ok except for the below expected error (dc=jasperfamily,dc=org already existed), which is why I specified the -c option (keep going even if there's an error).
ldapadd -c -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f base.ldif Enter LDAP Password: ldap_add: Already exists (68) adding new entry "dc=jasperfamily,dc=org" adding new entry "ou=Hosts,dc=jasperfamily,dc=org" adding new entry "ou=Rpc,dc=jasperfamily,dc=org" adding new entry "ou=Services,dc=jasperfamily,dc=org" adding new entry "nisMapName=netgroup.byuser,dc=jasperfamily,dc=org" adding new entry "ou=Mounts,dc=jasperfamily,dc=org" adding new entry "ou=Networks,dc=jasperfamily,dc=org" adding new entry "ou=People,dc=jasperfamily,dc=org" adding new entry "ou=Group,dc=jasperfamily,dc=org" adding new entry "ou=Netgroup,dc=jasperfamily,dc=org" adding new entry "ou=Protocols,dc=jasperfamily,dc=org" adding new entry "ou=Aliases,dc=jasperfamily,dc=org" adding new entry "nisMapName=netgroup.byhost,dc=jasperfamily,dc=org"
To add my rick (501:501) userid, create the following rick.ldif file,
dn: uid=rick,ou=People,dc=jasperfamily,dc=org cn: Rick Jasper sn: Jasper objectClass: top objectClass: person objectClass: posixAccount objectClass: shadowAccount uid: rick uidNumber: 501 gidNumber: 501 loginShell: /bin/bash homeDirectory: /home/rickand add it with
ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f rick.ldif Enter LDAP Password: adding new entry "uid=rick,ou=People,dc=jasperfamily,dc=org"You can display this with
ldapsearch -x 'cn=Rick Jasper'
This is almost perfect. I can login as rick, but I get this error message when I do,
id: cannot find name for group ID 501There are hints that perhaps the group line in /etc/nsswitch.conf isn't right, but it's set to group: files ldap which seems right.
I'm guessing it's because I left out a gid: rick line in my rick.ldif file. There's a uid: line. So, to delete my rick entry and readd,
ldapdelete -x -w secret -D "cn=Manager,dc=jasperfamily,dc=org"
"uid=rick,ou=People,dc=jasperfamily,dc=org"
ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f rick.ldif
Nope, that wasn't it. Revert. Checking Google again ...
How 'bout adding a 501 Group? Here's a group501.ldif file,
dn: gidNumber=501,ou=Group,dc=jasperfamily,dc=org cn: rick gidNumber: 501 objectClass: top objectClass: posixGroupand a
ldapadd -a -w secret -x -D "cn=Manager,dc=jasperfamily,dc=org" -f group501.ldif adding new entry "gidNumber=501,ou=Group,dc=jasperfamily,dc=org"gets it so I can login and my group DOES show up just fine. Bingo!
There's a problem on the client reboot though. See this Redhat bug for a solution, which is to vi /etc/ldap.conf and
Sep 14 22:54:44 linux4 sshd[19462]: Accepted password for rick from 192.168.1.222 port 33102 ssh2 Sep 14 22:54:44 linux4 sshd[19464]: pam_unix(sshd:session): session opened for user rick by (uid=0) Sep 14 22:54:44 linux4 sshd[19462]: nss_ldap: could not search LDAP server - Server is unavailable Sep 14 22:54:44 linux4 sshd[19462]: fatal: login_get_lastlog: Cannot find account for uid 501The solution was to also set "nss_connect_policy oneshot" (whatever that means).
On the LDAP server (linux2), you may want it to also look at the LDAP database when resolving userids and groups. Add "ldap" to these 3 lines in the /etc/nsswitch.conf file,
passwd: files ldap shadow: files ldap groups: files ldap
So to recap, to add a user, say adam/502, create an adam.ldif file like so (the blank line is required),
dn: uid=adam,ou=People,dc=jasperfamily,dc=org cn: Adam Jasper sn: Jasper objectClass: top objectClass: person objectClass: posixAccount objectClass: shadowAccount uid: adam uidNumber: 502 gidNumber: 502 loginShell: /bin/bash homeDirectory: /home/adam dn: gidNumber=502,ou=Group,dc=jasperfamily,dc=org cn: adam gidNumber: 502 objectClass: top objectClass: posixGroupand add it to the LDAP database like so,
ldapadd -a -w secret -x -D "cn=Manager,dc=jasperfamily,dc=org" -f adam.ldif
You'll have to create the home directories on each system (or share them somehow) by hand. A quick and dirty way to create it is
adduser adam -u 502 userdel adam
Finally, you'll need to add this new userid to the Kerberos database.
kadmin -p admin/admin Authenticating as principal admin/admin with password. Password for admin/admin@JASPERFAMILY.ORG: global kadmin: addprinc adam WARNING: no policy specified for rick@JASPERFAMILY.ORG; defaulting to no policy Enter password for principal "rick@JASPERFAMILY.ORG": adampw Re-enter password for principal "rick@JASPERFAMILY.ORG": adampw Principal "rick@JASPERFAMILY.ORG" created. kadmin.loocal: quit
He also likes this LDAP Browser/Editor. I didn't check it out.