xref: /netbsd-src/external/bsd/libbind/dist/irs/nis_ng.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
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