]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/glibc/glibc-rh1039988.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh1039988.patch
1 commit 9a3c6a6ff602c88d7155139a7d7d0000b7b7e946
2 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3 Date: Thu Jan 2 10:05:27 2014 +0530
4
5 Fix return code from getent netgroup when the netgroup is not found (bz #16366)
6
7 nscd incorrectly returns a success even when the netgroup in question
8 is not found and adds a positive result in the cache. this patch
9 fixes this behaviour by adding a negative lookup entry to cache and
10 returning an error when the netgroup is not found.
11
12 diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
13 index 50936ee..9fc1664 100644
14 --- a/nscd/netgroupcache.c
15 +++ b/nscd/netgroupcache.c
16 @@ -65,6 +65,55 @@ struct dataset
17 char strdata[0];
18 };
19
20 +/* Sends a notfound message and prepares a notfound dataset to write to the
21 + cache. Returns true if there was enough memory to allocate the dataset and
22 + returns the dataset in DATASETP, total bytes to write in TOTALP and the
23 + timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the
24 + dataset. */
25 +static bool
26 +do_notfound (struct database_dyn *db, int fd, request_header *req,
27 + const char *key, struct dataset **datasetp, ssize_t *totalp,
28 + time_t *timeoutp, char **key_copy)
29 +{
30 + struct dataset *dataset;
31 + ssize_t total;
32 + time_t timeout;
33 + bool cacheable = false;
34 +
35 + total = sizeof (notfound);
36 + timeout = time (NULL) + db->negtimeout;
37 +
38 + if (fd != -1)
39 + TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
40 +
41 + dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
42 + /* If we cannot permanently store the result, so be it. */
43 + if (dataset != NULL)
44 + {
45 + dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
46 + dataset->head.recsize = total;
47 + dataset->head.notfound = true;
48 + dataset->head.nreloads = 0;
49 + dataset->head.usable = true;
50 +
51 + /* Compute the timeout time. */
52 + timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
53 + dataset->head.ttl = db->negtimeout;
54 +
55 + /* This is the reply. */
56 + memcpy (&dataset->resp, &notfound, total);
57 +
58 + /* Copy the key data. */
59 + memcpy (dataset->strdata, key, req->key_len);
60 + *key_copy = dataset->strdata;
61 +
62 + cacheable = true;
63 + }
64 + *timeoutp = timeout;
65 + *totalp = total;
66 + *datasetp = dataset;
67 + return cacheable;
68 +}
69
70 static time_t
71 addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
72 @@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
73 struct dataset *dataset;
74 bool cacheable = false;
75 ssize_t total;
76 + bool found = false;
77
78 char *key_copy = NULL;
79 struct __netgrent data;
80 @@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
81 && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
82 {
83 /* No such service. */
84 - total = sizeof (notfound);
85 - timeout = time (NULL) + db->negtimeout;
86 -
87 - if (fd != -1)
88 - TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
89 -
90 - dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
91 - /* If we cannot permanently store the result, so be it. */
92 - if (dataset != NULL)
93 - {
94 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
95 - dataset->head.recsize = total;
96 - dataset->head.notfound = true;
97 - dataset->head.nreloads = 0;
98 - dataset->head.usable = true;
99 -
100 - /* Compute the timeout time. */
101 - timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
102 - dataset->head.ttl = db->negtimeout;
103 -
104 - /* This is the reply. */
105 - memcpy (&dataset->resp, &notfound, total);
106 -
107 - /* Copy the key data. */
108 - memcpy (dataset->strdata, key, req->key_len);
109 -
110 - cacheable = true;
111 - }
112 -
113 + cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
114 + &key_copy);
115 goto writeout;
116 }
117
118 @@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
119
120 if (status == NSS_STATUS_SUCCESS)
121 {
122 + found = true;
123 union
124 {
125 enum nss_status (*f) (struct __netgrent *, char *, size_t,
126 @@ -326,6 +350,15 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
127 }
128 }
129
130 + /* No results. Return a failure and write out a notfound record in the
131 + cache. */
132 + if (!found)
133 + {
134 + cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
135 + &key_copy);
136 + goto writeout;
137 + }
138 +
139 total = buffilled;
140
141 /* Fill in the dataset. */