diff options
author | djl <none@none> | 2006-09-29 06:00:17 -0700 |
---|---|---|
committer | djl <none@none> | 2006-09-29 06:00:17 -0700 |
commit | cb5caa98562cf06753163f558cbcfe30b8f4673a (patch) | |
tree | 7a24623821583899295e29553207e69701b471ff /usr/src/lib/nsswitch/files/common/files_common.c | |
parent | 350f572a3fa518fc3690d53066c2c54fd03b5a08 (diff) | |
download | illumos-joyent-cb5caa98562cf06753163f558cbcfe30b8f4673a.tar.gz |
PSARC 2005/133 Sparks: Name Service Switch 2
4406529 artificial limit of 10 threads per backend
4516075 LDAP connections could be reused more
4696964 LDAP naming services should support Kerberos authentication
4740951 Need host based authentication options in Native LDAP
4952533 Some backends of gethostby* do not set h_errno correctly
4979596 getXbyY calls should have better buffer mechanism
5028908 /usr/bin/logins accesses free memory deep in nss_getent_u().
5046881 nscd: old-data-ok parameter is not useful, should go away
6225323 NSS/nscd Enhancements (Sparks Project)
--HG--
rename : usr/src/cmd/nscd/attrstr.c => deleted_files/usr/src/cmd/nscd/attrstr.c
rename : usr/src/cmd/nscd/hash.c => deleted_files/usr/src/cmd/nscd/hash.c
rename : usr/src/cmd/nscd/nscd_parse.c => deleted_files/usr/src/cmd/nscd/nscd_parse.c
rename : usr/src/cmd/nscd/nscd.h => usr/src/cmd/nscd/cache.h
Diffstat (limited to 'usr/src/lib/nsswitch/files/common/files_common.c')
-rw-r--r-- | usr/src/lib/nsswitch/files/common/files_common.c | 142 |
1 files changed, 109 insertions, 33 deletions
diff --git a/usr/src/lib/nsswitch/files/common/files_common.c b/usr/src/lib/nsswitch/files/common/files_common.c index bdf03a3ca9..0f89f25d0b 100644 --- a/usr/src/lib/nsswitch/files/common/files_common.c +++ b/usr/src/lib/nsswitch/files/common/files_common.c @@ -41,6 +41,7 @@ #include <poll.h> #include <unistd.h> #include <sys/stat.h> +#include <sys/mman.h> /*ARGSUSED*/ nss_status_t @@ -69,7 +70,7 @@ _nss_files_endent(be, dummy) void *dummy; { if (be->f != 0) { - fclose(be->f); + (void) fclose(be->f); be->f = 0; } if (be->buf != 0) { @@ -186,7 +187,7 @@ _nss_files_do_all(be, args, filter, func) } while (res == NSS_NOTFOUND); - _nss_files_endent(be, 0); + (void) _nss_files_endent(be, 0); return (res); } @@ -208,6 +209,8 @@ _nss_files_XY_all(be, args, netdb, filter, check) int parsestat; int (*func)(); + if (filter != NULL && *filter == '\0') + return (NSS_NOTFOUND); if (be->buf == 0 && (be->buf = malloc(be->minbuf)) == 0) { return (NSS_UNAVAIL); /* really panic, malloc failed */ @@ -230,7 +233,7 @@ _nss_files_XY_all(be, args, netdb, filter, check) be->minbuf)) < 0) { /* End of file */ args->returnval = 0; - args->erange = 0; + args->returnlen = 0; break; } if (filter != 0 && strstr(instr, filter) == 0) { @@ -277,17 +280,21 @@ _nss_files_XY_all(be, args, netdb, filter, check) } args->returnval = 0; + args->returnlen = 0; + + if (check != NULL && (*check)(args, instr, linelen) == 0) + continue; func = args->str2ent; parsestat = (*func)(instr, linelen, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { - args->returnval = args->buf.result; - if (check == 0 || (*check)(args)) { - res = NSS_SUCCESS; - break; - } + args->returnval = (args->buf.result != NULL)? + args->buf.result : args->buf.buffer; + args->returnlen = linelen; + res = NSS_SUCCESS; + break; } else if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; break; @@ -339,15 +346,22 @@ _nss_files_hash_destroy(files_hash_t *fhp) extern void __nss_use_files_hash(void); #endif /* pic */ +/*ARGSUSED*/ nss_status_t _nss_files_XY_hash(files_backend_ptr_t be, nss_XbyY_args_t *args, int netdb, files_hash_t *fhp, int hashop, files_XY_check_func check) { + /* LINTED E_FUNC_VAR_UNUSED */ int fd, retries, ht; + /* LINTED E_FUNC_VAR_UNUSED */ uint_t hash, line, f; + /* LINTED E_FUNC_VAR_UNUSED */ files_hashent_t *hp, *htab; + /* LINTED E_FUNC_VAR_UNUSED */ char *cp, *first, *last; + /* LINTED E_FUNC_VAR_UNUSED */ nss_XbyY_args_t xargs; + /* LINTED E_FUNC_VAR_UNUSED */ struct stat64 st; #ifndef PIC @@ -375,26 +389,30 @@ retry: st.st_mtim.tv_nsec == fhp->fh_mtime.tv_nsec && fhp->fh_table != NULL) { htab = &fhp->fh_table[hashop * fhp->fh_size]; - hash = fhp->fh_hash_func[hashop](args, 1); + hash = fhp->fh_hash_func[hashop](args, 1, NULL, 0); for (hp = htab[hash % fhp->fh_size].h_first; hp != NULL; hp = hp->h_next) { if (hp->h_hash != hash) continue; line = hp - htab; + if ((*check)(args, fhp->fh_line[line].l_start, + fhp->fh_line[line].l_len) == 0) + continue; if ((*args->str2ent)(fhp->fh_line[line].l_start, fhp->fh_line[line].l_len, args->buf.result, args->buf.buffer, args->buf.buflen) == NSS_STR_PARSE_SUCCESS) { - args->returnval = args->buf.result; - if ((*check)(args)) { - mutex_unlock(&fhp->fh_lock); - return (NSS_SUCCESS); - } + args->returnval = (args->buf.result)? + args->buf.result:args->buf.buffer; + args->returnlen = fhp->fh_line[line].l_len; + mutex_unlock(&fhp->fh_lock); + return (NSS_SUCCESS); } else { args->erange = 1; } } args->returnval = 0; + args->returnlen = 0; mutex_unlock(&fhp->fh_lock); return (NSS_NOTFOUND); } @@ -461,14 +479,6 @@ retry: if (fhp->fh_line == NULL || fhp->fh_table == NULL) goto unavail; - xargs = *args; - xargs.buf.result = malloc(fhp->fh_resultsize + fhp->fh_bufsize); - if (xargs.buf.result == NULL) - goto unavail; - xargs.buf.buffer = (char *)xargs.buf.result + fhp->fh_resultsize; - xargs.buf.buflen = fhp->fh_bufsize; - xargs.returnval = xargs.buf.result; - line = 0; cp = fhp->fh_file_start; while (cp < fhp->fh_file_end) { @@ -494,18 +504,14 @@ retry: --last; *++last = '\0'; } - if ((*xargs.str2ent)(first, last - first, - xargs.buf.result, xargs.buf.buffer, xargs.buf.buflen) != - NSS_STR_PARSE_SUCCESS) - continue; for (ht = 0; ht < fhp->fh_nhtab; ht++) { hp = &fhp->fh_table[ht * fhp->fh_size + line]; - hp->h_hash = fhp->fh_hash_func[ht](&xargs, 0); + hp->h_hash = fhp->fh_hash_func[ht](&xargs, 0, first, + last - first); } fhp->fh_line[line].l_start = first; fhp->fh_line[line++].l_len = last - first; } - free(xargs.buf.result); /* * Populate the hash tables in reverse order so that the hash chains @@ -561,13 +567,13 @@ _nss_files_destr(be, dummy) { if (be != 0) { if (be->f != 0) { - _nss_files_endent(be, 0); + (void) _nss_files_endent(be, 0); } if (be->hashinfo != NULL) { - mutex_lock(&be->hashinfo->fh_lock); + (void) mutex_lock(&be->hashinfo->fh_lock); if (--be->hashinfo->fh_refcnt == 0) _nss_files_hash_destroy(be->hashinfo); - mutex_unlock(&be->hashinfo->fh_lock); + (void) mutex_unlock(&be->hashinfo->fh_lock); } free(be); } @@ -596,10 +602,80 @@ _nss_files_constr(ops, n_ops, filename, min_bufsize, fhp) be->hashinfo = fhp; if (fhp != NULL) { - mutex_lock(&fhp->fh_lock); + (void) mutex_lock(&fhp->fh_lock); fhp->fh_refcnt++; - mutex_unlock(&fhp->fh_lock); + (void) mutex_unlock(&fhp->fh_lock); } return ((nss_backend_t *)be); } + +int +_nss_files_check_name_colon(nss_XbyY_args_t *argp, const char *line, + int linelen) +{ + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); +} + +/* + * This routine is used to parse lines of the form: + * name number aliases + * It returns 1 if the key in argp matches any one of the + * names in the line, otherwise 0 + * Used by rpc, networks, protocols + */ +int +_nss_files_check_name_aliases(nss_XbyY_args_t *argp, const char *line, + int linelen) +{ + const char *limit, *linep, *keyp; + + linep = line; + limit = line + linelen; + keyp = argp->key.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && isspace(*linep)) + return (1); + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the aliases */ + while (linep < limit) { + /* + * 1st pass: skip number + * Other passes: skip remainder of the alias name, if any + */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the alias name */ + keyp = argp->key.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + } + return (0); +} |