1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1990 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" /* c2 secure */ 28 29 #include <stdio.h> 30 #include <grp.h> 31 #include <grpadj.h> 32 #include <rpcsvc/ypclnt.h> 33 34 extern void rewind(); 35 extern long strtol(); 36 extern int strlen(); 37 extern int strcmp(); 38 extern int fclose(); 39 extern char *strcpy(); 40 extern char *calloc(); 41 extern char *malloc(); 42 43 void setgraent(), endgraent(); 44 45 static struct gradata { 46 char *domain; 47 FILE *grfa; 48 char *yp; 49 int yplen; 50 char *oldyp; 51 int oldyplen; 52 struct list { 53 char *name; 54 struct list *nxt; 55 } *minuslist; /* list of - items */ 56 struct group_adjunct interpgra; 57 char interpline[BUFSIZ+1]; 58 struct group_adjunct *sv; 59 } *gradata, *_gradata(); 60 61 static char *GROUPADJ = "/etc/security/group.adjunct"; 62 static struct group_adjunct *interpret(); 63 static struct group_adjunct *interpretwithsave(); 64 static struct group_adjunct *save(); 65 static struct group_adjunct *getnamefromyellow(); 66 static struct group_adjunct *getgidfromyellow(); 67 68 static struct gradata * 69 _gradata() 70 { 71 register struct gradata *g = gradata; 72 73 if (g == 0) { 74 g = (struct gradata *)calloc(1, sizeof (struct gradata)); 75 gradata = g; 76 } 77 return (g); 78 } 79 80 #ifdef NOT_DEFINED 81 struct group_adjunct * 82 getgragid(gid) 83 register gid; 84 { 85 struct group *getgrgid(); 86 struct group *gr; 87 88 if ((gr = getgrgid(gid)) == NULL) 89 return NULL; 90 return (getgranam(gr->gr_name)); 91 } 92 #endif NOT_DEFINED 93 94 struct group_adjunct * 95 getgranam(name) 96 register char *name; 97 { 98 register struct gradata *g = _gradata(); 99 struct group_adjunct *gra; 100 char line[BUFSIZ+1]; 101 102 setgraent(); 103 if (g == 0) 104 return (0); 105 if (!g->grfa) 106 return NULL; 107 while (fgets(line, BUFSIZ, g->grfa) != NULL) { 108 if ((gra = interpret(line, strlen(line))) == NULL) 109 continue; 110 if (matchname(line, &gra, name)) { 111 endgraent(); 112 return (gra); 113 } 114 } 115 endgraent(); 116 return (NULL); 117 } 118 119 void 120 setgraent() 121 { 122 register struct gradata *g = _gradata(); 123 124 if (g == NULL) 125 return; 126 if (g->domain == NULL) 127 (void) yp_get_default_domain(&g->domain); 128 if (!g->grfa) 129 g->grfa = fopen(GROUPADJ, "r"); 130 else 131 rewind(g->grfa); 132 if (g->yp) 133 free(g->yp); 134 g->yp = NULL; 135 freeminuslist(); 136 } 137 138 void 139 endgraent() 140 { 141 register struct gradata *g = _gradata(); 142 143 if (g == 0) 144 return; 145 if (g->grfa) { 146 (void) fclose(g->grfa); 147 g->grfa = NULL; 148 } 149 if (g->yp) 150 free(g->yp); 151 g->yp = NULL; 152 freeminuslist(); 153 } 154 155 struct group_adjunct * 156 fgetgraent(f) 157 FILE *f; 158 { 159 char line1[BUFSIZ+1]; 160 161 if(fgets(line1, BUFSIZ, f) == NULL) 162 return(NULL); 163 return (interpret(line1, strlen(line1))); 164 } 165 166 static char * 167 grskip(p,c) 168 register char *p; 169 register c; 170 { 171 while(*p && *p != c && *p != '\n') ++p; 172 if (*p == '\n') 173 *p = '\0'; 174 else if (*p != '\0') 175 *p++ = '\0'; 176 return(p); 177 } 178 179 struct group_adjunct * 180 getgraent() 181 { 182 register struct gradata *g = _gradata(); 183 char line1[BUFSIZ+1]; 184 static struct group_adjunct *savegra; 185 struct group_adjunct *gra; 186 187 if (g == 0) 188 return (0); 189 if (g->domain == NULL) { 190 (void) yp_get_default_domain(&g->domain); 191 } 192 if(!g->grfa && !(g->grfa = fopen(GROUPADJ, "r"))) 193 return(NULL); 194 again: 195 if (g->yp) { 196 gra = interpretwithsave(g->yp, g->yplen, savegra); 197 free(g->yp); 198 if (gra == NULL) 199 return(NULL); 200 getnextfromyellow(); 201 if (onminuslist(gra)) 202 goto again; 203 else 204 return (gra); 205 } 206 else if (fgets(line1, BUFSIZ, g->grfa) == NULL) 207 return(NULL); 208 if ((gra = interpret(line1, strlen(line1))) == NULL) 209 return(NULL); 210 switch(line1[0]) { 211 case '+': 212 if (strcmp(gra->gra_name, "+") == 0) { 213 getfirstfromyellow(); 214 savegra = save(gra); 215 goto again; 216 } 217 /* 218 * else look up this entry in NIS 219 */ 220 savegra = save(gra); 221 gra = getnamefromyellow(gra->gra_name+1, savegra); 222 if (gra == NULL) 223 goto again; 224 else if (onminuslist(gra)) 225 goto again; 226 else 227 return (gra); 228 break; 229 case '-': 230 addtominuslist(gra->gra_name+1); 231 goto again; 232 break; 233 default: 234 if (onminuslist(gra)) 235 goto again; 236 return (gra); 237 break; 238 } 239 /*NOTREACHED*/ 240 } 241 242 static struct group_adjunct * 243 interpret(val, len) 244 char *val; 245 { 246 register struct gradata *g = _gradata(); 247 register char *p; 248 249 if (g == 0) 250 return (0); 251 strncpy(g->interpline, val, len); 252 p = g->interpline; 253 g->interpline[len] = '\n'; 254 g->interpline[len+1] = 0; 255 g->interpgra.gra_name = p; 256 p = grskip(p,':'); 257 if (strcmp(g->interpgra.gra_name, "+") == 0) { 258 /* we are going to the NIS - fix the 259 * rest of the struct as much as is needed 260 */ 261 g->interpgra.gra_passwd = ""; 262 return (&g->interpgra); 263 } 264 g->interpgra.gra_passwd = p; 265 while(*p && *p != '\n') p++; 266 *p = '\0'; 267 return (&g->interpgra); 268 } 269 270 static 271 freeminuslist() { 272 register struct gradata *g = _gradata(); 273 struct list *ls; 274 275 if (g == 0) 276 return; 277 for (ls = g->minuslist; ls != NULL; ls = ls->nxt) { 278 free(ls->name); 279 free(ls); 280 } 281 g->minuslist = NULL; 282 } 283 284 static struct group_adjunct * 285 interpretwithsave(val, len, savegra) 286 char *val; 287 struct group_adjunct *savegra; 288 { 289 register struct gradata *g = _gradata(); 290 struct group_adjunct *gra; 291 292 if (g == 0) 293 return (0); 294 if ((gra = interpret(val, len)) == NULL) 295 return (NULL); 296 if (savegra->gra_passwd && *savegra->gra_passwd) 297 gra->gra_passwd = savegra->gra_passwd; 298 return (gra); 299 } 300 301 static 302 onminuslist(gra) 303 struct group_adjunct *gra; 304 { 305 register struct gradata *g = _gradata(); 306 struct list *ls; 307 register char *nm; 308 309 if (g == 0) 310 return 0; 311 nm = gra->gra_name; 312 for (ls = g->minuslist; ls != NULL; ls = ls->nxt) 313 if (strcmp(ls->name, nm) == 0) 314 return 1; 315 return 0; 316 } 317 318 static 319 getnextfromyellow() 320 { 321 register struct gradata *g = _gradata(); 322 int reason; 323 char *key = NULL; 324 int keylen; 325 326 if (g == 0) 327 return; 328 if (reason = yp_next(g->domain, "group.adjunct.byname", 329 g->oldyp, g->oldyplen, &key, &keylen, 330 &g->yp, &g->yplen)) { 331 #ifdef DEBUG 332 fprintf(stderr, "reason yp_next failed is %d\n", reason); 333 #endif 334 g->yp = NULL; 335 } 336 if (g->oldyp) 337 free(g->oldyp); 338 g->oldyp = key; 339 g->oldyplen = keylen; 340 } 341 342 static 343 getfirstfromyellow() 344 { 345 register struct gradata *g = _gradata(); 346 int reason; 347 char *key = NULL; 348 int keylen; 349 350 if (g == 0) 351 return; 352 if (reason = yp_first(g->domain, "group.adjunct.byname", 353 &key, &keylen, &g->yp, &g->yplen)) { 354 #ifdef DEBUG 355 fprintf(stderr, "reason yp_first failed is %d\n", reason); 356 #endif 357 g->yp = NULL; 358 } 359 if (g->oldyp) 360 free(g->oldyp); 361 g->oldyp = key; 362 g->oldyplen = keylen; 363 } 364 365 static struct group_adjunct * 366 getnamefromyellow(name, savegra) 367 char *name; 368 struct group_adjunct *savegra; 369 { 370 register struct gradata *g = _gradata(); 371 struct group_adjunct *gra; 372 int reason; 373 char *val; 374 int vallen; 375 376 if (g == 0) 377 return (NULL); 378 if (reason = yp_match(g->domain, "group.adjunct.byname", 379 name, strlen(name), &val, &vallen)) { 380 #ifdef DEBUG 381 fprintf(stderr, "reason yp_next failed is %d\n", reason); 382 #endif 383 return NULL; 384 } 385 else { 386 gra = interpret(val, vallen); 387 free(val); 388 if (gra == NULL) 389 return NULL; 390 if (savegra->gra_passwd && *savegra->gra_passwd) 391 gra->gra_passwd = savegra->gra_passwd; 392 return gra; 393 } 394 } 395 396 static 397 addtominuslist(name) 398 char *name; 399 { 400 register struct gradata *g = _gradata(); 401 struct list *ls; 402 char *buf; 403 404 if (g == 0) 405 return; 406 ls = (struct list *)malloc(sizeof(struct list)); 407 buf = (char *)malloc(strlen(name) + 1); 408 (void) strcpy(buf, name); 409 ls->name = buf; 410 ls->nxt = g->minuslist; 411 g->minuslist = ls; 412 } 413 414 /* 415 * save away psswd field, which is the only 416 * one which can be specified in a local + entry to override the 417 * value in the NIS 418 */ 419 static struct group_adjunct * 420 save(gra) 421 struct group_adjunct *gra; 422 { 423 register struct gradata *g = _gradata(); 424 425 if (g == 0) 426 return 0; 427 /* 428 * free up stuff from last time around 429 */ 430 if (g->sv) { 431 free(g->sv->gra_passwd); 432 free(g->sv); 433 } 434 g->sv = (struct group_adjunct *)calloc(1, sizeof(struct group_adjunct)); 435 g->sv->gra_passwd = (char *)malloc(strlen(gra->gra_passwd) + 1); 436 (void) strcpy(g->sv->gra_passwd, gra->gra_passwd); 437 return g->sv; 438 } 439 440 static 441 matchname(line1, grap, name) 442 char line1[]; 443 struct group_adjunct **grap; 444 char *name; 445 { 446 struct group_adjunct *savegra; 447 struct group_adjunct *gra = *grap; 448 449 switch(line1[0]) { 450 case '+': 451 if (strcmp(gra->gra_name, "+") == 0) { 452 savegra = save(gra); 453 gra = getnamefromyellow(name, savegra); 454 if (gra) { 455 *grap = gra; 456 return 1; 457 } 458 else 459 return 0; 460 } 461 if (strcmp(gra->gra_name+1, name) == 0) { 462 savegra = save(gra); 463 gra = getnamefromyellow(gra->gra_name+1, savegra); 464 if (gra) { 465 *grap = gra; 466 return 1; 467 } 468 else 469 return 0; 470 } 471 break; 472 case '-': 473 if (strcmp(gra->gra_name+1, name) == 0) { 474 *grap = NULL; 475 return 1; 476 } 477 break; 478 default: 479 if (strcmp(gra->gra_name, name) == 0) 480 return 1; 481 } 482 return 0; 483 } 484