126219Swpaul/*
226219Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
326219Swpaul * unrestricted use provided that this legend is included on all tape
426219Swpaul * media and as a part of the software program in whole or part.  Users
526219Swpaul * may copy or modify Sun RPC without charge, but are not authorized
626219Swpaul * to license or distribute it to anyone else except as part of a product or
726219Swpaul * program developed by the user or with the express written consent of
826219Swpaul * Sun Microsystems, Inc.
926219Swpaul *
1026219Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1126219Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1226219Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1326219Swpaul *
1426219Swpaul * Sun RPC is provided with no support and without any obligation on the
1526219Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction,
1626219Swpaul * modification or enhancement.
1726219Swpaul *
1826219Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1926219Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
2026219Swpaul * OR ANY PART THEREOF.
2126219Swpaul *
2226219Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2326219Swpaul * or profits or other special, indirect and consequential damages, even if
2426219Swpaul * Sun has been advised of the possibility of such damages.
2526219Swpaul *
2626219Swpaul * Sun Microsystems, Inc.
2726219Swpaul * 2550 Garcia Avenue
2826219Swpaul * Mountain View, California  94043
2926219Swpaul */
30136581Sobrien
31136581Sobrien#if defined(LIBC_SCCS) && !defined(lint)
3226219Swpaulstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
3326219Swpaul#endif
3492990Sobrien#include <sys/cdefs.h>
3592990Sobrien__FBSDID("$FreeBSD$");
36136581Sobrien
3726219Swpaul/*
3826219Swpaul * netname utility routines convert from unix names to network names and
3926219Swpaul * vice-versa This module is operating system dependent! What we define here
4026219Swpaul * will work with any unix system that has adopted the sun NIS domain
4126219Swpaul * architecture.
4226219Swpaul */
4374462Salfred#include "namespace.h"
4426219Swpaul#include <sys/param.h>
4526219Swpaul#include <rpc/rpc.h>
4626219Swpaul#include <rpc/rpc_com.h>
4726219Swpaul#ifdef YP
4826219Swpaul#include <rpcsvc/yp_prot.h>
4926219Swpaul#include <rpcsvc/ypclnt.h>
5026219Swpaul#endif
5126219Swpaul#include <ctype.h>
5226219Swpaul#include <stdio.h>
5326219Swpaul#include <grp.h>
5426219Swpaul#include <pwd.h>
5526219Swpaul#include <string.h>
5626219Swpaul#include <stdlib.h>
5726219Swpaul#include <unistd.h>
5874462Salfred#include "un-namespace.h"
5926219Swpaul
6026219Swpaulstatic char    *OPSYS = "unix";
61137675Sbz#ifdef YP
6226219Swpaulstatic char    *NETID = "netid.byname";
63137675Sbz#endif
6426219Swpaulstatic char    *NETIDFILE = "/etc/netid";
6526219Swpaul
6692905Sobrienstatic int getnetid( char *, char * );
6792905Sobrienstatic int _getgroups( char *, gid_t * );
6826219Swpaul
6926219Swpaul/*
7026219Swpaul * Convert network-name into unix credential
7126219Swpaul */
7226219Swpaulint
7326219Swpaulnetname2user(netname, uidp, gidp, gidlenp, gidlist)
7426219Swpaul	char            netname[MAXNETNAMELEN + 1];
7526219Swpaul	uid_t            *uidp;
7626219Swpaul	gid_t            *gidp;
7726219Swpaul	int            *gidlenp;
7826219Swpaul	gid_t	       *gidlist;
7926219Swpaul{
8026219Swpaul	char           *p;
8126219Swpaul	int             gidlen;
8226219Swpaul	uid_t           uid;
8337300Sbde	long		luid;
8426219Swpaul	struct passwd  *pwd;
8526219Swpaul	char            val[1024];
8626219Swpaul	char           *val1, *val2;
8726219Swpaul	char           *domain;
8826219Swpaul	int             vallen;
8926219Swpaul	int             err;
9026219Swpaul
9126219Swpaul	if (getnetid(netname, val)) {
9265220Sache		char *res = val;
9365220Sache
9465220Sache		p = strsep(&res, ":");
9526219Swpaul		if (p == NULL)
9626219Swpaul			return (0);
9765220Sache		*uidp = (uid_t) atol(p);
9865220Sache		p = strsep(&res, "\n,");
9926219Swpaul		if (p == NULL) {
10026219Swpaul			return (0);
10126219Swpaul		}
10265220Sache		*gidp = (gid_t) atol(p);
103194498Sbrooks		for (gidlen = 0; gidlen < NGRPS; gidlen++) {
10465220Sache			p = strsep(&res, "\n,");
10526219Swpaul			if (p == NULL)
10626219Swpaul				break;
10726219Swpaul			gidlist[gidlen] = (gid_t) atol(p);
10826219Swpaul		}
10926219Swpaul		*gidlenp = gidlen;
11026219Swpaul
11126219Swpaul		return (1);
11226219Swpaul	}
11326219Swpaul	val1 = strchr(netname, '.');
11426219Swpaul	if (val1 == NULL)
11526219Swpaul		return (0);
11626219Swpaul	if (strncmp(netname, OPSYS, (val1-netname)))
11726219Swpaul		return (0);
11826219Swpaul	val1++;
11926219Swpaul	val2 = strchr(val1, '@');
12026219Swpaul	if (val2 == NULL)
12126219Swpaul		return (0);
12226219Swpaul	vallen = val2 - val1;
12326219Swpaul	if (vallen > (1024 - 1))
12426219Swpaul		vallen = 1024 - 1;
12526219Swpaul	(void) strncpy(val, val1, 1024);
12626219Swpaul	val[vallen] = 0;
12726219Swpaul
12890271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
12926219Swpaul	if (err)
13026219Swpaul		return (0);
13126219Swpaul
13226219Swpaul	if (strcmp(val2 + 1, domain))
13326219Swpaul		return (0);	/* wrong domain */
13426219Swpaul
13537300Sbde	if (sscanf(val, "%ld", &luid) != 1)
13626219Swpaul		return (0);
13737300Sbde	uid = luid;
13837300Sbde
13926219Swpaul	/* use initgroups method */
14026219Swpaul	pwd = getpwuid(uid);
14126219Swpaul	if (pwd == NULL)
14226219Swpaul		return (0);
14326219Swpaul	*uidp = pwd->pw_uid;
14426219Swpaul	*gidp = pwd->pw_gid;
14526219Swpaul	*gidlenp = _getgroups(pwd->pw_name, gidlist);
14626219Swpaul	return (1);
14726219Swpaul}
14826219Swpaul
14926219Swpaul/*
15026219Swpaul * initgroups
15126219Swpaul */
15226219Swpaul
15326219Swpaulstatic int
15426219Swpaul_getgroups(uname, groups)
15526219Swpaul	char           *uname;
156194498Sbrooks	gid_t          groups[NGRPS];
15726219Swpaul{
15826219Swpaul	gid_t           ngroups = 0;
15992889Sobrien	struct group *grp;
16092889Sobrien	int    i;
16192889Sobrien	int    j;
16226219Swpaul	int             filter;
16326219Swpaul
16426219Swpaul	setgrent();
16526219Swpaul	while ((grp = getgrent())) {
16626219Swpaul		for (i = 0; grp->gr_mem[i]; i++)
16726219Swpaul			if (!strcmp(grp->gr_mem[i], uname)) {
168194498Sbrooks				if (ngroups == NGRPS) {
16926219Swpaul#ifdef DEBUG
17026219Swpaul					fprintf(stderr,
17126219Swpaul				"initgroups: %s is in too many groups\n", uname);
17226219Swpaul#endif
17326219Swpaul					goto toomany;
17426219Swpaul				}
17526219Swpaul				/* filter out duplicate group entries */
17626219Swpaul				filter = 0;
17726219Swpaul				for (j = 0; j < ngroups; j++)
17826219Swpaul					if (groups[j] == grp->gr_gid) {
17926219Swpaul						filter++;
18026219Swpaul						break;
18126219Swpaul					}
18226219Swpaul				if (!filter)
18326219Swpaul					groups[ngroups++] = grp->gr_gid;
18426219Swpaul			}
18526219Swpaul	}
18626219Swpaultoomany:
18726219Swpaul	endgrent();
18826219Swpaul	return (ngroups);
18926219Swpaul}
19026219Swpaul
19126219Swpaul/*
19226219Swpaul * Convert network-name to hostname
19326219Swpaul */
19426219Swpaulint
19526219Swpaulnetname2host(netname, hostname, hostlen)
19626219Swpaul	char            netname[MAXNETNAMELEN + 1];
19726219Swpaul	char           *hostname;
19826219Swpaul	int             hostlen;
19926219Swpaul{
20026219Swpaul	int             err;
20126219Swpaul	char            valbuf[1024];
20226219Swpaul	char           *val;
20326219Swpaul	char           *val2;
20426219Swpaul	int             vallen;
20526219Swpaul	char           *domain;
20626219Swpaul
20726219Swpaul	if (getnetid(netname, valbuf)) {
20826219Swpaul		val = valbuf;
20926219Swpaul		if ((*val == '0') && (val[1] == ':')) {
21026219Swpaul			(void) strncpy(hostname, val + 2, hostlen);
21126219Swpaul			return (1);
21226219Swpaul		}
21326219Swpaul	}
21426219Swpaul	val = strchr(netname, '.');
21526219Swpaul	if (val == NULL)
21626219Swpaul		return (0);
21726219Swpaul	if (strncmp(netname, OPSYS, (val - netname)))
21826219Swpaul		return (0);
21926219Swpaul	val++;
22026219Swpaul	val2 = strchr(val, '@');
22126219Swpaul	if (val2 == NULL)
22226219Swpaul		return (0);
22326219Swpaul	vallen = val2 - val;
22426219Swpaul	if (vallen > (hostlen - 1))
22526219Swpaul		vallen = hostlen - 1;
22626219Swpaul	(void) strncpy(hostname, val, vallen);
22726219Swpaul	hostname[vallen] = 0;
22826219Swpaul
22990271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
23026219Swpaul	if (err)
23126219Swpaul		return (0);
23226219Swpaul
23326219Swpaul	if (strcmp(val2 + 1, domain))
23426219Swpaul		return (0);	/* wrong domain */
23526219Swpaul	else
23626219Swpaul		return (1);
23726219Swpaul}
23826219Swpaul
23926219Swpaul/*
24026219Swpaul * reads the file /etc/netid looking for a + to optionally go to the
24126219Swpaul * network information service.
24226219Swpaul */
24326219Swpaulint
24426219Swpaulgetnetid(key, ret)
24526219Swpaul	char           *key, *ret;
24626219Swpaul{
24726219Swpaul	char            buf[1024];	/* big enough */
24826219Swpaul	char           *res;
24926219Swpaul	char           *mkey;
25026219Swpaul	char           *mval;
25126219Swpaul	FILE           *fd;
25226219Swpaul#ifdef YP
25326219Swpaul	char           *domain;
25426219Swpaul	int             err;
25526219Swpaul	char           *lookup;
25626219Swpaul	int             len;
25726219Swpaul#endif
25826219Swpaul
25926219Swpaul	fd = fopen(NETIDFILE, "r");
26065220Sache	if (fd == NULL) {
26126219Swpaul#ifdef YP
26226219Swpaul		res = "+";
26326219Swpaul		goto getnetidyp;
26426219Swpaul#else
26526219Swpaul		return (0);
26626219Swpaul#endif
26726219Swpaul	}
26826219Swpaul	for (;;) {
26965220Sache		if (fd == NULL)
27026219Swpaul			return (0);	/* getnetidyp brings us here */
27165220Sache		res = fgets(buf, sizeof(buf), fd);
27265220Sache		if (res == NULL) {
27326219Swpaul			fclose(fd);
27426219Swpaul			return (0);
27526219Swpaul		}
27626219Swpaul		if (res[0] == '#')
27726219Swpaul			continue;
27826219Swpaul		else if (res[0] == '+') {
27926219Swpaul#ifdef YP
28026219Swpaul	getnetidyp:
28126219Swpaul			err = yp_get_default_domain(&domain);
28226219Swpaul			if (err) {
28326219Swpaul				continue;
28426219Swpaul			}
28526219Swpaul			lookup = NULL;
28626219Swpaul			err = yp_match(domain, NETID, key,
28726219Swpaul				strlen(key), &lookup, &len);
28826219Swpaul			if (err) {
28926219Swpaul#ifdef DEBUG
29026219Swpaul				fprintf(stderr, "match failed error %d\n", err);
29126219Swpaul#endif
29226219Swpaul				continue;
29326219Swpaul			}
29426219Swpaul			lookup[len] = 0;
29526219Swpaul			strcpy(ret, lookup);
29626219Swpaul			free(lookup);
29726583Swpaul			if (fd != NULL)
29826583Swpaul				fclose(fd);
29926219Swpaul			return (2);
30026219Swpaul#else	/* YP */
30126219Swpaul#ifdef DEBUG
30226219Swpaul			fprintf(stderr,
30326219Swpaul"Bad record in %s '+' -- NIS not supported in this library copy\n",
30426219Swpaul				NETIDFILE);
30526219Swpaul#endif
30626219Swpaul			continue;
30726219Swpaul#endif	/* YP */
30826219Swpaul		} else {
30965220Sache			mkey = strsep(&res, "\t ");
31026219Swpaul			if (mkey == NULL) {
31126219Swpaul				fprintf(stderr,
31226219Swpaul		"Bad record in %s -- %s", NETIDFILE, buf);
31326219Swpaul				continue;
31426219Swpaul			}
31565220Sache			do {
31665220Sache				mval = strsep(&res, " \t#\n");
31765220Sache			} while (mval != NULL && !*mval);
31826219Swpaul			if (mval == NULL) {
31926219Swpaul				fprintf(stderr,
32026219Swpaul		"Bad record in %s val problem - %s", NETIDFILE, buf);
32126219Swpaul				continue;
32226219Swpaul			}
32326219Swpaul			if (strcmp(mkey, key) == 0) {
32426219Swpaul				strcpy(ret, mval);
32526219Swpaul				fclose(fd);
32626219Swpaul				return (1);
32726219Swpaul
32826219Swpaul			}
32926219Swpaul		}
33026219Swpaul	}
33126219Swpaul}
332