netnamer.c revision 92889
1236769Sobrien/* 2236769Sobrien * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3236769Sobrien * unrestricted use provided that this legend is included on all tape 4236769Sobrien * media and as a part of the software program in whole or part. Users 5236769Sobrien * may copy or modify Sun RPC without charge, but are not authorized 6236769Sobrien * to license or distribute it to anyone else except as part of a product or 7236769Sobrien * program developed by the user or with the express written consent of 8236769Sobrien * Sun Microsystems, Inc. 9236769Sobrien * 10236769Sobrien * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11236769Sobrien * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12236769Sobrien * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13236769Sobrien * 14236769Sobrien * Sun RPC is provided with no support and without any obligation on the 15236769Sobrien * part of Sun Microsystems, Inc. to assist in its use, correction, 16236769Sobrien * modification or enhancement. 17236769Sobrien * 18236769Sobrien * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19236769Sobrien * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20236769Sobrien * OR ANY PART THEREOF. 21236769Sobrien * 22236769Sobrien * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23236769Sobrien * or profits or other special, indirect and consequential damages, even if 24236769Sobrien * Sun has been advised of the possibility of such damages. 25236769Sobrien * 26236769Sobrien * Sun Microsystems, Inc. 27236769Sobrien * 2550 Garcia Avenue 28236769Sobrien * Mountain View, California 94043 29236769Sobrien * 30236769Sobrien * $FreeBSD: head/lib/libc/rpc/netnamer.c 92889 2002-03-21 18:49:23Z obrien $ 31236769Sobrien */ 32236769Sobrien#if !defined(lint) && defined(SCCSIDS) 33236769Sobrienstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; 34236769Sobrien#endif 35236769Sobrien/* 36236769Sobrien * netname utility routines convert from unix names to network names and 37236769Sobrien * vice-versa This module is operating system dependent! What we define here 38236769Sobrien * will work with any unix system that has adopted the sun NIS domain 39236769Sobrien * architecture. 40236769Sobrien */ 41236769Sobrien#include "namespace.h" 42236769Sobrien#include <sys/param.h> 43236769Sobrien#include <rpc/rpc.h> 44236769Sobrien#include <rpc/rpc_com.h> 45236769Sobrien#ifdef YP 46236769Sobrien#include <rpcsvc/yp_prot.h> 47236769Sobrien#include <rpcsvc/ypclnt.h> 48236769Sobrien#endif 49236769Sobrien#include <ctype.h> 50236769Sobrien#include <stdio.h> 51236769Sobrien#include <grp.h> 52236769Sobrien#include <pwd.h> 53236769Sobrien#include <string.h> 54236769Sobrien#include <stdlib.h> 55236769Sobrien#include <unistd.h> 56236769Sobrien#include "un-namespace.h" 57236769Sobrien 58236769Sobrienstatic char *OPSYS = "unix"; 59236769Sobrienstatic char *NETID = "netid.byname"; 60236769Sobrienstatic char *NETIDFILE = "/etc/netid"; 61236769Sobrien 62236769Sobrienstatic int getnetid __P(( char *, char * )); 63236769Sobrienstatic int _getgroups __P(( char *, gid_t * )); 64236769Sobrien 65236769Sobrien#ifndef NGROUPS 66236769Sobrien#define NGROUPS 16 67236769Sobrien#endif 68236769Sobrien 69236769Sobrien/* 70236769Sobrien * Convert network-name into unix credential 71236769Sobrien */ 72236769Sobrienint 73236769Sobriennetname2user(netname, uidp, gidp, gidlenp, gidlist) 74236769Sobrien char netname[MAXNETNAMELEN + 1]; 75 uid_t *uidp; 76 gid_t *gidp; 77 int *gidlenp; 78 gid_t *gidlist; 79{ 80 char *p; 81 int gidlen; 82 uid_t uid; 83 long luid; 84 struct passwd *pwd; 85 char val[1024]; 86 char *val1, *val2; 87 char *domain; 88 int vallen; 89 int err; 90 91 if (getnetid(netname, val)) { 92 char *res = val; 93 94 p = strsep(&res, ":"); 95 if (p == NULL) 96 return (0); 97 *uidp = (uid_t) atol(p); 98 p = strsep(&res, "\n,"); 99 if (p == NULL) { 100 return (0); 101 } 102 *gidp = (gid_t) atol(p); 103 gidlen = 0; 104 for (gidlen = 0; gidlen < NGROUPS; gidlen++) { 105 p = strsep(&res, "\n,"); 106 if (p == NULL) 107 break; 108 gidlist[gidlen] = (gid_t) atol(p); 109 } 110 *gidlenp = gidlen; 111 112 return (1); 113 } 114 val1 = strchr(netname, '.'); 115 if (val1 == NULL) 116 return (0); 117 if (strncmp(netname, OPSYS, (val1-netname))) 118 return (0); 119 val1++; 120 val2 = strchr(val1, '@'); 121 if (val2 == NULL) 122 return (0); 123 vallen = val2 - val1; 124 if (vallen > (1024 - 1)) 125 vallen = 1024 - 1; 126 (void) strncpy(val, val1, 1024); 127 val[vallen] = 0; 128 129 err = __rpc_get_default_domain(&domain); /* change to rpc */ 130 if (err) 131 return (0); 132 133 if (strcmp(val2 + 1, domain)) 134 return (0); /* wrong domain */ 135 136 if (sscanf(val, "%ld", &luid) != 1) 137 return (0); 138 uid = luid; 139 140 /* use initgroups method */ 141 pwd = getpwuid(uid); 142 if (pwd == NULL) 143 return (0); 144 *uidp = pwd->pw_uid; 145 *gidp = pwd->pw_gid; 146 *gidlenp = _getgroups(pwd->pw_name, gidlist); 147 return (1); 148} 149 150/* 151 * initgroups 152 */ 153 154static int 155_getgroups(uname, groups) 156 char *uname; 157 gid_t groups[NGROUPS]; 158{ 159 gid_t ngroups = 0; 160 struct group *grp; 161 int i; 162 int j; 163 int filter; 164 165 setgrent(); 166 while ((grp = getgrent())) { 167 for (i = 0; grp->gr_mem[i]; i++) 168 if (!strcmp(grp->gr_mem[i], uname)) { 169 if (ngroups == NGROUPS) { 170#ifdef DEBUG 171 fprintf(stderr, 172 "initgroups: %s is in too many groups\n", uname); 173#endif 174 goto toomany; 175 } 176 /* filter out duplicate group entries */ 177 filter = 0; 178 for (j = 0; j < ngroups; j++) 179 if (groups[j] == grp->gr_gid) { 180 filter++; 181 break; 182 } 183 if (!filter) 184 groups[ngroups++] = grp->gr_gid; 185 } 186 } 187toomany: 188 endgrent(); 189 return (ngroups); 190} 191 192/* 193 * Convert network-name to hostname 194 */ 195int 196netname2host(netname, hostname, hostlen) 197 char netname[MAXNETNAMELEN + 1]; 198 char *hostname; 199 int hostlen; 200{ 201 int err; 202 char valbuf[1024]; 203 char *val; 204 char *val2; 205 int vallen; 206 char *domain; 207 208 if (getnetid(netname, valbuf)) { 209 val = valbuf; 210 if ((*val == '0') && (val[1] == ':')) { 211 (void) strncpy(hostname, val + 2, hostlen); 212 return (1); 213 } 214 } 215 val = strchr(netname, '.'); 216 if (val == NULL) 217 return (0); 218 if (strncmp(netname, OPSYS, (val - netname))) 219 return (0); 220 val++; 221 val2 = strchr(val, '@'); 222 if (val2 == NULL) 223 return (0); 224 vallen = val2 - val; 225 if (vallen > (hostlen - 1)) 226 vallen = hostlen - 1; 227 (void) strncpy(hostname, val, vallen); 228 hostname[vallen] = 0; 229 230 err = __rpc_get_default_domain(&domain); /* change to rpc */ 231 if (err) 232 return (0); 233 234 if (strcmp(val2 + 1, domain)) 235 return (0); /* wrong domain */ 236 else 237 return (1); 238} 239 240/* 241 * reads the file /etc/netid looking for a + to optionally go to the 242 * network information service. 243 */ 244int 245getnetid(key, ret) 246 char *key, *ret; 247{ 248 char buf[1024]; /* big enough */ 249 char *res; 250 char *mkey; 251 char *mval; 252 FILE *fd; 253#ifdef YP 254 char *domain; 255 int err; 256 char *lookup; 257 int len; 258#endif 259 260 fd = fopen(NETIDFILE, "r"); 261 if (fd == NULL) { 262#ifdef YP 263 res = "+"; 264 goto getnetidyp; 265#else 266 return (0); 267#endif 268 } 269 for (;;) { 270 if (fd == NULL) 271 return (0); /* getnetidyp brings us here */ 272 res = fgets(buf, sizeof(buf), fd); 273 if (res == NULL) { 274 fclose(fd); 275 return (0); 276 } 277 if (res[0] == '#') 278 continue; 279 else if (res[0] == '+') { 280#ifdef YP 281 getnetidyp: 282 err = yp_get_default_domain(&domain); 283 if (err) { 284 continue; 285 } 286 lookup = NULL; 287 err = yp_match(domain, NETID, key, 288 strlen(key), &lookup, &len); 289 if (err) { 290#ifdef DEBUG 291 fprintf(stderr, "match failed error %d\n", err); 292#endif 293 continue; 294 } 295 lookup[len] = 0; 296 strcpy(ret, lookup); 297 free(lookup); 298 if (fd != NULL) 299 fclose(fd); 300 return (2); 301#else /* YP */ 302#ifdef DEBUG 303 fprintf(stderr, 304"Bad record in %s '+' -- NIS not supported in this library copy\n", 305 NETIDFILE); 306#endif 307 continue; 308#endif /* YP */ 309 } else { 310 mkey = strsep(&res, "\t "); 311 if (mkey == NULL) { 312 fprintf(stderr, 313 "Bad record in %s -- %s", NETIDFILE, buf); 314 continue; 315 } 316 do { 317 mval = strsep(&res, " \t#\n"); 318 } while (mval != NULL && !*mval); 319 if (mval == NULL) { 320 fprintf(stderr, 321 "Bad record in %s val problem - %s", NETIDFILE, buf); 322 continue; 323 } 324 if (strcmp(mkey, key) == 0) { 325 strcpy(ret, mval); 326 fclose(fd); 327 return (1); 328 329 } 330 } 331 } 332} 333