nis_ng.c revision 1.1.1.1.4.2
1164426Ssam/*	$NetBSD: nis_ng.c,v 1.1.1.1.4.2 2011/01/06 21:42:18 riz Exp $	*/
2164426Ssam
3164426Ssam/*
4164426Ssam * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5164426Ssam * Copyright (c) 1996,1999 by Internet Software Consortium.
6164426Ssam *
7164426Ssam * Permission to use, copy, modify, and distribute this software for any
8164426Ssam * purpose with or without fee is hereby granted, provided that the above
9164426Ssam * copyright notice and this permission notice appear in all copies.
10164426Ssam *
11164426Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12164426Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13164426Ssam * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14164426Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15164426Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16164426Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17164426Ssam * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18164426Ssam */
19164426Ssam
20164426Ssam#if defined(LIBC_SCCS) && !defined(lint)
21164426Ssamstatic const char rcsid[] = "Id: nis_ng.c,v 1.4 2005/04/27 04:56:32 sra Exp";
22164426Ssam#endif
23164426Ssam
24164426Ssam/* Imports */
25164426Ssam
26164426Ssam#include "port_before.h"
27164426Ssam
28164426Ssam#ifndef WANT_IRS_NIS
29164426Ssamstatic int __bind_irs_nis_unneeded;
30164426Ssam#else
31164426Ssam
32164426Ssam#include <sys/types.h>
33164426Ssam#include <netinet/in.h>
34164426Ssam#include <rpc/rpc.h>
35164426Ssam#include <rpc/xdr.h>
36164426Ssam#include <rpcsvc/yp_prot.h>
37164426Ssam#include <rpcsvc/ypclnt.h>
38164426Ssam
39164426Ssam#include <isc/assertions.h>
40164426Ssam#include <ctype.h>
41164426Ssam#include <errno.h>
42164426Ssam#include <netdb.h>
43164426Ssam#include <stdio.h>
44164426Ssam#include <stdlib.h>
45164426Ssam#include <string.h>
46164426Ssam
47164426Ssam#include <netinet/in.h>
48164426Ssam#ifdef T_NULL
49164426Ssam#undef T_NULL			/* Silence re-definition warning of T_NULL. */
50164426Ssam#endif
51164426Ssam#include <arpa/nameser.h>
52164426Ssam#include <resolv.h>
53164426Ssam
54164426Ssam#include <isc/memcluster.h>
55164426Ssam#include <irs.h>
56164426Ssam
57164426Ssam#include "port_after.h"
58164426Ssam
59164426Ssam#include "irs_p.h"
60164426Ssam#include "nis_p.h"
61164426Ssam
62164426Ssam/* Definitions */
63164426Ssam
64164426Ssamstruct tmpgrp {
65164426Ssam	const char *	name;
66164426Ssam	const char *	host;
67164426Ssam	const char *	user;
68164426Ssam	const char *	domain;
69164426Ssam	struct tmpgrp *	next;
70164426Ssam};
71164426Ssam
72164426Ssamstruct pvt {
73164426Ssam	char *		nis_domain;
74164426Ssam	struct tmpgrp *	tmp;
75164426Ssam	struct tmpgrp *	cur;
76164426Ssam	char *		tmpgroup;
77164426Ssam};
78164426Ssam
79164426Ssamenum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
80164426Ssam
81164426Ssamstatic /*const*/ char netgroup_map[]	= "netgroup";
82164426Ssam
83164426Ssam/* Forward */
84164426Ssam
85164426Ssamstatic void 		ng_close(struct irs_ng *);
86164426Ssamstatic int		ng_next(struct irs_ng *, const char **,
87164426Ssam				const char **, const char **);
88164426Ssamstatic int		ng_test(struct irs_ng *,
89164426Ssam 				const char *, const char *,
90164426Ssam				const char *, const char *);
91164426Ssamstatic void		ng_rewind(struct irs_ng *, const char *);
92164426Ssamstatic void		ng_minimize(struct irs_ng *);
93164426Ssam
94164426Ssamstatic void		add_group_to_list(struct pvt *, const char *, int);
95164426Ssamstatic void		add_tuple_to_list(struct pvt *, const char *, char *);
96164426Ssamstatic void		tmpfree(struct pvt *);
97164426Ssam
98164426Ssam/* Public */
99164426Ssam
100164426Ssamstruct irs_ng *
101164426Ssamirs_nis_ng(struct irs_acc *this) {
102164426Ssam	struct irs_ng *ng;
103164426Ssam	struct pvt *pvt;
104164426Ssam
105164426Ssam	if (!(ng = memget(sizeof *ng))) {
106164426Ssam		errno = ENOMEM;
107164426Ssam		return (NULL);
108164426Ssam	}
109164426Ssam	memset(ng, 0x5e, sizeof *ng);
110164426Ssam	if (!(pvt = memget(sizeof *pvt))) {
111164426Ssam		memput(ng, sizeof *ng);
112164426Ssam		errno = ENOMEM;
113164426Ssam		return (NULL);
114164426Ssam	}
115164426Ssam	memset(pvt, 0, sizeof *pvt);
116164426Ssam	pvt->nis_domain = ((struct nis_p *)this->private)->domain;
117164426Ssam	ng->private = pvt;
118164426Ssam	ng->close = ng_close;
119164426Ssam	ng->next = ng_next;
120164426Ssam	ng->test = ng_test;
121164426Ssam	ng->rewind = ng_rewind;
122164426Ssam	ng->minimize = ng_minimize;
123164426Ssam	return (ng);
124164426Ssam}
125164426Ssam
126164426Ssam/* Methods */
127164426Ssam
128164426Ssamstatic void
129164426Ssamng_close(struct irs_ng *this) {
130164426Ssam	struct pvt *pvt = (struct pvt *)this->private;
131164426Ssam
132164426Ssam	tmpfree(pvt);
133164426Ssam	memput(pvt, sizeof *pvt);
134164426Ssam	memput(this, sizeof *this);
135164426Ssam}
136164426Ssam
137164426Ssamstatic int
138164426Ssamng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) {
139164426Ssam	struct pvt *pvt = (struct pvt *)this->private;
140164426Ssam
141164426Ssam	if (!pvt->cur)
142164426Ssam		return (0);
143164426Ssam	*host = pvt->cur->host;
144164426Ssam	*user = pvt->cur->user;
145164426Ssam	*domain = pvt->cur->domain;
146164426Ssam	pvt->cur = pvt->cur->next;
147164426Ssam	return (1);
148164426Ssam}
149164426Ssam
150164426Ssamstatic int
151164426Ssamng_test(struct irs_ng *this, const char *name,
152164426Ssam	const char *host, const char *user, const char *domain)
153164426Ssam{
154164426Ssam	struct pvt *pvt = (struct pvt *)this->private;
155164426Ssam	struct tmpgrp *cur;
156164426Ssam
157164426Ssam	tmpfree(pvt);
158164426Ssam	add_group_to_list(pvt, name, strlen(name));
159164426Ssam	for (cur = pvt->tmp; cur; cur = cur->next) {
160164426Ssam		if ((!host || !cur->host || !strcmp(host, cur->host)) &&
161164426Ssam		    (!user || !cur->user || !strcmp(user, cur->user)) &&
162164426Ssam		    (!domain || !cur->domain || !strcmp(domain, cur->domain)))
163164426Ssam			break;
164164426Ssam	}
165164426Ssam	tmpfree(pvt);
166164426Ssam	return ((cur == NULL) ? 0 : 1);
167164426Ssam}
168164426Ssam
169164426Ssamstatic void
170164426Ssamng_rewind(struct irs_ng *this, const char *name) {
171164426Ssam	struct pvt *pvt = (struct pvt *)this->private;
172164426Ssam
173164426Ssam	/* Either hand back or free the existing list. */
174164426Ssam	if (pvt->tmpgroup) {
175164426Ssam		if (pvt->tmp && !strcmp(pvt->tmpgroup, name))
176164426Ssam			goto reset;
177164426Ssam		tmpfree(pvt);
178164426Ssam	}
179164426Ssam	pvt->tmpgroup = strdup(name);
180164426Ssam	add_group_to_list(pvt, name, strlen(name));
181164426Ssam reset:
182164426Ssam	pvt->cur = pvt->tmp;
183164426Ssam}
184164426Ssam
185164426Ssamstatic void
186164426Ssamng_minimize(struct irs_ng *this) {
187164426Ssam	UNUSED(this);
188164426Ssam	/* NOOP */
189164426Ssam}
190164426Ssam
191164426Ssam/* Private */
192164426Ssam
193164426Ssamstatic void
194164426Ssamadd_group_to_list(struct pvt *pvt, const char *name, int len) {
195164426Ssam	char *vdata, *cp, *np;
196164426Ssam	struct tmpgrp *tmp;
197164426Ssam	int vlen, r;
198164426Ssam	char *nametmp;
199164426Ssam
200164426Ssam	/* Don't add the same group to the list more than once. */
201164426Ssam	for (tmp = pvt->tmp; tmp; tmp = tmp->next)
202164426Ssam		if (!strcmp(tmp->name, name))
203164426Ssam			return;
204164426Ssam
205164426Ssam	DE_CONST(name, nametmp);
206164426Ssam	r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len,
207164426Ssam		     &vdata, &vlen);
208164426Ssam	if (r == 0) {
209164426Ssam		cp = vdata;
210164426Ssam		if (*cp && cp[strlen(cp)-1] == '\n')
211164426Ssam                  cp[strlen(cp)-1] = '\0';
212164426Ssam		for ( ; cp; cp = np) {
213164426Ssam			np = strchr(cp, ' ');
214164426Ssam			if (np)
215164426Ssam				*np++ = '\0';
216164426Ssam			if (*cp == '(')
217164426Ssam				add_tuple_to_list(pvt, name, cp);
218164426Ssam			else
219164426Ssam				add_group_to_list(pvt, cp, strlen(cp));
220164426Ssam		}
221164426Ssam		free(vdata);
222164426Ssam	}
223164426Ssam}
224164426Ssam
225164426Ssamstatic void
226164426Ssamadd_tuple_to_list(struct pvt *pvt, const char *name, char *cp) {
227164426Ssam	struct tmpgrp *tmp;
228164426Ssam	char *tp, *np;
229164426Ssam
230164426Ssam	INSIST(*cp++ == '(');
231164426Ssam
232164426Ssam	tmp = malloc(sizeof *tmp + strlen(name) + sizeof '\0' +
233164426Ssam		     strlen(cp) - sizeof ')');
234164426Ssam	if (!tmp)
235164426Ssam		return;
236164426Ssam	memset(tmp, 0, sizeof *tmp);
237164426Ssam	tp = ((char *)tmp) + sizeof *tmp;
238164426Ssam
239164426Ssam	/* Name */
240164426Ssam	strcpy(tp, name);
241164426Ssam	tmp->name = tp;
242164426Ssam	tp += strlen(tp) + 1;
243164426Ssam
244164426Ssam	/* Host */
245164426Ssam	if (!(np = strchr(cp, ',')))
246164426Ssam		goto cleanup;
247164426Ssam	*np++ = '\0';
248164426Ssam	strcpy(tp, cp);
249164426Ssam	tmp->host = tp;
250164426Ssam	tp += strlen(tp) + 1;
251164426Ssam	cp = np;
252164426Ssam
253164426Ssam	/* User */
254164426Ssam	if (!(np = strchr(cp, ',')))
255164426Ssam		goto cleanup;
256164426Ssam	*np++ = '\0';
257164426Ssam	strcpy(tp, cp);
258164426Ssam	tmp->user = tp;
259164426Ssam	tp += strlen(tp) + 1;
260164426Ssam	cp = np;
261164426Ssam
262164426Ssam	/* Domain */
263164426Ssam	if (!(np = strchr(cp, ')')))
264164426Ssam		goto cleanup;
265164426Ssam	*np++ = '\0';
266164426Ssam	strcpy(tp, cp);
267164426Ssam	tmp->domain = tp;
268164426Ssam
269164426Ssam	/*
270164426Ssam	 * Empty string in file means wildcard, but
271164426Ssam	 * NULL string in return value means wildcard.
272164426Ssam	 */
273164426Ssam	if (!*tmp->host)
274164426Ssam		tmp->host = NULL;
275164426Ssam	if (!*tmp->user)
276164426Ssam		tmp->user = NULL;
277164426Ssam	if (!*tmp->domain)
278164426Ssam		tmp->domain = NULL;
279164426Ssam
280164426Ssam	/* Add to list (LIFO). */
281164426Ssam	tmp->next = pvt->tmp;
282164426Ssam	pvt->tmp = tmp;
283164426Ssam	return;
284164426Ssam
285164426Ssam cleanup:
286164426Ssam	free(tmp);
287164426Ssam}
288164426Ssam
289164426Ssamstatic void
290164426Ssamtmpfree(struct pvt *pvt) {
291164426Ssam	struct tmpgrp *cur, *next;
292164426Ssam
293164426Ssam	if (pvt->tmpgroup) {
294164426Ssam		free(pvt->tmpgroup);
295164426Ssam		pvt->tmpgroup = NULL;
296164426Ssam	}
297164426Ssam	for (cur = pvt->tmp; cur; cur = next) {
298164426Ssam		next = cur->next;
299164426Ssam		free(cur);
300164426Ssam	}
301164426Ssam	pvt->tmp = NULL;
302164426Ssam}
303164426Ssam
304164426Ssam#endif /*WANT_IRS_NIS*/
305164426Ssam
306164426Ssam/*! \file */
307164426Ssam