netnamer.c revision 92889
1235783Skib/* 2235783Skib * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3235783Skib * unrestricted use provided that this legend is included on all tape 4235783Skib * media and as a part of the software program in whole or part. Users 5235783Skib * may copy or modify Sun RPC without charge, but are not authorized 6235783Skib * to license or distribute it to anyone else except as part of a product or 7235783Skib * program developed by the user or with the express written consent of 8235783Skib * Sun Microsystems, Inc. 9235783Skib * 10235783Skib * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11235783Skib * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12235783Skib * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13235783Skib * 14235783Skib * Sun RPC is provided with no support and without any obligation on the 15235783Skib * part of Sun Microsystems, Inc. to assist in its use, correction, 16235783Skib * modification or enhancement. 17235783Skib * 18235783Skib * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19235783Skib * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20235783Skib * OR ANY PART THEREOF. 21235783Skib * 22235783Skib * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23235783Skib * or profits or other special, indirect and consequential damages, even if 24235783Skib * Sun has been advised of the possibility of such damages. 25235783Skib * 26235783Skib * Sun Microsystems, Inc. 27235783Skib * 2550 Garcia Avenue 28235783Skib * Mountain View, California 94043 29235783Skib * 30235783Skib * $FreeBSD: head/lib/libc/rpc/netnamer.c 92889 2002-03-21 18:49:23Z obrien $ 31235783Skib */ 32235783Skib#if !defined(lint) && defined(SCCSIDS) 33235783Skibstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; 34235783Skib#endif 35235783Skib/* 36235783Skib * netname utility routines convert from unix names to network names and 37235783Skib * vice-versa This module is operating system dependent! What we define here 38235783Skib * will work with any unix system that has adopted the sun NIS domain 39235783Skib * architecture. 40235783Skib */ 41235783Skib#include "namespace.h" 42235783Skib#include <sys/param.h> 43235783Skib#include <rpc/rpc.h> 44235783Skib#include <rpc/rpc_com.h> 45235783Skib#ifdef YP 46235783Skib#include <rpcsvc/yp_prot.h> 47235783Skib#include <rpcsvc/ypclnt.h> 48235783Skib#endif 49235783Skib#include <ctype.h> 50235783Skib#include <stdio.h> 51235783Skib#include <grp.h> 52235783Skib#include <pwd.h> 53235783Skib#include <string.h> 54235783Skib#include <stdlib.h> 55235783Skib#include <unistd.h> 56235783Skib#include "un-namespace.h" 57235783Skib 58235783Skibstatic char *OPSYS = "unix"; 59235783Skibstatic char *NETID = "netid.byname"; 60235783Skibstatic char *NETIDFILE = "/etc/netid"; 61235783Skib 62235783Skibstatic int getnetid __P(( char *, char * )); 63235783Skibstatic int _getgroups __P(( char *, gid_t * )); 64235783Skib 65235783Skib#ifndef NGROUPS 66235783Skib#define NGROUPS 16 67235783Skib#endif 68235783Skib 69235783Skib/* 70235783Skib * Convert network-name into unix credential 71235783Skib */ 72235783Skibint 73235783Skibnetname2user(netname, uidp, gidp, gidlenp, gidlist) 74235783Skib char netname[MAXNETNAMELEN + 1]; 75235783Skib uid_t *uidp; 76235783Skib gid_t *gidp; 77235783Skib int *gidlenp; 78235783Skib gid_t *gidlist; 79235783Skib{ 80235783Skib char *p; 81235783Skib int gidlen; 82235783Skib uid_t uid; 83235783Skib long luid; 84235783Skib struct passwd *pwd; 85235783Skib char val[1024]; 86235783Skib char *val1, *val2; 87235783Skib char *domain; 88235783Skib int vallen; 89235783Skib int err; 90235783Skib 91235783Skib if (getnetid(netname, val)) { 92235783Skib char *res = val; 93235783Skib 94235783Skib p = strsep(&res, ":"); 95235783Skib if (p == NULL) 96235783Skib return (0); 97235783Skib *uidp = (uid_t) atol(p); 98235783Skib p = strsep(&res, "\n,"); 99235783Skib if (p == NULL) { 100235783Skib return (0); 101235783Skib } 102235783Skib *gidp = (gid_t) atol(p); 103235783Skib gidlen = 0; 104235783Skib for (gidlen = 0; gidlen < NGROUPS; gidlen++) { 105235783Skib p = strsep(&res, "\n,"); 106235783Skib if (p == NULL) 107235783Skib break; 108235783Skib gidlist[gidlen] = (gid_t) atol(p); 109235783Skib } 110235783Skib *gidlenp = gidlen; 111235783Skib 112235783Skib return (1); 113235783Skib } 114235783Skib val1 = strchr(netname, '.'); 115235783Skib if (val1 == NULL) 116235783Skib return (0); 117235783Skib if (strncmp(netname, OPSYS, (val1-netname))) 118235783Skib return (0); 119235783Skib val1++; 120235783Skib val2 = strchr(val1, '@'); 121235783Skib if (val2 == NULL) 122235783Skib return (0); 123235783Skib vallen = val2 - val1; 124235783Skib if (vallen > (1024 - 1)) 125235783Skib vallen = 1024 - 1; 126235783Skib (void) strncpy(val, val1, 1024); 127235783Skib val[vallen] = 0; 128235783Skib 129235783Skib err = __rpc_get_default_domain(&domain); /* change to rpc */ 130235783Skib if (err) 131235783Skib return (0); 132235783Skib 133235783Skib if (strcmp(val2 + 1, domain)) 134235783Skib return (0); /* wrong domain */ 135235783Skib 136235783Skib if (sscanf(val, "%ld", &luid) != 1) 137235783Skib return (0); 138235783Skib uid = luid; 139235783Skib 140235783Skib /* use initgroups method */ 141235783Skib pwd = getpwuid(uid); 142235783Skib if (pwd == NULL) 143235783Skib return (0); 144235783Skib *uidp = pwd->pw_uid; 145235783Skib *gidp = pwd->pw_gid; 146235783Skib *gidlenp = _getgroups(pwd->pw_name, gidlist); 147235783Skib return (1); 148235783Skib} 149235783Skib 150235783Skib/* 151235783Skib * initgroups 152235783Skib */ 153235783Skib 154235783Skibstatic int 155235783Skib_getgroups(uname, groups) 156235783Skib char *uname; 157235783Skib gid_t groups[NGROUPS]; 158235783Skib{ 159235783Skib gid_t ngroups = 0; 160235783Skib struct group *grp; 161235783Skib int i; 162235783Skib int j; 163235783Skib int filter; 164235783Skib 165235783Skib setgrent(); 166235783Skib while ((grp = getgrent())) { 167235783Skib for (i = 0; grp->gr_mem[i]; i++) 168235783Skib if (!strcmp(grp->gr_mem[i], uname)) { 169235783Skib if (ngroups == NGROUPS) { 170235783Skib#ifdef DEBUG 171235783Skib fprintf(stderr, 172235783Skib "initgroups: %s is in too many groups\n", uname); 173235783Skib#endif 174235783Skib goto toomany; 175235783Skib } 176235783Skib /* filter out duplicate group entries */ 177235783Skib filter = 0; 178280369Skib for (j = 0; j < ngroups; j++) 179280369Skib if (groups[j] == grp->gr_gid) { 180280369Skib filter++; 181280369Skib break; 182280369Skib } 183280369Skib if (!filter) 184280369Skib groups[ngroups++] = grp->gr_gid; 185280369Skib } 186280369Skib } 187280369Skibtoomany: 188280369Skib endgrent(); 189280369Skib return (ngroups); 190280369Skib} 191280369Skib 192280369Skib/* 193280369Skib * Convert network-name to hostname 194280369Skib */ 195280369Skibint 196280369Skibnetname2host(netname, hostname, hostlen) 197280369Skib char netname[MAXNETNAMELEN + 1]; 198280369Skib char *hostname; 199280369Skib int hostlen; 200235783Skib{ 201235783Skib int err; 202235783Skib char valbuf[1024]; 203235783Skib char *val; 204235783Skib char *val2; 205235783Skib int vallen; 206235783Skib char *domain; 207235783Skib 208235783Skib if (getnetid(netname, valbuf)) { 209280369Skib val = valbuf; 210235783Skib if ((*val == '0') && (val[1] == ':')) { 211235783Skib (void) strncpy(hostname, val + 2, hostlen); 212235783Skib return (1); 213235783Skib } 214235783Skib } 215235783Skib val = strchr(netname, '.'); 216235783Skib if (val == NULL) 217235783Skib return (0); 218235783Skib if (strncmp(netname, OPSYS, (val - netname))) 219235783Skib return (0); 220235783Skib val++; 221235783Skib val2 = strchr(val, '@'); 222235783Skib if (val2 == NULL) 223235783Skib return (0); 224235783Skib vallen = val2 - val; 225235783Skib if (vallen > (hostlen - 1)) 226235783Skib vallen = hostlen - 1; 227235783Skib (void) strncpy(hostname, val, vallen); 228235783Skib hostname[vallen] = 0; 229235783Skib 230235783Skib err = __rpc_get_default_domain(&domain); /* change to rpc */ 231235783Skib if (err) 232235783Skib return (0); 233235783Skib 234235783Skib if (strcmp(val2 + 1, domain)) 235235783Skib return (0); /* wrong domain */ 236235783Skib else 237235783Skib return (1); 238235783Skib} 239235783Skib 240235783Skib/* 241235783Skib * reads the file /etc/netid looking for a + to optionally go to the 242235783Skib * network information service. 243235783Skib */ 244235783Skibint 245235783Skibgetnetid(key, ret) 246235783Skib char *key, *ret; 247235783Skib{ 248235783Skib char buf[1024]; /* big enough */ 249235783Skib char *res; 250235783Skib char *mkey; 251235783Skib char *mval; 252235783Skib FILE *fd; 253235783Skib#ifdef YP 254235783Skib char *domain; 255235783Skib int err; 256235783Skib char *lookup; 257235783Skib int len; 258235783Skib#endif 259235783Skib 260235783Skib fd = fopen(NETIDFILE, "r"); 261235783Skib if (fd == NULL) { 262235783Skib#ifdef YP 263235783Skib res = "+"; 264235783Skib goto getnetidyp; 265235783Skib#else 266235783Skib return (0); 267235783Skib#endif 268235783Skib } 269235783Skib for (;;) { 270280369Skib if (fd == NULL) 271280369Skib return (0); /* getnetidyp brings us here */ 272280369Skib res = fgets(buf, sizeof(buf), fd); 273280369Skib if (res == NULL) { 274280369Skib fclose(fd); 275280369Skib return (0); 276280369Skib } 277280369Skib if (res[0] == '#') 278280369Skib continue; 279280369Skib else if (res[0] == '+') { 280280369Skib#ifdef YP 281280369Skib getnetidyp: 282280369Skib err = yp_get_default_domain(&domain); 283235783Skib if (err) { 284235783Skib continue; 285235783Skib } 286235783Skib lookup = NULL; 287235783Skib err = yp_match(domain, NETID, key, 288235783Skib strlen(key), &lookup, &len); 289235783Skib if (err) { 290235783Skib#ifdef DEBUG 291235783Skib fprintf(stderr, "match failed error %d\n", err); 292235783Skib#endif 293235783Skib continue; 294235783Skib } 295280369Skib lookup[len] = 0; 296280369Skib strcpy(ret, lookup); 297280369Skib free(lookup); 298280369Skib if (fd != NULL) 299280369Skib fclose(fd); 300235783Skib return (2); 301235783Skib#else /* YP */ 302235783Skib#ifdef DEBUG 303235783Skib fprintf(stderr, 304235783Skib"Bad record in %s '+' -- NIS not supported in this library copy\n", 305235783Skib NETIDFILE); 306235783Skib#endif 307235783Skib continue; 308235783Skib#endif /* YP */ 309235783Skib } else { 310235783Skib mkey = strsep(&res, "\t "); 311235783Skib if (mkey == NULL) { 312235783Skib fprintf(stderr, 313235783Skib "Bad record in %s -- %s", NETIDFILE, buf); 314235783Skib continue; 315235783Skib } 316235783Skib do { 317235783Skib mval = strsep(&res, " \t#\n"); 318235783Skib } while (mval != NULL && !*mval); 319235783Skib if (mval == NULL) { 320235783Skib fprintf(stderr, 321235783Skib "Bad record in %s val problem - %s", NETIDFILE, buf); 322235783Skib continue; 323235783Skib } 324235783Skib if (strcmp(mkey, key) == 0) { 325235783Skib strcpy(ret, mval); 326235783Skib fclose(fd); 327235783Skib return (1); 328235783Skib 329235783Skib } 330235783Skib } 331235783Skib } 332235783Skib} 333235783Skib