diff options
Diffstat (limited to 'usr/src/lib/nsswitch/files/common')
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 = ðeraddr; + + 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)); +} |