NSS

This page has information about NSS, the "Name Service Switch" mechanisms that allows to store things like users and passwords somewhere else than in plain old files. Read on for a more complete description.

As long as databases are stored in local system files, NSS is not needed and therefore nothing needs to be installed. NSS becomes relevant only when the first data source that provides non-local information is installed. This is documented further down under the "LDAP data source" section. This section also contains the Debian packages that need to be installed.


References

nscd (name service caching daemon) 
man nscd
GNU C Library 
http://www.gnu.org/software/libc/manual/html_node/NSS-Basics.html
Wikipedia 
http://en.wikipedia.org/wiki/Name_Service_Switch
RFC 2307 (definitions for nis.schema
ftp://ftp.rfc-editor.org/in-notes/rfc2307.txt


Glossary

NSS 
Name Service Switch
Configuration database 
A database that contains a collection of names of the same "type". For instance: "user names", "group names", "passwords".
Source 
A source that provides a configuration database. For instance: a local file (/etc/passwd), LDAP directory, MySQL database


Overview: What is NSS

NSS decouples applications that need certain system information from the source that provides this information. Applications are not aware whether or not NSS is enabled - actually they don't even know that a concept such as NSS exists! Applications call system functions and NSS is encapsulated behind these system functions.

A rough overview of how NSS is involved when an application makes a system call:

  • A programm has the ID of a system user and needs the user's name
  • The program uses a C system call
  • The system function notices that NSS is enabled
  • The system function queries the NSS configuration about possible sources for the database "user names"
  • The system function queries each source in the configured order
  • The first source that is able to satisfy the system function's request is used
  • The system function returns the desired user name to the program


NSS database types

aliases 
Mail aliases
ethers 
Ethernet numbers
group 
Groups of users. Traditionally stored in /etc/group
hosts 
Host names and numbers. Traditionally provided by DNS (dynamic) and stored in /etc/hosts (static)
netgroup 
Network wide list of host and users
networks 
Network names and numbers. . Traditionally provided by DNS (dynamic) and stored in /etc/networks (static)
protocols 
Network protocols. Traditionally stored in /etc/protocols
passwd 
User passwords. Traditionally stored in /etc/passwd
rpc 
Remote procedure call names and numbers
services 
Network services. Traditionally stored in /etc/services
shadow 
Shadow user passwords. Traditionally stored in /etc/shadow


LDAP data source

Debian Packages

libnss-ldap
nscd (automatically installed)

Note: There is a package named libnss-ldapd that provides the same service as libnss-ldap but is documented as "fixes problems related to host name lookups and name lookups during booting". I did not install the package because I do not think that I need it since I only want to use LDAP for the user database.


References

nss_ldap web site 
http://www.padl.com/OSS/nss_ldap.html
Local documentation 
/usr/share/doc/libnss-ldap


Configuration

dpkg

These are the questions asked by dpkg. Some of the questions appear only when dpkg-reconfigure is executed.

  • LDAP server URI = ldapi:///
  • Distinguished name of the search base = dc=herzbube,dc=ch
  • LDAP version to use = 3
  • Does the LDAP database require login? = Yes
  • Make the configuration file readable/writeable by its owner only? = Yes
  • LDAP account for root = cn=libnss-ldap-root,ou=users,dc=herzbube,dc=ch
  • LDAP root account password = secret
  • Unprivileged database user = cn=libnss-ldap,ou=users,dc=herzbube,dc=ch
  • Password for database login account = secret


The answers are stored in these files:

/etc/libnss-ldap.conf
/etc/libnss-ldap.secret

Some of the questions/answers are shared with the package libpam-ldap, so if that package has already been installed some questions may not be asked, the answers are simply taken from the DebConf database. To see a complete list of questions and answers that are stored in the DebConf database:

debconf-show libnss-ldap


Notes regarding permissions:

  • The file /etc/libnss-ldap.secret contains the password for the privileged LDAP user libnss-ldap-root. The file is owned by root and has mode 600.
  • The file /etc/libnss-ldap.conf contains the password for the unprivileged LDAP user libnss-ldap. The file is owned by root and has mode 600. Unlike libpam-ldap, the file does not have to be world readable because the nscd daemon, which runs as root, accesses the libnss-ldap module.
    • At some time in the past, when pelargir was still running Debian testing on a MacMini, I had to make /etc/libnss-ldap.conf world-readable (mode 644) after all, because non-root users were starting to have all sorts of problems.
    • A typical symptom was that after logging in a non-root user would see the following message as part of the bash login shell prompt: "I have no name!". Another symptom that I noticed was git clone operations failing with the error message "fatal: unable to look up current user in the passwd file: Permission denied". Giving the file mode 644 fixed all these problems.
    • Now that pelargir is running Debian stable (jessie) on a Dedicated Server, the original tight permissions seem to work again


/etc/libnss-ldap.conf

Edit /etc/libnss-ldap.conf:

  • pam_min_uid = 1000 (same policy as in /etc/adduser.conf)
  • pam_max_uid = 29999 (same policy as in /etc/adduser.conf)
  • nss_base_passwd = ou=users, (base DN is appended)
  • nss_base_shadow = ou=users, (base DN is appended)
  • nss_base_group = ou=groups, (base DN is appended)
  • Only if host names are stored in LDAP: nss_base_hosts = ou=hosts, (base DN is appended)

After the edit is finished, restart the nscd daemon to re-read the file:

/etc/init.d/nscd restart


/etc/nsswitch.conf

Edit /etc/nsswitch.conf:

passwd: compat ldap
group: compat ldap
shadow: compat ldap
gshadow: files
# Only if host names are stored in LDAP
# hosts: compat ldap dns

TODO: Find out why the "gshadow" entry requires "files" instead of "compat".


After the edit is finished, restart the nscd daemon to re-read the file:

/etc/init.d/nscd restart


Directory modifications

After configuring libpam-ldap, modify the LDAP directory as follows:

  • Add an LDAP user cn=libnss-ldap,ou=users,dc=herzbube,dc=ch to the directory
  • Add an LDAP user cn=libnss-ldap-root,ou=users,dc=herzbube,dc=ch to the directory

Configure access rights in /etc/ldap/slapd.conf, then restart the LDAP daemon. The access rights can be derived from reading /usr/share/doc/libpam-ldap/LDAP-Permissions.txt:

  • read-only access to the ou=users, ou=groups and ou=hosts tree for libnss-ldap
  • same read-only access for libnss-ldap-root, with the additional read-only access to the userPassword attribute

Add user, group and host LDAP entries to the directory:

  • User account LDAP entries must have the following structure so that nss_ldap can use them:
    • must be located below ou=users,dc=herzbube,dc=ch
    • must have object classes posixAccount and shadowAccount
    • apparently the gecos attribute cannot hold values with special characters (e.g. umlaut); for instance, I cannot add the value "Näf"
  • Group LDAP entries must have the following structure so that nss_ldap can use them:
    • must be located below ou=groups,dc=herzbube,dc=ch
    • must have object class posixGroup
    • the uniqueMember attribute is referenced by the nss_ldap documentation
      • I don't know exactly what this attribute is supposed to do
      • an example value: uid=patrick,ou=users,dc=herzbube,dc=ch
      • is an attribute from core.schema
      • attribute comes from RFC 2256 und has OID 2.5.4.50
      • the only object class with this attribute is groupOfUniqueNames (a structural object class, i.e. cannot be added to posixGroup)
      • at the moment I am simply ignoring this attribute since I cannot set it even if I knew what it is supposed to do
  • Host LDAP entries must have the following structure so that nss_ldap can use them:
    • must be located below ou=hosts,dc=herzbube,dc=ch
    • must have object classes ipHost
    • because ipHost is an auxiliary object class, the entries also require a structural object class; RFC 2307 recommends object class device
    • the cn attribute holds the host names; the distinguished value is the canonical host name, all other values are the aliases


System files modifications

After everything is set up, the entries stored in LDAP can now be removed from the system files

  • /etc/passwd
  • /etc/group
  • /etc/shadow
  • /etc/hosts

Warning: The hostname pelargir must be present in /etc/hosts, otherwise the LDAP daemon slapd refuses to start up once it has been shut down. This probably is a bootstrap problem: slapd tries to lookup the IP for pelargir using a system call, which triggers nscd and libnss-ldap to make a LDAP lookup, which of course fails since the daemon has not finished starting up.


nscd

Configuration file is

/etc/nscd.conf

Nowadays the default configuration is ok. In the past I had to manually make the following changes (although it's now obsolete, I keep this information for historical reasons):

enable-cache            hosts           yes

Explanation of the change:

  • Host caching is disabled by default because of a bug in nscd which can cause problems when the IP address of the LDAP server changes
  • See http://sourceware.org/bugzilla/show_bug.cgi?id=4428
  • I think this will not affect me since I don't change my LDAP server to anything else than 127.0.0.1
  • Anyway, performance on some things such as "ps aux" is very bad (don't ask me why there is a connection between the "ps" command and the hosts database), therefore I really need this caching