1 /* 2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3 * unrestricted use provided that this legend is included on all tape 4 * media and as a part of the software program in whole or part. Users 5 * may copy or modify Sun RPC without charge, but are not authorized 6 * to license or distribute it to anyone else except as part of a product or 7 * program developed by the user or with the express written consent of 8 * Sun Microsystems, Inc. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 #if !defined(lint) && defined(SCCSIDS) 31 static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; 32 #endif 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 /* 36 * netname utility routines convert from unix names to network names and 37 * vice-versa This module is operating system dependent! What we define here 38 * will work with any unix system that has adopted the sun NIS domain 39 * architecture. 40 */ 41 #include "namespace.h" 42 #include <sys/param.h> 43 #include <rpc/rpc.h> 44 #include <rpc/rpc_com.h> 45 #ifdef YP 46 #include <rpcsvc/yp_prot.h> 47 #include <rpcsvc/ypclnt.h> 48 #endif 49 #include <ctype.h> 50 #include <stdio.h> 51 #include <grp.h> 52 #include <pwd.h> 53 #include <string.h> 54 #include <stdlib.h> 55 #include <unistd.h> 56 #include "un-namespace.h" 57 58 static char *OPSYS = "unix"; 59 static char *NETID = "netid.byname"; 60 static char *NETIDFILE = "/etc/netid"; 61 62 static int getnetid( char *, char * ); 63 static int _getgroups( char *, gid_t * ); 64 65 #ifndef NGROUPS 66 #define NGROUPS 16 67 #endif 68 69 /* 70 * Convert network-name into unix credential 71 */ 72 int 73 netname2user(netname, uidp, gidp, gidlenp, gidlist) 74 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 154 static 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 } 187 toomany: 188 endgrent(); 189 return (ngroups); 190 } 191 192 /* 193 * Convert network-name to hostname 194 */ 195 int 196 netname2host(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 */ 244 int 245 getnetid(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