diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
commit | a334319f6530564d22e775935d9c91663623a1b4 (patch) | |
tree | b5877475619e4c938e98757d518bb1e9cbead751 /nis/nss_nisplus/nisplus-grp.c | |
parent | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff) | |
download | glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz |
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'nis/nss_nisplus/nisplus-grp.c')
-rw-r--r-- | nis/nss_nisplus/nisplus-grp.c | 380 |
1 files changed, 131 insertions, 249 deletions
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c index 7cc762fea9..daca94fc87 100644 --- a/nis/nss_nisplus/nisplus-grp.c +++ b/nis/nss_nisplus/nisplus-grp.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,7 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> #include <nss.h> #include <grp.h> #include <ctype.h> @@ -29,110 +27,68 @@ #include "nss-nisplus.h" #include "nisplus-parser.h" -#include <libnsl.h> -#include <nis_intern.h> -#include <nis_xdr.h> - __libc_lock_define_initialized (static, lock); -/* Connection information. */ -static ib_request *ibreq; -static directory_obj *dir; -static dir_binding bptr; -static char *tablepath; -static char *tableptr; -/* Cursor. */ -static netobj cursor; - +static nis_result *result; +static unsigned long next_entry; +static nis_name tablename_val; +static u_long tablename_len; -nis_name grp_tablename_val attribute_hidden; -size_t grp_tablename_len attribute_hidden; - -enum nss_status -_nss_grp_create_tablename (int *errnop) +static enum nss_status +_nss_create_tablename (int *errnop) { - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "group.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "group.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - grp_tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - if (atomic_compare_and_exchange_bool_acq (&grp_tablename_val, p, NULL)) - { - /* Another thread already installed the value. */ - free (p); - grp_tablename_len = strlen (grp_tablename_val); - } + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } - -static void -internal_endgrent (void) -{ - __nisbind_destroy (&bptr); - memset (&bptr, '\0', sizeof (bptr)); - - nis_free_directory (dir); - dir = NULL; - - nis_free_request (ibreq); - ibreq = NULL; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - memset (&cursor, '\0', sizeof (cursor)); - - free (tablepath); - tableptr = tablepath = NULL; -} - - static enum nss_status -internal_setgrent (int *errnop) +internal_setgrent (void) { - enum nss_status status = NSS_STATUS_SUCCESS; + enum nss_status status; + int err; - if (grp_tablename_val == NULL) - status = _nss_grp_create_tablename (errnop); + if (result) + nis_freeresult (result); + result = NULL; + next_entry = 0; - if (status == NSS_STATUS_SUCCESS) - { - ibreq = __create_ib_request (grp_tablename_val, 0); - if (ibreq == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + if (tablename_val == NULL) + if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS) + return NSS_STATUS_UNAVAIL; - nis_error retcode = __prepare_niscall (grp_tablename_val, &dir, &bptr, 0); - if (retcode != NIS_SUCCESS) + result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); + if (result == NULL) + { + status = NSS_STATUS_TRYAGAIN; + __set_errno (ENOMEM); + } + else + { + status = niserr2nss (result->status); + if (status != NSS_STATUS_SUCCESS) { - nis_free_request (ibreq); - ibreq = NULL; - status = niserr2nss (retcode); + nis_freeresult (result); + result = NULL; } } - return status; } - enum nss_status _nss_nisplus_setgrent (int stayopen) { @@ -140,133 +96,58 @@ _nss_nisplus_setgrent (int stayopen) __libc_lock_lock (lock); - internal_endgrent (); - - // XXX We need to be able to set errno. Pass in new parameter. - int err; - status = internal_setgrent (&err); + status = internal_setgrent (); __libc_lock_unlock (lock); return status; } - enum nss_status _nss_nisplus_endgrent (void) { __libc_lock_lock (lock); - internal_endgrent (); + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); return NSS_STATUS_SUCCESS; } - static enum nss_status internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen, int *errnop) { - int parse_res = -1; - enum nss_status retval = NSS_STATUS_SUCCESS; + int parse_res; - /* Get the next entry until we found a correct one. */ - do + if (result == NULL) { - nis_error status; - nis_result result; - memset (&result, '\0', sizeof (result)); + enum nss_status status; - if (cursor.n_bytes == NULL) - { - if (ibreq == NULL) - { - retval = internal_setgrent (errnop); - if (retval != NSS_STATUS_SUCCESS) - return retval; - } - - status = __do_niscall3 (&bptr, NIS_IBFIRST, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); - } - else - { - ibreq->ibr_cookie.n_bytes = cursor.n_bytes; - ibreq->ibr_cookie.n_len = cursor.n_len; - - status = __do_niscall3 (&bptr, NIS_IBNEXT, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); - - ibreq->ibr_cookie.n_bytes = NULL; - ibreq->ibr_cookie.n_len = 0; - } - - if (status != NIS_SUCCESS) - return niserr2nss (status); + status = internal_setgrent (); + if (result == NULL || status != NSS_STATUS_SUCCESS) + return status; + } - if (NIS_RES_STATUS (&result) == NIS_NOTFOUND) - { - /* No more entries on this server. This means we have to go - to the next server on the path. */ - status = __follow_path (&tablepath, &tableptr, ibreq, &bptr); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - directory_obj *newdir = NULL; - dir_binding newbptr; - status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - nis_free_directory (dir); - dir = newdir; - __nisbind_destroy (&bptr); - bptr = newbptr; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie); - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - parse_res = 0; - goto next; - } - else if (NIS_RES_STATUS (&result) != NIS_SUCCESS) - return niserr2nss (NIS_RES_STATUS (&result)); + /* Get the next entry until we found a correct one. */ + do + { + if (next_entry >= result->objects.objects_len) + return NSS_STATUS_NOTFOUND; - parse_res = _nss_nisplus_parse_grent (&result, gr, + parse_res = _nss_nisplus_parse_grent (result, next_entry, gr, buffer, buflen, errnop); - if (__builtin_expect (parse_res == -1, 0)) - { - *errnop = ERANGE; - retval = NSS_STATUS_TRYAGAIN; - goto freeres; - } + if (parse_res == -1) + return NSS_STATUS_TRYAGAIN; - next: - /* Free the old cursor. */ - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - /* Remember the new one. */ - cursor.n_bytes = result.cookie.n_bytes; - cursor.n_len = result.cookie.n_len; - /* Free the result structure. NB: we do not remove the cookie. */ - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - freeres: - xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result); - memset (&result, '\0', sizeof (result)); + ++next_entry; } while (!parse_res); - return retval; + return NSS_STATUS_SUCCESS; } enum nss_status @@ -290,9 +171,9 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr, { int parse_res; - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_grp_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; @@ -303,101 +184,102 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr, *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } - - nis_result *result; - char buf[strlen (name) + 9 + grp_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[name=%s],%s", name, grp_tablename_val); - - result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - - if (result == NULL) + else { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_result *result; + char buf[strlen (name) + 24 + tablename_len]; + int olderr = errno; - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + sprintf (buf, "[name=%s],%s", name, tablename_val); - nis_freeresult (result); - return status; - } + result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); - nis_freeresult (result); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) + if (result == NULL) { - *errnop = ERANGE; + *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } - else + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + enum nss_status status = niserr2nss (result->status); + + nis_freeresult (result); + return status; } - } - return NSS_STATUS_SUCCESS; + parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, + errnop); + nis_freeresult (result); + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } enum nss_status _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop) { - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_grp_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } - int parse_res; - nis_result *result; - char buf[8 + 3 * sizeof (unsigned long int) + grp_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[gid=%lu],%s", - (unsigned long int) gid, grp_tablename_val); + { + int parse_res; + nis_result *result; + char buf[36 + tablename_len]; + int olderr = errno; - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + sprintf (buf, "[gid=%lu],%s", (unsigned long int) gid, tablename_val); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - __set_errno (olderr); - - nis_freeresult (result); - return status; - } + __set_errno (olderr); - parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); - - nis_freeresult (result); - if (__builtin_expect (parse_res < 1, 0)) - { - __set_errno (olderr); - - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - return NSS_STATUS_NOTFOUND; - } - - return NSS_STATUS_SUCCESS; + nis_freeresult (result); + return status; + } + + parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, + errnop); + + nis_freeresult (result); + if (parse_res < 1) + { + __set_errno (olderr); + + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; + } } |