author | Jon Tibble <meths@btinternet.com> |
Thu, 09 Dec 2010 22:32:39 +0100 | |
changeset 13255 | 4afa820d78b9 |
parent 6812 | febeba71273d |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
2830 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
4843
5b42fe9ae29d
6590401 fixes for 6418491, 6518780 and 6570016 conspire to break java
raf
parents:
2830
diff
changeset
|
21 |
|
0 | 22 |
/* |
6812 | 23 |
* Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
0 | 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 |
||
6812 | 50 |
#include "lint.h" |
0 | 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. |
|
2830 | 77 |
* The behaviour in NSS was: |
78 |
* If we were certain that all the backends could provide netgroup information |
|
79 |
* in a common form, we could make the setnetgrent() backend return the entire |
|
80 |
* entry to the frontend, then implement getnetgrent() and endnetgrent() |
|
81 |
* strictly in the frontend (aka here). But we're not certain, so we won't. |
|
82 |
* In NSS2: |
|
83 |
* Since nscd returns the results, and it is nscd that accumulates |
|
84 |
* the results, then we can return the entire result on the setnetgrent. |
|
0 | 85 |
* |
86 |
* NOTE: |
|
87 |
* In the SunOS 4.x (YP) version of this code, innetgr() did not |
|
88 |
* affect the state of {set,get,end}netgrent(). Somewhere out |
|
89 |
* there probably lurks a program that depends on this behaviour, |
|
90 |
* so this version (both frontend and backends) had better |
|
91 |
* behave the same way. |
|
92 |
*/ |
|
93 |
||
94 |
/* ===> ?? fix "__" name */ |
|
95 |
int |
|
96 |
__multi_innetgr(ngroup, pgroup, |
|
97 |
nhost, phost, |
|
98 |
nuser, puser, |
|
99 |
ndomain, pdomain) |
|
100 |
nss_innetgr_argc ngroup, nhost, nuser, ndomain; |
|
101 |
nss_innetgr_argv pgroup, phost, puser, pdomain; |
|
102 |
{ |
|
103 |
struct nss_innetgr_args ia; |
|
104 |
||
105 |
if (ngroup == 0) { |
|
106 |
return (0); /* One thing fewer to worry backends */ |
|
107 |
} |
|
108 |
||
109 |
ia.groups.argc = ngroup; |
|
110 |
ia.groups.argv = pgroup; |
|
111 |
ia.arg[NSS_NETGR_MACHINE].argc = nhost; |
|
112 |
ia.arg[NSS_NETGR_MACHINE].argv = phost; |
|
113 |
ia.arg[NSS_NETGR_USER].argc = nuser; |
|
114 |
ia.arg[NSS_NETGR_USER].argv = puser; |
|
115 |
ia.arg[NSS_NETGR_DOMAIN].argc = ndomain; |
|
116 |
ia.arg[NSS_NETGR_DOMAIN].argv = pdomain; |
|
117 |
ia.status = NSS_NETGR_NO; |
|
118 |
||
119 |
(void) nss_search(&db_root, _nss_initf_netgroup, |
|
120 |
NSS_DBOP_NETGROUP_IN, &ia); |
|
121 |
return (ia.status == NSS_NETGR_FOUND); |
|
122 |
} |
|
123 |
||
124 |
int |
|
125 |
innetgr(group, host, user, domain) |
|
126 |
const char *group, *host, *user, *domain; |
|
127 |
{ |
|
128 |
#define IA(charp) \ |
|
129 |
(nss_innetgr_argc)((charp) != 0), (nss_innetgr_argv)(&(charp)) |
|
130 |
||
131 |
return (__multi_innetgr(IA(group), IA(host), IA(user), IA(domain))); |
|
132 |
} |
|
133 |
||
134 |
/* |
|
135 |
* Context for setnetgrent()/getnetgrent(). If the user is being sensible |
|
136 |
* the requests will be serialized anyway, but let's play safe and |
|
137 |
* serialize them ourselves (anything to prevent a coredump)... |
|
138 |
* We can't use lmutex_lock() here because we don't know what the backends |
|
139 |
* that we call may call in turn. They might call malloc()/free(). |
|
5002 | 140 |
* So we use the brute-force callout_lock_enter() instead. |
0 | 141 |
*/ |
142 |
static nss_backend_t *getnetgrent_backend; |
|
143 |
||
144 |
int |
|
145 |
setnetgrent(const char *netgroup) |
|
146 |
{ |
|
147 |
nss_backend_t *be; |
|
148 |
||
149 |
if (netgroup == NULL) { |
|
150 |
/* Prevent coredump, otherwise don't do anything profound */ |
|
151 |
netgroup = ""; |
|
152 |
} |
|
153 |
||
5002 | 154 |
callout_lock_enter(); |
0 | 155 |
be = getnetgrent_backend; |
156 |
if (be != NULL && NSS_INVOKE_DBOP(be, NSS_DBOP_SETENT, |
|
157 |
(void *)netgroup) != NSS_SUCCESS) { |
|
158 |
(void) NSS_INVOKE_DBOP(be, NSS_DBOP_DESTRUCTOR, 0); |
|
159 |
be = NULL; |
|
160 |
} |
|
161 |
if (be == NULL) { |
|
162 |
struct nss_setnetgrent_args args; |
|
163 |
||
164 |
args.netgroup = netgroup; |
|
165 |
args.iterator = 0; |
|
166 |
(void) nss_search(&db_root, _nss_initf_netgroup, |
|
167 |
NSS_DBOP_NETGROUP_SET, &args); |
|
168 |
be = args.iterator; |
|
169 |
} |
|
170 |
getnetgrent_backend = be; |
|
5002 | 171 |
callout_lock_exit(); |
0 | 172 |
return (0); |
173 |
} |
|
174 |
||
175 |
int |
|
176 |
getnetgrent_r(machinep, namep, domainp, buffer, buflen) |
|
177 |
char **machinep; |
|
178 |
char **namep; |
|
179 |
char **domainp; |
|
180 |
char *buffer; |
|
181 |
int buflen; |
|
182 |
{ |
|
183 |
struct nss_getnetgrent_args args; |
|
184 |
||
185 |
args.buffer = buffer; |
|
186 |
args.buflen = buflen; |
|
187 |
args.status = NSS_NETGR_NO; |
|
188 |
||
5002 | 189 |
callout_lock_enter(); |
0 | 190 |
if (getnetgrent_backend != 0) { |
191 |
(void) NSS_INVOKE_DBOP(getnetgrent_backend, |
|
192 |
NSS_DBOP_GETENT, &args); |
|
193 |
} |
|
5002 | 194 |
callout_lock_exit(); |
0 | 195 |
|
196 |
if (args.status == NSS_NETGR_FOUND) { |
|
197 |
*machinep = args.retp[NSS_NETGR_MACHINE]; |
|
198 |
*namep = args.retp[NSS_NETGR_USER]; |
|
199 |
*domainp = args.retp[NSS_NETGR_DOMAIN]; |
|
200 |
return (1); |
|
201 |
} else { |
|
202 |
return (0); |
|
203 |
} |
|
204 |
} |
|
205 |
||
206 |
static nss_XbyY_buf_t *buf; |
|
207 |
||
208 |
int |
|
209 |
getnetgrent(machinep, namep, domainp) |
|
210 |
char **machinep; |
|
211 |
char **namep; |
|
212 |
char **domainp; |
|
213 |
{ |
|
214 |
(void) NSS_XbyY_ALLOC(&buf, 0, NSS_BUFLEN_NETGROUP); |
|
215 |
return (getnetgrent_r(machinep, namep, domainp, |
|
216 |
buf->buffer, buf->buflen)); |
|
217 |
} |
|
218 |
||
219 |
int |
|
220 |
endnetgrent() |
|
221 |
{ |
|
5002 | 222 |
callout_lock_enter(); |
0 | 223 |
if (getnetgrent_backend != 0) { |
224 |
(void) NSS_INVOKE_DBOP(getnetgrent_backend, |
|
4843
5b42fe9ae29d
6590401 fixes for 6418491, 6518780 and 6570016 conspire to break java
raf
parents:
2830
diff
changeset
|
225 |
NSS_DBOP_DESTRUCTOR, 0); |
0 | 226 |
getnetgrent_backend = 0; |
227 |
} |
|
5002 | 228 |
callout_lock_exit(); |
0 | 229 |
nss_delete(&db_root); /* === ? */ |
230 |
NSS_XbyY_FREE(&buf); |
|
231 |
return (0); |
|
232 |
} |