1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

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

@ -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;
}
else
no_more = __nss_database_lookup ("initgroups", "group",
"compat [NOTFOUND=return] files", &nip);
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;
}
}
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;