More configurability for secondary group lookup

Together with a previous patch which introduced the initgroups
entry in nsswitch.conf this patch allows more customization of
the lookups for initgroups/getgrouplist.  Nothing changes if
the groups entry in nsswitch.conf is used.  If the initgroups entry
is used instead the code now doesn't automatically continue looking
for more entries aftedr a successful lookup.  Instead the normal
rules are followed which do specify that by default no more
service is consulted.  This can be overwritten with
	[SUCCESS=continue]
appropriately placed in the line.
This commit is contained in:
Ulrich Drepper 2011-05-10 00:36:29 -04:00
parent bc469bea5c
commit 7b3b0b2a63
4 changed files with 49 additions and 22 deletions

View File

@ -1,3 +1,13 @@
2011-05-10 Ulrich Drepper <drepper@gmail.com>
[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 <drepper@gmail.com> 2011-05-09 Ulrich Drepper <drepper@gmail.com>
[BZ #11532] [BZ #11532]

12
NEWS
View File

@ -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. Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
@ -9,11 +9,11 @@ Version 2.14
* The following bugs are resolved with this release: * The following bugs are resolved with this release:
11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947, 12158, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947,
12178, 12200, 12346, 12393, 12420, 12445, 12449, 12454, 12460, 12469, 12158, 12178, 12200, 12346, 12393, 12420, 12445, 12449, 12454, 12460,
12489, 12509, 12510, 12518, 12541, 12545, 12551, 12583, 12587, 12597, 12469, 12489, 12509, 12510, 12518, 12541, 12545, 12551, 12583, 12587,
12611, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713, 12597, 12611, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711,
12714, 12717, 12723, 12734, 12738 12713, 12714, 12717, 12723, 12734, 12738
* The RPC implementation in libc is obsoleted. Old programs keep working * The RPC implementation in libc is obsoleted. Old programs keep working
but new programs cannot be linked with the routines in libc anymore. but new programs cannot be linked with the routines in libc anymore.

View File

@ -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 void *__nss_lookup_function (service_user *ni, const char *fct_name);
extern service_user *__nss_group_database attribute_hidden; extern service_user *__nss_group_database attribute_hidden;
static service_user *initgroups_database;
static bool use_initgroups_entry;
#include "compat-initgroups.c" #include "compat-initgroups.c"
@ -69,32 +71,41 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
} }
#endif #endif
service_user *nip = NULL;
initgroups_dyn_function fct;
enum nss_status status = NSS_STATUS_UNAVAIL; enum nss_status status = NSS_STATUS_UNAVAIL;
int no_more; int no_more = 0;
/* Start is one, because we have the first group as parameter. */
long int start = 1;
/* Never store more than the starting *SIZE number of elements. */ /* Never store more than the starting *SIZE number of elements. */
assert (*size > 0); assert (*size > 0);
(*groupsp)[0] = group; (*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; no_more = __nss_database_lookup ("initgroups", NULL, "",
nip = __nss_group_database; &initgroups_database);
} if (no_more == 0 && initgroups_database == NULL)
else {
no_more = __nss_database_lookup ("initgroups", "group", if (__nss_group_database == NULL)
"compat [NOTFOUND=return] files", &nip); 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;
}
}
service_user *nip = initgroups_database;
while (! no_more) while (! no_more)
{ {
long int prev_start = start; 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) if (fct == NULL)
status = compat_call (nip, user, group, &start, size, groupsp, status = compat_call (nip, user, group, &start, size, groupsp,
limit, &errno); 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) if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
__libc_fatal ("illegal status in internal_getgrouplist"); __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) && nss_next_action (nip, status) == NSS_ACTION_RETURN)
break; break;

View File

@ -5,7 +5,7 @@
passwd: db files passwd: db files
group: db files group: db files
initgroups: db files initgroups: db [SUCCESS=continue] files
shadow: db files shadow: db files
gshadow: files gshadow: files