netnamer.c revision 137675
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: head/lib/libc/rpc/netnamer.c 137675 2004-11-13 20:40:32Z bz $");
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#ifndef NGROUPS
7026219Swpaul#define NGROUPS 16
7126219Swpaul#endif
7226219Swpaul
7326219Swpaul/*
7426219Swpaul * Convert network-name into unix credential
7526219Swpaul */
7626219Swpaulint
7726219Swpaulnetname2user(netname, uidp, gidp, gidlenp, gidlist)
7826219Swpaul	char            netname[MAXNETNAMELEN + 1];
7926219Swpaul	uid_t            *uidp;
8026219Swpaul	gid_t            *gidp;
8126219Swpaul	int            *gidlenp;
8226219Swpaul	gid_t	       *gidlist;
8326219Swpaul{
8426219Swpaul	char           *p;
8526219Swpaul	int             gidlen;
8626219Swpaul	uid_t           uid;
8737300Sbde	long		luid;
8826219Swpaul	struct passwd  *pwd;
8926219Swpaul	char            val[1024];
9026219Swpaul	char           *val1, *val2;
9126219Swpaul	char           *domain;
9226219Swpaul	int             vallen;
9326219Swpaul	int             err;
9426219Swpaul
9526219Swpaul	if (getnetid(netname, val)) {
9665220Sache		char *res = val;
9765220Sache
9865220Sache		p = strsep(&res, ":");
9926219Swpaul		if (p == NULL)
10026219Swpaul			return (0);
10165220Sache		*uidp = (uid_t) atol(p);
10265220Sache		p = strsep(&res, "\n,");
10326219Swpaul		if (p == NULL) {
10426219Swpaul			return (0);
10526219Swpaul		}
10665220Sache		*gidp = (gid_t) atol(p);
10726219Swpaul		gidlen = 0;
10826219Swpaul		for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
10965220Sache			p = strsep(&res, "\n,");
11026219Swpaul			if (p == NULL)
11126219Swpaul				break;
11226219Swpaul			gidlist[gidlen] = (gid_t) atol(p);
11326219Swpaul		}
11426219Swpaul		*gidlenp = gidlen;
11526219Swpaul
11626219Swpaul		return (1);
11726219Swpaul	}
11826219Swpaul	val1 = strchr(netname, '.');
11926219Swpaul	if (val1 == NULL)
12026219Swpaul		return (0);
12126219Swpaul	if (strncmp(netname, OPSYS, (val1-netname)))
12226219Swpaul		return (0);
12326219Swpaul	val1++;
12426219Swpaul	val2 = strchr(val1, '@');
12526219Swpaul	if (val2 == NULL)
12626219Swpaul		return (0);
12726219Swpaul	vallen = val2 - val1;
12826219Swpaul	if (vallen > (1024 - 1))
12926219Swpaul		vallen = 1024 - 1;
13026219Swpaul	(void) strncpy(val, val1, 1024);
13126219Swpaul	val[vallen] = 0;
13226219Swpaul
13390271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
13426219Swpaul	if (err)
13526219Swpaul		return (0);
13626219Swpaul
13726219Swpaul	if (strcmp(val2 + 1, domain))
13826219Swpaul		return (0);	/* wrong domain */
13926219Swpaul
14037300Sbde	if (sscanf(val, "%ld", &luid) != 1)
14126219Swpaul		return (0);
14237300Sbde	uid = luid;
14337300Sbde
14426219Swpaul	/* use initgroups method */
14526219Swpaul	pwd = getpwuid(uid);
14626219Swpaul	if (pwd == NULL)
14726219Swpaul		return (0);
14826219Swpaul	*uidp = pwd->pw_uid;
14926219Swpaul	*gidp = pwd->pw_gid;
15026219Swpaul	*gidlenp = _getgroups(pwd->pw_name, gidlist);
15126219Swpaul	return (1);
15226219Swpaul}
15326219Swpaul
15426219Swpaul/*
15526219Swpaul * initgroups
15626219Swpaul */
15726219Swpaul
15826219Swpaulstatic int
15926219Swpaul_getgroups(uname, groups)
16026219Swpaul	char           *uname;
16126219Swpaul	gid_t          groups[NGROUPS];
16226219Swpaul{
16326219Swpaul	gid_t           ngroups = 0;
16492889Sobrien	struct group *grp;
16592889Sobrien	int    i;
16692889Sobrien	int    j;
16726219Swpaul	int             filter;
16826219Swpaul
16926219Swpaul	setgrent();
17026219Swpaul	while ((grp = getgrent())) {
17126219Swpaul		for (i = 0; grp->gr_mem[i]; i++)
17226219Swpaul			if (!strcmp(grp->gr_mem[i], uname)) {
17326219Swpaul				if (ngroups == NGROUPS) {
17426219Swpaul#ifdef DEBUG
17526219Swpaul					fprintf(stderr,
17626219Swpaul				"initgroups: %s is in too many groups\n", uname);
17726219Swpaul#endif
17826219Swpaul					goto toomany;
17926219Swpaul				}
18026219Swpaul				/* filter out duplicate group entries */
18126219Swpaul				filter = 0;
18226219Swpaul				for (j = 0; j < ngroups; j++)
18326219Swpaul					if (groups[j] == grp->gr_gid) {
18426219Swpaul						filter++;
18526219Swpaul						break;
18626219Swpaul					}
18726219Swpaul				if (!filter)
18826219Swpaul					groups[ngroups++] = grp->gr_gid;
18926219Swpaul			}
19026219Swpaul	}
19126219Swpaultoomany:
19226219Swpaul	endgrent();
19326219Swpaul	return (ngroups);
19426219Swpaul}
19526219Swpaul
19626219Swpaul/*
19726219Swpaul * Convert network-name to hostname
19826219Swpaul */
19926219Swpaulint
20026219Swpaulnetname2host(netname, hostname, hostlen)
20126219Swpaul	char            netname[MAXNETNAMELEN + 1];
20226219Swpaul	char           *hostname;
20326219Swpaul	int             hostlen;
20426219Swpaul{
20526219Swpaul	int             err;
20626219Swpaul	char            valbuf[1024];
20726219Swpaul	char           *val;
20826219Swpaul	char           *val2;
20926219Swpaul	int             vallen;
21026219Swpaul	char           *domain;
21126219Swpaul
21226219Swpaul	if (getnetid(netname, valbuf)) {
21326219Swpaul		val = valbuf;
21426219Swpaul		if ((*val == '0') && (val[1] == ':')) {
21526219Swpaul			(void) strncpy(hostname, val + 2, hostlen);
21626219Swpaul			return (1);
21726219Swpaul		}
21826219Swpaul	}
21926219Swpaul	val = strchr(netname, '.');
22026219Swpaul	if (val == NULL)
22126219Swpaul		return (0);
22226219Swpaul	if (strncmp(netname, OPSYS, (val - netname)))
22326219Swpaul		return (0);
22426219Swpaul	val++;
22526219Swpaul	val2 = strchr(val, '@');
22626219Swpaul	if (val2 == NULL)
22726219Swpaul		return (0);
22826219Swpaul	vallen = val2 - val;
22926219Swpaul	if (vallen > (hostlen - 1))
23026219Swpaul		vallen = hostlen - 1;
23126219Swpaul	(void) strncpy(hostname, val, vallen);
23226219Swpaul	hostname[vallen] = 0;
23326219Swpaul
23490271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
23526219Swpaul	if (err)
23626219Swpaul		return (0);
23726219Swpaul
23826219Swpaul	if (strcmp(val2 + 1, domain))
23926219Swpaul		return (0);	/* wrong domain */
24026219Swpaul	else
24126219Swpaul		return (1);
24226219Swpaul}
24326219Swpaul
24426219Swpaul/*
24526219Swpaul * reads the file /etc/netid looking for a + to optionally go to the
24626219Swpaul * network information service.
24726219Swpaul */
24826219Swpaulint
24926219Swpaulgetnetid(key, ret)
25026219Swpaul	char           *key, *ret;
25126219Swpaul{
25226219Swpaul	char            buf[1024];	/* big enough */
25326219Swpaul	char           *res;
25426219Swpaul	char           *mkey;
25526219Swpaul	char           *mval;
25626219Swpaul	FILE           *fd;
25726219Swpaul#ifdef YP
25826219Swpaul	char           *domain;
25926219Swpaul	int             err;
26026219Swpaul	char           *lookup;
26126219Swpaul	int             len;
26226219Swpaul#endif
26326219Swpaul
26426219Swpaul	fd = fopen(NETIDFILE, "r");
26565220Sache	if (fd == NULL) {
26626219Swpaul#ifdef YP
26726219Swpaul		res = "+";
26826219Swpaul		goto getnetidyp;
26926219Swpaul#else
27026219Swpaul		return (0);
27126219Swpaul#endif
27226219Swpaul	}
27326219Swpaul	for (;;) {
27465220Sache		if (fd == NULL)
27526219Swpaul			return (0);	/* getnetidyp brings us here */
27665220Sache		res = fgets(buf, sizeof(buf), fd);
27765220Sache		if (res == NULL) {
27826219Swpaul			fclose(fd);
27926219Swpaul			return (0);
28026219Swpaul		}
28126219Swpaul		if (res[0] == '#')
28226219Swpaul			continue;
28326219Swpaul		else if (res[0] == '+') {
28426219Swpaul#ifdef YP
28526219Swpaul	getnetidyp:
28626219Swpaul			err = yp_get_default_domain(&domain);
28726219Swpaul			if (err) {
28826219Swpaul				continue;
28926219Swpaul			}
29026219Swpaul			lookup = NULL;
29126219Swpaul			err = yp_match(domain, NETID, key,
29226219Swpaul				strlen(key), &lookup, &len);
29326219Swpaul			if (err) {
29426219Swpaul#ifdef DEBUG
29526219Swpaul				fprintf(stderr, "match failed error %d\n", err);
29626219Swpaul#endif
29726219Swpaul				continue;
29826219Swpaul			}
29926219Swpaul			lookup[len] = 0;
30026219Swpaul			strcpy(ret, lookup);
30126219Swpaul			free(lookup);
30226583Swpaul			if (fd != NULL)
30326583Swpaul				fclose(fd);
30426219Swpaul			return (2);
30526219Swpaul#else	/* YP */
30626219Swpaul#ifdef DEBUG
30726219Swpaul			fprintf(stderr,
30826219Swpaul"Bad record in %s '+' -- NIS not supported in this library copy\n",
30926219Swpaul				NETIDFILE);
31026219Swpaul#endif
31126219Swpaul			continue;
31226219Swpaul#endif	/* YP */
31326219Swpaul		} else {
31465220Sache			mkey = strsep(&res, "\t ");
31526219Swpaul			if (mkey == NULL) {
31626219Swpaul				fprintf(stderr,
31726219Swpaul		"Bad record in %s -- %s", NETIDFILE, buf);
31826219Swpaul				continue;
31926219Swpaul			}
32065220Sache			do {
32165220Sache				mval = strsep(&res, " \t#\n");
32265220Sache			} while (mval != NULL && !*mval);
32326219Swpaul			if (mval == NULL) {
32426219Swpaul				fprintf(stderr,
32526219Swpaul		"Bad record in %s val problem - %s", NETIDFILE, buf);
32626219Swpaul				continue;
32726219Swpaul			}
32826219Swpaul			if (strcmp(mkey, key) == 0) {
32926219Swpaul				strcpy(ret, mval);
33026219Swpaul				fclose(fd);
33126219Swpaul				return (1);
33226219Swpaul
33326219Swpaul			}
33426219Swpaul		}
33526219Swpaul	}
33626219Swpaul}
337