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