Libinfo-129.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_netgroup.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Netgroup lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28 #include <netgr.h>
29 #include <mach/mach.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <rpc/types.h>
34 #include <rpc/xdr.h>
35
36 #include "_lu_types.h"
37 #include "lookup.h"
38 #include "lu_utils.h"
39 #include "lu_overrides.h"
40
41 #define FIX(x) ((x == NULL) ? NULL : (_lu_string *)&(x))
42
43 static void
44 free_netgroup_data(struct netgrent *ng)
45 {
46 if (ng == NULL) return;
47
48 if (ng->ng_host != NULL) free(ng->ng_host);
49 if (ng->ng_user != NULL) free(ng->ng_user);
50 if (ng->ng_domain != NULL) free(ng->ng_domain);
51 }
52
53 static void
54 free_netgroup(struct netgrent *ng)
55 {
56 if (ng == NULL) return;
57 free_netgroup_data(ng);
58 free(ng);
59 }
60
61 static void
62 free_lu_thread_info_netgroup(void *x)
63 {
64 struct lu_thread_info *tdata;
65
66 if (x == NULL) return;
67
68 tdata = (struct lu_thread_info *)x;
69
70 if (tdata->lu_entry != NULL)
71 {
72 free_netgroup((struct netgrent *)tdata->lu_entry);
73 tdata->lu_entry = NULL;
74 }
75
76 _lu_data_free_vm_xdr(tdata);
77
78 free(tdata);
79 }
80
81 static struct netgrent *
82 extract_netgroup(XDR *xdr)
83 {
84 char *h, *u, *d;
85 struct netgrent *ng;
86
87 if (xdr == NULL) return NULL;
88
89 h = NULL;
90 u = NULL;
91 d = NULL;
92
93 if (!xdr_string(xdr, &h, LU_LONG_STRING_LENGTH))
94 {
95 return NULL;
96 }
97
98 if (!xdr_string(xdr, &u, LU_LONG_STRING_LENGTH))
99 {
100 free(h);
101 return NULL;
102 }
103
104 if (!xdr_string(xdr, &d, LU_LONG_STRING_LENGTH))
105 {
106 free(h);
107 free(u);
108 return NULL;
109 }
110
111 ng = (struct netgrent *)calloc(1, sizeof(struct netgrent));
112
113 ng->ng_host = h;
114 ng->ng_user = u;
115 ng->ng_domain = d;
116
117 return ng;
118 }
119
120 #ifdef NOTDEF
121 static struct netgrent *
122 copy_netgroup(struct netgrent *in)
123 {
124 struct netgrent *ng;
125
126 if (in == NULL) return NULL;
127
128 ng = (struct group *)calloc(1, sizeof(struct netgrent));
129
130 ng->ng_host = LU_COPY_STRING(in->ng_host);
131 ng->ng_user = LU_COPY_STRING(in->ng_user);
132 ng->ng_domain = LU_COPY_STRING(in->ng_domain);
133
134 return ng;
135 }
136 #endif
137
138 static void
139 recycle_netgroup(struct lu_thread_info *tdata, struct netgrent *in)
140 {
141 struct netgrent *ng;
142
143 if (tdata == NULL) return;
144 ng = (struct netgrent *)tdata->lu_entry;
145
146 if (in == NULL)
147 {
148 free_netgroup(ng);
149 tdata->lu_entry = NULL;
150 }
151
152 if (tdata->lu_entry == NULL)
153 {
154 tdata->lu_entry = in;
155 return;
156 }
157
158 free_netgroup_data(ng);
159
160 ng->ng_host = in->ng_host;
161 ng->ng_user = in->ng_user;
162 ng->ng_domain = in->ng_domain;
163
164 free(in);
165 }
166
167
168 static int
169 lu_innetgr(const char *group, const char *host, const char *user,
170 const char *domain)
171 {
172 unsigned datalen;
173 XDR xdr;
174 char namebuf[4*_LU_MAXLUSTRLEN + 3*BYTES_PER_XDR_UNIT];
175 static int proc = -1;
176 int size;
177 int res;
178 _lu_innetgr_args args;
179 char *lookup_buf;
180
181 if (proc < 0)
182 {
183 if (_lookup_link(_lu_port, "innetgr", &proc) != KERN_SUCCESS)
184 {
185 return 0;
186 }
187 }
188
189 args.group = (char *)group;
190 args.host = FIX(host);
191 args.user = FIX(user);
192 args.domain = FIX(domain);
193
194 xdrmem_create(&xdr, namebuf, sizeof(namebuf), XDR_ENCODE);
195 if (!xdr__lu_innetgr_args(&xdr, &args))
196 {
197 xdr_destroy(&xdr);
198 return 0;
199 }
200
201 size = xdr_getpos(&xdr) / BYTES_PER_XDR_UNIT;
202 xdr_destroy(&xdr);
203
204 datalen = 0;
205 lookup_buf = NULL;
206
207 if (_lookup_all(_lu_port, proc, (unit *)namebuf, size, &lookup_buf, &datalen) != KERN_SUCCESS)
208 {
209 return 0;
210 }
211
212 datalen *= BYTES_PER_XDR_UNIT;
213 if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
214
215 xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE);
216 if (!xdr_int(&xdr, &res))
217 {
218 xdr_destroy(&xdr);
219 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
220 return 0;
221 }
222
223 xdr_destroy(&xdr);
224 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
225
226 return res;
227 }
228
229 static void
230 lu_endnetgrent(void)
231 {
232 struct lu_thread_info *tdata;
233
234 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
235 _lu_data_free_vm_xdr(tdata);
236 }
237
238
239 /*
240 * This is different than the other setXXXent routines
241 * since this is really more like getnetgrbyname() than
242 * getnetgrent().
243 */
244 static void
245 lu_setnetgrent(const char *name)
246 {
247 unsigned datalen;
248 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
249 XDR outxdr;
250 static int proc = -1;
251 struct lu_thread_info *tdata;
252
253 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
254 if (tdata == NULL)
255 {
256 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
257 _lu_data_set_key(_lu_data_key_netgroup, tdata);
258 }
259
260 lu_endnetgrent();
261
262 if (proc < 0)
263 {
264 if (_lookup_link(_lu_port, "getnetgrent", &proc) != KERN_SUCCESS)
265 {
266 lu_endnetgrent();
267 return;
268 }
269 }
270
271 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
272 if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
273 {
274 xdr_destroy(&outxdr);
275 lu_endnetgrent();
276 return;
277 }
278
279 datalen = xdr_getpos(&outxdr);
280 xdr_destroy(&outxdr);
281 if (_lookup_all(_lu_port, proc, (unit *)namebuf, datalen / BYTES_PER_XDR_UNIT, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
282 {
283 lu_endnetgrent();
284 return;
285 }
286
287 /* mig stubs measure size in words (4 bytes) */
288 tdata->lu_vm_length *= 4;
289
290 if (tdata->lu_xdr != NULL)
291 {
292 xdr_destroy(tdata->lu_xdr);
293 free(tdata->lu_xdr);
294 }
295 tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
296
297 xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
298 if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor)) lu_endnetgrent();
299 }
300
301
302 struct netgrent *
303 lu_getnetgrent(void)
304 {
305 struct netgrent *ng;
306 struct lu_thread_info *tdata;
307
308 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
309 if (tdata == NULL) return NULL;
310
311 if (tdata->lu_vm_cursor == 0)
312 {
313 lu_endnetgrent();
314 return NULL;
315 }
316
317 ng = extract_netgroup(tdata->lu_xdr);
318 if (ng == NULL)
319 {
320 lu_endnetgrent();
321 return NULL;
322 }
323
324 tdata->lu_vm_cursor--;
325
326 return ng;
327 }
328
329 int
330 innetgr(const char *group, const char *host, const char *user,
331 const char *domain)
332 {
333 if (_lu_running()) return (lu_innetgr(group, host, user, domain));
334 return 0;
335 }
336
337 struct netgrent *
338 getnetgrent(void)
339 {
340 struct netgrent *res = NULL;
341 struct lu_thread_info *tdata;
342
343 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
344 if (tdata == NULL)
345 {
346 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
347 _lu_data_set_key(_lu_data_key_netgroup, tdata);
348 }
349
350 res = NULL;
351 if (_lu_running()) res = lu_getnetgrent();
352
353 recycle_netgroup(tdata, res);
354 return (struct netgrent *)tdata->lu_entry;
355 }
356
357 void
358 setnetgrent(const char *name)
359 {
360 if (_lu_running()) lu_setnetgrent(name);
361 }
362
363 void
364 endnetgrent(void)
365 {
366 if (_lu_running()) lu_endnetgrent();
367 }