xref: /freebsd/lib/libc/rpc/netnamer.c (revision dc36d6f9bb1753f3808552f3afd30eda9a7b206a)
12e322d37SHiroki Sato /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
42e322d37SHiroki Sato  * Copyright (c) 2009, Sun Microsystems, Inc.
52e322d37SHiroki Sato  * All rights reserved.
6e8636dfdSBill Paul  *
72e322d37SHiroki Sato  * Redistribution and use in source and binary forms, with or without
82e322d37SHiroki Sato  * modification, are permitted provided that the following conditions are met:
92e322d37SHiroki Sato  * - Redistributions of source code must retain the above copyright notice,
102e322d37SHiroki Sato  *   this list of conditions and the following disclaimer.
112e322d37SHiroki Sato  * - Redistributions in binary form must reproduce the above copyright notice,
122e322d37SHiroki Sato  *   this list of conditions and the following disclaimer in the documentation
132e322d37SHiroki Sato  *   and/or other materials provided with the distribution.
142e322d37SHiroki Sato  * - Neither the name of Sun Microsystems, Inc. nor the names of its
152e322d37SHiroki Sato  *   contributors may be used to endorse or promote products derived
162e322d37SHiroki Sato  *   from this software without specific prior written permission.
17e8636dfdSBill Paul  *
182e322d37SHiroki Sato  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
192e322d37SHiroki Sato  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
202e322d37SHiroki Sato  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
212e322d37SHiroki Sato  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
222e322d37SHiroki Sato  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
232e322d37SHiroki Sato  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
242e322d37SHiroki Sato  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
252e322d37SHiroki Sato  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
262e322d37SHiroki Sato  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
272e322d37SHiroki Sato  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
282e322d37SHiroki Sato  * POSSIBILITY OF SUCH DAMAGE.
29e8636dfdSBill Paul  */
30a986ef57SDavid E. O'Brien 
31e8636dfdSBill Paul /*
32e8636dfdSBill Paul  * netname utility routines convert from unix names to network names and
33e8636dfdSBill Paul  * vice-versa This module is operating system dependent! What we define here
34e8636dfdSBill Paul  * will work with any unix system that has adopted the sun NIS domain
35e8636dfdSBill Paul  * architecture.
36e8636dfdSBill Paul  */
378360efbdSAlfred Perlstein #include "namespace.h"
38e8636dfdSBill Paul #include <sys/param.h>
39e8636dfdSBill Paul #include <rpc/rpc.h>
40e8636dfdSBill Paul #include <rpc/rpc_com.h>
41e8636dfdSBill Paul #ifdef YP
42e8636dfdSBill Paul #include <rpcsvc/yp_prot.h>
43e8636dfdSBill Paul #include <rpcsvc/ypclnt.h>
44e8636dfdSBill Paul #endif
45e8636dfdSBill Paul #include <ctype.h>
46e8636dfdSBill Paul #include <stdio.h>
47e8636dfdSBill Paul #include <grp.h>
48e8636dfdSBill Paul #include <pwd.h>
49e8636dfdSBill Paul #include <string.h>
50e8636dfdSBill Paul #include <stdlib.h>
51e8636dfdSBill Paul #include <unistd.h>
528360efbdSAlfred Perlstein #include "un-namespace.h"
53e8636dfdSBill Paul 
54e8636dfdSBill Paul static char    *OPSYS = "unix";
556c58990dSBjoern A. Zeeb #ifdef YP
56e8636dfdSBill Paul static char    *NETID = "netid.byname";
576c58990dSBjoern A. Zeeb #endif
58e8636dfdSBill Paul static char    *NETIDFILE = "/etc/netid";
59e8636dfdSBill Paul 
60c05ac53bSDavid E. O'Brien static int getnetid( char *, char * );
61*a2e41a58SJohn Baldwin static int _getgroups( char *, gid_t [NGRPS] );
62e8636dfdSBill Paul 
63e8636dfdSBill Paul /*
64e8636dfdSBill Paul  * Convert network-name into unix credential
65e8636dfdSBill Paul  */
66e8636dfdSBill Paul int
netname2user(char netname[MAXNETNAMELEN+1],uid_t * uidp,gid_t * gidp,int * gidlenp,gid_t * gidlist)67587cf682SCraig Rodrigues netname2user(char netname[MAXNETNAMELEN + 1], uid_t *uidp, gid_t *gidp,
68587cf682SCraig Rodrigues     int *gidlenp, gid_t *gidlist)
69e8636dfdSBill Paul {
70e8636dfdSBill Paul 	char           *p;
71e8636dfdSBill Paul 	int             gidlen;
72e8636dfdSBill Paul 	uid_t           uid;
732a29b52bSBruce Evans 	long		luid;
74e8636dfdSBill Paul 	struct passwd  *pwd;
75e8636dfdSBill Paul 	char            val[1024];
76e8636dfdSBill Paul 	char           *val1, *val2;
77e8636dfdSBill Paul 	char           *domain;
78e8636dfdSBill Paul 	int             vallen;
79e8636dfdSBill Paul 	int             err;
80e8636dfdSBill Paul 
81e8636dfdSBill Paul 	if (getnetid(netname, val)) {
8267ab6e98SAndrey A. Chernov 		char *res = val;
8367ab6e98SAndrey A. Chernov 
8467ab6e98SAndrey A. Chernov 		p = strsep(&res, ":");
85e8636dfdSBill Paul 		if (p == NULL)
86e8636dfdSBill Paul 			return (0);
8767ab6e98SAndrey A. Chernov 		*uidp = (uid_t) atol(p);
8867ab6e98SAndrey A. Chernov 		p = strsep(&res, "\n,");
89e8636dfdSBill Paul 		if (p == NULL) {
90e8636dfdSBill Paul 			return (0);
91e8636dfdSBill Paul 		}
9267ab6e98SAndrey A. Chernov 		*gidp = (gid_t) atol(p);
93838d9858SBrooks Davis 		for (gidlen = 0; gidlen < NGRPS; gidlen++) {
9467ab6e98SAndrey A. Chernov 			p = strsep(&res, "\n,");
95e8636dfdSBill Paul 			if (p == NULL)
96e8636dfdSBill Paul 				break;
97e8636dfdSBill Paul 			gidlist[gidlen] = (gid_t) atol(p);
98e8636dfdSBill Paul 		}
99e8636dfdSBill Paul 		*gidlenp = gidlen;
100e8636dfdSBill Paul 
101e8636dfdSBill Paul 		return (1);
102e8636dfdSBill Paul 	}
103e8636dfdSBill Paul 	val1 = strchr(netname, '.');
104e8636dfdSBill Paul 	if (val1 == NULL)
105e8636dfdSBill Paul 		return (0);
106e8636dfdSBill Paul 	if (strncmp(netname, OPSYS, (val1-netname)))
107e8636dfdSBill Paul 		return (0);
108e8636dfdSBill Paul 	val1++;
109e8636dfdSBill Paul 	val2 = strchr(val1, '@');
110e8636dfdSBill Paul 	if (val2 == NULL)
111e8636dfdSBill Paul 		return (0);
112e8636dfdSBill Paul 	vallen = val2 - val1;
113e8636dfdSBill Paul 	if (vallen > (1024 - 1))
114e8636dfdSBill Paul 		vallen = 1024 - 1;
115e8636dfdSBill Paul 	(void) strncpy(val, val1, 1024);
116e8636dfdSBill Paul 	val[vallen] = 0;
117e8636dfdSBill Paul 
1188d630135SAlfred Perlstein 	err = __rpc_get_default_domain(&domain);	/* change to rpc */
119e8636dfdSBill Paul 	if (err)
120e8636dfdSBill Paul 		return (0);
121e8636dfdSBill Paul 
122e8636dfdSBill Paul 	if (strcmp(val2 + 1, domain))
123e8636dfdSBill Paul 		return (0);	/* wrong domain */
124e8636dfdSBill Paul 
1252a29b52bSBruce Evans 	if (sscanf(val, "%ld", &luid) != 1)
126e8636dfdSBill Paul 		return (0);
1272a29b52bSBruce Evans 	uid = luid;
1282a29b52bSBruce Evans 
129e8636dfdSBill Paul 	/* use initgroups method */
130e8636dfdSBill Paul 	pwd = getpwuid(uid);
131e8636dfdSBill Paul 	if (pwd == NULL)
132e8636dfdSBill Paul 		return (0);
133e8636dfdSBill Paul 	*uidp = pwd->pw_uid;
134e8636dfdSBill Paul 	*gidp = pwd->pw_gid;
135e8636dfdSBill Paul 	*gidlenp = _getgroups(pwd->pw_name, gidlist);
136e8636dfdSBill Paul 	return (1);
137e8636dfdSBill Paul }
138e8636dfdSBill Paul 
139e8636dfdSBill Paul /*
140e8636dfdSBill Paul  * initgroups
141e8636dfdSBill Paul  */
142e8636dfdSBill Paul 
143e8636dfdSBill Paul static int
_getgroups(char * uname,gid_t groups[NGRPS])144587cf682SCraig Rodrigues _getgroups(char *uname, gid_t groups[NGRPS])
145e8636dfdSBill Paul {
146e8636dfdSBill Paul 	gid_t           ngroups = 0;
1478fb3f3f6SDavid E. O'Brien 	struct group *grp;
1488fb3f3f6SDavid E. O'Brien 	int    i;
1498fb3f3f6SDavid E. O'Brien 	int    j;
150e8636dfdSBill Paul 	int             filter;
151e8636dfdSBill Paul 
152e8636dfdSBill Paul 	setgrent();
153e8636dfdSBill Paul 	while ((grp = getgrent())) {
154e8636dfdSBill Paul 		for (i = 0; grp->gr_mem[i]; i++)
155e8636dfdSBill Paul 			if (!strcmp(grp->gr_mem[i], uname)) {
156838d9858SBrooks Davis 				if (ngroups == NGRPS) {
157e8636dfdSBill Paul #ifdef DEBUG
158e8636dfdSBill Paul 					fprintf(stderr,
159e8636dfdSBill Paul 				"initgroups: %s is in too many groups\n", uname);
160e8636dfdSBill Paul #endif
161e8636dfdSBill Paul 					goto toomany;
162e8636dfdSBill Paul 				}
163e8636dfdSBill Paul 				/* filter out duplicate group entries */
164e8636dfdSBill Paul 				filter = 0;
165e8636dfdSBill Paul 				for (j = 0; j < ngroups; j++)
166e8636dfdSBill Paul 					if (groups[j] == grp->gr_gid) {
167e8636dfdSBill Paul 						filter++;
168e8636dfdSBill Paul 						break;
169e8636dfdSBill Paul 					}
170e8636dfdSBill Paul 				if (!filter)
171e8636dfdSBill Paul 					groups[ngroups++] = grp->gr_gid;
172e8636dfdSBill Paul 			}
173e8636dfdSBill Paul 	}
174e8636dfdSBill Paul toomany:
175e8636dfdSBill Paul 	endgrent();
176e8636dfdSBill Paul 	return (ngroups);
177e8636dfdSBill Paul }
178e8636dfdSBill Paul 
179e8636dfdSBill Paul /*
180e8636dfdSBill Paul  * Convert network-name to hostname
181e8636dfdSBill Paul  */
182e8636dfdSBill Paul int
netname2host(char netname[MAXNETNAMELEN+1],char * hostname,int hostlen)183587cf682SCraig Rodrigues netname2host(char netname[MAXNETNAMELEN + 1], char *hostname, int hostlen)
184e8636dfdSBill Paul {
185e8636dfdSBill Paul 	int             err;
186e8636dfdSBill Paul 	char            valbuf[1024];
187e8636dfdSBill Paul 	char           *val;
188e8636dfdSBill Paul 	char           *val2;
189e8636dfdSBill Paul 	int             vallen;
190e8636dfdSBill Paul 	char           *domain;
191e8636dfdSBill Paul 
192e8636dfdSBill Paul 	if (getnetid(netname, valbuf)) {
193e8636dfdSBill Paul 		val = valbuf;
194e8636dfdSBill Paul 		if ((*val == '0') && (val[1] == ':')) {
195e8636dfdSBill Paul 			(void) strncpy(hostname, val + 2, hostlen);
196e8636dfdSBill Paul 			return (1);
197e8636dfdSBill Paul 		}
198e8636dfdSBill Paul 	}
199e8636dfdSBill Paul 	val = strchr(netname, '.');
200e8636dfdSBill Paul 	if (val == NULL)
201e8636dfdSBill Paul 		return (0);
202e8636dfdSBill Paul 	if (strncmp(netname, OPSYS, (val - netname)))
203e8636dfdSBill Paul 		return (0);
204e8636dfdSBill Paul 	val++;
205e8636dfdSBill Paul 	val2 = strchr(val, '@');
206e8636dfdSBill Paul 	if (val2 == NULL)
207e8636dfdSBill Paul 		return (0);
208e8636dfdSBill Paul 	vallen = val2 - val;
209e8636dfdSBill Paul 	if (vallen > (hostlen - 1))
210e8636dfdSBill Paul 		vallen = hostlen - 1;
211e8636dfdSBill Paul 	(void) strncpy(hostname, val, vallen);
212e8636dfdSBill Paul 	hostname[vallen] = 0;
213e8636dfdSBill Paul 
2148d630135SAlfred Perlstein 	err = __rpc_get_default_domain(&domain);	/* change to rpc */
215e8636dfdSBill Paul 	if (err)
216e8636dfdSBill Paul 		return (0);
217e8636dfdSBill Paul 
218e8636dfdSBill Paul 	if (strcmp(val2 + 1, domain))
219e8636dfdSBill Paul 		return (0);	/* wrong domain */
220e8636dfdSBill Paul 	else
221e8636dfdSBill Paul 		return (1);
222e8636dfdSBill Paul }
223e8636dfdSBill Paul 
224e8636dfdSBill Paul /*
225e8636dfdSBill Paul  * reads the file /etc/netid looking for a + to optionally go to the
226e8636dfdSBill Paul  * network information service.
227e8636dfdSBill Paul  */
228e8636dfdSBill Paul int
getnetid(char * key,char * ret)229587cf682SCraig Rodrigues getnetid(char *key, char *ret)
230e8636dfdSBill Paul {
231e8636dfdSBill Paul 	char            buf[1024];	/* big enough */
232e8636dfdSBill Paul 	char           *res;
233e8636dfdSBill Paul 	char           *mkey;
234e8636dfdSBill Paul 	char           *mval;
235e8636dfdSBill Paul 	FILE           *fd;
236e8636dfdSBill Paul #ifdef YP
237e8636dfdSBill Paul 	char           *domain;
238e8636dfdSBill Paul 	int             err;
239e8636dfdSBill Paul 	char           *lookup;
240e8636dfdSBill Paul 	int             len;
241e8636dfdSBill Paul #endif
24299d49860SEnji Cooper 	int rv;
24399d49860SEnji Cooper 
24499d49860SEnji Cooper 	rv = 0;
245e8636dfdSBill Paul 
246e8636dfdSBill Paul 	fd = fopen(NETIDFILE, "r");
24767ab6e98SAndrey A. Chernov 	if (fd == NULL) {
248e8636dfdSBill Paul #ifdef YP
249e8636dfdSBill Paul 		res = "+";
250e8636dfdSBill Paul 		goto getnetidyp;
251e8636dfdSBill Paul #else
252e8636dfdSBill Paul 		return (0);
253e8636dfdSBill Paul #endif
254e8636dfdSBill Paul 	}
25599d49860SEnji Cooper 	while (fd != NULL) {
25667ab6e98SAndrey A. Chernov 		res = fgets(buf, sizeof(buf), fd);
25767ab6e98SAndrey A. Chernov 		if (res == NULL) {
25899d49860SEnji Cooper 			rv = 0;
25999d49860SEnji Cooper 			goto done;
260e8636dfdSBill Paul 		}
261e8636dfdSBill Paul 		if (res[0] == '#')
262e8636dfdSBill Paul 			continue;
263e8636dfdSBill Paul 		else if (res[0] == '+') {
264e8636dfdSBill Paul #ifdef YP
265e8636dfdSBill Paul 	getnetidyp:
266e8636dfdSBill Paul 			err = yp_get_default_domain(&domain);
267e8636dfdSBill Paul 			if (err) {
268e8636dfdSBill Paul 				continue;
269e8636dfdSBill Paul 			}
270e8636dfdSBill Paul 			lookup = NULL;
271e8636dfdSBill Paul 			err = yp_match(domain, NETID, key,
272e8636dfdSBill Paul 				strlen(key), &lookup, &len);
273e8636dfdSBill Paul 			if (err) {
274e8636dfdSBill Paul #ifdef DEBUG
275e8636dfdSBill Paul 				fprintf(stderr, "match failed error %d\n", err);
276e8636dfdSBill Paul #endif
277e8636dfdSBill Paul 				continue;
278e8636dfdSBill Paul 			}
279e8636dfdSBill Paul 			lookup[len] = 0;
280e8636dfdSBill Paul 			strcpy(ret, lookup);
281e8636dfdSBill Paul 			free(lookup);
28299d49860SEnji Cooper 			rv = 2;
28399d49860SEnji Cooper 			goto done;
284e8636dfdSBill Paul #else	/* YP */
285e8636dfdSBill Paul #ifdef DEBUG
286e8636dfdSBill Paul 			fprintf(stderr,
287e8636dfdSBill Paul "Bad record in %s '+' -- NIS not supported in this library copy\n",
288e8636dfdSBill Paul 				NETIDFILE);
289e8636dfdSBill Paul #endif
290e8636dfdSBill Paul 			continue;
291e8636dfdSBill Paul #endif	/* YP */
292e8636dfdSBill Paul 		} else {
29367ab6e98SAndrey A. Chernov 			mkey = strsep(&res, "\t ");
294e8636dfdSBill Paul 			if (mkey == NULL) {
295e8636dfdSBill Paul 				fprintf(stderr,
296e8636dfdSBill Paul 		"Bad record in %s -- %s", NETIDFILE, buf);
297e8636dfdSBill Paul 				continue;
298e8636dfdSBill Paul 			}
29967ab6e98SAndrey A. Chernov 			do {
30067ab6e98SAndrey A. Chernov 				mval = strsep(&res, " \t#\n");
30167ab6e98SAndrey A. Chernov 			} while (mval != NULL && !*mval);
302e8636dfdSBill Paul 			if (mval == NULL) {
303e8636dfdSBill Paul 				fprintf(stderr,
304e8636dfdSBill Paul 		"Bad record in %s val problem - %s", NETIDFILE, buf);
305e8636dfdSBill Paul 				continue;
306e8636dfdSBill Paul 			}
307e8636dfdSBill Paul 			if (strcmp(mkey, key) == 0) {
308e8636dfdSBill Paul 				strcpy(ret, mval);
30999d49860SEnji Cooper 				rv = 1;
31099d49860SEnji Cooper 				goto done;
31199d49860SEnji Cooper 			}
31299d49860SEnji Cooper 		}
31399d49860SEnji Cooper 	}
314e8636dfdSBill Paul 
31599d49860SEnji Cooper done:
31699d49860SEnji Cooper 	if (fd != NULL)
31799d49860SEnji Cooper 		fclose(fd);
31899d49860SEnji Cooper 	return (rv);
319e8636dfdSBill Paul }
320