aboutsummaryrefslogtreecommitdiff
path: root/nscd
diff options
context:
space:
mode:
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