1258578Shrs/*-
2258578Shrs * Copyright (c) 2009, Sun Microsystems, Inc.
3258578Shrs * All rights reserved.
426219Swpaul *
5258578Shrs * Redistribution and use in source and binary forms, with or without
6258578Shrs * modification, are permitted provided that the following conditions are met:
7258578Shrs * - Redistributions of source code must retain the above copyright notice,
8258578Shrs *   this list of conditions and the following disclaimer.
9258578Shrs * - Redistributions in binary form must reproduce the above copyright notice,
10258578Shrs *   this list of conditions and the following disclaimer in the documentation
11258578Shrs *   and/or other materials provided with the distribution.
12258578Shrs * - Neither the name of Sun Microsystems, Inc. nor the names of its
13258578Shrs *   contributors may be used to endorse or promote products derived
14258578Shrs *   from this software without specific prior written permission.
15258578Shrs *
16258578Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17258578Shrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18258578Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19258578Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20258578Shrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21258578Shrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22258578Shrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23258578Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24258578Shrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25258578Shrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26258578Shrs * 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
71288113Srodrigcnetname2user(char netname[MAXNETNAMELEN + 1], uid_t *uidp, gid_t *gidp,
72288113Srodrigc    int *gidlenp, gid_t *gidlist)
7326219Swpaul{
7426219Swpaul	char           *p;
7526219Swpaul	int             gidlen;
7626219Swpaul	uid_t           uid;
7737300Sbde	long		luid;
7826219Swpaul	struct passwd  *pwd;
7926219Swpaul	char            val[1024];
8026219Swpaul	char           *val1, *val2;
8126219Swpaul	char           *domain;
8226219Swpaul	int             vallen;
8326219Swpaul	int             err;
8426219Swpaul
8526219Swpaul	if (getnetid(netname, val)) {
8665220Sache		char *res = val;
8765220Sache
8865220Sache		p = strsep(&res, ":");
8926219Swpaul		if (p == NULL)
9026219Swpaul			return (0);
9165220Sache		*uidp = (uid_t) atol(p);
9265220Sache		p = strsep(&res, "\n,");
9326219Swpaul		if (p == NULL) {
9426219Swpaul			return (0);
9526219Swpaul		}
9665220Sache		*gidp = (gid_t) atol(p);
97194498Sbrooks		for (gidlen = 0; gidlen < NGRPS; gidlen++) {
9865220Sache			p = strsep(&res, "\n,");
9926219Swpaul			if (p == NULL)
10026219Swpaul				break;
10126219Swpaul			gidlist[gidlen] = (gid_t) atol(p);
10226219Swpaul		}
10326219Swpaul		*gidlenp = gidlen;
10426219Swpaul
10526219Swpaul		return (1);
10626219Swpaul	}
10726219Swpaul	val1 = strchr(netname, '.');
10826219Swpaul	if (val1 == NULL)
10926219Swpaul		return (0);
11026219Swpaul	if (strncmp(netname, OPSYS, (val1-netname)))
11126219Swpaul		return (0);
11226219Swpaul	val1++;
11326219Swpaul	val2 = strchr(val1, '@');
11426219Swpaul	if (val2 == NULL)
11526219Swpaul		return (0);
11626219Swpaul	vallen = val2 - val1;
11726219Swpaul	if (vallen > (1024 - 1))
11826219Swpaul		vallen = 1024 - 1;
11926219Swpaul	(void) strncpy(val, val1, 1024);
12026219Swpaul	val[vallen] = 0;
12126219Swpaul
12290271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
12326219Swpaul	if (err)
12426219Swpaul		return (0);
12526219Swpaul
12626219Swpaul	if (strcmp(val2 + 1, domain))
12726219Swpaul		return (0);	/* wrong domain */
12826219Swpaul
12937300Sbde	if (sscanf(val, "%ld", &luid) != 1)
13026219Swpaul		return (0);
13137300Sbde	uid = luid;
13237300Sbde
13326219Swpaul	/* use initgroups method */
13426219Swpaul	pwd = getpwuid(uid);
13526219Swpaul	if (pwd == NULL)
13626219Swpaul		return (0);
13726219Swpaul	*uidp = pwd->pw_uid;
13826219Swpaul	*gidp = pwd->pw_gid;
13926219Swpaul	*gidlenp = _getgroups(pwd->pw_name, gidlist);
14026219Swpaul	return (1);
14126219Swpaul}
14226219Swpaul
14326219Swpaul/*
14426219Swpaul * initgroups
14526219Swpaul */
14626219Swpaul
14726219Swpaulstatic int
148288113Srodrigc_getgroups(char *uname, gid_t groups[NGRPS])
14926219Swpaul{
15026219Swpaul	gid_t           ngroups = 0;
15192889Sobrien	struct group *grp;
15292889Sobrien	int    i;
15392889Sobrien	int    j;
15426219Swpaul	int             filter;
15526219Swpaul
15626219Swpaul	setgrent();
15726219Swpaul	while ((grp = getgrent())) {
15826219Swpaul		for (i = 0; grp->gr_mem[i]; i++)
15926219Swpaul			if (!strcmp(grp->gr_mem[i], uname)) {
160194498Sbrooks				if (ngroups == NGRPS) {
16126219Swpaul#ifdef DEBUG
16226219Swpaul					fprintf(stderr,
16326219Swpaul				"initgroups: %s is in too many groups\n", uname);
16426219Swpaul#endif
16526219Swpaul					goto toomany;
16626219Swpaul				}
16726219Swpaul				/* filter out duplicate group entries */
16826219Swpaul				filter = 0;
16926219Swpaul				for (j = 0; j < ngroups; j++)
17026219Swpaul					if (groups[j] == grp->gr_gid) {
17126219Swpaul						filter++;
17226219Swpaul						break;
17326219Swpaul					}
17426219Swpaul				if (!filter)
17526219Swpaul					groups[ngroups++] = grp->gr_gid;
17626219Swpaul			}
17726219Swpaul	}
17826219Swpaultoomany:
17926219Swpaul	endgrent();
18026219Swpaul	return (ngroups);
18126219Swpaul}
18226219Swpaul
18326219Swpaul/*
18426219Swpaul * Convert network-name to hostname
18526219Swpaul */
18626219Swpaulint
187288113Srodrigcnetname2host(char netname[MAXNETNAMELEN + 1], char *hostname, int hostlen)
18826219Swpaul{
18926219Swpaul	int             err;
19026219Swpaul	char            valbuf[1024];
19126219Swpaul	char           *val;
19226219Swpaul	char           *val2;
19326219Swpaul	int             vallen;
19426219Swpaul	char           *domain;
19526219Swpaul
19626219Swpaul	if (getnetid(netname, valbuf)) {
19726219Swpaul		val = valbuf;
19826219Swpaul		if ((*val == '0') && (val[1] == ':')) {
19926219Swpaul			(void) strncpy(hostname, val + 2, hostlen);
20026219Swpaul			return (1);
20126219Swpaul		}
20226219Swpaul	}
20326219Swpaul	val = strchr(netname, '.');
20426219Swpaul	if (val == NULL)
20526219Swpaul		return (0);
20626219Swpaul	if (strncmp(netname, OPSYS, (val - netname)))
20726219Swpaul		return (0);
20826219Swpaul	val++;
20926219Swpaul	val2 = strchr(val, '@');
21026219Swpaul	if (val2 == NULL)
21126219Swpaul		return (0);
21226219Swpaul	vallen = val2 - val;
21326219Swpaul	if (vallen > (hostlen - 1))
21426219Swpaul		vallen = hostlen - 1;
21526219Swpaul	(void) strncpy(hostname, val, vallen);
21626219Swpaul	hostname[vallen] = 0;
21726219Swpaul
21890271Salfred	err = __rpc_get_default_domain(&domain);	/* change to rpc */
21926219Swpaul	if (err)
22026219Swpaul		return (0);
22126219Swpaul
22226219Swpaul	if (strcmp(val2 + 1, domain))
22326219Swpaul		return (0);	/* wrong domain */
22426219Swpaul	else
22526219Swpaul		return (1);
22626219Swpaul}
22726219Swpaul
22826219Swpaul/*
22926219Swpaul * reads the file /etc/netid looking for a + to optionally go to the
23026219Swpaul * network information service.
23126219Swpaul */
23226219Swpaulint
233288113Srodrigcgetnetid(char *key, char *ret)
23426219Swpaul{
23526219Swpaul	char            buf[1024];	/* big enough */
23626219Swpaul	char           *res;
23726219Swpaul	char           *mkey;
23826219Swpaul	char           *mval;
23926219Swpaul	FILE           *fd;
24026219Swpaul#ifdef YP
24126219Swpaul	char           *domain;
24226219Swpaul	int             err;
24326219Swpaul	char           *lookup;
24426219Swpaul	int             len;
24526219Swpaul#endif
246300387Sngie	int rv;
24726219Swpaul
248300387Sngie	rv = 0;
249300387Sngie
25026219Swpaul	fd = fopen(NETIDFILE, "r");
25165220Sache	if (fd == NULL) {
25226219Swpaul#ifdef YP
25326219Swpaul		res = "+";
25426219Swpaul		goto getnetidyp;
25526219Swpaul#else
25626219Swpaul		return (0);
25726219Swpaul#endif
25826219Swpaul	}
259300387Sngie	while (fd != NULL) {
26065220Sache		res = fgets(buf, sizeof(buf), fd);
26165220Sache		if (res == NULL) {
262300387Sngie			rv = 0;
263300387Sngie			goto done;
26426219Swpaul		}
26526219Swpaul		if (res[0] == '#')
26626219Swpaul			continue;
26726219Swpaul		else if (res[0] == '+') {
26826219Swpaul#ifdef YP
26926219Swpaul	getnetidyp:
27026219Swpaul			err = yp_get_default_domain(&domain);
27126219Swpaul			if (err) {
27226219Swpaul				continue;
27326219Swpaul			}
27426219Swpaul			lookup = NULL;
27526219Swpaul			err = yp_match(domain, NETID, key,
27626219Swpaul				strlen(key), &lookup, &len);
27726219Swpaul			if (err) {
27826219Swpaul#ifdef DEBUG
27926219Swpaul				fprintf(stderr, "match failed error %d\n", err);
28026219Swpaul#endif
28126219Swpaul				continue;
28226219Swpaul			}
28326219Swpaul			lookup[len] = 0;
28426219Swpaul			strcpy(ret, lookup);
28526219Swpaul			free(lookup);
286300387Sngie			rv = 2;
287300387Sngie			goto done;
28826219Swpaul#else	/* YP */
28926219Swpaul#ifdef DEBUG
29026219Swpaul			fprintf(stderr,
29126219Swpaul"Bad record in %s '+' -- NIS not supported in this library copy\n",
29226219Swpaul				NETIDFILE);
29326219Swpaul#endif
29426219Swpaul			continue;
29526219Swpaul#endif	/* YP */
29626219Swpaul		} else {
29765220Sache			mkey = strsep(&res, "\t ");
29826219Swpaul			if (mkey == NULL) {
29926219Swpaul				fprintf(stderr,
30026219Swpaul		"Bad record in %s -- %s", NETIDFILE, buf);
30126219Swpaul				continue;
30226219Swpaul			}
30365220Sache			do {
30465220Sache				mval = strsep(&res, " \t#\n");
30565220Sache			} while (mval != NULL && !*mval);
30626219Swpaul			if (mval == NULL) {
30726219Swpaul				fprintf(stderr,
30826219Swpaul		"Bad record in %s val problem - %s", NETIDFILE, buf);
30926219Swpaul				continue;
31026219Swpaul			}
31126219Swpaul			if (strcmp(mkey, key) == 0) {
31226219Swpaul				strcpy(ret, mval);
313300387Sngie				rv = 1;
314300387Sngie				goto done;
31526219Swpaul			}
31626219Swpaul		}
31726219Swpaul	}
318300387Sngie
319300387Sngiedone:
320300387Sngie	if (fd != NULL)
321300387Sngie		fclose(fd);
322300387Sngie	return (rv);
32326219Swpaul}
324