1*5bbd2a12Schristos /* $NetBSD: nis_ng.c,v 1.1.1.2 2012/09/09 16:07:58 christos Exp $ */
2b5677b36Schristos
3b5677b36Schristos /*
4b5677b36Schristos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5b5677b36Schristos * Copyright (c) 1996,1999 by Internet Software Consortium.
6b5677b36Schristos *
7b5677b36Schristos * Permission to use, copy, modify, and distribute this software for any
8b5677b36Schristos * purpose with or without fee is hereby granted, provided that the above
9b5677b36Schristos * copyright notice and this permission notice appear in all copies.
10b5677b36Schristos *
11b5677b36Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12b5677b36Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13b5677b36Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14b5677b36Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15b5677b36Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16b5677b36Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17b5677b36Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18b5677b36Schristos */
19b5677b36Schristos
20b5677b36Schristos #if defined(LIBC_SCCS) && !defined(lint)
21b5677b36Schristos static const char rcsid[] = "Id: nis_ng.c,v 1.4 2005/04/27 04:56:32 sra Exp ";
22b5677b36Schristos #endif
23b5677b36Schristos
24b5677b36Schristos /* Imports */
25b5677b36Schristos
26b5677b36Schristos #include "port_before.h"
27b5677b36Schristos
28b5677b36Schristos #ifndef WANT_IRS_NIS
29b5677b36Schristos static int __bind_irs_nis_unneeded;
30b5677b36Schristos #else
31b5677b36Schristos
32b5677b36Schristos #include <sys/types.h>
33b5677b36Schristos #include <netinet/in.h>
34b5677b36Schristos #include <rpc/rpc.h>
35b5677b36Schristos #include <rpc/xdr.h>
36b5677b36Schristos #include <rpcsvc/yp_prot.h>
37b5677b36Schristos #include <rpcsvc/ypclnt.h>
38b5677b36Schristos
39b5677b36Schristos #include <isc/assertions.h>
40b5677b36Schristos #include <ctype.h>
41b5677b36Schristos #include <errno.h>
42b5677b36Schristos #include <netdb.h>
43b5677b36Schristos #include <stdio.h>
44b5677b36Schristos #include <stdlib.h>
45b5677b36Schristos #include <string.h>
46b5677b36Schristos
47b5677b36Schristos #include <netinet/in.h>
48b5677b36Schristos #ifdef T_NULL
49b5677b36Schristos #undef T_NULL /* Silence re-definition warning of T_NULL. */
50b5677b36Schristos #endif
51b5677b36Schristos #include <arpa/nameser.h>
52b5677b36Schristos #include <resolv.h>
53b5677b36Schristos
54b5677b36Schristos #include <isc/memcluster.h>
55b5677b36Schristos #include <irs.h>
56b5677b36Schristos
57b5677b36Schristos #include "port_after.h"
58b5677b36Schristos
59b5677b36Schristos #include "irs_p.h"
60b5677b36Schristos #include "nis_p.h"
61b5677b36Schristos
62b5677b36Schristos /* Definitions */
63b5677b36Schristos
64b5677b36Schristos struct tmpgrp {
65b5677b36Schristos const char * name;
66b5677b36Schristos const char * host;
67b5677b36Schristos const char * user;
68b5677b36Schristos const char * domain;
69b5677b36Schristos struct tmpgrp * next;
70b5677b36Schristos };
71b5677b36Schristos
72b5677b36Schristos struct pvt {
73b5677b36Schristos char * nis_domain;
74b5677b36Schristos struct tmpgrp * tmp;
75b5677b36Schristos struct tmpgrp * cur;
76b5677b36Schristos char * tmpgroup;
77b5677b36Schristos };
78b5677b36Schristos
79b5677b36Schristos enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
80b5677b36Schristos
81b5677b36Schristos static /*const*/ char netgroup_map[] = "netgroup";
82b5677b36Schristos
83b5677b36Schristos /* Forward */
84b5677b36Schristos
85b5677b36Schristos static void ng_close(struct irs_ng *);
86b5677b36Schristos static int ng_next(struct irs_ng *, const char **,
87b5677b36Schristos const char **, const char **);
88b5677b36Schristos static int ng_test(struct irs_ng *,
89b5677b36Schristos const char *, const char *,
90b5677b36Schristos const char *, const char *);
91b5677b36Schristos static void ng_rewind(struct irs_ng *, const char *);
92b5677b36Schristos static void ng_minimize(struct irs_ng *);
93b5677b36Schristos
94b5677b36Schristos static void add_group_to_list(struct pvt *, const char *, int);
95b5677b36Schristos static void add_tuple_to_list(struct pvt *, const char *, char *);
96b5677b36Schristos static void tmpfree(struct pvt *);
97b5677b36Schristos
98b5677b36Schristos /* Public */
99b5677b36Schristos
100b5677b36Schristos struct irs_ng *
irs_nis_ng(struct irs_acc * this)101b5677b36Schristos irs_nis_ng(struct irs_acc *this) {
102b5677b36Schristos struct irs_ng *ng;
103b5677b36Schristos struct pvt *pvt;
104b5677b36Schristos
105b5677b36Schristos if (!(ng = memget(sizeof *ng))) {
106b5677b36Schristos errno = ENOMEM;
107b5677b36Schristos return (NULL);
108b5677b36Schristos }
109b5677b36Schristos memset(ng, 0x5e, sizeof *ng);
110b5677b36Schristos if (!(pvt = memget(sizeof *pvt))) {
111b5677b36Schristos memput(ng, sizeof *ng);
112b5677b36Schristos errno = ENOMEM;
113b5677b36Schristos return (NULL);
114b5677b36Schristos }
115b5677b36Schristos memset(pvt, 0, sizeof *pvt);
116b5677b36Schristos pvt->nis_domain = ((struct nis_p *)this->private)->domain;
117b5677b36Schristos ng->private = pvt;
118b5677b36Schristos ng->close = ng_close;
119b5677b36Schristos ng->next = ng_next;
120b5677b36Schristos ng->test = ng_test;
121b5677b36Schristos ng->rewind = ng_rewind;
122b5677b36Schristos ng->minimize = ng_minimize;
123b5677b36Schristos return (ng);
124b5677b36Schristos }
125b5677b36Schristos
126b5677b36Schristos /* Methods */
127b5677b36Schristos
128b5677b36Schristos static void
ng_close(struct irs_ng * this)129b5677b36Schristos ng_close(struct irs_ng *this) {
130b5677b36Schristos struct pvt *pvt = (struct pvt *)this->private;
131b5677b36Schristos
132b5677b36Schristos tmpfree(pvt);
133b5677b36Schristos memput(pvt, sizeof *pvt);
134b5677b36Schristos memput(this, sizeof *this);
135b5677b36Schristos }
136b5677b36Schristos
137b5677b36Schristos static int
ng_next(struct irs_ng * this,const char ** host,const char ** user,const char ** domain)138b5677b36Schristos ng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) {
139b5677b36Schristos struct pvt *pvt = (struct pvt *)this->private;
140b5677b36Schristos
141b5677b36Schristos if (!pvt->cur)
142b5677b36Schristos return (0);
143b5677b36Schristos *host = pvt->cur->host;
144b5677b36Schristos *user = pvt->cur->user;
145b5677b36Schristos *domain = pvt->cur->domain;
146b5677b36Schristos pvt->cur = pvt->cur->next;
147b5677b36Schristos return (1);
148b5677b36Schristos }
149b5677b36Schristos
150b5677b36Schristos static int
ng_test(struct irs_ng * this,const char * name,const char * host,const char * user,const char * domain)151b5677b36Schristos ng_test(struct irs_ng *this, const char *name,
152b5677b36Schristos const char *host, const char *user, const char *domain)
153b5677b36Schristos {
154b5677b36Schristos struct pvt *pvt = (struct pvt *)this->private;
155b5677b36Schristos struct tmpgrp *cur;
156b5677b36Schristos
157b5677b36Schristos tmpfree(pvt);
158b5677b36Schristos add_group_to_list(pvt, name, strlen(name));
159b5677b36Schristos for (cur = pvt->tmp; cur; cur = cur->next) {
160b5677b36Schristos if ((!host || !cur->host || !strcmp(host, cur->host)) &&
161b5677b36Schristos (!user || !cur->user || !strcmp(user, cur->user)) &&
162b5677b36Schristos (!domain || !cur->domain || !strcmp(domain, cur->domain)))
163b5677b36Schristos break;
164b5677b36Schristos }
165b5677b36Schristos tmpfree(pvt);
166b5677b36Schristos return ((cur == NULL) ? 0 : 1);
167b5677b36Schristos }
168b5677b36Schristos
169b5677b36Schristos static void
ng_rewind(struct irs_ng * this,const char * name)170b5677b36Schristos ng_rewind(struct irs_ng *this, const char *name) {
171b5677b36Schristos struct pvt *pvt = (struct pvt *)this->private;
172b5677b36Schristos
173b5677b36Schristos /* Either hand back or free the existing list. */
174b5677b36Schristos if (pvt->tmpgroup) {
175b5677b36Schristos if (pvt->tmp && !strcmp(pvt->tmpgroup, name))
176b5677b36Schristos goto reset;
177b5677b36Schristos tmpfree(pvt);
178b5677b36Schristos }
179b5677b36Schristos pvt->tmpgroup = strdup(name);
180b5677b36Schristos add_group_to_list(pvt, name, strlen(name));
181b5677b36Schristos reset:
182b5677b36Schristos pvt->cur = pvt->tmp;
183b5677b36Schristos }
184b5677b36Schristos
185b5677b36Schristos static void
ng_minimize(struct irs_ng * this)186b5677b36Schristos ng_minimize(struct irs_ng *this) {
187b5677b36Schristos UNUSED(this);
188b5677b36Schristos /* NOOP */
189b5677b36Schristos }
190b5677b36Schristos
191b5677b36Schristos /* Private */
192b5677b36Schristos
193b5677b36Schristos static void
add_group_to_list(struct pvt * pvt,const char * name,int len)194b5677b36Schristos add_group_to_list(struct pvt *pvt, const char *name, int len) {
195b5677b36Schristos char *vdata, *cp, *np;
196b5677b36Schristos struct tmpgrp *tmp;
197b5677b36Schristos int vlen, r;
198b5677b36Schristos char *nametmp;
199b5677b36Schristos
200b5677b36Schristos /* Don't add the same group to the list more than once. */
201b5677b36Schristos for (tmp = pvt->tmp; tmp; tmp = tmp->next)
202b5677b36Schristos if (!strcmp(tmp->name, name))
203b5677b36Schristos return;
204b5677b36Schristos
205b5677b36Schristos DE_CONST(name, nametmp);
206b5677b36Schristos r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len,
207b5677b36Schristos &vdata, &vlen);
208b5677b36Schristos if (r == 0) {
209b5677b36Schristos cp = vdata;
210b5677b36Schristos if (*cp && cp[strlen(cp)-1] == '\n')
211b5677b36Schristos cp[strlen(cp)-1] = '\0';
212b5677b36Schristos for ( ; cp; cp = np) {
213b5677b36Schristos np = strchr(cp, ' ');
214b5677b36Schristos if (np)
215b5677b36Schristos *np++ = '\0';
216b5677b36Schristos if (*cp == '(')
217b5677b36Schristos add_tuple_to_list(pvt, name, cp);
218b5677b36Schristos else
219b5677b36Schristos add_group_to_list(pvt, cp, strlen(cp));
220b5677b36Schristos }
221b5677b36Schristos free(vdata);
222b5677b36Schristos }
223b5677b36Schristos }
224b5677b36Schristos
225b5677b36Schristos static void
add_tuple_to_list(struct pvt * pvt,const char * name,char * cp)226b5677b36Schristos add_tuple_to_list(struct pvt *pvt, const char *name, char *cp) {
227b5677b36Schristos struct tmpgrp *tmp;
228b5677b36Schristos char *tp, *np;
229b5677b36Schristos
230b5677b36Schristos INSIST(*cp++ == '(');
231b5677b36Schristos
232b5677b36Schristos tmp = malloc(sizeof *tmp + strlen(name) + sizeof '\0' +
233b5677b36Schristos strlen(cp) - sizeof ')');
234b5677b36Schristos if (!tmp)
235b5677b36Schristos return;
236b5677b36Schristos memset(tmp, 0, sizeof *tmp);
237b5677b36Schristos tp = ((char *)tmp) + sizeof *tmp;
238b5677b36Schristos
239b5677b36Schristos /* Name */
240b5677b36Schristos strcpy(tp, name);
241b5677b36Schristos tmp->name = tp;
242b5677b36Schristos tp += strlen(tp) + 1;
243b5677b36Schristos
244b5677b36Schristos /* Host */
245b5677b36Schristos if (!(np = strchr(cp, ',')))
246b5677b36Schristos goto cleanup;
247b5677b36Schristos *np++ = '\0';
248b5677b36Schristos strcpy(tp, cp);
249b5677b36Schristos tmp->host = tp;
250b5677b36Schristos tp += strlen(tp) + 1;
251b5677b36Schristos cp = np;
252b5677b36Schristos
253b5677b36Schristos /* User */
254b5677b36Schristos if (!(np = strchr(cp, ',')))
255b5677b36Schristos goto cleanup;
256b5677b36Schristos *np++ = '\0';
257b5677b36Schristos strcpy(tp, cp);
258b5677b36Schristos tmp->user = tp;
259b5677b36Schristos tp += strlen(tp) + 1;
260b5677b36Schristos cp = np;
261b5677b36Schristos
262b5677b36Schristos /* Domain */
263b5677b36Schristos if (!(np = strchr(cp, ')')))
264b5677b36Schristos goto cleanup;
265b5677b36Schristos *np++ = '\0';
266b5677b36Schristos strcpy(tp, cp);
267b5677b36Schristos tmp->domain = tp;
268b5677b36Schristos
269b5677b36Schristos /*
270b5677b36Schristos * Empty string in file means wildcard, but
271b5677b36Schristos * NULL string in return value means wildcard.
272b5677b36Schristos */
273b5677b36Schristos if (!*tmp->host)
274b5677b36Schristos tmp->host = NULL;
275b5677b36Schristos if (!*tmp->user)
276b5677b36Schristos tmp->user = NULL;
277b5677b36Schristos if (!*tmp->domain)
278b5677b36Schristos tmp->domain = NULL;
279b5677b36Schristos
280b5677b36Schristos /* Add to list (LIFO). */
281b5677b36Schristos tmp->next = pvt->tmp;
282b5677b36Schristos pvt->tmp = tmp;
283b5677b36Schristos return;
284b5677b36Schristos
285b5677b36Schristos cleanup:
286b5677b36Schristos free(tmp);
287b5677b36Schristos }
288b5677b36Schristos
289b5677b36Schristos static void
tmpfree(struct pvt * pvt)290b5677b36Schristos tmpfree(struct pvt *pvt) {
291b5677b36Schristos struct tmpgrp *cur, *next;
292b5677b36Schristos
293b5677b36Schristos if (pvt->tmpgroup) {
294b5677b36Schristos free(pvt->tmpgroup);
295b5677b36Schristos pvt->tmpgroup = NULL;
296b5677b36Schristos }
297b5677b36Schristos for (cur = pvt->tmp; cur; cur = next) {
298b5677b36Schristos next = cur->next;
299b5677b36Schristos free(cur);
300b5677b36Schristos }
301b5677b36Schristos pvt->tmp = NULL;
302b5677b36Schristos }
303b5677b36Schristos
304b5677b36Schristos #endif /*WANT_IRS_NIS*/
305b5677b36Schristos
306b5677b36Schristos /*! \file */
307