diff options
Diffstat (limited to 'nis/nss_nis/nis-grp.c')
-rw-r--r-- | nis/nss_nis/nis-grp.c | 256 |
1 files changed, 72 insertions, 184 deletions
diff --git a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c index 6e36cf828f..8be7332515 100644 --- a/nis/nss_nis/nis-grp.c +++ b/nis/nss_nis/nis-grp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-1999, 2001-2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1996-1999, 2001-2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. @@ -17,17 +17,20 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <nss.h> +/* The following is an ugly trick to avoid a prototype declaration for + _nss_nis_endgrent. */ +#define _nss_nis_endgrent _nss_nis_endgrent_XXX +#include <grp.h> +#undef _nss_nis_endgrent #include <ctype.h> #include <errno.h> -#include <grp.h> -#include <nss.h> #include <string.h> #include <bits/libc-lock.h> #include <rpcsvc/yp.h> #include <rpcsvc/ypclnt.h> #include "nss-nis.h" -#include <libnsl.h> /* Get the declaration of the parser function. */ #define ENTNAME grent @@ -41,12 +44,12 @@ __libc_lock_define_initialized (static, lock) static bool_t new_start = 1; static char *oldkey; static int oldkeylen; -static intern_t intern; - -static void -internal_nis_endgrent (void) +enum nss_status +_nss_nis_setgrent (int stayopen) { + __libc_lock_lock (lock); + new_start = 1; if (oldkey != NULL) { @@ -55,186 +58,72 @@ internal_nis_endgrent (void) oldkeylen = 0; } - struct response_t *curr = intern.next; - - while (curr != NULL) - { - struct response_t *last = curr; - curr = curr->next; - free (last); - } - - intern.next = intern.start = NULL; -} - - -enum nss_status -_nss_nis_endgrent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endgrent (); - __libc_lock_unlock (lock); return NSS_STATUS_SUCCESS; } - - -enum nss_status -internal_nis_setgrent (void) -{ - /* We have to read all the data now. */ - char *domain; - if (__builtin_expect (yp_get_default_domain (&domain), 0)) - return NSS_STATUS_UNAVAIL; - - struct ypall_callback ypcb; - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) &intern; - enum nss_status status = yperr2nss (yp_all (domain, "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; -} - - -enum nss_status -_nss_nis_setgrent (int stayopen) -{ - enum nss_status result = NSS_STATUS_SUCCESS; - - __libc_lock_lock (lock); - - internal_nis_endgrent (); - - if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - result = internal_nis_setgrent (); - - __libc_lock_unlock (lock); - - return result; -} - +/* Make _nss_nis_endgrent an alias of _nss_nis_setgrent. We do this + even though the prototypes don't match. The argument of setgrent + is not used so this makes no difference. */ +strong_alias (_nss_nis_setgrent, _nss_nis_endgrent) static enum nss_status internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen, int *errnop) { - /* If we read the entire database at setpwent time we just iterate - over the data we have in memory. */ - bool batch_read = intern.start != NULL; + struct parser_data *data = (void *) buffer; + char *domain, *result, *outkey; + int len, keylen, parse_res; - char *domain = NULL; - if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0)) + if (yp_get_default_domain (&domain)) return NSS_STATUS_UNAVAIL; /* Get the next entry until we found a correct one. */ - int parse_res; do { - char *result; - char *outkey; - int len; - int keylen; - - if (batch_read) - { - struct response_t *bucket; - - handle_batch_read: - 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; - } - - for (result = &bucket->mem[intern.offset]; isspace (*result); - ++result) - ++intern.offset; + enum nss_status retval; + char *p; - len = strlen (result); - } + if (new_start) + retval = yperr2nss (yp_first (domain, "group.byname", + &outkey, &keylen, &result, &len)); else - { - int yperr; - - if (new_start) - { - /* Maybe we should read the database in one piece. */ - if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - && internal_nis_setgrent () == NSS_STATUS_SUCCESS - && intern.start != NULL) - { - batch_read = true; - goto handle_batch_read; - } - - yperr = yp_first (domain, "group.byname", &outkey, &keylen, - &result, &len); - } - else - yperr = yp_next (domain, "group.byname", oldkey, oldkeylen, - &outkey, &keylen, &result, &len); - - if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - } + retval = yperr2nss ( yp_next (domain, "group.byname", + oldkey, oldkeylen, + &outkey, &keylen, &result, &len)); - if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) + if (retval != NSS_STATUS_SUCCESS) + { + if (retval == NSS_STATUS_TRYAGAIN) + *errnop = errno; + return retval; + } + + if ((size_t) (len + 1) > buflen) { free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - char *p = strncpy (buffer, result, len); + p = strncpy (buffer, result, len); buffer[len] = '\0'; while (isspace (*p)) ++p; - if (!batch_read) - free (result); + free (result); - 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) { - if (!batch_read) - free (outkey); + free (outkey); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - if (batch_read) - intern.offset += len + 1; - else - { - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = 0; - } + free (oldkey); + oldkey = outkey; + oldkeylen = keylen; + new_start = 0; } while (parse_res < 1); @@ -260,46 +149,45 @@ enum nss_status _nss_nis_getgrnam_r (const char *name, struct group *grp, char *buffer, size_t buflen, int *errnop) { + struct parser_data *data = (void *) buffer; + enum nss_status retval; + char *domain, *result, *p; + int len, parse_res; + if (name == NULL) { *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } - char *domain; - if (__builtin_expect (yp_get_default_domain (&domain), 0)) + if (yp_get_default_domain (&domain)) return NSS_STATUS_UNAVAIL; - char *result; - int len; - int yperr = yp_match (domain, "group.byname", name, strlen (name), &result, - &len); + retval = yperr2nss (yp_match (domain, "group.byname", name, + strlen (name), &result, &len)); - if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) + if (retval != NSS_STATUS_SUCCESS) { - enum nss_status retval = yperr2nss (yperr); - if (retval == NSS_STATUS_TRYAGAIN) *errnop = errno; return retval; } - if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) + if ((size_t) (len + 1) > buflen) { free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - char *p = strncpy (buffer, result, len); + p = strncpy (buffer, result, len); buffer[len] = '\0'; while (isspace (*p)) ++p; free (result); - int 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) { if (parse_res == -1) return NSS_STATUS_TRYAGAIN; @@ -313,42 +201,42 @@ enum nss_status _nss_nis_getgrgid_r (gid_t gid, struct group *grp, char *buffer, size_t buflen, int *errnop) { - char *domain; - if (__builtin_expect (yp_get_default_domain (&domain), 0)) + struct parser_data *data = (void *) buffer; + enum nss_status retval; + char *domain, *result, *p; + int len, nlen, parse_res; + char buf[32]; + + if (yp_get_default_domain (&domain)) return NSS_STATUS_UNAVAIL; - char buf[32]; - int nlen = sprintf (buf, "%lu", (unsigned long int) gid); + nlen = sprintf (buf, "%lu", (unsigned long int) gid); - char *result; - int len; - int yperr = yp_match (domain, "group.bygid", buf, nlen, &result, &len); + retval = yperr2nss (yp_match (domain, "group.bygid", buf, + nlen, &result, &len)); - if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) + if (retval != NSS_STATUS_SUCCESS) { - enum nss_status retval = yperr2nss (yperr); - if (retval == NSS_STATUS_TRYAGAIN) *errnop = errno; return retval; } - if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) + if ((size_t) (len + 1) > buflen) { free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - char *p = strncpy (buffer, result, len); + p = strncpy (buffer, result, len); buffer[len] = '\0'; while (isspace (*p)) ++p; free (result); - int 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) { if (parse_res == -1) return NSS_STATUS_TRYAGAIN; |