Libinfo-222.3.6.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 struct lu_netgrent
44 {
45 char *ng_host;
46 char *ng_user;
47 char *ng_domain;
48 };
49
50 static void
51 free_netgroup_data(struct lu_netgrent *ng)
52 {
53 if (ng == NULL) return;
54
55 if (ng->ng_host != NULL) free(ng->ng_host);
56 if (ng->ng_user != NULL) free(ng->ng_user);
57 if (ng->ng_domain != NULL) free(ng->ng_domain);
58 }
59
60 static void
61 free_netgroup(struct lu_netgrent *ng)
62 {
63 if (ng == NULL) return;
64 free_netgroup_data(ng);
65 free(ng);
66 }
67
68 static void
69 free_lu_thread_info_netgroup(void *x)
70 {
71 struct lu_thread_info *tdata;
72
73 if (x == NULL) return;
74
75 tdata = (struct lu_thread_info *)x;
76
77 if (tdata->lu_entry != NULL)
78 {
79 free_netgroup((struct lu_netgrent *)tdata->lu_entry);
80 tdata->lu_entry = NULL;
81 }
82
83 _lu_data_free_vm_xdr(tdata);
84
85 free(tdata);
86 }
87
88 static struct lu_netgrent *
89 extract_netgroup(XDR *xdr)
90 {
91 char *h, *u, *d;
92 struct lu_netgrent *ng;
93
94 if (xdr == NULL) return NULL;
95
96 h = NULL;
97 u = NULL;
98 d = NULL;
99
100 if (!xdr_string(xdr, &h, LU_LONG_STRING_LENGTH))
101 {
102 return NULL;
103 }
104
105 if (!xdr_string(xdr, &u, LU_LONG_STRING_LENGTH))
106 {
107 free(h);
108 return NULL;
109 }
110
111 if (!xdr_string(xdr, &d, LU_LONG_STRING_LENGTH))
112 {
113 free(h);
114 free(u);
115 return NULL;
116 }
117
118 ng = (struct lu_netgrent *)calloc(1, sizeof(struct lu_netgrent));
119
120 ng->ng_host = h;
121 ng->ng_user = u;
122 ng->ng_domain = d;
123
124 return ng;
125 }
126
127 #ifdef NOTDEF
128 static struct lu_netgrent *
129 copy_netgroup(struct lu_netgrent *in)
130 {
131 struct lu_netgrent *ng;
132
133 if (in == NULL) return NULL;
134
135 ng = (struct group *)calloc(1, sizeof(struct lu_netgrent));
136
137 ng->ng_host = LU_COPY_STRING(in->ng_host);
138 ng->ng_user = LU_COPY_STRING(in->ng_user);
139 ng->ng_domain = LU_COPY_STRING(in->ng_domain);
140
141 return ng;
142 }
143 #endif
144
145 static void
146 recycle_netgroup(struct lu_thread_info *tdata, struct lu_netgrent *in)
147 {
148 struct lu_netgrent *ng;
149
150 if (tdata == NULL) return;
151 ng = (struct lu_netgrent *)tdata->lu_entry;
152
153 if (in == NULL)
154 {
155 free_netgroup(ng);
156 tdata->lu_entry = NULL;
157 }
158
159 if (tdata->lu_entry == NULL)
160 {
161 tdata->lu_entry = in;
162 return;
163 }
164
165 free_netgroup_data(ng);
166
167 ng->ng_host = in->ng_host;
168 ng->ng_user = in->ng_user;
169 ng->ng_domain = in->ng_domain;
170
171 free(in);
172 }
173
174
175 static int
176 lu_innetgr(const char *group, const char *host, const char *user,
177 const char *domain)
178 {
179 unsigned datalen;
180 XDR xdr;
181 char namebuf[4*_LU_MAXLUSTRLEN + 3*BYTES_PER_XDR_UNIT];
182 static int proc = -1;
183 int size;
184 int res;
185 _lu_innetgr_args args;
186 char *lookup_buf;
187
188 if (proc < 0)
189 {
190 if (_lookup_link(_lu_port, "innetgr", &proc) != KERN_SUCCESS)
191 {
192 return 0;
193 }
194 }
195
196 args.group = (char *)group;
197 args.host = FIX(host);
198 args.user = FIX(user);
199 args.domain = FIX(domain);
200
201 xdrmem_create(&xdr, namebuf, sizeof(namebuf), XDR_ENCODE);
202 if (!xdr__lu_innetgr_args(&xdr, &args))
203 {
204 xdr_destroy(&xdr);
205 return 0;
206 }
207
208 size = xdr_getpos(&xdr) / BYTES_PER_XDR_UNIT;
209 xdr_destroy(&xdr);
210
211 datalen = 0;
212 lookup_buf = NULL;
213
214 if (_lookup_all(_lu_port, proc, (unit *)namebuf, size, &lookup_buf, &datalen) != KERN_SUCCESS)
215 {
216 return 0;
217 }
218
219 datalen *= BYTES_PER_XDR_UNIT;
220 if ((lookup_buf == NULL) || (datalen == 0)) return 0;
221
222 xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE);
223 if (!xdr_int(&xdr, &res))
224 {
225 xdr_destroy(&xdr);
226 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
227 return 0;
228 }
229
230 xdr_destroy(&xdr);
231 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
232
233 return 1;
234 }
235
236 static void
237 lu_endnetgrent(void)
238 {
239 struct lu_thread_info *tdata;
240
241 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
242 _lu_data_free_vm_xdr(tdata);
243 }
244
245
246 /*
247 * This is different than the other setXXXent routines
248 * since this is really more like getnetgrbyname() than
249 * getnetgrent().
250 */
251 static void
252 lu_setnetgrent(const char *name)
253 {
254 unsigned datalen;
255 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
256 XDR outxdr;
257 static int proc = -1;
258 struct lu_thread_info *tdata;
259
260 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
261 if (tdata == NULL)
262 {
263 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
264 _lu_data_set_key(_lu_data_key_netgroup, tdata);
265 }
266
267 lu_endnetgrent();
268
269 if (proc < 0)
270 {
271 if (_lookup_link(_lu_port, "getnetgrent", &proc) != KERN_SUCCESS)
272 {
273 lu_endnetgrent();
274 return;
275 }
276 }
277
278 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
279 if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
280 {
281 xdr_destroy(&outxdr);
282 lu_endnetgrent();
283 return;
284 }
285
286 datalen = xdr_getpos(&outxdr);
287 xdr_destroy(&outxdr);
288 if (_lookup_all(_lu_port, proc, (unit *)namebuf, datalen / BYTES_PER_XDR_UNIT, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
289 {
290 lu_endnetgrent();
291 return;
292 }
293
294 /* mig stubs measure size in words (4 bytes) */
295 tdata->lu_vm_length *= 4;
296
297 if (tdata->lu_xdr != NULL)
298 {
299 xdr_destroy(tdata->lu_xdr);
300 free(tdata->lu_xdr);
301 }
302 tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
303
304 xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
305 if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor)) lu_endnetgrent();
306 }
307
308
309 static struct lu_netgrent *
310 lu_getnetgrent(void)
311 {
312 struct lu_netgrent *ng;
313 struct lu_thread_info *tdata;
314
315 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
316 if (tdata == NULL) return NULL;
317
318 if (tdata->lu_vm_cursor == 0)
319 {
320 lu_endnetgrent();
321 return NULL;
322 }
323
324 ng = extract_netgroup(tdata->lu_xdr);
325 if (ng == NULL)
326 {
327 lu_endnetgrent();
328 return NULL;
329 }
330
331 tdata->lu_vm_cursor--;
332
333 return ng;
334 }
335
336 int
337 innetgr(const char *group, const char *host, const char *user,
338 const char *domain)
339 {
340 if (_lu_running()) return (lu_innetgr(group, host, user, domain));
341 return 0;
342 }
343
344 int
345 getnetgrent(char **host, char **user, char **domain)
346 {
347 struct lu_netgrent *res = NULL;
348 struct lu_thread_info *tdata;
349
350 tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
351 if (tdata == NULL)
352 {
353 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
354 _lu_data_set_key(_lu_data_key_netgroup, tdata);
355 }
356
357 res = NULL;
358 if (_lu_running()) res = lu_getnetgrent();
359
360 recycle_netgroup(tdata, res);
361 if (res == NULL) return 0;
362
363 if (host != NULL) *host = res->ng_host;
364 if (user != NULL) *user = res->ng_user;
365 if (domain != NULL) *domain = res->ng_domain;
366
367 return 1;
368 }
369
370 void
371 setnetgrent(const char *name)
372 {
373 if (_lu_running()) lu_setnetgrent(name);
374 }
375
376 void
377 endnetgrent(void)
378 {
379 if (_lu_running()) lu_endnetgrent();
380 }