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.c166
-rw-r--r--usr/src/lib/nsswitch/files/common/ether_addr.c116
-rw-r--r--usr/src/lib/nsswitch/files/common/files_common.c606
-rw-r--r--usr/src/lib/nsswitch/files/common/files_common.h140
-rw-r--r--usr/src/lib/nsswitch/files/common/getauthattr.c79
-rw-r--r--usr/src/lib/nsswitch/files/common/getauuser.c75
-rw-r--r--usr/src/lib/nsswitch/files/common/getexecattr.c377
-rw-r--r--usr/src/lib/nsswitch/files/common/getgrent.c137
-rw-r--r--usr/src/lib/nsswitch/files/common/gethostent.c434
-rw-r--r--usr/src/lib/nsswitch/files/common/gethostent6.c100
-rw-r--r--usr/src/lib/nsswitch/files/common/getnetent.c103
-rw-r--r--usr/src/lib/nsswitch/files/common/getprinter.c176
-rw-r--r--usr/src/lib/nsswitch/files/common/getprofattr.c78
-rw-r--r--usr/src/lib/nsswitch/files/common/getprojent.c112
-rw-r--r--usr/src/lib/nsswitch/files/common/getprotoent.c102
-rw-r--r--usr/src/lib/nsswitch/files/common/getpwnam.c126
-rw-r--r--usr/src/lib/nsswitch/files/common/getrpcent.c105
-rw-r--r--usr/src/lib/nsswitch/files/common/getservent.c113
-rw-r--r--usr/src/lib/nsswitch/files/common/getspent.c75
-rw-r--r--usr/src/lib/nsswitch/files/common/getuserattr.c78
-rw-r--r--usr/src/lib/nsswitch/files/common/mapfile-vers64
-rw-r--r--usr/src/lib/nsswitch/files/common/netmasks.c93
22 files changed, 3455 insertions, 0 deletions
diff --git a/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c
new file mode 100644
index 0000000000..ef51910acb
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * 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"
+
+static const char *bootparams = "/etc/bootparams";
+
+#include "files_common.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+
+static nss_status_t _nss_files_XY_bootparams(files_backend_ptr_t,
+ nss_XbyY_args_t *, const char *);
+
+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;
+
+ /* bootparams_getbyname() has not set/endent; rewind on each call */
+ if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) {
+ return (res);
+ }
+ return (_nss_files_XY_bootparams(be, argp, argp->key.name));
+}
+
+static files_backend_op_t bootparams_ops[] = {
+ _nss_files_destr,
+ getbyname
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_bootparams_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(bootparams_ops,
+ sizeof (bootparams_ops) / sizeof (bootparams_ops[0]),
+ bootparams,
+ NSS_LINELEN_BOOTPARAMS,
+ NULL));
+}
+
+/*
+ * bootparams 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.
+ */
+/*ARGSUSED*/
+static nss_status_t
+_nss_files_XY_bootparams(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;
+
+ 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;
+
+ /*CONSTCOND*/
+ while (1) {
+ char *instr = be->buf;
+ char *p, *host, *limit;
+ int linelen;
+
+ /*
+ * _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;
+ break;
+ }
+
+ /*
+ * we need to strip off the host name before returning it.
+ */
+ p = instr;
+ limit = p + linelen;
+
+ /* Skip over leading whitespace */
+ while (p < limit && isspace(*p)) {
+ p++;
+ }
+ host = p;
+
+ /* Skip over the hostname */
+ while (p < limit && !isspace(*p)) {
+ p++;
+ }
+ *p++ = '\0';
+
+ if (strcasecmp(args->key.name, host) != 0) {
+ continue;
+ }
+
+ /* Skip over whitespace between name and first datum */
+ while (p < limit && isspace(*p)) {
+ p++;
+ }
+ if (p >= limit) {
+ /* Syntax error -- no data! Just skip it. */
+ continue;
+ }
+
+ linelen -= (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);
+}
diff --git a/usr/src/lib/nsswitch/files/common/ether_addr.c b/usr/src/lib/nsswitch/files/common/ether_addr.c
new file mode 100644
index 0000000000..4731e0c354
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/ether_addr.c
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * files/ether_addr.c -- "files" backend for nsswitch "ethers" database
+ *
+ * Copyright 1988-1995,2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * All routines necessary to deal with the file /etc/ethers. The file
+ * contains mappings from 48 bit ethernet addresses to their corresponding
+ * hosts names. The addresses have an ascii representation of the form
+ * "x:x:x:x:x:x" where x is a hex number between 0x00 and 0xff; the
+ * bytes are always in network order.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <nss_dbdefs.h>
+#include "files_common.h"
+#include <strings.h>
+
+#define _PATH_ETHERS "/etc/ethers"
+
+static int
+check_host(args)
+ nss_XbyY_args_t *args;
+{
+ return (strcmp(args->buf.buffer, args->key.name) == 0);
+}
+
+static nss_status_t
+getbyhost(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+ char hostname[MAXHOSTNAMELEN];
+ nss_status_t res;
+
+ 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;
+ return (res);
+}
+
+static int
+check_ether(args)
+ nss_XbyY_args_t *args;
+{
+ return (ether_cmp(args->buf.result, args->key.ether) == 0);
+}
+
+static nss_status_t
+getbyether(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+ struct ether_addr etheraddr;
+ nss_status_t res;
+
+ argp->buf.result = &etheraddr;
+
+ res = _nss_files_XY_all(be, argp, 0, NULL, check_ether);
+
+ argp->buf.result = NULL;
+ return (res);
+}
+
+static files_backend_op_t ethers_ops[] = {
+ _nss_files_destr,
+ getbyhost,
+ getbyether
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_ethers_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(ethers_ops,
+ sizeof (ethers_ops) / sizeof (ethers_ops[0]),
+ _PATH_ETHERS,
+ NSS_LINELEN_ETHERS,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/files_common.c b/usr/src/lib/nsswitch/files/common/files_common.c
new file mode 100644
index 0000000000..2a8c30bc43
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/files_common.c
@@ -0,0 +1,606 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1995-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Common code and structures used by name-service-switch "files" backends.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * An implementation that used mmap() sensibly would be a wonderful thing,
+ * but this here is just yer standard fgets() thang.
+ */
+
+#include "files_common.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/*ARGSUSED*/
+nss_status_t
+_nss_files_setent(be, dummy)
+ files_backend_ptr_t be;
+ void *dummy;
+{
+ if (be->f == 0) {
+ if (be->filename == 0) {
+ /* Backend isn't initialized properly? */
+ return (NSS_UNAVAIL);
+ }
+ if ((be->f = __nsl_fopen(be->filename, "r")) == 0) {
+ return (NSS_UNAVAIL);
+ }
+ } else {
+ __nsl_rewind(be->f);
+ }
+ return (NSS_SUCCESS);
+}
+
+/*ARGSUSED*/
+nss_status_t
+_nss_files_endent(be, dummy)
+ files_backend_ptr_t be;
+ void *dummy;
+{
+ if (be->f != 0) {
+ __nsl_fclose(be->f);
+ be->f = 0;
+ }
+ if (be->buf != 0) {
+ free(be->buf);
+ be->buf = 0;
+ }
+ return (NSS_SUCCESS);
+}
+
+/*
+ * This routine reads a line, including the processing of continuation
+ * characters. It always leaves (or inserts) \n\0 at the end of the line.
+ * It returns the length of the line read, excluding the \n\0. Who's idea
+ * was this?
+ * Returns -1 on EOF.
+ *
+ * Note that since each concurrent call to _nss_files_read_line has
+ * it's own FILE pointer, we can use getc_unlocked w/o difficulties,
+ * a substantial performance win.
+ */
+int
+_nss_files_read_line(f, buffer, buflen)
+ __NSL_FILE *f;
+ char *buffer;
+ int buflen;
+{
+ int linelen; /* 1st unused slot in buffer */
+ int c;
+
+ /*CONSTCOND*/
+ while (1) {
+ linelen = 0;
+ while (linelen < buflen - 1) { /* "- 1" saves room for \n\0 */
+ switch (c = __nsl_getc_unlocked(f)) {
+ case EOF:
+ if (linelen == 0 ||
+ buffer[linelen - 1] == '\\') {
+ return (-1);
+ } else {
+ buffer[linelen ] = '\n';
+ buffer[linelen + 1] = '\0';
+ return (linelen);
+ }
+ case '\n':
+ if (linelen > 0 &&
+ buffer[linelen - 1] == '\\') {
+ --linelen; /* remove the '\\' */
+ } else {
+ buffer[linelen ] = '\n';
+ buffer[linelen + 1] = '\0';
+ return (linelen);
+ }
+ break;
+ default:
+ buffer[linelen++] = c;
+ }
+ }
+ /* Buffer overflow -- eat rest of line and loop again */
+ /* ===> Should syslog() */
+ do {
+ c = __nsl_getc_unlocked(f);
+ if (c == EOF) {
+ return (-1);
+ }
+ } while (c != '\n');
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * used only for getgroupbymem() now.
+ */
+nss_status_t
+_nss_files_do_all(be, args, filter, func)
+ files_backend_ptr_t be;
+ void *args;
+ const char *filter;
+ files_do_all_func_t func;
+{
+ char *buffer;
+ int buflen;
+ nss_status_t res;
+
+ if (be->buf == 0 &&
+ (be->buf = malloc(be->minbuf)) == 0) {
+ return (NSS_UNAVAIL);
+ }
+ buffer = be->buf;
+ buflen = be->minbuf;
+
+ if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) {
+ return (res);
+ }
+
+ res = NSS_NOTFOUND;
+
+ do {
+ int linelen;
+
+ if ((linelen = _nss_files_read_line(be->f, buffer,
+ buflen)) < 0) {
+ /* End of file */
+ break;
+ }
+ if (filter != 0 && strstr(buffer, filter) == 0) {
+ /*
+ * Optimization: if the entry doesn't contain the
+ * filter string then it can't be the entry we want,
+ * so don't bother looking more closely at it.
+ */
+ continue;
+ }
+ res = (*func)(buffer, linelen, args);
+
+ } while (res == NSS_NOTFOUND);
+
+ _nss_files_endent(be, 0);
+ return (res);
+}
+
+/*
+ * Could implement this as an iterator function on top of _nss_files_do_all(),
+ * but the shared code is small enough that it'd be pretty silly.
+ */
+nss_status_t
+_nss_files_XY_all(be, args, netdb, filter, check)
+ files_backend_ptr_t be;
+ nss_XbyY_args_t *args;
+ int netdb; /* whether it uses netdb */
+ /* format or not */
+ const char *filter; /* advisory, to speed up */
+ /* string search */
+ files_XY_check_func check; /* NULL means one-shot, for getXXent */
+{
+ nss_status_t res;
+ int parsestat;
+ int (*func)();
+
+ if (be->buf == 0 &&
+ (be->buf = malloc(be->minbuf)) == 0) {
+ return (NSS_UNAVAIL); /* really panic, malloc failed */
+ }
+
+ if (check != 0 || be->f == 0) {
+ if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) {
+ return (res);
+ }
+ }
+
+ res = NSS_NOTFOUND;
+
+ /*CONSTCOND*/
+ while (1) {
+ char *instr = be->buf;
+ int linelen;
+
+ if ((linelen = _nss_files_read_line(be->f, instr,
+ be->minbuf)) < 0) {
+ /* End of file */
+ args->returnval = 0;
+ args->erange = 0;
+ break;
+ }
+ if (filter != 0 && strstr(instr, filter) == 0) {
+ /*
+ * Optimization: if the entry doesn't contain the
+ * filter string then it can't be the entry we want,
+ * so don't bother looking more closely at it.
+ */
+ continue;
+ }
+ if (netdb) {
+ char *first;
+ char *last;
+
+ if ((last = strchr(instr, '#')) == 0) {
+ last = instr + linelen;
+ }
+ *last-- = '\0'; /* Nuke '\n' or #comment */
+
+ /*
+ * Skip leading whitespace. Normally there isn't
+ * any, so it's not worth calling strspn().
+ */
+ for (first = instr; isspace(*first); first++) {
+ ;
+ }
+ if (*first == '\0') {
+ continue;
+ }
+ /*
+ * Found something non-blank on the line. Skip back
+ * over any trailing whitespace; since we know
+ * there's non-whitespace earlier in the line,
+ * checking for termination is easy.
+ */
+ while (isspace(*last)) {
+ --last;
+ }
+
+ linelen = last - first + 1;
+ if (first != instr) {
+ instr = first;
+ }
+ }
+
+ args->returnval = 0;
+
+ 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;
+ }
+ } else if (parsestat == NSS_STR_PARSE_ERANGE) {
+ args->erange = 1;
+ break;
+ } /* else if (parsestat == NSS_STR_PARSE_PARSE) don't care ! */
+ }
+
+ /*
+ * stayopen is set to 0 by default in order to close the opened
+ * file. Some applications may break if it is set to 1.
+ */
+ if (check != 0 && !args->stayopen) {
+ (void) _nss_files_endent(be, 0);
+ }
+
+ return (res);
+}
+
+/*
+ * File hashing support. Critical for sites with large (e.g. 1000+ lines)
+ * /etc/passwd or /etc/group files. Currently only used by getpw*() and
+ * getgr*() routines, but any files backend can use this stuff.
+ */
+static void
+_nss_files_hash_destroy(files_hash_t *fhp)
+{
+ free(fhp->fh_table);
+ fhp->fh_table = NULL;
+ free(fhp->fh_line);
+ fhp->fh_line = NULL;
+ free(fhp->fh_file_start);
+ fhp->fh_file_start = NULL;
+}
+#ifdef PIC
+/*
+ * It turns out the hashing stuff really needs to be disabled for processes
+ * other than the nscd; the consumption of swap space and memory is otherwise
+ * unacceptable when the nscd is killed w/ a large passwd file (4M) active.
+ * See 4031930 for details.
+ * So we just use this psuedo function to enable the hashing feature. Since
+ * this function name is private, we just create a function w/ the name
+ * __nss_use_files_hash in the nscd itself and everyone else uses the old
+ * interface.
+ * We also disable hashing for .a executables to avoid problems with large
+ * files....
+ */
+
+#pragma weak __nss_use_files_hash
+
+extern void __nss_use_files_hash(void);
+#endif /* pic */
+
+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)
+{
+ int fd, retries, ht;
+ uint_t hash, line, f;
+ files_hashent_t *hp, *htab;
+ char *cp, *first, *last;
+ nss_XbyY_args_t xargs;
+ struct stat64 st;
+
+#ifndef PIC
+ return (_nss_files_XY_all(be, args, netdb, 0, check));
+}
+#else
+ if (__nss_use_files_hash == 0)
+ return (_nss_files_XY_all(be, args, netdb, 0, check));
+
+ mutex_lock(&fhp->fh_lock);
+retry:
+ retries = 100;
+ while (stat64(be->filename, &st) < 0) {
+ /*
+ * On a healthy system this can't happen except during brief
+ * periods when the file is being modified/renamed. Keep
+ * trying until things settle down, but eventually give up.
+ */
+ if (--retries == 0)
+ goto unavail;
+ poll(0, 0, 100);
+ }
+
+ if (st.st_mtim.tv_sec == fhp->fh_mtime.tv_sec &&
+ 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);
+ 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 ((*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);
+ }
+ } else {
+ args->erange = 1;
+ }
+ }
+ args->returnval = 0;
+ mutex_unlock(&fhp->fh_lock);
+ return (NSS_NOTFOUND);
+ }
+
+ _nss_files_hash_destroy(fhp);
+
+ if (st.st_size > SSIZE_MAX)
+ goto unavail;
+
+ if ((fhp->fh_file_start = malloc((ssize_t)st.st_size + 1)) == NULL)
+ goto unavail;
+
+ if ((fd = open(be->filename, O_RDONLY)) < 0)
+ goto unavail;
+
+ if (read(fd, fhp->fh_file_start, (ssize_t)st.st_size) !=
+ (ssize_t)st.st_size) {
+ close(fd);
+ goto retry;
+ }
+
+ close(fd);
+
+ fhp->fh_file_end = fhp->fh_file_start + (off_t)st.st_size;
+ *fhp->fh_file_end = '\n';
+ fhp->fh_mtime = st.st_mtim;
+
+ /*
+ * If the file changed since we read it, or if it's less than
+ * 1-2 seconds old, don't trust it; its modification may still
+ * be in progress. The latter is a heuristic hack to minimize
+ * the likelihood of damage if someone modifies /etc/mumble
+ * directly (as opposed to editing and renaming a temp file).
+ *
+ * Note: the cast to u_int is there in case (1) someone rdated
+ * the system backwards since the last modification of /etc/mumble
+ * or (2) this is a diskless client whose time is badly out of sync
+ * with its server. The 1-2 second age hack doesn't cover these
+ * cases -- oh well.
+ */
+ if (stat64(be->filename, &st) < 0 ||
+ st.st_mtim.tv_sec != fhp->fh_mtime.tv_sec ||
+ st.st_mtim.tv_nsec != fhp->fh_mtime.tv_nsec ||
+ (uint_t)(time(0) - st.st_mtim.tv_sec + 2) < 4) {
+ poll(0, 0, 1000);
+ goto retry;
+ }
+
+ line = 1;
+ for (cp = fhp->fh_file_start; cp < fhp->fh_file_end; cp++)
+ if (*cp == '\n')
+ line++;
+
+ for (f = 2; f * f <= line; f++) { /* find next largest prime */
+ if (line % f == 0) {
+ f = 1;
+ line++;
+ }
+ }
+
+ fhp->fh_size = line;
+ fhp->fh_line = malloc(line * sizeof (files_linetab_t));
+ fhp->fh_table = calloc(line * fhp->fh_nhtab, sizeof (files_hashent_t));
+ 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) {
+ first = cp;
+ while (*cp != '\n')
+ cp++;
+ if (cp > first && *(cp - 1) == '\\') {
+ memmove(first + 2, first, cp - first - 1);
+ cp = first + 2;
+ continue;
+ }
+ last = cp;
+ *cp++ = '\0';
+ if (netdb) {
+ if ((last = strchr(first, '#')) == 0)
+ last = cp - 1;
+ *last-- = '\0'; /* nuke '\n' or #comment */
+ while (isspace(*first)) /* nuke leading whitespace */
+ first++;
+ if (*first == '\0') /* skip content-free lines */
+ continue;
+ while (isspace(*last)) /* nuke trailing whitespace */
+ --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);
+ }
+ 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
+ * end up in forward order. This ensures that hashed lookups find
+ * things in the same order that a linear search of the file would.
+ * This is essential in cases where there could be multiple matches.
+ * For example: until 2.7, root and smtp both had uid 0; but we
+ * certainly wouldn't want getpwuid(0) to return smtp.
+ */
+ for (ht = 0; ht < fhp->fh_nhtab; ht++) {
+ htab = &fhp->fh_table[ht * fhp->fh_size];
+ for (hp = &htab[line - 1]; hp >= htab; hp--) {
+ uint_t bucket = hp->h_hash % fhp->fh_size;
+ hp->h_next = htab[bucket].h_first;
+ htab[bucket].h_first = hp;
+ }
+ }
+
+ goto retry;
+
+unavail:
+ _nss_files_hash_destroy(fhp);
+ mutex_unlock(&fhp->fh_lock);
+ return (NSS_UNAVAIL);
+}
+#endif /* PIC */
+
+nss_status_t
+_nss_files_getent_rigid(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *args = (nss_XbyY_args_t *)a;
+
+ return (_nss_files_XY_all(be, args, 0, 0, 0));
+}
+
+nss_status_t
+_nss_files_getent_netdb(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *args = (nss_XbyY_args_t *)a;
+
+ return (_nss_files_XY_all(be, args, 1, 0, 0));
+}
+
+/*ARGSUSED*/
+nss_status_t
+_nss_files_destr(be, dummy)
+ files_backend_ptr_t be;
+ void *dummy;
+{
+ if (be != 0) {
+ if (be->f != 0) {
+ _nss_files_endent(be, 0);
+ }
+ if (be->hashinfo != NULL) {
+ mutex_lock(&be->hashinfo->fh_lock);
+ if (--be->hashinfo->fh_refcnt == 0)
+ _nss_files_hash_destroy(be->hashinfo);
+ mutex_unlock(&be->hashinfo->fh_lock);
+ }
+ free(be);
+ }
+ return (NSS_SUCCESS); /* In case anyone is dumb enough to check */
+}
+
+nss_backend_t *
+_nss_files_constr(ops, n_ops, filename, min_bufsize, fhp)
+ files_backend_op_t ops[];
+ int n_ops;
+ const char *filename;
+ int min_bufsize;
+ files_hash_t *fhp;
+{
+ files_backend_ptr_t be;
+
+ if ((be = (files_backend_ptr_t)malloc(sizeof (*be))) == 0) {
+ return (0);
+ }
+ be->ops = ops;
+ be->n_ops = n_ops;
+ be->filename = filename;
+ be->minbuf = min_bufsize;
+ be->f = 0;
+ be->buf = 0;
+ be->hashinfo = fhp;
+
+ if (fhp != NULL) {
+ mutex_lock(&fhp->fh_lock);
+ fhp->fh_refcnt++;
+ mutex_unlock(&fhp->fh_lock);
+ }
+
+ return ((nss_backend_t *)be);
+}
diff --git a/usr/src/lib/nsswitch/files/common/files_common.h b/usr/src/lib/nsswitch/files/common/files_common.h
new file mode 100644
index 0000000000..afa56329d5
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/files_common.h
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1995-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Common code and structures used by name-service-switch "files" backends.
+ */
+
+#ifndef _FILES_COMMON_H
+#define _FILES_COMMON_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "synonyms.h"
+#include <nss_common.h>
+#include <nss_dbdefs.h>
+#include <stdio.h>
+
+#include "../../../libnsl/include/nsl_stdio_prv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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 struct files_hashent {
+ struct files_hashent *h_first;
+ struct files_hashent *h_next;
+ u_int h_hash;
+} files_hashent_t;
+
+typedef struct {
+ char *l_start;
+ int l_len;
+} files_linetab_t;
+
+typedef struct {
+ mutex_t fh_lock;
+ int fh_resultsize;
+ int fh_bufsize;
+ int fh_nhtab;
+ files_hash_func *fh_hash_func;
+ int fh_refcnt;
+ int fh_size;
+ timestruc_t fh_mtime;
+ char *fh_file_start;
+ char *fh_file_end;
+ files_linetab_t *fh_line;
+ files_hashent_t *fh_table;
+} files_hash_t;
+
+struct files_backend {
+ files_backend_op_t *ops;
+ int n_ops;
+ const char *filename;
+ __NSL_FILE *f;
+ int minbuf;
+ char *buf;
+ files_hash_t *hashinfo;
+};
+
+/*
+ * Iterator function for _nss_files_do_all(), which probably calls yp_all().
+ * NSS_NOTFOUND means "keep enumerating", NSS_SUCCESS means"return now",
+ * other values don't make much sense. In other words we're abusing
+ * (overloading) the meaning of nss_status_t, but hey...
+ * _nss_files_XY_all() is a wrapper around _nss_files_do_all() that does the
+ * 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 *);
+
+#if defined(__STDC__)
+extern nss_backend_t *_nss_files_constr(files_backend_op_t *ops,
+ int n_ops,
+ const char *filename,
+ int min_bufsize,
+ files_hash_t *fhp);
+extern nss_status_t _nss_files_destr (files_backend_ptr_t, void *dummy);
+extern nss_status_t _nss_files_setent(files_backend_ptr_t, void *dummy);
+extern nss_status_t _nss_files_endent(files_backend_ptr_t, void *dummy);
+extern nss_status_t _nss_files_getent_rigid(files_backend_ptr_t, void *);
+extern nss_status_t _nss_files_getent_netdb(files_backend_ptr_t, void *);
+extern nss_status_t _nss_files_do_all(files_backend_ptr_t,
+ void *func_priv,
+ const char *filter,
+ files_do_all_func_t func);
+extern nss_status_t _nss_files_XY_all(files_backend_ptr_t be,
+ nss_XbyY_args_t *args,
+ int netdb,
+ const char *filter,
+ files_XY_check_func check);
+extern 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);
+int _nss_files_read_line(__NSL_FILE *f, char *buffer, int buflen);
+#else
+extern nss_backend_t *_nss_files_constr();
+extern nss_status_t _nss_files_destr ();
+extern nss_status_t _nss_files_setent();
+extern nss_status_t _nss_files_endent();
+extern nss_status_t _nss_files_getent_rigid();
+extern nss_status_t _nss_files_getent_netdb();
+extern nss_status_t _nss_files_do_all();
+extern nss_status_t _nss_files_XY_all();
+extern nss_status_t _nss_files_XY_hash();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FILES_COMMON_H */
diff --git a/usr/src/lib/nsswitch/files/common/getauthattr.c b/usr/src/lib/nsswitch/files/common/getauthattr.c
new file mode 100644
index 0000000000..df236111ec
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getauthattr.c
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include "files_common.h"
+#include <auth_attr.h>
+#include <string.h>
+
+/*
+ * 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));
+}
+
+static files_backend_op_t authattr_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname
+};
+
+nss_backend_t *
+_nss_files_auth_attr_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5,
+ const char *dummy6)
+{
+ return (_nss_files_constr(authattr_ops,
+ sizeof (authattr_ops) / sizeof (authattr_ops[0]),
+ AUTHATTR_FILENAME,
+ NSS_LINELEN_AUTHATTR,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getauuser.c b/usr/src/lib/nsswitch/files/common/getauuser.c
new file mode 100644
index 0000000000..b47525e416
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getauuser.c
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include "files_common.h"
+#include <bsm/libbsm.h>
+#include <string.h>
+
+/*
+ * 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));
+}
+
+static files_backend_op_t auuser_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname
+};
+
+nss_backend_t *
+_nss_files_audit_user_constr(const char *dummy1, const char *dummy2,
+ const char *dummy3)
+{
+ return (_nss_files_constr(auuser_ops,
+ sizeof (auuser_ops) / sizeof (auuser_ops[0]),
+ AUDITUSER_FILENAME,
+ NSS_LINELEN_AUDITUSER,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getexecattr.c b/usr/src/lib/nsswitch/files/common/getexecattr.c
new file mode 100644
index 0000000000..2c5f5b482d
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getexecattr.c
@@ -0,0 +1,377 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include "files_common.h"
+#include <time.h>
+#include <exec_attr.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <ctype.h>
+#include <synch.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+/*
+ * files/getexecattr.c -- "files" backend for nsswitch "exec_attr" database
+ *
+ * _execattr_files_read_line and _execattr_files_XY_all code based on
+ * nss_files_read_line and nss_files_XY_all respectively, from files_common.c
+ */
+
+
+/* externs from libnsl */
+extern int _doexeclist(nss_XbyY_args_t *);
+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)
+{
+ _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);
+ }
+
+ return (1);
+}
+
+
+static nss_status_t
+_exec_files_XY_all(files_backend_ptr_t be,
+ nss_XbyY_args_t *argp,
+ int getby_flag)
+{
+ int parse_stat = 0;
+ int lastlen = 0;
+ int exec_fd = 0;
+ 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;
+ struct stat f_stat;
+ nss_status_t res = NSS_NOTFOUND;
+ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp);
+ static rwlock_t exec_lock;
+
+ if (((be->buf == NULL) &&
+ ((be->buf = (char *)calloc(1, be->minbuf)) == NULL)) ||
+ (be->filename == NULL) ||
+ (rw_rdlock(&exec_lock) != 0)) {
+ return (NSS_UNAVAIL);
+ }
+
+ /*
+ * check the size and the time stamp on the file
+ */
+ if (stat(be->filename, &f_stat) != 0) {
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+ return (NSS_UNAVAIL);
+ }
+
+ f_size = f_stat.st_size;
+ f_time = f_stat.st_mtime;
+
+ while (f_time > read_time) {
+ /*
+ * file has been modified since we last read it.
+ * read it into the buffer with rw lock.
+ */
+ (void) rw_unlock(&exec_lock);
+ if (rw_wrlock(&exec_lock) != 0) {
+ (void) _nss_files_endent(be, 0);
+ return (NSS_UNAVAIL);
+ }
+ if ((be->f = __nsl_fopen(be->filename, "r")) == 0) {
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+ return (NSS_UNAVAIL);
+ }
+ exec_fd = __nsl_fileno(be->f);
+ if (f_buf != NULL)
+ free(f_buf);
+ if ((f_buf = malloc(f_size)) == NULL) {
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+ return (NSS_UNAVAIL);
+ }
+ if (read(exec_fd, f_buf, f_size) < f_size) {
+ free(f_buf);
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+ return (NSS_UNAVAIL);
+ }
+ read_time = f_time;
+ (void) rw_unlock(&exec_lock);
+ /*
+ * verify that the file did not change after
+ * we read it.
+ */
+ if (rw_rdlock(&exec_lock) != 0) {
+ free(f_buf);
+ (void) _nss_files_endent(be, 0);
+ return (NSS_UNAVAIL);
+ }
+ if (stat(be->filename, &f_stat) != 0) {
+ free(f_buf);
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+ return (NSS_UNAVAIL);
+ }
+ f_size = f_stat.st_size;
+ f_time = f_stat.st_mtime;
+ }
+
+ res = NSS_NOTFOUND;
+ 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;
+ }
+
+ /*
+ * If the entry doesn't contain the filter string then
+ * it can't be the entry we want, so don't bother looking
+ * more closely at it.
+ */
+ switch (getby_flag) {
+ case NSS_DBOP_EXECATTR_BYNAME:
+ if (strstr(instr, _priv_exec->name) == NULL)
+ continue;
+ break;
+ case NSS_DBOP_EXECATTR_BYID:
+ if (strstr(instr, _priv_exec->id) == NULL)
+ continue;
+ break;
+ case NSS_DBOP_EXECATTR_BYNAMEID:
+ if ((strstr(instr, _priv_exec->name) == NULL) ||
+ (strstr(instr, _priv_exec->id) == NULL))
+ continue;
+ break;
+ default:
+ break;
+ }
+ if ((strstr(instr, _priv_exec->policy) == NULL) ||
+ ((_priv_exec->type != NULL) &&
+ (strstr(instr, _priv_exec->type) == NULL)))
+ continue;
+
+ /*
+ * Get rid of white spaces, comments etc.
+ */
+ if ((last = strchr(instr, '#')) == NULL)
+ last = instr + linelen;
+ *last-- = '\0'; /* Nuke '\n' or #comment */
+ /*
+ * Skip leading whitespace. Normally there isn't any,
+ * so it's not worth calling strspn().
+ */
+ for (first = instr; isspace(*first); first++)
+ ;
+ if (*first == '\0')
+ continue;
+ /*
+ * Found something non-blank on the line. Skip back
+ * over any trailing whitespace; since we know there's
+ * non-whitespace earlier in the line, checking for
+ * termination is easy.
+ */
+ while (isspace(*last))
+ --last;
+ linelen = last - first + 1;
+ if (first != instr)
+ instr = first;
+
+ /*
+ * Parse the entry.
+ */
+ argp->returnval = NULL;
+ 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);
+ }
+ } else if (parse_stat == NSS_STR_PARSE_ERANGE) {
+ argp->erange = 1;
+ break;
+ } /* else if (parse_stat == NSS_STR_PARSE_PARSE) don't care ! */
+ }
+
+ (void) _nss_files_endent(be, 0);
+ (void) rw_unlock(&exec_lock);
+
+ return (res);
+}
+
+
+/*
+ * If search for exact match for id failed, get_wild checks if we have
+ * a wild-card entry for that id.
+ */
+static nss_status_t
+get_wild(files_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag)
+{
+ 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);
+ old_id = strdup(_priv_exec->id);
+ wild_id = old_id;
+ while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) {
+ _priv_exec->id = wild_id;
+ res = _exec_files_XY_all(be, argp, getby_flag);
+ if (res == NSS_SUCCESS)
+ break;
+ }
+ _priv_exec->id = orig_id;
+ if (old_id)
+ free(old_id);
+
+ return (res);
+}
+
+
+static nss_status_t
+getbynam(files_backend_ptr_t be, void *a)
+{
+ nss_status_t res;
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+
+ res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYNAME);
+
+ _exec_cleanup(res, argp);
+
+ return (res);
+}
+
+
+static nss_status_t
+getbyid(files_backend_ptr_t be, void *a)
+{
+ nss_status_t res;
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp);
+
+ res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYID);
+
+ if (res != NSS_SUCCESS)
+ res = get_wild(be, argp, NSS_DBOP_EXECATTR_BYID);
+
+ _exec_cleanup(res, argp);
+
+ return (res);
+}
+
+
+static nss_status_t
+getbynameid(files_backend_ptr_t be, void *a)
+{
+ nss_status_t res;
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp);
+
+ res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
+
+ if (res != NSS_SUCCESS)
+ res = get_wild(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
+
+ _exec_cleanup(res, argp);
+
+ return (res);
+}
+
+
+static files_backend_op_t execattr_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbynam,
+ getbyid,
+ getbynameid
+};
+
+nss_backend_t *
+_nss_files_exec_attr_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5,
+ const char *dummy6,
+ const char *dummy7)
+{
+ return (_nss_files_constr(execattr_ops,
+ sizeof (execattr_ops)/sizeof (execattr_ops[0]),
+ EXECATTR_FILENAME,
+ NSS_LINELEN_EXECATTR,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getgrent.c b/usr/src/lib/nsswitch/files/common/getgrent.c
new file mode 100644
index 0000000000..82bc1989df
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getgrent.c
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * 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 "files_common.h"
+#include <strings.h>
+
+static u_int
+hash_grname(nss_XbyY_args_t *argp, int keyhash)
+{
+ 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++;
+
+ return (hash);
+}
+
+static u_int
+hash_grgid(nss_XbyY_args_t *argp, int keyhash)
+{
+ struct group *g = argp->returnval;
+ return (keyhash ? (u_int)argp->key.gid : (u_int)g->gr_gid);
+}
+
+static files_hash_func hash_gr[2] = { hash_grname, hash_grgid };
+
+static files_hash_t hashinfo = {
+ DEFAULTMUTEX,
+ sizeof (struct group),
+ NSS_BUFLEN_GROUP,
+ 2,
+ hash_gr
+};
+
+static int
+check_grname(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct group *g = (struct group *)argp->returnval;
+
+ /* +/- entries only valid in compat source */
+ if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-'))
+ return (0);
+ return (strcmp(g->gr_name, argp->key.name) == 0);
+}
+
+static nss_status_t
+getbyname(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_grname));
+}
+
+static int
+check_grgid(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct group *g = (struct group *)argp->returnval;
+
+ /* +/- entries only valid in compat source */
+ if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-'))
+ return (0);
+ return (g->gr_gid == argp->key.gid);
+}
+
+static nss_status_t
+getbygid(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ return (_nss_files_XY_hash(be, a, 0, &hashinfo, 1, check_grgid));
+}
+
+static nss_status_t
+getbymember(be, a)
+ files_backend_ptr_t be;
+ void *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));
+}
+
+static files_backend_op_t group_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_rigid,
+ getbyname,
+ getbygid,
+ getbymember
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_group_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(group_ops,
+ sizeof (group_ops) / sizeof (group_ops[0]),
+ GF_PATH,
+ NSS_LINELEN_GROUP,
+ &hashinfo));
+}
diff --git a/usr/src/lib/nsswitch/files/common/gethostent.c b/usr/src/lib/nsswitch/files/common/gethostent.c
new file mode 100644
index 0000000000..24dd4550c1
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/gethostent.c
@@ -0,0 +1,434 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * files/gethostent.c -- "files" backend for nsswitch "hosts" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <netdb.h>
+#include "files_common.h"
+#include <string.h>
+#include <strings.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+
+static int check_name();
+static char *do_aliases();
+static char *strcasestr();
+nss_status_t __nss_files_XY_hostbyname();
+int __nss_files_2herrno();
+
+static int
+check_name(host, args)
+ struct hostent *host;
+ nss_XbyY_args_t *args;
+{
+ const char *name = args->key.name;
+ char **aliasp;
+
+ if (!host->h_name)
+ return (0);
+ if (strcasecmp(host->h_name, name) == 0) {
+ return (1);
+ }
+ for (aliasp = host->h_aliases; *aliasp != 0; aliasp++) {
+ if (strcasecmp(*aliasp, name) == 0) {
+ return (1);
+ }
+ }
+ 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;
+
+ res = __nss_files_XY_hostbyname(be, argp, argp->key.name, AF_INET);
+ if (res != NSS_SUCCESS)
+ argp->h_errno = __nss_files_2herrno(res);
+ return (res);
+}
+
+
+int
+__nss_files_check_addr(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct hostent *host = (struct hostent *)argp->returnval;
+
+ /*
+ * 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,
+ argp->key.hostaddr.len) == 0);
+}
+
+
+static nss_status_t
+getbyaddr(be, a)
+ files_backend_ptr_t be;
+ void *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);
+ if (res != NSS_SUCCESS)
+ argp->h_errno = __nss_files_2herrno(res);
+ return (res);
+}
+
+
+static files_backend_op_t host_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbyaddr,
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_hosts_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(host_ops,
+ sizeof (host_ops) / sizeof (host_ops[0]),
+ _PATH_HOSTS,
+ NSS_LINELEN_HOSTS,
+ NULL));
+}
+
+
+/*
+ * XXX - this duplicates code from files_common.c because we need to keep
+ * going after we've found a match to satisfy the multihomed host case.
+ */
+nss_status_t
+__nss_files_XY_hostbyname(be, args, filter, type)
+ files_backend_ptr_t be;
+ nss_XbyY_args_t *args;
+ 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) {
+ return (NSS_UNAVAIL);
+ }
+
+ if (be->f == 0) {
+ if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS)
+ return (res);
+ }
+
+ res = NSS_NOTFOUND;
+ args->erange = 0;
+ args->returnval = (char *)0;
+ hp = thp = (struct hostent *)args->buf.result;
+
+ for (;;) {
+ char *instr = be->buf;
+ int linelen;
+
+ if ((linelen = _nss_files_read_line(be->f,
+ instr, be->minbuf)) < 0) {
+ break; /* EOF */
+ }
+
+ /*
+ * This check avoids a malloc()/free() for the common
+ * case. Also, if we're trying to match an alias and an
+ * already matched entry doesn't share a canonical name
+ * with the current one, bail.
+ */
+ if (nhosts == 0 && strcasestr(instr, filter) == 0) {
+ continue;
+ }
+
+ if ((last = strchr(instr, '#')) == 0)
+ last = instr + linelen;
+ *last-- = '\0';
+ for (first = instr; isspace(*first); first++)
+ ;
+ /* Ignore blank and comment lines */
+ if (*first == '\0')
+ continue;
+
+ while (isspace(*last))
+ --last;
+ linelen = last - first + 1;
+ 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;
+ continue;
+ }
+
+ /*
+ * Still need to check, strcasestr() above is just a hint.
+ */
+
+ 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 (nhosts == 1) {
+ res = NSS_SUCCESS;
+ args->returnval = args->buf.result;
+ thp = &he; /* switch to tmp hostent */
+ continue;
+ }
+ if (nhosts >= MAXADDRS)
+ break;
+ abuf = do_aliases(thp, abuf, abuf_start, abuf_end);
+ if (abuf == NULL) {
+ args->erange = 1;
+ res = NSS_NOTFOUND;
+ break;
+ }
+ } else if (abuf &&
+ strcasecmp(hp->h_name, thp->h_name) == 0) {
+ /*
+ * This line didn't have the requested name but
+ * is part of the same multihomed host (i.e. it
+ * has the same canonical name as the previous
+ * line), so march on...
+ */
+ continue;
+ } else if (nhosts) {
+ break;
+ }
+ }
+
+ if (abuf) {
+ struct in_addr *addrp;
+ struct in6_addr *addrp6;
+
+ if (type == AF_INET) {
+ addrp = (struct in_addr *)(ROUND_DOWN(args->buf.buffer +
+ args->buf.buflen, sizeof (*addrp)));
+ hp->h_addr_list = (char **)(ROUND_DOWN(addrp -
+ ((nhosts + 1) * sizeof (char *) +
+ (nhosts * sizeof (*addrp))), sizeof (char *)));
+ for (i = 0, --addrp; i < nhosts; i++, --addrp) {
+ (*(in_addr_t *)addrp) = taddr[i];
+ hp->h_addr_list[i] = (char *)addrp;
+ }
+ } else {
+ addrp6 = (struct in6_addr *)
+ (ROUND_DOWN(args->buf.buffer + args->buf.buflen,
+ sizeof (*addrp6)));
+ hp->h_addr_list = (char **)(ROUND_DOWN(addrp6 -
+ ((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));
+ hp->h_addr_list[i] = (char *)addrp6;
+ }
+ }
+
+ hp->h_addr_list[nhosts] = 0;
+ hp->h_aliases = _nss_netdb_aliases(abuf_start,
+ abuf - abuf_start, args->buf.buffer,
+ (char *)hp->h_addr_list - args->buf.buffer);
+ if (hp->h_aliases == 0) {
+ args->erange = 1;
+ res = NSS_STR_PARSE_ERANGE;
+ } else {
+ hp->h_name = hp->h_aliases[0];
+ hp->h_aliases++;
+ }
+ free(abuf_start);
+ }
+
+ /*
+ * stayopen is set to 0 by default in order to close the opened
+ * file. Some applications may break if it is set to 1.
+ */
+ if (!args->stayopen)
+ (void) _nss_files_endent(be, 0);
+
+ return (res);
+}
+
+/*
+ * A case-insensitive version of strstr().
+ */
+static char *
+strcasestr(as1, as2)
+ char *as1;
+ char *as2;
+{
+ int c2;
+ register char *tptr;
+ register char *s1, *s2;
+
+ s1 = as1;
+ s2 = as2;
+
+ if (s2 == NULL || *s2 == '\0')
+ return (0);
+
+ while (*s1) {
+ if (tolower(*s1++) == tolower(c2 = *s2)) {
+ tptr = s1;
+ while ((tolower(c2 = *++s2) ==
+ tolower(*s1++)) && c2 != 0)
+ ;
+ if (c2 == 0)
+ return ((char *)tptr - 1);
+ s1 = tptr;
+ s2 = as2;
+ }
+ }
+ return (0);
+}
+
+
+static char *
+do_aliases(hp, abuf, start, end)
+ struct hostent *hp;
+ char *abuf;
+ char *start;
+ char *end;
+{
+ char **cp;
+
+ for (cp = hp->h_aliases; cp && *cp && **cp; cp++) {
+ size_t len;
+
+ len = strlen(*cp);
+ if (abuf+len+1 >= end) {
+ free(start);
+ return ((char *)0);
+ }
+ (void) strcpy(abuf, *cp);
+ abuf += len;
+ *abuf++ = ' ';
+ }
+ *abuf = '\0';
+
+ return (abuf);
+}
+
+
+/*
+ * This is a copy of a routine in libnsl/nss/netdir_inet.c. It is
+ * here because /etc/lib/nss_files.so.1 cannot call routines
+ * in libnsl. Care should be taken to keep the two copies in sync.
+ */
+int
+__nss_files_2herrno(nsstat)
+ nss_status_t nsstat;
+{
+ switch (nsstat) {
+ case NSS_SUCCESS:
+ /* no macro-defined success code for h_errno */
+ return (0);
+ case NSS_NOTFOUND:
+ return (HOST_NOT_FOUND);
+ case NSS_TRYAGAIN:
+ return (TRY_AGAIN);
+ case NSS_UNAVAIL:
+ return (NO_RECOVERY);
+ }
+ /* anything else */
+ return (NO_RECOVERY);
+}
diff --git a/usr/src/lib/nsswitch/files/common/gethostent6.c b/usr/src/lib/nsswitch/files/common/gethostent6.c
new file mode 100644
index 0000000000..22d8703848
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/gethostent6.c
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1988-1995, 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * files/gethostent6.c -- "files" backend for nsswitch "hosts" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <netdb.h>
+#include "files_common.h"
+#include <string.h>
+#include <strings.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+
+extern nss_status_t __nss_files_XY_hostbyname();
+extern int __nss_files_2herrno();
+extern int __nss_files_check_addr(nss_XbyY_args_t *);
+
+
+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;
+
+ res = __nss_files_XY_hostbyname(be, argp, argp->key.ipnode.name,
+ AF_INET6);
+ if (res != NSS_SUCCESS)
+ argp->h_errno = __nss_files_2herrno(res);
+ return (res);
+}
+
+
+
+static nss_status_t
+getbyaddr(be, a)
+ files_backend_ptr_t be;
+ void *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);
+ 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,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbyaddr,
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_ipnodes_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(ipnodes_ops,
+ sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]),
+ _PATH_IPNODES,
+ NSS_LINELEN_HOSTS,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getnetent.c b/usr/src/lib/nsswitch/files/common/getnetent.c
new file mode 100644
index 0000000000..992f19326c
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getnetent.c
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ *
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getnetent.c -- "files" backend for nsswitch "networks" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#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);
+}
+
+static nss_status_t
+getbyname(be, a)
+ 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));
+}
+
+static int
+check_addr(args)
+ nss_XbyY_args_t *args;
+{
+ struct netent *net = (struct netent *)args->returnval;
+
+ return ((net->n_addrtype == args->key.netaddr.type) &&
+ (net->n_net == args->key.netaddr.net));
+}
+
+static nss_status_t
+getbyaddr(be, a)
+ 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, 0, check_addr));
+}
+
+static files_backend_op_t net_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbyaddr
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_networks_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(net_ops,
+ sizeof (net_ops) / sizeof (net_ops[0]),
+ _PATH_NETWORKS,
+ NSS_LINELEN_NETWORKS,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getprinter.c b/usr/src/lib/nsswitch/files/common/getprinter.c
new file mode 100644
index 0000000000..deeaa947bf
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getprinter.c
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * files/printers_getbyname.c -- "files" backend for
+ * nsswitch "printers" database.
+ *
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+static const char *printers = "/etc/printers.conf";
+
+#pragma weak _nss_files__printers_constr = _nss_files_printers_constr
+
+#include "files_common.h"
+#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;
+{
+ nss_XbyY_args_t *args = (nss_XbyY_args_t *)a;
+
+ return (_nss_files_XY_all(be, args, 1, 0, 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));
+}
+
+static files_backend_op_t printers_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ getent,
+ getbyname
+};
+
+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);
+}
diff --git a/usr/src/lib/nsswitch/files/common/getprofattr.c b/usr/src/lib/nsswitch/files/common/getprofattr.c
new file mode 100644
index 0000000000..67c49369b0
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getprofattr.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include "files_common.h"
+#include <prof_attr.h>
+#include <string.h>
+
+/*
+ * 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));
+}
+
+static files_backend_op_t profattr_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname
+};
+
+nss_backend_t *
+_nss_files_prof_attr_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5)
+{
+ return (_nss_files_constr(profattr_ops,
+ sizeof (profattr_ops) / sizeof (profattr_ops[0]),
+ PROFATTR_FILENAME,
+ NSS_LINELEN_PROFATTR,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getprojent.c b/usr/src/lib/nsswitch/files/common/getprojent.c
new file mode 100644
index 0000000000..cad512746c
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getprojent.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <project.h>
+#include <string.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++;
+
+ 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);
+}
+
+static files_hash_func hash_proj[2] = {
+ hash_projname,
+ hash_projid
+};
+
+static files_hash_t hashinfo = {
+ DEFAULTMUTEX,
+ sizeof (struct project),
+ NSS_BUFLEN_PROJECT,
+ 2,
+ hash_proj
+};
+
+static int
+check_projname(nss_XbyY_args_t *argp) {
+ struct project *p = argp->returnval;
+
+ if (p->pj_name == 0)
+ 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;
+
+ if (p->pj_name == 0)
+ return (0);
+ return (p->pj_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));
+}
+
+static nss_status_t
+getbyprojid(files_backend_ptr_t be, void *a) {
+ return (_nss_files_XY_hash(be, a, 0, &hashinfo, 1, check_projid));
+}
+
+static files_backend_op_t project_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_rigid,
+ getbyname,
+ getbyprojid
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_project_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(project_ops,
+ sizeof (project_ops) / sizeof (project_ops[0]),
+ PROJF_PATH,
+ NSS_LINELEN_PROJECT,
+ &hashinfo));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getprotoent.c b/usr/src/lib/nsswitch/files/common/getprotoent.c
new file mode 100644
index 0000000000..25659b2e92
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getprotoent.c
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getprotoent.c -- "files" backend for nsswitch "protocols" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#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);
+}
+
+static nss_status_t
+getbyname(be, a)
+ 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));
+}
+
+static int
+check_addr(args)
+ nss_XbyY_args_t *args;
+{
+ struct protoent *proto = (struct protoent *)args->returnval;
+
+ return (proto->p_proto == args->key.number);
+}
+
+static nss_status_t
+getbynumber(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a;
+ char numstr[12];
+
+ sprintf(numstr, "%d", argp->key.number);
+ return (_nss_files_XY_all(be, argp, 1, 0, check_addr));
+}
+
+static files_backend_op_t proto_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbynumber
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_protocols_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(proto_ops,
+ sizeof (proto_ops) / sizeof (proto_ops[0]),
+ _PATH_PROTOCOLS,
+ NSS_LINELEN_PROTOCOLS,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getpwnam.c b/usr/src/lib/nsswitch/files/common/getpwnam.c
new file mode 100644
index 0000000000..303b8323c6
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getpwnam.c
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getpwnam.c -- "files" backend for nsswitch "passwd" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <pwd.h>
+#include <shadow.h>
+#include <unistd.h> /* for PF_PATH */
+#include "files_common.h"
+#include <strings.h>
+
+static u_int
+hash_pwname(nss_XbyY_args_t *argp, int keyhash)
+{
+ 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++;
+
+ return (hash);
+}
+
+static u_int
+hash_pwuid(nss_XbyY_args_t *argp, int keyhash)
+{
+ struct passwd *p = argp->returnval;
+ return (keyhash ? (u_int)argp->key.uid : (u_int)p->pw_uid);
+}
+
+static files_hash_func hash_pw[2] = { hash_pwname, hash_pwuid };
+
+static files_hash_t hashinfo = {
+ DEFAULTMUTEX,
+ sizeof (struct passwd),
+ NSS_BUFLEN_PASSWD,
+ 2,
+ hash_pw
+};
+
+static int
+check_pwname(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct passwd *p = (struct passwd *)argp->returnval;
+
+ /* +/- entries valid for compat source only */
+ if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-'))
+ return (0);
+ return (strcmp(p->pw_name, argp->key.name) == 0);
+}
+
+static nss_status_t
+getbyname(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_pwname));
+}
+
+static int
+check_pwuid(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct passwd *p = (struct passwd *)argp->returnval;
+
+ /* +/- entries valid for compat source only */
+ if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-'))
+ return (0);
+ return (p->pw_uid == argp->key.uid);
+}
+
+static nss_status_t
+getbyuid(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ return (_nss_files_XY_hash(be, a, 0, &hashinfo, 1, check_pwuid));
+}
+
+static files_backend_op_t passwd_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_rigid,
+ getbyname,
+ getbyuid
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_passwd_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(passwd_ops,
+ sizeof (passwd_ops) / sizeof (passwd_ops[0]),
+ PF_PATH,
+ NSS_LINELEN_PASSWD,
+ &hashinfo));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getrpcent.c b/usr/src/lib/nsswitch/files/common/getrpcent.c
new file mode 100644
index 0000000000..789822c63c
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getrpcent.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getrpcent.c -- "files" backend for nsswitch "rpc" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#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);
+}
+
+static nss_status_t
+getbyname(be, a)
+ 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));
+}
+
+static int
+check_rpcnum(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct rpcent *rpc = (struct rpcent *) argp->returnval;
+
+ return (rpc->r_number == argp->key.number);
+}
+
+
+static nss_status_t
+getbynumber(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a;
+ char numstr[12];
+
+ sprintf(numstr, "%d", argp->key.number);
+ return (_nss_files_XY_all(be, argp, 1, numstr, check_rpcnum));
+}
+
+static files_backend_op_t rpc_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbynumber
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_rpc_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(rpc_ops,
+ sizeof (rpc_ops) / sizeof (rpc_ops[0]),
+ "/etc/rpc",
+ NSS_LINELEN_RPC,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getservent.c b/usr/src/lib/nsswitch/files/common/getservent.c
new file mode 100644
index 0000000000..855b543d55
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getservent.c
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getservent.c -- "files" backend for nsswitch "services" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <netdb.h>
+#include "files_common.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <strings.h>
+
+static int
+check_name(args)
+ nss_XbyY_args_t *args;
+{
+ struct servent *serv = (struct servent *) args->returnval;
+ const char *name = args->key.serv.serv.name;
+ const char *proto = args->key.serv.proto;
+ char **aliasp;
+
+ if (proto != 0 && strcmp(serv->s_proto, proto) != 0) {
+ return (0);
+ }
+ if (strcmp(serv->s_name, name) == 0) {
+ return (1);
+ }
+ for (aliasp = serv->s_aliases; *aliasp != 0; aliasp++) {
+ if (strcmp(*aliasp, name) == 0) {
+ return (1);
+ }
+ }
+ 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;
+
+ 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;
+{
+ struct servent *serv = (struct servent *) args->returnval;
+ const char *proto = args->key.serv.proto;
+
+ return (serv->s_port == args->key.serv.serv.port &&
+ (proto == 0 || strcmp(serv->s_proto, proto) == 0));
+}
+
+static nss_status_t
+getbyport(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a;
+ char portstr[12];
+
+ sprintf(portstr, "%d", ntohs(argp->key.serv.serv.port));
+ return (_nss_files_XY_all(be, argp, 1, portstr, check_port));
+}
+
+static files_backend_op_t serv_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname,
+ getbyport
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_services_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(serv_ops,
+ sizeof (serv_ops) / sizeof (serv_ops[0]),
+ _PATH_SERVICES,
+ NSS_LINELEN_SERVICES,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getspent.c b/usr/src/lib/nsswitch/files/common/getspent.c
new file mode 100644
index 0000000000..7287f024d2
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getspent.c
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1988-1995 Sun Microsystems Inc
+ * All Rights Reserved.
+ *
+ * files/getspent.c -- "files" backend for nsswitch "shadow" database
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <shadow.h>
+#include "files_common.h"
+#include <strings.h>
+
+static int
+check_spnamp(argp)
+ nss_XbyY_args_t *argp;
+{
+ struct spwd *s = (struct spwd *)argp->returnval;
+
+ /* +/- entries valid in compat source only */
+ if (s->sp_namp != 0 && (s->sp_namp[0] == '+' || s->sp_namp[0] == '-'))
+ return (0);
+ return (strcmp(s->sp_namp, argp->key.name) == 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;
+
+ return (_nss_files_XY_all(be, argp, 0, argp->key.name, check_spnamp));
+}
+
+static files_backend_op_t shadow_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_rigid,
+ getbyname
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_shadow_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(shadow_ops,
+ sizeof (shadow_ops) / sizeof (shadow_ops[0]),
+ SHADOW,
+ NSS_LINELEN_SHADOW,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/getuserattr.c b/usr/src/lib/nsswitch/files/common/getuserattr.c
new file mode 100644
index 0000000000..82f377c5da
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/getuserattr.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include "files_common.h"
+#include <user_attr.h>
+#include <string.h>
+
+/*
+ * 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));
+}
+
+static files_backend_op_t userattr_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname
+};
+
+nss_backend_t *
+_nss_files_user_attr_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5)
+{
+ return (_nss_files_constr(userattr_ops,
+ sizeof (userattr_ops) / sizeof (userattr_ops[0]),
+ USERATTR_FILENAME,
+ NSS_LINELEN_USERATTR,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/mapfile-vers b/usr/src/lib/nsswitch/files/common/mapfile-vers
new file mode 100644
index 0000000000..a4c6b1b67f
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/mapfile-vers
@@ -0,0 +1,64 @@
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# 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.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Generic interface definition for usr/src/lib/nsswitch/files.
+#
+# For information regarding the establishment of versioned definitions see:
+# The Linker and Libraries Manual (version 2.5 or greater)
+# This is part of the Developers Guide in the Answerbook. Specifically refer
+# to Chapter 2 under section "Defining Additional Symbols" through section
+# "Reducing Symbol Scope", and Chapter 5 "Versioning".
+#
+# For specific OSNET rules for the modification (evolution) of these version
+# definitions see:
+# Policy for Shared Library Version Names and Interface Definitions
+
+
+SUNWprivate_1.1 {
+ global:
+ _nss_files_bootparams_constr;
+ _nss_files_auth_attr_constr;
+ _nss_files_audit_user_constr;
+ _nss_files_ethers_constr;
+ _nss_files_exec_attr_constr;
+ _nss_files_group_constr;
+ _nss_files_hosts_constr;
+ _nss_files_ipnodes_constr;
+ _nss_files_netmasks_constr;
+ _nss_files_networks_constr;
+ _nss_files_passwd_constr;
+ _nss_files_printers_constr;
+ _nss_files__printers_constr;
+ _nss_files_prof_attr_constr;
+ _nss_files_project_constr;
+ _nss_files_protocols_constr;
+ _nss_files_rpc_constr;
+ _nss_files_services_constr;
+ _nss_files_shadow_constr;
+ _nss_files_user_attr_constr;
+ local:
+ *;
+};
diff --git a/usr/src/lib/nsswitch/files/common/netmasks.c b/usr/src/lib/nsswitch/files/common/netmasks.c
new file mode 100644
index 0000000000..876fcf66a6
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/netmasks.c
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * files/netmasks.c -- "files" backend for nsswitch "netmasks" database
+ *
+ * Copyright (c) 1996 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * All routines necessary to deal with the file /etc/inet/netmasks. The file
+ * contains mappings from 32 bit network internet addresses to their
+ * corresponding 32 bit mask internet addresses. The addresses are in dotted
+ * internet address form.
+ */
+
+#include "files_common.h"
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <nss_dbdefs.h>
+
+/*
+ * Validate 'files' netmasks entry. The comparison objects are in IPv4
+ * internet address format.
+ */
+static int
+check_addr(args)
+ nss_XbyY_args_t *args;
+{
+ struct in_addr tmp;
+
+ tmp.s_addr = inet_addr(args->key.name);
+ return (memcmp(args->buf.buffer, (char *)&tmp,
+ sizeof (struct in_addr)) == 0);
+}
+
+static nss_status_t
+getbynet(be, a)
+ files_backend_ptr_t be;
+ void *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;
+ res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_addr);
+ argp->buf.buffer = NULL;
+ argp->buf.buflen = 0;
+
+ return (res);
+}
+
+static files_backend_op_t netmasks_ops[] = {
+ _nss_files_destr,
+ getbynet
+};
+
+/*ARGSUSED*/
+nss_backend_t *
+_nss_files_netmasks_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(netmasks_ops,
+ sizeof (netmasks_ops) / sizeof (netmasks_ops[0]),
+ _PATH_NETMASKS, NSS_LINELEN_NETMASKS, NULL));
+}