diff --git a/ChangeLog b/ChangeLog index 7c6cf7a495..f4363afc9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-05-10 Ulrich Drepper + + [BZ #11257] + * grp/initgroups.c (internal_getgrouplist): When we found the service + list through the initgroups entry in nsswitch.conf do not always + continue on a successful lookup. Don't always use the + __nss_group_data-ase value if it is set. + * nss/nsswitch.conf (initgroups): Change action for successful db + lookup to continue for compatibility. + 2011-05-09 Ulrich Drepper [BZ #11532] diff --git a/NEWS b/NEWS index 2e2e69797d..f5cc012cd7 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2011-5-9 +GNU C Library NEWS -- history of user-visible changes. 2011-5-10 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc. See the end for copying conditions. @@ -9,11 +9,11 @@ Version 2.14 * The following bugs are resolved with this release: - 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947, 12158, - 12178, 12200, 12346, 12393, 12420, 12445, 12449, 12454, 12460, 12469, - 12489, 12509, 12510, 12518, 12541, 12545, 12551, 12583, 12587, 12597, - 12611, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713, - 12714, 12717, 12723, 12734, 12738 + 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947, + 12158, 12178, 12200, 12346, 12393, 12420, 12445, 12449, 12454, 12460, + 12469, 12489, 12509, 12510, 12518, 12541, 12545, 12551, 12583, 12587, + 12597, 12611, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, + 12713, 12714, 12717, 12723, 12734, 12738 * The RPC implementation in libc is obsoleted. Old programs keep working but new programs cannot be linked with the routines in libc anymore. diff --git a/grp/initgroups.c b/grp/initgroups.c index 25acf2a249..dad30d5aa4 100644 --- a/grp/initgroups.c +++ b/grp/initgroups.c @@ -44,6 +44,8 @@ extern int __nss_group_lookup (service_user **nip, const char *name, extern void *__nss_lookup_function (service_user *ni, const char *fct_name); extern service_user *__nss_group_database attribute_hidden; +static service_user *initgroups_database; +static bool use_initgroups_entry; #include "compat-initgroups.c" @@ -69,32 +71,41 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, } #endif - service_user *nip = NULL; - initgroups_dyn_function fct; enum nss_status status = NSS_STATUS_UNAVAIL; - int no_more; - /* Start is one, because we have the first group as parameter. */ - long int start = 1; + int no_more = 0; /* Never store more than the starting *SIZE number of elements. */ assert (*size > 0); (*groupsp)[0] = group; + /* Start is one, because we have the first group as parameter. */ + long int start = 1; - if (__nss_group_database != NULL) + if (initgroups_database == NULL) { - no_more = 0; - nip = __nss_group_database; + no_more = __nss_database_lookup ("initgroups", NULL, "", + &initgroups_database); + if (no_more == 0 && initgroups_database == NULL) + { + if (__nss_group_database == NULL) + no_more = __nss_database_lookup ("group", NULL, "compat files", + &__nss_group_database); + + initgroups_database = __nss_group_database; + } + else if (initgroups_database != NULL) + { + assert (no_more == 0); + use_initgroups_entry = true; + } } - else - no_more = __nss_database_lookup ("initgroups", "group", - "compat [NOTFOUND=return] files", &nip); + service_user *nip = initgroups_database; while (! no_more) { long int prev_start = start; - fct = __nss_lookup_function (nip, "initgroups_dyn"); - + initgroups_dyn_function fct = __nss_lookup_function (nip, + "initgroups_dyn"); if (fct == NULL) status = compat_call (nip, user, group, &start, size, groupsp, limit, &errno); @@ -121,7 +132,13 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) __libc_fatal ("illegal status in internal_getgrouplist"); - if (status != NSS_STATUS_SUCCESS + /* For compatibility reason we will continue to look for more + entries using the next service even though data has already + been found if the nsswitch.conf file contained only a 'groups' + line and no 'initgroups' line. If the latter is available + we always respect the status. This means that the default + for successful lookups is to return. */ + if ((use_initgroups_entry || status != NSS_STATUS_SUCCESS) && nss_next_action (nip, status) == NSS_ACTION_RETURN) break; diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf index 73736a61ae..39ca88bf51 100644 --- a/nss/nsswitch.conf +++ b/nss/nsswitch.conf @@ -5,7 +5,7 @@ passwd: db files group: db files -initgroups: db files +initgroups: db [SUCCESS=continue] files shadow: db files gshadow: files