1261057Smav/*-
2261057Smav * Copyright (c) 2009, Sun Microsystems, Inc.
3261057Smav * All rights reserved.
426219Swpaul *
5261057Smav * Redistribution and use in source and binary forms, with or without
6261057Smav * modification, are permitted provided that the following conditions are met:
7261057Smav * - Redistributions of source code must retain the above copyright notice,
8261057Smav *   this list of conditions and the following disclaimer.
9261057Smav * - Redistributions in binary form must reproduce the above copyright notice,
10261057Smav *   this list of conditions and the following disclaimer in the documentation
11261057Smav *   and/or other materials provided with the distribution.
12261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its
13261057Smav *   contributors may be used to endorse or promote products derived
14261057Smav *   from this software without specific prior written permission.
15261057Smav *
16261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26261057Smav * POSSIBILITY OF SUCH DAMAGE.
2726219Swpaul */
28136581Sobrien
29136581Sobrien#if defined(LIBC_SCCS) && !defined(lint)
3026219Swpaulstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
3126219Swpaul#endif
3292990Sobrien#include <sys/cdefs.h>
3392990Sobrien__FBSDID("$FreeBSD$");
34136581Sobrien
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";
59137675Sbz#ifdef YP
6026219Swpaulstatic char    *NETID = "netid.byname";
61137675Sbz#endif
6226219Swpaulstatic char    *NETIDFILE = "/etc/netid";
6326219Swpaul
6492905Sobrienstatic int getnetid( char *, char * );
6592905Sobrienstatic int _getgroups( char *, gid_t * );
6626219Swpaul
6726219Swpaul/*
6826219Swpaul * Convert network-name into unix credential
6926219Swpaul */
7026219Swpaulint
7126219Swpaulnetname2user(netname, uidp, gidp, gidlenp, gidlist)
7226219Swpaul	char            netname[MAXNETNAMELEN + 1];
7326219Swpaul	uid_t            *uidp;
7426219Swpaul	gid_t            *gidp;
7526219Swpaul	int            *gidlenp;
7626219Swpaul	gid_t	       *gidlist;
7726219Swpaul{
7826219Swpaul	char           *p;
7926219Swpaul	int             gidlen;
8026219Swpaul	uid_t           uid;
8137300Sbde	long		luid;
8226219Swpaul	struct passwd  *pwd;
8326219Swpaul	char            val[1024];
8426219Swpaul	char           *val1, *val2;
8526219Swpaul	char           *domain;
8626219Swpaul	int             vallen;
8726219Swpaul	int             err;
8826219Swpaul
8926219Swpaul	if (getnetid(netname, val)) {
9065220Sache		char *res = val;
9165220Sache
9265220Sache		p = strsep(&res, ":");
9326219Swpaul		if (p == NULL)
9426219Swpaul			return (0);
9565220Sache		*uidp = (uid_t) atol(p);
9665220Sache		p = strsep(&res, "\n,");
9726219Swpaul		if (p == NULL) {
9826219Swpaul			return (0);
9926219Swpaul		}
10065220Sache		*gidp = (gid_t) atol(p);
101194498Sbrooks		for (gidlen = 0; gidlen < NGRPS; gidlen++) {
10265220Sache			p = strsep(&res, "\n,");
10326219Swpaul			if (p == NULL)
10426219Swpaul				break;
10526219Swpaul			gidlist[gidlen] = (gid_t) atol(p);
10626219Swpaul		}
10726219Swpaul		*gidlenp = gidlen;
10826219Swpaul
10926219Swpaul		return (1);
11026219Swpaul	}
11126219Swpaul	val1 = strchr(netname, '.');
11226219Swpaul	if (val1 == NULL)
11326219Swpaul		return (0);
11426219Swpaul	if (strncmp(netname, OPSYS, (val1-netname)))
11526219Swpaul		return (0);
11626219Swpaul	val1++;
11726219Swpaul	val2 = strchr(val1, '@');
11826219Swpaul	if (val2 == NULL)
11926219Swpaul		return (0);
12026219Swpaul	vallen = val2 - val1;
12126219Swpaul	if (vallen > (1024 - 1))
12226219Swpaul		vallen = 1024 - 1;
12326219Swpaul	(void) strncpy(val, val1, 1024);
12426219Swpaul	val[vallen] = 0;
12526219Swpaul
12690271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
12726219Swpaul	if (err)
12826219Swpaul		return (0);
12926219Swpaul
13026219Swpaul	if (strcmp(val2 + 1, domain))
13126219Swpaul		return (0);	/* wrong domain */
13226219Swpaul
13337300Sbde	if (sscanf(val, "%ld", &luid) != 1)
13426219Swpaul		return (0);
13537300Sbde	uid = luid;
13637300Sbde
13726219Swpaul	/* use initgroups method */
13826219Swpaul	pwd = getpwuid(uid);
13926219Swpaul	if (pwd == NULL)
14026219Swpaul		return (0);
14126219Swpaul	*uidp = pwd->pw_uid;
14226219Swpaul	*gidp = pwd->pw_gid;
14326219Swpaul	*gidlenp = _getgroups(pwd->pw_name, gidlist);
14426219Swpaul	return (1);
14526219Swpaul}
14626219Swpaul
14726219Swpaul/*
14826219Swpaul * initgroups
14926219Swpaul */
15026219Swpaul
15126219Swpaulstatic int
15226219Swpaul_getgroups(uname, groups)
15326219Swpaul	char           *uname;
154194498Sbrooks	gid_t          groups[NGRPS];
15526219Swpaul{
15626219Swpaul	gid_t           ngroups = 0;
15792889Sobrien	struct group *grp;
15892889Sobrien	int    i;
15992889Sobrien	int    j;
16026219Swpaul	int             filter;
16126219Swpaul
16226219Swpaul	setgrent();
16326219Swpaul	while ((grp = getgrent())) {
16426219Swpaul		for (i = 0; grp->gr_mem[i]; i++)
16526219Swpaul			if (!strcmp(grp->gr_mem[i], uname)) {
166194498Sbrooks				if (ngroups == NGRPS) {
16726219Swpaul#ifdef DEBUG
16826219Swpaul					fprintf(stderr,
16926219Swpaul				"initgroups: %s is in too many groups\n", uname);
17026219Swpaul#endif
17126219Swpaul					goto toomany;
17226219Swpaul				}
17326219Swpaul				/* filter out duplicate group entries */
17426219Swpaul				filter = 0;
17526219Swpaul				for (j = 0; j < ngroups; j++)
17626219Swpaul					if (groups[j] == grp->gr_gid) {
17726219Swpaul						filter++;
17826219Swpaul						break;
17926219Swpaul					}
18026219Swpaul				if (!filter)
18126219Swpaul					groups[ngroups++] = grp->gr_gid;
18226219Swpaul			}
18326219Swpaul	}
18426219Swpaultoomany:
18526219Swpaul	endgrent();
18626219Swpaul	return (ngroups);
18726219Swpaul}
18826219Swpaul
18926219Swpaul/*
19026219Swpaul * Convert network-name to hostname
19126219Swpaul */
19226219Swpaulint
19326219Swpaulnetname2host(netname, hostname, hostlen)
19426219Swpaul	char            netname[MAXNETNAMELEN + 1];
19526219Swpaul	char           *hostname;
19626219Swpaul	int             hostlen;
19726219Swpaul{
19826219Swpaul	int             err;
19926219Swpaul	char            valbuf[1024];
20026219Swpaul	char           *val;
20126219Swpaul	char           *val2;
20226219Swpaul	int             vallen;
20326219Swpaul	char           *domain;
20426219Swpaul
20526219Swpaul	if (getnetid(netname, valbuf)) {
20626219Swpaul		val = valbuf;
20726219Swpaul		if ((*val == '0') && (val[1] == ':')) {
20826219Swpaul			(void) strncpy(hostname, val + 2, hostlen);
20926219Swpaul			return (1);
21026219Swpaul		}
21126219Swpaul	}
21226219Swpaul	val = strchr(netname, '.');
21326219Swpaul	if (val == NULL)
21426219Swpaul		return (0);
21526219Swpaul	if (strncmp(netname, OPSYS, (val - netname)))
21626219Swpaul		return (0);
21726219Swpaul	val++;
21826219Swpaul	val2 = strchr(val, '@');
21926219Swpaul	if (val2 == NULL)
22026219Swpaul		return (0);
22126219Swpaul	vallen = val2 - val;
22226219Swpaul	if (vallen > (hostlen - 1))
22326219Swpaul		vallen = hostlen - 1;
22426219Swpaul	(void) strncpy(hostname, val, vallen);
22526219Swpaul	hostname[vallen] = 0;
22626219Swpaul
22790271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
22826219Swpaul	if (err)
22926219Swpaul		return (0);
23026219Swpaul
23126219Swpaul	if (strcmp(val2 + 1, domain))
23226219Swpaul		return (0);	/* wrong domain */
23326219Swpaul	else
23426219Swpaul		return (1);
23526219Swpaul}
23626219Swpaul
23726219Swpaul/*
23826219Swpaul * reads the file /etc/netid looking for a + to optionally go to the
23926219Swpaul * network information service.
24026219Swpaul */
24126219Swpaulint
24226219Swpaulgetnetid(key, ret)
24326219Swpaul	char           *key, *ret;
24426219Swpaul{
24526219Swpaul	char            buf[1024];	/* big enough */
24626219Swpaul	char           *res;
24726219Swpaul	char           *mkey;
24826219Swpaul	char           *mval;
24926219Swpaul	FILE           *fd;
25026219Swpaul#ifdef YP
25126219Swpaul	char           *domain;
25226219Swpaul	int             err;
25326219Swpaul	char           *lookup;
25426219Swpaul	int             len;
25526219Swpaul#endif
25626219Swpaul
25726219Swpaul	fd = fopen(NETIDFILE, "r");
25865220Sache	if (fd == NULL) {
25926219Swpaul#ifdef YP
26026219Swpaul		res = "+";
26126219Swpaul		goto getnetidyp;
26226219Swpaul#else
26326219Swpaul		return (0);
26426219Swpaul#endif
26526219Swpaul	}
26626219Swpaul	for (;;) {
26765220Sache		if (fd == NULL)
26826219Swpaul			return (0);	/* getnetidyp brings us here */
26965220Sache		res = fgets(buf, sizeof(buf), fd);
27065220Sache		if (res == NULL) {
27126219Swpaul			fclose(fd);
27226219Swpaul			return (0);
27326219Swpaul		}
27426219Swpaul		if (res[0] == '#')
27526219Swpaul			continue;
27626219Swpaul		else if (res[0] == '+') {
27726219Swpaul#ifdef YP
27826219Swpaul	getnetidyp:
27926219Swpaul			err = yp_get_default_domain(&domain);
28026219Swpaul			if (err) {
28126219Swpaul				continue;
28226219Swpaul			}
28326219Swpaul			lookup = NULL;
28426219Swpaul			err = yp_match(domain, NETID, key,
28526219Swpaul				strlen(key), &lookup, &len);
28626219Swpaul			if (err) {
28726219Swpaul#ifdef DEBUG
28826219Swpaul				fprintf(stderr, "match failed error %d\n", err);
28926219Swpaul#endif
29026219Swpaul				continue;
29126219Swpaul			}
29226219Swpaul			lookup[len] = 0;
29326219Swpaul			strcpy(ret, lookup);
29426219Swpaul			free(lookup);
29526583Swpaul			if (fd != NULL)
29626583Swpaul				fclose(fd);
29726219Swpaul			return (2);
29826219Swpaul#else	/* YP */
29926219Swpaul#ifdef DEBUG
30026219Swpaul			fprintf(stderr,
30126219Swpaul"Bad record in %s '+' -- NIS not supported in this library copy\n",
30226219Swpaul				NETIDFILE);
30326219Swpaul#endif
30426219Swpaul			continue;
30526219Swpaul#endif	/* YP */
30626219Swpaul		} else {
30765220Sache			mkey = strsep(&res, "\t ");
30826219Swpaul			if (mkey == NULL) {
30926219Swpaul				fprintf(stderr,
31026219Swpaul		"Bad record in %s -- %s", NETIDFILE, buf);
31126219Swpaul				continue;
31226219Swpaul			}
31365220Sache			do {
31465220Sache				mval = strsep(&res, " \t#\n");
31565220Sache			} while (mval != NULL && !*mval);
31626219Swpaul			if (mval == NULL) {
31726219Swpaul				fprintf(stderr,
31826219Swpaul		"Bad record in %s val problem - %s", NETIDFILE, buf);
31926219Swpaul				continue;
32026219Swpaul			}
32126219Swpaul			if (strcmp(mkey, key) == 0) {
32226219Swpaul				strcpy(ret, mval);
32326219Swpaul				fclose(fd);
32426219Swpaul				return (1);
32526219Swpaul
32626219Swpaul			}
32726219Swpaul		}
32826219Swpaul	}
32926219Swpaul}
330