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 | |
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')
24 files changed, 1354 insertions, 668 deletions
diff --git a/usr/src/lib/nsswitch/files/Makefile.com b/usr/src/lib/nsswitch/files/Makefile.com index f6105144d7..0f5ff82629 100644 --- a/usr/src/lib/nsswitch/files/Makefile.com +++ b/usr/src/lib/nsswitch/files/Makefile.com @@ -61,8 +61,10 @@ include ../../Makefile.com include ../../../Makefile.rootfs CPPFLAGS += -I../../../common/inc +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 -LDLIBS += -lnsl +LDLIBS += -lsocket -lnsl DYNLIB1 = nss_files.so$(VERS) all: $(DYNLIB1) fnamecheck diff --git a/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c index ef51910acb..e1e88b1ced 100644 --- a/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c +++ b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,11 +19,11 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * * files/bootparams_getbyname.c -- "files" backend for * nsswitch "bootparams" database. - * - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -44,7 +43,7 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; /* bootparams_getbyname() has not set/endent; rewind on each call */ @@ -108,14 +107,14 @@ _nss_files_XY_bootparams(be, args, filter) * _nss_files_read_line does process the '\' that are used * in /etc/bootparams for continuation and gives one long * buffer. - * + * * linelen counts the characters up to but excluding the '\n' */ if ((linelen = _nss_files_read_line(be->f, instr, be->minbuf)) < 0) { /* End of file */ args->returnval = 0; - args->erange = 0; + args->returnlen = 0; break; } @@ -158,6 +157,7 @@ _nss_files_XY_bootparams(be, args, filter) (void) memcpy(args->buf.buffer, p, linelen); args->buf.buffer[linelen] = '\0'; args->returnval = args->buf.result; + args->returnlen = linelen; res = NSS_SUCCESS; break; } diff --git a/usr/src/lib/nsswitch/files/common/ether_addr.c b/usr/src/lib/nsswitch/files/common/ether_addr.c index 4731e0c354..b8900cf043 100644 --- a/usr/src/lib/nsswitch/files/common/ether_addr.c +++ b/usr/src/lib/nsswitch/files/common/ether_addr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,9 +19,9 @@ * CDDL HEADER END */ /* - * files/ether_addr.c -- "files" backend for nsswitch "ethers" database + * files/ether_addr.c -- "files" backend for nsswitch "ethers" database * - * Copyright 1988-1995,2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,14 +43,38 @@ #include <nss_dbdefs.h> #include "files_common.h" #include <strings.h> +#include <ctype.h> #define _PATH_ETHERS "/etc/ethers" +#define DIGIT(x) \ + (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') static int -check_host(args) - nss_XbyY_args_t *args; +check_host(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (strcmp(args->buf.buffer, args->key.name) == 0); + const char *limit, *linep, *keyp; + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip mac address */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + + /* compare the host name */ + keyp = argp->key.name; + while (*keyp != '\0' && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && linep == limit); } static nss_status_t @@ -63,21 +86,57 @@ getbyhost(be, a) char hostname[MAXHOSTNAMELEN]; nss_status_t res; - argp->buf.buffer = hostname; - argp->buf.buflen = MAXHOSTNAMELEN; + /* + * use the buffer passed in if result is to be returned + * in /etc file format + */ + if (argp->buf.result != NULL) { + argp->buf.buffer = hostname; + argp->buf.buflen = MAXHOSTNAMELEN; + } res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_host); - argp->buf.buffer = NULL; - argp->buf.buflen = 0; + if (argp->buf.result != NULL) { + argp->buf.buffer = NULL; + argp->buf.buflen = 0; + } + return (res); } static int -check_ether(args) - nss_XbyY_args_t *args; +check_ether(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (ether_cmp(args->buf.result, args->key.ether) == 0); + + const char *limit, *linep; + uchar_t ether[6]; + ptrdiff_t i; + int n; + + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + for (i = 0; i < 6; i++) { + n = 0; + while (linep < limit && isxdigit(*linep)) { + n = 16 * n + DIGIT(*linep); + linep++; + } + if (*linep != ':' && i < 5) { + return (0); + } else if (*linep == ':' && i == 5) { + return (0); + } else { + linep++; + ether[i] = (uchar_t)n; + } + } + return (ether_cmp((void *)ether, (void *)argp->key.ether) == 0); } static nss_status_t 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); +} diff --git a/usr/src/lib/nsswitch/files/common/files_common.h b/usr/src/lib/nsswitch/files/common/files_common.h index 87980f8310..9f7457a033 100644 --- a/usr/src/lib/nsswitch/files/common/files_common.h +++ b/usr/src/lib/nsswitch/files/common/files_common.h @@ -45,12 +45,12 @@ extern "C" { typedef struct files_backend *files_backend_ptr_t; typedef nss_status_t (*files_backend_op_t)(files_backend_ptr_t, void *); -typedef u_int (*files_hash_func)(nss_XbyY_args_t *, int); +typedef uint_t (*files_hash_func)(nss_XbyY_args_t *, int, const char *, int); typedef struct files_hashent { struct files_hashent *h_first; struct files_hashent *h_next; - u_int h_hash; + uint_t h_hash; } files_hashent_t; typedef struct { @@ -92,7 +92,8 @@ struct files_backend { * generic work for nss_XbyY_args_t backends (calls cstr2ent etc). */ typedef nss_status_t (*files_do_all_func_t)(const char *, int, void *args); -typedef int (*files_XY_check_func)(nss_XbyY_args_t *); +typedef int (*files_XY_check_func)(nss_XbyY_args_t *, + const char *, int); #if defined(__STDC__) extern nss_backend_t *_nss_files_constr(files_backend_op_t *ops, @@ -133,6 +134,9 @@ extern nss_status_t _nss_files_XY_all(); extern nss_status_t _nss_files_XY_hash(); #endif +int _nss_files_check_name_aliases(nss_XbyY_args_t *, const char *, int); +int _nss_files_check_name_colon(nss_XbyY_args_t *, const char *, int); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/nsswitch/files/common/getauthattr.c b/usr/src/lib/nsswitch/files/common/getauthattr.c index df236111ec..bf02ce214c 100644 --- a/usr/src/lib/nsswitch/files/common/getauthattr.c +++ b/usr/src/lib/nsswitch/files/common/getauthattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,24 +34,14 @@ * files/getauthattr.c -- * "files" backend for nsswitch "auth_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - authstr_t *auth = (authstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(auth->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t authattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t authattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_auth_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getauuser.c b/usr/src/lib/nsswitch/files/common/getauuser.c index b47525e416..08a79e271f 100644 --- a/usr/src/lib/nsswitch/files/common/getauuser.c +++ b/usr/src/lib/nsswitch/files/common/getauuser.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,24 +34,14 @@ * files/getauuser.c -- * "files" backend for nsswitch "audit_user" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - au_user_str_t *au_user = (au_user_str_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(au_user->au_name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t auuser_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t auuser_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_audit_user_constr(const char *dummy1, const char *dummy2, const char *dummy3) diff --git a/usr/src/lib/nsswitch/files/common/getexecattr.c b/usr/src/lib/nsswitch/files/common/getexecattr.c index 502c0112b9..ac9e50ad3a 100644 --- a/usr/src/lib/nsswitch/files/common/getexecattr.c +++ b/usr/src/lib/nsswitch/files/common/getexecattr.c @@ -52,29 +52,47 @@ extern int _readbufline(char *, int, char *, int, int *); extern char *_exec_wild_id(char *, const char *); extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *); -typedef int (*_exec_XY_check_func) (nss_XbyY_args_t *); - /* * check_match: returns 1 if matching entry found, else returns 0. */ static int -check_match(nss_XbyY_args_t *argp) +check_match(nss_XbyY_args_t *argp, const char *line, int linelen) { + const char *limit, *linep, *keyp; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - const char *name = _priv_exec->name; - const char *type = _priv_exec->type; - const char *id = _priv_exec->id; - const char *policy = _priv_exec->policy; - execstr_t *exec = (execstr_t *)argp->returnval; - - if ((policy && exec->policy && (strcmp(policy, exec->policy) != 0)) || - (name && exec->name && (strcmp(name, exec->name) != 0)) || - (type && exec->type && (strcmp(type, exec->type) != 0)) || - (id && exec->id && (strcmp(id, exec->id) != 0))) { - return (0); + const char *exec_field[6]; + int i; + + exec_field[0] = _priv_exec->name; /* name */ + exec_field[1] = _priv_exec->policy; /* policy */ + exec_field[2] = _priv_exec->type; /* type */ + exec_field[3] = NULL; /* res1 */ + exec_field[4] = NULL; /* res2 */ + exec_field[5] = _priv_exec->id; /* id */ + /* No need to check attr field */ + + linep = line; + limit = line + linelen; + + for (i = 0; i < 6; i++) { + keyp = exec_field[i]; + if (keyp) { + /* compare field */ + while (*keyp && linep < limit && + *linep != ':' && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp || linep == limit || *linep != ':') + return (0); + } else { + /* skip field */ + while (linep < limit && *linep != ':') + linep++; + } + linep++; } - return (1); } @@ -90,7 +108,6 @@ _exec_files_XY_all(files_backend_ptr_t be, int f_size = 0; time_t f_time = 0; static time_t read_time = 0; - char *key = NULL; char *first; char *last; static char *f_buf = NULL; @@ -169,16 +186,15 @@ _exec_files_XY_all(files_backend_ptr_t be, } res = NSS_NOTFOUND; + /*CONSTCOND*/ while (1) { int linelen = 0; - int check_stat = 0; char *instr = be->buf; linelen = _readbufline(f_buf, f_size, instr, be->minbuf, &lastlen); if (linelen < 0) { /* End of file */ - argp->erange = 0; break; } @@ -235,26 +251,25 @@ _exec_files_XY_all(files_backend_ptr_t be, if (first != instr) instr = first; - /* - * Parse the entry. - */ + /* Check the entry */ argp->returnval = NULL; + argp->returnlen = 0; + if (check_match(argp, instr, linelen) == 0) + continue; + + /* Marshall the data */ parse_stat = (*argp->str2ent)(instr, linelen, argp->buf.result, argp->buf.buffer, argp->buf.buflen); if (parse_stat == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; - if (check_match(argp)) { - res = NSS_SUCCESS; - if (_priv_exec->search_flag == GET_ONE) { - break; - } else if (_doexeclist(argp) == 0) { - res = NSS_UNAVAIL; - break; - } - } else { - argp->returnval = NULL; - memset(argp->buf.buffer, NULL, - argp->buf.buflen); + argp->returnval = (argp->buf.result != NULL)? + argp->buf.result : argp->buf.buffer; + argp->returnlen = linelen; + res = NSS_SUCCESS; + if (_priv_exec->search_flag == GET_ONE) { + break; + } else if (_doexeclist(argp) == 0) { + res = NSS_UNAVAIL; + break; } } else if (parse_stat == NSS_STR_PARSE_ERANGE) { argp->erange = 1; @@ -276,13 +291,13 @@ _exec_files_XY_all(files_backend_ptr_t be, static nss_status_t get_wild(files_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) { - char *orig_id = NULL; + const char *orig_id = NULL; char *old_id = NULL; char *wild_id = NULL; nss_status_t res = NSS_NOTFOUND; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - orig_id = strdup(_priv_exec->id); + orig_id = _priv_exec->id; old_id = strdup(_priv_exec->id); wild_id = old_id; while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) { @@ -318,6 +333,7 @@ getbyid(files_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYID); @@ -336,6 +352,7 @@ getbynameid(files_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYNAMEID); @@ -359,6 +376,7 @@ static files_backend_op_t execattr_ops[] = { getbynameid }; +/*ARGSUSED*/ nss_backend_t * _nss_files_exec_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getgrent.c b/usr/src/lib/nsswitch/files/common/getgrent.c index 82bc1989df..6f45136f16 100644 --- a/usr/src/lib/nsswitch/files/common/getgrent.c +++ b/usr/src/lib/nsswitch/files/common/getgrent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,37 +19,71 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getgrent.c -- "files" backend for nsswitch "group" database + * files/getgrent.c -- "files" backend for nsswitch "group" database */ #pragma ident "%Z%%M% %I% %E% SMI" #include <grp.h> #include <unistd.h> /* for GF_PATH */ +#include <stdlib.h> /* for GF_PATH */ #include "files_common.h" #include <strings.h> -static u_int -hash_grname(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_grname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct group *g = argp->returnval; - const char *name = keyhash ? argp->key.name : g->gr_name; - u_int hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } -static u_int -hash_grgid(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_grgid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct group *g = argp->returnval; - return (keyhash ? (u_int)argp->key.gid : (u_int)g->gr_gid); + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.gid); + + /* skip groupname */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (GID_NOBODY); + + /* gid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + /* empty gid */ + if (linep == end) + return (GID_NOBODY); + + return (id); } static files_hash_func hash_gr[2] = { hash_grname, hash_grgid }; @@ -64,15 +97,22 @@ static files_hash_t hashinfo = { }; static int -check_grname(argp) - nss_XbyY_args_t *argp; +check_grname(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct group *g = (struct group *)argp->returnval; + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; - /* +/- entries only valid in compat source */ - if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-')) + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(g->gr_name, argp->key.name) == 0); + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -84,15 +124,34 @@ getbyname(be, a) } static int -check_grgid(argp) - nss_XbyY_args_t *argp; +check_grgid(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct group *g = (struct group *)argp->returnval; + const char *linep, *limit, *end; + gid_t gr_gid; + + linep = line; + limit = line + linelen; + + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') + return (0); - /* +/- entries only valid in compat source */ - if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-')) + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) return (0); - return (g->gr_gid == argp->key.gid); + + /* uid */ + end = linep; + gr_gid = (gid_t)strtol(linep, (char **)&end, 10); + + /* empty gid is not valid */ + if (linep == end) + return (0); + + return (gr_gid == argp->key.gid); } static nss_status_t @@ -108,7 +167,7 @@ getbymember(be, a) files_backend_ptr_t be; void *a; { - struct nss_groupsbymem *argp = (struct nss_groupsbymem *) a; + struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a; return (_nss_files_do_all(be, argp, argp->username, (files_do_all_func_t)argp->process_cstr)); diff --git a/usr/src/lib/nsswitch/files/common/gethostent.c b/usr/src/lib/nsswitch/files/common/gethostent.c index 24dd4550c1..7012cbc856 100644 --- a/usr/src/lib/nsswitch/files/common/gethostent.c +++ b/usr/src/lib/nsswitch/files/common/gethostent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * files/gethostent.c -- "files" backend for nsswitch "hosts" database @@ -38,33 +37,84 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/nameser.h> +#include <arpa/inet.h> #include <ctype.h> -static int check_name(); +static int check_name(nss_XbyY_args_t *, const char *, int, + int, const char **, int *, void *, int *); static char *do_aliases(); -static char *strcasestr(); +static char *strcasestr(const char *as1, const char *as2); nss_status_t __nss_files_XY_hostbyname(); int __nss_files_2herrno(); +static int __nss_files_get_addr(int, const char *, int, + void *, int, int *); static int -check_name(host, args) - struct hostent *host; - nss_XbyY_args_t *args; +check_name(nss_XbyY_args_t *argp, const char *line, int linelen, + int type, const char **namep, int *namelen, + void *addrp, int *addrsize) { - const char *name = args->key.name; - char **aliasp; - - if (!host->h_name) - return (0); - if (strcasecmp(host->h_name, name) == 0) { - return (1); + const char *limit, *linep, *keyp, *addrstart; + int v6flag = 0, addrlen; + + linep = line; + limit = line + linelen; + + /* Address */ + addrstart = linep; + while (linep < limit && !isspace(*linep)) { + if (*linep == ':') + v6flag++; + linep++; } - for (aliasp = host->h_aliases; *aliasp != 0; aliasp++) { - if (strcasecmp(*aliasp, name) == 0) { + addrlen = linep - addrstart; + + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* Canonical name */ + keyp = argp->key.name; + *namep = linep; + while (*keyp && linep < limit && !isspace(*linep) && + tolower(*keyp) == tolower(*linep)) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) { + if (__nss_files_get_addr(type, addrstart, addrlen, + addrp, v6flag, addrsize)) { + *namelen = linep - *namep; return (1); } } + while (linep < limit && !isspace(*linep)) + linep++; + *namelen = linep - *namep; + + /* Aliases */ + while (linep < limit) { + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare name (case insensitive) */ + keyp = argp->key.name; + while (*keyp && linep < limit && !isspace(*linep) && + tolower(*keyp) == tolower(*linep)) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (__nss_files_get_addr(type, addrstart, addrlen, + addrp, v6flag, addrsize)); + + /* skip remainder of alias, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + } return (0); + } static nss_status_t @@ -81,22 +131,87 @@ getbyname(be, a) return (res); } +static int +__nss_files_get_addr(int af, const char *addrstart, int addrlen, + void *addrp, int v6flag, int *h_length) +{ + struct in_addr addr_ipv4; + struct in6_addr *addrpv6; + in_addr_t *addrpv4; + char addrbuf[INET6_ADDRSTRLEN + 1]; + + if (addrlen >= sizeof (addrbuf)) + return (0); + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + + if (af == AF_INET) { + addrpv4 = (in_addr_t *)addrp; + if ((*addrpv4 = inet_addr(addrbuf)) == 0xffffffffU) + return (0); + *h_length = sizeof (in_addr_t); + } else if (af == AF_INET6) { + addrpv6 = (struct in6_addr *)addrp; + if (v6flag) { + if (inet_pton(af, addrbuf, addrpv6) != 1) + return (0); + } else { + if ((addr_ipv4.s_addr = inet_addr(addrbuf)) == + 0xffffffffU) + return (0); + IN6_INADDR_TO_V4MAPPED(&addr_ipv4, addrpv6); + } + *h_length = sizeof (struct in6_addr); + } else { + return (0); + } + return (1); +} + int -__nss_files_check_addr(argp) - nss_XbyY_args_t *argp; +__nss_files_check_addr(int af, nss_XbyY_args_t *argp, const char *line, + int linelen) { - struct hostent *host = (struct hostent *)argp->returnval; + const char *limit, *linep, *addrstart; + int v6flag = 0, addrlen, h_length; + in_addr_t addr_ipv4; + struct in6_addr addr_ipv6; + char *h_addrp; + + /* Compare the address type */ + if (argp->key.hostaddr.type != af) + return (0); - /* - * We know that /etc/hosts can only store one address per host, so... - */ - return (host->h_length == argp->key.hostaddr.len && - host->h_addrtype == argp->key.hostaddr.type && - memcmp(host->h_addr_list[0], argp->key.hostaddr.addr, + /* Retrieve the address */ + if (af == AF_INET) + h_addrp = (char *)&addr_ipv4; + else + h_addrp = (char *)&addr_ipv6; + linep = line; + limit = line + linelen; + addrstart = linep; + while (linep < limit && !isspace(*linep)) { + if (*linep == ':') + v6flag++; + linep++; + } + addrlen = linep - addrstart; + if (__nss_files_get_addr(af, addrstart, addrlen, h_addrp, + v6flag, &h_length) == 0) + return (0); + + /* Compare the address */ + return (h_length == argp->key.hostaddr.len && + memcmp(h_addrp, argp->key.hostaddr.addr, argp->key.hostaddr.len) == 0); } +static int +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) +{ + return (__nss_files_check_addr(AF_INET, argp, line, linelen)); +} static nss_status_t getbyaddr(be, a) @@ -106,7 +221,7 @@ getbyaddr(be, a) nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; - res = _nss_files_XY_all(be, argp, 1, 0, __nss_files_check_addr); + res = _nss_files_XY_all(be, argp, 1, 0, check_addr); if (res != NSS_SUCCESS) argp->h_errno = __nss_files_2herrno(res); return (res); @@ -146,20 +261,21 @@ __nss_files_XY_hostbyname(be, args, filter, type) const char *filter; /* hint for name string */ int type; { - nss_status_t res; - int parsestat; - char *first; - char *last; - int i, nhosts = 0; - struct hostent he, *hp, *thp; - in_addr_t taddr[MAXADDRS]; - struct in6_addr taddr6[MAXADDRS]; - char *abuf = 0; /* alias buffer */ - char *abuf_start = 0, *abuf_end; - int (*func)(); - - if (be->buf == 0 && - (be->buf = malloc(be->minbuf)) == 0) { + nss_status_t res; + char *abuf = NULL, *abuf_start = NULL, *abuf_end; + char *first, *last, *buffer; + int parsestat, i, nhosts = 0, buflen; + const char *namep; + char *h_name; + int h_namelen, namelen; + struct hostent *hp; + in_addr_t *taddr = NULL; + struct in6_addr *taddr6 = NULL; + size_t ntaddr; + void *addrp; + char *alias_end = NULL; + + if (be->buf == 0 && (be->buf = malloc(be->minbuf)) == 0) { return (NSS_UNAVAIL); } @@ -168,10 +284,25 @@ __nss_files_XY_hostbyname(be, args, filter, type) return (res); } + ntaddr = MAXADDRS; + if (type == AF_INET) { + taddr = (in_addr_t *)calloc(ntaddr, sizeof (*taddr)); + if (taddr == NULL) + return (NSS_UNAVAIL); + } else { + taddr6 = (struct in6_addr *)calloc(ntaddr, sizeof (*taddr6)); + if (taddr6 == NULL) + return (NSS_UNAVAIL); + } + res = NSS_NOTFOUND; - args->erange = 0; args->returnval = (char *)0; - hp = thp = (struct hostent *)args->buf.result; + args->returnlen = 0; + hp = (struct hostent *)args->buf.result; + buffer = args->buf.buffer; + buflen = args->buf.buflen; + h_namelen = 0; + h_name = NULL; for (;;) { char *instr = be->buf; @@ -207,83 +338,189 @@ __nss_files_XY_hostbyname(be, args, filter, type) if (first != instr) instr = first; - if (nhosts && strcasestr(instr, hp->h_name) == 0) { - break; - } - /* - * If we've already matched once and have a possible match - * on this line, copy the aliases where they're safe from - * being overwritten when we look at the next entry. They're - * saved as a string of blank separated names for the alias - * parser. On errors, we return failure whether or not we - * have already obtained a valid address. - */ - if (nhosts == 1 && !abuf) { - abuf = malloc(args->buf.buflen); - if (abuf == NULL) { - res = NSS_UNAVAIL; - break; - } - abuf_start = &abuf[0]; - abuf_end = abuf_start + args->buf.buflen; - if (abuf + strlen(hp->h_name) + 1 > abuf_end) { - free(abuf_start); - abuf = NULL; - args->erange = 1; - res = NSS_NOTFOUND; - break; - } - (void) strcpy(abuf, hp->h_name); - abuf += strlen(hp->h_name); - *abuf++ = ' '; - abuf = do_aliases(hp, abuf, abuf_start, abuf_end); - if (abuf == NULL) { - args->erange = 1; - res = NSS_NOTFOUND; - break; - } - } - func = args->str2ent; - parsestat = (*func)(instr, linelen, thp, - args->buf.buffer, args->buf.buflen); - - if (parsestat != NSS_STR_PARSE_SUCCESS) { - if (parsestat == NSS_STR_PARSE_ERANGE) - args->erange = 1; + /* Bail out if the canonical name does not match */ + if (nhosts && strcasestr(instr, h_name) == 0) { continue; } /* * Still need to check, strcasestr() above is just a hint. */ + addrp = (type == AF_INET)? + (void *)&taddr[nhosts]: + (void *)&taddr6[nhosts]; + + if (check_name(args, instr, linelen, + type, &namep, &namelen, + addrp, &i)) { - if (type == thp->h_addrtype) - if (check_name(thp, args)) { - if (type == AF_INET) - taddr[nhosts++] = - (*(in_addr_t *)thp->h_addr_list[0]); - else { - memcpy(&taddr6[nhosts++], thp->h_addr_list[0], - sizeof (struct in6_addr)); + /* + * If we've already matched once and have a possible + * match on this line, copy the aliases where they're + * safe from being overwritten when we look at the + * next entry. They're saved as a string of blank + * separated names for the alias parser. On errors, + * we return failure whether or not we have already + * obtained a valid address. + */ + if (nhosts == 1 && hp) { + if (h_namelen + 1 > args->buf.buflen) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } + abuf = (char *)malloc(args->buf.buflen); + if (abuf == NULL) { + res = NSS_UNAVAIL; + break; + } + abuf_start = abuf; + abuf_end = abuf_start + args->buf.buflen; + (void) memcpy(abuf, h_name, h_namelen); + abuf += h_namelen; + *abuf = '\0'; + abuf = do_aliases(hp, abuf, abuf_end); + if (abuf == NULL) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } } + if (hp != NULL) { + /* inside the application */ + parsestat = (*args->str2ent)(instr, linelen, + hp, buffer, buflen); + if (parsestat != NSS_STR_PARSE_SUCCESS) { + if (parsestat == NSS_STR_PARSE_ERANGE) + args->erange = 1; + (void) memset(buffer, 0, buflen); + continue; + } + } else { + /* inside nscd */ + int alen, cplen, erange = 0; + char *ap; + + /* Add alias to the first line if any */ + if (nhosts > 0) { + + /* get to the start of alias */ + ap = (char *)namep + namelen; + /* see if there's any alias */ + if (ap == instr + linelen) + alen = 0; + else + alen = linelen - (ap - instr); + if (alen + 1 >= buflen) + erange = 1; + if (erange == 0 && alen != 0) { + /* make room for the alias */ + if (alias_end != NULL) + (void) memmove(alias_end + + alen, alias_end, buffer - + alias_end); + /* copy in the alias */ + (void) memmove(alias_end, + ap, alen); + buffer += alen; + buflen -= alen; + alias_end += alen; + } + + /* Add delimiter to the buffer */ + *buffer++ = '\n'; + buflen--; + args->returnlen++; + } + + /* copy just the addr if not first one */ + if (alias_end == NULL) + cplen = linelen; + else + cplen = namep - instr; + + if (cplen >= buflen || erange == 1) { + args->erange = 1; + if (nhosts > 0) { + *(--buffer) = '\0'; + buflen++; + args->returnlen--; + } + continue; + } + + (void) memcpy(buffer, instr, cplen); + /* Adjust buffer */ + buffer += cplen; + *buffer = '\0'; + buflen -= cplen; + if (alias_end == NULL) + alias_end = buffer; + } + + args->returnlen += linelen; - if (nhosts == 1) { + /* + * If this is the first one, save the canonical + * name for future matches and continue. + */ + if (++nhosts == 1) { + h_name = malloc(namelen + 1); + if (h_name == NULL) { + res = NSS_UNAVAIL; + break; + } res = NSS_SUCCESS; - args->returnval = args->buf.result; - thp = &he; /* switch to tmp hostent */ + (void) memcpy(h_name, namep, namelen); + h_name[namelen] = '\0'; + h_namelen = namelen; + if (hp) + args->returnval = hp; + else + args->returnval = args->buf.buffer; continue; } - if (nhosts >= MAXADDRS) - break; - abuf = do_aliases(thp, abuf, abuf_start, abuf_end); - if (abuf == NULL) { - args->erange = 1; - res = NSS_NOTFOUND; - break; + + + /* Extend the array */ + if (nhosts >= ntaddr) { + ntaddr *= 2; + if (type == AF_INET) { + addrp = realloc(taddr, + sizeof (*taddr) * ntaddr); + if (addrp == NULL) { + res = NSS_UNAVAIL; + break; + } + taddr = (in_addr_t *)addrp; + } else { + addrp = realloc(taddr6, + sizeof (*taddr6) * ntaddr); + if (addrp == NULL) { + res = NSS_UNAVAIL; + break; + } + taddr6 = (struct in6_addr *)addrp; + } + } + + /* + * For non-nscd, save aliases in a temporary buffer + * Don't have to do this for nscd as 'buffer' already + * contains the required data in the appropriate + * format + */ + if (hp) { + abuf = do_aliases(hp, abuf, abuf_end); + if (abuf == NULL) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } } - } else if (abuf && - strcasecmp(hp->h_name, thp->h_name) == 0) { + } else if (namep && h_namelen == namelen && + strncasecmp(h_name, namep, namelen) == 0) { /* * This line didn't have the requested name but * is part of the same multihomed host (i.e. it @@ -296,7 +533,10 @@ __nss_files_XY_hostbyname(be, args, filter, type) } } - if (abuf) { + if (abuf && res == NSS_SUCCESS) { + + /* abuf != NULL implies hp and abuf_start != NULL */ + struct in_addr *addrp; struct in6_addr *addrp6; @@ -318,8 +558,8 @@ __nss_files_XY_hostbyname(be, args, filter, type) ((nhosts + 1) * sizeof (char *) + (nhosts * sizeof (*addrp6))), sizeof (char *))); for (i = 0, --addrp6; i < nhosts; i++, --addrp6) { - memcpy(addrp6, &taddr6[i], - sizeof (struct in6_addr)); + (void) memcpy(addrp6, &taddr6[i], + sizeof (struct in6_addr)); hp->h_addr_list[i] = (char *)addrp6; } } @@ -330,12 +570,11 @@ __nss_files_XY_hostbyname(be, args, filter, type) (char *)hp->h_addr_list - args->buf.buffer); if (hp->h_aliases == 0) { args->erange = 1; - res = NSS_STR_PARSE_ERANGE; + res = NSS_NOTFOUND; } else { hp->h_name = hp->h_aliases[0]; hp->h_aliases++; } - free(abuf_start); } /* @@ -345,6 +584,15 @@ __nss_files_XY_hostbyname(be, args, filter, type) if (!args->stayopen) (void) _nss_files_endent(be, 0); + if (taddr) + free(taddr); + if (taddr6) + free(taddr6); + if (h_name) + free(h_name); + if (abuf_start) + free(abuf_start); + return (res); } @@ -352,13 +600,11 @@ __nss_files_XY_hostbyname(be, args, filter, type) * A case-insensitive version of strstr(). */ static char * -strcasestr(as1, as2) - char *as1; - char *as2; +strcasestr(const char *as1, const char *as2) { int c2; - register char *tptr; - register char *s1, *s2; + register const char *tptr; + register const char *s1, *s2; s1 = as1; s2 = as2; @@ -383,25 +629,22 @@ strcasestr(as1, as2) static char * -do_aliases(hp, abuf, start, end) - struct hostent *hp; - char *abuf; - char *start; - char *end; +do_aliases(struct hostent *hp, char *abuf, char *end) { - char **cp; + char **cp; + size_t len; - for (cp = hp->h_aliases; cp && *cp && **cp; cp++) { - size_t len; + if ((cp = hp->h_aliases) == NULL) + return (abuf); + for (; *cp; cp++) { len = strlen(*cp); if (abuf+len+1 >= end) { - free(start); - return ((char *)0); + return (NULL); } - (void) strcpy(abuf, *cp); - abuf += len; *abuf++ = ' '; + (void) memcpy(abuf, *cp, len); + abuf += len; } *abuf = '\0'; diff --git a/usr/src/lib/nsswitch/files/common/gethostent6.c b/usr/src/lib/nsswitch/files/common/gethostent6.c index 22d8703848..a47f1b5f45 100644 --- a/usr/src/lib/nsswitch/files/common/gethostent6.c +++ b/usr/src/lib/nsswitch/files/common/gethostent6.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 1988-1995, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * files/gethostent6.c -- "files" backend for nsswitch "hosts" database + * files/gethostent6.c -- "files" backend for nsswitch "hosts" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,8 +41,7 @@ extern nss_status_t __nss_files_XY_hostbyname(); extern int __nss_files_2herrno(); -extern int __nss_files_check_addr(nss_XbyY_args_t *); - +extern int __nss_files_check_addr(int, nss_XbyY_args_t *, const char *, int); static nss_status_t getbyname(be, a) @@ -60,7 +58,11 @@ getbyname(be, a) return (res); } - +static int +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) +{ + return (__nss_files_check_addr(AF_INET6, argp, line, linelen)); +} static nss_status_t getbyaddr(be, a) @@ -71,13 +73,12 @@ getbyaddr(be, a) nss_status_t res; - res = _nss_files_XY_all(be, argp, 1, 0, __nss_files_check_addr); + res = _nss_files_XY_all(be, argp, 1, 0, check_addr); if (res != NSS_SUCCESS) argp->h_errno = __nss_files_2herrno(res); return (res); } - static files_backend_op_t ipnodes_ops[] = { _nss_files_destr, _nss_files_endent, diff --git a/usr/src/lib/nsswitch/files/common/getnetent.c b/usr/src/lib/nsswitch/files/common/getnetent.c index 992f19326c..d47b78d324 100644 --- a/usr/src/lib/nsswitch/files/common/getnetent.c +++ b/usr/src/lib/nsswitch/files/common/getnetent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,55 +19,70 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. - * - * files/getnetent.c -- "files" backend for nsswitch "networks" database + * files/getnetent.c -- "files" backend for nsswitch "networks" database */ #pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <netdb.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct netent *net = (struct netent *)args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(net->n_name, name) == 0) - return (1); - for (aliasp = net->n_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) - return (1); - } - return (0); -} +#include <ctype.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct netent *net = (struct netent *)args->returnval; - return ((net->n_addrtype == args->key.netaddr.type) && - (net->n_net == args->key.netaddr.net)); + const char *limit, *linep, *addrstart; + int addrlen; + char addrbuf[NSS_LINELEN_NETWORKS]; + in_addr_t linenet; + + linep = line; + limit = line + linelen; + + /* skip network name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + + addrstart = linep; + while (linep < limit && !isspace(*linep)) + linep++; + addrlen = linep - addrstart; + if (addrlen < sizeof (addrbuf)) { + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + if ((linenet = inet_network(addrbuf)) == + (in_addr_t)0xffffffffU) + return (0); + return (AF_INET == argp->key.netaddr.type && + linenet == argp->key.netaddr.net); + } + return (0); } static nss_status_t @@ -76,7 +90,7 @@ getbyaddr(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 1, 0, check_addr)); } diff --git a/usr/src/lib/nsswitch/files/common/getprinter.c b/usr/src/lib/nsswitch/files/common/getprinter.c index c41771f8d2..8f5fab855b 100644 --- a/usr/src/lib/nsswitch/files/common/getprinter.c +++ b/usr/src/lib/nsswitch/files/common/getprinter.c @@ -36,140 +36,63 @@ static const char *printers = "/etc/printers.conf"; #include <stdlib.h> #include <strings.h> -static nss_status_t _nss_files_XY_printers(files_backend_ptr_t, - nss_XbyY_args_t *, const char *); - - -static nss_status_t -getent(be, a) - files_backend_ptr_t be; - void *a; +static int +check_name(nss_XbyY_args_t *argp, const char *line, int linelen) { - nss_XbyY_args_t *args = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, args, 0, 0, 0)); + const char *limit, *linep; + const char *keyp = argp->key.name; + int klen = strlen(keyp); + + linep = line; + limit = line + linelen; + + /* + * find the name in the namelist a|b|c...: + */ + while (linep+klen < limit && *linep != '|' && *linep != ':') { + if ((strncmp(linep, keyp, klen) == 0) && + ((*(linep + klen) == '|') || (*(linep + klen) == ':'))) { + return (1); + } else { + while (linep < limit && *linep != '|' && *linep != ':') + linep++; + if (linep >= limit || *linep == ':') + return (0); + if (*linep == '|') + linep++; + } + } + return (0); } - static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - nss_status_t res; - /* printers_getbyname() has not set/endent; rewind on each call */ - if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) { - return (res); - } - return (_nss_files_XY_printers(be, argp, argp->key.name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + check_name)); } static files_backend_op_t printers_ops[] = { _nss_files_destr, _nss_files_endent, _nss_files_setent, - getent, + _nss_files_getent_rigid, getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_printers_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; { return (_nss_files_constr(printers_ops, - sizeof (printers_ops) / sizeof (printers_ops[0]), - printers, - NSS_LINELEN_PRINTERS, - NULL)); -} - -/* - * printers has the hostname as part of the data in the file, but the other - * backends don't include it in the data passed to the backend. For this - * reason, we process everything here and don't bother calling the backend. - */ -static nss_status_t -_nss_files_XY_printers(be, args, filter) - files_backend_ptr_t be; - nss_XbyY_args_t *args; - const char *filter; - /* - * filter not useful here since the key - * we are looking for is the first "word" - * on the line and we can be fast enough. - */ -{ - nss_status_t res; - int parsestat; - int namelen; - - if (be->buf == 0 && - (be->buf = (char *)malloc(be->minbuf)) == 0) { - (void) _nss_files_endent(be, 0); - return (NSS_UNAVAIL); /* really panic, malloc failed */ - } - - res = NSS_NOTFOUND; - namelen = strlen(args->key.name); - - while (1) { - char *instr = be->buf; - char *p, *limit; - int linelen; - int found = 0; - - /* - * _nss_files_read_line does process the '\' that are used - * in /etc/printers.conf for continuation and gives one long - * buffer. - * - * linelen counts the characters up to but excluding the '\n' - */ - if ((linelen = _nss_files_read_line(be->f, instr, - be->minbuf)) < 0) { - /* End of file */ - args->returnval = 0; - args->erange = 0; - break; - } - p = instr; - - if (*p == '#') /* comment */ - continue; - - /* - * find the name in the namelist a|b|c...: - */ - if ((limit = strchr(instr, ':')) == NULL) /* bad line */ - continue; - while ((p < limit) && (found == 0)) { - if ((strncmp(p, args->key.name, namelen) == 0) && - ((*(p+namelen) == '|') || (*(p+namelen) == ':'))) - found++; - else { - if ((p = strchr(p, '|')) == NULL) - p = limit; - else /* skip the '|' */ - p++; - } - } - if (found == 0) - continue; - - p = instr; - - if (args->buf.buflen <= linelen) { /* not enough buffer */ - args->erange = 1; - break; - } - (void) memcpy(args->buf.buffer, p, linelen); - args->buf.buffer[linelen] = '\0'; - args->returnval = args->buf.result; - res = NSS_SUCCESS; - break; - } - (void) _nss_files_endent(be, 0); - return (res); + sizeof (printers_ops) / sizeof (printers_ops[0]), + printers, + NSS_LINELEN_PRINTERS, + NULL)); } diff --git a/usr/src/lib/nsswitch/files/common/getprofattr.c b/usr/src/lib/nsswitch/files/common/getprofattr.c index 67c49369b0..83d4369eaa 100644 --- a/usr/src/lib/nsswitch/files/common/getprofattr.c +++ b/usr/src/lib/nsswitch/files/common/getprofattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,24 +34,14 @@ * files/getprofattr.c -- * "files" backend for nsswitch "prof_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - profstr_t *prof = (profstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(prof->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t profattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t profattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_prof_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getprojent.c b/usr/src/lib/nsswitch/files/common/getprojent.c index cad512746c..e534760093 100644 --- a/usr/src/lib/nsswitch/files/common/getprojent.c +++ b/usr/src/lib/nsswitch/files/common/getprojent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -29,24 +28,57 @@ #include <sys/types.h> #include <project.h> #include <string.h> +#include <stdlib.h> #include "files_common.h" static uint_t -hash_projname(nss_XbyY_args_t *argp, int keyhash) { - struct project *p = argp->returnval; - const char *name = keyhash ? argp->key.name : p->pj_name; - uint_t hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - +hash_projname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { + + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } static uint_t -hash_projid(nss_XbyY_args_t *argp, int keyhash) { - struct project *p = argp->returnval; - return (keyhash ? (uint_t)argp->key.projid : (uint_t)p->pj_projid); +hash_projid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { + + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.projid); + + /* skip projname */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (0); + + /* projid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + if (linep == end) + return (0); + + return (id); } static files_hash_func hash_proj[2] = { @@ -63,26 +95,35 @@ static files_hash_t hashinfo = { }; static int -check_projname(nss_XbyY_args_t *argp) { - struct project *p = argp->returnval; +check_projid(nss_XbyY_args_t *argp, const char *line, int linelen) { + projid_t projid; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + /* skip projname */ + while (linep < limit && *linep++ != ':'); - if (p->pj_name == 0) + /* empty projname not allowed */ + if (linep == limit || linep == line + 1) return (0); - return (strcmp(p->pj_name, argp->key.name) == 0); -} -static int -check_projid(nss_XbyY_args_t *argp) { - struct project *p = argp->returnval; + /* projid */ + end = linep; + projid = (projid_t)strtol(linep, (char **)&end, 10); - if (p->pj_name == 0) + /* empty projid is not valid */ + if (linep == end) return (0); - return (p->pj_projid == argp->key.projid); + + return (projid == argp->key.projid); } static nss_status_t getbyname(files_backend_ptr_t be, void *a) { - return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_projname)); + return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, + _nss_files_check_name_colon)); } static nss_status_t diff --git a/usr/src/lib/nsswitch/files/common/getprotoent.c b/usr/src/lib/nsswitch/files/common/getprotoent.c index 25659b2e92..2f3578d13b 100644 --- a/usr/src/lib/nsswitch/files/common/getprotoent.c +++ b/usr/src/lib/nsswitch/files/common/getprotoent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getprotoent.c -- "files" backend for nsswitch "protocols" database + * files/getprotoent.c -- "files" backend for nsswitch "protocols" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,41 +30,39 @@ #include <netdb.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct protoent *proto = (struct protoent *)args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(proto->p_name, name) == 0) - return (1); - for (aliasp = proto->p_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) - return (1); - } - return (0); -} +#include <ctype.h> +#include <stdlib.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct protoent *proto = (struct protoent *)args->returnval; + int proto; + const char *limit, *linep; + + linep = line; + limit = line + linelen; - return (proto->p_proto == args->key.number); + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + proto = (int)strtol(linep, NULL, 10); + return (proto == argp->key.number); } static nss_status_t @@ -73,10 +70,10 @@ getbynumber(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_files_XY_all(be, argp, 1, 0, check_addr)); } diff --git a/usr/src/lib/nsswitch/files/common/getpwnam.c b/usr/src/lib/nsswitch/files/common/getpwnam.c index 303b8323c6..8faa2014eb 100644 --- a/usr/src/lib/nsswitch/files/common/getpwnam.c +++ b/usr/src/lib/nsswitch/files/common/getpwnam.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getpwnam.c -- "files" backend for nsswitch "passwd" database + * files/getpwnam.c -- "files" backend for nsswitch "passwd" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,25 +32,60 @@ #include <unistd.h> /* for PF_PATH */ #include "files_common.h" #include <strings.h> +#include <stdlib.h> -static u_int -hash_pwname(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_pwname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct passwd *p = argp->returnval; - const char *name = keyhash ? argp->key.name : p->pw_name; - u_int hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } -static u_int -hash_pwuid(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_pwuid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct passwd *p = argp->returnval; - return (keyhash ? (u_int)argp->key.uid : (u_int)p->pw_uid); + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.uid); + + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (UID_NOBODY); + + /* uid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + + /* empty uid */ + if (linep == end) + return (UID_NOBODY); + + return (id); } static files_hash_func hash_pw[2] = { hash_pwname, hash_pwuid }; @@ -65,15 +99,22 @@ static files_hash_t hashinfo = { }; static int -check_pwname(argp) - nss_XbyY_args_t *argp; +check_pwname(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct passwd *p = (struct passwd *)argp->returnval; + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; /* +/- entries valid for compat source only */ - if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-')) + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(p->pw_name, argp->key.name) == 0); + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -85,15 +126,34 @@ getbyname(be, a) } static int -check_pwuid(argp) - nss_XbyY_args_t *argp; +check_pwuid(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct passwd *p = (struct passwd *)argp->returnval; + const char *linep, *limit, *end; + uid_t pw_uid; + + linep = line; + limit = line + linelen; /* +/- entries valid for compat source only */ - if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-')) + if (linelen == 0 || *line == '+' || *line == '-') + return (0); + + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) return (0); - return (p->pw_uid == argp->key.uid); + + /* uid */ + end = linep; + pw_uid = (uid_t)strtol(linep, (char **)&end, 10); + + /* empty uid is not valid */ + if (linep == end) + return (0); + + return (pw_uid == argp->key.uid); } static nss_status_t diff --git a/usr/src/lib/nsswitch/files/common/getrpcent.c b/usr/src/lib/nsswitch/files/common/getrpcent.c index 789822c63c..3732c368dd 100644 --- a/usr/src/lib/nsswitch/files/common/getrpcent.c +++ b/usr/src/lib/nsswitch/files/common/getrpcent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getrpcent.c -- "files" backend for nsswitch "rpc" database + * files/getrpcent.c -- "files" backend for nsswitch "rpc" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,43 +30,39 @@ #include <rpc/rpcent.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct rpcent *rpc = (struct rpcent *) args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(rpc->r_name, name) == 0) { - return (1); - } - for (aliasp = rpc->r_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) { - return (1); - } - } - return (0); -} +#include <ctype.h> +#include <stdlib.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_rpcnum(argp) - nss_XbyY_args_t *argp; +check_rpcnum(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct rpcent *rpc = (struct rpcent *) argp->returnval; + int r_number; + const char *limit, *linep; + + linep = line; + limit = line + linelen; - return (rpc->r_number == argp->key.number); + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + r_number = (int)strtol(linep, NULL, 10); + return (r_number == argp->key.number); } @@ -76,10 +71,10 @@ getbynumber(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_files_XY_all(be, argp, 1, numstr, check_rpcnum)); } diff --git a/usr/src/lib/nsswitch/files/common/getservent.c b/usr/src/lib/nsswitch/files/common/getservent.c index 855b543d55..32e73ea3f6 100644 --- a/usr/src/lib/nsswitch/files/common/getservent.c +++ b/usr/src/lib/nsswitch/files/common/getservent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getservent.c -- "files" backend for nsswitch "services" database + * files/getservent.c -- "files" backend for nsswitch "services" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -32,27 +31,85 @@ #include "files_common.h" #include <sys/types.h> #include <netinet/in.h> +#include <inttypes.h> #include <strings.h> +#include <ctype.h> +#include <stdlib.h> static int -check_name(args) - nss_XbyY_args_t *args; +check_name(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct servent *serv = (struct servent *) args->returnval; - const char *name = args->key.serv.serv.name; - const char *proto = args->key.serv.proto; - char **aliasp; + const char *limit, *linep, *keyp; + int name_match = 0; - if (proto != 0 && strcmp(serv->s_proto, proto) != 0) { - return (0); + linep = line; + limit = line + linelen; + keyp = argp->key.serv.serv.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; } - if (strcmp(serv->s_name, name) == 0) { - return (1); + if (*keyp == '\0' && linep < limit && isspace(*linep)) { + if (argp->key.serv.proto == NULL) + return (1); + else + name_match = 1; } - for (aliasp = serv->s_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) { + + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip port number */ + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + + linep++; + if ((keyp = argp->key.serv.proto) == NULL) { + /* skip protocol */ + while (linep < limit && !isspace(*linep)) + linep++; + } else { + /* compare protocol */ + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + /* no protocol match */ + if (*keyp || (linep < limit && !isspace(*linep))) + return (0); + /* protocol and name match, return */ + if (name_match) return (1); + /* protocol match but name yet to be matched, so continue */ + } + + /* compare with the aliases */ + while (linep < limit) { + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare with the alias name */ + keyp = argp->key.serv.serv.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + + /* skip remainder of the alias name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; } return (0); } @@ -62,21 +119,56 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 1, argp->key.serv.serv.name, check_name)); } static int -check_port(args) - nss_XbyY_args_t *args; +check_port(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct servent *serv = (struct servent *) args->returnval; - const char *proto = args->key.serv.proto; + const char *limit, *linep, *keyp, *numstart; + int numlen, s_port; + char numbuf[12], *numend; + + linep = line; + limit = line + linelen; + + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare port num */ + numstart = linep; + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + numlen = linep - numstart; + if (numlen == 0 || numlen >= sizeof (numbuf)) + return (0); + (void) memcpy(numbuf, numstart, numlen); + numbuf[numlen] = '\0'; + s_port = htons((int)strtol(numbuf, &numend, 10)); + if (*numend != '\0') + return (0); + if (s_port == argp->key.serv.serv.port) { + if ((keyp = argp->key.serv.proto) == NULL) + return (1); + } else + return (0); - return (serv->s_port == args->key.serv.serv.port && - (proto == 0 || strcmp(serv->s_proto, proto) == 0)); + /* compare protocol */ + linep++; + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && (linep == limit || isspace(*linep))); } static nss_status_t @@ -84,10 +176,10 @@ getbyport(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char portstr[12]; - sprintf(portstr, "%d", ntohs(argp->key.serv.serv.port)); + (void) snprintf(portstr, 12, "%d", ntohs(argp->key.serv.serv.port)); return (_nss_files_XY_all(be, argp, 1, portstr, check_port)); } diff --git a/usr/src/lib/nsswitch/files/common/getspent.c b/usr/src/lib/nsswitch/files/common/getspent.c index 7287f024d2..af280b6d74 100644 --- a/usr/src/lib/nsswitch/files/common/getspent.c +++ b/usr/src/lib/nsswitch/files/common/getspent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getspent.c -- "files" backend for nsswitch "shadow" database + * files/getspent.c -- "files" backend for nsswitch "shadow" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,15 +32,19 @@ #include <strings.h> static int -check_spnamp(argp) - nss_XbyY_args_t *argp; +check_spnamp(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct spwd *s = (struct spwd *)argp->returnval; + const char *linep = line; + const char *keyp = argp->key.name; - /* +/- entries valid in compat source only */ - if (s->sp_namp != 0 && (s->sp_namp[0] == '+' || s->sp_namp[0] == '-')) + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(s->sp_namp, argp->key.name) == 0); + while (*keyp && linelen-- && *keyp == *linep) { + keyp++; + linep++; + } + return (linelen && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -49,7 +52,7 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 0, argp->key.name, check_spnamp)); } diff --git a/usr/src/lib/nsswitch/files/common/getuserattr.c b/usr/src/lib/nsswitch/files/common/getuserattr.c index 82f377c5da..3ada2a420f 100644 --- a/usr/src/lib/nsswitch/files/common/getuserattr.c +++ b/usr/src/lib/nsswitch/files/common/getuserattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,24 +34,14 @@ * files/getuserattr.c -- * "files" backend for nsswitch "user_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - userstr_t *user = (userstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(user->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t userattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t userattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_user_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/netmasks.c b/usr/src/lib/nsswitch/files/common/netmasks.c index 876fcf66a6..2fe4a2fe1b 100644 --- a/usr/src/lib/nsswitch/files/common/netmasks.c +++ b/usr/src/lib/nsswitch/files/common/netmasks.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,10 @@ * CDDL HEADER END */ /* - * files/netmasks.c -- "files" backend for nsswitch "netmasks" database + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1996 Sun Microsystems Inc - * All Rights Reserved. + * files/netmasks.c -- "files" backend for nsswitch "netmasks" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -43,20 +42,45 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <nss_dbdefs.h> +#include <ctype.h> /* * Validate 'files' netmasks entry. The comparison objects are in IPv4 * internet address format. */ static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct in_addr tmp; + const char *limit, *linep, *addrstart; + int addrlen; + char addrbuf[NSS_LINELEN_NETMASKS]; + struct in_addr lineaddr, argsaddr; - tmp.s_addr = inet_addr(args->key.name); - return (memcmp(args->buf.buffer, (char *)&tmp, - sizeof (struct in_addr)) == 0); + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + addrstart = linep; + while (linep < limit && !isspace(*linep)) + linep++; + if (linep == limit) + return (0); + addrlen = linep - addrstart; + if (addrlen < sizeof (addrbuf)) { + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + if ((lineaddr.s_addr = inet_addr(addrbuf)) == + (in_addr_t)0xffffffffU) + return (0); + if ((argsaddr.s_addr = inet_addr(argp->key.name)) + == (in_addr_t)0xffffffffU) + return (0); + return (lineaddr.s_addr == argsaddr.s_addr); + } + return (0); } static nss_status_t @@ -64,15 +88,46 @@ getbynet(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; char tmpbuf[NSS_LINELEN_NETMASKS]; - argp->buf.buffer = tmpbuf; - argp->buf.buflen = NSS_LINELEN_NETMASKS; + /* + * use the buffer passed in if result is to be returned + * in /etc file format + */ + if (argp->buf.result != NULL) { + argp->buf.buffer = tmpbuf; + argp->buf.buflen = NSS_LINELEN_NETMASKS; + } res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_addr); - argp->buf.buffer = NULL; - argp->buf.buflen = 0; + if (argp->buf.result != NULL) { + argp->buf.buffer = NULL; + argp->buf.buflen = 0; + } else { + /* the frontend expects the netmask data only */ + if (res == NSS_SUCCESS) { + char *m; + char *s = (char *)argp->returnval; + int l = 0; + + m = s + argp->returnlen - 1; + + /* skip trailing spaces */ + while (s < m && isspace(*m)) + m--; + + for (; s <= m; m--) { + if (isspace(*m)) + break; + l++; + } + m++; + (void) memmove(argp->returnval, m, l); + argp->returnlen = l; + *(s + l) = '\0'; + } + } return (res); } diff --git a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c index f41f606034..180a660189 100644 --- a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c +++ b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c @@ -28,30 +28,102 @@ #include "files_common.h" #include <string.h> #include <libtsnet.h> +#include <netinet/in.h> /* * files/tsol_getrhent.c -- * "files" backend for nsswitch "tnrhdb" database */ static int -check_addr(nss_XbyY_args_t *args) +check_addr(nss_XbyY_args_t *args, const char *line, int linelen) { - tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)args->returnval; + const char *limit, *linep, *keyp; + char prev; + int ipv6; - if ((args->key.hostaddr.type == rhstrp->family) && - (strcmp(args->key.hostaddr.addr, rhstrp->address) == 0)) + linep = line; + limit = line + linelen; + keyp = args->key.hostaddr.addr; + prev = '\0'; + + if (strstr(linep, "\\:") != NULL) + ipv6 = 1; + else + ipv6 = 0; + + /* + * compare addr in + * + * 192.168.120.6:public + * fec0\:\:a00\:20ff\:fea0\:21f7:cipso + * + * ':' is the seperator. + */ + + while (*keyp && linep < limit && *keyp == *linep) { + if ((ipv6 == 0 && *linep == ':') || + (ipv6 == 1 && prev != '\\' && *linep == ':')) + break; + + prev = *linep; + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') || + (ipv6 == 1 && prev != '\\' && *linep == ':'))) return (1); return (0); } +static void +escape_colon(const char *in, char *out) { + int i, j; + for (i = 0, j = 0; in[i] != '\0'; i++) { + if (in[i] == ':') { + out[j++] = '\\'; + out[j++] = in[i]; + } else + out[j++] = in[i]; + } + out[j] = '\0'; +} + static nss_status_t getbyaddr(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = a; + char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */ + const char *addr = NULL; + nss_status_t rc; + + if (argp->key.hostaddr.addr == NULL || + (argp->key.hostaddr.type != AF_INET && + argp->key.hostaddr.type != AF_INET6)) + return (NSS_NOTFOUND); + if (strchr(argp->key.hostaddr.addr, ':') != NULL) { + /* IPV6 */ + if (argp->key.hostaddr.type == AF_INET) + return (NSS_NOTFOUND); + escape_colon(argp->key.hostaddr.addr, addr6); + /* save the key in original format */ + addr = argp->key.hostaddr.addr; + /* Replace the key with escaped format */ + argp->key.hostaddr.addr = addr6; + } else { + /* IPV4 */ + if (argp->key.hostaddr.type == AF_INET6) + return (NSS_NOTFOUND); + } + + rc = _nss_files_XY_all(be, argp, 1, + argp->key.hostaddr.addr, check_addr); + + /* restore argp->key.hostaddr.addr */ + if (addr) + argp->key.hostaddr.addr = addr; - return (_nss_files_XY_all(be, argp, 1, - argp->key.hostaddr.addr, check_addr)); + return (rc); } static files_backend_op_t tsol_rh_ops[] = { @@ -62,9 +134,10 @@ static files_backend_op_t tsol_rh_ops[] = { getbyaddr }; -/* ARGSUSED */ nss_backend_t * +/* LINTED E_FUNC_ARG_UNUSED */ _nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2, +/* LINTED E_FUNC_ARG_UNUSED */ const char *dummy3) { return (_nss_files_constr(tsol_rh_ops, diff --git a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c index ae5e9ca2be..dd604a5ee9 100644 --- a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c +++ b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c @@ -34,12 +34,20 @@ * "files" backend for nsswitch "tnrhtp" database */ static int -check_name(nss_XbyY_args_t *args) +check_name(nss_XbyY_args_t *args, const char *line, int linelen) { - tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)args->returnval; - const char *name = args->key.name; + const char *limit, *linep, *keyp; - if (strcmp(tpstrp->template, name) == 0) + linep = line; + limit = line + linelen; + keyp = args->key.name; + + /* compare template name, ':' is the seperator */ + while (*keyp && linep < limit && *linep != ':' && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && *linep == ':') return (1); return (0); @@ -52,6 +60,9 @@ getbyname(be, a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + if (argp->key.name == NULL) + return (NSS_NOTFOUND); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); } @@ -62,8 +73,8 @@ static files_backend_op_t tsol_tp_ops[] = { _nss_files_getent_netdb, getbyname }; - nss_backend_t * +/* LINTED E_FUNC_ARG_UNUSED */ _nss_files_tnrhtp_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; { |