summaryrefslogtreecommitdiff
path: root/nscd
diff options
context:
space:
mode:
Diffstat (limited to 'nscd')
-rw-r--r--nscd/Depend1
-rw-r--r--nscd/Makefile19
-rw-r--r--nscd/aicache.c136
-rw-r--r--nscd/cache.c20
-rw-r--r--nscd/connections.c265
-rw-r--r--nscd/dbg_log.c4
-rw-r--r--nscd/dbg_log.h2
-rw-r--r--nscd/gai.c9
-rw-r--r--nscd/getgrgid_r.c6
-rw-r--r--nscd/getgrnam_r.c6
-rw-r--r--nscd/gethstbyad_r.c3
-rw-r--r--nscd/gethstbynm3_r.c4
-rw-r--r--nscd/getpwnam_r.c2
-rw-r--r--nscd/getpwuid_r.c2
-rw-r--r--nscd/getsrvbynm_r.c2
-rw-r--r--nscd/getsrvbypt_r.c2
-rw-r--r--nscd/grpcache.c109
-rw-r--r--nscd/hstcache.c97
-rw-r--r--nscd/initgrcache.c48
-rw-r--r--nscd/mem.c2
-rw-r--r--nscd/netgroupcache.c65
-rw-r--r--nscd/nscd-client.h16
-rw-r--r--nscd/nscd.c4
-rw-r--r--nscd/nscd.h4
-rw-r--r--nscd/nscd_conf.c2
-rw-r--r--nscd/nscd_getai.c4
-rw-r--r--nscd/nscd_getgr_r.c8
-rw-r--r--nscd/nscd_gethst_r.c11
-rw-r--r--nscd/nscd_getpw_r.c8
-rw-r--r--nscd/nscd_getserv_r.c4
-rw-r--r--nscd/nscd_helper.c13
-rw-r--r--nscd/nscd_initgroups.c4
-rw-r--r--nscd/nscd_netgroup.c6
-rw-r--r--nscd/nscd_proto.h36
-rw-r--r--nscd/nscd_setup_thread.c2
-rw-r--r--nscd/nscd_stat.c29
-rw-r--r--nscd/pwdcache.c112
-rw-r--r--nscd/selinux.c2
-rw-r--r--nscd/selinux.h2
-rw-r--r--nscd/servicescache.c92
40 files changed, 413 insertions, 750 deletions
diff --git a/nscd/Depend b/nscd/Depend
index 6c1aa44e6e..ba64a2d899 100644
--- a/nscd/Depend
+++ b/nscd/Depend
@@ -1 +1,2 @@
nptl
+htl
diff --git a/nscd/Makefile b/nscd/Makefile
index 50bad32ea5..b713a84c49 100644
--- a/nscd/Makefile
+++ b/nscd/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2016 Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -73,18 +73,17 @@ LDLIBS-nscd = $(selinux-LIBS)
include ../Rules
-CFLAGS-nscd_getpw_r.c = -fexceptions
-CFLAGS-nscd_getgr_r.c = -fexceptions
-CFLAGS-nscd_gethst_r.c = -fexceptions
-CFLAGS-nscd_getai.c = -fexceptions
-CFLAGS-nscd_initgroups.c = -fexceptions
+CFLAGS-nscd_getpw_r.c += -fexceptions
+CFLAGS-nscd_getgr_r.c += -fexceptions
+CFLAGS-nscd_gethst_r.c += -fexceptions
+CFLAGS-nscd_getai.c += -fexceptions
+CFLAGS-nscd_initgroups.c += -fexceptions
CPPFLAGS-nscd += -D_FORTIFY_SOURCE=2
ifeq (yesyes,$(have-fpie)$(build-shared))
CFLAGS-nscd += $(pie-ccflag)
endif
-CFLAGS-nscd += $(stack-protector)
ifeq (yesyes,$(have-fpie)$(build-shared))
LDFLAGS-nscd = -Wl,-z,now
@@ -93,12 +92,12 @@ endif
# Set libof-nscd.
cpp-srcs-left := $(nscd-modules)
lib := nscd
-include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
$(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
ifeq ($(build-shared),yes)
-$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
+$(objpfx)nscd: $(shared-thread-library)
else
-$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
+$(objpfx)nscd: $(static-thread-library)
endif
diff --git a/nscd/aicache.c b/nscd/aicache.c
index a2e6cf8475..439e0ea126 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -1,5 +1,5 @@
/* Cache handling for host lookup.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -25,13 +25,13 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
-#include <resolv/res_hconf.h>
+#include <resolv/resolv-internal.h>
+#include <resolv/resolv_context.h>
+#include <resolv/res_use_inet6.h>
+#include <scratch_buffer.h>
#include "dbg_log.h"
#include "nscd.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
typedef enum nss_status (*nss_gethostbyname4_r)
@@ -100,23 +100,22 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
no_more = 0;
nip = hosts_database;
- /* Initialize configurations. */
- if (__glibc_unlikely (!_res_hconf.initialized))
- _res_hconf_init ();
- if (__res_maybe_init (&_res, 0) == -1)
+ /* Initialize configurations. If we are looking for both IPv4 and
+ IPv6 address we don't want the lookup functions to automatically
+ promote IPv4 addresses to IPv6 addresses. Therefore, use the
+ _no_inet6 variant. */
+ struct resolv_context *ctx = __resolv_context_get ();
+ bool enable_inet6 = __resolv_context_disable_inet6 (ctx);
+ if (ctx == NULL)
no_more = 1;
- /* If we are looking for both IPv4 and IPv6 address we don't want
- the lookup functions to automatically promote IPv4 addresses to
- IPv6 addresses. Currently this is decided by setting the
- RES_USE_INET6 bit in _res.options. */
- int old_res_options = _res.options;
- _res.options &= ~RES_USE_INET6;
-
- size_t tmpbuf6len = 1024;
- char *tmpbuf6 = alloca (tmpbuf6len);
- size_t tmpbuf4len = 0;
- char *tmpbuf4 = NULL;
+ struct scratch_buffer tmpbuf6;
+ scratch_buffer_init (&tmpbuf6);
+ struct scratch_buffer tmpbuf4;
+ scratch_buffer_init (&tmpbuf4);
+ struct scratch_buffer canonbuf;
+ scratch_buffer_init (&canonbuf);
+
int32_t ttl = INT32_MAX;
ssize_t total = 0;
char *key_copy = NULL;
@@ -129,6 +128,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
int naddrs = 0;
size_t addrslen = 0;
+
char *canon = NULL;
size_t canonlen;
@@ -143,12 +143,17 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
at = &atmem;
rc6 = 0;
herrno = 0;
- status[1] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
+ status[1] = DL_CALL_FCT (fct4, (key, &at,
+ tmpbuf6.data, tmpbuf6.length,
&rc6, &herrno, &ttl));
if (rc6 != ERANGE || (herrno != NETDB_INTERNAL
&& herrno != TRY_AGAIN))
break;
- tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
+ if (!scratch_buffer_grow (&tmpbuf6))
+ {
+ rc6 = ENOMEM;
+ break;
+ }
}
if (rc6 != 0 && herrno == NETDB_INTERNAL)
@@ -226,41 +231,38 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
while (1)
{
rc6 = 0;
- status[0] = DL_CALL_FCT (fct, (key, AF_INET6, &th[0], tmpbuf6,
- tmpbuf6len, &rc6, &herrno, &ttl,
+ status[0] = DL_CALL_FCT (fct, (key, AF_INET6, &th[0],
+ tmpbuf6.data, tmpbuf6.length,
+ &rc6, &herrno, &ttl,
&canon));
if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
break;
- tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
+ if (!scratch_buffer_grow (&tmpbuf6))
+ {
+ rc6 = ENOMEM;
+ break;
+ }
}
if (rc6 != 0 && herrno == NETDB_INTERNAL)
goto out;
- /* If the IPv6 lookup has been successful do not use the
- buffer used in that lookup, use a new one. */
- if (status[0] == NSS_STATUS_SUCCESS && rc6 == 0)
- {
- tmpbuf4len = 512;
- tmpbuf4 = alloca (tmpbuf4len);
- }
- else
- {
- tmpbuf4len = tmpbuf6len;
- tmpbuf4 = tmpbuf6;
- }
-
/* Next collect IPv4 information. */
while (1)
{
rc4 = 0;
- status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1], tmpbuf4,
- tmpbuf4len, &rc4, &herrno,
+ status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1],
+ tmpbuf4.data, tmpbuf4.length,
+ &rc4, &herrno,
ttl == INT32_MAX ? &ttl : NULL,
canon == NULL ? &canon : NULL));
if (rc4 != ERANGE || herrno != NETDB_INTERNAL)
break;
- tmpbuf4 = extend_alloca (tmpbuf4, tmpbuf4len, 2 * tmpbuf4len);
+ if (!scratch_buffer_grow (&tmpbuf4))
+ {
+ rc4 = ENOMEM;
+ break;
+ }
}
if (rc4 != 0 && herrno == NETDB_INTERNAL)
@@ -286,13 +288,11 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
cfct = __nss_lookup_function (nip, "getcanonname_r");
if (cfct != NULL)
{
- const size_t max_fqdn_len = 256;
- char *buf = alloca (max_fqdn_len);
char *s;
int rc;
- if (DL_CALL_FCT (cfct, (key, buf, max_fqdn_len, &s,
- &rc, &herrno))
+ if (DL_CALL_FCT (cfct, (key, canonbuf.data, canonbuf.length,
+ &s, &rc, &herrno))
== NSS_STATUS_SUCCESS)
canon = s;
else
@@ -321,18 +321,20 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
addrfamily = AF_INET6;
}
- size_t tmpbuflen = 512;
- char *tmpbuf = alloca (tmpbuflen);
int rc;
while (1)
{
rc = __gethostbyaddr2_r (addr, addrlen, addrfamily,
- &hstent_mem, tmpbuf, tmpbuflen,
+ &hstent_mem,
+ canonbuf.data, canonbuf.length,
&hstent, &herrno, NULL);
if (rc != ERANGE || herrno != NETDB_INTERNAL)
break;
- tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
- tmpbuflen * 2);
+ if (!scratch_buffer_grow (&canonbuf))
+ {
+ rc = ENOMEM;
+ break;
+ }
}
if (rc == 0)
@@ -449,32 +451,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
would unnecessarily let the receiver wait. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
-# ifndef __ASSUME_SENDFILE
- ssize_t written;
- written =
-# endif
- sendfileall (fd, db->wr_fd, (char *) &dataset->resp
- - (char *) db->head, dataset->head.recsize);
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- writeall (fd, &dataset->resp, dataset->head.recsize);
+ writeall (fd, &dataset->resp, dataset->head.recsize);
}
goto out;
@@ -536,7 +513,8 @@ next_nip:
}
out:
- _res.options |= old_res_options & RES_USE_INET6;
+ __resolv_context_enable_inet6 (ctx, enable_inet6);
+ __resolv_context_put (ctx);
if (dataset != NULL && !alloca_used)
{
@@ -560,6 +538,10 @@ next_nip:
dh->usable = false;
}
+ scratch_buffer_free (&tmpbuf6);
+ scratch_buffer_free (&tmpbuf4);
+ scratch_buffer_free (&canonbuf);
+
return timeout;
}
diff --git a/nscd/cache.c b/nscd/cache.c
index 3021abd41e..efe4214d95 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -25,11 +25,11 @@
#include <string.h>
#include <libintl.h>
#include <arpa/inet.h>
-#include <rpcsvc/nis.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <nss.h>
#include "nscd.h"
#include "dbg_log.h"
@@ -74,7 +74,7 @@ struct datahead *
cache_search (request_type type, const void *key, size_t len,
struct database_dyn *table, uid_t owner)
{
- unsigned long int hash = __nis_hash (key, len) % table->head->module;
+ unsigned long int hash = __nss_hash (key, len) % table->head->module;
unsigned long int nsearched = 0;
struct datahead *result = NULL;
@@ -153,7 +153,7 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
first ? _(" (first)") : "");
}
- unsigned long int hash = __nis_hash (key, len) % table->head->module;
+ unsigned long int hash = __nss_hash (key, len) % table->head->module;
struct hashentry *newp;
newp = mempool_alloc (table, sizeof (struct hashentry), 0);
@@ -178,12 +178,12 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
assert ((newp->packet & BLOCK_ALIGN_M1) == 0);
/* Put the new entry in the first position. */
- do
- newp->next = table->head->array[hash];
- while (atomic_compare_and_exchange_bool_rel (&table->head->array[hash],
- (ref_t) ((char *) newp
- - table->data),
- (ref_t) newp->next));
+ /* TODO Review concurrency. Use atomic_exchange_release. */
+ newp->next = atomic_load_relaxed (&table->head->array[hash]);
+ while (!atomic_compare_exchange_weak_release (&table->head->array[hash],
+ (ref_t *) &newp->next,
+ (ref_t) ((char *) newp
+ - table->data)));
/* Update the statistics. */
if (packet->notfound)
diff --git a/nscd/connections.c b/nscd/connections.c
index f3b16f7246..47fbb9923a 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -1,5 +1,5 @@
/* Inner loops of cache daemon.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -46,9 +46,6 @@
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/poll.h>
-#ifdef HAVE_SENDFILE
-# include <sys/sendfile.h>
-#endif
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
@@ -59,7 +56,7 @@
#include <resolv/resolv.h>
#include <kernel-features.h>
-#include <libc-internal.h>
+#include <libc-diag.h>
/* Support to run nscd as an unprivileged user */
@@ -106,11 +103,17 @@ const char *const serv2str[LASTREQ] =
[GETFDNETGR] = "GETFDNETGR"
};
+#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
+# define RWLOCK_INITIALIZER PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
+#else
+# define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
+#endif
+
/* The control data structures for the services. */
struct database_dyn dbs[lastdb] =
{
[pwddb] = {
- .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
+ .lock = RWLOCK_INITIALIZER,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
@@ -129,7 +132,7 @@ struct database_dyn dbs[lastdb] =
.mmap_used = false
},
[grpdb] = {
- .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
+ .lock = RWLOCK_INITIALIZER,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
@@ -148,7 +151,7 @@ struct database_dyn dbs[lastdb] =
.mmap_used = false
},
[hstdb] = {
- .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
+ .lock = RWLOCK_INITIALIZER,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
@@ -167,7 +170,7 @@ struct database_dyn dbs[lastdb] =
.mmap_used = false
},
[servdb] = {
- .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
+ .lock = RWLOCK_INITIALIZER,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
@@ -186,7 +189,7 @@ struct database_dyn dbs[lastdb] =
.mmap_used = false
},
[netgrdb] = {
- .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
+ .lock = RWLOCK_INITIALIZER,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
@@ -257,10 +260,6 @@ int inotify_fd = -1;
static int nl_status_fd = -1;
#endif
-#ifndef __ASSUME_ACCEPT4
-static int have_accept4;
-#endif
-
/* Number of times clients had to wait. */
unsigned long int client_queued;
@@ -283,26 +282,6 @@ writeall (int fd, const void *buf, size_t len)
}
-#ifdef HAVE_SENDFILE
-ssize_t
-sendfileall (int tofd, int fromfd, off_t off, size_t len)
-{
- ssize_t n = len;
- ssize_t ret;
-
- do
- {
- ret = TEMP_FAILURE_RETRY (sendfile (tofd, fromfd, &off, n));
- if (ret <= 0)
- break;
- n -= ret;
- }
- while (n > 0);
- return ret < 0 ? ret : len - n;
-}
-#endif
-
-
enum usekey
{
use_not = 0,
@@ -499,13 +478,6 @@ fail:
}
-#ifdef O_CLOEXEC
-# define EXTRA_O_FLAGS O_CLOEXEC
-#else
-# define EXTRA_O_FLAGS 0
-#endif
-
-
/* Initialize database information structures. */
void
nscd_init (void)
@@ -528,7 +500,7 @@ nscd_init (void)
if (dbs[cnt].persistent)
{
/* Try to open the appropriate file on disk. */
- int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS);
+ int fd = open (dbs[cnt].db_filename, O_RDWR | O_CLOEXEC);
if (fd != -1)
{
char *msg = NULL;
@@ -608,7 +580,7 @@ nscd_init (void)
if (dbs[cnt].shared)
{
dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
- O_RDONLY | EXTRA_O_FLAGS);
+ O_RDONLY | O_CLOEXEC);
if (dbs[cnt].ro_fd == -1)
dbg_log (_("\
cannot create read-only descriptor for \"%s\"; no mmap"),
@@ -648,23 +620,23 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
if (dbs[cnt].persistent)
{
fd = open (dbs[cnt].db_filename,
- O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS,
+ O_RDWR | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR);
if (fd != -1 && dbs[cnt].shared)
ro_fd = open (dbs[cnt].db_filename,
- O_RDONLY | EXTRA_O_FLAGS);
+ O_RDONLY | O_CLOEXEC);
}
else
{
char fname[] = _PATH_NSCD_XYZ_DB_TMP;
- fd = mkostemp (fname, EXTRA_O_FLAGS);
+ fd = mkostemp (fname, O_CLOEXEC);
/* We do not need the file name anymore after we
opened another file descriptor in read-only mode. */
if (fd != -1)
{
if (dbs[cnt].shared)
- ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS);
+ ro_fd = open (fname, O_RDONLY | O_CLOEXEC);
unlink (fname);
}
@@ -782,24 +754,6 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
}
}
-#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
- /* We do not check here whether the O_CLOEXEC provided to the
- open call was successful or not. The two fcntl calls are
- only performed once each per process start-up and therefore
- is not noticeable at all. */
- if (paranoia
- && ((dbs[cnt].wr_fd != -1
- && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
- || (dbs[cnt].ro_fd != -1
- && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
- {
- dbg_log (_("\
-cannot set socket to close on exec: %s; disabling paranoia mode"),
- strerror (errno));
- paranoia = 0;
- }
-#endif
-
if (dbs[cnt].head == NULL)
{
/* We do not use the persistent database. Just
@@ -1106,14 +1060,15 @@ cannot handle old request version %d; current version is %d"),
if (debug_level > 0)
{
#ifdef SO_PEERCRED
+ char pbuf[sizeof ("/proc//exe") + 3 * sizeof (long int)];
# ifdef PATH_MAX
char buf[PATH_MAX];
# else
char buf[4096];
# endif
- snprintf (buf, sizeof (buf), "/proc/%ld/exe", (long int) pid);
- ssize_t n = readlink (buf, buf, sizeof (buf) - 1);
+ snprintf (pbuf, sizeof (pbuf), "/proc/%ld/exe", (long int) pid);
+ ssize_t n = readlink (pbuf, buf, sizeof (buf) - 1);
if (n <= 0)
dbg_log (_("\
@@ -1185,35 +1140,8 @@ request from '%s' [%ld] not handled due to missing permission"),
if (cached != NULL)
{
/* Hurray it's in the cache. */
- ssize_t nwritten;
-
-#ifdef HAVE_SENDFILE
- if (__glibc_likely (db->mmap_used))
- {
- assert (db->wr_fd != -1);
- assert ((char *) cached->data > (char *) db->data);
- assert ((char *) cached->data - (char *) db->head
- + cached->recsize
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- nwritten = sendfileall (fd, db->wr_fd,
- (char *) cached->data
- - (char *) db->head, cached->recsize);
-# ifndef __ASSUME_SENDFILE
- if (nwritten == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- nwritten = writeall (fd, cached->data, cached->recsize);
-
- if (nwritten != cached->recsize
- && __builtin_expect (debug_level, 0) > 0)
+ if (writeall (fd, cached->data, cached->recsize) != cached->recsize
+ && __glibc_unlikely (debug_level > 0))
{
/* We have problems sending the result. */
char buf[256];
@@ -1353,64 +1281,83 @@ request from '%s' [%ld] not handled due to missing permission"),
}
}
-
-/* Restart the process. */
-static void
-restart (void)
+static char *
+read_cmdline (size_t *size)
{
- /* First determine the parameters. We do not use the parameters
- passed to main() since in case nscd is started by running the
- dynamic linker this will not work. Yes, this is not the usual
- case but nscd is part of glibc and we occasionally do this. */
- size_t buflen = 1024;
- char *buf = alloca (buflen);
- size_t readlen = 0;
int fd = open ("/proc/self/cmdline", O_RDONLY);
- if (fd == -1)
+ if (fd < 0)
+ return NULL;
+ size_t current = 0;
+ size_t limit = 1024;
+ char *buffer = malloc (limit);
+ if (buffer == NULL)
{
- dbg_log (_("\
-cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
- strerror (errno));
-
- paranoia = 0;
- return;
+ close (fd);
+ errno = ENOMEM;
+ return NULL;
}
-
while (1)
{
- ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
- buflen - readlen));
- if (n == -1)
+ if (current == limit)
{
- dbg_log (_("\
-cannot read /proc/self/cmdline: %s; disabling paranoia mode"),
- strerror (errno));
+ char *newptr;
+ if (2 * limit < limit
+ || (newptr = realloc (buffer, 2 * limit)) == NULL)
+ {
+ free (buffer);
+ close (fd);
+ errno = ENOMEM;
+ return NULL;
+ }
+ buffer = newptr;
+ limit *= 2;
+ }
+ ssize_t n = TEMP_FAILURE_RETRY (read (fd, buffer + current,
+ limit - current));
+ if (n == -1)
+ {
+ int e = errno;
+ free (buffer);
close (fd);
- paranoia = 0;
- return;
+ errno = e;
+ return NULL;
}
-
- readlen += n;
-
- if (readlen < buflen)
+ if (n == 0)
break;
-
- /* We might have to extend the buffer. */
- size_t old_buflen = buflen;
- char *newp = extend_alloca (buf, buflen, 2 * buflen);
- buf = memmove (newp, buf, old_buflen);
+ current += n;
}
close (fd);
+ *size = current;
+ return buffer;
+}
+
+
+/* Restart the process. */
+static void
+restart (void)
+{
+ /* First determine the parameters. We do not use the parameters
+ passed to main because then nscd would use the system libc after
+ restarting even if it was started by a non-system dynamic linker
+ during glibc testing. */
+ size_t readlen;
+ char *cmdline = read_cmdline (&readlen);
+ if (cmdline == NULL)
+ {
+ dbg_log (_("\
+cannot open /proc/self/cmdline: %m; disabling paranoia mode"));
+ paranoia = 0;
+ return;
+ }
/* Parse the command line. Worst case scenario: every two
characters form one parameter (one character plus NUL). */
char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
int argc = 0;
- char *cp = buf;
- while (cp < buf + readlen)
+ for (char *cp = cmdline; cp < cmdline + readlen;)
{
argv[argc++] = cp;
cp = (char *) rawmemchr (cp, '\0') + 1;
@@ -1427,6 +1374,7 @@ cannot change to old UID: %s; disabling paranoia mode"),
strerror (errno));
paranoia = 0;
+ free (cmdline);
return;
}
@@ -1438,6 +1386,7 @@ cannot change to old GID: %s; disabling paranoia mode"),
ignore_value (setuid (server_uid));
paranoia = 0;
+ free (cmdline);
return;
}
}
@@ -1455,6 +1404,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
ignore_value (setgid (server_gid));
}
paranoia = 0;
+ free (cmdline);
return;
}
@@ -1503,6 +1453,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
dbg_log (_("cannot change current working directory to \"/\": %s"),
strerror (errno));
paranoia = 0;
+ free (cmdline);
/* Reenable the databases. */
time_t now = time (NULL);
@@ -1675,16 +1626,6 @@ nscd_run_worker (void *p)
/* We are done with the list. */
pthread_mutex_unlock (&readylist_lock);
-#ifndef __ASSUME_ACCEPT4
- if (have_accept4 < 0)
- {
- /* We do not want to block on a short read or so. */
- int fl = fcntl (fd, F_GETFL);
- if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
- goto close_and_out;
- }
-#endif
-
/* Now read the request. */
request_header req;
if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
@@ -2124,24 +2065,8 @@ main_loop_poll (void)
if (conns[0].revents != 0)
{
/* We have a new incoming connection. Accept the connection. */
- int fd;
-
-#ifndef __ASSUME_ACCEPT4
- fd = -1;
- if (have_accept4 >= 0)
-#endif
- {
- fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
+ int fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
SOCK_NONBLOCK));
-#ifndef __ASSUME_ACCEPT4
- if (have_accept4 == 0)
- have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
-#endif
- }
-#ifndef __ASSUME_ACCEPT4
- if (have_accept4 < 0)
- fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
-#endif
/* Use the descriptor if we have not reached the limit. */
if (fd >= 0)
@@ -2309,24 +2234,8 @@ main_loop_epoll (int efd)
if (revs[cnt].data.fd == sock)
{
/* A new connection. */
- int fd;
-
-# ifndef __ASSUME_ACCEPT4
- fd = -1;
- if (have_accept4 >= 0)
-# endif
- {
- fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
+ int fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
SOCK_NONBLOCK));
-# ifndef __ASSUME_ACCEPT4
- if (have_accept4 == 0)
- have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
-# endif
- }
-# ifndef __ASSUME_ACCEPT4
- if (have_accept4 < 0)
- fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
-# endif
/* Use the descriptor if we have not reached the limit. */
if (fd >= 0)
diff --git a/nscd/dbg_log.c b/nscd/dbg_log.c
index f2ca3c8787..57726bda78 100644
--- a/nscd/dbg_log.c
+++ b/nscd/dbg_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
@@ -67,7 +67,7 @@ dbg_log (const char *fmt,...)
char buf[256];
strftime (buf, sizeof (buf), "%c", &now);
- char msg[512];
+ char msg[1024];
snprintf (msg, sizeof (msg), "%s - %d: %s%s", buf, getpid (), msg2,
msg2[strlen (msg2) - 1] == '\n' ? "" : "\n");
if (dbgout)
diff --git a/nscd/dbg_log.h b/nscd/dbg_log.h
index acc2129164..c5402f52c4 100644
--- a/nscd/dbg_log.h
+++ b/nscd/dbg_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
diff --git a/nscd/gai.c b/nscd/gai.c
index 68a222f7ae..24bdfee1db 100644
--- a/nscd/gai.c
+++ b/nscd/gai.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2004.
@@ -31,6 +31,8 @@
#define __qsort_r qsort_r
/* nscd uses 1MB or 2MB thread stacks. */
#define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
+#define __getifaddrs getifaddrs
+#define __freeifaddrs freeifaddrs
/* We are nscd, so we don't want to be talking to ourselves. */
#undef USE_NSCD
@@ -40,9 +42,6 @@
/* Support code. */
#include <check_pf.c>
#include <check_native.c>
-#ifdef HAVE_LIBIDN
-# include <libidn/idn-stub.c>
-#endif
/* Some variables normally defined in libc. */
-service_user *__nss_hosts_database;
+service_user *__nss_hosts_database attribute_hidden;
diff --git a/nscd/getgrgid_r.c b/nscd/getgrgid_r.c
index 8039f86ea8..e2c7fcb310 100644
--- a/nscd/getgrgid_r.c
+++ b/nscd/getgrgid_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -17,6 +17,7 @@
#include <grp.h>
+#include <grp-merge.h>
#define LOOKUP_TYPE struct group
#define FUNCTION_NAME getgrgid
@@ -25,6 +26,9 @@
#define ADD_VARIABLES gid
#define BUFLEN NSS_BUFLEN_GROUP
+#define DEEPCOPY_FN __copy_grp
+#define MERGE_FN __merge_grp
+
/* We are nscd, so we don't want to be talking to ourselves. */
#undef USE_NSCD
diff --git a/nscd/getgrnam_r.c b/nscd/getgrnam_r.c
index 67e4cd1e0a..5c9e2b510b 100644
--- a/nscd/getgrnam_r.c
+++ b/nscd/getgrnam_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -17,6 +17,7 @@
#include <grp.h>
+#include <grp-merge.h>
#define LOOKUP_TYPE struct group
#define FUNCTION_NAME getgrnam
@@ -24,6 +25,9 @@
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
+#define DEEPCOPY_FN __copy_grp
+#define MERGE_FN __merge_grp
+
/* We are nscd, so we don't want to be talking to ourselves. */
#undef USE_NSCD
diff --git a/nscd/gethstbyad_r.c b/nscd/gethstbyad_r.c
index a85f9c8334..423514556e 100644
--- a/nscd/gethstbyad_r.c
+++ b/nscd/gethstbyad_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -28,7 +28,6 @@
#define EXTRA_VARIABLES , ttlp
#define NEED_H_ERRNO 1
#define NEED__RES 1
-#define NEED__RES_HCONF 1
/* We are nscd, so we don't want to be talking to ourselves. */
#undef USE_NSCD
diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
index 2135a36fea..7beb9dce9f 100644
--- a/nscd/gethstbynm3_r.c
+++ b/nscd/gethstbynm3_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -32,7 +32,7 @@
#define ADD_VARIABLES name, af
#define EXTRA_VARIABLES , ttlp, canonp
#define NEED_H_ERRNO 1
-#define NEED__RES_HCONF 1
+#define NEED__RES 1
#define HANDLE_DIGITS_DOTS 1
#define HAVE_LOOKUP_BUFFER 1
diff --git a/nscd/getpwnam_r.c b/nscd/getpwnam_r.c
index a376b06b8f..82494974c6 100644
--- a/nscd/getpwnam_r.c
+++ b/nscd/getpwnam_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/nscd/getpwuid_r.c b/nscd/getpwuid_r.c
index cdba0fed4b..55ddfd3f7f 100644
--- a/nscd/getpwuid_r.c
+++ b/nscd/getpwuid_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/nscd/getsrvbynm_r.c b/nscd/getsrvbynm_r.c
index 2a9002ee9b..88d33c83ef 100644
--- a/nscd/getsrvbynm_r.c
+++ b/nscd/getsrvbynm_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/nscd/getsrvbypt_r.c b/nscd/getsrvbypt_r.c
index ab0078dad2..81f1ff1086 100644
--- a/nscd/getsrvbypt_r.c
+++ b/nscd/getsrvbypt_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index 38311701a7..b4c8ea9c56 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -1,5 +1,5 @@
/* Cache handling for group lookup.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -16,7 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
-#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
@@ -32,12 +31,10 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <stackinfo.h>
+#include <scratch_buffer.h>
#include "nscd.h"
#include "dbg_log.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
/* This is the standard reply in case the service is disabled. */
static const gr_response_header disabled =
@@ -205,10 +202,19 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
dataset = NULL;
if (he == NULL)
- dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ {
+ /* Prevent an INVALIDATE request from pruning the data between
+ the two calls to cache_add. */
+ if (db->propagate)
+ pthread_mutex_lock (&db->prune_run_lock);
+ dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ }
if (dataset == NULL)
{
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
+
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
@@ -309,37 +315,9 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && ! dataset_temporary)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
/* Add the record to the database. But only if it has not been
@@ -396,6 +374,8 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
out:
pthread_rwlock_unlock (&db->lock);
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
}
}
@@ -437,12 +417,12 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- size_t buflen = 1024;
- char *buffer = (char *) alloca (buflen);
+
struct group resultbuf;
struct group *grp;
- bool use_malloc = false;
int errval = 0;
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
if (__glibc_unlikely (debug_level > 0))
{
@@ -452,43 +432,24 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
dbg_log (_("Reloading \"%s\" in group cache!"), keystr);
}
- while (lookup (req->type, key, &resultbuf, buffer, buflen, &grp) != 0
+ while (lookup (req->type, key, &resultbuf,
+ tmpbuf.data, tmpbuf.length, &grp) != 0
&& (errval = errno) == ERANGE)
- {
- errno = 0;
-
- if (__glibc_unlikely (buflen > 32768))
- {
- char *old_buffer = buffer;
- buflen *= 2;
- buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
- if (buffer == NULL)
- {
- /* We ran out of memory. We cannot do anything but
- sending a negative response. In reality this should
- never happen. */
- grp = NULL;
- buffer = old_buffer;
-
- /* We set the error to indicate this is (possibly) a
- temporary error and that it does not mean the entry
- is not available at all. */
- errval = EAGAIN;
- break;
- }
- use_malloc = true;
- }
- else
- /* Allocate a new buffer on the stack. If possible combine it
- with the previously allocated buffer. */
- buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
- }
+ if (!scratch_buffer_grow (&tmpbuf))
+ {
+ /* We ran out of memory. We cannot do anything but sending a
+ negative response. In reality this should never
+ happen. */
+ grp = NULL;
+ /* We set the error to indicate this is (possibly) a temporary
+ error and that it does not mean the entry is not available
+ at all. */
+ errval = EAGAIN;
+ break;
+ }
time_t timeout = cache_addgr (db, fd, req, keystr, grp, uid, he, dh, errval);
-
- if (use_malloc)
- free (buffer);
-
+ scratch_buffer_free (&tmpbuf);
return timeout;
}
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 04708ededc..5597e13ec1 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -1,5 +1,5 @@
/* Cache handling for host lookup.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -34,12 +34,10 @@
#include <arpa/nameser.h>
#include <sys/mman.h>
#include <stackinfo.h>
+#include <scratch_buffer.h>
#include "nscd.h"
#include "dbg_log.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
/* This is the standard reply in case the service is disabled. */
@@ -352,37 +350,9 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
unnecessarily keep the receiver waiting. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
/* Add the record to the database. But only if it has not been
@@ -463,11 +433,8 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- int buflen = 1024;
- char *buffer = (char *) alloca (buflen);
struct hostent resultbuf;
struct hostent *hst;
- bool use_malloc = false;
int errval = 0;
int32_t ttl = INT32_MAX;
@@ -487,46 +454,30 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
dbg_log (_("Reloading \"%s\" in hosts cache!"), (char *) str);
}
- while (lookup (req->type, key, &resultbuf, buffer, buflen, &hst, &ttl) != 0
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
+
+ while (lookup (req->type, key, &resultbuf,
+ tmpbuf.data, tmpbuf.length, &hst, &ttl) != 0
&& h_errno == NETDB_INTERNAL
&& (errval = errno) == ERANGE)
- {
- errno = 0;
-
- if (__glibc_unlikely (buflen > 32768))
- {
- char *old_buffer = buffer;
- buflen *= 2;
- buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
- if (buffer == NULL)
- {
- /* We ran out of memory. We cannot do anything but
- sending a negative response. In reality this should
- never happen. */
- hst = NULL;
- buffer = old_buffer;
-
- /* We set the error to indicate this is (possibly) a
- temporary error and that it does not mean the entry
- is not available at all. */
- h_errno = TRY_AGAIN;
- errval = EAGAIN;
- break;
- }
- use_malloc = true;
- }
- else
- /* Allocate a new buffer on the stack. If possible combine it
- with the previously allocated buffer. */
- buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
- }
+ if (!scratch_buffer_grow (&tmpbuf))
+ {
+ /* We ran out of memory. We cannot do anything but sending a
+ negative response. In reality this should never
+ happen. */
+ hst = NULL;
+ /* We set the error to indicate this is (possibly) a temporary
+ error and that it does not mean the entry is not
+ available at all. */
+ h_errno = TRY_AGAIN;
+ errval = EAGAIN;
+ break;
+ }
time_t timeout = cache_addhst (db, fd, req, key, hst, uid, he, dh,
h_errno == TRY_AGAIN ? errval : 0, ttl);
-
- if (use_malloc)
- free (buffer);
-
+ scratch_buffer_free (&tmpbuf);
return timeout;
}
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index c85a7514f8..2c74951f57 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -1,5 +1,5 @@
/* Cache handling for host lookup.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -25,15 +25,18 @@
#include <unistd.h>
#include <sys/mman.h>
#include <scratch_buffer.h>
+#include <config.h>
#include "dbg_log.h"
#include "nscd.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
#include "../nss/nsswitch.h"
+#ifdef LINK_OBSOLETE_NSL
+# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
+#else
+# define DEFAULT_CONFIG "files"
+#endif
/* Type of the lookup function. */
typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
@@ -85,8 +88,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
int no_more;
if (group_database == NULL)
- no_more = __nss_database_lookup ("group", NULL,
- "compat [NOTFOUND=return] files",
+ no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG,
&group_database);
else
no_more = 0;
@@ -348,37 +350,9 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
diff --git a/nscd/mem.c b/nscd/mem.c
index 1aafd37af9..9ff0ddd3aa 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -1,5 +1,5 @@
/* Cache memory handling.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 08e9022a32..2b35389cc8 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -1,5 +1,5 @@
/* Cache handling for netgroup lookup.
- Copyright (C) 2011-2016 Free Software Foundation, Inc.
+ Copyright (C) 2011-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
@@ -413,33 +413,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
since while inserting this thread might block and so would
unnecessarily let the receiver wait. */
writeout:
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && cacheable)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
-# ifndef __ASSUME_SENDFILE
- ssize_t written =
-# endif
- sendfileall (fd, db->wr_fd, (char *) &dataset->resp
- - (char *) db->head, dataset->head.recsize);
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-#endif
- {
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
- use_write:
-#endif
- writeall (fd, &dataset->resp, dataset->head.recsize);
- }
+ writeall (fd, &dataset->resp, dataset->head.recsize);
}
if (cacheable)
@@ -480,7 +454,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
{
const char *group = key;
key = (char *) rawmemchr (key, '\0') + 1;
- size_t group_len = key - group - 1;
+ size_t group_len = key - group;
const char *host = *key++ ? key : NULL;
if (host != NULL)
key = (char *) rawmemchr (key, '\0') + 1;
@@ -584,6 +558,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
dh->timeout = timeout;
dh->ttl = dataset->head.ttl;
++dh->nreloads;
+ if (cacheable)
+ pthread_rwlock_unlock (&db->lock);
return timeout;
}
@@ -592,36 +568,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
/* We write the dataset before inserting it to the database
since while inserting this thread might block and so would
unnecessarily let the receiver wait. */
- assert (fd != -1);
+ assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && cacheable)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head + sizeof (*dataset)
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
-# ifndef __ASSUME_SENDFILE
- ssize_t written =
-# endif
- sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp - (char *) db->head,
- sizeof (innetgroup_response_header));
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-#endif
- {
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
- use_write:
-#endif
- writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
- }
+ writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
}
if (cacheable)
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index c0190ce3f8..624effabb4 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -400,10 +400,12 @@ extern struct mapped_database *__nscd_get_mapping (request_type type,
extern struct mapped_database *__nscd_get_map_ref (request_type type,
const char *name,
volatile struct locked_map_ptr *mapptr,
- int *gc_cyclep);
+ int *gc_cyclep)
+ attribute_hidden;
/* Unmap database. */
-extern void __nscd_unmap (struct mapped_database *mapped);
+extern void __nscd_unmap (struct mapped_database *mapped)
+ attribute_hidden;
/* Drop reference of mapping. */
static int
@@ -433,7 +435,8 @@ extern struct datahead *__nscd_cache_search (request_type type,
const char *key,
size_t keylen,
const struct mapped_database *mapped,
- size_t datalen);
+ size_t datalen)
+ attribute_hidden;
/* Wrappers around read, readv and write that only read/write less than LEN
bytes on error or EOF. */
@@ -443,10 +446,9 @@ extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
attribute_hidden;
extern ssize_t writeall (int fd, const void *buf, size_t len)
attribute_hidden;
-extern ssize_t sendfileall (int tofd, int fromfd, off_t off, size_t len)
- attribute_hidden;
/* Get netlink timestamp counter from mapped area or zero. */
-extern uint32_t __nscd_get_nl_timestamp (void);
+extern uint32_t __nscd_get_nl_timestamp (void)
+ attribute_hidden;
#endif /* nscd.h */
diff --git a/nscd/nscd.c b/nscd/nscd.c
index bd7c777f09..67e2a336c4 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -510,7 +510,7 @@ print_version (FILE *stream, struct argp_state *state)
Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2016");
+"), "2018");
fprintf (stream, gettext ("Written by %s.\n"),
"Thorsten Kukuk and Ulrich Drepper");
}
diff --git a/nscd/nscd.h b/nscd/nscd.h
index ddc780f2d1..4533578100 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -108,7 +108,7 @@ init_traced_file(struct traced_file *file, const char *fname, int crinit)
size_t len = (size_t)(dname - fname);
if (len > sizeof (file->dname))
abort ();
- strncpy (file->dname, file->fname, len);
+ memcpy (file->dname, file->fname, len);
file->dname[len] = '\0';
}
/* The basename is the name just after the last forward slash. */
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index 38b7bf711a..265a02434d 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index 86528c4387..35cb19e91d 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -189,7 +189,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 931d654a59..d9f72b2e3d 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -40,8 +40,7 @@ int __nss_not_use_nscd_group;
static int nscd_getgr_r (const char *key, size_t keylen, request_type type,
struct group *resultbuf, char *buffer,
- size_t buflen, struct group **result)
- internal_function;
+ size_t buflen, struct group **result);
int
@@ -82,7 +81,6 @@ libc_freeres_fn (gr_map_free)
static int
-internal_function
nscd_getgr_r (const char *key, size_t keylen, request_type type,
struct group *resultbuf, char *buffer, size_t buflen,
struct group **result)
@@ -305,7 +303,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 7448add041..edff48eac4 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -17,7 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <errno.h>
-#include <resolv.h>
+#include <resolv/resolv-internal.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -32,7 +32,7 @@ int __nss_not_use_nscd_hosts;
static int nscd_gethst_r (const char *key, size_t keylen, request_type type,
struct hostent *resultbuf, char *buffer,
size_t buflen, struct hostent **result,
- int *h_errnop) internal_function;
+ int *h_errnop);
int
@@ -42,7 +42,7 @@ __nscd_gethostbyname_r (const char *name, struct hostent *resultbuf,
{
request_type reqtype;
- reqtype = (_res.options & RES_USE_INET6) ? GETHOSTBYNAMEv6 : GETHOSTBYNAME;
+ reqtype = res_use_inet6 () ? GETHOSTBYNAMEv6 : GETHOSTBYNAME;
return nscd_gethst_r (name, strlen (name) + 1, reqtype, resultbuf,
buffer, buflen, result, h_errnop);
@@ -135,7 +135,6 @@ __nscd_get_nl_timestamp (void)
int __nss_have_localdomain attribute_hidden;
static int
-internal_function
nscd_gethst_r (const char *key, size_t keylen, request_type type,
struct hostent *resultbuf, char *buffer, size_t buflen,
struct hostent **result, int *h_errnop)
@@ -436,7 +435,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index 59fbfee32c..285e331304 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -38,8 +38,7 @@ int __nss_not_use_nscd_passwd;
static int nscd_getpw_r (const char *key, size_t keylen, request_type type,
struct passwd *resultbuf, char *buffer,
- size_t buflen, struct passwd **result)
- internal_function;
+ size_t buflen, struct passwd **result);
int
__nscd_getpwnam_r (const char *name, struct passwd *resultbuf, char *buffer,
@@ -81,7 +80,6 @@ libc_freeres_fn (pw_map_free)
static int
-internal_function
nscd_getpw_r (const char *key, size_t keylen, request_type type,
struct passwd *resultbuf, char *buffer, size_t buflen,
struct passwd **result)
@@ -218,7 +216,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
index 769bdb3c55..574a9be7ab 100644
--- a/nscd/nscd_getserv_r.c
+++ b/nscd/nscd_getserv_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
@@ -356,7 +356,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index e168635ba6..2f3b4e02ab 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <stdint.h>
#include <sys/mman.h>
+#include <sys/param.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -34,12 +35,11 @@
#include <sys/uio.h>
#include <sys/un.h>
#include <not-cancel.h>
-#include <nis/rpcsvc/nis.h>
#include <kernel-features.h>
+#include <nss.h>
#include "nscd-client.h"
-
/* Extra time we wait if the socket is still receiving data. This
value is in milliseconds. Note that the other side is nscd on the
local machine and it is already transmitting data. So the wait
@@ -236,7 +236,7 @@ open_socket (request_type type, const char *key, size_t keylen)
}
out:
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
return -1;
}
@@ -443,7 +443,6 @@ __nscd_get_map_ref (request_type type, const char *name,
#define MINIMUM_HASHENTRY_SIZE \
(offsetof (struct hashentry, dellist) + sizeof (int32_t))
-
/* Don't return const struct datahead *, as eventhough the record
is normally constant, it can change arbitrarily during nscd
garbage collection. */
@@ -451,7 +450,7 @@ struct datahead *
__nscd_cache_search (request_type type, const char *key, size_t keylen,
const struct mapped_database *mapped, size_t datalen)
{
- unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
+ unsigned long int hash = __nss_hash (key, keylen) % mapped->head->module;
size_t datasize = mapped->datasize;
ref_t trail = mapped->head->array[hash];
@@ -555,7 +554,7 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type,
return sock;
}
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
}
__set_errno (saved_errno);
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index 61a0a2b6ac..d7f0291c95 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -157,7 +157,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_netgroup.c b/nscd/nscd_netgroup.c
index 90024bfcb5..6295803f67 100644
--- a/nscd/nscd_netgroup.c
+++ b/nscd/nscd_netgroup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
@@ -139,7 +139,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap)
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
@@ -263,7 +263,7 @@ __nscd_innetgr (const char *netgroup, const char *host, const char *user,
out_close:
if (sock != -1)
- close_not_cancel_no_status (sock);
+ __close_nocancel_nostatus (sock);
out:
if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
diff --git a/nscd/nscd_proto.h b/nscd/nscd_proto.h
index c9295ae33c..87e2e3844e 100644
--- a/nscd/nscd_proto.h
+++ b/nscd/nscd_proto.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -39,41 +39,49 @@ extern int __nss_not_use_nscd_netgroup attribute_hidden;
extern int __nscd_getpwnam_r (const char *name, struct passwd *resultbuf,
char *buffer, size_t buflen,
- struct passwd **result);
+ struct passwd **result) attribute_hidden;
extern int __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf,
char *buffer, size_t buflen,
- struct passwd **result);
+ struct passwd **result) attribute_hidden;
extern int __nscd_getgrnam_r (const char *name, struct group *resultbuf,
char *buffer, size_t buflen,
- struct group **result);
+ struct group **result) attribute_hidden;
extern int __nscd_getgrgid_r (gid_t gid, struct group *resultbuf,
char *buffer, size_t buflen,
- struct group **result);
+ struct group **result) attribute_hidden;
extern int __nscd_gethostbyname_r (const char *name,
struct hostent *resultbuf,
char *buffer, size_t buflen,
- struct hostent **result, int *h_errnop);
+ struct hostent **result, int *h_errnop)
+ attribute_hidden;
extern int __nscd_gethostbyname2_r (const char *name, int af,
struct hostent *resultbuf,
char *buffer, size_t buflen,
- struct hostent **result, int *h_errnop);
+ struct hostent **result, int *h_errnop)
+ attribute_hidden;
extern int __nscd_gethostbyaddr_r (const void *addr, socklen_t len, int type,
struct hostent *resultbuf,
char *buffer, size_t buflen,
- struct hostent **result, int *h_errnop);
+ struct hostent **result, int *h_errnop)
+ attribute_hidden;
extern int __nscd_getai (const char *key, struct nscd_ai_result **result,
- int *h_errnop);
+ int *h_errnop) attribute_hidden;
extern int __nscd_getgrouplist (const char *user, gid_t group, long int *size,
- gid_t **groupsp, long int limit);
+ gid_t **groupsp, long int limit)
+ attribute_hidden;
extern int __nscd_getservbyname_r (const char *name, const char *proto,
struct servent *result_buf, char *buf,
- size_t buflen, struct servent **result);
+ size_t buflen, struct servent **result)
+ attribute_hidden;
extern int __nscd_getservbyport_r (int port, const char *proto,
struct servent *result_buf, char *buf,
- size_t buflen, struct servent **result);
+ size_t buflen, struct servent **result)
+ attribute_hidden;
extern int __nscd_innetgr (const char *netgroup, const char *host,
- const char *user, const char *domain);
-extern int __nscd_setnetgrent (const char *group, struct __netgrent *datap);
+ const char *user, const char *domain)
+ attribute_hidden;
+extern int __nscd_setnetgrent (const char *group, struct __netgrent *datap)
+ attribute_hidden;
#endif /* _NSCD_PROTO_H */
diff --git a/nscd/nscd_setup_thread.c b/nscd/nscd_setup_thread.c
index 9b3412393a..eb60e89f37 100644
--- a/nscd/nscd_setup_thread.c
+++ b/nscd/nscd_setup_thread.c
@@ -1,5 +1,5 @@
/* Setup of nscd worker threads. Stub verison.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
index f34c3526cb..8428322c35 100644
--- a/nscd/nscd_stat.c
+++ b/nscd/nscd_stat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
@@ -35,9 +35,23 @@
# include <selinux/avc.h>
#endif /* HAVE_SELINUX */
+/* We use this to make sure the receiver is the same. The lower 16
+ bits are reserved for flags indicating compilation variants. This
+ version needs to be updated if the definition of struct statdata
+ changes. */
+#define STATDATA_VERSION 0x01020000U
-/* We use this to make sure the receiver is the same. */
-static const char compilation[21] = __DATE__ " " __TIME__;
+#ifdef HAVE_SELINUX
+# define STATDATA_VERSION_SELINUX_FLAG 0x0001U
+#else
+# define STATDATA_VERSION_SELINUX_FLAG 0x0000U
+#endif
+
+/* All flags affecting the struct statdata layout. */
+#define STATDATA_VERSION_FLAGS STATDATA_VERSION_SELINUX_FLAG
+
+/* The full version number for struct statdata. */
+#define STATDATA_VERSION_FULL (STATDATA_VERSION | STATDATA_VERSION_FLAGS)
/* Statistic data for one database. */
struct dbstat
@@ -68,10 +82,11 @@ struct dbstat
uintmax_t addfailed;
};
-/* Record for transmitting statistics. */
+/* Record for transmitting statistics. If this definition changes,
+ update STATDATA_VERSION above. */
struct statdata
{
- char version[sizeof (compilation)];
+ unsigned int version; /* Must be STATDATA_VERSION_FULL. */
int debug_level;
time_t runtime;
unsigned long int client_queued;
@@ -96,7 +111,7 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
memset (&data, 0, sizeof (data));
- memcpy (data.version, compilation, sizeof (compilation));
+ data.version = STATDATA_VERSION_FULL;
data.debug_level = debug_level;
data.runtime = time (NULL) - start_time;
data.client_queued = client_queued;
@@ -196,7 +211,7 @@ receive_print_stats (void)
/* Read as much data as we expect. */
if (TEMP_FAILURE_RETRY (read (fd, &data, sizeof (data))) != sizeof (data)
- || (memcmp (data.version, compilation, sizeof (compilation)) != 0
+ || (data.version != STATDATA_VERSION_FULL
/* Yes, this is an assignment! */
&& (errno = EINVAL)))
{
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 6dd6746f39..b08cfd7870 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -1,5 +1,5 @@
/* Cache handling for passwd lookup.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -16,7 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
-#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
@@ -32,12 +31,10 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <stackinfo.h>
+#include <scratch_buffer.h>
#include "nscd.h"
#include "dbg_log.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
/* This is the standard reply in case the service is disabled. */
static const pw_response_header disabled =
@@ -198,10 +195,19 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
dataset = NULL;
if (he == NULL)
- dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ {
+ /* Prevent an INVALIDATE request from pruning the data between
+ the two calls to cache_add. */
+ if (db->propagate)
+ pthread_mutex_lock (&db->prune_run_lock);
+ dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ }
if (dataset == NULL)
{
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
+
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
@@ -287,37 +293,9 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
@@ -374,6 +352,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
out:
pthread_rwlock_unlock (&db->lock);
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
}
}
@@ -415,60 +395,40 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- size_t buflen = 1024;
- char *buffer = (char *) alloca (buflen);
struct passwd resultbuf;
struct passwd *pwd;
- bool use_malloc = false;
int errval = 0;
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
if (__glibc_unlikely (debug_level > 0))
{
if (he == NULL)
- dbg_log (_("Haven't found \"%s\" in password cache!"), keystr);
+ dbg_log (_("Haven't found \"%s\" in user database cache!"), keystr);
else
- dbg_log (_("Reloading \"%s\" in password cache!"), keystr);
+ dbg_log (_("Reloading \"%s\" in user database cache!"), keystr);
}
- while (lookup (req->type, key, &resultbuf, buffer, buflen, &pwd) != 0
+ while (lookup (req->type, key, &resultbuf,
+ tmpbuf.data, tmpbuf.length, &pwd) != 0
&& (errval = errno) == ERANGE)
- {
- errno = 0;
-
- if (__glibc_unlikely (buflen > 32768))
- {
- char *old_buffer = buffer;
- buflen *= 2;
- buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
- if (buffer == NULL)
- {
- /* We ran out of memory. We cannot do anything but
- sending a negative response. In reality this should
- never happen. */
- pwd = NULL;
- buffer = old_buffer;
-
- /* We set the error to indicate this is (possibly) a
- temporary error and that it does not mean the entry
- is not available at all. */
- errval = EAGAIN;
- break;
- }
- use_malloc = true;
- }
- else
- /* Allocate a new buffer on the stack. If possible combine it
- with the previously allocated buffer. */
- buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
- }
+ if (!scratch_buffer_grow (&tmpbuf))
+ {
+ /* We ran out of memory. We cannot do anything but sending a
+ negative response. In reality this should never
+ happen. */
+ pwd = NULL;
+ /* We set the error to indicate this is (possibly) a temporary
+ error and that it does not mean the entry is not available
+ at all. */
+ errval = EAGAIN;
+ break;
+ }
/* Add the entry to the cache. */
time_t timeout = cache_addpw (db, fd, req, keystr, pwd, c_uid, he, dh,
errval);
-
- if (use_malloc)
- free (buffer);
-
+ scratch_buffer_free (&tmpbuf);
return timeout;
}
diff --git a/nscd/selinux.c b/nscd/selinux.c
index 641f96c5d4..bb3b6eba85 100644
--- a/nscd/selinux.c
+++ b/nscd/selinux.c
@@ -1,5 +1,5 @@
/* SELinux access controls for nscd.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
diff --git a/nscd/selinux.h b/nscd/selinux.h
index 1b03988707..615bb93a57 100644
--- a/nscd/selinux.h
+++ b/nscd/selinux.h
@@ -1,5 +1,5 @@
/* Header for nscd SELinux access controls.
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
+ Copyright (C) 2004-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index 00a235360d..f71c1a608a 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -1,5 +1,5 @@
/* Cache handling for services lookup.
- Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ Copyright (C) 2007-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@drepper.com>, 2007.
@@ -16,7 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
-#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <libintl.h>
@@ -25,6 +24,7 @@
#include <stdint.h>
#include <sys/mman.h>
#include <kernel-features.h>
+#include <scratch_buffer.h>
#include "nscd.h"
#include "dbg_log.h"
@@ -278,37 +278,9 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
unnecessarily keep the receiver waiting. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
/* Add the record to the database. But only if it has not been
@@ -374,12 +346,11 @@ addservbyX (struct database_dyn *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- size_t buflen = 1024;
- char *buffer = (char *) alloca (buflen);
struct servent resultbuf;
struct servent *serv;
- bool use_malloc = false;
int errval = 0;
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
if (__glibc_unlikely (debug_level > 0))
{
@@ -389,43 +360,24 @@ addservbyX (struct database_dyn *db, int fd, request_header *req,
dbg_log (_("Reloading \"%s\" in services cache!"), key);
}
- while (lookup (req->type, key, &resultbuf, buffer, buflen, &serv) != 0
+ while (lookup (req->type, key, &resultbuf,
+ tmpbuf.data, tmpbuf.length, &serv) != 0
&& (errval = errno) == ERANGE)
- {
- errno = 0;
-
- if (__glibc_unlikely (buflen > 32768))
- {
- char *old_buffer = buffer;
- buflen *= 2;
- buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
- if (buffer == NULL)
- {
- /* We ran out of memory. We cannot do anything but
- sending a negative response. In reality this should
- never happen. */
- serv = NULL;
- buffer = old_buffer;
-
- /* We set the error to indicate this is (possibly) a
- temporary error and that it does not mean the entry
- is not available at all. */
- errval = EAGAIN;
- break;
- }
- use_malloc = true;
- }
- else
- /* Allocate a new buffer on the stack. If possible combine it
- with the previously allocated buffer. */
- buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
- }
+ if (!scratch_buffer_grow (&tmpbuf))
+ {
+ /* We ran out of memory. We cannot do anything but sending a
+ negative response. In reality this should never
+ happen. */
+ serv = NULL;
+ /* We set the error to indicate this is (possibly) a temporary
+ error and that it does not mean the entry is not available
+ at all. */
+ errval = EAGAIN;
+ break;
+ }
time_t timeout = cache_addserv (db, fd, req, key, serv, uid, he, dh, errval);
-
- if (use_malloc)
- free (buffer);
-
+ scratch_buffer_free (&tmpbuf);
return timeout;
}