Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix return code from getent netgroup when the netgroup is not found (…
…bz #16366)

nscd incorrectly returns a success even when the netgroup in question
is not found and adds a positive result in the cache.  this patch
fixes this behaviour by adding a negative lookup entry to cache and
returning an error when the netgroup is not found.
  • Loading branch information
Siddhesh Poyarekar committed Jan 2, 2014
1 parent d412421 commit 9a3c6a6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 30 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
@@ -1,5 +1,9 @@
2013-01-02 Siddhesh Poyarekar <siddhesh@redhat.com>

[BZ #16366]
* nscd/netgroupcache.c (do_notfound): New function.
(addgetnetgrentX): Use it.

[BZ # 16365]
* nscd/netgroupcache.c (addgetnetgrentX): Break if status is
NSS_STATUS_NOTFOUND.
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Expand Up @@ -23,7 +23,7 @@ Version 2.19
16038, 16041, 16055, 16071, 16072, 16074, 16077, 16078, 16103, 16112,
16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195, 16214,
16245, 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337,
16338, 16356, 16365, 16369, 16372, 16375, 16379.
16338, 16356, 16365, 16366, 16369, 16372, 16375, 16379.

* Slovenian translations for glibc messages have been contributed by the
Translation Project's Slovenian team of translators.
Expand Down
91 changes: 62 additions & 29 deletions nscd/netgroupcache.c
Expand Up @@ -65,6 +65,55 @@ struct dataset
char strdata[0];
};

/* Sends a notfound message and prepares a notfound dataset to write to the
cache. Returns true if there was enough memory to allocate the dataset and
returns the dataset in DATASETP, total bytes to write in TOTALP and the
timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the
dataset. */
static bool
do_notfound (struct database_dyn *db, int fd, request_header *req,
const char *key, struct dataset **datasetp, ssize_t *totalp,
time_t *timeoutp, char **key_copy)
{
struct dataset *dataset;
ssize_t total;
time_t timeout;
bool cacheable = false;

total = sizeof (notfound);
timeout = time (NULL) + db->negtimeout;

if (fd != -1)
TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));

dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
/* If we cannot permanently store the result, so be it. */
if (dataset != NULL)
{
dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
dataset->head.recsize = total;
dataset->head.notfound = true;
dataset->head.nreloads = 0;
dataset->head.usable = true;

/* Compute the timeout time. */
timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
dataset->head.ttl = db->negtimeout;

/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);

/* Copy the key data. */
memcpy (dataset->strdata, key, req->key_len);
*key_copy = dataset->strdata;

cacheable = true;
}
*timeoutp = timeout;
*totalp = total;
*datasetp = dataset;
return cacheable;
}

static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
Expand All @@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
struct dataset *dataset;
bool cacheable = false;
ssize_t total;
bool found = false;

char *key_copy = NULL;
struct __netgrent data;
Expand All @@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
total = sizeof (notfound);
timeout = time (NULL) + db->negtimeout;

if (fd != -1)
TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));

dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
/* If we cannot permanently store the result, so be it. */
if (dataset != NULL)
{
dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
dataset->head.recsize = total;
dataset->head.notfound = true;
dataset->head.nreloads = 0;
dataset->head.usable = true;

/* Compute the timeout time. */
timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
dataset->head.ttl = db->negtimeout;

/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);

/* Copy the key data. */
memcpy (dataset->strdata, key, req->key_len);

cacheable = true;
}

cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
&key_copy);
goto writeout;
}

Expand Down Expand Up @@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,

if (status == NSS_STATUS_SUCCESS)
{
found = true;
union
{
enum nss_status (*f) (struct __netgrent *, char *, size_t,
Expand Down Expand Up @@ -326,6 +350,15 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
}

/* No results. Return a failure and write out a notfound record in the
cache. */
if (!found)
{
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
&key_copy);
goto writeout;
}

total = buffilled;

/* Fill in the dataset. */
Expand Down

0 comments on commit 9a3c6a6

Please sign in to comment.