netnamer.c revision 74462
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
2965220Sache *
3065220Sache * $FreeBSD: head/lib/libc/rpc/netnamer.c 74462 2001-03-19 12:50:13Z alfred $
3126219Swpaul */
3226219Swpaul#if !defined(lint) && defined(SCCSIDS)
3326219Swpaulstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
3426219Swpaul#endif
3526219Swpaul/*
3626219Swpaul * netname utility routines convert from unix names to network names and
3726219Swpaul * vice-versa This module is operating system dependent! What we define here
3826219Swpaul * will work with any unix system that has adopted the sun NIS domain
3926219Swpaul * architecture.
4026219Swpaul */
4174462Salfred#include "namespace.h"
4226219Swpaul#include <sys/param.h>
4326219Swpaul#include <rpc/rpc.h>
4426219Swpaul#include <rpc/rpc_com.h>
4526219Swpaul#ifdef YP
4626219Swpaul#include <rpcsvc/yp_prot.h>
4726219Swpaul#include <rpcsvc/ypclnt.h>
4826219Swpaul#endif
4926219Swpaul#include <ctype.h>
5026219Swpaul#include <stdio.h>
5126219Swpaul#include <grp.h>
5226219Swpaul#include <pwd.h>
5326219Swpaul#include <string.h>
5426219Swpaul#include <stdlib.h>
5526219Swpaul#include <unistd.h>
5674462Salfred#include "un-namespace.h"
5726219Swpaul
5826219Swpaulstatic char    *OPSYS = "unix";
5926219Swpaulstatic char    *NETID = "netid.byname";
6026219Swpaulstatic char    *NETIDFILE = "/etc/netid";
6126219Swpaul
6226219Swpaulstatic int getnetid __P(( char *, char * ));
6326219Swpaulstatic int _getgroups __P(( char *, gid_t * ));
6426219Swpaul
6526219Swpaul#ifndef NGROUPS
6626219Swpaul#define NGROUPS 16
6726219Swpaul#endif
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);
10326219Swpaul		gidlen = 0;
10426219Swpaul		for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
10565220Sache			p = strsep(&res, "\n,");
10626219Swpaul			if (p == NULL)
10726219Swpaul				break;
10826219Swpaul			gidlist[gidlen] = (gid_t) atol(p);
10926219Swpaul		}
11026219Swpaul		*gidlenp = gidlen;
11126219Swpaul
11226219Swpaul		return (1);
11326219Swpaul	}
11426219Swpaul	val1 = strchr(netname, '.');
11526219Swpaul	if (val1 == NULL)
11626219Swpaul		return (0);
11726219Swpaul	if (strncmp(netname, OPSYS, (val1-netname)))
11826219Swpaul		return (0);
11926219Swpaul	val1++;
12026219Swpaul	val2 = strchr(val1, '@');
12126219Swpaul	if (val2 == NULL)
12226219Swpaul		return (0);
12326219Swpaul	vallen = val2 - val1;
12426219Swpaul	if (vallen > (1024 - 1))
12526219Swpaul		vallen = 1024 - 1;
12626219Swpaul	(void) strncpy(val, val1, 1024);
12726219Swpaul	val[vallen] = 0;
12826219Swpaul
12926219Swpaul	err = _rpc_get_default_domain(&domain);	/* change to rpc */
13026219Swpaul	if (err)
13126219Swpaul		return (0);
13226219Swpaul
13326219Swpaul	if (strcmp(val2 + 1, domain))
13426219Swpaul		return (0);	/* wrong domain */
13526219Swpaul
13637300Sbde	if (sscanf(val, "%ld", &luid) != 1)
13726219Swpaul		return (0);
13837300Sbde	uid = luid;
13937300Sbde
14026219Swpaul	/* use initgroups method */
14126219Swpaul	pwd = getpwuid(uid);
14226219Swpaul	if (pwd == NULL)
14326219Swpaul		return (0);
14426219Swpaul	*uidp = pwd->pw_uid;
14526219Swpaul	*gidp = pwd->pw_gid;
14626219Swpaul	*gidlenp = _getgroups(pwd->pw_name, gidlist);
14726219Swpaul	return (1);
14826219Swpaul}
14926219Swpaul
15026219Swpaul/*
15126219Swpaul * initgroups
15226219Swpaul */
15326219Swpaul
15426219Swpaulstatic int
15526219Swpaul_getgroups(uname, groups)
15626219Swpaul	char           *uname;
15726219Swpaul	gid_t          groups[NGROUPS];
15826219Swpaul{
15926219Swpaul	gid_t           ngroups = 0;
16026219Swpaul	register struct group *grp;
16126219Swpaul	register int    i;
16226219Swpaul	register int    j;
16326219Swpaul	int             filter;
16426219Swpaul
16526219Swpaul	setgrent();
16626219Swpaul	while ((grp = getgrent())) {
16726219Swpaul		for (i = 0; grp->gr_mem[i]; i++)
16826219Swpaul			if (!strcmp(grp->gr_mem[i], uname)) {
16926219Swpaul				if (ngroups == NGROUPS) {
17026219Swpaul#ifdef DEBUG
17126219Swpaul					fprintf(stderr,
17226219Swpaul				"initgroups: %s is in too many groups\n", uname);
17326219Swpaul#endif
17426219Swpaul					goto toomany;
17526219Swpaul				}
17626219Swpaul				/* filter out duplicate group entries */
17726219Swpaul				filter = 0;
17826219Swpaul				for (j = 0; j < ngroups; j++)
17926219Swpaul					if (groups[j] == grp->gr_gid) {
18026219Swpaul						filter++;
18126219Swpaul						break;
18226219Swpaul					}
18326219Swpaul				if (!filter)
18426219Swpaul					groups[ngroups++] = grp->gr_gid;
18526219Swpaul			}
18626219Swpaul	}
18726219Swpaultoomany:
18826219Swpaul	endgrent();
18926219Swpaul	return (ngroups);
19026219Swpaul}
19126219Swpaul
19226219Swpaul/*
19326219Swpaul * Convert network-name to hostname
19426219Swpaul */
19526219Swpaulint
19626219Swpaulnetname2host(netname, hostname, hostlen)
19726219Swpaul	char            netname[MAXNETNAMELEN + 1];
19826219Swpaul	char           *hostname;
19926219Swpaul	int             hostlen;
20026219Swpaul{
20126219Swpaul	int             err;
20226219Swpaul	char            valbuf[1024];
20326219Swpaul	char           *val;
20426219Swpaul	char           *val2;
20526219Swpaul	int             vallen;
20626219Swpaul	char           *domain;
20726219Swpaul
20826219Swpaul	if (getnetid(netname, valbuf)) {
20926219Swpaul		val = valbuf;
21026219Swpaul		if ((*val == '0') && (val[1] == ':')) {
21126219Swpaul			(void) strncpy(hostname, val + 2, hostlen);
21226219Swpaul			return (1);
21326219Swpaul		}
21426219Swpaul	}
21526219Swpaul	val = strchr(netname, '.');
21626219Swpaul	if (val == NULL)
21726219Swpaul		return (0);
21826219Swpaul	if (strncmp(netname, OPSYS, (val - netname)))
21926219Swpaul		return (0);
22026219Swpaul	val++;
22126219Swpaul	val2 = strchr(val, '@');
22226219Swpaul	if (val2 == NULL)
22326219Swpaul		return (0);
22426219Swpaul	vallen = val2 - val;
22526219Swpaul	if (vallen > (hostlen - 1))
22626219Swpaul		vallen = hostlen - 1;
22726219Swpaul	(void) strncpy(hostname, val, vallen);
22826219Swpaul	hostname[vallen] = 0;
22926219Swpaul
23026219Swpaul	err = _rpc_get_default_domain(&domain);	/* change to rpc */
23126219Swpaul	if (err)
23226219Swpaul		return (0);
23326219Swpaul
23426219Swpaul	if (strcmp(val2 + 1, domain))
23526219Swpaul		return (0);	/* wrong domain */
23626219Swpaul	else
23726219Swpaul		return (1);
23826219Swpaul}
23926219Swpaul
24026219Swpaul/*
24126219Swpaul * reads the file /etc/netid looking for a + to optionally go to the
24226219Swpaul * network information service.
24326219Swpaul */
24426219Swpaulint
24526219Swpaulgetnetid(key, ret)
24626219Swpaul	char           *key, *ret;
24726219Swpaul{
24826219Swpaul	char            buf[1024];	/* big enough */
24926219Swpaul	char           *res;
25026219Swpaul	char           *mkey;
25126219Swpaul	char           *mval;
25226219Swpaul	FILE           *fd;
25326219Swpaul#ifdef YP
25426219Swpaul	char           *domain;
25526219Swpaul	int             err;
25626219Swpaul	char           *lookup;
25726219Swpaul	int             len;
25826219Swpaul#endif
25926219Swpaul
26026219Swpaul	fd = fopen(NETIDFILE, "r");
26165220Sache	if (fd == NULL) {
26226219Swpaul#ifdef YP
26326219Swpaul		res = "+";
26426219Swpaul		goto getnetidyp;
26526219Swpaul#else
26626219Swpaul		return (0);
26726219Swpaul#endif
26826219Swpaul	}
26926219Swpaul	for (;;) {
27065220Sache		if (fd == NULL)
27126219Swpaul			return (0);	/* getnetidyp brings us here */
27265220Sache		res = fgets(buf, sizeof(buf), fd);
27365220Sache		if (res == NULL) {
27426219Swpaul			fclose(fd);
27526219Swpaul			return (0);
27626219Swpaul		}
27726219Swpaul		if (res[0] == '#')
27826219Swpaul			continue;
27926219Swpaul		else if (res[0] == '+') {
28026219Swpaul#ifdef YP
28126219Swpaul	getnetidyp:
28226219Swpaul			err = yp_get_default_domain(&domain);
28326219Swpaul			if (err) {
28426219Swpaul				continue;
28526219Swpaul			}
28626219Swpaul			lookup = NULL;
28726219Swpaul			err = yp_match(domain, NETID, key,
28826219Swpaul				strlen(key), &lookup, &len);
28926219Swpaul			if (err) {
29026219Swpaul#ifdef DEBUG
29126219Swpaul				fprintf(stderr, "match failed error %d\n", err);
29226219Swpaul#endif
29326219Swpaul				continue;
29426219Swpaul			}
29526219Swpaul			lookup[len] = 0;
29626219Swpaul			strcpy(ret, lookup);
29726219Swpaul			free(lookup);
29826583Swpaul			if (fd != NULL)
29926583Swpaul				fclose(fd);
30026219Swpaul			return (2);
30126219Swpaul#else	/* YP */
30226219Swpaul#ifdef DEBUG
30326219Swpaul			fprintf(stderr,
30426219Swpaul"Bad record in %s '+' -- NIS not supported in this library copy\n",
30526219Swpaul				NETIDFILE);
30626219Swpaul#endif
30726219Swpaul			continue;
30826219Swpaul#endif	/* YP */
30926219Swpaul		} else {
31065220Sache			mkey = strsep(&res, "\t ");
31126219Swpaul			if (mkey == NULL) {
31226219Swpaul				fprintf(stderr,
31326219Swpaul		"Bad record in %s -- %s", NETIDFILE, buf);
31426219Swpaul				continue;
31526219Swpaul			}
31665220Sache			do {
31765220Sache				mval = strsep(&res, " \t#\n");
31865220Sache			} while (mval != NULL && !*mval);
31926219Swpaul			if (mval == NULL) {
32026219Swpaul				fprintf(stderr,
32126219Swpaul		"Bad record in %s val problem - %s", NETIDFILE, buf);
32226219Swpaul				continue;
32326219Swpaul			}
32426219Swpaul			if (strcmp(mkey, key) == 0) {
32526219Swpaul				strcpy(ret, mval);
32626219Swpaul				fclose(fd);
32726219Swpaul				return (1);
32826219Swpaul
32926219Swpaul			}
33026219Swpaul		}
33126219Swpaul	}
33226219Swpaul}
333