summaryrefslogtreecommitdiff
path: root/nscd/pwdcache.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 15:49:30 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 15:49:30 +0000
commite14d51045326808a48d43d7e0b45860cd33e2b17 (patch)
tree90b47e500bf7b1ccffae92fc2105cea5b8b7b61f /nscd/pwdcache.c
parentc949e9c224c0fc890982cc42797ae868b04faa00 (diff)
parent963c37d5c0eb62b38f8764b23931c0dcdd497a13 (diff)
Merge commit 'refs/top-bases/t/context_functions' into t/context_functions
Diffstat (limited to 'nscd/pwdcache.c')
-rw-r--r--nscd/pwdcache.c112
1 files changed, 36 insertions, 76 deletions
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 6dd6746f39..b08cfd7870 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -1,5 +1,5 @@
/* Cache handling for passwd lookup.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -16,7 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
-#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
@@ -32,12 +31,10 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <stackinfo.h>
+#include <scratch_buffer.h>
#include "nscd.h"
#include "dbg_log.h"
-#ifdef HAVE_SENDFILE
-# include <kernel-features.h>
-#endif
/* This is the standard reply in case the service is disabled. */
static const pw_response_header disabled =
@@ -198,10 +195,19 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
dataset = NULL;
if (he == NULL)
- dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ {
+ /* Prevent an INVALIDATE request from pruning the data between
+ the two calls to cache_add. */
+ if (db->propagate)
+ pthread_mutex_lock (&db->prune_run_lock);
+ dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+ }
if (dataset == NULL)
{
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
+
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
@@ -287,37 +293,9 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head
- + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
- ssize_t written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head,
- dataset->head.recsize);
- if (written != dataset->head.recsize)
- {
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- all_written = false;
- }
- }
- else
-# ifndef __ASSUME_SENDFILE
- use_write:
-# endif
-#endif
- if (writeall (fd, &dataset->resp, dataset->head.recsize)
- != dataset->head.recsize)
- all_written = false;
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
@@ -374,6 +352,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
out:
pthread_rwlock_unlock (&db->lock);
+ if (he == NULL && db->propagate)
+ pthread_mutex_unlock (&db->prune_run_lock);
}
}
@@ -415,60 +395,40 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
look again in the table whether the dataset is now available. We
simply insert it. It does not matter if it is in there twice. The
pruning function only will look at the timestamp. */
- size_t buflen = 1024;
- char *buffer = (char *) alloca (buflen);
struct passwd resultbuf;
struct passwd *pwd;
- bool use_malloc = false;
int errval = 0;
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
if (__glibc_unlikely (debug_level > 0))
{
if (he == NULL)
- dbg_log (_("Haven't found \"%s\" in password cache!"), keystr);
+ dbg_log (_("Haven't found \"%s\" in user database cache!"), keystr);
else
- dbg_log (_("Reloading \"%s\" in password cache!"), keystr);
+ dbg_log (_("Reloading \"%s\" in user database cache!"), keystr);
}
- while (lookup (req->type, key, &resultbuf, buffer, buflen, &pwd) != 0
+ while (lookup (req->type, key, &resultbuf,
+ tmpbuf.data, tmpbuf.length, &pwd) != 0
&& (errval = errno) == ERANGE)
- {
- errno = 0;
-
- if (__glibc_unlikely (buflen > 32768))
- {
- char *old_buffer = buffer;
- buflen *= 2;
- buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
- if (buffer == NULL)
- {
- /* We ran out of memory. We cannot do anything but
- sending a negative response. In reality this should
- never happen. */
- pwd = NULL;
- buffer = old_buffer;
-
- /* We set the error to indicate this is (possibly) a
- temporary error and that it does not mean the entry
- is not available at all. */
- errval = EAGAIN;
- break;
- }
- use_malloc = true;
- }
- else
- /* Allocate a new buffer on the stack. If possible combine it
- with the previously allocated buffer. */
- buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
- }
+ if (!scratch_buffer_grow (&tmpbuf))
+ {
+ /* We ran out of memory. We cannot do anything but sending a
+ negative response. In reality this should never
+ happen. */
+ pwd = NULL;
+ /* We set the error to indicate this is (possibly) a temporary
+ error and that it does not mean the entry is not available
+ at all. */
+ errval = EAGAIN;
+ break;
+ }
/* Add the entry to the cache. */
time_t timeout = cache_addpw (db, fd, req, keystr, pwd, c_uid, he, dh,
errval);
-
- if (use_malloc)
- free (buffer);
-
+ scratch_buffer_free (&tmpbuf);
return timeout;
}