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