aboutsummaryrefslogtreecommitdiff
path: root/nis/nss_nis/nis-initgroups.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/nss_nis/nis-initgroups.c')
-rw-r--r--nis/nss_nis/nis-initgroups.c121
1 files changed, 66 insertions, 55 deletions
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index a5a3ba6144..33a9662b4c 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -30,7 +30,6 @@
#include <sys/param.h>
#include "nss-nis.h"
-#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME grent
@@ -38,6 +37,47 @@
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
+struct response_t
+{
+ struct response_t *next;
+ char val[0];
+};
+
+struct intern_t
+{
+ struct response_t *start;
+ struct response_t *next;
+};
+typedef struct intern_t intern_t;
+
+static int
+saveit (int instatus, char *inkey, int inkeylen, char *inval,
+ int invallen, char *indata)
+{
+ intern_t *intern = (intern_t *) indata;
+
+ if (instatus != YP_TRUE)
+ return 1;
+
+ if (inkey && inkeylen > 0 && inval && invallen > 0)
+ {
+ struct response_t *newp = malloc (sizeof (struct response_t)
+ + invallen + 1);
+ if (newp == NULL)
+ return 1; /* We have no error code for out of memory */
+
+ if (intern->start == NULL)
+ intern->start = newp;
+ else
+ intern->next->next = newp;
+ intern->next = newp;
+
+ newp->next = NULL;
+ *((char *) mempcpy (newp->val, inval, invallen)) = '\0';
+ }
+
+ return 0;
+}
static enum nss_status
internal_setgrent (char *domainname, intern_t *intern)
@@ -45,72 +85,41 @@ internal_setgrent (char *domainname, intern_t *intern)
struct ypall_callback ypcb;
enum nss_status status;
- ypcb.foreach = _nis_saveit;
+ intern->start = NULL;
+
+ ypcb.foreach = saveit;
ypcb.data = (char *) intern;
status = yperr2nss (yp_all (domainname, "group.byname", &ypcb));
-
- /* Mark the last buffer as full. */
- if (intern->next != NULL)
- intern->next->size = intern->offset;
-
intern->next = intern->start;
- intern->offset = 0;
return status;
}
-
static enum nss_status
internal_getgrent_r (struct group *grp, char *buffer, size_t buflen,
int *errnop, intern_t *intern)
{
+ struct parser_data *data = (void *) buffer;
+ int parse_res;
+ char *p;
+
if (intern->start == NULL)
return NSS_STATUS_NOTFOUND;
/* Get the next entry until we found a correct one. */
- int parse_res;
do
{
- struct response_t *bucket = intern->next;
-
- if (__builtin_expect (intern->offset >= bucket->size, 0))
- {
- if (bucket->next == NULL)
- return NSS_STATUS_NOTFOUND;
-
- /* We look at all the content in the current bucket. Go on
- to the next. */
- bucket = intern->next = bucket->next;
- intern->offset = 0;
- }
-
- char *p;
- for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
- ++intern->offset;
+ if (intern->next == NULL)
+ return NSS_STATUS_NOTFOUND;
- size_t len = strlen (p) + 1;
- if (__builtin_expect (len > buflen, 0))
- {
- *errnop = ERANGE;
- return NSS_STATUS_TRYAGAIN;
- }
+ p = strncpy (buffer, intern->next->val, buflen);
+ while (isspace (*p))
+ ++p;
- /* We unfortunately have to copy the data in the user-provided
- buffer because that buffer might be around for a very long
- time and the servent structure must remain valid. If we would
- rely on the BUCKET memory the next 'setservent' or 'endservent'
- call would destroy it.
-
- The important thing is that it is a single NUL-terminated
- string. This is what the parsing routine expects. */
- p = memcpy (buffer, &bucket->mem[intern->offset], len);
-
- parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen,
- errnop);
- if (__builtin_expect (parse_res == -1, 0))
+ parse_res = _nss_files_parse_grent (p, grp, data, buflen, errnop);
+ if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
-
- intern->offset += len;
+ intern->next = intern->next->next;
}
while (!parse_res);
@@ -157,12 +166,13 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
ssize_t keylen = snprintf (key, sizeof (key), "unix.%lu@%s",
(unsigned long int) uid, domainname);
+ enum nss_status retval;
char *result;
int reslen;
- int yperr = yp_match (domainname, "netid.byname", key, keylen, &result,
- &reslen);
- if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
- return yperr2nss (yperr);
+ retval = yperr2nss (yp_match (domainname, "netid.byname", key, keylen,
+ &result, &reslen));
+ if (retval != NSS_STATUS_SUCCESS)
+ return retval;
/* Parse the result: following the colon is a comma separated list of
group IDs. */
@@ -197,6 +207,7 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
if (*start == *size)
{
/* Need a bigger buffer. */
+ gid_t *newgroups;
long int newsize;
if (limit > 0 && *size == limit)
@@ -208,7 +219,7 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
else
newsize = MIN (limit, 2 * *size);
- gid_t *newgroups = realloc (groups, newsize * sizeof (*groups));
+ newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
goto errout;
*groupsp = groups = newgroups;
@@ -236,7 +247,7 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
return NSS_STATUS_UNAVAIL;
/* Check whether we are supposed to use the netid.byname map. */
- if (_nsl_default_nss () & NSS_FLAG_NETID_AUTHORITATIVE)
+ if (_nis_default_nss () & NSS_FLAG_NETID_AUTHORITATIVE)
{
/* We need the user ID. */
uid_t uid;
@@ -251,7 +262,7 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
char *tmpbuf;
enum nss_status status;
- intern_t intern = { NULL, NULL, 0 };
+ intern_t intern = { NULL, NULL };
gid_t *groups = *groupsp;
status = internal_setgrent (domainname, &intern);