diff options
Diffstat (limited to 'usr/src/lib/nsswitch/files/common')
23 files changed, 1351 insertions, 667 deletions
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; { |