about summary refs log tree commit diff
path: root/nscd
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
committerUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
commita334319f6530564d22e775935d9c91663623a1b4 (patch)
treeb5877475619e4c938e98757d518bb1e9cbead751 /nscd
parent0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff)
downloadglibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz
glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.xz
glibc-a334319f6530564d22e775935d9c91663623a1b4.zip
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'nscd')
-rw-r--r--nscd/Makefile45
-rw-r--r--nscd/aicache.c60
-rw-r--r--nscd/cache.c97
-rw-r--r--nscd/connections.c587
-rw-r--r--nscd/dbg_log.c24
-rw-r--r--nscd/gai.c21
-rw-r--r--nscd/getgrgid_r.c22
-rw-r--r--nscd/getgrnam_r.c22
-rw-r--r--nscd/gethstbyad_r.c22
-rw-r--r--nscd/gethstbynm2_r.c22
-rw-r--r--nscd/getpwnam_r.c22
-rw-r--r--nscd/getpwuid_r.c22
-rw-r--r--nscd/grpcache.c80
-rw-r--r--nscd/hstcache.c58
-rw-r--r--nscd/initgrcache.c63
-rw-r--r--nscd/mem.c52
-rw-r--r--nscd/nscd-client.h26
-rw-r--r--nscd/nscd.c102
-rw-r--r--nscd/nscd.conf11
-rw-r--r--nscd/nscd.h34
-rw-r--r--nscd/nscd.init43
-rw-r--r--nscd/nscd_conf.c194
-rw-r--r--nscd/nscd_getai.c83
-rw-r--r--nscd/nscd_getgr_r.c114
-rw-r--r--nscd/nscd_gethst_r.c159
-rw-r--r--nscd/nscd_getpw_r.c74
-rw-r--r--nscd/nscd_helper.c253
-rw-r--r--nscd/nscd_initgroups.c77
-rw-r--r--nscd/nscd_nischeck.c96
-rw-r--r--nscd/nscd_setup_thread.c26
-rw-r--r--nscd/nscd_stat.c26
-rw-r--r--nscd/pwdcache.c77
-rw-r--r--nscd/selinux.c154
-rw-r--r--nscd/selinux.h12
34 files changed, 907 insertions, 1873 deletions
diff --git a/nscd/Makefile b/nscd/Makefile
index 9c98018217..70a35198c2 100644
--- a/nscd/Makefile
+++ b/nscd/Makefile
@@ -1,5 +1,4 @@
-# Copyright (C) 1998,2000,2002,2003,2004,2005,2006
-#	Free Software Foundation, Inc.
+# Copyright (C) 1998, 2000, 2002, 2003, 2004 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
@@ -37,12 +36,13 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
 
 ifeq ($(have-thread-library),yes)
 
+others := nscd_nischeck
 ifneq (yesyes,$(have-fpie)$(build-shared))
 others += nscd
 endif
-install-sbin := nscd
+install-sbin := nscd nscd_nischeck
 
-extra-objs := $(nscd-modules:=.o)
+extra-objs := $(nscd-modules:=.o) nscd_nischeck.o
 
 endif
 
@@ -51,32 +51,15 @@ otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \
 	     $(resolvobjdir)/libresolv.a
 endif
 
-all-nscd-modules := $(nscd-modules) selinux
 ifeq (yes,$(have-selinux))
-ifeq (yes,$(have-libaudit))
-libaudit = -laudit
-ifeq (yes,$(have-libcap))
-libcap = -lcap
-endif
-endif
-
 nscd-modules += selinux
-selinux-LIBS := -lselinux $(libaudit) $(libcap)
-
-# The configure.in check for libselinux and its headers did not use
-# $SYSINCLUDES.  The directory specified by --with-headers usually
-# contains only the basic kernel interface headers, not something like
-# libselinux.  So the simplest thing is to presume that the standard
-# system headers will be ok for this file.
-$(objpfx)nscd_stat.o: sysincludes = # nothing
-$(objpfx)selinux.o: sysincludes = # nothing
+selinux-LIBS := -lselinux
 endif
 
-LDLIBS-nscd = $(selinux-LIBS)
-
 distribute := nscd.h nscd-client.h dbg_log.h \
-	      $(addsuffix .c, $(filter-out xmalloc,$(all-nscd-modules))) \
-	      nscd.conf nscd.init nscd_proto.h nscd-types.h
+	      $(addsuffix .c, $(filter-out xmalloc, $(nscd-modules))) \
+	      nscd_nischeck.c nscd.conf nscd.init nscd_proto.h \
+	      nscd-types.h
 
 include ../Rules
 
@@ -86,13 +69,10 @@ CFLAGS-nscd_gethst_r.c = -fexceptions
 CFLAGS-nscd_getai.c = -fexceptions
 CFLAGS-nscd_initgroups.c = -fexceptions
 
-nscd-cflags = -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2
+nscd-cflags = -DIS_IN_nscd=1
 ifeq (yesyes,$(have-fpie)$(build-shared))
 nscd-cflags += -fpie
 endif
-ifeq (yes,$(have-ssp))
-nscd-cflags += -fstack-protector
-endif
 
 CFLAGS-nscd.c += $(nscd-cflags)
 CFLAGS-connections.c += $(nscd-cflags)
@@ -124,13 +104,13 @@ relro-LDFLAGS += -Wl,-z,now
 endif
 
 $(objpfx)nscd: $(addprefix $(objpfx),$(nscd-modules:=.o))
-	$(LINK.o) -pie -Wl,-O1 $(nscd-cflags) \
+	$(LINK.o) -pie -Wl,-O1 \
 	  $(sysdep-LDFLAGS) $(config-LDFLAGS) $(relro-LDFLAGS) \
 	  $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
 	  $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
 	  $(LDFLAGS) $(LDFLAGS-$(@F)) \
 	  -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
-	  -o $@ $^ $(LDLIBS-nscd) $(common-objpfx)libc_nonshared.a
+	  -o $@ $^ $(selinux-LIBS) $(common-objpfx)libc_nonshared.a
 endif
 
 # This makes sure -DNOT_IN_libc is passed for all these modules.
@@ -139,11 +119,14 @@ lib := nonlib
 include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
 
 $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
+$(objpfx)nscd_nischeck: $(objpfx)nscd_nischeck.o
 
 ifeq ($(build-shared),yes)
 $(objpfx)nscd: $(common-objpfx)rt/librt.so $(shared-thread-library) \
 	       $(common-objpfx)nis/libnsl.so
+$(objpfx)nscd_nischeck: $(common-objpfx)nis/libnsl.so
 else
 $(objpfx)nscd: $(common-objpfx)rt/librt.a $(static-thread-library) \
 	       $(common-objpfx)nis/libnsl.a
+$(objpfx)nscd_nischeck: $(common-objpfx)nis/libnsl.a
 endif
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 4640b4df94..4e0496ff44 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -1,20 +1,22 @@
 /* Cache handling for host lookup.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <assert.h>
 #include <errno.h>
@@ -24,12 +26,8 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
-
-#include "dbg_log.h"
-#include "nscd.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
+#include <dbg_log.h>
+#include <nscd.h>
 
 
 typedef enum nss_status (*nss_gethostbyname3_r)
@@ -312,7 +310,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
 		      *family++ = th[j].h_addrtype;
 		    }
 
-	      void *cp = family;
+	      char *cp = family;
 	      if (canon != NULL)
 		cp = mempcpy (cp, canon, canonlen);
 
@@ -367,31 +365,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
 		     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->resp - (char *) db->head
-			      + total
-			      <= (sizeof (struct database_pers_head)
-				  + db->head->module * sizeof (ref_t)
-				  + db->head->data_size));
-		      ssize_t written;
-		      written = sendfileall (fd, db->wr_fd,
-					     (char *) &dataset->resp
-					     - (char *) db->head, total);
-# ifndef __ASSUME_SENDFILE
-		      if (written == -1 && errno == ENOSYS)
-			goto use_write;
-# endif
-		    }
-		  else
-# ifndef __ASSUME_SENDFILE
-		  use_write:
-# endif
-#endif
-		    writeall (fd, &dataset->resp, total);
+		  TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
 		}
 
 	      goto out;
@@ -425,7 +399,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
       total = sizeof (notfound);
 
       if (fd != -1)
-	TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
+	TEMP_FAILURE_RETRY (write (fd, &notfound, total));
 
       dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
       /* If we cannot permanently store the result, so be it.  */
diff --git a/nscd/cache.c b/nscd/cache.c
index be9be2aa4f..efac4b3bcc 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -1,25 +1,26 @@
-/* Copyright (c) 1998, 1999, 2003-2005, 2006 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <assert.h>
 #include <atomic.h>
 #include <errno.h>
 #include <error.h>
-#include <inttypes.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
@@ -168,12 +169,6 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
   if (nentries > table->head->maxnentries)
     table->head->maxnentries = nentries;
 
-  if (table->persistent)
-    // XXX async OK?
-    msync ((void *) table->head,
-	   (char *) &table->head->array[hash] - (char *) table->head
-	   + sizeof (ref_t), MS_ASYNC);
-
   return 0;
 }
 
@@ -190,42 +185,21 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
    free the data structures since some hash table entries share the same
    data.  */
 void
-prune_cache (struct database_dyn *table, time_t now, int fd)
+prune_cache (struct database_dyn *table, time_t now)
 {
   size_t cnt = table->head->module;
 
   /* If this table is not actually used don't do anything.  */
   if (cnt == 0)
-    {
-      if (fd != -1)
-	{
-	  /* Reply to the INVALIDATE initiator.  */
-	  int32_t resp = 0;
-	  writeall (fd, &resp, sizeof (resp));
-	}
-      return;
-    }
-
-  /* This function can be called from the cleanup thread but also in
-     response to an invalidate command.  Make sure only one thread is
-     running.  When not serving INVALIDATE request, no need for the
-     second to wait around.  */
-  if (fd == -1)
-    {
-      if (pthread_mutex_trylock (&table->prunelock) != 0)
-	/* The work is already being done.  */
-	return;
-    }
-  else
-    pthread_mutex_lock (&table->prunelock);
+    return;
 
   /* If we check for the modification of the underlying file we invalidate
      the entries also in this case.  */
   if (table->check_file)
     {
-      struct stat64 st;
+      struct stat st;
 
-      if (stat64 (table->filename, &st) < 0)
+      if (stat (table->filename, &st) < 0)
 	{
 	  char buf[128];
 	  /* We cannot stat() the file, disable file checking if the
@@ -258,10 +232,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
   char *const data = table->data;
   bool any = false;
 
-  if (__builtin_expect (debug_level > 2, 0))
-    dbg_log (_("pruning %s cache; time %ld"),
-	     dbnames[table - dbs], (long int) now);
-
   do
     {
       ref_t run = table->head->array[--cnt];
@@ -271,25 +241,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 	  struct hashentry *runp = (struct hashentry *) (data + run);
 	  struct datahead *dh = (struct datahead *) (data + runp->packet);
 
-	  /* Some debug support.  */
-	  if (__builtin_expect (debug_level > 2, 0))
-	    {
-	      char buf[INET6_ADDRSTRLEN];
-	      const char *str;
-
-	      if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
-		{
-		  inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
-			     data + runp->key, buf, sizeof (buf));
-		  str = buf;
-		}
-	      else
-		str = data + runp->key;
-
-	      dbg_log (_("considering %s entry \"%s\", timeout %" PRIu64),
-		       serv2str[runp->type], str, dh->timeout);
-	    }
-
 	  /* Check whether the entry timed out.  */
 	  if (dh->timeout < now)
 	    {
@@ -388,14 +339,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
     }
   while (cnt > 0);
 
-  if (fd != -1)
-    {
-      /* Reply to the INVALIDATE initiator that the cache has been
-	 invalidated.  */
-      int32_t resp = 0;
-      writeall (fd, &resp, sizeof (resp));
-    }
-
   if (first <= last)
     {
       struct hashentry *head = NULL;
@@ -452,7 +395,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
       /* Make sure the data is saved to disk.  */
       if (table->persistent)
 	msync (table->head,
-	       data + table->head->first_free - (char *) table->head,
+	       table->data + table->head->first_free - (char *) table->head,
 	       MS_ASYNC);
 
       /* One extra pass if we do debugging.  */
@@ -468,11 +411,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 	      if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
 		{
 		  inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
-			     data + runp->key, buf, sizeof (buf));
+			     table->data + runp->key, buf, sizeof (buf));
 		  str = buf;
 		}
 	      else
-		str = data + runp->key;
+		str = table->data + runp->key;
 
 	      dbg_log ("remove %s entry \"%s\"", serv2str[runp->type], str);
 
@@ -484,6 +427,4 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
   /* Run garbage collection if any entry has been removed or replaced.  */
   if (any)
     gc (table);
-
-  pthread_mutex_unlock (&table->prunelock);
 }
diff --git a/nscd/connections.c b/nscd/connections.c
index 8f11421431..f22d72e265 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -1,20 +1,22 @@
 /* Inner loops of cache daemon.
-   Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1998-2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <alloca.h>
 #include <assert.h>
@@ -37,9 +39,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>
@@ -47,9 +46,10 @@
 #include "nscd.h"
 #include "dbg_log.h"
 #include "selinux.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
+
+
+/* Number of bytes of data we initially reserve for each hash table bucket.  */
+#define DEFAULT_DATASIZE_PER_BUCKET 1024
 
 
 /* Wrapper functions with error checking for standard functions.  */
@@ -68,7 +68,6 @@ static gid_t *server_groups;
 # define NGROUPS 32
 #endif
 static int server_ngroups;
-static volatile int sighup_pending;
 
 static pthread_attr_t attr;
 
@@ -101,13 +100,10 @@ struct database_dyn dbs[lastdb] =
 {
   [pwddb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
-    .propagate = 1,
     .shared = 0,
-    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/passwd",
     .db_filename = _PATH_NSCD_PASSWD_DB,
     .disabled_iov = &pwd_iov_disabled,
@@ -119,13 +115,10 @@ struct database_dyn dbs[lastdb] =
   },
   [grpdb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
-    .propagate = 1,
     .shared = 0,
-    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/group",
     .db_filename = _PATH_NSCD_GROUP_DB,
     .disabled_iov = &grp_iov_disabled,
@@ -137,13 +130,10 @@ struct database_dyn dbs[lastdb] =
   },
   [hstdb] = {
     .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
-    .prunelock = PTHREAD_MUTEX_INITIALIZER,
     .enabled = 0,
     .check_file = 1,
     .persistent = 0,
-    .propagate = 0,		/* Not used.  */
     .shared = 0,
-    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/hosts",
     .db_filename = _PATH_NSCD_HOSTS_DB,
     .disabled_iov = &hst_iov_disabled,
@@ -191,252 +181,20 @@ static int sock;
 unsigned long int client_queued;
 
 
-ssize_t
-writeall (int fd, const void *buf, size_t len)
-{
-  size_t n = len;
-  ssize_t ret;
-  do
-    {
-      ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
-      if (ret <= 0)
-	break;
-      buf = (const char *) buf + ret;
-      n -= ret;
-    }
-  while (n > 0);
-  return ret < 0 ? ret : len - n;
-}
-
-
-#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,
-    /* The following three are not really used, they are symbolic constants.  */
-    use_first = 16,
-    use_begin = 32,
-    use_end = 64,
-
-    use_he = 1,
-    use_he_begin = use_he | use_begin,
-    use_he_end = use_he | use_end,
-#if SEPARATE_KEY
-    use_key = 2,
-    use_key_begin = use_key | use_begin,
-    use_key_end = use_key | use_end,
-    use_key_first = use_key_begin | use_first,
-#endif
-    use_data = 3,
-    use_data_begin = use_data | use_begin,
-    use_data_end = use_data | use_end,
-    use_data_first = use_data_begin | use_first
-  };
-
-
-static int
-check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
-	   enum usekey use, ref_t start, size_t len)
-{
-  assert (len >= 2);
-
-  if (start > first_free || start + len > first_free
-      || (start & BLOCK_ALIGN_M1))
-    return 0;
-
-  if (usemap[start] == use_not)
-    {
-      /* Add the start marker.  */
-      usemap[start] = use | use_begin;
-      use &= ~use_first;
-
-      while (--len > 0)
-	if (usemap[++start] != use_not)
-	  return 0;
-	else
-	  usemap[start] = use;
-
-      /* Add the end marker.  */
-      usemap[start] = use | use_end;
-    }
-  else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
-    {
-      /* Hash entries can't be shared.  */
-      if (use == use_he)
-	return 0;
-
-      usemap[start] |= (use & use_first);
-      use &= ~use_first;
-
-      while (--len > 1)
-	if (usemap[++start] != use)
-	  return 0;
-
-      if (usemap[++start] != (use | use_end))
-	return 0;
-    }
-  else
-    /* Points to a wrong object or somewhere in the middle.  */
-    return 0;
-
-  return 1;
-}
-
-
-/* Verify data in persistent database.  */
-static int
-verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
+/* Initialize database information structures.  */
+void
+nscd_init (void)
 {
-  assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb);
-
-  time_t now = time (NULL);
-
-  struct database_pers_head *head = mem;
-  struct database_pers_head head_copy = *head;
-
-  /* Check that the header that was read matches the head in the database.  */
-  if (readhead != NULL && memcmp (head, readhead, sizeof (*head)) != 0)
-    return 0;
-
-  /* First some easy tests: make sure the database header is sane.  */
-  if (head->version != DB_VERSION
-      || head->header_size != sizeof (*head)
-      /* We allow a timestamp to be one hour ahead of the current time.
-	 This should cover daylight saving time changes.  */
-      || head->timestamp > now + 60 * 60 + 60
-      || (head->gc_cycle & 1)
-      || (size_t) head->module > INT32_MAX / sizeof (ref_t)
-      || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t)
-      || head->first_free < 0
-      || head->first_free > head->data_size
-      || (head->first_free & BLOCK_ALIGN_M1) != 0
-      || head->maxnentries < 0
-      || head->maxnsearched < 0)
-    return 0;
-
-  uint8_t *usemap = calloc (head->first_free, 1);
-  if (usemap == NULL)
-    return 0;
-
-  const char *data = (char *) &head->array[roundup (head->module,
-						    ALIGN / sizeof (ref_t))];
-
-  nscd_ssize_t he_cnt = 0;
-  for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
-    {
-      ref_t work = head->array[cnt];
-
-      while (work != ENDREF)
-	{
-	  if (! check_use (data, head->first_free, usemap, use_he, work,
-			   sizeof (struct hashentry)))
-	    goto fail;
-
-	  /* Now we know we can dereference the record.  */
-	  struct hashentry *here = (struct hashentry *) (data + work);
-
-	  ++he_cnt;
-
-	  /* Make sure the record is for this type of service.  */
-	  if (here->type >= LASTREQ
-	      || serv2db[here->type] != &dbs[dbnr])
-	    goto fail;
-
-	  /* Validate boolean field value.  */
-	  if (here->first != false && here->first != true)
-	    goto fail;
-
-	  if (here->len < 0)
-	    goto fail;
-
-	  /* Now the data.  */
-	  if (here->packet < 0
-	      || here->packet > head->first_free
-	      || here->packet + sizeof (struct datahead) > head->first_free)
-	    goto fail;
-
-	  struct datahead *dh = (struct datahead *) (data + here->packet);
-
-	  if (! check_use (data, head->first_free, usemap,
-			   use_data | (here->first ? use_first : 0),
-			   here->packet, dh->allocsize))
-	    goto fail;
-
-	  if (dh->allocsize < sizeof (struct datahead)
-	      || dh->recsize > dh->allocsize
-	      || (dh->notfound != false && dh->notfound != true)
-	      || (dh->usable != false && dh->usable != true))
-	    goto fail;
-
-	  if (here->key < here->packet + sizeof (struct datahead)
-	      || here->key > here->packet + dh->allocsize
-	      || here->key + here->len > here->packet + dh->allocsize)
-	    {
-#if SEPARATE_KEY
-	      /* If keys can appear outside of data, this should be done
-		 instead.  But gc doesn't mark the data in that case.  */
-	      if (! check_use (data, head->first_free, usemap,
-			       use_key | (here->first ? use_first : 0),
-			       here->key, here->len))
-#endif
-		goto fail;
-	    }
-
-	  work = here->next;
-	}
-    }
-
-  if (he_cnt != head->nentries)
-    goto fail;
+  struct sockaddr_un sock_addr;
+  size_t cnt;
 
-  /* See if all data and keys had at least one reference from
-     he->first == true hashentry.  */
-  for (ref_t idx = 0; idx < head->first_free; ++idx)
+  /* Secure mode and unprivileged mode are incompatible */
+  if (server_user != NULL && secure_in_use)
     {
-#if SEPARATE_KEY
-      if (usemap[idx] == use_key_begin)
-	goto fail;
-#endif
-      if (usemap[idx] == use_data_begin)
-	goto fail;
+      dbg_log (_("Cannot run nscd in secure mode as unprivileged user"));
+      exit (1);
     }
 
-  /* Finally, make sure the database hasn't changed since the first test.  */
-  if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
-    goto fail;
-
-  free (usemap);
-  return 1;
-
-fail:
-  free (usemap);
-  return 0;
-}
-
-
-/* Initialize database information structures.  */
-void
-nscd_init (void)
-{
   /* Look up unprivileged uid/gid/groups before we start listening on the
      socket  */
   if (server_user != NULL)
@@ -446,7 +204,7 @@ nscd_init (void)
     /* No configuration for this value, assume a default.  */
     nthreads = 2 * lastdb;
 
-  for (size_t cnt = 0; cnt < lastdb; ++cnt)
+  for (cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
       {
 	pthread_rwlock_init (&dbs[cnt].lock, NULL);
@@ -469,7 +227,7 @@ nscd_init (void)
 		  fail_db:
 		    dbg_log (_("invalid persistent database file \"%s\": %s"),
 			     dbs[cnt].db_filename, strerror (errno));
-		    unlink (dbs[cnt].db_filename);
+		    dbs[cnt].persistent = 0;
 		  }
 		else if (head.module == 0 && head.data_size == 0)
 		  {
@@ -482,39 +240,22 @@ nscd_init (void)
 		    dbg_log (_("invalid persistent database file \"%s\": %s"),
 			     dbs[cnt].db_filename,
 			     _("header size does not match"));
-		    unlink (dbs[cnt].db_filename);
+		    dbs[cnt].persistent = 0;
 		  }
 		else if ((total = (sizeof (head)
 				   + roundup (head.module * sizeof (ref_t),
 					      ALIGN)
 				   + head.data_size))
-			 > st.st_size
-			 || total < sizeof (head))
+			 > st.st_size)
 		  {
 		    dbg_log (_("invalid persistent database file \"%s\": %s"),
 			     dbs[cnt].db_filename,
 			     _("file size does not match"));
-		    unlink (dbs[cnt].db_filename);
+		    dbs[cnt].persistent = 0;
 		  }
-		/* Note we map with the maximum size allowed for the
-		   database.  This is likely much larger than the
-		   actual file size.  This is OK on most OSes since
-		   extensions of the underlying file will
-		   automatically translate more pages available for
-		   memory access.  */
-		else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
-				      PROT_READ | PROT_WRITE,
-				      MAP_SHARED, fd, 0))
-			 == MAP_FAILED)
+		else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
+				      MAP_SHARED, fd, 0)) == MAP_FAILED)
 		  goto fail_db;
-		else if (!verify_persistent_db (mem, &head, cnt))
-		  {
-		    munmap (mem, total);
-		    dbg_log (_("invalid persistent database file \"%s\": %s"),
-			     dbs[cnt].db_filename,
-			     _("verification failed"));
-		    unlink (dbs[cnt].db_filename);
-		  }
 		else
 		  {
 		    /* Success.  We have the database.  */
@@ -637,23 +378,20 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
 		if (offset % ps != 0)
 		  {
 		    towrite = MIN (remaining, ps - (offset % ps));
-		    if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
-		      goto write_fail;
+		    pwrite (fd, tmpbuf, towrite, offset);
 		    offset += towrite;
 		    remaining -= towrite;
 		  }
 
 		while (remaining > ps)
 		  {
-		    if (pwrite (fd, tmpbuf, ps, offset) == -1)
-		      goto write_fail;
+		    pwrite (fd, tmpbuf, ps, offset);
 		    offset += ps;
 		    remaining -= ps;
 		  }
 
-		if (remaining > 0
-		    && pwrite (fd, tmpbuf, remaining, offset) != remaining)
-		  goto write_fail;
+		if (remaining > 0)
+		  pwrite (fd, tmpbuf, remaining, offset);
 
 		/* Create the header of the file.  */
 		struct database_pers_head head =
@@ -669,13 +407,10 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
 
 		if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
 		     != sizeof (head))
-		    || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
-			!= 0)
-		    || (mem = mmap (NULL, dbs[cnt].max_db_size,
-				    PROT_READ | PROT_WRITE,
+		    || ftruncate (fd, total) != 0
+		    || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
 				    MAP_SHARED, fd, 0)) == MAP_FAILED)
 		  {
-		  write_fail:
 		    unlink (dbs[cnt].db_filename);
 		    dbg_log (_("cannot write to database file %s: %s"),
 			     dbs[cnt].db_filename, strerror (errno));
@@ -726,7 +461,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
 	    dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
 				     + (dbs[cnt].suggested_module
 					* sizeof (ref_t)));
-	    memset (dbs[cnt].head, '\0', sizeof (struct database_pers_head));
+	    memset (dbs[cnt].head, '\0', sizeof (dbs[cnt].head));
 	    assert (~ENDREF == 0);
 	    memset (dbs[cnt].head->array, '\xff',
 		    dbs[cnt].suggested_module * sizeof (ref_t));
@@ -743,9 +478,9 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
 	if (dbs[cnt].check_file)
 	  {
 	    /* We need the modification date of the file.  */
-	    struct stat64 st;
+	    struct stat st;
 
-	    if (stat64 (dbs[cnt].filename, &st) < 0)
+	    if (stat (dbs[cnt].filename, &st) < 0)
 	      {
 		/* We cannot stat() the file, disable file checking.  */
 		dbg_log (_("cannot stat() file `%s': %s"),
@@ -762,16 +497,15 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
   if (sock < 0)
     {
       dbg_log (_("cannot open socket: %s"), strerror (errno));
-      exit (errno == EACCES ? 4 : 1);
+      exit (1);
     }
   /* Bind a name to the socket.  */
-  struct sockaddr_un sock_addr;
   sock_addr.sun_family = AF_UNIX;
   strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
   if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
     {
       dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
-      exit (errno == EACCES ? 4 : 1);
+      exit (1);
     }
 
   /* We don't want to get stuck on accept.  */
@@ -817,10 +551,9 @@ close_sockets (void)
 
 
 static void
-invalidate_cache (char *key, int fd)
+invalidate_cache (char *key)
 {
   dbtype number;
-  int32_t resp;
 
   if (strcmp (key, "passwd") == 0)
     number = pwddb;
@@ -834,19 +567,10 @@ invalidate_cache (char *key, int fd)
       res_init ();
     }
   else
-    {
-      resp = EINVAL;
-      writeall (fd, &resp, sizeof (resp));
-      return;
-    }
+    return;
 
   if (dbs[number].enabled)
-    prune_cache (&dbs[number], LONG_MAX, fd);
-  else
-    {
-      resp = 0;
-      writeall (fd, &resp, sizeof (resp));
-    }
+    prune_cache (&dbs[number], LONG_MAX);
 }
 
 
@@ -864,14 +588,9 @@ send_ro_fd (struct database_dyn *db, char *key, int fd)
   iov[0].iov_len = strlen (key) + 1;
 
   /* Prepare the control message to transfer the descriptor.  */
-  union
-  {
-    struct cmsghdr hdr;
-    char bytes[CMSG_SPACE (sizeof (int))];
-  } buf;
+  char buf[CMSG_SPACE (sizeof (int))];
   struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
-			.msg_control = buf.bytes,
-			.msg_controllen = sizeof (buf) };
+			.msg_control = buf, .msg_controllen = sizeof (buf) };
   struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
 
   cmsg->cmsg_level = SOL_SOCKET;
@@ -884,10 +603,7 @@ send_ro_fd (struct database_dyn *db, char *key, int fd)
 
   /* Send the control message.  We repeat when we are interrupted but
      everything else is ignored.  */
-#ifndef MSG_NOSIGNAL
-# define MSG_NOSIGNAL 0
-#endif
-  (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
+  (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, 0));
 
   if (__builtin_expect (debug_level > 0, 0))
     dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
@@ -944,9 +660,8 @@ cannot handle old request version %d; current version is %d"),
       if (!db->enabled)
 	{
 	  /* No, sent the prepared record.  */
-	  if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
-					db->disabled_iov->iov_len,
-					MSG_NOSIGNAL))
+	  if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
+					 db->disabled_iov->iov_len))
 	      != (ssize_t) db->disabled_iov->iov_len
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {
@@ -973,34 +688,8 @@ cannot handle old request version %d; current version is %d"),
       if (cached != NULL)
 	{
 	  /* Hurray it's in the cache.  */
-	  ssize_t nwritten;
-
-#ifdef HAVE_SENDFILE
-	  if (db->mmap_used || !cached->notfound)
-	    {
-	      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
+	  if (TEMP_FAILURE_RETRY (write (fd, cached->data, cached->recsize))
+	      != cached->recsize
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {
 	      /* We have problems sending the result.  */
@@ -1070,28 +759,29 @@ cannot handle old request version %d; current version is %d"),
     case GETSTAT:
     case SHUTDOWN:
     case INVALIDATE:
-      {
-	/* Get the callers credentials.  */
+      if (! secure_in_use)
+	{
+	  /* Get the callers credentials.  */
 #ifdef SO_PEERCRED
-	struct ucred caller;
-	socklen_t optlen = sizeof (caller);
+	  struct ucred caller;
+	  socklen_t optlen = sizeof (caller);
 
-	if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
-	  {
-	    char buf[256];
+	  if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
+	    {
+	      char buf[256];
 
-	    dbg_log (_("error getting caller's id: %s"),
-		     strerror_r (errno, buf, sizeof (buf)));
-	    break;
-	  }
+	      dbg_log (_("error getting callers id: %s"),
+		       strerror_r (errno, buf, sizeof (buf)));
+	      break;
+	    }
 
-	uid = caller.uid;
+	  uid = caller.uid;
 #else
-	/* Some systems have no SO_PEERCRED implementation.  They don't
-	   care about security so we don't as well.  */
-	uid = 0;
+	  /* Some systems have no SO_PEERCRED implementation.  They don't
+	     care about security so we don't as well.  */
+	  uid = 0;
 #endif
-      }
+	}
 
       /* Accept shutdown, getstat and invalidate only from root.  For
 	 the stat call also allow the user specified in the config file.  */
@@ -1103,7 +793,7 @@ cannot handle old request version %d; current version is %d"),
       else if (uid == 0)
 	{
 	  if (req->type == INVALIDATE)
-	    invalidate_cache (key, fd);
+	    invalidate_cache (key);
 	  else
 	    termination_handler (0);
 	}
@@ -1190,7 +880,7 @@ cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
   /* Second, change back to the old user if we changed it.  */
   if (server_user != NULL)
     {
-      if (setresuid (old_uid, old_uid, old_uid) != 0)
+      if (setuid (old_uid) != 0)
 	{
 	  dbg_log (_("\
 cannot change to old UID: %s; disabling paranoia mode"),
@@ -1200,7 +890,7 @@ cannot change to old UID: %s; disabling paranoia mode"),
 	  return;
 	}
 
-      if (setresgid (old_gid, old_gid, old_gid) != 0)
+      if (setgid (old_gid) != 0)
 	{
 	  dbg_log (_("\
 cannot change to old GID: %s; disabling paranoia mode"),
@@ -1251,9 +941,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
       setuid (server_uid);
       setgid (server_gid);
     }
-  if (chdir ("/") != 0)
-    dbg_log (_("cannot change current working directory to \"/\": %s"),
-	     strerror (errno));
+  chdir ("/");
   paranoia = 0;
 }
 
@@ -1330,10 +1018,6 @@ nscd_run (void *p)
 	      if (readylist == NULL && to == ETIMEDOUT)
 		{
 		  --nready;
-
-		  if (sighup_pending)
-		    goto sighup_prune;
-
 		  pthread_mutex_unlock (&readylist_lock);
 		  goto only_prune;
 		}
@@ -1343,34 +1027,6 @@ nscd_run (void *p)
 	    pthread_cond_wait (&readylist_cond, &readylist_lock);
 	}
 
-      if (sighup_pending)
-	{
-	  --nready;
-	  pthread_cond_signal (&readylist_cond);
-	sighup_prune:
-	  sighup_pending = 0;
-	  pthread_mutex_unlock (&readylist_lock);
-
-	  /* Prune the password database.  */
-	  if (dbs[pwddb].enabled)
-	    prune_cache (&dbs[pwddb], LONG_MAX, -1);
-
-	  /* Prune the group database.  */
-	  if (dbs[grpdb].enabled)
-	    prune_cache (&dbs[grpdb], LONG_MAX, -1);
-
-	  /* Prune the host database.  */
-	  if (dbs[hstdb].enabled)
-	    prune_cache (&dbs[hstdb], LONG_MAX, -1);
-
-	  /* Re-locking.  */
-	  pthread_mutex_lock (&readylist_lock);
-
-	  /* One more thread available.  */
-	  ++nready;
-	  continue;
-	}
-
       struct fdlist *it = readylist->next;
       if (readylist->next == readylist)
 	/* Just one entry on the list.  */
@@ -1417,7 +1073,25 @@ nscd_run (void *p)
 #ifdef SO_PEERCRED
       pid_t pid = 0;
 
-      if (__builtin_expect (debug_level > 0, 0))
+      if (secure_in_use)
+	{
+	  struct ucred caller;
+	  socklen_t optlen = sizeof (caller);
+
+	  if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
+	    {
+	      dbg_log (_("error getting callers id: %s"),
+		       strerror_r (errno, buf, sizeof (buf)));
+	      goto close_and_out;
+	    }
+
+	  if (req.type < GETPWBYNAME || req.type > LASTDBREQ
+	      || serv2db[req.type]->secure)
+	    uid = caller.uid;
+
+	  pid = caller.pid;
+	}
+      else if (__builtin_expect (debug_level > 0, 0))
 	{
 	  struct ucred caller;
 	  socklen_t optlen = sizeof (caller);
@@ -1481,7 +1155,8 @@ handle_request: request received (Version = %d)"), req.version);
 	  /* The pthread_cond_timedwait() call timed out.  It is time
 		 to clean up the cache.  */
 	  assert (my_number < lastdb);
-	  prune_cache (&dbs[my_number], time (NULL), -1);
+	  prune_cache (&dbs[my_number],
+		       prune_ts.tv_sec + (prune_ts.tv_nsec >= 500000000));
 
 	  if (clock_gettime (timeout_clock, &prune_ts) == -1)
 	    /* Should never happen.  */
@@ -1542,7 +1217,7 @@ fd_ready (int fd)
 	{
 	  /* We got another thread.  */
 	  ++nthreads;
-	  /* The new thread might need a kick.  */
+	  /* The new thread might new a kick.  */
 	  do_signal = true;
 	}
 
@@ -1605,24 +1280,18 @@ main_loop_poll (void)
 	      /* We have a new incoming connection.  Accept the connection.  */
 	      int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
 
-	      /* Use the descriptor if we have not reached the limit.  */
-	      if (fd >= 0)
+	      /* use the descriptor if we have not reached the limit.  */
+	      if (fd >= 0 && firstfree < nconns)
 		{
-		  if (firstfree < nconns)
-		    {
-		      conns[firstfree].fd = fd;
-		      conns[firstfree].events = POLLRDNORM;
-		      starttime[firstfree] = now;
-		      if (firstfree >= nused)
-			nused = firstfree + 1;
-
-		      do
-			++firstfree;
-		      while (firstfree < nused && conns[firstfree].fd != -1);
-		    }
-		  else
-		    /* We cannot use the connection so close it.  */
-		    close (fd);
+		  conns[firstfree].fd = fd;
+		  conns[firstfree].events = POLLRDNORM;
+		  starttime[firstfree] = now;
+		  if (firstfree >= nused)
+		    nused = firstfree + 1;
+
+		  do
+		    ++firstfree;
+		  while (firstfree < nused && conns[firstfree].fd != -1);
 		}
 
 	      --n;
@@ -1733,9 +1402,10 @@ main_loop_epoll (int efd)
 	else
 	  {
 	    /* Remove the descriptor from the epoll descriptor.  */
-	    (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, NULL);
+	    struct epoll_event ev = { 0, };
+	    (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, &ev);
 
-	    /* Get a worker to handle the request.  */
+	    /* Get a worked to handle the request.  */
 	    fd_ready (revs[cnt].data.fd);
 
 	    /* Reset the time.  */
@@ -1755,7 +1425,8 @@ main_loop_epoll (int efd)
 	if (cnt != sock && starttime[cnt] != 0 && starttime[cnt] < laststart)
 	  {
 	    /* We are waiting for this one for too long.  Close it.  */
-	    (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, NULL);
+	    struct epoll_event ev = {0, };
+	    (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, &ev);
 
 	    (void) close (cnt);
 
@@ -1908,49 +1579,23 @@ begin_drop_privileges (void)
 static void
 finish_drop_privileges (void)
 {
-#if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
-  /* We need to preserve the capabilities to connect to the audit daemon.  */
-  cap_t new_caps = preserve_capabilities ();
-#endif
-
   if (setgroups (server_ngroups, server_groups) == -1)
     {
       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
       error (EXIT_FAILURE, errno, _("setgroups failed"));
     }
 
-  int res;
-  if (paranoia)
-    res = setresgid (server_gid, server_gid, old_gid);
-  else
-    res = setgid (server_gid);
-  if (res == -1)
+  if (setgid (server_gid) == -1)
     {
       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
       perror ("setgid");
-      exit (4);
+      exit (1);
     }
 
-  if (paranoia)
-    res = setresuid (server_uid, server_uid, old_uid);
-  else
-    res = setuid (server_uid);
-  if (res == -1)
+  if (setuid (server_uid) == -1)
     {
       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
       perror ("setuid");
-      exit (4);
+      exit (1);
     }
-
-#if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
-  /* Remove the temporary capabilities.  */
-  install_real_capabilities (new_caps);
-#endif
-}
-
-/* Handle the HUP signal which will force a dump of the cache */
-void
-sighup_handler (int signum)
-{
-  sighup_pending = 1;
 }
diff --git a/nscd/dbg_log.c b/nscd/dbg_log.c
index d64afc7e8d..afa06dcbe9 100644
--- a/nscd/dbg_log.c
+++ b/nscd/dbg_log.c
@@ -1,19 +1,21 @@
-/* Copyright (c) 1998, 2000, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 2000, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <stdarg.h>
 #include <stdio.h>
@@ -42,7 +44,7 @@ init_logfile (void)
 {
   if (logfilename)
     {
-      dbgout = fopen64 (logfilename, "a");
+      dbgout = fopen (logfilename, "a");
       return dbgout == NULL ? 0 : 1;
     }
   return 1;
diff --git a/nscd/gai.c b/nscd/gai.c
index 68719d876a..722c7e415d 100644
--- a/nscd/gai.c
+++ b/nscd/gai.c
@@ -1,21 +1,3 @@
-/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2004.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include <alloca.h>
 /* This file uses the getaddrinfo code but it compiles it without NSCD
    support.  We just need a few symbol renames.  */
 #define __getservbyname_r getservbyname_r
@@ -26,9 +8,6 @@
 #define __bind bind
 #define __sendto sendto
 #define __strchrnul strchrnul
-#define __getline getline
-/* nscd uses 1MB or 2MB thread stacks.  */
-#define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
 
 #include <getaddrinfo.c>
 
diff --git a/nscd/getgrgid_r.c b/nscd/getgrgid_r.c
index 037509d8aa..d46fb0fcac 100644
--- a/nscd/getgrgid_r.c
+++ b/nscd/getgrgid_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <grp.h>
 
diff --git a/nscd/getgrnam_r.c b/nscd/getgrnam_r.c
index 8fc74dcbaf..42daa16177 100644
--- a/nscd/getgrnam_r.c
+++ b/nscd/getgrnam_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <grp.h>
 
diff --git a/nscd/gethstbyad_r.c b/nscd/gethstbyad_r.c
index 4c02492101..47ed3e22e7 100644
--- a/nscd/gethstbyad_r.c
+++ b/nscd/gethstbyad_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996,1997,1998,1999,2000,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <netdb.h>
 
diff --git a/nscd/gethstbynm2_r.c b/nscd/gethstbynm2_r.c
index 416b5ceafa..b0cc713a84 100644
--- a/nscd/gethstbynm2_r.c
+++ b/nscd/gethstbynm2_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996, 1997, 1998, 2000, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <ctype.h>
 #include <errno.h>
diff --git a/nscd/getpwnam_r.c b/nscd/getpwnam_r.c
index c92209a0cf..df73b99e4a 100644
--- a/nscd/getpwnam_r.c
+++ b/nscd/getpwnam_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <pwd.h>
 
diff --git a/nscd/getpwuid_r.c b/nscd/getpwuid_r.c
index f68951511e..015a521bbe 100644
--- a/nscd/getpwuid_r.c
+++ b/nscd/getpwuid_r.c
@@ -1,19 +1,21 @@
-/* Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <pwd.h>
 
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index c207492cc0..c565f5a682 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -1,20 +1,22 @@
 /* Cache handling for group lookup.
-   Copyright (C) 1998-2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <alloca.h>
 #include <assert.h>
@@ -30,14 +32,10 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/mman.h>
-#include <sys/socket.h>
 #include <stackinfo.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 =
@@ -109,8 +107,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     case.  */
 	  total = sizeof (notfound);
 
-	  written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-					      MSG_NOSIGNAL));
+	  written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
@@ -170,7 +167,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
       char *gr_name;
       char *cp;
       const size_t key_len = strlen (key);
-      const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1;
+      const size_t buf_len = 3 + sizeof (grp->gr_gid) + key_len + 1;
       char *buf = alloca (buf_len);
       ssize_t n;
       size_t cnt;
@@ -279,7 +276,6 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 		  /* Adjust pointers into the memory block.  */
 		  gr_name = (char *) newp + (gr_name - (char *) dataset);
 		  cp = (char *) newp + (cp - (char *) dataset);
-		  key_copy = (char *) newp + (key_copy - (char *) dataset);
 
 		  dataset = memcpy (newp, dataset, total + n);
 		  alloca_used = false;
@@ -296,30 +292,7 @@ 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) && !alloca_used)
-	    {
-	      assert (db->wr_fd != -1);
-	      assert ((char *) &dataset->resp > (char *) db->data);
-	      assert ((char *) &dataset->resp - (char *) db->head
-		      + total
-		      <= (sizeof (struct database_pers_head)
-			  + db->head->module * sizeof (ref_t)
-			  + db->head->data_size));
-	      written = sendfileall (fd, db->wr_fd,
-				     (char *) &dataset->resp
-				     - (char *) db->head, total);
-# ifndef __ASSUME_SENDFILE
-	      if (written == -1 && errno == ENOSYS)
-		goto use_write;
-# endif
-	    }
-	  else
-# ifndef __ASSUME_SENDFILE
-	  use_write:
-# endif
-#endif
-	    written = writeall (fd, &dataset->resp, total);
+	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -343,10 +316,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     marked with FIRST first.  Otherwise we end up with
 	     dangling "pointers" in case a latter hash entry cannot be
 	     added.  */
-	  bool first = true;
+	  bool first = req->type == GETGRBYNAME;
 
 	  /* If the request was by GID, add that entry first.  */
-	  if (req->type == GETGRBYGID)
+	  if (req->type != GETGRBYNAME)
 	    {
 	      if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true,
 			     db, owner) < 0)
@@ -356,14 +329,12 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 		  dataset->head.usable = false;
 		  goto out;
 		}
-
-	      first = false;
 	    }
 	  /* If the key is different from the name add a separate entry.  */
 	  else if (strcmp (key_copy, gr_name) != 0)
 	    {
 	      if (cache_add (GETGRBYNAME, key_copy, key_len + 1,
-			     &dataset->head, true, db, owner) < 0)
+			     &dataset->head, first, db, owner) < 0)
 		{
 		  /* Could not allocate memory.  Make sure the data gets
 		     discarded.  */
@@ -375,13 +346,11 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	    }
 
 	  /* We have to add the value for both, byname and byuid.  */
-	  if ((req->type == GETGRBYNAME || db->propagate)
-	      && __builtin_expect (cache_add (GETGRBYNAME, gr_name,
-					      gr_name_len,
-					      &dataset->head, first, db, owner)
-				   == 0, 1))
+	  if (__builtin_expect (cache_add (GETGRBYNAME, gr_name, gr_name_len,
+					   &dataset->head, first, db, owner)
+				== 0, 1))
 	    {
-	      if (req->type == GETGRBYNAME && db->propagate)
+	      if (req->type == GETGRBYNAME)
 		(void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head,
 				  req->type != GETGRBYNAME, db, owner);
 	    }
@@ -460,10 +429,11 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
+#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen *= 2;
+	  buflen += INCR;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -484,7 +454,7 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
       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);
+	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
     }
 
 #if 0
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index e27ece5bc6..99d2998f49 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -1,20 +1,22 @@
 /* Cache handling for host lookup.
-   Copyright (C) 1998-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <alloca.h>
 #include <assert.h>
@@ -36,9 +38,6 @@
 
 #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.  */
@@ -116,8 +115,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
@@ -329,30 +327,7 @@ 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->resp - (char *) db->head
-		      + total
-		      <= (sizeof (struct database_pers_head)
-			  + db->head->module * sizeof (ref_t)
-			  + db->head->data_size));
-	      written = sendfileall (fd, db->wr_fd,
-				     (char *) &dataset->resp
-				     - (char *) db->head, total);
-# ifndef __ASSUME_SENDFILE
-	      if (written == -1 && errno == ENOSYS)
-		goto use_write;
-# endif
-	    }
-	  else
-# ifndef __ASSUME_SENDFILE
-	  use_write:
-# endif
-#endif
-	    written = writeall (fd, &dataset->resp, total);
+	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -478,10 +453,11 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
+#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen *= 2;
+	  buflen += INCR;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -502,7 +478,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
       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);
+	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
     }
 
 #if 0
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index f1f859c552..b46433716b 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -1,20 +1,22 @@
 /* Cache handling for host lookup.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <assert.h>
 #include <errno.h>
@@ -24,12 +26,8 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
-
-#include "dbg_log.h"
-#include "nscd.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
+#include <dbg_log.h>
+#include <nscd.h>
 
 #include "../nss/nsswitch.h"
 
@@ -107,7 +105,6 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 
   long int start = 0;
   bool all_tryagain = true;
-  bool any_success = false;
 
   /* This is temporary memory, we need not (ad must not) call
      mempool_alloc.  */
@@ -159,8 +156,6 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
 	__libc_fatal ("illegal status in internal_getgrouplist");
 
-      any_success |= status == NSS_STATUS_SUCCESS;
-
       if (status != NSS_STATUS_SUCCESS
 	  && nss_next_action (nip, status) == NSS_ACTION_RETURN)
 	 break;
@@ -174,7 +169,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
   ssize_t total;
   ssize_t written;
  out:
-  if (!any_success)
+  if (start == 0)
     {
       /* Nothing found.  Create a negative result record.  */
       written = total = sizeof (notfound);
@@ -193,8 +188,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	  /* We have no data.  This means we send the standard reply for this
 	     case.  */
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
@@ -349,30 +343,7 @@ 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->resp - (char *) db->head
-		      + total
-		      <= (sizeof (struct database_pers_head)
-			  + db->head->module * sizeof (ref_t)
-			  + db->head->data_size));
-	      written = sendfileall (fd, db->wr_fd,
-				     (char *) &dataset->resp
-				     - (char *) db->head, total);
-# ifndef __ASSUME_SENDFILE
-	      if (written == -1 && errno == ENOSYS)
-		goto use_write;
-# endif
-	    }
-	  else
-# ifndef __ASSUME_SENDFILE
-	  use_write:
-# endif
-#endif
-	    written = writeall (fd, &dataset->resp, total);
+	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
 	}
 
 
diff --git a/nscd/mem.c b/nscd/mem.c
index 5206c5af38..c3a0f96702 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -1,25 +1,26 @@
 /* Cache memory handling.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <assert.h>
 #include <errno.h>
 #include <error.h>
-#include <fcntl.h>
 #include <inttypes.h>
 #include <libintl.h>
 #include <limits.h>
@@ -33,6 +34,12 @@
 #include "nscd.h"
 
 
+/* Maximum alignment requirement we will encounter.  */
+#define BLOCK_ALIGN_LOG 3
+#define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
+#define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
+
+
 static int
 sort_he (const void *p1, const void *p2)
 {
@@ -187,7 +194,7 @@ gc (struct database_dyn *db)
       highref -= BLOCK_ALIGN;
     }
 
-  /* Now we can iterate over the MARK array and find bits which are not
+  /* No we can iterate over the MARK array and find bits which are not
      set.  These represent memory which can be recovered.  */
   size_t byte = 0;
   /* Find the first gap.  */
@@ -479,26 +486,17 @@ mempool_alloc (struct database_dyn *db, size_t len)
       if (! tried_resize)
 	{
 	  /* Try to resize the database.  Grow size of 1/8th.  */
+	  size_t new_data_size = db->head->data_size + db->head->data_size / 8;
 	  size_t oldtotal = (sizeof (struct database_pers_head)
-			     + roundup (db->head->module * sizeof (ref_t), ALIGN)
+			     + db->head->module * sizeof (ref_t)
 			     + db->head->data_size);
-	  size_t new_data_size = (db->head->data_size
-				  + MAX (2 * len, db->head->data_size / 8));
 	  size_t newtotal = (sizeof (struct database_pers_head)
-			     + roundup (db->head->module * sizeof (ref_t), ALIGN)
+			     + db->head->module * sizeof (ref_t)
 			     + new_data_size);
-	  if (newtotal > db->max_db_size)
-	    {
-	      new_data_size -= newtotal - db->max_db_size;
-	      newtotal = db->max_db_size;
-	    }
 
-	  if (db->mmap_used && newtotal > oldtotal
-	      /* We only have to adjust the file size.  The new pages
-		 become magically available.  */
-	      && TEMP_FAILURE_RETRY_VAL (posix_fallocate (db->wr_fd, oldtotal,
-							  newtotal
-							  - oldtotal)) == 0)
+	  if ((!db->mmap_used || ftruncate (db->wr_fd, newtotal) != 0)
+	      /* Try to resize the mapping.  Note: no MREMAP_MAYMOVE.  */
+	      && mremap (db->head, oldtotal, newtotal, 0) == 0)
 	    {
 	      db->head->data_size = new_data_size;
 	      tried_resize = true;
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index 8946b6315b..d49cb8136c 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -1,5 +1,4 @@
-/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+/* Copyright (c) 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
@@ -29,7 +28,6 @@
 #include <sys/types.h>
 #include <atomic.h>
 #include <nscd-types.h>
-#include <sys/uio.h>
 
 
 /* Version number of the daemon interface */
@@ -258,7 +256,6 @@ struct mapped_database
   const char *data;
   size_t mapsize;
   int counter;		/* > 0 indicates it is usable.  */
-  size_t datasize;
 };
 #define NO_MAPPING ((struct mapped_database *) -1l)
 
@@ -278,7 +275,7 @@ extern int __nscd_open_socket (const char *key, size_t keylen,
 /* Get reference of mapping.  */
 extern struct mapped_database *__nscd_get_map_ref (request_type type,
 						   const char *name,
-						   volatile struct locked_map_ptr *mapptr,
+						   struct locked_map_ptr *mapptr,
 						   int *gc_cyclep);
 
 /* Unmap database.  */
@@ -307,20 +304,9 @@ static inline int __nscd_drop_map_ref (struct mapped_database *map,
 
 
 /* Search the mapped database.  */
-extern struct datahead *__nscd_cache_search (request_type type,
-					     const char *key,
-					     size_t keylen,
-					     const struct mapped_database *mapped);
-
-/* Wrappers around read, readv and write that only read/write less than LEN
-   bytes on error or EOF.  */
-extern ssize_t __readall (int fd, void *buf, size_t len)
-  attribute_hidden;
-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;
+extern const struct datahead *__nscd_cache_search (request_type type,
+						   const char *key,
+						   size_t keylen,
+						   const struct mapped_database *mapped);
 
 #endif /* nscd.h */
diff --git a/nscd/nscd.c b/nscd/nscd.c
index 588b09d4fb..0cc1818d9d 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -1,19 +1,21 @@
-/* Copyright (c) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 /* nscd - Name Service Cache Daemon. Caches passwd, group, and hosts.  */
 
@@ -70,6 +72,7 @@ int disabled_passwd;
 int disabled_group;
 int go_background = 1;
 
+int secure_in_use;
 static const char *conffile = _PATH_NSCDCONF;
 
 time_t start_time;
@@ -119,9 +122,6 @@ static struct argp argp =
   options, parse_opt, NULL, doc,
 };
 
-/* The SIGHUP handler is extern to this file */
-extern void sighup_handler(int signum);
-
 /* True if only statistics are requested.  */
 static bool get_stats;
 
@@ -145,15 +145,17 @@ main (int argc, char **argv)
     {
       error (0, 0, gettext ("wrong number of arguments"));
       argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 
   /* Read the configuration file.  */
   if (nscd_parse_file (conffile, dbs) != 0)
-    /* We couldn't read the configuration file.  We don't start the
-       server.  */
-    error (EXIT_FAILURE, 0,
-	   _("failure while reading configuration file; this is fatal"));
+    {
+      /* We couldn't read the configuration file.  We don't start the
+	 server.  */
+      dbg_log (_("cannot read configuration file; this is fatal"));
+      exit (1);
+    }
 
   /* Do we only get statistics?  */
   if (get_stats)
@@ -238,9 +240,7 @@ main (int argc, char **argv)
 
       setsid ();
 
-      if (chdir ("/") != 0)
-	error (EXIT_FAILURE, errno,
-	       _("cannot change current working directory to \"/\""));
+      chdir ("/");
 
       openlog ("nscd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);
 
@@ -266,7 +266,6 @@ main (int argc, char **argv)
   signal (SIGINT, termination_handler);
   signal (SIGQUIT, termination_handler);
   signal (SIGTERM, termination_handler);
-  signal (SIGHUP, sighup_handler);
   signal (SIGPIPE, SIG_IGN);
 
   /* Cleanup files created by a previous 'bind'.  */
@@ -302,7 +301,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
     case 'K':
       if (getuid () != 0)
-	error (4, 0, _("Only root is allowed to use this option!"));
+	error (EXIT_FAILURE, 0, _("Only root is allowed to use this option!"));
       {
 	int sock = nscd_open_socket ();
 	request_header req;
@@ -314,9 +313,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	req.version = NSCD_VERSION;
 	req.type = SHUTDOWN;
 	req.key_len = 0;
-	nbytes = TEMP_FAILURE_RETRY (send (sock, &req,
-					   sizeof (request_header),
-					   MSG_NOSIGNAL));
+	nbytes = TEMP_FAILURE_RETRY (write (sock, &req,
+					    sizeof (request_header)));
 	close (sock);
 	exit (nbytes != sizeof (request_header) ? EXIT_FAILURE : EXIT_SUCCESS);
       }
@@ -327,7 +325,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
     case 'i':
       if (getuid () != 0)
-	error (4, 0, _("Only root is allowed to use this option!"));
+	error (EXIT_FAILURE, 0, _("Only root is allowed to use this option!"));
       else
 	{
 	  int sock = nscd_open_socket ();
@@ -336,6 +334,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	    exit (EXIT_FAILURE);
 
 	  request_header req;
+	  ssize_t nbytes;
+	  struct iovec iov[2];
+
 	  if (strcmp (arg, "passwd") == 0)
 	    req.key_len = sizeof "passwd";
 	  else if (strcmp (arg, "group") == 0)
@@ -348,38 +349,17 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	  req.version = NSCD_VERSION;
 	  req.type = INVALIDATE;
 
-	  struct iovec iov[2];
 	  iov[0].iov_base = &req;
 	  iov[0].iov_len = sizeof (req);
 	  iov[1].iov_base = arg;
 	  iov[1].iov_len = req.key_len;
 
-	  ssize_t nbytes = TEMP_FAILURE_RETRY (writev (sock, iov, 2));
-
-	  if (nbytes != iov[0].iov_len + iov[1].iov_len)
-	    {
-	      int err = errno;
-	      close (sock);
-	      error (EXIT_FAILURE, err, _("write incomplete"));
-	    }
-
-	  /* Wait for ack.  Older nscd just closed the socket when
-	     prune_cache finished, silently ignore that.  */
-	  int32_t resp = 0;
-	  nbytes = TEMP_FAILURE_RETRY (read (sock, &resp, sizeof (resp)));
-	  if (nbytes != 0 && nbytes != sizeof (resp))
-	    {
-	      int err = errno;
-	      close (sock);
-	      error (EXIT_FAILURE, err, _("cannot read invalidate ACK"));
-	    }
+	  nbytes = TEMP_FAILURE_RETRY (writev (sock, iov, 2));
 
 	  close (sock);
 
-	  if (resp != 0)
-	    error (EXIT_FAILURE, resp, _("invalidation failed"));
-
-	  exit (0);
+	  exit (nbytes != iov[0].iov_len + iov[1].iov_len
+		? EXIT_FAILURE : EXIT_SUCCESS);
 	}
 
     case 't':
@@ -387,7 +367,16 @@ parse_opt (int key, char *arg, struct argp_state *state)
       break;
 
     case 'S':
+#if 0
+      if (strcmp (arg, "passwd,yes") == 0)
+	secure_in_use = dbs[pwddb].secure = 1;
+      else if (strcmp (arg, "group,yes") == 0)
+	secure_in_use = dbs[grpdb].secure = 1;
+      else if (strcmp (arg, "hosts,yes") == 0)
+	secure_in_use = dbs[hstdb].secure = 1;
+#else
       error (0, 0, _("secure services not implemented anymore"));
+#endif
       break;
 
     default:
@@ -406,7 +395,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\
-"), "2006");
+"), "2004");
   fprintf (stream, gettext ("Written by %s.\n"),
 	   "Thorsten Kukuk and Ulrich Drepper");
 }
@@ -453,9 +442,6 @@ termination_handler (int signum)
   /* Synchronize memory.  */
   for (int cnt = 0; cnt < lastdb; ++cnt)
     {
-      if (!dbs[cnt].enabled)
-	continue;
-
       /* Make sure nobody keeps using the database.  */
       dbs[cnt].head->timestamp = 0;
 
@@ -509,10 +495,10 @@ write_pid (const char *file)
     return -1;
 
   fprintf (fp, "%d\n", getpid ());
-
-  int result = fflush (fp) || ferror (fp) ? -1 : 0;
+  if (fflush (fp) || ferror (fp))
+    return -1;
 
   fclose (fp);
 
-  return result;
+  return 0;
 }
diff --git a/nscd/nscd.conf b/nscd/nscd.conf
index 954eafd554..87e7a84487 100644
--- a/nscd/nscd.conf
+++ b/nscd/nscd.conf
@@ -23,8 +23,6 @@
 #	check-files		<service> <yes|no>
 #	persistent		<service> <yes|no>
 #	shared			<service> <yes|no>
-#	max-db-size		<service> <number bytes>
-#	auto-propagate		<service> <yes|no>
 #
 # Currently supported cache names (services): passwd, group, hosts
 #
@@ -33,8 +31,8 @@
 #	logfile			/var/log/nscd.log
 #	threads			6
 #	max-threads		128
-	server-user		nscd
-#	stat-user		nocpulse
+#	server-user		nobody
+#	stat-user		somebody
 	debug-level		0
 #	reload-count		5
 	paranoia		no
@@ -47,8 +45,6 @@
 	check-files		passwd		yes
 	persistent		passwd		yes
 	shared			passwd		yes
-	max-db-size		passwd		33554432
-	auto-propagate		passwd		yes
 
 	enable-cache		group		yes
 	positive-time-to-live	group		3600
@@ -57,8 +53,6 @@
 	check-files		group		yes
 	persistent		group		yes
 	shared			group		yes
-	max-db-size		group		33554432
-	auto-propagate		group		yes
 
 	enable-cache		hosts		yes
 	positive-time-to-live	hosts		3600
@@ -67,4 +61,3 @@
 	check-files		hosts		yes
 	persistent		hosts		yes
 	shared			hosts		yes
-	max-db-size		hosts		33554432
diff --git a/nscd/nscd.h b/nscd/nscd.h
index 5c2ff3a95b..d5dc613d22 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
+/* Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -58,18 +58,16 @@ typedef enum
 struct database_dyn
 {
   pthread_rwlock_t lock;
-  pthread_mutex_t prunelock;
 
   int enabled;
   int check_file;
   int persistent;
   int shared;
-  int propagate;
-  const char filename[12];
+  const char *filename;
   const char *db_filename;
   time_t file_mtime;
   size_t suggested_module;
-  size_t max_db_size;
+  int secure;
 
   unsigned long int postimeout;	/* In seconds.  */
   unsigned long int negtimeout;	/* In seconds.  */
@@ -96,17 +94,6 @@ struct database_dyn
 /* Path used when not using persistent storage.  */
 #define _PATH_NSCD_XYZ_DB_TMP	"/var/run/nscd/dbXXXXXX"
 
-/* Maximum alignment requirement we will encounter.  */
-#define BLOCK_ALIGN_LOG 3
-#define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
-#define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
-
-/* Default value for the maximum size of the database files.  */
-#define DEFAULT_MAX_DB_SIZE	(32 * 1024 * 1024)
-
-/* Number of bytes of data we initially reserve for each hash table bucket.  */
-#define DEFAULT_DATASIZE_PER_BUCKET 1024
-
 
 /* Global variables.  */
 extern struct database_dyn dbs[lastdb];
@@ -123,6 +110,9 @@ extern int nthreads;
 /* Maximum number of threads to use.  */
 extern int max_nthreads;
 
+/* Tables for which we cache data with uid.  */
+extern int secure_in_use; /* Is one of the above 1?  */
+
 /* User name to run server processes as.  */
 extern const char *server_user;
 
@@ -185,7 +175,7 @@ extern struct datahead *cache_search (request_type, void *key, size_t len,
 extern int cache_add (int type, const void *key, size_t len,
 		      struct datahead *packet, bool first,
 		      struct database_dyn *table, uid_t owner);
-extern void prune_cache (struct database_dyn *table, time_t now, int fd);
+extern void prune_cache (struct database_dyn *table, time_t now);
 
 /* pwdcache.c */
 extern void addpwbyname (struct database_dyn *db, int fd, request_header *req,
@@ -246,14 +236,4 @@ extern void gc (struct database_dyn *db);
 /* nscd_setup_thread.c */
 extern void setup_thread (struct database_dyn *db);
 
-
-/* Special version of TEMP_FAILURE_RETRY for functions returning error
-   values.  */
-#define TEMP_FAILURE_RETRY_VAL(expression) \
-  (__extension__							      \
-    ({ long int __result;						      \
-       do __result = (long int) (expression);				      \
-       while (__result == EINTR);					      \
-       __result; }))
-
 #endif /* nscd.h */
diff --git a/nscd/nscd.init b/nscd/nscd.init
index 1fba72f5c3..d5c1cb9ae3 100644
--- a/nscd/nscd.init
+++ b/nscd/nscd.init
@@ -9,18 +9,7 @@
 #		slow naming services like NIS, NIS+, LDAP, or hesiod.
 # processname: /usr/sbin/nscd
 # config: /etc/nscd.conf
-# config: /etc/sysconfig/nscd
 #
-### BEGIN INIT INFO
-# Provides: nscd
-# Required-Start: $syslog
-# Default-Stop: 0 1 6
-# Short-Description: Starts the Name Switch Cache Daemon
-# Description:  This is a daemon which handles passwd and group lookups \
-#		for running programs and cache the results for the next \
-#		query.  You should start this daemon if you use \
-#		slow naming services like NIS, NIS+, LDAP, or hesiod.
-### END INIT INFO
 
 # Sanity checks.
 [ -f /etc/nscd.conf ] || exit 0
@@ -29,8 +18,20 @@
 # Source function library.
 . /etc/init.d/functions
 
-# Source an auxiliary options file if we have one, and pick up NSCD_OPTIONS.
-[ -r /etc/sysconfig/nscd ] && . /etc/sysconfig/nscd
+# nscd does not run on any kernel lower than 2.2.0 because of threading
+# problems, so we require that in first place.
+case $(uname -r) in
+    2.[2-9].*)
+	# this is okay
+	;;
+    [3-9]*)
+	# these are of course also okay
+	;;
+    *)
+	#this is not
+	exit 0
+	;;
+esac
 
 RETVAL=0
 prog=nscd
@@ -46,7 +47,7 @@ start () {
 #   	fi
 #   done
     echo -n $"Starting $prog: "
-    daemon /usr/sbin/nscd $secure $NSCD_OPTIONS
+    daemon /usr/sbin/nscd $secure
     RETVAL=$?
     echo
     [ $RETVAL -eq 0 ] && touch /var/lock/subsys/nscd
@@ -87,23 +88,21 @@ case "$1" in
 	RETVAL=$?
 	;;
     status)
-	status nscd
+        status nscd
 	RETVAL=$?
-	;;
+        ;;
     restart)
 	restart
 	RETVAL=$?
 	;;
-    try-restart | condrestart)
+    condrestart)
 	[ -e /var/lock/subsys/nscd ] && restart
 	RETVAL=$?
 	;;
-    force-reload | reload)
-    	echo -n $"Reloading $prog: "
-	killproc /usr/sbin/nscd -HUP
+    reload)
+  	killproc /usr/sbin/nscd -HUP
 	RETVAL=$?
-	echo
-	;;
+        ;;
     *)
 	echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
 	RETVAL=1
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index 2048eca886..d21f2fc501 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -1,23 +1,24 @@
-/* Copyright (c) 1998,2000,2003,2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <ctype.h>
 #include <errno.h>
-#include <error.h>
 #include <libintl.h>
 #include <malloc.h>
 #include <pwd.h>
@@ -44,18 +45,6 @@ const char *dbnames[lastdb] =
   [hstdb] = "hosts"
 };
 
-
-static int
-find_db (const char *name)
-{
-  for (int cnt = 0; cnt < lastdb; ++cnt)
-    if (strcmp (name, dbnames[cnt]) == 0)
-      return cnt;
-
-  error (0, 0, _("database %s is not supported\n"), name);
-  return -1;
-}
-
 int
 nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 {
@@ -63,7 +52,6 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
   char *line, *cp, *entry, *arg1, *arg2;
   size_t len;
   int cnt;
-  const unsigned int initial_error_message_count = error_message_count;
 
   /* Open the configuration file.  */
   fp = fopen (fname, "r");
@@ -103,7 +91,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       ++arg1;
       *cp = '\0';
       if (strlen (entry) == 0)
-	error (0, 0, _("Parse error: %s"), line);
+	dbg_log (_("Parse error: %s"), line);
       while (isspace (*arg1) && *arg1 != '\0')
 	++arg1;
       cp = arg1;
@@ -124,49 +112,64 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 
       if (strcmp (entry, "positive-time-to-live") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    dbs[idx].postimeout = atol (arg2);
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		dbs[cnt].postimeout = atol (arg2);
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "negative-time-to-live") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    dbs[idx].negtimeout = atol (arg2);
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		dbs[cnt].negtimeout = atol (arg2);
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "suggested-size") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    dbs[idx].suggested_module = atol (arg2);
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		dbs[cnt].suggested_module = atol (arg2);
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "enable-cache") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    {
-	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].enabled = 0;
-	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].enabled = 1;
-	    }
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		if (strcmp (arg2, "no") == 0)
+		  dbs[cnt].enabled = 0;
+		else if (strcmp (arg2, "yes") == 0)
+		  dbs[cnt].enabled = 1;
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "check-files") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    {
-	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].check_file = 0;
-	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].check_file = 1;
-	    }
-	}
-      else if (strcmp (entry, "max-db-size") == 0)
-	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    dbs[idx].max_db_size = atol (arg2);
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		if (strcmp (arg2, "no") == 0)
+		  dbs[cnt].check_file = 0;
+		else if (strcmp (arg2, "yes") == 0)
+		  dbs[cnt].check_file = 1;
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "logfile") == 0)
 	set_logfile (arg1);
@@ -188,14 +191,14 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       else if (strcmp (entry, "server-user") == 0)
         {
           if (!arg1)
-            error (0, 0, _("Must specify user name for server-user option"));
+            dbg_log (_("Must specify user name for server-user option"));
           else
             server_user = xstrdup (arg1);
         }
       else if (strcmp (entry, "stat-user") == 0)
         {
           if (arg1 == NULL)
-            error (0, 0, _("Must specify user name for stat-user option"));
+            dbg_log (_("Must specify user name for stat-user option"));
           else
 	    {
 	      stat_user = xstrdup (arg1);
@@ -207,25 +210,31 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
         }
       else if (strcmp (entry, "persistent") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    {
-	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].persistent = 0;
-	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].persistent = 1;
-	    }
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		if (strcmp (arg2, "no") == 0)
+		  dbs[cnt].persistent = 0;
+		else if (strcmp (arg2, "yes") == 0)
+		  dbs[cnt].persistent = 1;
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "shared") == 0)
 	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    {
-	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].shared = 0;
-	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].shared = 1;
-	    }
+	  for (cnt = 0; cnt < lastdb; ++cnt)
+	    if (strcmp (arg1, dbnames[cnt]) == 0)
+	      {
+		if (strcmp (arg2, "no") == 0)
+		  dbs[cnt].shared = 0;
+		else if (strcmp (arg2, "yes") == 0)
+		  dbs[cnt].shared = 1;
+		break;
+	      }
+	  if (cnt == lastdb)
+	    dbg_log ("database %s is not supported\n", arg1);
 	}
       else if (strcmp (entry, "reload-count") == 0)
 	{
@@ -239,7 +248,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	      else if (count >= 0)
 	    reload_count = count;
 	      else
-		error (0, 0, _("invalid value for 'reload-count': %u"), count);
+		dbg_log (_("invalid value for 'reload-count': %u"), count);
 	    }
 	}
       else if (strcmp (entry, "paranoia") == 0)
@@ -254,21 +263,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	  if (arg1 != NULL)
 	    restart_interval = atol (arg1);
 	  else
-            error (0, 0, _("Must specify value for restart-interval option"));
-	}
-      else if (strcmp (entry, "auto-propagate") == 0)
-	{
-	  int idx = find_db (arg1);
-	  if (idx >= 0)
-	    {
-	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].propagate = 0;
-	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].propagate = 1;
-	    }
+            dbg_log (_("Must specify value for restart-interval option"));
 	}
       else
-	error (0, 0, _("Unknown option: %s %s %s"), entry, arg1, arg2);
+	dbg_log (_("Unknown option: %s %s %s"), entry, arg1, arg2);
     }
   while (!feof_unlocked (fp));
 
@@ -281,7 +279,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       oldcwd = get_current_dir_name ();
       if (oldcwd == NULL)
 	{
-	  error (0, 0, _("\
+	  dbg_log (_("\
 cannot get current working directory: %s; disabling paranoia mode"),
 		   strerror (errno));
 	  paranoia = 0;
@@ -292,26 +290,10 @@ cannot get current working directory: %s; disabling paranoia mode"),
   if (max_nthreads < nthreads)
     max_nthreads = nthreads;
 
-  for (cnt = 0; cnt < lastdb; ++cnt)
-    {
-      size_t datasize = (sizeof (struct database_pers_head)
-			 + roundup (dbs[cnt].suggested_module
-				    * sizeof (ref_t), ALIGN)
-			 + (dbs[cnt].suggested_module
-			    * DEFAULT_DATASIZE_PER_BUCKET));
-      if (datasize > dbs[cnt].max_db_size)
-	{
-	  error (0, 0, _("maximum file size for %s database too small"),
-		   dbnames[cnt]);
-	  dbs[cnt].max_db_size = datasize;
-	}
-
-    }
-
   /* Free the buffer.  */
   free (line);
   /* Close configuration file.  */
   fclose (fp);
 
-  return error_message_count != initial_error_message_count;
+  return 0;
 }
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index 5df32dc6dc..24b374b0dc 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -34,7 +34,7 @@ extern int __nss_not_use_nscd_hosts;
 
 
 /* We use the mapping from nscd_gethst.  */
-libc_locked_map_ptr (extern, __hst_map_handle) attribute_hidden;
+libc_locked_map_ptr (extern, __hst_map_handle);
 
 
 int
@@ -42,7 +42,6 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 {
   size_t keylen = strlen (key) + 1;
   int gc_cycle;
-  int nretries = 0;
 
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
@@ -51,53 +50,49 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 			       &gc_cycle);
 
  retry:;
+  const ai_response_header *ai_resp = NULL;
   struct nscd_ai_result *resultbuf = NULL;
   const char *recend = (const char *) ~UINTMAX_C (0);
   char *respdata = NULL;
   int retval = -1;
   int sock = -1;
-  ai_response_header ai_resp;
 
   if (mapped != NO_MAPPING)
     {
-      struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
-						    mapped);
+      const struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
+							  mapped);
       if (found != NULL)
 	{
-	  respdata = (char *) (&found->data[0].aidata + 1);
-	  ai_resp = found->data[0].aidata;
+	  ai_resp = &found->data[0].aidata;
+	  respdata = (char *) (ai_resp + 1);
 	  recend = (const char *) found->data + found->recsize;
-	  /* Now check if we can trust ai_resp fields.  If GC is
-	     in progress, it can contain anything.  */
-	  if (mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out;
-	    }
 	}
     }
 
   /* If we do not have the cache mapped, try to get the data over the
      socket.  */
-  if (respdata == NULL)
+  ai_response_header ai_resp_mem;
+  if (ai_resp == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp,
-				 sizeof (ai_resp));
+      sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp_mem,
+				 sizeof (ai_resp_mem));
       if (sock == -1)
 	{
-	  /* nscd not running or wrong version.  */
+	  /* nscd not running or wrong version or hosts caching disabled.  */
 	  __nss_not_use_nscd_hosts = 1;
 	  goto out;
 	}
+
+      ai_resp = &ai_resp_mem;
     }
 
-  if (ai_resp.found == 1)
+  if (ai_resp->found == 1)
     {
-      size_t datalen = ai_resp.naddrs + ai_resp.addrslen + ai_resp.canonlen;
+      size_t datalen = ai_resp->naddrs + ai_resp->addrslen + ai_resp->canonlen;
 
-      /* This check really only affects the case where the data
+      /* This check is really only affects the case where the data
 	 comes from the mapped cache.  */
-      if (respdata + datalen > recend)
+      if ((char *) (ai_resp + 1) + datalen > recend)
 	{
 	  assert (sock == -1);
 	  goto out;
@@ -113,10 +108,10 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 	}
 
       /* Set up the data structure, including pointers.  */
-      resultbuf->naddrs = ai_resp.naddrs;
+      resultbuf->naddrs = ai_resp->naddrs;
       resultbuf->addrs = (char *) (resultbuf + 1);
-      resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp.addrslen);
-      if (ai_resp.canonlen != 0)
+      resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp->addrslen);
+      if (ai_resp->canonlen != 0)
 	resultbuf->canon = (char *) (resultbuf->family + resultbuf->naddrs);
       else
 	resultbuf->canon = NULL;
@@ -124,7 +119,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) __readall (sock, resultbuf + 1, datalen) == datalen)
+	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, resultbuf + 1,
+						   datalen)) == datalen)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
@@ -142,13 +138,10 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 
 	  /* Try to detect corrupt databases.  */
 	  if (resultbuf->canon != NULL
-	      && resultbuf->canon[ai_resp.canonlen - 1] != '\0')
+	      && resultbuf->canon[ai_resp->canonlen - 1] != '\0')
 	    /* We cannot use the database.  */
 	    {
-	      if (mapped->head->gc_cycle != gc_cycle)
-		retval = -2;
-	      else
-		free (resultbuf);
+	      free (resultbuf);
 	      goto out_close;
 	    }
 
@@ -158,15 +151,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
     }
   else
     {
-      if (__builtin_expect (ai_resp.found == -1, 0))
-	{
-	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_hosts = 1;
-	  goto out_close;
-	}
-
       /* Store the error number.  */
-      *h_errnop = ai_resp.error;
+      *h_errnop = ai_resp->error;
 
       /* The `errno' to some value != ERANGE.  */
       __set_errno (ENOENT);
@@ -178,25 +164,22 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
     {
       /* When we come here this means there has been a GC cycle while we
 	 were looking for the data.  This means the data might have been
 	 inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
+      if ((gc_cycle & 1) != 0)
 	{
 	  /* nscd is just running gc now.  Disable using the mapping.  */
-	  if (atomic_decrement_val (&mapped->counter) == 0)
-	    __nscd_unmap (mapped);
+	  __nscd_unmap (mapped);
 	  mapped = NO_MAPPING;
 	}
 
-      if (retval != -1)
-	{
-	  *result = NULL;
-	  free (resultbuf);
-	  goto retry;
-	}
+      *result = NULL;
+      free (resultbuf);
+
+      goto retry;
     }
 
   return retval;
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index fc036f2888..282912db3e 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2000, 2002-2005, 2006, 2007
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -67,7 +67,7 @@ __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
 }
 
 
-libc_locked_map_ptr (,__gr_map_handle) attribute_hidden;
+libc_locked_map_ptr (,__gr_map_handle);
 /* Note that we only free the structure if necessary.  The memory
    mapping is not removed since it is not visible to the malloc
    handling.  */
@@ -89,7 +89,6 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	      struct group **result)
 {
   int gc_cycle;
-  int nretries = 0;
   const uint32_t *len = NULL;
   size_t lensize = 0;
 
@@ -99,59 +98,55 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 						       &__gr_map_handle,
 						       &gc_cycle);
  retry:;
+  const gr_response_header *gr_resp = NULL;
   const char *gr_name = NULL;
   size_t gr_name_len = 0;
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
-  gr_response_header gr_resp;
 
   if (mapped != NO_MAPPING)
     {
-      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+      const struct datahead *found = __nscd_cache_search (type, key, keylen,
+							  mapped);
       if (found != NULL)
 	{
-	  len = (const uint32_t *) (&found->data[0].grdata + 1);
-	  gr_resp = found->data[0].grdata;
+	  gr_resp = &found->data[0].grdata;
+	  len = (const uint32_t *) (gr_resp + 1);
+	  /* The alignment is always sufficient.  */
+	  assert (((uintptr_t) len & (__alignof__ (*len) - 1)) == 0);
 	  gr_name = ((const char *) len
-		     + gr_resp.gr_mem_cnt * sizeof (uint32_t));
-	  gr_name_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+		     + gr_resp->gr_mem_cnt * sizeof (uint32_t));
+	  gr_name_len = gr_resp->gr_name_len + gr_resp->gr_passwd_len;
 	  recend = (const char *) found->data + found->recsize;
-	  /* Now check if we can trust gr_resp fields.  If GC is
-	     in progress, it can contain anything.  */
-	  if (mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out;
-	    }
-
-	  /* The alignment is always sufficient, unless GC is in progress.  */
-	  assert (((uintptr_t) len & (__alignof__ (*len) - 1)) == 0);
 	}
     }
 
+  gr_response_header gr_resp_mem;
   int sock = -1;
-  if (gr_name == NULL)
+  if (gr_resp == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &gr_resp,
-				 sizeof (gr_resp));
+      sock = __nscd_open_socket (key, keylen, type, &gr_resp_mem,
+				 sizeof (gr_resp_mem));
       if (sock == -1)
 	{
 	  __nss_not_use_nscd_group = 1;
 	  goto out;
 	}
+
+      gr_resp = &gr_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (gr_resp.found == -1, 0))
+  if (__builtin_expect (gr_resp->found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_group = 1;
       goto out_close;
     }
 
-  if (gr_resp.found == 1)
+  if (gr_resp->found == 1)
     {
       struct iovec vec[2];
       char *p = buffer;
@@ -163,8 +158,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	 align the pointer.  */
       align = ((__alignof__ (char *) - (p - ((char *) 0)))
 	       & (__alignof__ (char *) - 1));
-      total_len = (align + (1 + gr_resp.gr_mem_cnt) * sizeof (char *)
-		   + gr_resp.gr_name_len + gr_resp.gr_passwd_len);
+      total_len = (align + (1 + gr_resp->gr_mem_cnt) * sizeof (char *)
+		   + gr_resp->gr_name_len + gr_resp->gr_passwd_len);
       if (__builtin_expect (buflen < total_len, 0))
 	{
 	no_room:
@@ -176,16 +171,16 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 
       p += align;
       resultbuf->gr_mem = (char **) p;
-      p += (1 + gr_resp.gr_mem_cnt) * sizeof (char *);
+      p += (1 + gr_resp->gr_mem_cnt) * sizeof (char *);
 
       /* Set pointers for strings.  */
       resultbuf->gr_name = p;
-      p += gr_resp.gr_name_len;
+      p += gr_resp->gr_name_len;
       resultbuf->gr_passwd = p;
-      p += gr_resp.gr_passwd_len;
+      p += gr_resp->gr_passwd_len;
 
       /* Fill in what we know now.  */
-      resultbuf->gr_gid = gr_resp.gr_gid;
+      resultbuf->gr_gid = gr_resp->gr_gid;
 
       /* Read the length information, group name, and password.  */
       if (gr_name == NULL)
@@ -193,21 +188,21 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	  /* Allocate array to store lengths.  */
 	  if (lensize == 0)
 	    {
-	      lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+	      lensize = gr_resp->gr_mem_cnt * sizeof (uint32_t);
 	      len = (uint32_t *) alloca (lensize);
 	    }
-	  else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
+	  else if (gr_resp->gr_mem_cnt * sizeof (uint32_t) > lensize)
 	    len = extend_alloca (len, lensize,
-				 gr_resp.gr_mem_cnt * sizeof (uint32_t));
+				 gr_resp->gr_mem_cnt * sizeof (uint32_t));
 
 	  vec[0].iov_base = (void *) len;
-	  vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+	  vec[0].iov_len = gr_resp->gr_mem_cnt * sizeof (uint32_t);
 	  vec[1].iov_base = resultbuf->gr_name;
-	  vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+	  vec[1].iov_len = gr_resp->gr_name_len + gr_resp->gr_passwd_len;
 	  total_len = vec[0].iov_len + vec[1].iov_len;
 
 	  /* Get this data.  */
-	  size_t n = __readvall (sock, vec, 2);
+	  size_t n = TEMP_FAILURE_RETRY (__readv (sock, vec, 2));
 	  if (__builtin_expect (n != total_len, 0))
 	    goto out_close;
 	}
@@ -215,14 +210,14 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	/* We already have the data.  Just copy the group name and
 	   password.  */
 	memcpy (resultbuf->gr_name, gr_name,
-		gr_resp.gr_name_len + gr_resp.gr_passwd_len);
+		gr_resp->gr_name_len + gr_resp->gr_passwd_len);
 
       /* Clear the terminating entry.  */
-      resultbuf->gr_mem[gr_resp.gr_mem_cnt] = NULL;
+      resultbuf->gr_mem[gr_resp->gr_mem_cnt] = NULL;
 
       /* Prepare reading the group members.  */
       total_len = 0;
-      for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
+      for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
 	{
 	  resultbuf->gr_mem[cnt] = p;
 	  total_len += len[cnt];
@@ -230,30 +225,15 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	}
 
       if (__builtin_expect (gr_name + gr_name_len + total_len > recend, 0))
-	{
-	  /* len array might contain garbage during nscd GC cycle,
-	     retry rather than fail in that case.  */
-	  if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
-	    retval = -2;
-	  goto out_close;
-	}
+	goto out_close;
       if (__builtin_expect (total_len > buflen, 0))
-	{
-	  /* len array might contain garbage during nscd GC cycle,
-	     retry rather than fail in that case.  */
-	  if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out_close;
-	    }
-	  else
-	    goto no_room;
-	}
+	goto no_room;
 
       retval = 0;
       if (gr_name == NULL)
 	{
-	  size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
+	  size_t n = TEMP_FAILURE_RETRY (__read (sock, resultbuf->gr_mem[0],
+						 total_len));
 	  if (__builtin_expect (n != total_len, 0))
 	    {
 	      /* The `errno' to some value != ERANGE.  */
@@ -270,14 +250,14 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 
 	  /* Try to detect corrupt databases.  */
 	  if (resultbuf->gr_name[gr_name_len - 1] != '\0'
-	      || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
-	      || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
+	      || resultbuf->gr_passwd[gr_resp->gr_passwd_len - 1] != '\0'
+	      || ({for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
 		     if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
 		       break;
-	  	   cnt < gr_resp.gr_mem_cnt; }))
+	  	   cnt < gr_resp->gr_mem_cnt; }))
 	    {
 	      /* We cannot use the database.  */
-	      retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
+	      retval = -1;
 	      goto out_close;
 	    }
 
@@ -296,21 +276,19 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
     {
       /* When we come here this means there has been a GC cycle while we
 	 were looking for the data.  This means the data might have been
 	 inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
+      if ((gc_cycle & 1) != 0)
 	{
 	  /* nscd is just running gc now.  Disable using the mapping.  */
-	  if (atomic_decrement_val (&mapped->counter) == 0)
-	    __nscd_unmap (mapped);
+	  __nscd_unmap (mapped);
 	  mapped = NO_MAPPING;
 	}
 
-      if (retval != -1)
-	goto retry;
+      goto retry;
     }
 
   return retval;
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 90e1815bdd..5d9d569107 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -87,7 +87,7 @@ __nscd_gethostbyaddr_r (const void *addr, socklen_t len, int type,
 }
 
 
-libc_locked_map_ptr (, __hst_map_handle) attribute_hidden;
+libc_locked_map_ptr (, __hst_map_handle);
 /* Note that we only free the structure if necessary.  The memory
    mapping is not removed since it is not visible to the malloc
    handling.  */
@@ -118,6 +118,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 			       &gc_cycle);
 
  retry:;
+  const hst_response_header *hst_resp = NULL;
   const char *h_name = NULL;
   const uint32_t *aliases_len = NULL;
   const char *addr_list = NULL;
@@ -125,27 +126,18 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
   int sock = -1;
-  hst_response_header hst_resp;
   if (mapped != NO_MAPPING)
     {
-      /* No const qualifier, as it can change during garbage collection.  */
-      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+      const struct datahead *found = __nscd_cache_search (type, key, keylen,
+							  mapped);
       if (found != NULL)
 	{
-	  h_name = (char *) (&found->data[0].hstdata + 1);
-	  hst_resp = found->data[0].hstdata;
-	  aliases_len = (uint32_t *) (h_name + hst_resp.h_name_len);
+	  hst_resp = &found->data[0].hstdata;
+	  h_name = (char *) (hst_resp + 1);
+	  aliases_len = (uint32_t *) (h_name + hst_resp->h_name_len);
 	  addr_list = ((char *) aliases_len
-		       + hst_resp.h_aliases_cnt * sizeof (uint32_t));
-	  addr_list_len = hst_resp.h_addr_list_cnt * INADDRSZ;
-	  recend = (const char *) found->data + found->recsize;
-	  /* Now check if we can trust hst_resp fields.  If GC is
-	     in progress, it can contain anything.  */
-	  if (mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out;
-	    }
+		       + hst_resp->h_aliases_cnt * sizeof (uint32_t));
+	  addr_list_len = hst_resp->h_addr_list_cnt * INADDRSZ;
 
 #ifndef _STRING_ARCH_unaligned
 	  /* The aliases_len array in the mapped database might very
@@ -155,47 +147,51 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	  if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
 	      != 0)
 	    {
-	      uint32_t *tmp = alloca (hst_resp.h_aliases_cnt
+	      uint32_t *tmp = alloca (hst_resp->h_aliases_cnt
 				      * sizeof (uint32_t));
 	      aliases_len = memcpy (tmp, aliases_len,
-				    hst_resp.h_aliases_cnt
+				    hst_resp->h_aliases_cnt
 				    * sizeof (uint32_t));
 	    }
 #endif
 	  if (type != GETHOSTBYADDR && type != GETHOSTBYNAME)
 	    {
-	      if (hst_resp.h_length == INADDRSZ)
+	      if (hst_resp->h_length == INADDRSZ)
 		addr_list += addr_list_len;
-	      addr_list_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
+	      addr_list_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
 	    }
+	  recend = (const char *) found->data + found->recsize;
 	  if (__builtin_expect ((const char *) addr_list + addr_list_len
 				> recend, 0))
-	    goto out;
+	    goto out_close;
 	}
     }
 
-  if (h_name == NULL)
+  hst_response_header hst_resp_mem;
+  if (hst_resp == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &hst_resp,
-				 sizeof (hst_resp));
+      sock = __nscd_open_socket (key, keylen, type, &hst_resp_mem,
+				 sizeof (hst_resp_mem));
       if (sock == -1)
 	{
 	  __nss_not_use_nscd_hosts = 1;
-	  goto out;
+	  goto out;;
 	}
+
+      hst_resp = &hst_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (hst_resp.found == -1, 0))
+  if (__builtin_expect (hst_resp->found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_hosts = 1;
       goto out_close;
     }
 
-  if (hst_resp.found == 1)
+  if (hst_resp->found == 1)
     {
       struct iovec vec[4];
       char *cp = buffer;
@@ -211,18 +207,17 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	 align the pointer and the base of the h_addr_list pointers.  */
       align1 = ((__alignof__ (char *) - (cp - ((char *) 0)))
 		& (__alignof__ (char *) - 1));
-      align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp.h_name_len)
+      align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp->h_name_len)
 					 - ((char *) 0)))
 		& (__alignof__ (char *) - 1));
-      if (buflen < (align1 + hst_resp.h_name_len + align2
-		    + ((hst_resp.h_aliases_cnt + hst_resp.h_addr_list_cnt
+      if (buflen < (align1 + hst_resp->h_name_len + align2
+		    + ((hst_resp->h_aliases_cnt + hst_resp->h_addr_list_cnt
 			+ 2)
 		       * sizeof (char *))
-		    + hst_resp.h_addr_list_cnt * (type == AF_INET
-						  ? INADDRSZ : IN6ADDRSZ)))
+		    + hst_resp->h_addr_list_cnt * (type == AF_INET
+						   ? INADDRSZ : IN6ADDRSZ)))
 	{
 	no_room:
-	  *h_errnop = NETDB_INTERNAL;
 	  __set_errno (ERANGE);
 	  retval = ERANGE;
 	  goto out_close;
@@ -231,12 +226,12 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 
       /* Prepare the result as far as we can.  */
       resultbuf->h_aliases = (char **) cp;
-      cp += (hst_resp.h_aliases_cnt + 1) * sizeof (char *);
+      cp += (hst_resp->h_aliases_cnt + 1) * sizeof (char *);
       resultbuf->h_addr_list = (char **) cp;
-      cp += (hst_resp.h_addr_list_cnt + 1) * sizeof (char *);
+      cp += (hst_resp->h_addr_list_cnt + 1) * sizeof (char *);
 
       resultbuf->h_name = cp;
-      cp += hst_resp.h_name_len + align2;
+      cp += hst_resp->h_name_len + align2;
 
       if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
 	{
@@ -248,7 +243,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	  resultbuf->h_addrtype = AF_INET6;
 	  resultbuf->h_length = IN6ADDRSZ;
 	}
-      for (cnt = 0; cnt < hst_resp.h_addr_list_cnt; ++cnt)
+      for (cnt = 0; cnt < hst_resp->h_addr_list_cnt; ++cnt)
 	{
 	  resultbuf->h_addr_list[cnt] = cp;
 	  cp += resultbuf->h_length;
@@ -258,63 +253,64 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
       if (h_name == NULL)
 	{
 	  vec[0].iov_base = resultbuf->h_name;
-	  vec[0].iov_len = hst_resp.h_name_len;
-	  total_len = hst_resp.h_name_len;
+	  vec[0].iov_len = hst_resp->h_name_len;
+	  total_len = hst_resp->h_name_len;
 	  n = 1;
 
-	  if (hst_resp.h_aliases_cnt > 0)
+	  if (hst_resp->h_aliases_cnt > 0)
 	    {
-	      aliases_len = alloca (hst_resp.h_aliases_cnt
+	      aliases_len = alloca (hst_resp->h_aliases_cnt
 				    * sizeof (uint32_t));
 	      vec[n].iov_base = (void *) aliases_len;
-	      vec[n].iov_len = hst_resp.h_aliases_cnt * sizeof (uint32_t);
+	      vec[n].iov_len = hst_resp->h_aliases_cnt * sizeof (uint32_t);
 
-	      total_len += hst_resp.h_aliases_cnt * sizeof (uint32_t);
+	      total_len += hst_resp->h_aliases_cnt * sizeof (uint32_t);
 	      ++n;
 	    }
 
 	  if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
 	    {
 	      vec[n].iov_base = resultbuf->h_addr_list[0];
-	      vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+	      vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
 
-	      total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
+	      total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
 
 	      ++n;
 	    }
 	  else
 	    {
-	      if (hst_resp.h_length == INADDRSZ)
+	      if (hst_resp->h_length == INADDRSZ)
 		{
-		  ignore = alloca (hst_resp.h_addr_list_cnt * INADDRSZ);
+		  ignore = alloca (hst_resp->h_addr_list_cnt * INADDRSZ);
 		  vec[n].iov_base = ignore;
-		  vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+		  vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
 
-		  total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
+		  total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
 
 		  ++n;
 		}
 
 	      vec[n].iov_base = resultbuf->h_addr_list[0];
-	      vec[n].iov_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
+	      vec[n].iov_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
 
-	      total_len += hst_resp.h_addr_list_cnt * IN6ADDRSZ;
+	      total_len += hst_resp->h_addr_list_cnt * IN6ADDRSZ;
 
 	      ++n;
 	    }
 
-	  if ((size_t) __readvall (sock, vec, n) != total_len)
+	  if ((size_t) TEMP_FAILURE_RETRY (__readv (sock, vec, n))
+	      != total_len)
 	    goto out_close;
 	}
       else
 	{
-	  memcpy (resultbuf->h_name, h_name, hst_resp.h_name_len);
+	  memcpy (resultbuf->h_name, h_name, hst_resp->h_name_len);
 	  memcpy (resultbuf->h_addr_list[0], addr_list, addr_list_len);
 	}
 
       /*  Now we also can read the aliases.  */
       total_len = 0;
-      for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
+      for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
 	{
 	  resultbuf->h_aliases[cnt] = cp;
 	  cp += aliases_len[cnt];
@@ -324,32 +320,17 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 
       if (__builtin_expect ((const char *) addr_list + addr_list_len
 			    + total_len > recend, 0))
-	{
-	  /* aliases_len array might contain garbage during nscd GC cycle,
-	     retry rather than fail in that case.  */
-	  if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
-	    retval = -2;
-	  goto out_close;
-	}
+	goto out_close;
       /* See whether this would exceed the buffer capacity.  */
       if (__builtin_expect (cp > buffer + buflen, 0))
-	{
-	  /* aliases_len array might contain garbage during nscd GC cycle,
-	     retry rather than fail in that case.  */
-	  if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out_close;
-	    }
-	  goto no_room;
-	}
+	goto no_room;
 
       /* And finally read the aliases.  */
       if (addr_list == NULL)
 	{
-	  if (total_len == 0
-	      || ((size_t) __readall (sock, resultbuf->h_aliases[0], total_len)
-		  == total_len))
+	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock,
+						   resultbuf->h_aliases[0],
+						   total_len)) == total_len)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
@@ -361,18 +342,14 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 		  (const char *) addr_list + addr_list_len, total_len);
 
 	  /* Try to detect corrupt databases.  */
-	  if (resultbuf->h_name[hst_resp.h_name_len - 1] != '\0'
-	      || ({for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
+	  if (resultbuf->h_name[hst_resp->h_name_len - 1] != '\0'
+	      || ({for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
 		     if (resultbuf->h_aliases[cnt][aliases_len[cnt] - 1]
 			 != '\0')
 		       break;
-		   cnt < hst_resp.h_aliases_cnt; }))
-	    {
-	      /* We cannot use the database.  */
-	      if (mapped->head->gc_cycle != gc_cycle)
-		retval = -2;
-	      goto out_close;
-	    }
+		   cnt < hst_resp->h_aliases_cnt; }))
+	    /* We cannot use the database.  */
+	    goto out_close;
 
 	  retval = 0;
 	  *result = resultbuf;
@@ -381,7 +358,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   else
     {
       /* Store the error number.  */
-      *h_errnop = hst_resp.error;
+      *h_errnop = hst_resp->error;
 
       /* The `errno' to some value != ERANGE.  */
       __set_errno (ENOENT);
@@ -393,21 +370,19 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
     {
       /* When we come here this means there has been a GC cycle while we
 	 were looking for the data.  This means the data might have been
 	 inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5)
 	{
 	  /* nscd is just running gc now.  Disable using the mapping.  */
-	  if (atomic_decrement_val (&mapped->counter) == 0)
-	    __nscd_unmap (mapped);
+	  __nscd_unmap (mapped);
 	  mapped = NO_MAPPING;
 	}
 
-      if (retval != -1)
-	goto retry;
+      goto retry;
     }
 
   return retval;
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index b84baa1a66..fe5fb43ca1 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1998, 1999, 2003, 2004, 2005, 2007
-   Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
 
@@ -89,81 +88,76 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
 	      struct passwd **result)
 {
   int gc_cycle;
-  int nretries = 0;
-
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
   mapped = __nscd_get_map_ref (GETFDPW, "passwd", &map_handle, &gc_cycle);
 
  retry:;
+  const pw_response_header *pw_resp = NULL;
   const char *pw_name = NULL;
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
-  pw_response_header pw_resp;
 
   if (mapped != NO_MAPPING)
     {
-      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
+      const struct datahead *found = __nscd_cache_search (type, key, keylen,
+							  mapped);
       if (found != NULL)
 	{
-	  pw_name = (const char *) (&found->data[0].pwdata + 1);
-	  pw_resp = found->data[0].pwdata;
+	  pw_resp = &found->data[0].pwdata;
+	  pw_name = (const char *) (pw_resp + 1);
 	  recend = (const char *) found->data + found->recsize;
-	  /* Now check if we can trust pw_resp fields.  If GC is
-	     in progress, it can contain anything.  */
-	  if (mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out;
-	    }
 	}
     }
 
+  pw_response_header pw_resp_mem;
   int sock = -1;
-  if (pw_name == NULL)
+  if (pw_resp == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &pw_resp,
-				 sizeof (pw_resp));
+      sock = __nscd_open_socket (key, keylen, type, &pw_resp_mem,
+				 sizeof (pw_resp_mem));
       if (sock == -1)
 	{
 	  __nss_not_use_nscd_passwd = 1;
 	  goto out;
 	}
+
+      pw_resp = &pw_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (pw_resp.found == -1, 0))
+  if (__builtin_expect (pw_resp->found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_passwd = 1;
       goto out_close;
     }
 
-  if (pw_resp.found == 1)
+  if (pw_resp->found == 1)
     {
       /* Set the information we already have.  */
-      resultbuf->pw_uid = pw_resp.pw_uid;
-      resultbuf->pw_gid = pw_resp.pw_gid;
+      resultbuf->pw_uid = pw_resp->pw_uid;
+      resultbuf->pw_gid = pw_resp->pw_gid;
 
       char *p = buffer;
       /* get pw_name */
       resultbuf->pw_name = p;
-      p += pw_resp.pw_name_len;
+      p += pw_resp->pw_name_len;
       /* get pw_passwd */
       resultbuf->pw_passwd = p;
-      p += pw_resp.pw_passwd_len;
+      p += pw_resp->pw_passwd_len;
       /* get pw_gecos */
       resultbuf->pw_gecos = p;
-      p += pw_resp.pw_gecos_len;
+      p += pw_resp->pw_gecos_len;
       /* get pw_dir */
       resultbuf->pw_dir = p;
-      p += pw_resp.pw_dir_len;
+      p += pw_resp->pw_dir_len;
       /* get pw_pshell */
       resultbuf->pw_shell = p;
-      p += pw_resp.pw_shell_len;
+      p += pw_resp->pw_shell_len;
 
       ssize_t total = p - buffer;
       if (__builtin_expect (pw_name + total > recend, 0))
@@ -178,7 +172,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
       retval = 0;
       if (pw_name == NULL)
 	{
-	  ssize_t nbytes = __readall (sock, buffer, total);
+	  ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, buffer, total));
 
 	  if (__builtin_expect (nbytes != total, 0))
 	    {
@@ -195,14 +189,14 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
 	  memcpy (resultbuf->pw_name, pw_name, total);
 
 	  /* Try to detect corrupt databases.  */
-	  if (resultbuf->pw_name[pw_resp.pw_name_len - 1] != '\0'
-	      || resultbuf->pw_passwd[pw_resp.pw_passwd_len - 1] != '\0'
-	      || resultbuf->pw_gecos[pw_resp.pw_gecos_len - 1] != '\0'
-	      || resultbuf->pw_dir[pw_resp.pw_dir_len - 1] != '\0'
-	      || resultbuf->pw_shell[pw_resp.pw_shell_len - 1] != '\0')
+	  if (resultbuf->pw_name[pw_resp->pw_name_len - 1] != '\0'
+	      || resultbuf->pw_passwd[pw_resp->pw_passwd_len - 1] != '\0'
+	      || resultbuf->pw_gecos[pw_resp->pw_gecos_len - 1] != '\0'
+	      || resultbuf->pw_dir[pw_resp->pw_dir_len - 1] != '\0'
+	      || resultbuf->pw_shell[pw_resp->pw_shell_len - 1] != '\0')
 	    {
 	      /* We cannot use the database.  */
-	      retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
+	      retval = -1;
 	      goto out_close;
 	    }
 
@@ -221,21 +215,21 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
     {
       /* When we come here this means there has been a GC cycle while we
 	 were looking for the data.  This means the data might have been
 	 inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
+      if ((gc_cycle & 1) != 0)
 	{
 	  /* nscd is just running gc now.  Disable using the mapping.  */
-	  if (atomic_decrement_val (&mapped->counter) == 0)
-	    __nscd_unmap (mapped);
+	  __nscd_unmap (mapped);
 	  mapped = NO_MAPPING;
 	}
 
-      if (retval != -1)
-	goto retry;
+      free (resultbuf);
+
+      goto retry;
     }
 
   return retval;
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 71ea53e19d..0e16cb8aeb 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1998-2002,2003,2004,2005,2006,2007
-   Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -22,14 +21,11 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
-#include <string.h>
-#include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <sys/uio.h>
 #include <sys/un.h>
 #include <not-cancel.h>
@@ -38,64 +34,6 @@
 #include "nscd-client.h"
 
 
-ssize_t
-__readall (int fd, void *buf, size_t len)
-{
-  size_t n = len;
-  ssize_t ret;
-  do
-    {
-      ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
-      if (ret <= 0)
-	break;
-      buf = (char *) buf + ret;
-      n -= ret;
-    }
-  while (n > 0);
-  return ret < 0 ? ret : len - n;
-}
-
-
-ssize_t
-__readvall (int fd, const struct iovec *iov, int iovcnt)
-{
-  ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
-  if (ret <= 0)
-    return ret;
-
-  size_t total = 0;
-  for (int i = 0; i < iovcnt; ++i)
-    total += iov[i].iov_len;
-
-  if (ret < total)
-    {
-      struct iovec iov_buf[iovcnt];
-      ssize_t r = ret;
-
-      struct iovec *iovp = memcpy (iov_buf, iov, iovcnt * sizeof (*iov));
-      do
-	{
-	  while (iovp->iov_len <= r)
-	    {
-	      r -= iovp->iov_len;
-	      --iovcnt;
-	      ++iovp;
-	    }
-	  iovp->iov_base = (char *) iovp->iov_base + r;
-	  iovp->iov_len -= r;
-	  r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
-	  if (r <= 0)
-	    break;
-	  ret += r;
-	}
-      while (ret < total);
-      if (r < 0)
-	ret = r;
-    }
-  return ret;
-}
-
-
 static int
 open_socket (void)
 {
@@ -139,36 +77,6 @@ __nscd_unmap (struct mapped_database *mapped)
 }
 
 
-static int
-wait_on_socket (int sock)
-{
-  struct pollfd fds[1];
-  fds[0].fd = sock;
-  fds[0].events = POLLIN | POLLERR | POLLHUP;
-  int n = __poll (fds, 1, 5 * 1000);
-  if (n == -1 && __builtin_expect (errno == EINTR, 0))
-    {
-      /* Handle the case where the poll() call is interrupted by a
-	 signal.  We cannot just use TEMP_FAILURE_RETRY since it might
-	 lead to infinite loops.  */
-      struct timeval now;
-      (void) __gettimeofday (&now, NULL);
-      long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000;
-      while (1)
-	{
-	  long int timeout = end - (now.tv_sec * 1000
-				    + (now.tv_usec + 500) / 1000);
-	  n = __poll (fds, 1, timeout);
-	  if (n != -1 || errno != EINTR)
-	    break;
-	  (void) __gettimeofday (&now, NULL);
-	}
-    }
-
-  return n;
-}
-
-
 /* Try to get a file descriptor for the shared meory segment
    containing the database.  */
 static struct mapped_database *
@@ -178,115 +86,102 @@ get_mapping (request_type type, const char *key,
   struct mapped_database *result = NO_MAPPING;
 #ifdef SCM_RIGHTS
   const size_t keylen = strlen (key) + 1;
+  char resdata[keylen];
   int saved_errno = errno;
 
   int mapfd = -1;
 
   /* Send the request.  */
-  struct
-  {
-    request_header req;
-    char key[keylen];
-  } reqdata;
-  size_t real_sizeof_reqdata = sizeof (request_header) + keylen;
+  struct iovec iov[2];
+  request_header req;
 
   int sock = open_socket ();
   if (sock < 0)
     goto out;
 
-  reqdata.req.version = NSCD_VERSION;
-  reqdata.req.type = type;
-  reqdata.req.key_len = keylen;
-  memcpy (reqdata.key, key, keylen);
-
-# ifndef MSG_NOSIGNAL
-#  define MSG_NOSIGNAL 0
-# endif
-  if (__builtin_expect (TEMP_FAILURE_RETRY (__send (sock, &reqdata,
-						    real_sizeof_reqdata,
-						    MSG_NOSIGNAL))
-			!= real_sizeof_reqdata, 0))
+  req.version = NSCD_VERSION;
+  req.type = type;
+  req.key_len = keylen;
+
+  iov[0].iov_base = &req;
+  iov[0].iov_len = sizeof (req);
+  iov[1].iov_base = (void *) key;
+  iov[1].iov_len = keylen;
+
+  if (TEMP_FAILURE_RETRY (__writev (sock, iov, 2))
+      != iov[0].iov_len + iov[1].iov_len)
     /* We cannot even write the request.  */
     goto out_close2;
 
   /* Room for the data sent along with the file descriptor.  We expect
      the key name back.  */
-# define resdata reqdata.key
-  struct iovec iov[1];
   iov[0].iov_base = resdata;
   iov[0].iov_len = keylen;
 
-  union
-  {
-    struct cmsghdr hdr;
-    char bytes[CMSG_SPACE (sizeof (int))];
-  } buf;
+  char buf[CMSG_SPACE (sizeof (int))];
   struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
-			.msg_control = buf.bytes,
-			.msg_controllen = sizeof (buf) };
+			.msg_control = buf, .msg_controllen = sizeof (buf) };
   struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
 
   cmsg->cmsg_level = SOL_SOCKET;
   cmsg->cmsg_type = SCM_RIGHTS;
   cmsg->cmsg_len = CMSG_LEN (sizeof (int));
 
-  /* This access is well-aligned since BUF is correctly aligned for an
-     int and CMSG_DATA preserves this alignment.  */
   *(int *) CMSG_DATA (cmsg) = -1;
 
   msg.msg_controllen = cmsg->cmsg_len;
 
-  if (wait_on_socket (sock) <= 0)
-    goto out_close2;
-
-  if (__builtin_expect (TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, 0))
-			!= keylen, 0))
+  struct pollfd fds[1];
+  fds[0].fd = sock;
+  fds[0].events = POLLIN | POLLERR | POLLHUP;
+  if (__poll (fds, 1, 5 * 1000) <= 0)
+    /* Failure or timeout.  */
     goto out_close2;
 
-  if (__builtin_expect (CMSG_FIRSTHDR (&msg) == NULL
-			|| (CMSG_FIRSTHDR (&msg)->cmsg_len
-			    != CMSG_LEN (sizeof (int))), 0))
+  if (TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, 0)) != keylen)
     goto out_close2;
 
   mapfd = *(int *) CMSG_DATA (cmsg);
 
+  if (CMSG_FIRSTHDR (&msg)->cmsg_len != CMSG_LEN (sizeof (int)))
+    goto out_close;
+
   struct stat64 st;
-  if (__builtin_expect (strcmp (resdata, key) != 0, 0)
-      || __builtin_expect (fstat64 (mapfd, &st) != 0, 0)
-      || __builtin_expect (st.st_size < sizeof (struct database_pers_head), 0))
+  if (strcmp (resdata, key) != 0
+      || fstat64 (mapfd, &st) != 0
+      || st.st_size < sizeof (struct database_pers_head))
     goto out_close;
 
   struct database_pers_head head;
-  if (__builtin_expect (TEMP_FAILURE_RETRY (__pread (mapfd, &head,
-						     sizeof (head), 0))
-			!= sizeof (head), 0))
+  if (TEMP_FAILURE_RETRY (__pread (mapfd, &head, sizeof (head), 0))
+      != sizeof (head))
     goto out_close;
 
-  if (__builtin_expect (head.version != DB_VERSION, 0)
-      || __builtin_expect (head.header_size != sizeof (head), 0)
+  if (head.version != DB_VERSION || head.header_size != sizeof (head)
       /* This really should not happen but who knows, maybe the update
 	 thread got stuck.  */
-      || __builtin_expect (! head.nscd_certainly_running
-			   && head.timestamp + MAPPING_TIMEOUT < time (NULL),
-			   0))
+      || (! head.nscd_certainly_running
+	  && head.timestamp + MAPPING_TIMEOUT < time (NULL)))
     goto out_close;
 
   size_t size = (sizeof (head) + roundup (head.module * sizeof (ref_t), ALIGN)
 		 + head.data_size);
 
-  if (__builtin_expect (st.st_size < size, 0))
+  if (st.st_size < size)
     goto out_close;
 
   /* The file is large enough, map it now.  */
   void *mapping = __mmap (NULL, size, PROT_READ, MAP_SHARED, mapfd, 0);
-  if (__builtin_expect (mapping != MAP_FAILED, 1))
+  if (mapping != MAP_FAILED)
     {
       /* Allocate a record for the mapping.  */
-      struct mapped_database *newp = malloc (sizeof (*newp));
+      struct mapped_database *newp;
+
+      newp = malloc (sizeof (*newp));
       if (newp == NULL)
 	{
 	  /* Ugh, after all we went through the memory allocation failed.  */
-	  __munmap (mapping, size);
+	  __munmap (result, size);
 	  goto out_close;
 	}
 
@@ -294,7 +189,6 @@ get_mapping (request_type type, const char *key,
       newp->data = ((char *) mapping + head.header_size
 		    + roundup (head.module * sizeof (ref_t), ALIGN));
       newp->mapsize = size;
-      newp->datasize = head.data_size;
       /* Set counter to 1 to show it is usable.  */
       newp->counter = 1;
 
@@ -321,18 +215,17 @@ get_mapping (request_type type, const char *key,
 
 struct mapped_database *
 __nscd_get_map_ref (request_type type, const char *name,
-		    volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
+		    struct locked_map_ptr *mapptr, int *gc_cyclep)
 {
   struct mapped_database *cur = mapptr->mapped;
   if (cur == NO_MAPPING)
     return cur;
 
   int cnt = 0;
-  while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
-								1, 0) != 0, 0))
+  while (atomic_compare_and_exchange_val_acq (&mapptr->lock, 1, 0) != 0)
     {
       // XXX Best number of rounds?
-      if (__builtin_expect (++cnt > 5, 0))
+      if (++cnt > 5)
 	return NO_MAPPING;
 
       atomic_delay ();
@@ -345,10 +238,8 @@ __nscd_get_map_ref (request_type type, const char *name,
       /* If not mapped or timestamp not updated, request new map.  */
       if (cur == NULL
 	  || (cur->head->nscd_certainly_running == 0
-	      && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL))
-	  || cur->head->data_size > cur->datasize)
-	cur = get_mapping (type, name,
-			   (struct mapped_database **) &mapptr->mapped);
+	      && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
+	cur = get_mapping (type, name, &mapptr->mapped);
 
       if (__builtin_expect (cur != NO_MAPPING, 1))
 	{
@@ -366,50 +257,28 @@ __nscd_get_map_ref (request_type type, const char *name,
 }
 
 
-/* Don't return const struct datahead *, as eventhough the record
-   is normally constant, it can change arbitrarily during nscd
-   garbage collection.  */
-struct datahead *
+const struct datahead *
 __nscd_cache_search (request_type type, const char *key, size_t keylen,
 		     const struct mapped_database *mapped)
 {
   unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
-  size_t datasize = mapped->datasize;
 
   ref_t work = mapped->head->array[hash];
-  while (work != ENDREF && work + sizeof (struct hashentry) <= datasize)
+  while (work != ENDREF)
     {
       struct hashentry *here = (struct hashentry *) (mapped->data + work);
 
-#ifndef _STRING_ARCH_unaligned
-      /* Although during garbage collection when moving struct hashentry
-	 records around we first copy from old to new location and then
-	 adjust pointer from previous hashentry to it, there is no barrier
-	 between those memory writes.  It is very unlikely to hit it,
-	 so check alignment only if a misaligned load can crash the
-	 application.  */
-      if ((uintptr_t) here & (__alignof__ (*here) - 1))
-	return NULL;
-#endif
-
-      if (type == here->type
-	  && keylen == here->len
-	  && here->key + keylen <= datasize
-	  && memcmp (key, mapped->data + here->key, keylen) == 0
-	  && here->packet + sizeof (struct datahead) <= datasize)
+      if (type == here->type && keylen == here->len
+	  && memcmp (key, mapped->data + here->key, keylen) == 0)
 	{
 	  /* We found the entry.  Increment the appropriate counter.  */
-	  struct datahead *dh
+	  const struct datahead *dh
 	    = (struct datahead *) (mapped->data + here->packet);
 
-#ifndef _STRING_ARCH_unaligned
-	  if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
-	    return NULL;
-#endif
-
 	  /* See whether we must ignore the entry or whether something
 	     is wrong because garbage collection is in progress.  */
-	  if (dh->usable && here->packet + dh->allocsize <= datasize)
+	  if (dh->usable && ((char *) dh + dh->allocsize
+			     <= (char *) mapped->head + mapped->mapsize))
 	    return dh;
 	}
 
@@ -442,13 +311,19 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type,
       vec[1].iov_len = keylen;
 
       ssize_t nbytes = TEMP_FAILURE_RETRY (__writev (sock, vec, 2));
-      if (nbytes == (ssize_t) (sizeof (request_header) + keylen)
-	  /* Wait for data.  */
-	  && wait_on_socket (sock) > 0)
+      if (nbytes == (ssize_t) (sizeof (request_header) + keylen))
 	{
-	  nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen));
-	  if (nbytes == (ssize_t) responselen)
-	    return sock;
+	  /* Wait for data.  */
+	  struct pollfd fds[1];
+	  fds[0].fd = sock;
+	  fds[0].events = POLLIN | POLLERR | POLLHUP;
+	  if (__poll (fds, 1, 5 * 1000) > 0)
+	    {
+	      nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
+						   responselen));
+	      if (nbytes == (ssize_t) responselen)
+		return sock;
+	    }
 	}
 
       close_not_cancel_no_status (sock);
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index 866455a96c..2ea9e7f862 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -30,7 +30,7 @@
 
 
 /* We use the same mapping as in nscd_getgr.   */
-libc_locked_map_ptr (extern, __gr_map_handle) attribute_hidden;
+libc_locked_map_ptr (extern, __gr_map_handle);
 
 
 int
@@ -39,7 +39,6 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
 {
   size_t userlen = strlen (user) + 1;
   int gc_cycle;
-  int nretries = 0;
 
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
@@ -47,49 +46,44 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
   mapped = __nscd_get_map_ref (GETFDGR, "group", &__gr_map_handle, &gc_cycle);
 
  retry:;
+  const initgr_response_header *initgr_resp = NULL;
   char *respdata = NULL;
   int retval = -1;
   int sock = -1;
-  initgr_response_header initgr_resp;
 
   if (mapped != NO_MAPPING)
     {
-      struct datahead *found = __nscd_cache_search (INITGROUPS, user,
-						    userlen, mapped);
+      const struct datahead *found = __nscd_cache_search (INITGROUPS, user,
+							  userlen, mapped);
       if (found != NULL)
 	{
-	  respdata = (char *) (&found->data[0].initgrdata + 1);
-	  initgr_resp = found->data[0].initgrdata;
+	  initgr_resp = &found->data[0].initgrdata;
+	  respdata = (char *) (initgr_resp + 1);
 	  char *recend = (char *) found->data + found->recsize;
 
-	  /* Now check if we can trust initgr_resp fields.  If GC is
-	     in progress, it can contain anything.  */
-	  if (mapped->head->gc_cycle != gc_cycle)
-	    {
-	      retval = -2;
-	      goto out;
-	    }
-
-	  if (respdata + initgr_resp.ngrps * sizeof (int32_t) > recend)
+	  if (respdata + initgr_resp->ngrps * sizeof (int32_t) > recend)
 	    goto out;
 	}
     }
 
   /* If we do not have the cache mapped, try to get the data over the
      socket.  */
-  if (respdata == NULL)
+  initgr_response_header initgr_resp_mem;
+  if (initgr_resp == NULL)
     {
-      sock = __nscd_open_socket (user, userlen, INITGROUPS, &initgr_resp,
-				 sizeof (initgr_resp));
+      sock = __nscd_open_socket (user, userlen, INITGROUPS, &initgr_resp_mem,
+				 sizeof (initgr_resp_mem));
       if (sock == -1)
 	{
-	  /* nscd not running or wrong version.  */
+	  /* nscd not running or wrong version or hosts caching disabled.  */
 	  __nss_not_use_nscd_group = 1;
 	  goto out;
 	}
+
+      initgr_resp = &initgr_resp_mem;
     }
 
-  if (initgr_resp.found == 1)
+  if (initgr_resp->found == 1)
     {
       /* The following code assumes that gid_t and int32_t are the
 	 same size.  This is the case for al existing implementation.
@@ -97,46 +91,40 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
 	 doesn't use memcpy but instead copies each array element one
 	 by one.  */
       assert (sizeof (int32_t) == sizeof (gid_t));
-      assert (initgr_resp.ngrps >= 0);
+      assert (initgr_resp->ngrps > 0);
 
       /* Make sure we have enough room.  We always count GROUP in even
 	 though we might not end up adding it.  */
-      if (*size < initgr_resp.ngrps + 1)
+      if (*size < initgr_resp->ngrps + 1)
 	{
 	  gid_t *newp = realloc (*groupsp,
-				 (initgr_resp.ngrps + 1) * sizeof (gid_t));
+				 (initgr_resp->ngrps + 1) * sizeof (gid_t));
 	  if (newp == NULL)
 	    /* We cannot increase the buffer size.  */
-	    goto out_close;
+	    goto out;
 
 	  *groupsp = newp;
-	  *size = initgr_resp.ngrps + 1;
+	  *size = initgr_resp->ngrps + 1;
 	}
 
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) __readall (sock, *groupsp, initgr_resp.ngrps
-						  * sizeof (gid_t))
-	      == initgr_resp.ngrps * sizeof (gid_t))
-	    retval = initgr_resp.ngrps;
+	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, *groupsp,
+						   initgr_resp->ngrps
+						   * sizeof (gid_t)))
+	      == initgr_resp->ngrps * sizeof (gid_t))
+	    retval = initgr_resp->ngrps;
 	}
       else
 	{
 	  /* Just copy the data.  */
-	  retval = initgr_resp.ngrps;
+	  retval = initgr_resp->ngrps;
 	  memcpy (*groupsp, respdata, retval * sizeof (gid_t));
 	}
     }
   else
     {
-      if (__builtin_expect (initgr_resp.found == -1, 0))
-	{
-	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_group = 1;
-	  goto out_close;
-	}
-
       /* No group found yet.   */
       retval = 0;
 
@@ -155,25 +143,22 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
 	(*groupsp)[retval++] = group;
     }
 
- out_close:
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
     {
       /* When we come here this means there has been a GC cycle while we
 	 were looking for the data.  This means the data might have been
 	 inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
+      if ((gc_cycle & 1) != 0)
 	{
 	  /* nscd is just running gc now.  Disable using the mapping.  */
-	  if (atomic_decrement_val (&mapped->counter) == 0)
-	    __nscd_unmap (mapped);
+	  __nscd_unmap (mapped);
 	  mapped = NO_MAPPING;
 	}
 
-      if (retval != -1)
-	goto retry;
+      goto retry;
     }
 
   return retval;
diff --git a/nscd/nscd_nischeck.c b/nscd/nscd_nischeck.c
new file mode 100644
index 0000000000..a6817cf79e
--- /dev/null
+++ b/nscd/nscd_nischeck.c
@@ -0,0 +1,96 @@
+/* Copyright (c) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* nscd_nischeck: Check, if everybody has read permissions for NIS+ table.
+   Return value:
+    0: Everybody can read the NIS+ table
+    1: Only authenticated users could read the NIS+ table */
+
+#include <argp.h>
+#include <error.h>
+#include <stdlib.h>
+#include <libintl.h>
+#include <locale.h>
+#include <rpcsvc/nis.h>
+
+/* Get libc version number.  */
+#include <version.h>
+
+#define PACKAGE _libc_intl_domainname
+
+/* Name and version of program.  */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  NULL, NULL, NULL, NULL,
+};
+
+int
+main (int argc, char **argv)
+{
+  int remaining;
+  nis_result *res;
+  char *tablename, *cp;
+
+  /* Set locale via LC_ALL.  */
+  setlocale (LC_ALL, "");
+  /* Set the text message domain.  */
+  textdomain (PACKAGE);
+
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  if (remaining + 1 != argc)
+    {
+      error (0, 0, gettext ("wrong number of arguments"));
+      argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
+      exit (EXIT_FAILURE);
+    }
+
+  tablename = alloca (strlen (argv[1]) + 10);
+  cp = stpcpy (tablename, argv[1]);
+  strcpy (cp, ".org_dir");
+
+  res = nis_lookup (tablename, EXPAND_NAME|FOLLOW_LINKS);
+
+  if (res == NULL ||
+      (res->status != NIS_SUCCESS && res->status != NIS_S_SUCCESS))
+    return 0;
+
+  if (NIS_NOBODY(NIS_RES_OBJECT(res)->zo_access, NIS_READ_ACC))
+    return 0;
+  else
+    return 1;
+}
+
+/* Print the version information.  */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "nscd_nischeck (GNU %s) %s\n", PACKAGE, VERSION);
+  fprintf (stream, gettext ("\
+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\
+"), "2004");
+  fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
+}
diff --git a/nscd/nscd_setup_thread.c b/nscd/nscd_setup_thread.c
deleted file mode 100644
index 32bfe07000..0000000000
--- a/nscd/nscd_setup_thread.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Setup of nscd worker threads.  Stub verison.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include <nscd.h>
-
-
-void
-setup_thread (struct database_dyn *db)
-{
-  /* Nothing.  */
-}
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
index 7f6bd1c83e..9231642278 100644
--- a/nscd/nscd_stat.c
+++ b/nscd/nscd_stat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
 
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/socket.h>
 #include <unistd.h>
 #include <libintl.h>
 
@@ -76,10 +75,6 @@ struct statdata
   int debug_level;
   time_t runtime;
   unsigned long int client_queued;
-  int nthreads;
-  int max_nthreads;
-  int paranoia;
-  time_t restart_interval;
   int ndbs;
   struct dbstat dbs[lastdb];
 #ifdef HAVE_SELINUX
@@ -98,10 +93,6 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
   data.debug_level = debug_level;
   data.runtime = time (NULL) - start_time;
   data.client_queued = client_queued;
-  data.nthreads = nthreads;
-  data.max_nthreads = max_nthreads;
-  data.paranoia = paranoia;
-  data.restart_interval = restart_interval;
   data.ndbs = lastdb;
 
   for (cnt = 0; cnt < lastdb; ++cnt)
@@ -134,8 +125,7 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
   if (selinux_enabled)
     nscd_avc_cache_stats (&data.cstats);
 
-  if (TEMP_FAILURE_RETRY (send (fd, &data, sizeof (data), MSG_NOSIGNAL))
-      != sizeof (data))
+  if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
     {
       char buf[256];
       dbg_log (_("cannot write statistics: %s"),
@@ -153,8 +143,8 @@ receive_print_stats (void)
   int fd;
   int i;
   uid_t uid = getuid ();
-  const char *yesstr = _("yes");
-  const char *nostr = _("no");
+  const char *yesstr = nl_langinfo (YESSTR);
+  const char *nostr = nl_langinfo (NOSTR);
 
   /* Find out whether there is another user but root allowed to
      request statistics.  */
@@ -182,8 +172,7 @@ receive_print_stats (void)
   req.version = NSCD_VERSION;
   req.type = GETSTAT;
   req.key_len = 0;
-  nbytes = TEMP_FAILURE_RETRY (send (fd, &req, sizeof (request_header),
-				     MSG_NOSIGNAL));
+  nbytes = TEMP_FAILURE_RETRY (write (fd, &req, sizeof (request_header)));
   if (nbytes != sizeof (request_header))
     {
       int err = errno;
@@ -241,9 +230,8 @@ receive_print_stats (void)
 	    "%15lu  number of times clients had to wait\n"
 	    "%15s  paranoia mode enabled\n"
 	    "%15lu  restart internal\n"),
-	  data.nthreads, data.max_nthreads, data.client_queued,
-	  data.paranoia ? yesstr : nostr,
-	  (unsigned long int) data.restart_interval);
+	  nthreads, max_nthreads, data.client_queued,
+	  paranoia ? yesstr : nostr, (unsigned long int) restart_interval);
 
   for (i = 0; i < lastdb; ++i)
     {
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index ae579df510..e8b9578778 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -1,20 +1,22 @@
 /* Cache handling for passwd lookup.
-   Copyright (C) 1998-2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #include <alloca.h>
 #include <assert.h>
@@ -30,14 +32,10 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
-#include <sys/socket.h>
 #include <stackinfo.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 =
@@ -116,8 +114,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
@@ -274,7 +271,6 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 		{
 		  /* Adjust pointer into the memory block.  */
 		  cp = (char *) newp + (cp - (char *) dataset);
-		  key_copy = (char *) newp + (key_copy - (char *) dataset);
 
 		  dataset = memcpy (newp, dataset, total + n);
 		  alloca_used = false;
@@ -291,30 +287,7 @@ 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->resp - (char *) db->head
-		      + total
-		      <= (sizeof (struct database_pers_head)
-                          + db->head->module * sizeof (ref_t)
-                          + db->head->data_size));
-	      written = sendfileall (fd, db->wr_fd,
-				     (char *) &dataset->resp
-				     - (char *) db->head, total);
-# ifndef __ASSUME_SENDFILE
-	      if (written == -1 && errno == ENOSYS)
-		goto use_write;
-# endif
-	    }
-	  else
-# ifndef __ASSUME_SENDFILE
-	  use_write:
-# endif
-#endif
-	    written = writeall (fd, &dataset->resp, total);
+	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
 	}
 
 
@@ -339,10 +312,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	     marked with FIRST first.  Otherwise we end up with
 	     dangling "pointers" in case a latter hash entry cannot be
 	     added.  */
-	  bool first = true;
+	  bool first = req->type == GETPWBYNAME;
 
 	  /* If the request was by UID, add that entry first.  */
-	  if (req->type == GETPWBYUID)
+	  if (req->type != GETPWBYNAME)
 	    {
 	      if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true,
 			     db, owner) < 0)
@@ -352,14 +325,12 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 		  dataset->head.usable = false;
 		  goto out;
 		}
-
-	      first = false;
 	    }
 	  /* If the key is different from the name add a separate entry.  */
 	  else if (strcmp (key_copy, dataset->strdata) != 0)
 	    {
 	      if (cache_add (GETPWBYNAME, key_copy, key_len + 1,
-			     &dataset->head, true, db, owner) < 0)
+			     &dataset->head, first, db, owner) < 0)
 		{
 		  /* Could not allocate memory.  Make sure the data gets
 		     discarded.  */
@@ -371,12 +342,11 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	    }
 
 	  /* We have to add the value for both, byname and byuid.  */
-	  if ((req->type == GETPWBYNAME || db->propagate)
-	      && __builtin_expect (cache_add (GETPWBYNAME, dataset->strdata,
-					      pw_name_len, &dataset->head,
-					      first, db, owner) == 0, 1))
+	  if (__builtin_expect (cache_add (GETPWBYNAME, dataset->strdata,
+					   pw_name_len, &dataset->head, first,
+					   db, owner) == 0, 1))
 	    {
-	      if (req->type == GETPWBYNAME && db->propagate)
+	      if (req->type == GETPWBYNAME)
 		(void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head,
 				  req->type != GETPWBYNAME, db, owner);
 	    }
@@ -455,10 +425,11 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
+#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen *= 2;
+	  buflen += INCR;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -479,7 +450,7 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
       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);
+	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
     }
 
 #if 0
diff --git a/nscd/selinux.c b/nscd/selinux.c
index b826031150..f57f0920ae 100644
--- a/nscd/selinux.c
+++ b/nscd/selinux.c
@@ -1,5 +1,5 @@
 /* SELinux access controls for nscd.
-   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
 
@@ -18,7 +18,6 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include "config.h"
 #include <error.h>
 #include <errno.h>
 #include <libintl.h>
@@ -27,15 +26,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <syslog.h>
-#include <unistd.h>
-#include <sys/prctl.h>
 #include <selinux/av_permissions.h>
 #include <selinux/avc.h>
 #include <selinux/flask.h>
 #include <selinux/selinux.h>
-#ifdef HAVE_LIBAUDIT
-# include <libaudit.h>
-#endif
 
 #include "dbg_log.h"
 #include "selinux.h"
@@ -72,11 +66,6 @@ static struct avc_entry_ref aeref;
 /* Thread to listen for SELinux status changes via netlink.  */
 static pthread_t avc_notify_thread;
 
-#ifdef HAVE_LIBAUDIT
-/* Prototype for supporting the audit daemon */
-static void log_callback (const char *fmt, ...);
-#endif
-
 /* Prototypes for AVC callback functions.  */
 static void *avc_create_thread (void (*run) (void));
 static void avc_stop_thread (void *thread);
@@ -88,11 +77,7 @@ static void avc_free_lock (void *lock);
 /* AVC callback structures for use in avc_init.  */
 static const struct avc_log_callback log_cb =
 {
-#ifdef HAVE_LIBAUDIT
-  .func_log = log_callback,
-#else
   .func_log = dbg_log,
-#endif
   .func_audit = NULL
 };
 static const struct avc_thread_callback thread_cb =
@@ -108,137 +93,6 @@ static const struct avc_lock_callback lock_cb =
   .func_free_lock = avc_free_lock
 };
 
-#ifdef HAVE_LIBAUDIT
-/* The audit system's netlink socket descriptor */
-static int audit_fd = -1;
-
-/* When an avc denial occurs, log it to audit system */
-static void
-log_callback (const char *fmt, ...)
-{
-  if (audit_fd >= 0)
-    {
-      va_list ap;
-      va_start (ap, fmt);
-
-      char *buf;
-      int e = vasprintf (&buf, fmt, ap);
-      if (e < 0)
-	{
-	  buf = alloca (BUFSIZ);
-	  vsnprintf (buf, BUFSIZ, fmt, ap);
-	}
-
-      /* FIXME: need to attribute this to real user, using getuid for now */
-      audit_log_user_avc_message (audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
-				  NULL, getuid ());
-
-      if (e >= 0)
-	free (buf);
-
-      va_end (ap);
-    }
-}
-
-/* Initialize the connection to the audit system */
-static void
-audit_init (void)
-{
-  audit_fd = audit_open ();
-  if (audit_fd < 0
-      /* If kernel doesn't support audit, bail out */
-      && errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
-    dbg_log (_("Failed opening connection to the audit subsystem: %m"));
-}
-
-
-# ifdef HAVE_LIBCAP
-static const cap_value_t new_cap_list[] =
-  { CAP_AUDIT_WRITE };
-#  define nnew_cap_list (sizeof (new_cap_list) / sizeof (new_cap_list[0]))
-static const cap_value_t tmp_cap_list[] =
-  { CAP_AUDIT_WRITE, CAP_SETUID, CAP_SETGID };
-#  define ntmp_cap_list (sizeof (tmp_cap_list) / sizeof (tmp_cap_list[0]))
-
-cap_t
-preserve_capabilities (void)
-{
-  if (getuid () != 0)
-    /* Not root, then we cannot preserve anything.  */
-    return NULL;
-
-  if (prctl (PR_SET_KEEPCAPS, 1) == -1)
-    {
-      dbg_log (_("Failed to set keep-capabilities"));
-      error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
-      /* NOTREACHED */
-    }
-
-  cap_t tmp_caps = cap_init ();
-  cap_t new_caps;
-  if (tmp_caps != NULL)
-    new_caps = cap_init ();
-
-  if (tmp_caps == NULL || new_caps == NULL)
-    {
-      if (tmp_caps != NULL)
-	cap_free (tmp_caps);
-
-      dbg_log (_("Failed to initialize drop of capabilities"));
-      error (EXIT_FAILURE, 0, _("cap_init failed"));
-    }
-
-  /* There is no reason why these should not work.  */
-  cap_set_flag (new_caps, CAP_PERMITTED, nnew_cap_list,
-		(cap_value_t *) new_cap_list, CAP_SET);
-  cap_set_flag (new_caps, CAP_EFFECTIVE, nnew_cap_list,
-		(cap_value_t *) new_cap_list, CAP_SET);
-
-  cap_set_flag (tmp_caps, CAP_PERMITTED, ntmp_cap_list,
-		(cap_value_t *) tmp_cap_list, CAP_SET);
-  cap_set_flag (tmp_caps, CAP_EFFECTIVE, ntmp_cap_list,
-		(cap_value_t *) tmp_cap_list, CAP_SET);
-
-  int res = cap_set_proc (tmp_caps);
-
-  cap_free (tmp_caps);
-
-  if (__builtin_expect (res != 0, 0))
-    {
-      cap_free (new_caps);
-      dbg_log (_("Failed to drop capabilities\n"));
-      error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
-    }
-
-  return new_caps;
-}
-
-void
-install_real_capabilities (cap_t new_caps)
-{
-  /* If we have no capabilities there is nothing to do here.  */
-  if (new_caps == NULL)
-    return;
-
-  if (cap_set_proc (new_caps))
-    {
-      cap_free (new_caps);
-      dbg_log (_("Failed to drop capabilities"));
-      error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
-      /* NOTREACHED */
-    }
-
-  cap_free (new_caps);
-
-  if (prctl (PR_SET_KEEPCAPS, 0) == -1)
-    {
-      dbg_log (_("Failed to unset keep-capabilities"));
-      error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
-      /* NOTREACHED */
-    }
-}
-# endif /* HAVE_LIBCAP */
-#endif /* HAVE_LIBAUDIT */
 
 /* Determine if we are running on an SELinux kernel. Set selinux_enabled
    to the result.  */
@@ -328,9 +182,6 @@ nscd_avc_init (void)
     error (EXIT_FAILURE, errno, _("Failed to start AVC"));
   else
     dbg_log (_("Access Vector Cache (AVC) started"));
-#ifdef HAVE_LIBAUDIT
-  audit_init ();
-#endif
 }
 
 
@@ -411,9 +262,6 @@ void
 nscd_avc_destroy (void)
 {
   avc_destroy ();
-#ifdef HAVE_LIBAUDIT
-  audit_close (audit_fd);
-#endif
 }
 
 #endif /* HAVE_SELINUX */
diff --git a/nscd/selinux.h b/nscd/selinux.h
index 27afcd6e86..b9eb053aa0 100644
--- a/nscd/selinux.h
+++ b/nscd/selinux.h
@@ -1,5 +1,5 @@
 /* Header for nscd SELinux access controls.
-   Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Matthew Rickard <mjricka@epoch.ncsc.mil>, 2004.
 
@@ -22,9 +22,6 @@
 #define _SELINUX_H 1
 
 #include "nscd.h"
-#ifdef HAVE_LIBCAP
-# include <sys/capability.h>
-#endif
 
 #ifdef HAVE_SELINUX
 /* Global variable to tell if the kernel has SELinux support.  */
@@ -45,13 +42,6 @@ extern int nscd_request_avc_has_perm (int fd, request_type req);
 extern void nscd_avc_cache_stats (struct avc_cache_stats *cstats);
 /* Display statistics on AVC usage.  */
 extern void nscd_avc_print_stats (struct avc_cache_stats *cstats);
-
-# ifdef HAVE_LIBCAP
-/* Preserve capabilities to connect to connnect to the audit daemon.  */
-extern cap_t preserve_capabilities (void);
-/* Install final capabilities.  */
-extern void install_real_capabilities (cap_t new_caps);
-# endif
 #else
 # define selinux_enabled 0
 # define nscd_avc_init() (void) 0