]> git.saurik.com Git - apple/libinfo.git/blob - lookup.subproj/lu_netgroup.c
Libinfo-278.0.3.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 <netdb.h>
29 #include <mach/mach.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include "lu_utils.h"
34 #include "lu_overrides.h"
35
36 struct li_netgrent
37 {
38 char *ng_host;
39 char *ng_user;
40 char *ng_domain;
41 };
42
43 #define ENTRY_SIZE sizeof(struct li_netgrent)
44 #define ENTRY_KEY _li_data_key_netgroup
45
46 static struct li_netgrent *
47 copy_netgroup(struct li_netgrent *in)
48 {
49 if (in == NULL) return NULL;
50
51 return (struct li_netgrent *)LI_ils_create("sss", in->ng_host, in->ng_user, in->ng_domain);
52 }
53
54 /*
55 * Extract the next netgroup entry from a kvarray.
56 */
57 static struct li_netgrent *
58 extract_netgroup(kvarray_t *in)
59 {
60 struct li_netgrent tmp;
61 uint32_t d, k, kcount;
62
63 if (in == NULL) return NULL;
64
65 d = in->curr;
66 in->curr++;
67
68 if (d >= in->count) return NULL;
69
70 memset(&tmp, 0, ENTRY_SIZE);
71
72 kcount = in->dict[d].kcount;
73
74 for (k = 0; k < kcount; k++)
75 {
76 if (!strcmp(in->dict[d].key[k], "user"))
77 {
78 if (tmp.ng_user != NULL) continue;
79 if (in->dict[d].vcount[k] == 0) continue;
80
81 tmp.ng_user = (char *)in->dict[d].val[k][0];
82 }
83 else if (!strcmp(in->dict[d].key[k], "host"))
84 {
85 if (tmp.ng_host != NULL) continue;
86 if (in->dict[d].vcount[k] == 0) continue;
87
88 tmp.ng_host = (char *)in->dict[d].val[k][0];
89 }
90 else if (!strcmp(in->dict[d].key[k], "domain"))
91 {
92 if (tmp.ng_domain != NULL) continue;
93 if (in->dict[d].vcount[k] == 0) continue;
94
95 tmp.ng_domain = (char *)in->dict[d].val[k][0];
96 }
97 }
98
99 if (tmp.ng_user == NULL) tmp.ng_user = "";
100 if (tmp.ng_host == NULL) tmp.ng_host = "";
101 if (tmp.ng_domain == NULL) tmp.ng_domain = "";
102
103 return copy_netgroup(&tmp);
104 }
105
106 static int
107 check_innetgr(kvarray_t *in)
108 {
109 uint32_t d, k, kcount;
110
111 if (in == NULL) return 0;
112
113 d = in->curr;
114 if (d >= in->count) return 0;
115
116 kcount = in->dict[d].kcount;
117
118 for (k = 0; k < kcount; k++)
119 {
120 if (!strcmp(in->dict[d].key[k], "result"))
121 {
122 if (in->dict[d].vcount[k] == 0) continue;
123 return atoi(in->dict[d].val[k][0]);
124 }
125 }
126
127 return 0;
128 }
129
130 static int
131 ds_innetgr(const char *group, const char *host, const char *user, const char *domain)
132 {
133 int is_innetgr;
134 kvbuf_t *request;
135 kvarray_t *reply;
136 kern_return_t status;
137 static int proc = -1;
138
139 if (proc < 0)
140 {
141 status = LI_DSLookupGetProcedureNumber("innetgr", &proc);
142 if (status != KERN_SUCCESS) return 0;
143 }
144
145 /* Encode NULL */
146 if (group == NULL) group = "";
147 if (host == NULL) host = "";
148 if (user == NULL) user = "";
149 if (domain == NULL) domain = "";
150
151 request = kvbuf_query("ksksksks", "netgroup", group, "host", host, "user", user, "domain", domain);
152 if (request == NULL) return 0;
153
154 reply = NULL;
155 status = LI_DSLookupQuery(proc, request, &reply);
156 kvbuf_free(request);
157
158 if (status != KERN_SUCCESS) return 0;
159
160 is_innetgr = check_innetgr(reply);
161 kvarray_free(reply);
162
163 return is_innetgr;
164 }
165
166 static void
167 ds_endnetgrent(void)
168 {
169 LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
170 }
171
172 /*
173 * This is different than the other setXXXent routines
174 * since this is really more like getnetgrbyname() than
175 * getnetgrent().
176 */
177 static void
178 ds_setnetgrent(const char *name)
179 {
180 struct li_thread_info *tdata;
181 kvbuf_t *request;
182 kvarray_t *reply;
183 kern_return_t status;
184 static int proc = -1;
185
186 tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
187 if (tdata == NULL) return;
188
189 if (tdata->li_vm != NULL) return;
190
191 if (proc < 0)
192 {
193 status = LI_DSLookupGetProcedureNumber("getnetgrent", &proc);
194 if (status != KERN_SUCCESS)
195 {
196 LI_data_free_kvarray(tdata);
197 return;
198 }
199 }
200
201 request = kvbuf_query_key_val("netgroup", name);
202 if (request == NULL) return;
203
204 reply = NULL;
205 status = LI_DSLookupQuery(proc, request, &reply);
206 kvbuf_free(request);
207
208 if (status != KERN_SUCCESS)
209 {
210 LI_data_free_kvarray(tdata);
211 return;
212 }
213
214 tdata->li_vm = (char *)reply;
215 }
216
217
218 static struct li_netgrent *
219 ds_getnetgrent(void)
220 {
221 struct li_netgrent *entry;
222 struct li_thread_info *tdata;
223
224 tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
225 if (tdata == NULL) return NULL;
226
227 entry = extract_netgroup((kvarray_t *)(tdata->li_vm));
228 if (entry == NULL)
229 {
230 ds_endnetgrent();
231 return NULL;
232 }
233
234 return entry;
235 }
236
237 int
238 innetgr(const char *group, const char *host, const char *user,
239 const char *domain)
240 {
241 if (_ds_running()) return (ds_innetgr(group, host, user, domain));
242 return 0;
243 }
244
245 int
246 getnetgrent(char **host, char **user, char **domain)
247 {
248 struct li_netgrent *res = NULL;
249 struct li_thread_info *tdata;
250
251 tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
252 if (tdata == NULL) return 0;
253
254 res = NULL;
255 if (_ds_running()) res = ds_getnetgrent();
256
257 LI_data_recycle(tdata, res, ENTRY_SIZE);
258 if (res == NULL) return 0;
259
260 if (host != NULL) *host = res->ng_host;
261 if (user != NULL) *user = res->ng_user;
262 if (domain != NULL) *domain = res->ng_domain;
263
264 return 1;
265 }
266
267 void
268 setnetgrent(const char *name)
269 {
270 if (_ds_running()) ds_setnetgrent(name);
271 }
272
273 void
274 endnetgrent(void)
275 {
276 if (_ds_running()) ds_endnetgrent();
277 }