diff options
Diffstat (limited to 'nis/nss_compat/compat-initgroups.c')
-rw-r--r-- | nis/nss_compat/compat-initgroups.c | 146 |
1 files changed, 79 insertions, 67 deletions
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c index 97ddaeebab..a0c3455eb6 100644 --- a/nis/nss_compat/compat-initgroups.c +++ b/nis/nss_compat/compat-initgroups.c @@ -29,6 +29,7 @@ #include <rpcsvc/nis.h> #include <nsswitch.h> +#include "nss-nis.h" #include "nss-nisplus.h" #include "nisplus-parser.h" @@ -53,6 +54,12 @@ struct blacklist_t int size; }; +struct response_t +{ + char *val; + struct response_t *next; +}; + struct ent_t { bool_t nis; @@ -62,6 +69,8 @@ struct ent_t nis_result *result; FILE *stream; struct blacklist_t blacklist; + struct response_t *start; + struct response_t *next; }; typedef struct ent_t ent_t; @@ -70,6 +79,36 @@ typedef struct ent_t ent_t; static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); +static int +saveit (int instatus, char *inkey, int inkeylen, char *inval, + int invallen, char *indata) +{ + ent_t *intern = (ent_t *) indata; + + if (instatus != YP_TRUE) + return instatus; + + if (inkey && inkeylen > 0 && inval && invallen > 0) + { + if (intern->start == NULL) + { + intern->start = malloc (sizeof (struct response_t)); + intern->next = intern->start; + } + else + { + intern->next->next = malloc (sizeof (struct response_t)); + intern->next = intern->next->next; + } + intern->next->next = NULL; + intern->next->val = malloc (invallen + 1); + strncpy (intern->next->val, inval, invallen); + intern->next->val[invallen] = '\0'; + } + + return 0; +} + static enum nss_status _nss_first_init (void) { @@ -105,6 +144,9 @@ internal_setgrent (ent_t *ent) ent->nis = ent->nis_first = 0; + ent->start = NULL; + ent->next = NULL; + if (_nss_first_init () != NSS_STATUS_SUCCESS) return NSS_STATUS_UNAVAIL; @@ -197,6 +239,16 @@ internal_endgrent (ent_t *ent) else ent->blacklist.current = 0; + while (ent->start != NULL) + { + if (ent->start->val != NULL) + free (ent->start->val); + ent->next = ent->start; + ent->start = ent->start->next; + free (ent->next); + } + + return NSS_STATUS_SUCCESS; } @@ -205,10 +257,8 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer, size_t buflen, int *errnop) { struct parser_data *data = (void *) buffer; - char *domain; - char *outkey, *outval; - int outkeylen, outvallen, parse_res; - char *p; + char *domain, *p; + int parse_res; if (yp_get_default_domain (&domain) != YPERR_SUCCESS) { @@ -216,85 +266,47 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer, return NSS_STATUS_NOTFOUND; } - do + if (ent->start == NULL) { - char *save_oldkey; - int save_oldlen; - bool_t save_nis_first; + struct ypall_callback ypcb; + enum nss_status status; - if (ent->nis_first) - { - if (yp_first (domain, "group.byname", &outkey, &outkeylen, - &outval, &outvallen) != YPERR_SUCCESS) - { - ent->nis = 0; - *errnop = ENOENT; - return NSS_STATUS_UNAVAIL; - } + ypcb.foreach = saveit; + ypcb.data = (char *) ent; + status = yperr2nss (yp_all (domain, "group.byname", &ypcb)); + ent->next = ent->start; - if ( buflen < ((size_t) outvallen + 1)) - { - free (outval); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - save_oldkey = ent->oldkey; - save_oldlen = ent->oldkeylen; - save_nis_first = TRUE; - ent->oldkey = outkey; - ent->oldkeylen = outkeylen; - ent->nis_first = FALSE; - } - else + if (ent->start == NULL || status != NSS_STATUS_SUCCESS) { - if (yp_next (domain, "group.byname", ent->oldkey, ent->oldkeylen, - &outkey, &outkeylen, &outval, &outvallen) - != YPERR_SUCCESS) - { - ent->nis = 0; - *errnop = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - if ( buflen < ((size_t) outvallen + 1)) - { - free (outval); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - save_oldkey = ent->oldkey; - save_oldlen = ent->oldkeylen; - save_nis_first = FALSE; - ent->oldkey = outkey; - ent->oldkeylen = outkeylen; + ent->nis = 0; + *errnop = ENOENT; + return NSS_STATUS_UNAVAIL; } + } - /* Copy the found data to our buffer... */ - p = strncpy (buffer, outval, buflen); - /* ...and free the data. */ - free (outval); + do + { + if (ent->next == NULL) + { + *errnop = ENOENT; + ent->nis = 0; + return NSS_STATUS_NOTFOUND; + } + /* Copy the found data to our buffer... */ + p = strncpy (buffer, ent->next->val, buflen); while (isspace (*p)) - ++p; + ++p; parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop); if (parse_res == -1) { - free (ent->oldkey); - ent->oldkey = save_oldkey; - ent->oldkeylen = save_oldlen; - ent->nis_first = save_nis_first; *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - else - { - if (!save_nis_first) - free (save_oldkey); - } + + ent->next = ent->next->next; if (parse_res && in_blacklist (result->gr_name, strlen (result->gr_name), ent)) |