summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
authormichen <none@none>2006-11-12 19:14:12 -0800
committermichen <none@none>2006-11-12 19:14:12 -0800
commite37190e5b4531a897e4191a30b8f41678b582e25 (patch)
tree9aa2ce3c03a9ce51763fa42ae37e5c0d236fe4f7 /usr/src/lib/libc
parent82496103dc7749da27d989495d92566a426c2815 (diff)
downloadillumos-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.c4
-rw-r--r--usr/src/lib/libc/port/gen/nss_common.c45
-rw-r--r--usr/src/lib/libc/port/gen/nss_dbdefs.c88
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 &&