diff options
author | michen <none@none> | 2006-11-12 19:14:12 -0800 |
---|---|---|
committer | michen <none@none> | 2006-11-12 19:14:12 -0800 |
commit | e37190e5b4531a897e4191a30b8f41678b582e25 (patch) | |
tree | 9aa2ce3c03a9ce51763fa42ae37e5c0d236fe4f7 /usr/src/lib/libc | |
parent | 82496103dc7749da27d989495d92566a426c2815 (diff) | |
download | illumos-joyent-e37190e5b4531a897e4191a30b8f41678b582e25.tar.gz |
6462185 /etc/hosts parsing is still retarded and broken
6479473 nscd needs a better way to manage resources for setxxxent/getxxxent requests
6486404 ftpuser(anonymous, root or regular) test fails ramdomly when system is stressed.
6487770 id -a may return incorrect group ids on a system running snv_50/snv_51
6490506 nscd dumps core on a system bfu'd from a nightly built with gcc
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/port/gen/getgrnam_r.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/nss_common.c | 45 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/nss_dbdefs.c | 88 |
3 files changed, 40 insertions, 97 deletions
diff --git a/usr/src/lib/libc/port/gen/getgrnam_r.c b/usr/src/lib/libc/port/gen/getgrnam_r.c index 2432e4a275..17b8ed6f0e 100644 --- a/usr/src/lib/libc/port/gen/getgrnam_r.c +++ b/usr/src/lib/libc/port/gen/getgrnam_r.c @@ -249,7 +249,7 @@ fgetgrent_r(FILE *f, struct group *result, char *buffer, int buflen) * values in the array are unique. */ -static nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *); +extern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *); int _getgroupsbymember(const char *username, gid_t gid_array[], @@ -422,7 +422,7 @@ str2group(const char *instr, int lenstr, void *ent, char *buffer, int buflen) return (NSS_STR_PARSE_ERANGE); } -static nss_status_t +nss_status_t process_cstr(const char *instr, int instr_len, struct nss_groupsbymem *gbm) { /* diff --git a/usr/src/lib/libc/port/gen/nss_common.c b/usr/src/lib/libc/port/gen/nss_common.c index 2fa1fbf3dc..2f4349770f 100644 --- a/usr/src/lib/libc/port/gen/nss_common.c +++ b/usr/src/lib/libc/port/gen/nss_common.c @@ -1259,6 +1259,7 @@ struct nss_getent_context { struct nss_db_state *s; nssuint_t cookie; nssuint_t seq_num; + nssuint_t cookie_setent; nss_db_params_t param; }; @@ -1359,12 +1360,16 @@ nss_setent_u(nss_db_root_t *rootp, nss_db_initf_t initf, s = 0; } else { s = contextp->s; + if (contextp->cookie != NSCD_LOCAL_COOKIE) + contextp->cookie = NSCD_NEW_COOKIE; } /* name service cache daemon divert */ - status = _nsc_setent_u(rootp, initf, contextpp); - if (status != NSS_TRYLOCAL) - return; + if (contextp->cookie == NSCD_NEW_COOKIE) { + status = _nsc_setent_u(rootp, initf, contextpp); + if (status != NSS_TRYLOCAL) + return; + } /* fall through - process locally */ if (s == 0) { @@ -1632,7 +1637,6 @@ nss_pack(void *buffer, size_t bufsize, nss_db_root_t *rootp, const char *dbn; size_t blen, len, off = 0; char *bptr; - nssuint_t *uptr; struct nss_groupsbymem *gbm; if (pbuf == NULL || in == NULL || initf == (nss_db_initf_t)NULL) { @@ -1715,8 +1719,9 @@ nss_pack(void *buffer, size_t bufsize, nss_db_root_t *rootp, gbm = (struct nss_groupsbymem *)search_args; if (search_fnum == NSS_DBOP_GROUP_BYMEMBER && strcmp(dbn, NSS_DBNAM_GROUP) == 0 && gbm->numgids == 1) { - uptr = (nssuint_t *)((void *)((char *)buffer + off)); - *uptr = (nssuint_t)gbm->gid_array[0]; + gid_t *gidp; + gidp = (gid_t *)((void *)((char *)buffer + off)); + *gidp = gbm->gid_array[0]; } errno = 0; /* just in case ... */ @@ -1818,7 +1823,7 @@ nss_unpack(void *buffer, size_t bufsize, nss_db_root_t *rootp, int i; int fmt_type; gid_t *gidp; - nssuint_t *uptr; + gid_t *gptr; struct nss_groupsbymem *arg; @@ -1857,16 +1862,15 @@ nss_unpack(void *buffer, size_t bufsize, nss_db_root_t *rootp, if (fmt_type == 1) { arg = (struct nss_groupsbymem *)in; /* copy returned gid array from returned nscd buffer */ - i = len / sizeof (nssuint_t); + i = len / sizeof (gid_t); /* not enough buffer */ if (i > arg->maxgids) { i = arg->maxgids; } arg->numgids = i; gidp = arg->gid_array; - uptr = (nssuint_t *)((void *)buf); - while (--i >= 0) - *gidp++ = (gid_t)*uptr++; + gptr = (gid_t *)((void *)buf); + memcpy(gidp, gptr, len); return (NSS_SUCCESS); } if (fmt_type == 2) { @@ -1934,8 +1938,13 @@ nss_unpack_ent(void *buffer, size_t bufsize, nss_db_root_t *rootp, nptr = (nssuint_t *)((void *)((char *)buffer + pbuf->key_off)); cookie = contextp->cookie; - if (cookie != NSCD_NEW_COOKIE && cookie != *nptr) { - /* Should either be new or a match, else error */ + if (cookie != NSCD_NEW_COOKIE && cookie != contextp->cookie_setent && + cookie != *nptr) { + /* + * Should either be new, or the cookie returned by the last + * setent (i.e., this is the first getent after the setent) + * or a match, else error + */ return (NSS_NOTFOUND); } /* save away for the next ent request */ @@ -2112,6 +2121,8 @@ _nsc_setent_u(nss_db_root_t *rootp, nss_db_initf_t initf, /* unpack returned cookie stash it away */ status = nss_unpack_ent((void *)doorptr, bufsize, rootp, initf, contextpp, NULL); + /* save the setent cookie for later use */ + contextp->cookie_setent = contextp->cookie; /* * check if doors reallocated the memory underneath us * if they did munmap it or suffer a memory leak @@ -2165,8 +2176,14 @@ _nsc_getent_u(nss_db_root_t *rootp, nss_db_initf_t initf, /* If fallback to standard nss logic (door failure) if possible */ if (status != NSS_SUCCESS) { - if (contextp->cookie == NSCD_NEW_COOKIE) { + if (status == NSS_TRYLOCAL || + contextp->cookie == NSCD_NEW_COOKIE) { contextp->cookie = NSCD_LOCAL_COOKIE; + + /* init the local cookie */ + nss_setent_u(rootp, initf, contextpp); + if (contextpp->ctx == 0) + return (NSS_UNAVAIL); return (NSS_TRYLOCAL); } return (NSS_UNAVAIL); diff --git a/usr/src/lib/libc/port/gen/nss_dbdefs.c b/usr/src/lib/libc/port/gen/nss_dbdefs.c index 687c3a9711..61a2bbf6dd 100644 --- a/usr/src/lib/libc/port/gen/nss_dbdefs.c +++ b/usr/src/lib/libc/port/gen/nss_dbdefs.c @@ -181,6 +181,8 @@ _nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen) } +extern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *); + /* * pack well known getXbyY keys to packed buffer prior to the door_call * to nscd. Some consideration is given to ordering the tests based on @@ -773,7 +775,7 @@ nss_packed_set_status(void *buffer, size_t length, nss_status_t status, if (in->numgids >= 0) { pbuf->p_status = NSS_SUCCESS; pbuf->data_len = in->numgids * - sizeof (nssuint_t); + sizeof (gid_t); pbuf->p_herrno = 0; } else { pbuf->p_status = status; @@ -977,9 +979,9 @@ nss_upack_key2arg(void *buffer, size_t length, char **dbname, gbm->numgids = (int)(*uptr++); if (gbm->numgids == 1) { /* insert initial group into data area */ - ((nssuint_t *) - ((void *)gbm->gid_array))[0] = *uptr++; - } + gbm->gid_array[0] = (gid_t)(*uptr++); + } else + uptr++; gbm->username = (const char *)uptr; break; case 't': @@ -1110,82 +1112,6 @@ str2packent( } /* - * getgroupsbymem format interposed cstr2X function - * This are similar to the API in getgrnam_r EXCEPT, this API - * store values in nssuint_t quantities in the buffer, not gid_t - * quantities. The unpacker in nss_common.c knows how to unpack - * into gid_t quantities. - */ - -static nss_status_t -pack_cstr(const char *instr, int instr_len, struct nss_groupsbymem *gbm) -{ - /* - * It's possible to do a much less inefficient version of this by - * selectively duplicating code from str2group(). For now, - * however, we'll take the easy way out and implement this on - * top of str2group(). - */ - - const char *username = gbm->username; - nss_XbyY_buf_t *buf; - struct group *grp; - char **memp; - char *mem; - int parsestat; - - /* TODO FIX THIS - with getdoorbsize type call */ - buf = _nss_XbyY_buf_alloc(sizeof (struct group), NSS_BUFLEN_GROUP); - if (buf == 0) - return (NSS_UNAVAIL); - - grp = (struct group *)buf->result; - - parsestat = (*gbm->str2ent)(instr, instr_len, - grp, buf->buffer, buf->buflen); - - if (parsestat != NSS_STR_PARSE_SUCCESS) { - _nss_XbyY_buf_free(buf); - return (NSS_NOTFOUND); /* === ? */ - } - - if (grp->gr_mem) { - for (memp = grp->gr_mem; (memp) && ((mem = *memp) != 0); - memp++) { - if (strcmp(mem, username) == 0) { - gid_t gid = grp->gr_gid; - nssuint_t *gidp; - int numgids; - int i; - - gidp = (nssuint_t *)((void *)gbm->gid_array); - numgids = gbm->numgids; - - _nss_XbyY_buf_free(buf); - - for (i = 0; i < numgids && - *gidp != (nssuint_t)gid; - i++, gidp++) { - ; - } - if (i >= numgids) { - if (i >= gbm->maxgids) { - /* Filled the array; stop searching */ - return (NSS_SUCCESS); - } - *gidp = (nssuint_t)gid; - gbm->numgids = numgids + 1; - } - return (NSS_NOTFOUND); /* Explained in */ - /* <nss_dbdefs.h> */ - } - } - } - _nss_XbyY_buf_free(buf); - return (NSS_NOTFOUND); -} - -/* * Initialize db_root, initf, dbop and arg from a packed buffer */ @@ -1237,7 +1163,7 @@ nss_packed_arg_init(void *buffer, size_t length, nss_db_root_t *db_root, if (nss_pinit_funcs(index, initf, &real_s2e) != NSS_SUCCESS) return (NSS_ERROR); ((struct nss_groupsbymem *)arg)->str2ent = real_s2e; - ((struct nss_groupsbymem *)arg)->process_cstr = pack_cstr; + ((struct nss_groupsbymem *)arg)->process_cstr = process_cstr; return (NSS_SUCCESS); } if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN && |