1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland 28*5c51f124SMoriah Waterland /* 29*5c51f124SMoriah Waterland * This module fetches group and passwd structs for the caller. It 30*5c51f124SMoriah Waterland * uses a hash table to speed up retrieval of repeated entries. If 31*5c51f124SMoriah Waterland * the attempts to initialize the hash tables fail, this just 32*5c51f124SMoriah Waterland * continues the slow way. 33*5c51f124SMoriah Waterland */ 34*5c51f124SMoriah Waterland 35*5c51f124SMoriah Waterland #include <pwd.h> 36*5c51f124SMoriah Waterland #include <grp.h> 37*5c51f124SMoriah Waterland #include <string.h> 38*5c51f124SMoriah Waterland #include <stdio.h> 39*5c51f124SMoriah Waterland #include <stdlib.h> 40*5c51f124SMoriah Waterland #include <unistd.h> 41*5c51f124SMoriah Waterland #include "pkglib.h" 42*5c51f124SMoriah Waterland #include "pkglocale.h" 43*5c51f124SMoriah Waterland #include "nhash.h" 44*5c51f124SMoriah Waterland 45*5c51f124SMoriah Waterland #define HASHSIZE 151 46*5c51f124SMoriah Waterland #define BSZ 4 47*5c51f124SMoriah Waterland 48*5c51f124SMoriah Waterland #define ERR_DUPFAIL "%s: strdup(%s) failed.\n" 49*5c51f124SMoriah Waterland #define ERR_ADDFAIL "%s: add_cache() failed.\n" 50*5c51f124SMoriah Waterland #define ERR_BADMEMB "%s: %s in \"%s\" %s structure is invalid.\n" 51*5c51f124SMoriah Waterland #define ERR_NOGRP "dup_gr_ent(): no group entry provided.\n" 52*5c51f124SMoriah Waterland #define ERR_NOPWD "dup_pw_ent(): no passwd entry provided.\n" 53*5c51f124SMoriah Waterland #define ERR_NOINIT "%s: init_cache() failed.\n" 54*5c51f124SMoriah Waterland #define ERR_MALLOC "%s: malloc(%d) failed for %s.\n" 55*5c51f124SMoriah Waterland 56*5c51f124SMoriah Waterland static Cache *pwnam_cache = (Cache *) NULL; 57*5c51f124SMoriah Waterland static Cache *grnam_cache = (Cache *) NULL; 58*5c51f124SMoriah Waterland static Cache *pwuid_cache = (Cache *) NULL; 59*5c51f124SMoriah Waterland static Cache *grgid_cache = (Cache *) NULL; 60*5c51f124SMoriah Waterland 61*5c51f124SMoriah Waterland static int dup_gr_ent(struct group *grp); 62*5c51f124SMoriah Waterland static int dup_pw_ent(struct passwd *pwp); 63*5c51f124SMoriah Waterland 64*5c51f124SMoriah Waterland /* 65*5c51f124SMoriah Waterland * These indicate whether the hash table has been initialized for the four 66*5c51f124SMoriah Waterland * categories. 67*5c51f124SMoriah Waterland */ 68*5c51f124SMoriah Waterland static int is_a_pwnam_cache; 69*5c51f124SMoriah Waterland static int is_a_grnam_cache; 70*5c51f124SMoriah Waterland static int is_a_pwuid_cache; 71*5c51f124SMoriah Waterland static int is_a_grgid_cache; 72*5c51f124SMoriah Waterland 73*5c51f124SMoriah Waterland extern char *get_install_root(void); 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland /* 76*5c51f124SMoriah Waterland * If there's a grnam cache, then update it with this new 77*5c51f124SMoriah Waterland * group, otherwise, skip it. 78*5c51f124SMoriah Waterland */ 79*5c51f124SMoriah Waterland static Item * 80*5c51f124SMoriah Waterland cache_alloc(char *fname, int len, size_t struct_size) 81*5c51f124SMoriah Waterland { 82*5c51f124SMoriah Waterland Item *itemp; 83*5c51f124SMoriah Waterland 84*5c51f124SMoriah Waterland /* 85*5c51f124SMoriah Waterland * Allocate space for the Item pointer, key and data. 86*5c51f124SMoriah Waterland */ 87*5c51f124SMoriah Waterland if ((itemp = (Item *) malloc(sizeof (*itemp))) == 88*5c51f124SMoriah Waterland Null_Item) { 89*5c51f124SMoriah Waterland (void) fprintf(stderr, 90*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), fname, 91*5c51f124SMoriah Waterland sizeof (*itemp), "itemp"); 92*5c51f124SMoriah Waterland } else if ((itemp->key = (char *)malloc(len)) == NULL) { 93*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, len, 94*5c51f124SMoriah Waterland "itemp->key"); 95*5c51f124SMoriah Waterland free(itemp); 96*5c51f124SMoriah Waterland } else if ((itemp->data = malloc(struct_size)) == NULL) { 97*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, 98*5c51f124SMoriah Waterland struct_size, "itemp->data"); 99*5c51f124SMoriah Waterland free(itemp->key); 100*5c51f124SMoriah Waterland free(itemp); 101*5c51f124SMoriah Waterland } else { 102*5c51f124SMoriah Waterland /* Set length parameters. */ 103*5c51f124SMoriah Waterland itemp->keyl = len; 104*5c51f124SMoriah Waterland itemp->datal = struct_size; 105*5c51f124SMoriah Waterland 106*5c51f124SMoriah Waterland return (itemp); 107*5c51f124SMoriah Waterland } 108*5c51f124SMoriah Waterland 109*5c51f124SMoriah Waterland return ((Item *) NULL); 110*5c51f124SMoriah Waterland } 111*5c51f124SMoriah Waterland 112*5c51f124SMoriah Waterland /* Get the required group structure based upon the group name. */ 113*5c51f124SMoriah Waterland struct group * 114*5c51f124SMoriah Waterland cgrnam(char *nam) 115*5c51f124SMoriah Waterland { 116*5c51f124SMoriah Waterland struct group *grp; 117*5c51f124SMoriah Waterland Item *itemp; 118*5c51f124SMoriah Waterland int len; 119*5c51f124SMoriah Waterland static int cache_failed; 120*5c51f124SMoriah Waterland 121*5c51f124SMoriah Waterland /* Attempt to initialize the grname cache. */ 122*5c51f124SMoriah Waterland if (!is_a_grnam_cache && !cache_failed) { 123*5c51f124SMoriah Waterland if (init_cache(&grnam_cache, HASHSIZE, BSZ, 124*5c51f124SMoriah Waterland (int (*)())NULL, (int (*)())NULL) == -1) { 125*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrnam()"); 126*5c51f124SMoriah Waterland grnam_cache = (Cache *) NULL; 127*5c51f124SMoriah Waterland cache_failed = 1; 128*5c51f124SMoriah Waterland } else 129*5c51f124SMoriah Waterland is_a_grnam_cache = 1; 130*5c51f124SMoriah Waterland } 131*5c51f124SMoriah Waterland 132*5c51f124SMoriah Waterland len = strlen(nam) + 1; 133*5c51f124SMoriah Waterland 134*5c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 135*5c51f124SMoriah Waterland if ((itemp = lookup_cache(grnam_cache, nam, len)) == Null_Item) { 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland /* Get the group by name. */ 138*5c51f124SMoriah Waterland if ((grp = clgrnam(nam)) != NULL || 139*5c51f124SMoriah Waterland (grp = getgrnam(nam)) != NULL) { 140*5c51f124SMoriah Waterland /* A group by that name exists on this machine. */ 141*5c51f124SMoriah Waterland if (dup_gr_ent(grp)) 142*5c51f124SMoriah Waterland /* 143*5c51f124SMoriah Waterland * Effectively no such group since struct 144*5c51f124SMoriah Waterland * couldn't be duplicated. 145*5c51f124SMoriah Waterland */ 146*5c51f124SMoriah Waterland grp = (struct group *)NULL; 147*5c51f124SMoriah Waterland /* 148*5c51f124SMoriah Waterland * If there's a grnam cache, then update it with this 149*5c51f124SMoriah Waterland * new group, otherwise, skip it. 150*5c51f124SMoriah Waterland */ 151*5c51f124SMoriah Waterland else if (is_a_grnam_cache) { 152*5c51f124SMoriah Waterland if ((itemp = cache_alloc("cgrnam()", len, 153*5c51f124SMoriah Waterland sizeof (struct group))) != Null_Item) { 154*5c51f124SMoriah Waterland /* 155*5c51f124SMoriah Waterland * With that allocated, insert the 156*5c51f124SMoriah Waterland * group name as key and set the key 157*5c51f124SMoriah Waterland * length. 158*5c51f124SMoriah Waterland */ 159*5c51f124SMoriah Waterland (void) memmove(itemp->key, nam, len); 160*5c51f124SMoriah Waterland 161*5c51f124SMoriah Waterland /* 162*5c51f124SMoriah Waterland * Insert the data associated with 163*5c51f124SMoriah Waterland * the key and the data length. 164*5c51f124SMoriah Waterland */ 165*5c51f124SMoriah Waterland (void) memmove(itemp->data, grp, 166*5c51f124SMoriah Waterland sizeof (struct group)); 167*5c51f124SMoriah Waterland 168*5c51f124SMoriah Waterland /* Insert the Item into the cache. */ 169*5c51f124SMoriah Waterland if (add_cache(grnam_cache, itemp) == -1) 170*5c51f124SMoriah Waterland (void) fprintf(stderr, 171*5c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 172*5c51f124SMoriah Waterland "cgrnam()"); 173*5c51f124SMoriah Waterland } 174*5c51f124SMoriah Waterland } 175*5c51f124SMoriah Waterland } 176*5c51f124SMoriah Waterland return (grp); 177*5c51f124SMoriah Waterland } else /* Found it in the cache. */ 178*5c51f124SMoriah Waterland return ((struct group *)itemp->data); 179*5c51f124SMoriah Waterland } 180*5c51f124SMoriah Waterland 181*5c51f124SMoriah Waterland struct passwd * 182*5c51f124SMoriah Waterland cpwnam(char *nam) 183*5c51f124SMoriah Waterland { 184*5c51f124SMoriah Waterland struct passwd *pwd; 185*5c51f124SMoriah Waterland Item *itemp; 186*5c51f124SMoriah Waterland int len; 187*5c51f124SMoriah Waterland static int cache_failed; 188*5c51f124SMoriah Waterland 189*5c51f124SMoriah Waterland if (!is_a_pwnam_cache && !cache_failed) { 190*5c51f124SMoriah Waterland if (init_cache(&pwnam_cache, HASHSIZE, BSZ, 191*5c51f124SMoriah Waterland (int (*)())NULL, (int (*)())NULL) == -1) { 192*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cpwnam()"); 193*5c51f124SMoriah Waterland pwnam_cache = (Cache *) NULL; 194*5c51f124SMoriah Waterland cache_failed = 1; 195*5c51f124SMoriah Waterland } else 196*5c51f124SMoriah Waterland is_a_pwnam_cache = 1; 197*5c51f124SMoriah Waterland } 198*5c51f124SMoriah Waterland 199*5c51f124SMoriah Waterland len = strlen(nam) + 1; 200*5c51f124SMoriah Waterland 201*5c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 202*5c51f124SMoriah Waterland if ((itemp = lookup_cache(pwnam_cache, nam, len)) == Null_Item) { 203*5c51f124SMoriah Waterland 204*5c51f124SMoriah Waterland /* Get the passwd by name. */ 205*5c51f124SMoriah Waterland if ((pwd = clpwnam(nam)) != NULL || 206*5c51f124SMoriah Waterland (pwd = getpwnam(nam)) != NULL) { 207*5c51f124SMoriah Waterland /* A passwd by that name exists on this machine. */ 208*5c51f124SMoriah Waterland if (dup_pw_ent(pwd)) 209*5c51f124SMoriah Waterland /* 210*5c51f124SMoriah Waterland * Effectively no such passwd since struct 211*5c51f124SMoriah Waterland * couldn't be duplicated. 212*5c51f124SMoriah Waterland */ 213*5c51f124SMoriah Waterland pwd = (struct passwd *)NULL; 214*5c51f124SMoriah Waterland /* 215*5c51f124SMoriah Waterland * If there's a pwnam cache, then update it with this 216*5c51f124SMoriah Waterland * new passwd, otherwise, skip it. 217*5c51f124SMoriah Waterland */ 218*5c51f124SMoriah Waterland else if (is_a_pwnam_cache) { 219*5c51f124SMoriah Waterland /* 220*5c51f124SMoriah Waterland * Allocate space for the Item pointer, key 221*5c51f124SMoriah Waterland * and data. 222*5c51f124SMoriah Waterland */ 223*5c51f124SMoriah Waterland if ((itemp = cache_alloc("cpwnam()", len, 224*5c51f124SMoriah Waterland sizeof (struct passwd))) != Null_Item) { 225*5c51f124SMoriah Waterland /* 226*5c51f124SMoriah Waterland * With that allocated, insert the 227*5c51f124SMoriah Waterland * group name as key and set the key 228*5c51f124SMoriah Waterland * length. 229*5c51f124SMoriah Waterland */ 230*5c51f124SMoriah Waterland (void) memmove(itemp->key, nam, len); 231*5c51f124SMoriah Waterland 232*5c51f124SMoriah Waterland /* 233*5c51f124SMoriah Waterland * Insert the data associated with 234*5c51f124SMoriah Waterland * the key and the data length. 235*5c51f124SMoriah Waterland */ 236*5c51f124SMoriah Waterland (void) memmove(itemp->data, pwd, 237*5c51f124SMoriah Waterland sizeof (struct passwd)); 238*5c51f124SMoriah Waterland 239*5c51f124SMoriah Waterland if (add_cache(pwnam_cache, itemp) == -1) 240*5c51f124SMoriah Waterland (void) fprintf(stderr, 241*5c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 242*5c51f124SMoriah Waterland "cpwnam()"); 243*5c51f124SMoriah Waterland } 244*5c51f124SMoriah Waterland } 245*5c51f124SMoriah Waterland } 246*5c51f124SMoriah Waterland return (pwd); 247*5c51f124SMoriah Waterland } else /* Found it in the cache. */ 248*5c51f124SMoriah Waterland return ((struct passwd *)itemp->data); 249*5c51f124SMoriah Waterland } 250*5c51f124SMoriah Waterland 251*5c51f124SMoriah Waterland static int 252*5c51f124SMoriah Waterland uid_hash(void *datap, int datalen, int hsz) 253*5c51f124SMoriah Waterland { 254*5c51f124SMoriah Waterland #ifdef lint 255*5c51f124SMoriah Waterland int i = datalen; 256*5c51f124SMoriah Waterland datalen = i; 257*5c51f124SMoriah Waterland #endif /* lint */ 258*5c51f124SMoriah Waterland 259*5c51f124SMoriah Waterland return (*((uid_t *)datap) % hsz); 260*5c51f124SMoriah Waterland } 261*5c51f124SMoriah Waterland 262*5c51f124SMoriah Waterland static int 263*5c51f124SMoriah Waterland uid_comp(void *datap1, void *datap2, int datalen) 264*5c51f124SMoriah Waterland { 265*5c51f124SMoriah Waterland #ifdef lint 266*5c51f124SMoriah Waterland int i = datalen; 267*5c51f124SMoriah Waterland datalen = i; 268*5c51f124SMoriah Waterland #endif /* lint */ 269*5c51f124SMoriah Waterland 270*5c51f124SMoriah Waterland return (*((uid_t *)datap1) - *((uid_t *)datap2)); 271*5c51f124SMoriah Waterland } 272*5c51f124SMoriah Waterland 273*5c51f124SMoriah Waterland struct group * 274*5c51f124SMoriah Waterland cgrgid(gid_t gid) 275*5c51f124SMoriah Waterland { 276*5c51f124SMoriah Waterland struct group *grp; 277*5c51f124SMoriah Waterland Item *itemp; 278*5c51f124SMoriah Waterland int len; 279*5c51f124SMoriah Waterland static int cache_failed; 280*5c51f124SMoriah Waterland 281*5c51f124SMoriah Waterland if (!is_a_grgid_cache && !cache_failed) { 282*5c51f124SMoriah Waterland if (init_cache(&grgid_cache, HASHSIZE, BSZ, 283*5c51f124SMoriah Waterland uid_hash, uid_comp) == -1) { 284*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrgid()"); 285*5c51f124SMoriah Waterland grgid_cache = (Cache *) NULL; 286*5c51f124SMoriah Waterland cache_failed = 1; 287*5c51f124SMoriah Waterland } else 288*5c51f124SMoriah Waterland is_a_grgid_cache = 1; 289*5c51f124SMoriah Waterland } 290*5c51f124SMoriah Waterland 291*5c51f124SMoriah Waterland len = sizeof (uid_t); 292*5c51f124SMoriah Waterland 293*5c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 294*5c51f124SMoriah Waterland if ((itemp = lookup_cache(grgid_cache, &gid, len)) == Null_Item) { 295*5c51f124SMoriah Waterland if ((grp = clgrgid(gid)) != NULL || 296*5c51f124SMoriah Waterland (grp = getgrgid(gid)) != NULL) { 297*5c51f124SMoriah Waterland /* A group by that number exists on this machine. */ 298*5c51f124SMoriah Waterland if (dup_gr_ent(grp)) 299*5c51f124SMoriah Waterland /* 300*5c51f124SMoriah Waterland * Effectively no such group since struct 301*5c51f124SMoriah Waterland * couldn't be duplicated. 302*5c51f124SMoriah Waterland */ 303*5c51f124SMoriah Waterland grp = (struct group *)NULL; 304*5c51f124SMoriah Waterland /* 305*5c51f124SMoriah Waterland * If there's a grnam cache, then update it with this 306*5c51f124SMoriah Waterland * new group, otherwise, skip it. 307*5c51f124SMoriah Waterland */ 308*5c51f124SMoriah Waterland else if (is_a_grgid_cache) { 309*5c51f124SMoriah Waterland if ((itemp = cache_alloc("cgrgid()", len, 310*5c51f124SMoriah Waterland sizeof (struct group))) != Null_Item) { 311*5c51f124SMoriah Waterland /* 312*5c51f124SMoriah Waterland * With that allocated, insert the 313*5c51f124SMoriah Waterland * group name as key and set the key 314*5c51f124SMoriah Waterland * length. 315*5c51f124SMoriah Waterland */ 316*5c51f124SMoriah Waterland (void) memmove(itemp->key, &gid, len); 317*5c51f124SMoriah Waterland 318*5c51f124SMoriah Waterland /* 319*5c51f124SMoriah Waterland * Insert the data associated with 320*5c51f124SMoriah Waterland * the key and the data length. 321*5c51f124SMoriah Waterland */ 322*5c51f124SMoriah Waterland (void) memmove(itemp->data, grp, 323*5c51f124SMoriah Waterland sizeof (struct group)); 324*5c51f124SMoriah Waterland 325*5c51f124SMoriah Waterland if (add_cache(grgid_cache, itemp) == -1) 326*5c51f124SMoriah Waterland (void) fprintf(stderr, 327*5c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 328*5c51f124SMoriah Waterland "cgrgid()"); 329*5c51f124SMoriah Waterland } 330*5c51f124SMoriah Waterland } 331*5c51f124SMoriah Waterland } 332*5c51f124SMoriah Waterland return (grp); 333*5c51f124SMoriah Waterland } else /* Found it in the cache. */ 334*5c51f124SMoriah Waterland return ((struct group *)itemp->data); 335*5c51f124SMoriah Waterland } 336*5c51f124SMoriah Waterland 337*5c51f124SMoriah Waterland struct passwd * 338*5c51f124SMoriah Waterland cpwuid(uid_t uid) 339*5c51f124SMoriah Waterland { 340*5c51f124SMoriah Waterland struct passwd *pwd; 341*5c51f124SMoriah Waterland Item *itemp; 342*5c51f124SMoriah Waterland int len; 343*5c51f124SMoriah Waterland static int cache_failed; 344*5c51f124SMoriah Waterland 345*5c51f124SMoriah Waterland if (!is_a_pwuid_cache && !cache_failed) { 346*5c51f124SMoriah Waterland if (init_cache(&pwuid_cache, HASHSIZE, BSZ, 347*5c51f124SMoriah Waterland uid_hash, uid_comp) == -1) { 348*5c51f124SMoriah Waterland (void) fprintf(stderr, 349*5c51f124SMoriah Waterland pkg_gt(ERR_NOINIT), "cpwuid()"); 350*5c51f124SMoriah Waterland pwuid_cache = (Cache *) NULL; 351*5c51f124SMoriah Waterland cache_failed = 1; 352*5c51f124SMoriah Waterland } else 353*5c51f124SMoriah Waterland is_a_pwuid_cache = 1; 354*5c51f124SMoriah Waterland } 355*5c51f124SMoriah Waterland 356*5c51f124SMoriah Waterland len = sizeof (uid_t); 357*5c51f124SMoriah Waterland 358*5c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 359*5c51f124SMoriah Waterland if ((itemp = lookup_cache(pwuid_cache, &uid, len)) == Null_Item) { 360*5c51f124SMoriah Waterland 361*5c51f124SMoriah Waterland /* Get the passwd by number. */ 362*5c51f124SMoriah Waterland if ((pwd = clpwuid(uid)) != NULL || 363*5c51f124SMoriah Waterland (pwd = getpwuid(uid)) != NULL) { 364*5c51f124SMoriah Waterland /* A passwd by that user ID exists on this machine. */ 365*5c51f124SMoriah Waterland if (dup_pw_ent(pwd)) 366*5c51f124SMoriah Waterland /* 367*5c51f124SMoriah Waterland * Effectively no such passwd since struct 368*5c51f124SMoriah Waterland * couldn't be duplicated. 369*5c51f124SMoriah Waterland */ 370*5c51f124SMoriah Waterland pwd = (struct passwd *)NULL; 371*5c51f124SMoriah Waterland /* 372*5c51f124SMoriah Waterland * If there's a pwuid cache, then update it with this 373*5c51f124SMoriah Waterland * new passwd, otherwise, skip it. 374*5c51f124SMoriah Waterland */ 375*5c51f124SMoriah Waterland else if (is_a_pwuid_cache) { 376*5c51f124SMoriah Waterland if ((itemp = cache_alloc("cpwuid()", len, 377*5c51f124SMoriah Waterland sizeof (struct passwd))) != Null_Item) { 378*5c51f124SMoriah Waterland /* 379*5c51f124SMoriah Waterland * With that allocated, insert the 380*5c51f124SMoriah Waterland * group name as key and set the key 381*5c51f124SMoriah Waterland * length. 382*5c51f124SMoriah Waterland */ 383*5c51f124SMoriah Waterland (void) memmove(itemp->key, &uid, len); 384*5c51f124SMoriah Waterland 385*5c51f124SMoriah Waterland /* 386*5c51f124SMoriah Waterland * Insert the data associated with 387*5c51f124SMoriah Waterland * the key and the data length. 388*5c51f124SMoriah Waterland */ 389*5c51f124SMoriah Waterland (void) memmove(itemp->data, pwd, 390*5c51f124SMoriah Waterland sizeof (struct passwd)); 391*5c51f124SMoriah Waterland 392*5c51f124SMoriah Waterland if (add_cache(pwuid_cache, itemp) == -1) 393*5c51f124SMoriah Waterland (void) fprintf(stderr, 394*5c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 395*5c51f124SMoriah Waterland "cpwuid()"); 396*5c51f124SMoriah Waterland } 397*5c51f124SMoriah Waterland } 398*5c51f124SMoriah Waterland } 399*5c51f124SMoriah Waterland return (pwd); 400*5c51f124SMoriah Waterland } else /* Found it in the cache. */ 401*5c51f124SMoriah Waterland return ((struct passwd *)itemp->data); 402*5c51f124SMoriah Waterland } 403*5c51f124SMoriah Waterland 404*5c51f124SMoriah Waterland /* 405*5c51f124SMoriah Waterland * This function duplicates the group structure provided from kernel static 406*5c51f124SMoriah Waterland * memory. There is a lot of defensive coding here because there have been 407*5c51f124SMoriah Waterland * problems with the getgr*() functions. They will sometimes provide NULL 408*5c51f124SMoriah Waterland * values instead of pointers to NULL values. There has been no explanation 409*5c51f124SMoriah Waterland * for the reason behind this; but, this function takes a NULL to be an 410*5c51f124SMoriah Waterland * invalid (char *) and returns an error. 411*5c51f124SMoriah Waterland */ 412*5c51f124SMoriah Waterland static int 413*5c51f124SMoriah Waterland dup_gr_ent(struct group *grp) 414*5c51f124SMoriah Waterland { 415*5c51f124SMoriah Waterland char **tp = NULL; 416*5c51f124SMoriah Waterland char **memp = NULL; 417*5c51f124SMoriah Waterland int nent = 0; /* Number of entries in the member list. */ 418*5c51f124SMoriah Waterland 419*5c51f124SMoriah Waterland if (grp) { 420*5c51f124SMoriah Waterland if (grp->gr_name == NULL) { 421*5c51f124SMoriah Waterland (void) fprintf(stderr, 422*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_name", 423*5c51f124SMoriah Waterland "unknown", "group"); 424*5c51f124SMoriah Waterland return (-1); 425*5c51f124SMoriah Waterland } else if ((grp->gr_name = strdup(grp->gr_name)) == NULL) { 426*5c51f124SMoriah Waterland (void) fprintf(stderr, 427*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_name"); 428*5c51f124SMoriah Waterland return (-1); 429*5c51f124SMoriah Waterland } 430*5c51f124SMoriah Waterland if (grp->gr_passwd == NULL) { 431*5c51f124SMoriah Waterland (void) fprintf(stderr, 432*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_passwd", 433*5c51f124SMoriah Waterland grp->gr_name, "group"); 434*5c51f124SMoriah Waterland return (-1); 435*5c51f124SMoriah Waterland } else if ((grp->gr_passwd = strdup(grp->gr_passwd)) == NULL) { 436*5c51f124SMoriah Waterland (void) fprintf(stderr, 437*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_passwd"); 438*5c51f124SMoriah Waterland return (-1); 439*5c51f124SMoriah Waterland } 440*5c51f124SMoriah Waterland /* 441*5c51f124SMoriah Waterland * Allocate space for the member list and move the members 442*5c51f124SMoriah Waterland * into it. 443*5c51f124SMoriah Waterland */ 444*5c51f124SMoriah Waterland if (grp->gr_mem) { 445*5c51f124SMoriah Waterland /* 446*5c51f124SMoriah Waterland * First count the members. The nent variable will be 447*5c51f124SMoriah Waterland * the number of members + 1 for the terminator. 448*5c51f124SMoriah Waterland */ 449*5c51f124SMoriah Waterland for (tp = grp->gr_mem; *tp; nent++, tp++); 450*5c51f124SMoriah Waterland 451*5c51f124SMoriah Waterland /* Now allocate room for the pointers. */ 452*5c51f124SMoriah Waterland memp = malloc(sizeof (char **)* (nent+1)); 453*5c51f124SMoriah Waterland 454*5c51f124SMoriah Waterland if (memp == NULL) { 455*5c51f124SMoriah Waterland (void) fprintf(stderr, 456*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "dup_gr_ent()", 457*5c51f124SMoriah Waterland (sizeof (char **)* (nent+1)), 458*5c51f124SMoriah Waterland "memp"); 459*5c51f124SMoriah Waterland return (-1); 460*5c51f124SMoriah Waterland } 461*5c51f124SMoriah Waterland 462*5c51f124SMoriah Waterland /* 463*5c51f124SMoriah Waterland * Now copy over the pointers and entries. It should 464*5c51f124SMoriah Waterland * be noted that if the structure is messed up here, 465*5c51f124SMoriah Waterland * the resulting member list will be truncated at the 466*5c51f124SMoriah Waterland * NULL entry. 467*5c51f124SMoriah Waterland */ 468*5c51f124SMoriah Waterland for (nent = 0, tp = grp->gr_mem; *tp; tp++) { 469*5c51f124SMoriah Waterland if ((memp[nent++] = strdup(*tp)) == NULL) { 470*5c51f124SMoriah Waterland (void) fprintf(stderr, 471*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", 472*5c51f124SMoriah Waterland "gr_mem"); 473*5c51f124SMoriah Waterland return (-1); 474*5c51f124SMoriah Waterland } 475*5c51f124SMoriah Waterland } 476*5c51f124SMoriah Waterland } else { 477*5c51f124SMoriah Waterland (void) fprintf(stderr, 478*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_mem", 479*5c51f124SMoriah Waterland grp->gr_name, "group"); 480*5c51f124SMoriah Waterland return (-1); 481*5c51f124SMoriah Waterland } 482*5c51f124SMoriah Waterland } else { 483*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOGRP)); 484*5c51f124SMoriah Waterland return (-1); 485*5c51f124SMoriah Waterland } 486*5c51f124SMoriah Waterland memp[nent++] = '\0'; 487*5c51f124SMoriah Waterland return (0); 488*5c51f124SMoriah Waterland } 489*5c51f124SMoriah Waterland 490*5c51f124SMoriah Waterland /* 491*5c51f124SMoriah Waterland * This function duplicates the passwd structure provided from kernel static 492*5c51f124SMoriah Waterland * memory. As in the above function, since there have been problems with the 493*5c51f124SMoriah Waterland * getpw*() functions, the structure provided is rigorously scrubbed. This 494*5c51f124SMoriah Waterland * function takes a NULL to be an invalid (char *) and returns an error if 495*5c51f124SMoriah Waterland * one is detected. 496*5c51f124SMoriah Waterland */ 497*5c51f124SMoriah Waterland static int 498*5c51f124SMoriah Waterland dup_pw_ent(struct passwd *pwd) 499*5c51f124SMoriah Waterland { 500*5c51f124SMoriah Waterland if (pwd) { 501*5c51f124SMoriah Waterland if (pwd->pw_name == NULL) { 502*5c51f124SMoriah Waterland (void) fprintf(stderr, 503*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_name", 504*5c51f124SMoriah Waterland "unknown", "passwd"); 505*5c51f124SMoriah Waterland return (-1); 506*5c51f124SMoriah Waterland } else if ((pwd->pw_name = strdup(pwd->pw_name)) == NULL) { 507*5c51f124SMoriah Waterland (void) fprintf(stderr, 508*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_name"); 509*5c51f124SMoriah Waterland return (-1); 510*5c51f124SMoriah Waterland } 511*5c51f124SMoriah Waterland 512*5c51f124SMoriah Waterland if (pwd->pw_passwd == NULL) { 513*5c51f124SMoriah Waterland (void) fprintf(stderr, 514*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_passwd", 515*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 516*5c51f124SMoriah Waterland return (-1); 517*5c51f124SMoriah Waterland } else if ((pwd->pw_passwd = strdup(pwd->pw_passwd)) == NULL) { 518*5c51f124SMoriah Waterland (void) fprintf(stderr, 519*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_passwd"); 520*5c51f124SMoriah Waterland return (-1); 521*5c51f124SMoriah Waterland } 522*5c51f124SMoriah Waterland 523*5c51f124SMoriah Waterland if (pwd->pw_age == NULL) { 524*5c51f124SMoriah Waterland (void) fprintf(stderr, 525*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_age", 526*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 527*5c51f124SMoriah Waterland return (-1); 528*5c51f124SMoriah Waterland } else if ((pwd->pw_age = strdup(pwd->pw_age)) == NULL) { 529*5c51f124SMoriah Waterland (void) fprintf(stderr, 530*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_age"); 531*5c51f124SMoriah Waterland return (-1); 532*5c51f124SMoriah Waterland } 533*5c51f124SMoriah Waterland 534*5c51f124SMoriah Waterland if (pwd->pw_comment == NULL) { 535*5c51f124SMoriah Waterland (void) fprintf(stderr, 536*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_comment", 537*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 538*5c51f124SMoriah Waterland return (-1); 539*5c51f124SMoriah Waterland } else if ((pwd->pw_comment = strdup(pwd->pw_comment)) == 540*5c51f124SMoriah Waterland NULL) { 541*5c51f124SMoriah Waterland (void) fprintf(stderr, 542*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_comment"); 543*5c51f124SMoriah Waterland return (-1); 544*5c51f124SMoriah Waterland } 545*5c51f124SMoriah Waterland 546*5c51f124SMoriah Waterland if (pwd->pw_gecos == NULL) { 547*5c51f124SMoriah Waterland (void) fprintf(stderr, 548*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_gecos", 549*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 550*5c51f124SMoriah Waterland return (-1); 551*5c51f124SMoriah Waterland } else if ((pwd->pw_gecos = strdup(pwd->pw_gecos)) == NULL) { 552*5c51f124SMoriah Waterland (void) fprintf(stderr, 553*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_gecos"); 554*5c51f124SMoriah Waterland return (-1); 555*5c51f124SMoriah Waterland } 556*5c51f124SMoriah Waterland 557*5c51f124SMoriah Waterland if (pwd->pw_dir == NULL) { 558*5c51f124SMoriah Waterland (void) fprintf(stderr, 559*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_dir", 560*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 561*5c51f124SMoriah Waterland return (-1); 562*5c51f124SMoriah Waterland } else if ((pwd->pw_dir = strdup(pwd->pw_dir)) == NULL) { 563*5c51f124SMoriah Waterland (void) fprintf(stderr, 564*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_dir"); 565*5c51f124SMoriah Waterland return (-1); 566*5c51f124SMoriah Waterland } 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland if (pwd->pw_shell == NULL) { 569*5c51f124SMoriah Waterland (void) fprintf(stderr, 570*5c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_shell", 571*5c51f124SMoriah Waterland pwd->pw_name, "passwd"); 572*5c51f124SMoriah Waterland return (-1); 573*5c51f124SMoriah Waterland } else if ((pwd->pw_shell = strdup(pwd->pw_shell)) == NULL) { 574*5c51f124SMoriah Waterland (void) fprintf(stderr, 575*5c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_shell"); 576*5c51f124SMoriah Waterland return (-1); 577*5c51f124SMoriah Waterland } 578*5c51f124SMoriah Waterland } else { 579*5c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOPWD)); 580*5c51f124SMoriah Waterland return (-1); 581*5c51f124SMoriah Waterland } 582*5c51f124SMoriah Waterland 583*5c51f124SMoriah Waterland return (0); 584*5c51f124SMoriah Waterland } 585*5c51f124SMoriah Waterland 586*5c51f124SMoriah Waterland /* 587*5c51f124SMoriah Waterland * Check the client's etc/group file for the group name 588*5c51f124SMoriah Waterland * 589*5c51f124SMoriah Waterland * returns a pointer to the group structure if the group is found 590*5c51f124SMoriah Waterland * returns NULL if not found 591*5c51f124SMoriah Waterland */ 592*5c51f124SMoriah Waterland struct group * 593*5c51f124SMoriah Waterland clgrnam(char *nam) 594*5c51f124SMoriah Waterland { 595*5c51f124SMoriah Waterland struct group *gr; 596*5c51f124SMoriah Waterland char *instroot, *buf; 597*5c51f124SMoriah Waterland FILE *gr_ptr; 598*5c51f124SMoriah Waterland 599*5c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 600*5c51f124SMoriah Waterland if ((buf = (char *)malloc(strlen(instroot) + 601*5c51f124SMoriah Waterland strlen(GROUP) + 1)) == NULL) { 602*5c51f124SMoriah Waterland (void) fprintf(stderr, 603*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clgrnam()", 604*5c51f124SMoriah Waterland strlen(instroot) + strlen(GROUP), "buf"); 605*5c51f124SMoriah Waterland } 606*5c51f124SMoriah Waterland (void) sprintf(buf, "%s%s", instroot, GROUP); 607*5c51f124SMoriah Waterland if ((gr_ptr = fopen(buf, "r")) == NULL) { 608*5c51f124SMoriah Waterland free(buf); 609*5c51f124SMoriah Waterland return (NULL); 610*5c51f124SMoriah Waterland } else { 611*5c51f124SMoriah Waterland while ((gr = fgetgrent(gr_ptr)) != NULL) { 612*5c51f124SMoriah Waterland if (strcmp(gr->gr_name, nam) == 0) { 613*5c51f124SMoriah Waterland break; 614*5c51f124SMoriah Waterland } 615*5c51f124SMoriah Waterland } 616*5c51f124SMoriah Waterland } 617*5c51f124SMoriah Waterland free(buf); 618*5c51f124SMoriah Waterland (void) fclose(gr_ptr); 619*5c51f124SMoriah Waterland return (gr); 620*5c51f124SMoriah Waterland } else { 621*5c51f124SMoriah Waterland return (NULL); 622*5c51f124SMoriah Waterland } 623*5c51f124SMoriah Waterland } 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland /* 626*5c51f124SMoriah Waterland * Check the client's etc/passwd file for the user name 627*5c51f124SMoriah Waterland * 628*5c51f124SMoriah Waterland * returns a pointer to the passwd structure if the passwd is found 629*5c51f124SMoriah Waterland * returns NULL if not found 630*5c51f124SMoriah Waterland */ 631*5c51f124SMoriah Waterland struct passwd * 632*5c51f124SMoriah Waterland clpwnam(char *nam) 633*5c51f124SMoriah Waterland { 634*5c51f124SMoriah Waterland struct passwd *pw; 635*5c51f124SMoriah Waterland char *instroot, *buf; 636*5c51f124SMoriah Waterland FILE *pw_ptr; 637*5c51f124SMoriah Waterland 638*5c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 639*5c51f124SMoriah Waterland if ((buf = (char *)malloc(strlen(instroot) + 640*5c51f124SMoriah Waterland strlen(PASSWD) + 1)) == NULL) { 641*5c51f124SMoriah Waterland (void) fprintf(stderr, 642*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clpwnam()", 643*5c51f124SMoriah Waterland strlen(instroot) + strlen(PASSWD), "buf"); 644*5c51f124SMoriah Waterland } 645*5c51f124SMoriah Waterland (void) sprintf(buf, "%s%s", instroot, PASSWD); 646*5c51f124SMoriah Waterland if ((pw_ptr = fopen(buf, "r")) == NULL) { 647*5c51f124SMoriah Waterland free(buf); 648*5c51f124SMoriah Waterland return (NULL); 649*5c51f124SMoriah Waterland } else { 650*5c51f124SMoriah Waterland while ((pw = fgetpwent(pw_ptr)) != NULL) { 651*5c51f124SMoriah Waterland if (strcmp(pw->pw_name, nam) == 0) { 652*5c51f124SMoriah Waterland break; 653*5c51f124SMoriah Waterland } 654*5c51f124SMoriah Waterland } 655*5c51f124SMoriah Waterland } 656*5c51f124SMoriah Waterland free(buf); 657*5c51f124SMoriah Waterland (void) fclose(pw_ptr); 658*5c51f124SMoriah Waterland return (pw); 659*5c51f124SMoriah Waterland } else { 660*5c51f124SMoriah Waterland return (NULL); 661*5c51f124SMoriah Waterland } 662*5c51f124SMoriah Waterland } 663*5c51f124SMoriah Waterland 664*5c51f124SMoriah Waterland /* 665*5c51f124SMoriah Waterland * Check the client's etc/group file for the group id 666*5c51f124SMoriah Waterland * 667*5c51f124SMoriah Waterland * returns a pointer to the group structure if the group id is found 668*5c51f124SMoriah Waterland * returns NULL if not found 669*5c51f124SMoriah Waterland */ 670*5c51f124SMoriah Waterland struct group * 671*5c51f124SMoriah Waterland clgrgid(gid_t gid) 672*5c51f124SMoriah Waterland { 673*5c51f124SMoriah Waterland struct group *gr; 674*5c51f124SMoriah Waterland char *instroot, *buf; 675*5c51f124SMoriah Waterland FILE *gr_ptr; 676*5c51f124SMoriah Waterland 677*5c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 678*5c51f124SMoriah Waterland if ((buf = (char *)malloc(strlen(instroot) + 679*5c51f124SMoriah Waterland strlen(GROUP) + 1)) == NULL) { 680*5c51f124SMoriah Waterland (void) fprintf(stderr, 681*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clgrgid()", 682*5c51f124SMoriah Waterland strlen(instroot) + strlen(GROUP), "buf"); 683*5c51f124SMoriah Waterland } 684*5c51f124SMoriah Waterland (void) sprintf(buf, "%s%s", instroot, GROUP); 685*5c51f124SMoriah Waterland if ((gr_ptr = fopen(buf, "r")) == NULL) { 686*5c51f124SMoriah Waterland free(buf); 687*5c51f124SMoriah Waterland return (NULL); 688*5c51f124SMoriah Waterland } else { 689*5c51f124SMoriah Waterland while ((gr = fgetgrent(gr_ptr)) != NULL) { 690*5c51f124SMoriah Waterland if (gr->gr_gid == gid) { 691*5c51f124SMoriah Waterland break; 692*5c51f124SMoriah Waterland } 693*5c51f124SMoriah Waterland } 694*5c51f124SMoriah Waterland } 695*5c51f124SMoriah Waterland free(buf); 696*5c51f124SMoriah Waterland (void) fclose(gr_ptr); 697*5c51f124SMoriah Waterland return (gr); 698*5c51f124SMoriah Waterland } else { 699*5c51f124SMoriah Waterland return (NULL); 700*5c51f124SMoriah Waterland } 701*5c51f124SMoriah Waterland } 702*5c51f124SMoriah Waterland 703*5c51f124SMoriah Waterland /* 704*5c51f124SMoriah Waterland * Check the client's etc/passwd file for the user id 705*5c51f124SMoriah Waterland * 706*5c51f124SMoriah Waterland * returns a pointer to the passwd structure if the user id is found 707*5c51f124SMoriah Waterland * returns NULL if not found 708*5c51f124SMoriah Waterland */ 709*5c51f124SMoriah Waterland struct passwd * 710*5c51f124SMoriah Waterland clpwuid(uid_t uid) 711*5c51f124SMoriah Waterland { 712*5c51f124SMoriah Waterland struct passwd *pw; 713*5c51f124SMoriah Waterland char *instroot, *buf; 714*5c51f124SMoriah Waterland FILE *pw_ptr; 715*5c51f124SMoriah Waterland 716*5c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 717*5c51f124SMoriah Waterland if ((buf = (char *)malloc(strlen(instroot) + 718*5c51f124SMoriah Waterland strlen(PASSWD) + 1)) == NULL) { 719*5c51f124SMoriah Waterland (void) fprintf(stderr, 720*5c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clpwuid()", 721*5c51f124SMoriah Waterland strlen(instroot) + strlen(PASSWD), "buf"); 722*5c51f124SMoriah Waterland } 723*5c51f124SMoriah Waterland (void) sprintf(buf, "%s%s", instroot, PASSWD); 724*5c51f124SMoriah Waterland if ((pw_ptr = fopen(buf, "r")) == NULL) { 725*5c51f124SMoriah Waterland free(buf); 726*5c51f124SMoriah Waterland return (NULL); 727*5c51f124SMoriah Waterland } else { 728*5c51f124SMoriah Waterland while ((pw = fgetpwent(pw_ptr)) != NULL) { 729*5c51f124SMoriah Waterland if (pw->pw_uid == uid) { 730*5c51f124SMoriah Waterland break; 731*5c51f124SMoriah Waterland } 732*5c51f124SMoriah Waterland } 733*5c51f124SMoriah Waterland } 734*5c51f124SMoriah Waterland free(buf); 735*5c51f124SMoriah Waterland (void) fclose(pw_ptr); 736*5c51f124SMoriah Waterland return (pw); 737*5c51f124SMoriah Waterland } else { 738*5c51f124SMoriah Waterland return (NULL); 739*5c51f124SMoriah Waterland } 740*5c51f124SMoriah Waterland } 741