netnamer.c revision 261046
1133808Spjd/*-
2133808Spjd * Copyright (c) 2009, Sun Microsystems, Inc.
3133808Spjd * All rights reserved.
4133808Spjd *
5133808Spjd * Redistribution and use in source and binary forms, with or without
6133808Spjd * modification, are permitted provided that the following conditions are met:
7133808Spjd * - Redistributions of source code must retain the above copyright notice,
8133808Spjd *   this list of conditions and the following disclaimer.
9133808Spjd * - Redistributions in binary form must reproduce the above copyright notice,
10133808Spjd *   this list of conditions and the following disclaimer in the documentation
11133808Spjd *   and/or other materials provided with the distribution.
12133808Spjd * - Neither the name of Sun Microsystems, Inc. nor the names of its
13133808Spjd *   contributors may be used to endorse or promote products derived
14133808Spjd *   from this software without specific prior written permission.
15133808Spjd *
16133808Spjd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17133808Spjd * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18133808Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19133808Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20133808Spjd * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21133808Spjd * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22133808Spjd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23133808Spjd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24133808Spjd * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25133808Spjd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26133808Spjd * POSSIBILITY OF SUCH DAMAGE.
27133808Spjd */
28133808Spjd
29133808Spjd#if defined(LIBC_SCCS) && !defined(lint)
30133808Spjdstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
31133808Spjd#endif
32133808Spjd#include <sys/cdefs.h>
33133808Spjd__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/netnamer.c 261046 2014-01-22 23:45:27Z mav $");
34133808Spjd
35133808Spjd/*
36133808Spjd * netname utility routines convert from unix names to network names and
37133808Spjd * vice-versa This module is operating system dependent! What we define here
38133808Spjd * will work with any unix system that has adopted the sun NIS domain
39133808Spjd * architecture.
40133808Spjd */
41133808Spjd#include "namespace.h"
42133808Spjd#include <sys/param.h>
43133808Spjd#include <rpc/rpc.h>
44133808Spjd#include <rpc/rpc_com.h>
45133808Spjd#ifdef YP
46133808Spjd#include <rpcsvc/yp_prot.h>
47133808Spjd#include <rpcsvc/ypclnt.h>
48133808Spjd#endif
49133808Spjd#include <ctype.h>
50133808Spjd#include <stdio.h>
51133808Spjd#include <grp.h>
52133808Spjd#include <pwd.h>
53133808Spjd#include <string.h>
54133808Spjd#include <stdlib.h>
55133808Spjd#include <unistd.h>
56133808Spjd#include "un-namespace.h"
57133808Spjd
58133808Spjdstatic char    *OPSYS = "unix";
59133808Spjd#ifdef YP
60133808Spjdstatic char    *NETID = "netid.byname";
61133808Spjd#endif
62133808Spjdstatic char    *NETIDFILE = "/etc/netid";
63133808Spjd
64133808Spjdstatic int getnetid( char *, char * );
65133808Spjdstatic int _getgroups( char *, gid_t * );
66133808Spjd
67133808Spjd/*
68133808Spjd * Convert network-name into unix credential
69133808Spjd */
70133808Spjdint
71133808Spjdnetname2user(netname, uidp, gidp, gidlenp, gidlist)
72133808Spjd	char            netname[MAXNETNAMELEN + 1];
73133808Spjd	uid_t            *uidp;
74133808Spjd	gid_t            *gidp;
75133808Spjd	int            *gidlenp;
76133808Spjd	gid_t	       *gidlist;
77133808Spjd{
78133808Spjd	char           *p;
79133808Spjd	int             gidlen;
80133808Spjd	uid_t           uid;
81133808Spjd	long		luid;
82133808Spjd	struct passwd  *pwd;
83133808Spjd	char            val[1024];
84133808Spjd	char           *val1, *val2;
85133808Spjd	char           *domain;
86133808Spjd	int             vallen;
87133808Spjd	int             err;
88133808Spjd
89133808Spjd	if (getnetid(netname, val)) {
90133808Spjd		char *res = val;
91133808Spjd
92133808Spjd		p = strsep(&res, ":");
93133808Spjd		if (p == NULL)
94133808Spjd			return (0);
95133808Spjd		*uidp = (uid_t) atol(p);
96134124Spjd		p = strsep(&res, "\n,");
97134168Spjd		if (p == NULL) {
98134168Spjd			return (0);
99134168Spjd		}
100133808Spjd		*gidp = (gid_t) atol(p);
101133808Spjd		for (gidlen = 0; gidlen < NGRPS; gidlen++) {
102133808Spjd			p = strsep(&res, "\n,");
103133808Spjd			if (p == NULL)
104133808Spjd				break;
105133808Spjd			gidlist[gidlen] = (gid_t) atol(p);
106133808Spjd		}
107133808Spjd		*gidlenp = gidlen;
108133808Spjd
109133808Spjd		return (1);
110133808Spjd	}
111133808Spjd	val1 = strchr(netname, '.');
112133808Spjd	if (val1 == NULL)
113133808Spjd		return (0);
114133808Spjd	if (strncmp(netname, OPSYS, (val1-netname)))
115133808Spjd		return (0);
116133808Spjd	val1++;
117133808Spjd	val2 = strchr(val1, '@');
118133808Spjd	if (val2 == NULL)
119133808Spjd		return (0);
120133808Spjd	vallen = val2 - val1;
121133808Spjd	if (vallen > (1024 - 1))
122133808Spjd		vallen = 1024 - 1;
123133808Spjd	(void) strncpy(val, val1, 1024);
124133808Spjd	val[vallen] = 0;
125133808Spjd
126133808Spjd	err = __rpc_get_default_domain(&domain);	/* change to rpc */
127133808Spjd	if (err)
128133808Spjd		return (0);
129133808Spjd
130133808Spjd	if (strcmp(val2 + 1, domain))
131133808Spjd		return (0);	/* wrong domain */
132133808Spjd
133134124Spjd	if (sscanf(val, "%ld", &luid) != 1)
134134124Spjd		return (0);
135134124Spjd	uid = luid;
136134124Spjd
137134124Spjd	/* use initgroups method */
138134124Spjd	pwd = getpwuid(uid);
139134124Spjd	if (pwd == NULL)
140134124Spjd		return (0);
141134124Spjd	*uidp = pwd->pw_uid;
142134124Spjd	*gidp = pwd->pw_gid;
143134124Spjd	*gidlenp = _getgroups(pwd->pw_name, gidlist);
144134124Spjd	return (1);
145134124Spjd}
146134124Spjd
147134124Spjd/*
148134124Spjd * initgroups
149134168Spjd */
150134168Spjd
151134168Spjdstatic int
152134168Spjd_getgroups(uname, groups)
153134168Spjd	char           *uname;
154134168Spjd	gid_t          groups[NGRPS];
155134168Spjd{
156134168Spjd	gid_t           ngroups = 0;
157134168Spjd	struct group *grp;
158134168Spjd	int    i;
159134168Spjd	int    j;
160134168Spjd	int             filter;
161134168Spjd
162134168Spjd	setgrent();
163134168Spjd	while ((grp = getgrent())) {
164134168Spjd		for (i = 0; grp->gr_mem[i]; i++)
165134168Spjd			if (!strcmp(grp->gr_mem[i], uname)) {
166134124Spjd				if (ngroups == NGRPS) {
167134124Spjd#ifdef DEBUG
168134124Spjd					fprintf(stderr,
169133808Spjd				"initgroups: %s is in too many groups\n", uname);
170133808Spjd#endif
171133808Spjd					goto toomany;
172133808Spjd				}
173133808Spjd				/* filter out duplicate group entries */
174133808Spjd				filter = 0;
175133808Spjd				for (j = 0; j < ngroups; j++)
176133808Spjd					if (groups[j] == grp->gr_gid) {
177133808Spjd						filter++;
178134168Spjd						break;
179134168Spjd					}
180134168Spjd				if (!filter)
181134168Spjd					groups[ngroups++] = grp->gr_gid;
182134168Spjd			}
183134168Spjd	}
184134168Spjdtoomany:
185134124Spjd	endgrent();
186134124Spjd	return (ngroups);
187134124Spjd}
188134124Spjd
189134124Spjd/*
190134124Spjd * Convert network-name to hostname
191134124Spjd */
192134168Spjdint
193134168Spjdnetname2host(netname, hostname, hostlen)
194134168Spjd	char            netname[MAXNETNAMELEN + 1];
195134168Spjd	char           *hostname;
196134168Spjd	int             hostlen;
197134168Spjd{
198134168Spjd	int             err;
199133808Spjd	char            valbuf[1024];
200133808Spjd	char           *val;
201133808Spjd	char           *val2;
202133808Spjd	int             vallen;
203133808Spjd	char           *domain;
204133808Spjd
205133808Spjd	if (getnetid(netname, valbuf)) {
206133808Spjd		val = valbuf;
207133808Spjd		if ((*val == '0') && (val[1] == ':')) {
208133808Spjd			(void) strncpy(hostname, val + 2, hostlen);
209133808Spjd			return (1);
210133808Spjd		}
211133808Spjd	}
212133808Spjd	val = strchr(netname, '.');
213133808Spjd	if (val == NULL)
214133808Spjd		return (0);
215133808Spjd	if (strncmp(netname, OPSYS, (val - netname)))
216133808Spjd		return (0);
217133808Spjd	val++;
218133808Spjd	val2 = strchr(val, '@');
219133808Spjd	if (val2 == NULL)
220133808Spjd		return (0);
221133808Spjd	vallen = val2 - val;
222133808Spjd	if (vallen > (hostlen - 1))
223133808Spjd		vallen = hostlen - 1;
224133808Spjd	(void) strncpy(hostname, val, vallen);
225133808Spjd	hostname[vallen] = 0;
226133808Spjd
227133808Spjd	err = __rpc_get_default_domain(&domain);	/* change to rpc */
228133808Spjd	if (err)
229133808Spjd		return (0);
230133808Spjd
231133808Spjd	if (strcmp(val2 + 1, domain))
232133808Spjd		return (0);	/* wrong domain */
233133808Spjd	else
234133808Spjd		return (1);
235133808Spjd}
236133808Spjd
237133808Spjd/*
238133808Spjd * reads the file /etc/netid looking for a + to optionally go to the
239133808Spjd * network information service.
240133808Spjd */
241133808Spjdint
242133808Spjdgetnetid(key, ret)
243133808Spjd	char           *key, *ret;
244133808Spjd{
245133808Spjd	char            buf[1024];	/* big enough */
246133808Spjd	char           *res;
247133808Spjd	char           *mkey;
248133808Spjd	char           *mval;
249133808Spjd	FILE           *fd;
250133808Spjd#ifdef YP
251133808Spjd	char           *domain;
252133808Spjd	int             err;
253133808Spjd	char           *lookup;
254133808Spjd	int             len;
255133808Spjd#endif
256133808Spjd
257133808Spjd	fd = fopen(NETIDFILE, "r");
258133808Spjd	if (fd == NULL) {
259133808Spjd#ifdef YP
260133808Spjd		res = "+";
261133808Spjd		goto getnetidyp;
262133808Spjd#else
263133808Spjd		return (0);
264133808Spjd#endif
265133808Spjd	}
266133808Spjd	for (;;) {
267133808Spjd		if (fd == NULL)
268133808Spjd			return (0);	/* getnetidyp brings us here */
269133808Spjd		res = fgets(buf, sizeof(buf), fd);
270133808Spjd		if (res == NULL) {
271133808Spjd			fclose(fd);
272133808Spjd			return (0);
273133808Spjd		}
274133808Spjd		if (res[0] == '#')
275133808Spjd			continue;
276133808Spjd		else if (res[0] == '+') {
277133808Spjd#ifdef YP
278133808Spjd	getnetidyp:
279133808Spjd			err = yp_get_default_domain(&domain);
280133808Spjd			if (err) {
281133808Spjd				continue;
282133808Spjd			}
283133808Spjd			lookup = NULL;
284133808Spjd			err = yp_match(domain, NETID, key,
285133808Spjd				strlen(key), &lookup, &len);
286133808Spjd			if (err) {
287133808Spjd#ifdef DEBUG
288133808Spjd				fprintf(stderr, "match failed error %d\n", err);
289133808Spjd#endif
290133808Spjd				continue;
291133808Spjd			}
292133808Spjd			lookup[len] = 0;
293133808Spjd			strcpy(ret, lookup);
294133808Spjd			free(lookup);
295133808Spjd			if (fd != NULL)
296133808Spjd				fclose(fd);
297133808Spjd			return (2);
298133808Spjd#else	/* YP */
299133808Spjd#ifdef DEBUG
300133808Spjd			fprintf(stderr,
301133808Spjd"Bad record in %s '+' -- NIS not supported in this library copy\n",
302133808Spjd				NETIDFILE);
303133808Spjd#endif
304133808Spjd			continue;
305133808Spjd#endif	/* YP */
306133808Spjd		} else {
307133808Spjd			mkey = strsep(&res, "\t ");
308133808Spjd			if (mkey == NULL) {
309133808Spjd				fprintf(stderr,
310133808Spjd		"Bad record in %s -- %s", NETIDFILE, buf);
311133808Spjd				continue;
312133808Spjd			}
313133808Spjd			do {
314133808Spjd				mval = strsep(&res, " \t#\n");
315133808Spjd			} while (mval != NULL && !*mval);
316133808Spjd			if (mval == NULL) {
317133808Spjd				fprintf(stderr,
318133808Spjd		"Bad record in %s val problem - %s", NETIDFILE, buf);
319133808Spjd				continue;
320133808Spjd			}
321133808Spjd			if (strcmp(mkey, key) == 0) {
322133808Spjd				strcpy(ret, mval);
323133808Spjd				fclose(fd);
324133808Spjd				return (1);
325133808Spjd
326133808Spjd			}
327133808Spjd		}
328133808Spjd	}
329133808Spjd}
330133808Spjd