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.
This commit is contained in:
Siddhesh Poyarekar 2014-01-02 10:05:27 +05:30
parent d41242129b
commit 9a3c6a6ff6
3 changed files with 67 additions and 30 deletions

View File

@ -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.

2
NEWS
View File

@ -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.

View File

@ -65,44 +65,21 @@ struct dataset
char strdata[0];
};
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
struct datahead *dh, struct dataset **resultp)
/* 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)
{
if (__builtin_expect (debug_level > 0, 0))
{
if (he == NULL)
dbg_log (_("Haven't found \"%s\" in netgroup cache!"), key);
else
dbg_log (_("Reloading \"%s\" in netgroup cache!"), key);
}
static service_user *netgroup_database;
time_t timeout;
struct dataset *dataset;
bool cacheable = false;
ssize_t total;
time_t timeout;
bool cacheable = false;
char *key_copy = NULL;
struct __netgrent data;
size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
size_t buffilled = sizeof (*dataset);
char *buffer = NULL;
size_t nentries = 0;
bool use_malloc = false;
size_t group_len = strlen (key) + 1;
union
{
struct name_list elem;
char mem[sizeof (struct name_list) + group_len];
} first_needed;
if (netgroup_database == NULL
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
total = sizeof (notfound);
timeout = time (NULL) + db->negtimeout;
@ -128,10 +105,56 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
/* 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,
const char *key, uid_t uid, struct hashentry *he,
struct datahead *dh, struct dataset **resultp)
{
if (__builtin_expect (debug_level > 0, 0))
{
if (he == NULL)
dbg_log (_("Haven't found \"%s\" in netgroup cache!"), key);
else
dbg_log (_("Reloading \"%s\" in netgroup cache!"), key);
}
static service_user *netgroup_database;
time_t timeout;
struct dataset *dataset;
bool cacheable = false;
ssize_t total;
bool found = false;
char *key_copy = NULL;
struct __netgrent data;
size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
size_t buffilled = sizeof (*dataset);
char *buffer = NULL;
size_t nentries = 0;
bool use_malloc = false;
size_t group_len = strlen (key) + 1;
union
{
struct name_list elem;
char mem[sizeof (struct name_list) + group_len];
} first_needed;
if (netgroup_database == NULL
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
&key_copy);
goto writeout;
}
@ -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,
@ -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. */