ncgrpw.c revision 9781:ccf49524d5dc
1292932Sdim/* 2292932Sdim * CDDL HEADER START 3292932Sdim * 4292932Sdim * The contents of this file are subject to the terms of the 5292932Sdim * Common Development and Distribution License (the "License"). 6292932Sdim * You may not use this file except in compliance with the License. 7292932Sdim * 8292932Sdim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9292932Sdim * or http://www.opensolaris.org/os/licensing. 10292932Sdim * See the License for the specific language governing permissions 11292932Sdim * and limitations under the License. 12292932Sdim * 13292932Sdim * When distributing Covered Code, include this CDDL HEADER in each 14292932Sdim * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15292932Sdim * If applicable, add the following below this CDDL HEADER, with the 16292932Sdim * fields enclosed by brackets "[]" replaced with your own identifying 17292932Sdim * information: Portions Copyright [yyyy] [name of copyright owner] 18292932Sdim * 19292932Sdim * CDDL HEADER END 20292932Sdim */ 21292932Sdim 22292932Sdim/* 23292932Sdim * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24292932Sdim * Use is subject to license terms. 25292932Sdim */ 26292932Sdim 27292932Sdim 28292932Sdim/* 29292932Sdim * This module fetches group and passwd structs for the caller. It 30292932Sdim * uses a hash table to speed up retrieval of repeated entries. If 31292932Sdim * the attempts to initialize the hash tables fail, this just 32292932Sdim * continues the slow way. 33292932Sdim */ 34292932Sdim 35292932Sdim#include <pwd.h> 36292932Sdim#include <grp.h> 37292932Sdim#include <string.h> 38292932Sdim#include <stdio.h> 39292932Sdim#include <stdlib.h> 40292932Sdim#include <unistd.h> 41292932Sdim#include "pkglib.h" 42292932Sdim#include "pkglocale.h" 43292932Sdim#include "nhash.h" 44292932Sdim 45292932Sdim#define HASHSIZE 151 46292932Sdim#define BSZ 4 47292932Sdim 48292932Sdim#define ERR_DUPFAIL "%s: strdup(%s) failed.\n" 49292932Sdim#define ERR_ADDFAIL "%s: add_cache() failed.\n" 50292932Sdim#define ERR_BADMEMB "%s: %s in \"%s\" %s structure is invalid.\n" 51292932Sdim#define ERR_NOGRP "dup_gr_ent(): no group entry provided.\n" 52292932Sdim#define ERR_NOPWD "dup_pw_ent(): no passwd entry provided.\n" 53292932Sdim#define ERR_NOINIT "%s: init_cache() failed.\n" 54292932Sdim#define ERR_MALLOC "%s: malloc(%d) failed for %s.\n" 55292932Sdim 56292932Sdimstatic Cache *pwnam_cache = (Cache *) NULL; 57292932Sdimstatic Cache *grnam_cache = (Cache *) NULL; 58292932Sdimstatic Cache *pwuid_cache = (Cache *) NULL; 59292932Sdimstatic Cache *grgid_cache = (Cache *) NULL; 60292932Sdim 61292932Sdimstatic int dup_gr_ent(struct group *grp); 62292932Sdimstatic int dup_pw_ent(struct passwd *pwp); 63292932Sdim 64292932Sdim/* 65292932Sdim * These indicate whether the hash table has been initialized for the four 66292932Sdim * categories. 67292932Sdim */ 68292932Sdimstatic int is_a_pwnam_cache; 69292932Sdimstatic int is_a_grnam_cache; 70292932Sdimstatic int is_a_pwuid_cache; 71292932Sdimstatic int is_a_grgid_cache; 72292932Sdim 73292932Sdimextern char *get_install_root(void); 74292932Sdim 75292932Sdim/* 76292932Sdim * If there's a grnam cache, then update it with this new 77292932Sdim * group, otherwise, skip it. 78292932Sdim */ 79292932Sdimstatic Item * 80292932Sdimcache_alloc(char *fname, int len, size_t struct_size) 81292932Sdim{ 82292932Sdim Item *itemp; 83292932Sdim 84292932Sdim /* 85292932Sdim * Allocate space for the Item pointer, key and data. 86292932Sdim */ 87292932Sdim if ((itemp = (Item *) malloc(sizeof (*itemp))) == 88292932Sdim Null_Item) { 89292932Sdim (void) fprintf(stderr, 90292932Sdim pkg_gt(ERR_MALLOC), fname, 91292932Sdim sizeof (*itemp), "itemp"); 92292932Sdim } else if ((itemp->key = (char *)malloc(len)) == NULL) { 93292932Sdim (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, len, 94292932Sdim "itemp->key"); 95292932Sdim free(itemp); 96292932Sdim } else if ((itemp->data = malloc(struct_size)) == NULL) { 97292932Sdim (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, 98292932Sdim struct_size, "itemp->data"); 99292932Sdim free(itemp->key); 100292932Sdim free(itemp); 101292932Sdim } else { 102292932Sdim /* Set length parameters. */ 103292932Sdim itemp->keyl = len; 104292932Sdim itemp->datal = struct_size; 105292932Sdim 106292932Sdim return (itemp); 107292932Sdim } 108292932Sdim 109292932Sdim return ((Item *) NULL); 110292932Sdim} 111292932Sdim 112292932Sdim/* Get the required group structure based upon the group name. */ 113292932Sdimstruct group * 114292932Sdimcgrnam(char *nam) 115292932Sdim{ 116292932Sdim struct group *grp; 117292932Sdim Item *itemp; 118292932Sdim int len; 119292932Sdim static int cache_failed; 120292932Sdim 121292932Sdim /* Attempt to initialize the grname cache. */ 122292932Sdim if (!is_a_grnam_cache && !cache_failed) { 123292932Sdim if (init_cache(&grnam_cache, HASHSIZE, BSZ, 124292932Sdim (int (*)())NULL, (int (*)())NULL) == -1) { 125292932Sdim (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrnam()"); 126292932Sdim grnam_cache = (Cache *) NULL; 127292932Sdim cache_failed = 1; 128292932Sdim } else 129292932Sdim is_a_grnam_cache = 1; 130292932Sdim } 131292932Sdim 132292932Sdim len = strlen(nam) + 1; 133292932Sdim 134292932Sdim /* First look in the cache. Failing that, do it the hard way. */ 135292932Sdim if ((itemp = lookup_cache(grnam_cache, nam, len)) == Null_Item) { 136292932Sdim 137292932Sdim /* Get the group by name. */ 138292932Sdim if ((grp = clgrnam(nam)) != NULL || 139292932Sdim (grp = getgrnam(nam)) != NULL) { 140292932Sdim /* A group by that name exists on this machine. */ 141292932Sdim if (dup_gr_ent(grp)) 142292932Sdim /* 143292932Sdim * Effectively no such group since struct 144292932Sdim * couldn't be duplicated. 145292932Sdim */ 146292932Sdim grp = (struct group *)NULL; 147292932Sdim /* 148292932Sdim * If there's a grnam cache, then update it with this 149292932Sdim * new group, otherwise, skip it. 150292932Sdim */ 151292932Sdim else if (is_a_grnam_cache) { 152292932Sdim if ((itemp = cache_alloc("cgrnam()", len, 153292932Sdim sizeof (struct group))) != Null_Item) { 154292932Sdim /* 155292932Sdim * With that allocated, insert the 156292932Sdim * group name as key and set the key 157292932Sdim * length. 158292932Sdim */ 159292932Sdim (void) memmove(itemp->key, nam, len); 160292932Sdim 161292932Sdim /* 162292932Sdim * Insert the data associated with 163292932Sdim * the key and the data length. 164292932Sdim */ 165292932Sdim (void) memmove(itemp->data, grp, 166292932Sdim sizeof (struct group)); 167292932Sdim 168292932Sdim /* Insert the Item into the cache. */ 169292932Sdim if (add_cache(grnam_cache, itemp) == -1) 170292932Sdim (void) fprintf(stderr, 171292932Sdim pkg_gt(ERR_ADDFAIL), 172292932Sdim "cgrnam()"); 173292932Sdim } 174292932Sdim } 175292932Sdim } 176292932Sdim return (grp); 177292932Sdim } else /* Found it in the cache. */ 178292932Sdim return ((struct group *)itemp->data); 179292932Sdim} 180292932Sdim 181292932Sdimstruct passwd * 182292932Sdimcpwnam(char *nam) 183292932Sdim{ 184292932Sdim struct passwd *pwd; 185292932Sdim Item *itemp; 186292932Sdim int len; 187292932Sdim static int cache_failed; 188292932Sdim 189292932Sdim if (!is_a_pwnam_cache && !cache_failed) { 190292932Sdim if (init_cache(&pwnam_cache, HASHSIZE, BSZ, 191292932Sdim (int (*)())NULL, (int (*)())NULL) == -1) { 192292932Sdim (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cpwnam()"); 193292932Sdim pwnam_cache = (Cache *) NULL; 194292932Sdim cache_failed = 1; 195292932Sdim } else 196292932Sdim is_a_pwnam_cache = 1; 197292932Sdim } 198292932Sdim 199292932Sdim len = strlen(nam) + 1; 200292932Sdim 201292932Sdim /* First look in the cache. Failing that, do it the hard way. */ 202292932Sdim if ((itemp = lookup_cache(pwnam_cache, nam, len)) == Null_Item) { 203292932Sdim 204292932Sdim /* Get the passwd by name. */ 205292932Sdim if ((pwd = clpwnam(nam)) != NULL || 206292932Sdim (pwd = getpwnam(nam)) != NULL) { 207292932Sdim /* A passwd by that name exists on this machine. */ 208292932Sdim if (dup_pw_ent(pwd)) 209292932Sdim /* 210292932Sdim * Effectively no such passwd since struct 211292932Sdim * couldn't be duplicated. 212292932Sdim */ 213292932Sdim pwd = (struct passwd *)NULL; 214292932Sdim /* 215292932Sdim * If there's a pwnam cache, then update it with this 216292932Sdim * new passwd, otherwise, skip it. 217292932Sdim */ 218292932Sdim else if (is_a_pwnam_cache) { 219292932Sdim /* 220292932Sdim * Allocate space for the Item pointer, key 221292932Sdim * and data. 222292932Sdim */ 223292932Sdim if ((itemp = cache_alloc("cpwnam()", len, 224292932Sdim sizeof (struct passwd))) != Null_Item) { 225292932Sdim /* 226292932Sdim * With that allocated, insert the 227292932Sdim * group name as key and set the key 228292932Sdim * length. 229292932Sdim */ 230292932Sdim (void) memmove(itemp->key, nam, len); 231292932Sdim 232292932Sdim /* 233292932Sdim * Insert the data associated with 234292932Sdim * the key and the data length. 235292932Sdim */ 236292932Sdim (void) memmove(itemp->data, pwd, 237292932Sdim sizeof (struct passwd)); 238292932Sdim 239292932Sdim if (add_cache(pwnam_cache, itemp) == -1) 240292932Sdim (void) fprintf(stderr, 241292932Sdim pkg_gt(ERR_ADDFAIL), 242292932Sdim "cpwnam()"); 243292932Sdim } 244292932Sdim } 245292932Sdim } 246292932Sdim return (pwd); 247292932Sdim } else /* Found it in the cache. */ 248292932Sdim return ((struct passwd *)itemp->data); 249292932Sdim} 250292932Sdim 251292932Sdimstatic int 252292932Sdimuid_hash(void *datap, int datalen, int hsz) 253292932Sdim{ 254292932Sdim#ifdef lint 255292932Sdim int i = datalen; 256292932Sdim datalen = i; 257292932Sdim#endif /* lint */ 258292932Sdim 259292932Sdim return (*((uid_t *)datap) % hsz); 260292932Sdim} 261292932Sdim 262292932Sdimstatic int 263292932Sdimuid_comp(void *datap1, void *datap2, int datalen) 264292932Sdim{ 265292932Sdim#ifdef lint 266292932Sdim int i = datalen; 267292932Sdim datalen = i; 268292932Sdim#endif /* lint */ 269292932Sdim 270292932Sdim return (*((uid_t *)datap1) - *((uid_t *)datap2)); 271292932Sdim} 272292932Sdim 273292932Sdimstruct group * 274292932Sdimcgrgid(gid_t gid) 275292932Sdim{ 276292932Sdim struct group *grp; 277292932Sdim Item *itemp; 278292932Sdim int len; 279292932Sdim static int cache_failed; 280292932Sdim 281292932Sdim if (!is_a_grgid_cache && !cache_failed) { 282292932Sdim if (init_cache(&grgid_cache, HASHSIZE, BSZ, 283292932Sdim uid_hash, uid_comp) == -1) { 284292932Sdim (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrgid()"); 285292932Sdim grgid_cache = (Cache *) NULL; 286292932Sdim cache_failed = 1; 287292932Sdim } else 288292932Sdim is_a_grgid_cache = 1; 289292932Sdim } 290292932Sdim 291292932Sdim len = sizeof (uid_t); 292292932Sdim 293292932Sdim /* First look in the cache. Failing that, do it the hard way. */ 294292932Sdim if ((itemp = lookup_cache(grgid_cache, &gid, len)) == Null_Item) { 295292932Sdim if ((grp = clgrgid(gid)) != NULL || 296292932Sdim (grp = getgrgid(gid)) != NULL) { 297292932Sdim /* A group by that number exists on this machine. */ 298292932Sdim if (dup_gr_ent(grp)) 299292932Sdim /* 300292932Sdim * Effectively no such group since struct 301292932Sdim * couldn't be duplicated. 302292932Sdim */ 303292932Sdim grp = (struct group *)NULL; 304292932Sdim /* 305292932Sdim * If there's a grnam cache, then update it with this 306292932Sdim * new group, otherwise, skip it. 307292932Sdim */ 308292932Sdim else if (is_a_grgid_cache) { 309292932Sdim if ((itemp = cache_alloc("cgrgid()", len, 310292932Sdim sizeof (struct group))) != Null_Item) { 311292932Sdim /* 312292932Sdim * With that allocated, insert the 313292932Sdim * group name as key and set the key 314292932Sdim * length. 315292932Sdim */ 316292932Sdim (void) memmove(itemp->key, &gid, len); 317292932Sdim 318292932Sdim /* 319292932Sdim * Insert the data associated with 320292932Sdim * the key and the data length. 321292932Sdim */ 322292932Sdim (void) memmove(itemp->data, grp, 323292932Sdim sizeof (struct group)); 324292932Sdim 325292932Sdim if (add_cache(grgid_cache, itemp) == -1) 326292932Sdim (void) fprintf(stderr, 327292932Sdim pkg_gt(ERR_ADDFAIL), 328292932Sdim "cgrgid()"); 329292932Sdim } 330292932Sdim } 331292932Sdim } 332292932Sdim return (grp); 333292932Sdim } else /* Found it in the cache. */ 334292932Sdim return ((struct group *)itemp->data); 335292932Sdim} 336292932Sdim 337292932Sdimstruct passwd * 338292932Sdimcpwuid(uid_t uid) 339292932Sdim{ 340292932Sdim struct passwd *pwd; 341292932Sdim Item *itemp; 342292932Sdim int len; 343292932Sdim static int cache_failed; 344292932Sdim 345292932Sdim if (!is_a_pwuid_cache && !cache_failed) { 346292932Sdim if (init_cache(&pwuid_cache, HASHSIZE, BSZ, 347292932Sdim uid_hash, uid_comp) == -1) { 348292932Sdim (void) fprintf(stderr, 349292932Sdim pkg_gt(ERR_NOINIT), "cpwuid()"); 350292932Sdim pwuid_cache = (Cache *) NULL; 351292932Sdim cache_failed = 1; 352292932Sdim } else 353292932Sdim is_a_pwuid_cache = 1; 354292932Sdim } 355292932Sdim 356292932Sdim len = sizeof (uid_t); 357292932Sdim 358292932Sdim /* First look in the cache. Failing that, do it the hard way. */ 359292932Sdim if ((itemp = lookup_cache(pwuid_cache, &uid, len)) == Null_Item) { 360292932Sdim 361292932Sdim /* Get the passwd by number. */ 362292932Sdim if ((pwd = clpwuid(uid)) != NULL || 363292932Sdim (pwd = getpwuid(uid)) != NULL) { 364292932Sdim /* A passwd by that user ID exists on this machine. */ 365292932Sdim if (dup_pw_ent(pwd)) 366292932Sdim /* 367292932Sdim * Effectively no such passwd since struct 368292932Sdim * couldn't be duplicated. 369292932Sdim */ 370292932Sdim pwd = (struct passwd *)NULL; 371292932Sdim /* 372292932Sdim * If there's a pwuid cache, then update it with this 373292932Sdim * new passwd, otherwise, skip it. 374292932Sdim */ 375292932Sdim else if (is_a_pwuid_cache) { 376292932Sdim if ((itemp = cache_alloc("cpwuid()", len, 377292932Sdim sizeof (struct passwd))) != Null_Item) { 378292932Sdim /* 379292932Sdim * With that allocated, insert the 380292932Sdim * group name as key and set the key 381292932Sdim * length. 382292932Sdim */ 383292932Sdim (void) memmove(itemp->key, &uid, len); 384292932Sdim 385292932Sdim /* 386292932Sdim * Insert the data associated with 387292932Sdim * the key and the data length. 388292932Sdim */ 389292932Sdim (void) memmove(itemp->data, pwd, 390292932Sdim sizeof (struct passwd)); 391292932Sdim 392292932Sdim if (add_cache(pwuid_cache, itemp) == -1) 393292932Sdim (void) fprintf(stderr, 394292932Sdim pkg_gt(ERR_ADDFAIL), 395292932Sdim "cpwuid()"); 396 } 397 } 398 } 399 return (pwd); 400 } else /* Found it in the cache. */ 401 return ((struct passwd *)itemp->data); 402} 403 404/* 405 * This function duplicates the group structure provided from kernel static 406 * memory. There is a lot of defensive coding here because there have been 407 * problems with the getgr*() functions. They will sometimes provide NULL 408 * values instead of pointers to NULL values. There has been no explanation 409 * for the reason behind this; but, this function takes a NULL to be an 410 * invalid (char *) and returns an error. 411 */ 412static int 413dup_gr_ent(struct group *grp) 414{ 415 char **tp = NULL; 416 char **memp = NULL; 417 int nent = 0; /* Number of entries in the member list. */ 418 419 if (grp) { 420 if (grp->gr_name == NULL) { 421 (void) fprintf(stderr, 422 pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_name", 423 "unknown", "group"); 424 return (-1); 425 } else if ((grp->gr_name = strdup(grp->gr_name)) == NULL) { 426 (void) fprintf(stderr, 427 pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_name"); 428 return (-1); 429 } 430 if (grp->gr_passwd == NULL) { 431 (void) fprintf(stderr, 432 pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_passwd", 433 grp->gr_name, "group"); 434 return (-1); 435 } else if ((grp->gr_passwd = strdup(grp->gr_passwd)) == NULL) { 436 (void) fprintf(stderr, 437 pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_passwd"); 438 return (-1); 439 } 440 /* 441 * Allocate space for the member list and move the members 442 * into it. 443 */ 444 if (grp->gr_mem) { 445 /* 446 * First count the members. The nent variable will be 447 * the number of members + 1 for the terminator. 448 */ 449 for (tp = grp->gr_mem; *tp; nent++, tp++); 450 451 /* Now allocate room for the pointers. */ 452 memp = malloc(sizeof (char **)* (nent+1)); 453 454 if (memp == NULL) { 455 (void) fprintf(stderr, 456 pkg_gt(ERR_MALLOC), "dup_gr_ent()", 457 (sizeof (char **)* (nent+1)), 458 "memp"); 459 return (-1); 460 } 461 462 /* 463 * Now copy over the pointers and entries. It should 464 * be noted that if the structure is messed up here, 465 * the resulting member list will be truncated at the 466 * NULL entry. 467 */ 468 for (nent = 0, tp = grp->gr_mem; *tp; tp++) { 469 if ((memp[nent++] = strdup(*tp)) == NULL) { 470 (void) fprintf(stderr, 471 pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", 472 "gr_mem"); 473 return (-1); 474 } 475 } 476 } else { 477 (void) fprintf(stderr, 478 pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_mem", 479 grp->gr_name, "group"); 480 return (-1); 481 } 482 } else { 483 (void) fprintf(stderr, pkg_gt(ERR_NOGRP)); 484 return (-1); 485 } 486 memp[nent++] = '\0'; 487 return (0); 488} 489 490/* 491 * This function duplicates the passwd structure provided from kernel static 492 * memory. As in the above function, since there have been problems with the 493 * getpw*() functions, the structure provided is rigorously scrubbed. This 494 * function takes a NULL to be an invalid (char *) and returns an error if 495 * one is detected. 496 */ 497static int 498dup_pw_ent(struct passwd *pwd) 499{ 500 if (pwd) { 501 if (pwd->pw_name == NULL) { 502 (void) fprintf(stderr, 503 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_name", 504 "unknown", "passwd"); 505 return (-1); 506 } else if ((pwd->pw_name = strdup(pwd->pw_name)) == NULL) { 507 (void) fprintf(stderr, 508 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_name"); 509 return (-1); 510 } 511 512 if (pwd->pw_passwd == NULL) { 513 (void) fprintf(stderr, 514 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_passwd", 515 pwd->pw_name, "passwd"); 516 return (-1); 517 } else if ((pwd->pw_passwd = strdup(pwd->pw_passwd)) == NULL) { 518 (void) fprintf(stderr, 519 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_passwd"); 520 return (-1); 521 } 522 523 if (pwd->pw_age == NULL) { 524 (void) fprintf(stderr, 525 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_age", 526 pwd->pw_name, "passwd"); 527 return (-1); 528 } else if ((pwd->pw_age = strdup(pwd->pw_age)) == NULL) { 529 (void) fprintf(stderr, 530 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_age"); 531 return (-1); 532 } 533 534 if (pwd->pw_comment == NULL) { 535 (void) fprintf(stderr, 536 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_comment", 537 pwd->pw_name, "passwd"); 538 return (-1); 539 } else if ((pwd->pw_comment = strdup(pwd->pw_comment)) == 540 NULL) { 541 (void) fprintf(stderr, 542 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_comment"); 543 return (-1); 544 } 545 546 if (pwd->pw_gecos == NULL) { 547 (void) fprintf(stderr, 548 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_gecos", 549 pwd->pw_name, "passwd"); 550 return (-1); 551 } else if ((pwd->pw_gecos = strdup(pwd->pw_gecos)) == NULL) { 552 (void) fprintf(stderr, 553 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_gecos"); 554 return (-1); 555 } 556 557 if (pwd->pw_dir == NULL) { 558 (void) fprintf(stderr, 559 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_dir", 560 pwd->pw_name, "passwd"); 561 return (-1); 562 } else if ((pwd->pw_dir = strdup(pwd->pw_dir)) == NULL) { 563 (void) fprintf(stderr, 564 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_dir"); 565 return (-1); 566 } 567 568 if (pwd->pw_shell == NULL) { 569 (void) fprintf(stderr, 570 pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_shell", 571 pwd->pw_name, "passwd"); 572 return (-1); 573 } else if ((pwd->pw_shell = strdup(pwd->pw_shell)) == NULL) { 574 (void) fprintf(stderr, 575 pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_shell"); 576 return (-1); 577 } 578 } else { 579 (void) fprintf(stderr, pkg_gt(ERR_NOPWD)); 580 return (-1); 581 } 582 583 return (0); 584} 585 586/* 587 * Check the client's etc/group file for the group name 588 * 589 * returns a pointer to the group structure if the group is found 590 * returns NULL if not found 591 */ 592struct group * 593clgrnam(char *nam) 594{ 595 struct group *gr; 596 char *instroot, *buf; 597 FILE *gr_ptr; 598 599 if ((instroot = get_install_root()) != NULL) { 600 if ((buf = (char *)malloc(strlen(instroot) + 601 strlen(GROUP) + 1)) == NULL) { 602 (void) fprintf(stderr, 603 pkg_gt(ERR_MALLOC), "clgrnam()", 604 strlen(instroot) + strlen(GROUP), "buf"); 605 } 606 (void) sprintf(buf, "%s%s", instroot, GROUP); 607 if ((gr_ptr = fopen(buf, "r")) == NULL) { 608 free(buf); 609 return (NULL); 610 } else { 611 while ((gr = fgetgrent(gr_ptr)) != NULL) { 612 if (strcmp(gr->gr_name, nam) == 0) { 613 break; 614 } 615 } 616 } 617 free(buf); 618 (void) fclose(gr_ptr); 619 return (gr); 620 } else { 621 return (NULL); 622 } 623} 624 625/* 626 * Check the client's etc/passwd file for the user name 627 * 628 * returns a pointer to the passwd structure if the passwd is found 629 * returns NULL if not found 630 */ 631struct passwd * 632clpwnam(char *nam) 633{ 634 struct passwd *pw; 635 char *instroot, *buf; 636 FILE *pw_ptr; 637 638 if ((instroot = get_install_root()) != NULL) { 639 if ((buf = (char *)malloc(strlen(instroot) + 640 strlen(PASSWD) + 1)) == NULL) { 641 (void) fprintf(stderr, 642 pkg_gt(ERR_MALLOC), "clpwnam()", 643 strlen(instroot) + strlen(PASSWD), "buf"); 644 } 645 (void) sprintf(buf, "%s%s", instroot, PASSWD); 646 if ((pw_ptr = fopen(buf, "r")) == NULL) { 647 free(buf); 648 return (NULL); 649 } else { 650 while ((pw = fgetpwent(pw_ptr)) != NULL) { 651 if (strcmp(pw->pw_name, nam) == 0) { 652 break; 653 } 654 } 655 } 656 free(buf); 657 (void) fclose(pw_ptr); 658 return (pw); 659 } else { 660 return (NULL); 661 } 662} 663 664/* 665 * Check the client's etc/group file for the group id 666 * 667 * returns a pointer to the group structure if the group id is found 668 * returns NULL if not found 669 */ 670struct group * 671clgrgid(gid_t gid) 672{ 673 struct group *gr; 674 char *instroot, *buf; 675 FILE *gr_ptr; 676 677 if ((instroot = get_install_root()) != NULL) { 678 if ((buf = (char *)malloc(strlen(instroot) + 679 strlen(GROUP) + 1)) == NULL) { 680 (void) fprintf(stderr, 681 pkg_gt(ERR_MALLOC), "clgrgid()", 682 strlen(instroot) + strlen(GROUP), "buf"); 683 } 684 (void) sprintf(buf, "%s%s", instroot, GROUP); 685 if ((gr_ptr = fopen(buf, "r")) == NULL) { 686 free(buf); 687 return (NULL); 688 } else { 689 while ((gr = fgetgrent(gr_ptr)) != NULL) { 690 if (gr->gr_gid == gid) { 691 break; 692 } 693 } 694 } 695 free(buf); 696 (void) fclose(gr_ptr); 697 return (gr); 698 } else { 699 return (NULL); 700 } 701} 702 703/* 704 * Check the client's etc/passwd file for the user id 705 * 706 * returns a pointer to the passwd structure if the user id is found 707 * returns NULL if not found 708 */ 709struct passwd * 710clpwuid(uid_t uid) 711{ 712 struct passwd *pw; 713 char *instroot, *buf; 714 FILE *pw_ptr; 715 716 if ((instroot = get_install_root()) != NULL) { 717 if ((buf = (char *)malloc(strlen(instroot) + 718 strlen(PASSWD) + 1)) == NULL) { 719 (void) fprintf(stderr, 720 pkg_gt(ERR_MALLOC), "clpwuid()", 721 strlen(instroot) + strlen(PASSWD), "buf"); 722 } 723 (void) sprintf(buf, "%s%s", instroot, PASSWD); 724 if ((pw_ptr = fopen(buf, "r")) == NULL) { 725 free(buf); 726 return (NULL); 727 } else { 728 while ((pw = fgetpwent(pw_ptr)) != NULL) { 729 if (pw->pw_uid == uid) { 730 break; 731 } 732 } 733 } 734 free(buf); 735 (void) fclose(pw_ptr); 736 return (pw); 737 } else { 738 return (NULL); 739 } 740} 741