]>
Commit | Line | Data |
---|---|---|
12788f63 MT |
1 | 2011-11-07 Andreas Schwab <schwab@redhat.com> |
2 | ||
3 | * nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): | |
4 | Fix size of allocated buffer. | |
5 | ||
6 | 2011-05-10 Ulrich Drepper <drepper@gmail.com> | |
7 | ||
8 | [BZ #11257] | |
9 | * grp/initgroups.c (internal_getgrouplist): When we found the service | |
10 | list through the initgroups entry in nsswitch.conf do not always | |
11 | continue on a successful lookup. Don't always use the | |
12 | __nss_group_data-ase value if it is set. | |
13 | * nss/nsswitch.conf (initgroups): Change action for successful db | |
14 | lookup to continue for compatibility. | |
15 | ||
16 | 2011-05-06 Ulrich Drepper <drepper@gmail.com> | |
17 | ||
18 | * nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Return | |
19 | NSS_STATUS_NOTFOUND if no record was found. | |
20 | ||
21 | 2011-04-29 Ulrich Drepper <drepper@gmail.com> | |
22 | ||
23 | * grp/initgroups.c (internal_getgrouplist): Prefer initgroups setting | |
24 | to groups setting in database lookup. | |
25 | * nss/nsswitch.conf: Add initgroups entry. | |
26 | ||
27 | 2011-04-21 Ulrich Drepper <drepper@gmail.com> | |
28 | ||
29 | * nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Fix | |
30 | problem in reallocation in last patch. | |
31 | ||
32 | 2011-04-19 Ulrich Drepper <drepper@gmail.com> | |
33 | ||
34 | * nss/nss_files/files-initgroups.c: New file. | |
35 | * nss/Makefile (libnss_files-routines): Add files-initgroups. | |
36 | * nss/Versions (libnss_files) [GLIBC_PRIVATE]: Export | |
37 | _nss_files_initgroups_dyn. | |
38 | ||
39 | 2011-01-13 Ulrich Drepper <drepper@gmail.com> | |
40 | ||
41 | [BZ #10484] | |
42 | * nss/nss_files/files-hosts.c (HOST_DB_LOOKUP): Handle overflows of | |
43 | temporary buffer used to handle multi lookups locally. | |
44 | * include/alloca.h: Add libc_hidden_proto for __libc_alloca_cutoff. | |
45 | ||
46 | 2011-01-13 Ulrich Drepper <drepper@gmail.com> | |
47 | ||
48 | [BZ #10484] | |
49 | * Versions [libc] (GLIBC_PRIVATE): Export __libc_alloca_cutoff. | |
50 | * alloca_cutoff.c: Add libc_hidden_def. | |
51 | ||
52 | Index: glibc-2.12-2-gc4ccff1/grp/initgroups.c | |
53 | =================================================================== | |
54 | --- glibc-2.12-2-gc4ccff1.orig/grp/initgroups.c | |
55 | +++ glibc-2.12-2-gc4ccff1/grp/initgroups.c | |
56 | @@ -43,6 +43,8 @@ extern int __nss_group_lookup (service_u | |
57 | extern void *__nss_lookup_function (service_user *ni, const char *fct_name); | |
58 | ||
59 | extern service_user *__nss_group_database attribute_hidden; | |
60 | +static service_user *initgroups_database; | |
61 | +static bool use_initgroups_entry; | |
62 | ||
63 | ||
64 | #include "compat-initgroups.c" | |
65 | @@ -67,32 +69,41 @@ internal_getgrouplist (const char *user, | |
66 | } | |
67 | #endif | |
68 | ||
69 | - service_user *nip = NULL; | |
70 | - initgroups_dyn_function fct; | |
71 | enum nss_status status = NSS_STATUS_UNAVAIL; | |
72 | - int no_more; | |
73 | - /* Start is one, because we have the first group as parameter. */ | |
74 | - long int start = 1; | |
75 | + int no_more = 0; | |
76 | ||
77 | /* Never store more than the starting *SIZE number of elements. */ | |
78 | assert (*size > 0); | |
79 | (*groupsp)[0] = group; | |
80 | + /* Start is one, because we have the first group as parameter. */ | |
81 | + long int start = 1; | |
82 | ||
83 | - if (__nss_group_database != NULL) | |
84 | + if (initgroups_database == NULL) | |
85 | { | |
86 | - no_more = 0; | |
87 | - nip = __nss_group_database; | |
88 | + no_more = __nss_database_lookup ("initgroups", NULL, "", | |
89 | + &initgroups_database); | |
90 | + if (no_more == 0 && initgroups_database == NULL) | |
91 | + { | |
92 | + if (__nss_group_database == NULL) | |
93 | + no_more = __nss_database_lookup ("group", NULL, "compat files", | |
94 | + &__nss_group_database); | |
95 | + | |
96 | + initgroups_database = __nss_group_database; | |
97 | + } | |
98 | + else if (initgroups_database != NULL) | |
99 | + { | |
100 | + assert (no_more == 0); | |
101 | + use_initgroups_entry = true; | |
102 | + } | |
103 | } | |
104 | - else | |
105 | - no_more = __nss_database_lookup ("group", NULL, | |
106 | - "compat [NOTFOUND=return] files", &nip); | |
107 | ||
108 | + service_user *nip = initgroups_database; | |
109 | while (! no_more) | |
110 | { | |
111 | long int prev_start = start; | |
112 | ||
113 | - fct = __nss_lookup_function (nip, "initgroups_dyn"); | |
114 | - | |
115 | + initgroups_dyn_function fct = __nss_lookup_function (nip, | |
116 | + "initgroups_dyn"); | |
117 | if (fct == NULL) | |
118 | status = compat_call (nip, user, group, &start, size, groupsp, | |
119 | limit, &errno); | |
120 | @@ -119,7 +130,13 @@ internal_getgrouplist (const char *user, | |
121 | if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) | |
122 | __libc_fatal ("illegal status in internal_getgrouplist"); | |
123 | ||
124 | - if (status != NSS_STATUS_SUCCESS | |
125 | + /* For compatibility reason we will continue to look for more | |
126 | + entries using the next service even though data has already | |
127 | + been found if the nsswitch.conf file contained only a 'groups' | |
128 | + line and no 'initgroups' line. If the latter is available | |
129 | + we always respect the status. This means that the default | |
130 | + for successful lookups is to return. */ | |
131 | + if ((use_initgroups_entry || status != NSS_STATUS_SUCCESS) | |
132 | && nss_next_action (nip, status) == NSS_ACTION_RETURN) | |
133 | break; | |
134 | ||
135 | Index: glibc-2.12-2-gc4ccff1/include/alloca.h | |
136 | =================================================================== | |
137 | --- glibc-2.12-2-gc4ccff1.orig/include/alloca.h | |
138 | +++ glibc-2.12-2-gc4ccff1/include/alloca.h | |
139 | @@ -14,6 +14,7 @@ extern void *__alloca (size_t __size); | |
140 | ||
141 | extern int __libc_use_alloca (size_t size) __attribute__ ((const)); | |
142 | extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const)); | |
143 | +libc_hidden_proto (__libc_alloca_cutoff) | |
144 | ||
145 | #define __MAX_ALLOCA_CUTOFF 65536 | |
146 | ||
147 | Index: glibc-2.12-2-gc4ccff1/nptl/Versions | |
148 | =================================================================== | |
149 | --- glibc-2.12-2-gc4ccff1.orig/nptl/Versions | |
150 | +++ glibc-2.12-2-gc4ccff1/nptl/Versions | |
151 | @@ -27,6 +27,7 @@ libc { | |
152 | pthread_cond_broadcast; pthread_cond_timedwait; | |
153 | } | |
154 | GLIBC_PRIVATE { | |
155 | + __libc_alloca_cutoff; | |
156 | # Internal libc interface to libpthread | |
157 | __libc_dl_error_tsd; | |
158 | } | |
159 | Index: glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c | |
160 | =================================================================== | |
161 | --- glibc-2.12-2-gc4ccff1.orig/nptl/alloca_cutoff.c | |
162 | +++ glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c | |
163 | @@ -34,3 +34,4 @@ __libc_alloca_cutoff (size_t size) | |
164 | assume the maximum available stack space. */ | |
165 | ?: __MAX_ALLOCA_CUTOFF * 4)); | |
166 | } | |
167 | +libc_hidden_def (__libc_alloca_cutoff) | |
168 | Index: glibc-2.12-2-gc4ccff1/nss/Makefile | |
169 | =================================================================== | |
170 | --- glibc-2.12-2-gc4ccff1.orig/nss/Makefile | |
171 | +++ glibc-2.12-2-gc4ccff1/nss/Makefile | |
172 | @@ -63,7 +63,7 @@ vpath %.c $(subdir-dirs) | |
173 | ||
174 | ||
175 | libnss_files-routines := $(addprefix files-,$(databases)) \ | |
176 | - files-have_o_cloexec | |
177 | + files-initgroups files-have_o_cloexec | |
178 | distribute += files-XXX.c files-parse.c | |
179 | ||
180 | ||
181 | Index: glibc-2.12-2-gc4ccff1/nss/Versions | |
182 | =================================================================== | |
183 | --- glibc-2.12-2-gc4ccff1.orig/nss/Versions | |
184 | +++ glibc-2.12-2-gc4ccff1/nss/Versions | |
185 | @@ -95,5 +95,7 @@ libnss_files { | |
186 | _nss_netgroup_parseline; | |
187 | _nss_files_getpublickey; | |
188 | _nss_files_getsecretkey; | |
189 | + | |
190 | + _nss_files_initgroups_dyn; | |
191 | } | |
192 | } | |
193 | Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c | |
194 | =================================================================== | |
195 | --- glibc-2.12-2-gc4ccff1.orig/nss/nss_files/files-hosts.c | |
196 | +++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c | |
197 | @@ -129,19 +129,22 @@ _nss_files_get##name##_r (proto, | |
198 | && _res_hconf.flags & HCONF_FLAG_MULTI) \ | |
199 | { \ | |
200 | /* We have to get all host entries from the file. */ \ | |
201 | - const size_t tmp_buflen = MIN (buflen, 4096); \ | |
202 | - char tmp_buffer[tmp_buflen] \ | |
203 | + size_t tmp_buflen = MIN (buflen, 4096); \ | |
204 | + char tmp_buffer_stack[tmp_buflen] \ | |
205 | __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\ | |
206 | + char *tmp_buffer = tmp_buffer_stack; \ | |
207 | struct hostent tmp_result_buf; \ | |
208 | int naddrs = 1; \ | |
209 | int naliases = 0; \ | |
210 | char *bufferend; \ | |
211 | + bool tmp_buffer_malloced = false; \ | |
212 | \ | |
213 | while (result->h_aliases[naliases] != NULL) \ | |
214 | ++naliases; \ | |
215 | \ | |
216 | bufferend = (char *) &result->h_aliases[naliases + 1]; \ | |
217 | \ | |
218 | + again: \ | |
219 | while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \ | |
220 | tmp_buflen, errnop H_ERRNO_ARG \ | |
221 | EXTRA_ARGS_VALUE)) \ | |
222 | @@ -182,7 +185,7 @@ _nss_files_get##name##_r (proto, | |
223 | } \ | |
224 | /* If the real name is different add it also to the \ | |
225 | aliases. This means that there is a duplication \ | |
226 | - in the alias list but this is really the users \ | |
227 | + in the alias list but this is really the user's \ | |
228 | problem. */ \ | |
229 | if (strcmp (old_result->h_name, \ | |
230 | tmp_result_buf.h_name) != 0) \ | |
231 | @@ -204,7 +207,7 @@ _nss_files_get##name##_r (proto, | |
232 | *errnop = ERANGE; \ | |
233 | *herrnop = NETDB_INTERNAL; \ | |
234 | status = NSS_STATUS_TRYAGAIN; \ | |
235 | - break; \ | |
236 | + goto out; \ | |
237 | } \ | |
238 | \ | |
239 | new_h_addr_list = \ | |
240 | @@ -268,8 +271,54 @@ _nss_files_get##name##_r (proto, | |
241 | } \ | |
242 | } \ | |
243 | \ | |
244 | - if (status != NSS_STATUS_TRYAGAIN) \ | |
245 | + if (status == NSS_STATUS_TRYAGAIN) \ | |
246 | + { \ | |
247 | + size_t newsize = 2 * tmp_buflen; \ | |
248 | + if (tmp_buffer_malloced) \ | |
249 | + { \ | |
250 | + char *newp = realloc (tmp_buffer, newsize); \ | |
251 | + if (newp != NULL) \ | |
252 | + { \ | |
253 | + assert ((((uintptr_t) newp) \ | |
254 | + & (__alignof__ (struct hostent_data) - 1)) \ | |
255 | + == 0); \ | |
256 | + tmp_buffer = newp; \ | |
257 | + tmp_buflen = newsize; \ | |
258 | + goto again; \ | |
259 | + } \ | |
260 | + } \ | |
261 | + else if (!__libc_use_alloca (buflen + newsize)) \ | |
262 | + { \ | |
263 | + tmp_buffer = malloc (newsize); \ | |
264 | + if (tmp_buffer != NULL) \ | |
265 | + { \ | |
266 | + assert ((((uintptr_t) tmp_buffer) \ | |
267 | + & (__alignof__ (struct hostent_data) - 1)) \ | |
268 | + == 0); \ | |
269 | + tmp_buffer_malloced = true; \ | |
270 | + tmp_buflen = newsize; \ | |
271 | + goto again; \ | |
272 | + } \ | |
273 | + } \ | |
274 | + else \ | |
275 | + { \ | |
276 | + tmp_buffer \ | |
277 | + = extend_alloca (tmp_buffer, tmp_buflen, \ | |
278 | + newsize \ | |
279 | + + __alignof__ (struct hostent_data)); \ | |
280 | + tmp_buffer = (char *) (((uintptr_t) tmp_buffer \ | |
281 | + + __alignof__ (struct hostent_data) \ | |
282 | + - 1) \ | |
283 | + & ~(__alignof__ (struct hostent_data)\ | |
284 | + - 1)); \ | |
285 | + goto again; \ | |
286 | + } \ | |
287 | + } \ | |
288 | + else \ | |
289 | status = NSS_STATUS_SUCCESS; \ | |
290 | + out: \ | |
291 | + if (tmp_buffer_malloced) \ | |
292 | + free (tmp_buffer); \ | |
293 | } \ | |
294 | \ | |
295 | \ | |
296 | Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c | |
297 | =================================================================== | |
298 | --- /dev/null | |
299 | +++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c | |
300 | @@ -0,0 +1,137 @@ | |
301 | +/* Initgroups handling in nss_files module. | |
302 | + Copyright (C) 2011 Free Software Foundation, Inc. | |
303 | + This file is part of the GNU C Library. | |
304 | + | |
305 | + The GNU C Library is free software; you can redistribute it and/or | |
306 | + modify it under the terms of the GNU Lesser General Public | |
307 | + License as published by the Free Software Foundation; either | |
308 | + version 2.1 of the License, or (at your option) any later version. | |
309 | + | |
310 | + The GNU C Library is distributed in the hope that it will be useful, | |
311 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
312 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
313 | + Lesser General Public License for more details. | |
314 | + | |
315 | + You should have received a copy of the GNU Lesser General Public | |
316 | + License along with the GNU C Library; if not, write to the Free | |
317 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
318 | + 02111-1307 USA. */ | |
319 | + | |
320 | +#include <alloca.h> | |
321 | +#include <errno.h> | |
322 | +#include <grp.h> | |
323 | +#include <nss.h> | |
324 | +#include <stdio_ext.h> | |
325 | +#include <string.h> | |
326 | +#include <sys/param.h> | |
327 | + | |
328 | +enum nss_status | |
329 | +_nss_files_initgroups_dyn (const char *user, gid_t group, long int *start, | |
330 | + long int *size, gid_t **groupsp, long int limit, | |
331 | + int *errnop) | |
332 | +{ | |
333 | + FILE *stream = fopen ("/etc/group", "re"); | |
334 | + if (stream == NULL) | |
335 | + { | |
336 | + *errnop = errno; | |
337 | + return *errnop == ENOMEM ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; | |
338 | + } | |
339 | + | |
340 | + /* No other thread using this stream. */ | |
341 | + __fsetlocking (stream, FSETLOCKING_BYCALLER); | |
342 | + | |
343 | + char *line = NULL; | |
344 | + size_t linelen = 0; | |
345 | + enum nss_status status = NSS_STATUS_SUCCESS; | |
346 | + bool any = false; | |
347 | + | |
348 | + size_t buflen = 1024; | |
349 | + void *buffer = alloca (buflen); | |
350 | + bool buffer_use_malloc = false; | |
351 | + | |
352 | + gid_t *groups = *groupsp; | |
353 | + | |
354 | + /* We have to iterate over the entire file. */ | |
355 | + while (!feof_unlocked (stream)) | |
356 | + { | |
357 | + ssize_t n = getline (&line, &linelen, stream); | |
358 | + if (n < 0) | |
359 | + { | |
360 | + if (! feof_unlocked (stream)) | |
361 | + status = ((*errnop = errno) == ENOMEM | |
362 | + ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL); | |
363 | + break; | |
364 | + } | |
365 | + | |
366 | + struct group grp; | |
367 | + int res; | |
368 | + while ((res = _nss_files_parse_grent (line, &grp, buffer, buflen, | |
369 | + errnop)) == -1) | |
370 | + { | |
371 | + size_t newbuflen = 2 * buflen; | |
372 | + if (buffer_use_malloc || ! __libc_use_alloca (buflen + newbuflen)) | |
373 | + { | |
374 | + void *newbuf = realloc (buffer_use_malloc ? buffer : NULL, | |
375 | + newbuflen); | |
376 | + if (newbuf == NULL) | |
377 | + { | |
378 | + *errnop = ENOMEM; | |
379 | + status = NSS_STATUS_TRYAGAIN; | |
380 | + goto out; | |
381 | + } | |
382 | + buffer = newbuf; | |
383 | + buflen = newbuflen; | |
384 | + buffer_use_malloc = true; | |
385 | + } | |
386 | + else | |
387 | + buffer = extend_alloca (buffer, buflen, newbuflen); | |
388 | + } | |
389 | + | |
390 | + if (res > 0 && grp.gr_gid != group) | |
391 | + for (char **m = grp.gr_mem; *m != NULL; ++m) | |
392 | + if (strcmp (*m, user) == 0) | |
393 | + { | |
394 | + /* Matches user. Insert this group. */ | |
395 | + if (*start == *size) | |
396 | + { | |
397 | + /* Need a bigger buffer. */ | |
398 | + if (limit > 0 && *size == limit) | |
399 | + /* We reached the maximum. */ | |
400 | + goto out; | |
401 | + | |
402 | + long int newsize; | |
403 | + if (limit <= 0) | |
404 | + newsize = 2 * *size; | |
405 | + else | |
406 | + newsize = MIN (limit, 2 * *size); | |
407 | + | |
408 | + gid_t *newgroups = realloc (groups, | |
409 | + newsize * sizeof (*groups)); | |
410 | + if (newgroups == NULL) | |
411 | + { | |
412 | + *errnop = ENOMEM; | |
413 | + status = NSS_STATUS_TRYAGAIN; | |
414 | + goto out; | |
415 | + } | |
416 | + *groupsp = groups = newgroups; | |
417 | + *size = newsize; | |
418 | + } | |
419 | + | |
420 | + groups[*start] = grp.gr_gid; | |
421 | + *start += 1; | |
422 | + any = true; | |
423 | + | |
424 | + break; | |
425 | + } | |
426 | + } | |
427 | + | |
428 | + out: | |
429 | + /* Free memory. */ | |
430 | + if (buffer_use_malloc) | |
431 | + free (buffer); | |
432 | + free (line); | |
433 | + | |
434 | + fclose (stream); | |
435 | + | |
436 | + return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status; | |
437 | +} | |
438 | Index: glibc-2.12-2-gc4ccff1/nss/nsswitch.conf | |
439 | =================================================================== | |
440 | --- glibc-2.12-2-gc4ccff1.orig/nss/nsswitch.conf | |
441 | +++ glibc-2.12-2-gc4ccff1/nss/nsswitch.conf | |
442 | @@ -5,6 +5,7 @@ | |
443 | ||
444 | passwd: db files | |
445 | group: db files | |
446 | +initgroups: db [SUCCESS=continue] files | |
447 | shadow: db files | |
448 | gshadow: files | |
449 |