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