diff --git a/ChangeLog b/ChangeLog index c0c429de..fca0c16a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-11-17 Nicolas François + + * NEWS, lib/nscd.c: Execute nscd -i instead of using the private + glibc socket to flush the nscd tables. This comes from the RedHat + patch shadow-4.0.16-nscd.c. + * lib/commonio.c: Forbid inheritance of the passwd and group files + to the spawed processes (like nscd). This comes from the RedHat + patch shadow-4.0.17-notInheritFd.patch. + * lib/nscd.h: Update header. + 2007-11-17 Nicolas François * src/usermod.c (fail_exit): Add static variables pw_locked, diff --git a/NEWS b/NEWS index 243f1b15..6e61c154 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,8 @@ shadow-4.0.18.1 -> shadow-4.0.18.2 UNRELEASED - usermod: Update the group database before flushing the nscd caches. - usermod: Make sure the group modifications will be allowed before writing the passwd files. +- Flush the nscd tables using nscd -i instead of the private glibc socket. + (RedHat patches shadow-4.0.16-nscd.c and shadow-4.0.17-notInheritFd.patch) shadow-4.0.18.1 -> shadow-4.0.18.2 28-10-2007 diff --git a/lib/commonio.c b/lib/commonio.c index 036d232d..85eb7c41 100644 --- a/lib/commonio.c +++ b/lib/commonio.c @@ -460,6 +460,10 @@ int commonio_open (struct commonio_db *db, int mode) } return 0; } + + /* Do not inherit fd in spawned processes (e.g. nscd) */ + fcntl(fileno(db->fp), F_SETFD, FD_CLOEXEC); + #ifdef WITH_SELINUX db->scontext = NULL; if ((is_selinux_enabled () > 0) && (!db->readonly)) { diff --git a/lib/nscd.c b/lib/nscd.c index f09aec8a..d897af74 100644 --- a/lib/nscd.c +++ b/lib/nscd.c @@ -1,101 +1,50 @@ -/* Copyright (c) 1999 SuSE GmbH Nuerenberg, Germany - Author: Thorsten Kukuk */ +/* Author: Peter Vrabec */ -#include -#include +/* because of TEMP_FAILURE_RETRY */ +#define _GNU_SOURCE + +#include #include #include -#include #include -#include -#include +#include +#include +#include +#include -/* Version number of the daemon interface */ -#define NSCD_VERSION 2 -/* Path for the Unix domain socket. */ -#define _PATH_NSCDSOCKET "/var/run/nscd/socket" -#define _PATH_NSCDSOCKET_OLD "/var/run/.nscd_socket" - -/* Available services. */ -typedef enum { - GETPWBYNAME, - GETPWBYUID, - GETGRBYNAME, - GETGRBYGID, - GETHOSTBYNAME, - GETHOSTBYNAMEv6, - GETHOSTBYADDR, - GETHOSTBYADDRv6, - LASTDBREQ = GETHOSTBYADDRv6, - SHUTDOWN, /* Shut the server down. */ - GETSTAT, /* Get the server statistic. */ - INVALIDATE, /* Invalidate one special cache. */ - LASTREQ -} request_type; - -/* Header common to all requests */ -typedef struct { - int version; /* Version number of the daemon interface. */ - request_type type; /* Service requested. */ -#if defined(__alpha__) - int64_t key_len; /* Key length is 64bit on Alpha. */ -#else - int32_t key_len; /* Key length, 32bit on most plattforms. */ -#endif -} request_header; - -/* Create a socket connected to a name. */ -static int nscd_open_socket (void) -{ - struct sockaddr_un addr; - int sock; - - sock = socket (PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - return -1; - - addr.sun_family = AF_UNIX; - assert (sizeof (addr.sun_path) >= sizeof (_PATH_NSCDSOCKET)); - strcpy (addr.sun_path, _PATH_NSCDSOCKET); - if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) { - addr.sun_family = AF_UNIX; - assert (sizeof (addr.sun_path) >= - sizeof (_PATH_NSCDSOCKET_OLD)); - strcpy (addr.sun_path, _PATH_NSCDSOCKET_OLD); - if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < - 0) { - close (sock); - return -1; - } - } - - return sock; -} /* - * nscd_flush_cache - flush specyfied service bufor in nscd cache + * nscd_flush_cache - flush specified service buffer in nscd cache */ -int nscd_flush_cache (char *service) +int nscd_flush_cache (const char *service) { - int sock = nscd_open_socket (); - request_header req; - struct iovec iov[2]; - ssize_t nbytes; + pid_t pid, termpid; + int err, status; + char *spawnedArgs[] = {"/usr/sbin/nscd", "nscd", "-i", service, NULL}; + char *spawnedEnv[] = {NULL}; - if (sock == -1) + /* spawn process */ + if( (err=posix_spawn(&pid, spawnedArgs[0], NULL, NULL, + spawnedArgs, spawnedEnv)) !=0 ) + { + fprintf(stderr, "posix_spawn() error=%d\n", err); return -1; + } - req.version = NSCD_VERSION; - req.type = INVALIDATE; - req.key_len = strlen (service) + 1; + /* Wait for the spawned process to exit */ + termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); + if (termpid == -1) + { + perror("waitpid"); + return -1; + } + else if (termpid != pid) + { + fprintf(stderr, "waitpid returned %ld != %ld\n", + (long int) termpid, (long int) pid); + return -1; + } - iov[0].iov_base = &req; - iov[0].iov_len = sizeof (req); - iov[1].iov_base = service; - iov[1].iov_len = req.key_len; - - nbytes = writev (sock, iov, 2); - - close (sock); - return (nbytes != iov[0].iov_len + iov[1].iov_len ? (-1) : 0); + return 0; } + diff --git a/lib/nscd.h b/lib/nscd.h index 27e818af..dc986ae1 100644 --- a/lib/nscd.h +++ b/lib/nscd.h @@ -1,11 +1,8 @@ -/* Copyright (c) 1999 SuSE GmbH Nuerenberg, Germany - Author: Thorsten Kukuk */ - -#ifndef _FAILURE_H_ -#define _FAILURE_H_ +#ifndef _NSCD_H_ +#define _NSCD_H_ /* - * nscd_flush_cache - flush specyfied service bufor in nscd cache + * nscd_flush_cache - flush specified service buffer in nscd cache */ extern int nscd_flush_cache (char *service);