Problem
In this scenario,
getservent() and related library calls fail, even though
/etc/services is present, correct, and appropriately permissioned.
Side effects include the failure of utilities such as telnet,
syslogd, and various daemons which configuring listener
ports defined by service name.
By extension, this problem may also affect other NSS lookups, including
but not limited to: hosts, passwd, group, shadow, ethers, netmask, protocols,
rpc, netgroup, publickey, automount, aliases, bootparams, etc.
In most cases problems relating to user, automounts, and aliases
information will be more obvious.
Affected
- Probably affects most Unixes based on the GNU C Library
- Seen in Debian 3.1 (Sarge) with GNU Libc 2.3.2 (libc6)
Cause
The manual page for nsswitch.conf provides an example based on
NIS which does not translate directly to the best one for LDAP for most
environments. The use of [NOTFOUND=return] is generally only
applicable to scenarios where the appropriate NSS database was known to
exist and be the sole authoritive source, such as seen in many NIS
deployments. However, many LDAP deployments serve solely user account
information, and would first need to have more schemas activated and
entries added to support the additional NSS lookups.
Reproduction
You have the problem if the following code, when run, outputs
“getservbyname - failed”.
#include <stdio.h>
#include <netdb.h>
int main(void)
{
int succp = 1;
struct servent *service = getservbyname("ssh", "tcp");
if(service) {
int i = 0;
printf("found service \"%s\"\n", service->s_name);
while(service->s_aliases[i])
printf("with alias \"%s\"\n", service->s_aliases[i++]);
printf(" on port %d\n", service->s_port);
printf(" protocol \"%s\"\n", service->s_proto);
} else {
fprintf(stderr, "getservbyname - failed\n");
succp = 0;
}
return succp ? 0 : -1;
}
Solution
The documentation for /etc/nsswitch.conf recommends an
advanced syntax to allow multiple database services to be involved in
lookups. This syntax may not work in some cases. A line such as:
services: ldap [NOTFOUND=return] files # can break getserv*()
may totally disable lookups if LDAP is enabled but missing services
data, where any of the following should work just fine:
services: files ldap
services: ldap files
services: ldap [NOTFOUND=continue] files
|