0
|
1 |
/*
|
|
2 |
* CDDL HEADER START
|
|
3 |
*
|
|
4 |
* The contents of this file are subject to the terms of the
|
|
5 |
* Common Development and Distribution License, Version 1.0 only
|
|
6 |
* (the "License"). You may not use this file except in compliance
|
|
7 |
* with the License.
|
|
8 |
*
|
|
9 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
10 |
* or http://www.opensolaris.org/os/licensing.
|
|
11 |
* See the License for the specific language governing permissions
|
|
12 |
* and limitations under the License.
|
|
13 |
*
|
|
14 |
* When distributing Covered Code, include this CDDL HEADER in each
|
|
15 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
16 |
* If applicable, add the following below this CDDL HEADER, with the
|
|
17 |
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
18 |
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
19 |
*
|
|
20 |
* CDDL HEADER END
|
|
21 |
*/
|
|
22 |
/*
|
|
23 |
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
|
24 |
* Use is subject to license terms.
|
|
25 |
*/
|
|
26 |
|
|
27 |
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
28 |
|
|
29 |
/*
|
|
30 |
* getnetgrent.c
|
|
31 |
*
|
|
32 |
* - name-service switch frontend routines for the netgroup API.
|
|
33 |
*
|
|
34 |
* Policy decision:
|
|
35 |
* If netgroup A refers to netgroup B, both must occur in the same
|
|
36 |
* source (any other choice gives very confusing semantics). This
|
|
37 |
* assumption is deeply embedded in the code below and in the backends.
|
|
38 |
*
|
|
39 |
* innetgr() is implemented on top of something called __multi_innetgr(),
|
|
40 |
* which replaces each (char *) argument of innetgr() with a counted vector
|
|
41 |
* of (char *). The semantics are the same as an OR of the results of
|
|
42 |
* innetgr() operations on each possible 4-tuple picked from the arguments,
|
|
43 |
* but it's possible to implement some cases more efficiently. This is
|
|
44 |
* important for mountd, which used to read YP netgroup.byhost directly in
|
|
45 |
* order to determine efficiently whether a given host belonged to any one
|
|
46 |
* of a long list of netgroups. Wildcarded arguments are indicated by a
|
|
47 |
* count of zero.
|
|
48 |
*/
|
|
49 |
|
|
50 |
#include "synonyms.h"
|
|
51 |
#include <string.h>
|
|
52 |
#include <synch.h>
|
|
53 |
#include <nss_dbdefs.h>
|
|
54 |
#include <mtlib.h>
|
|
55 |
#include <libc.h>
|
|
56 |
|
|
57 |
static DEFINE_NSS_DB_ROOT(db_root);
|
|
58 |
|
|
59 |
void
|
|
60 |
_nss_initf_netgroup(p)
|
|
61 |
nss_db_params_t *p;
|
|
62 |
{
|
|
63 |
p->name = NSS_DBNAM_NETGROUP;
|
|
64 |
p->default_config = NSS_DEFCONF_NETGROUP;
|
|
65 |
}
|
|
66 |
|
|
67 |
/*
|
|
68 |
* The netgroup routines aren't quite like the majority of the switch clients.
|
|
69 |
* innetgr() more-or-less fits the getXXXbyYYY mould, but for the others:
|
|
70 |
* - setnetgrent("netgroup") is really a getXXXbyYYY routine, i.e. it
|
|
71 |
* searches the sources until it finds an entry with the given name.
|
|
72 |
* Rather than returning the (potentially large) entry, it simply
|
|
73 |
* initializes a cursor, and then...
|
|
74 |
* - getnetgrent(...) is repeatedly invoked by the user to extract the
|
|
75 |
* contents of the entry found by setnetgrent().
|
|
76 |
* - endnetgrent() is almost like a real endXXXent routine.
|
|
77 |
* If we were certain that all the backends could provide netgroup information
|
|
78 |
* in a common form, we could make the setnetgrent() backend return the entire
|
|
79 |
* entry to the frontend, then implement getnetgrent() and endnetgrent()
|
|
80 |
* strictly in the frontend (aka here). But we're not certain, so we won't.
|
|
81 |
*
|
|
82 |
* NOTE:
|
|
83 |
* In the SunOS 4.x (YP) version of this code, innetgr() did not
|
|
84 |
* affect the state of {set,get,end}netgrent(). Somewhere out
|
|
85 |
* there probably lurks a program that depends on this behaviour,
|
|
86 |
* so this version (both frontend and backends) had better
|
|
87 |
* behave the same way.
|
|
88 |
*/
|
|
89 |
|
|
90 |
/* ===> ?? fix "__" name */
|
|
91 |
int
|
|
92 |
__multi_innetgr(ngroup, pgroup,
|
|
93 |
nhost, phost,
|
|
94 |
nuser, puser,
|
|
95 |
ndomain, pdomain)
|
|
96 |
nss_innetgr_argc ngroup, nhost, nuser, ndomain;
|
|
97 |
nss_innetgr_argv pgroup, phost, puser, pdomain;
|
|
98 |
{
|
|
99 |
struct nss_innetgr_args ia;
|
|
100 |
|
|
101 |
if (ngroup == 0) {
|
|
102 |
return (0); /* One thing fewer to worry backends */
|
|
103 |
}
|
|
104 |
|
|
105 |
ia.groups.argc = ngroup;
|
|
106 |
ia.groups.argv = pgroup;
|
|
107 |
ia.arg[NSS_NETGR_MACHINE].argc = nhost;
|
|
108 |
ia.arg[NSS_NETGR_MACHINE].argv = phost;
|
|
109 |
ia.arg[NSS_NETGR_USER].argc = nuser;
|
|
110 |
ia.arg[NSS_NETGR_USER].argv = puser;
|
|
111 |
ia.arg[NSS_NETGR_DOMAIN].argc = ndomain;
|
|
112 |
ia.arg[NSS_NETGR_DOMAIN].argv = pdomain;
|
|
113 |
ia.status = NSS_NETGR_NO;
|
|
114 |
|
|
115 |
(void) nss_search(&db_root, _nss_initf_netgroup,
|
|
116 |
NSS_DBOP_NETGROUP_IN, &ia);
|
|
117 |
return (ia.status == NSS_NETGR_FOUND);
|
|
118 |
}
|
|
119 |
|
|
120 |
int
|
|
121 |
innetgr(group, host, user, domain)
|
|
122 |
const char *group, *host, *user, *domain;
|
|
123 |
{
|
|
124 |
#define IA(charp) \
|
|
125 |
(nss_innetgr_argc)((charp) != 0), (nss_innetgr_argv)(&(charp))
|
|
126 |
|
|
127 |
return (__multi_innetgr(IA(group), IA(host), IA(user), IA(domain)));
|
|
128 |
}
|
|
129 |
|
|
130 |
/*
|
|
131 |
* Context for setnetgrent()/getnetgrent(). If the user is being sensible
|
|
132 |
* the requests will be serialized anyway, but let's play safe and
|
|
133 |
* serialize them ourselves (anything to prevent a coredump)...
|
|
134 |
* We can't use lmutex_lock() here because we don't know what the backends
|
|
135 |
* that we call may call in turn. They might call malloc()/free().
|
|
136 |
* So we use the brute-force fork_lock_enter() instead.
|
|
137 |
*/
|
|
138 |
static nss_backend_t *getnetgrent_backend;
|
|
139 |
|
|
140 |
int
|
|
141 |
setnetgrent(const char *netgroup)
|
|
142 |
{
|
|
143 |
nss_backend_t *be;
|
|
144 |
|
|
145 |
if (netgroup == NULL) {
|
|
146 |
/* Prevent coredump, otherwise don't do anything profound */
|
|
147 |
netgroup = "";
|
|
148 |
}
|
|
149 |
|
|
150 |
(void) fork_lock_enter(NULL);
|
|
151 |
be = getnetgrent_backend;
|
|
152 |
if (be != NULL && NSS_INVOKE_DBOP(be, NSS_DBOP_SETENT,
|
|
153 |
(void *)netgroup) != NSS_SUCCESS) {
|
|
154 |
(void) NSS_INVOKE_DBOP(be, NSS_DBOP_DESTRUCTOR, 0);
|
|
155 |
be = NULL;
|
|
156 |
}
|
|
157 |
if (be == NULL) {
|
|
158 |
struct nss_setnetgrent_args args;
|
|
159 |
|
|
160 |
args.netgroup = netgroup;
|
|
161 |
args.iterator = 0;
|
|
162 |
(void) nss_search(&db_root, _nss_initf_netgroup,
|
|
163 |
NSS_DBOP_NETGROUP_SET, &args);
|
|
164 |
be = args.iterator;
|
|
165 |
}
|
|
166 |
getnetgrent_backend = be;
|
|
167 |
fork_lock_exit();
|
|
168 |
return (0);
|
|
169 |
}
|
|
170 |
|
|
171 |
int
|
|
172 |
getnetgrent_r(machinep, namep, domainp, buffer, buflen)
|
|
173 |
char **machinep;
|
|
174 |
char **namep;
|
|
175 |
char **domainp;
|
|
176 |
char *buffer;
|
|
177 |
int buflen;
|
|
178 |
{
|
|
179 |
struct nss_getnetgrent_args args;
|
|
180 |
|
|
181 |
args.buffer = buffer;
|
|
182 |
args.buflen = buflen;
|
|
183 |
args.status = NSS_NETGR_NO;
|
|
184 |
|
|
185 |
(void) fork_lock_enter(NULL);
|
|
186 |
if (getnetgrent_backend != 0) {
|
|
187 |
(void) NSS_INVOKE_DBOP(getnetgrent_backend,
|
|
188 |
NSS_DBOP_GETENT, &args);
|
|
189 |
}
|
|
190 |
fork_lock_exit();
|
|
191 |
|
|
192 |
if (args.status == NSS_NETGR_FOUND) {
|
|
193 |
*machinep = args.retp[NSS_NETGR_MACHINE];
|
|
194 |
*namep = args.retp[NSS_NETGR_USER];
|
|
195 |
*domainp = args.retp[NSS_NETGR_DOMAIN];
|
|
196 |
return (1);
|
|
197 |
} else {
|
|
198 |
return (0);
|
|
199 |
}
|
|
200 |
}
|
|
201 |
|
|
202 |
static nss_XbyY_buf_t *buf;
|
|
203 |
|
|
204 |
int
|
|
205 |
getnetgrent(machinep, namep, domainp)
|
|
206 |
char **machinep;
|
|
207 |
char **namep;
|
|
208 |
char **domainp;
|
|
209 |
{
|
|
210 |
(void) NSS_XbyY_ALLOC(&buf, 0, NSS_BUFLEN_NETGROUP);
|
|
211 |
return (getnetgrent_r(machinep, namep, domainp,
|
|
212 |
buf->buffer, buf->buflen));
|
|
213 |
}
|
|
214 |
|
|
215 |
int
|
|
216 |
endnetgrent()
|
|
217 |
{
|
|
218 |
(void) fork_lock_enter(NULL);
|
|
219 |
if (getnetgrent_backend != 0) {
|
|
220 |
(void) NSS_INVOKE_DBOP(getnetgrent_backend,
|
|
221 |
NSS_DBOP_DESTRUCTOR, 0);
|
|
222 |
getnetgrent_backend = 0;
|
|
223 |
}
|
|
224 |
fork_lock_exit();
|
|
225 |
nss_delete(&db_root); /* === ? */
|
|
226 |
NSS_XbyY_FREE(&buf);
|
|
227 |
return (0);
|
|
228 |
}
|