summaryrefslogtreecommitdiff
path: root/usr/src/lib/nsswitch/files/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/nsswitch/files/common')
-rw-r--r--usr/src/lib/nsswitch/files/common/bootparams_getbyname.c18
-rw-r--r--usr/src/lib/nsswitch/files/common/ether_addr.c89
-rw-r--r--usr/src/lib/nsswitch/files/common/files_common.c142
-rw-r--r--usr/src/lib/nsswitch/files/common/files_common.h10
-rw-r--r--usr/src/lib/nsswitch/files/common/getauthattr.c24
-rw-r--r--usr/src/lib/nsswitch/files/common/getauuser.c24
-rw-r--r--usr/src/lib/nsswitch/files/common/getexecattr.c90
-rw-r--r--usr/src/lib/nsswitch/files/common/getgrent.c123
-rw-r--r--usr/src/lib/nsswitch/files/common/gethostent.c501
-rw-r--r--usr/src/lib/nsswitch/files/common/gethostent6.c21
-rw-r--r--usr/src/lib/nsswitch/files/common/getnetent.c78
-rw-r--r--usr/src/lib/nsswitch/files/common/getprinter.c145
-rw-r--r--usr/src/lib/nsswitch/files/common/getprofattr.c24
-rw-r--r--usr/src/lib/nsswitch/files/common/getprojent.c95
-rw-r--r--usr/src/lib/nsswitch/files/common/getprotoent.c59
-rw-r--r--usr/src/lib/nsswitch/files/common/getpwnam.c118
-rw-r--r--usr/src/lib/nsswitch/files/common/getrpcent.c61
-rw-r--r--usr/src/lib/nsswitch/files/common/getservent.c146
-rw-r--r--usr/src/lib/nsswitch/files/common/getspent.c29
-rw-r--r--usr/src/lib/nsswitch/files/common/getuserattr.c24
-rw-r--r--usr/src/lib/nsswitch/files/common/netmasks.c89
-rw-r--r--usr/src/lib/nsswitch/files/common/tsol_getrhent.c87
-rw-r--r--usr/src/lib/nsswitch/files/common/tsol_gettpent.c21
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;
{