netnamer.c revision 92889
1235783Skib/*
2235783Skib * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3235783Skib * unrestricted use provided that this legend is included on all tape
4235783Skib * media and as a part of the software program in whole or part.  Users
5235783Skib * may copy or modify Sun RPC without charge, but are not authorized
6235783Skib * to license or distribute it to anyone else except as part of a product or
7235783Skib * program developed by the user or with the express written consent of
8235783Skib * Sun Microsystems, Inc.
9235783Skib *
10235783Skib * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11235783Skib * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12235783Skib * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13235783Skib *
14235783Skib * Sun RPC is provided with no support and without any obligation on the
15235783Skib * part of Sun Microsystems, Inc. to assist in its use, correction,
16235783Skib * modification or enhancement.
17235783Skib *
18235783Skib * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19235783Skib * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20235783Skib * OR ANY PART THEREOF.
21235783Skib *
22235783Skib * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23235783Skib * or profits or other special, indirect and consequential damages, even if
24235783Skib * Sun has been advised of the possibility of such damages.
25235783Skib *
26235783Skib * Sun Microsystems, Inc.
27235783Skib * 2550 Garcia Avenue
28235783Skib * Mountain View, California  94043
29235783Skib *
30235783Skib * $FreeBSD: head/lib/libc/rpc/netnamer.c 92889 2002-03-21 18:49:23Z obrien $
31235783Skib */
32235783Skib#if !defined(lint) && defined(SCCSIDS)
33235783Skibstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
34235783Skib#endif
35235783Skib/*
36235783Skib * netname utility routines convert from unix names to network names and
37235783Skib * vice-versa This module is operating system dependent! What we define here
38235783Skib * will work with any unix system that has adopted the sun NIS domain
39235783Skib * architecture.
40235783Skib */
41235783Skib#include "namespace.h"
42235783Skib#include <sys/param.h>
43235783Skib#include <rpc/rpc.h>
44235783Skib#include <rpc/rpc_com.h>
45235783Skib#ifdef YP
46235783Skib#include <rpcsvc/yp_prot.h>
47235783Skib#include <rpcsvc/ypclnt.h>
48235783Skib#endif
49235783Skib#include <ctype.h>
50235783Skib#include <stdio.h>
51235783Skib#include <grp.h>
52235783Skib#include <pwd.h>
53235783Skib#include <string.h>
54235783Skib#include <stdlib.h>
55235783Skib#include <unistd.h>
56235783Skib#include "un-namespace.h"
57235783Skib
58235783Skibstatic char    *OPSYS = "unix";
59235783Skibstatic char    *NETID = "netid.byname";
60235783Skibstatic char    *NETIDFILE = "/etc/netid";
61235783Skib
62235783Skibstatic int getnetid __P(( char *, char * ));
63235783Skibstatic int _getgroups __P(( char *, gid_t * ));
64235783Skib
65235783Skib#ifndef NGROUPS
66235783Skib#define NGROUPS 16
67235783Skib#endif
68235783Skib
69235783Skib/*
70235783Skib * Convert network-name into unix credential
71235783Skib */
72235783Skibint
73235783Skibnetname2user(netname, uidp, gidp, gidlenp, gidlist)
74235783Skib	char            netname[MAXNETNAMELEN + 1];
75235783Skib	uid_t            *uidp;
76235783Skib	gid_t            *gidp;
77235783Skib	int            *gidlenp;
78235783Skib	gid_t	       *gidlist;
79235783Skib{
80235783Skib	char           *p;
81235783Skib	int             gidlen;
82235783Skib	uid_t           uid;
83235783Skib	long		luid;
84235783Skib	struct passwd  *pwd;
85235783Skib	char            val[1024];
86235783Skib	char           *val1, *val2;
87235783Skib	char           *domain;
88235783Skib	int             vallen;
89235783Skib	int             err;
90235783Skib
91235783Skib	if (getnetid(netname, val)) {
92235783Skib		char *res = val;
93235783Skib
94235783Skib		p = strsep(&res, ":");
95235783Skib		if (p == NULL)
96235783Skib			return (0);
97235783Skib		*uidp = (uid_t) atol(p);
98235783Skib		p = strsep(&res, "\n,");
99235783Skib		if (p == NULL) {
100235783Skib			return (0);
101235783Skib		}
102235783Skib		*gidp = (gid_t) atol(p);
103235783Skib		gidlen = 0;
104235783Skib		for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
105235783Skib			p = strsep(&res, "\n,");
106235783Skib			if (p == NULL)
107235783Skib				break;
108235783Skib			gidlist[gidlen] = (gid_t) atol(p);
109235783Skib		}
110235783Skib		*gidlenp = gidlen;
111235783Skib
112235783Skib		return (1);
113235783Skib	}
114235783Skib	val1 = strchr(netname, '.');
115235783Skib	if (val1 == NULL)
116235783Skib		return (0);
117235783Skib	if (strncmp(netname, OPSYS, (val1-netname)))
118235783Skib		return (0);
119235783Skib	val1++;
120235783Skib	val2 = strchr(val1, '@');
121235783Skib	if (val2 == NULL)
122235783Skib		return (0);
123235783Skib	vallen = val2 - val1;
124235783Skib	if (vallen > (1024 - 1))
125235783Skib		vallen = 1024 - 1;
126235783Skib	(void) strncpy(val, val1, 1024);
127235783Skib	val[vallen] = 0;
128235783Skib
129235783Skib	err = __rpc_get_default_domain(&domain);	/* change to rpc */
130235783Skib	if (err)
131235783Skib		return (0);
132235783Skib
133235783Skib	if (strcmp(val2 + 1, domain))
134235783Skib		return (0);	/* wrong domain */
135235783Skib
136235783Skib	if (sscanf(val, "%ld", &luid) != 1)
137235783Skib		return (0);
138235783Skib	uid = luid;
139235783Skib
140235783Skib	/* use initgroups method */
141235783Skib	pwd = getpwuid(uid);
142235783Skib	if (pwd == NULL)
143235783Skib		return (0);
144235783Skib	*uidp = pwd->pw_uid;
145235783Skib	*gidp = pwd->pw_gid;
146235783Skib	*gidlenp = _getgroups(pwd->pw_name, gidlist);
147235783Skib	return (1);
148235783Skib}
149235783Skib
150235783Skib/*
151235783Skib * initgroups
152235783Skib */
153235783Skib
154235783Skibstatic int
155235783Skib_getgroups(uname, groups)
156235783Skib	char           *uname;
157235783Skib	gid_t          groups[NGROUPS];
158235783Skib{
159235783Skib	gid_t           ngroups = 0;
160235783Skib	struct group *grp;
161235783Skib	int    i;
162235783Skib	int    j;
163235783Skib	int             filter;
164235783Skib
165235783Skib	setgrent();
166235783Skib	while ((grp = getgrent())) {
167235783Skib		for (i = 0; grp->gr_mem[i]; i++)
168235783Skib			if (!strcmp(grp->gr_mem[i], uname)) {
169235783Skib				if (ngroups == NGROUPS) {
170235783Skib#ifdef DEBUG
171235783Skib					fprintf(stderr,
172235783Skib				"initgroups: %s is in too many groups\n", uname);
173235783Skib#endif
174235783Skib					goto toomany;
175235783Skib				}
176235783Skib				/* filter out duplicate group entries */
177235783Skib				filter = 0;
178280369Skib				for (j = 0; j < ngroups; j++)
179280369Skib					if (groups[j] == grp->gr_gid) {
180280369Skib						filter++;
181280369Skib						break;
182280369Skib					}
183280369Skib				if (!filter)
184280369Skib					groups[ngroups++] = grp->gr_gid;
185280369Skib			}
186280369Skib	}
187280369Skibtoomany:
188280369Skib	endgrent();
189280369Skib	return (ngroups);
190280369Skib}
191280369Skib
192280369Skib/*
193280369Skib * Convert network-name to hostname
194280369Skib */
195280369Skibint
196280369Skibnetname2host(netname, hostname, hostlen)
197280369Skib	char            netname[MAXNETNAMELEN + 1];
198280369Skib	char           *hostname;
199280369Skib	int             hostlen;
200235783Skib{
201235783Skib	int             err;
202235783Skib	char            valbuf[1024];
203235783Skib	char           *val;
204235783Skib	char           *val2;
205235783Skib	int             vallen;
206235783Skib	char           *domain;
207235783Skib
208235783Skib	if (getnetid(netname, valbuf)) {
209280369Skib		val = valbuf;
210235783Skib		if ((*val == '0') && (val[1] == ':')) {
211235783Skib			(void) strncpy(hostname, val + 2, hostlen);
212235783Skib			return (1);
213235783Skib		}
214235783Skib	}
215235783Skib	val = strchr(netname, '.');
216235783Skib	if (val == NULL)
217235783Skib		return (0);
218235783Skib	if (strncmp(netname, OPSYS, (val - netname)))
219235783Skib		return (0);
220235783Skib	val++;
221235783Skib	val2 = strchr(val, '@');
222235783Skib	if (val2 == NULL)
223235783Skib		return (0);
224235783Skib	vallen = val2 - val;
225235783Skib	if (vallen > (hostlen - 1))
226235783Skib		vallen = hostlen - 1;
227235783Skib	(void) strncpy(hostname, val, vallen);
228235783Skib	hostname[vallen] = 0;
229235783Skib
230235783Skib	err = __rpc_get_default_domain(&domain);	/* change to rpc */
231235783Skib	if (err)
232235783Skib		return (0);
233235783Skib
234235783Skib	if (strcmp(val2 + 1, domain))
235235783Skib		return (0);	/* wrong domain */
236235783Skib	else
237235783Skib		return (1);
238235783Skib}
239235783Skib
240235783Skib/*
241235783Skib * reads the file /etc/netid looking for a + to optionally go to the
242235783Skib * network information service.
243235783Skib */
244235783Skibint
245235783Skibgetnetid(key, ret)
246235783Skib	char           *key, *ret;
247235783Skib{
248235783Skib	char            buf[1024];	/* big enough */
249235783Skib	char           *res;
250235783Skib	char           *mkey;
251235783Skib	char           *mval;
252235783Skib	FILE           *fd;
253235783Skib#ifdef YP
254235783Skib	char           *domain;
255235783Skib	int             err;
256235783Skib	char           *lookup;
257235783Skib	int             len;
258235783Skib#endif
259235783Skib
260235783Skib	fd = fopen(NETIDFILE, "r");
261235783Skib	if (fd == NULL) {
262235783Skib#ifdef YP
263235783Skib		res = "+";
264235783Skib		goto getnetidyp;
265235783Skib#else
266235783Skib		return (0);
267235783Skib#endif
268235783Skib	}
269235783Skib	for (;;) {
270280369Skib		if (fd == NULL)
271280369Skib			return (0);	/* getnetidyp brings us here */
272280369Skib		res = fgets(buf, sizeof(buf), fd);
273280369Skib		if (res == NULL) {
274280369Skib			fclose(fd);
275280369Skib			return (0);
276280369Skib		}
277280369Skib		if (res[0] == '#')
278280369Skib			continue;
279280369Skib		else if (res[0] == '+') {
280280369Skib#ifdef YP
281280369Skib	getnetidyp:
282280369Skib			err = yp_get_default_domain(&domain);
283235783Skib			if (err) {
284235783Skib				continue;
285235783Skib			}
286235783Skib			lookup = NULL;
287235783Skib			err = yp_match(domain, NETID, key,
288235783Skib				strlen(key), &lookup, &len);
289235783Skib			if (err) {
290235783Skib#ifdef DEBUG
291235783Skib				fprintf(stderr, "match failed error %d\n", err);
292235783Skib#endif
293235783Skib				continue;
294235783Skib			}
295280369Skib			lookup[len] = 0;
296280369Skib			strcpy(ret, lookup);
297280369Skib			free(lookup);
298280369Skib			if (fd != NULL)
299280369Skib				fclose(fd);
300235783Skib			return (2);
301235783Skib#else	/* YP */
302235783Skib#ifdef DEBUG
303235783Skib			fprintf(stderr,
304235783Skib"Bad record in %s '+' -- NIS not supported in this library copy\n",
305235783Skib				NETIDFILE);
306235783Skib#endif
307235783Skib			continue;
308235783Skib#endif	/* YP */
309235783Skib		} else {
310235783Skib			mkey = strsep(&res, "\t ");
311235783Skib			if (mkey == NULL) {
312235783Skib				fprintf(stderr,
313235783Skib		"Bad record in %s -- %s", NETIDFILE, buf);
314235783Skib				continue;
315235783Skib			}
316235783Skib			do {
317235783Skib				mval = strsep(&res, " \t#\n");
318235783Skib			} while (mval != NULL && !*mval);
319235783Skib			if (mval == NULL) {
320235783Skib				fprintf(stderr,
321235783Skib		"Bad record in %s val problem - %s", NETIDFILE, buf);
322235783Skib				continue;
323235783Skib			}
324235783Skib			if (strcmp(mkey, key) == 0) {
325235783Skib				strcpy(ret, mval);
326235783Skib				fclose(fd);
327235783Skib				return (1);
328235783Skib
329235783Skib			}
330235783Skib		}
331235783Skib	}
332235783Skib}
333235783Skib