LDAP in the Solaris Operating Environment[c] Deploying Secure Directory Services
Murphy's law states that whatever can go wrong, will go wrong. While it is impossible to anticipate every conceivable misconfiguration or malfunction that can cause LDAP failures, there are common pitfalls, and the following sections offer some suggestions on how to recognize and correct these common problems:
The suggestions describe how to use the following tools:
A detailed discussion on the use of these tools appears in Chapter 6 "Management Tools and Toolkits" and Appendix C, "Using snoop with LDAP." If you are unfamiliar with the tools discussed here, consult that chapter first. Directory Server Configuration Problems
Directory server installation is not a common area in which to experience trouble, especially if you are installing the bundled version. However, there are four common problems that you might encounter:
These problems usually result in error messages during the installation or during the final step when the directory server is started for the first time. To diagnose these problems, perform the following procedures. After you fix the problem you should run setup or configure again. To Troubleshoot a Missing Solaris OE Patch
To Troubleshoot DNS FQN Failures
If you get a response such as ping: unknown host myserver.example.com , check the /etc/nsswitch.conf file to see if it is set up to search DNS. You can also add the FQN as an alias in the local /etc/ hosts file, then rerun setup . What to Do When the Directory Server Port Is Already in Use
This situation usually exhibits itself during setup when the default port number of the directory server is displayed. If the displayed number in brackets is not [ 389 ], chances are there is another directory instance running on that port. Another reason that port 389 may not listed as the default is if the installation is being performed as a non-root user. In this case, only ports above 1024 are available for configuration.
To Recognize an Incompatible Installation of the 64-Bit Version on a 32-Bit System
This problem presents itself when the package dependencies are checked. If you ignore the messages and proceed with the installation, the directory configuration fails. Remove all the packages you just installed and only install the packages without a trailing x in their name . Sun ONE Console Problems
The Sun ONE Console can fail to start for several reasons. Problems in this area often have to do with the Console having dependencies on other processes. If the Console is started from a window shell that is logged in as a different user than the desktop, the user must be granted permission (with xhost + ) to access the display. In addition, the administration and directory servers must be running before the Console can start. Some of the potential problems are:
To Invoke startconsole on a Protected Display
The console is an X-based application and the X-server must permit access. This situation is a common one because it is typical to log in, then switch to another user, (for example, root) to perform administrative functions. When you try to start the Console, you receive the following error: # /usr/sbin/directoryserver startconsole & Xlib: connection to ":0.0" refused by server Xlib: Client is not authorized to connect to Server Console: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable. To fix this problem, type the following command as the user to which the desktop display belongs. $ xhost + access control disabled, clients can connect from any host
Note For production use, you should not use just the "+" sign. Instead, specify the IP address of the system you are granting access to or connect to the system running the Console with Secure Shell (SSH).
To Troubleshoot Console Login Rejections
Server Configuration Problems
To Troubleshoot idsconfig Failures
If the idsconfig script is run after the directoryserver configure command provided with Sun ONE Directory Server 5.2, you should not encounter problems. However, if you run the script against an unbundled version of the Sun ONE Directory Server, you might have a problem. One known issue is with the 5.1sp1 release. For example, you might see the error message: ERROR: update of schema attributes failed!
To Diagnose Other idsconfig Problems
Watch for the following database- related problem . The following error is usually caused by using a back-end database name other than userRoot . The problem can be fixed by modifying the idsconfig script and commenting out the check database back ends. Contact Sun service for additional information. ERROR: Cannot determine the top of the tree Other script failures can be debugged by running the idsconfig script with the -x option and observing the commands that were being run at the point where the idsconfig script failed. # vi /usr/lib/ldap/idsconfig . . . #!/bin/sh -x . . . Secured LDAP Client Problems
These client problems might exhibit any of the following symptoms:
To Troubleshoot Client Initialization Problems
The problem can be fixed by specifying notfoo as the domain name or by modifying the value of the nisDomain attribute on the directory server. To Troubleshoot Client Data Access Problems
If an initialized Solaris LDAP client cannot access naming service, check the following. Check the name service containers with the ldaplist command . If the client is set up correctly, you should be able to see the name service containers as shown in the following example: # ldaplist dn: cn=Directory Administrators, dc=example, dc=com dn: ou=People, dc=example, dc=com dn: ou=Special Users, dc=example, dc=com dn: ou=group, dc=example, dc=com dn: ou=Groups, dc=example, dc=com dn: ou=rpc, dc=example, dc=com . . . You might see this instead: # ldaplist ldaplist:Object not found(Session error no available conn.) This indicates the client is unable to access the data using the authentication method defined for it. Even though the client might have initialized without problems, the following misconfigurations could exist:
To verify the proxyDN and associated proxypassword , try to bind to the directory server using a command like ldapsearch . # ldapsearch -D "cn=proxyagent, ou=profile, dc=example.com" -w mysecret -b dc=example, dc=com objectclass=\* If the ldapsearch command fails, make sure the password is what you think it is. If it succeeds, check the content of /var/ldap/ldap_client-cred for misspelling. For clients using the TLS:SIMPLE authentication method, check the server certificate header for the address of the directory server and make sure you can ping that address. Authentication Problems
To Troubleshoot Password Authentication Problems
After the client is successfully initialized, users might not be able to log in. This is a common problem that can be caused by a variety of configuration errors. If users cannot get authenticated, the first thing to do is to verify the entry for the user who is trying to log in. You can do this with either the ldapsearch or ldaplist command as shown below.
Authentication Examples
The method used to authenticate users is determined by how the pam.conf file is constructed on the client system. For the examples, the following Solaris 9 OE configuration file is used. # cat /etc/pam.conf # Authentication management # # login service (explicit because of pam_dial_auth) # login auth requisite pam_authtok_get.so.1 login auth required pam_dhkeys.so.1 login auth sufficient pam_unix_auth.so.1 login auth required pam_ldap.so.1 try_first_pass login auth required pam_dial_auth.so.1 This is the recommended stacking of PAM modules as discussed in Chapter 3 "Defining Directory Service Security Architecture." With a file set up like this one, pam_unix authentication is tried first, and if it succeeds, the user is authenticated. If it fails, pam_ldap is tried. The following sections show traces of how this is done. Authentication with pam_unix
In this example a user called tom logs in. The user's password is stored in {crypt} format (highlighted in bold text). LDAP: Operation *[APPL 4: Search Request] LDAP: [Base Object] LDAP: ou=people, dc=example, dc=com ..... LDAP: Equality Match *[3] LDAP: [Attr Descr] LDAP: objectClass LDAP: [Value] LDAP: shadowAccount LDAP: *[3] LDAP: [OctetString] LDAP: uid LDAP: [OctetString] LDAP: tom The trace shows that a search is performed in the ou=people container for an entry that contains the shadowAccount object class and an uid attribute equal to tom . The search base of ou=people , dc=example , dc=com is determined by values set in the client profile that the client is configured to use. The following trace shows the result of this search. LDAP: Operation *[APPL 4: Search ResEntry] LDAP: [Object Name] LDAP: uid=tom, ou=people, dc=example, dc=com LDAP: *[Partial Attributes] LDAP: *[Attribute] LDAP: [Type] LDAP: uid LDAP: *[Vals] LDAP: [Value] LDAP: tom LDAP: *[Attribute] LDAP: [Type] LDAP: userpassword LDAP: *[Vals] LDAP: [Value] LDAP: {crypt}SnLaPR6XvcJV6 The search in this case finds an entry with a DN of uid=tom , dc=sun , dc=com that matches the search criteria. The value of the userpassword attribute is then retrieved. If the value matches the password that the user entered, the authentication criteria is satisfied so pam_ldap is never invoked. If the value does not match, then pam_ldap is invoked as shown in the next example. Authentication with pam_ldap
In the following example, a user called michael attempts to log in. In this case the password for the account is not stored in {crypt} format so the attempt at pam_unix authentication fails. The try_first_pass option is specified in pam.conf , so the user is not prompted to enter an LDAP password. Instead, the first password entered is tried. If, however, the password entered was mistyped , the user is prompted for an LDAP password. In this example, it is assumed that the password entered the first time is correct. LDAP: Operation *[APPL 3: Search Request] LDAP: [Base Object] LDAP: ou=people, dc=example, dc=com LDAP: [Scope] LDAP: singleLevel LDAP: [DerefAliases] LDAP: derefAlways LDAP: [SizeLimit] LDAP: [TimeLimit] LDAP: [TypesOnly] LDAP: And *[0] LDAP: Equality Match *[3] LDAP: [Attr Descr] LDAP: objectclass LDAP: [Value] LDAP: posixAccount LDAP: *[3] LDAP: [OctetString] LDAP: uid LDAP: [OctetString] LDAP: michael In this example, a search is made for an entry that contains the posixAccount object class and has a uid attribute value equal to michael . This search is somewhat different than the one performed for pam_unix in that the posixAccount object class is specified instead of the shadowAccount object class, and the userpassword attribute value is not requested . If the search is successful, the DN of the entry is returned, which is used in the next example to bind to the directory. LDAP: ----- Lightweight Directory Access Protocol Header ---- LDAP: *[LDAPMessage] LDAP: [Message ID] LDAP: Operation *[APPL 0: Bind Request] LDAP: [Version] LDAP: [Object Name] LDAP: uid=michael, ou=people, dc=example, dc=com LDAP: Authentication: Simple [0] LDAP: mysecret ..... LDAP: Operation *[APPL 1: Bind Response] LDAP: [Result Code] LDAP: Success In this example, the entry found that satisfied the search criteria has a DN of uid= michael , ou=people , dc=example , dc=com . Using this DN along with the password, the bind request is attempted. If the request is successful, the user is authenticated. A key difference between pam_unix authentication (discussed in the previous example) is that the password entered by the user is sent to the directory server. In the example, no data encryption is used, so the password is sent in clear text. In production use, you would want to use data encryption, but for debugging purposes, sending it in clear text is helpful. If it works with clear text, then data encryption can be turned on. Authentication Problem Summary
The following is a summary of possible symptoms and corrective actions for common authentication problems. pam_unix Problems
Automounter Problems
The Solaris OE automounter relies heavily on a naming service to obtain the information it requires to function properly. If the information cannot be obtained or is incorrect, the automounter will fail to work. Identifying the source of the problem can be tricky because you might only see a message like this: # cd /home/tom /home/tom: No such file or directory The first step in diagnosing the problem is to determine where the automounter is looking for the information it needs. You can start by looking at the /etc/nsswitch.conf file that the client is using. # cat /etc/nsswitch.conf . . . hosts: ldap [NOTFOUND=return] files .... automount: files ldap . . . # cat /etc/auto_master /net -hosts -nosuid,nobrowse /home auto_home -nobrowse /xfn -xfn /tools auto_tools -nobrowse +auto_master The two key entries here are hosts and automount . The hosts entry is used to resolve the address of the NFS server specified in the autofs mount entry, and the automount entry is used to determine where to look for the auto_master entry. In this example, files is searched first, so the /etc/auto_master file is consulted to identify autofs mount points. The +auto_master notation instructs autofs to consult a name service if the mount point is not found in the file. To see the entry on the directory server, run the following command: # ldaplist -l auto_home tb250 dn: cn=tb250,nisMapName=auto_home,dc=example,dc=com objectClass: nisObject objectClass: top cn: tb250 nismapentry: nfsserver:/export/home7/tb250 nismapname: auto_home From the output, you can see an old style notation specifying nisObject to define automount objects. This definition does not work with the Phase 2 clients unless objectclass mapping is implemented. # ldaplist -l auto_home tb250 dn: automountKey=tb250,automountMapName=auto_home,dc=example,dc=com objectClass: automount objectClass: top automountKey: tb250 automountInformation: nfsserver:/export/home7/tb250 # This output shows the Phase 2 definition for the automount object is used. These objects do not work with Phase 1 clients or Phase 2 clients using Version 1.0 client profiles. To see what the automounter is doing, you can turn on debugging as shown in this example. # /etc/init.d/autofs stop # /usr/lib/autofs/automountd -vTT # /usr/sbin/automount -v automount: /net mounted automount: /home remounted automount: /xfn mounted automount: no unmounts # cd /home/tom LOOKUP REQUEST: Thu Aug 22 08:46:39 2002 name=tb250[] map=auto_home opts=nobrowse path=/home direct=0 getmapent_ldap: key=[ tom ] ldap_match: ldapkey =[ tom ] ldap_match: searchfilter =[ (&(objectClass=nisObject) (nisMapName=auto_home)(cn=tom)) ] ldap_match: __ns_ldap_list OK mapline: nfsserver:/export/home7/tom do_mount1:(nfs,nfs) /home/tom -nobrowse nfsserver:/export/home7/tom penalty=0 nfsmount: standard mount on /home/tom : nfsserver:/export/home7/tom ping: nfsserver timeout=15 request vers=3 min=2 pingnfs OK: nfs version=3 nfsmount: Get mount version: request vers=3 min=3 nfsmount: mount version=3 mount nfsserver:/export/home7/tom /home/tom () mount nfsserver:/export/home7/tom dev=3a40003 rdev=0 OK MOUNT REPLY : status=0, AUTOFS_DONE In this example, the search is made for an nisObject object. This means that is was performed on a Phase 1 client. The next example shows what the output on a Phase 2 client would look like. # cd /home/tb250 t1 LOOKUP REQUEST: Fri Aug 23 08:49:24 2002 t1 name=tb250[] map=auto_home opts=nobrowse path=/home direct=0 t1 PUSH /etc/auto_home t1 getmapent_ldap called t1 getmapent_ldap: key=[ tb250 ] t1 ldap_match called t1 ldap_match: key =[ tb250 ] t1 ldap_match: ldapkey =[ tb250 ] t1 ldap_match: Requesting list for (&(objectClass= automount)(automountKey=tb250)) in auto_home t1 ldap_match: __ns_ldap_list OK t1 ldap_match: found: nfsserver:/export/home7/tb250 Debugging SASL DIGEST-MD5 Problems
If SASL/DIGEST-MD5 authentication is used, a snoop trace will look something like this (bold text indicates the information to look for): LDAP: ----- Lightweight Directory Access Protocol Header ----- LDAP: *[LDAPMessage] LDAP: [Message ID] LDAP: Operation *[APPL 0: Bind Request] LDAP: [Version] LDAP: [Object Name] LDAP: Authentication: SASL *[3] LDAP: [OctetString] LDAP: DIGEST-MD5 LDAP: LDAP: ----- LDAP: ----- LDAP: LDAP: "" LDAP: LDAP: ----- Lightweight Directory Access Protocol Header ----- LDAP: *[LDAPMessage] LDAP: [Message ID] LDAP: Operation *[APPL 1: Bind Response] LDAP: [Result Code] LDAP: SASL Bind In Progress LDAP: [Matched DN] LDAP: [Error Message] LDAP: SASL Credentials [7] LDAP: realm="myserver.example.com",no LDAP: nce=" PXZxIw/DacrytK" ,qop="auth", LDAP: algorithm=md5-sess,charset=utf-8 LDAP: If you are having SASL/DIGEST-MD5 problems, check the directory server access log for errors, make sure SASL/DIGEST-MD5 is enabled and that passwords are stored in clear text. TLS/SSL Errors
TLS/SSL problems can be tricky to debug because the data transfer is encrypted. If you have problems connecting, check the system log ( syslog ) and the directory server access log for error messages. Example: # cat /var/adm/messages ... Sep 5 10:23:29 eelab14 ldaplist[9626]: [ID 605618 user.error] libldap: CERT_VerifyCertName: cert server name 'myldap' does not match 'myserver.example.com': SSL connection denied . . . In this example, there is a mismatch between the fully qualified directory server name and the name contained in the server certificate header. If the system log fails to provide sufficient information, check the directory server access log for clues. You can get additional information by turning on error log tracing as shown in FIGURE 4-4. Figure 4-4. Error Log Properties
Password Problems
Problems can occur if the password is not stored in the expected format, or the password is not what you expect. To generate a hashed password, use the pwdhash command as shown. # directoryserver pwdhash -D /var/mps/serverroot/slapd-vipivot \ -s crypt hello {crypt}VfHh.ESyoKX0U # directoryserver pwdhash -D /var/mps/serverroot/slapd-vipivot \ -s ssha hello {SSHA}3Kvdi0z6hIfQUCWGBvhGyo4rCOdRENccR0OPXQ== To change a password and store it in UNIX crypt format:. dn: uid=tb250,ou=people,dc=example,dc=com changetype: modify replace: userpassword userpassword: {crypt}VfHh.ESyoKX0U To change a password and store it in Sated Secure Hash Algorithm (SSHA): dn: cn=proxyagent,ou=profile,dc=example,dc=com changetype: modify replace: userpassword userpassword: {SSHA}3Kvdi0z6hIfQUCWGBvhGyo4rCOdRENccR0OPXQ== To change a password and store it in clear text. dn: uid=test,ou=people,dc=example,dc=com changetype: modify replace: userpassword userpassword: {clear}hello |