1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 /*
17 * Test program for files / netgroup support
18 */
19
20 #include <nsswitch.h>
21 #include <nss_common.h>
22 #include <nss_dbdefs.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 static DEFINE_NSS_DB_ROOT(db_root);
29
30 /*
31 * This is a NSS str2ent (parse) function to fill in a
32 * struct nss_netgrent. See NSS_XbyY_INIT below.
33 *
34 * A specialized but parse-equivalent version of this function
35 * is in the files back end. See str2netr() in:
36 * $SRC/lib/nsswitch/files/common/getnetgrent.c
37 */
38 static int
39 str2netgr(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
40 {
41 const char sep[] = " \t\n";
42 struct nss_netgrent *netgr = ent;
43 char *p;
44
45 if (lenstr + 1 > buflen)
46 return (NSS_STR_PARSE_ERANGE);
47
48 /*
49 * We copy the input string into the output buffer and
50 * operate on it in place.
51 */
52 if (instr != buffer) {
53 /* Overlapping buffer copies are OK */
54 (void) memmove(buffer, instr, lenstr);
55 buffer[lenstr] = '\0';
56 }
57
58 /* quick exit do not entry fill if not needed */
59 if (ent == (void *)NULL)
60 return (NSS_STR_PARSE_SUCCESS);
61
62 /* skip leading space */
63 p = buffer;
64 while (isspace(*p))
65 p++;
66
67 /* should be at the key */
68 if (*p == '\0')
69 return (NSS_STR_PARSE_PARSE);
70 netgr->netgr_name = p;
71
72 /* skip the key and null terminate */
73 p = strpbrk(p, sep);
74 if (p == NULL)
75 return (NSS_STR_PARSE_PARSE);
76 *p++ = '\0';
77
78 /* skip separators */
79 while (isspace(*p))
80 p++;
81
82 /*
83 * Should be at the members list, which is the
84 * rest of the input line.
85 */
86 if (*p == '\0')
87 return (NSS_STR_PARSE_PARSE);
88 netgr->netgr_members = p;
89
90 return (NSS_STR_PARSE_SUCCESS);
91 }
92
93 static void
94 initf_netgroup(nss_db_params_t *p)
95 {
96 p->name = NSS_DBNAM_NETGROUP;
97 p->default_config = NSS_DEFCONF_NETGROUP;
98 }
99
100 struct nss_netgrent *
101 netgr_getbyname(const char *name, struct nss_netgrent *result,
102 char *buffer, int buflen)
103 {
104 nss_XbyY_args_t arg = {0};
105
106 if (name == (const char *)NULL) {
107 errno = ERANGE;
108 return (NULL);
109 }
110 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2netgr);
111 arg.key.name = name;
112 (void) nss_search(&db_root, initf_netgroup,
113 NSS_DBOP_NETGROUP_BYNAME, &arg);
114 return ((struct nss_netgrent *)NSS_XbyY_FINI(&arg));
115 }
116
117 static char buf[NSS_LINELEN_NETGROUP];
118
119 int
120 main(int argc, char **argv)
121 {
122 struct nss_netgrent netgr, *ng;
123 int i;
124
125 if (argc < 2) {
126 (void) fprintf(stderr, "usage: %s netgroup [...]\n", argv[0]);
127 exit(1);
128 }
129
130 for (i = 1; i < argc; i++) {
131 ng = netgr_getbyname(argv[i], &netgr, buf, sizeof (buf));
132 if (ng == NULL) {
133 perror(argv[i]);
134 continue;
135 }
136 (void) printf("%s => %s\n",
137 netgr.netgr_name,
138 netgr.netgr_members);
139 }
140 return (0);
141 }