1204861Sdes/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */ 2204861Sdes/* 3204861Sdes * Copyright (c) 1989, 1993 4204861Sdes * The Regents of the University of California. All rights reserved. 5204861Sdes * 6204861Sdes * Redistribution and use in source and binary forms, with or without 7204861Sdes * modification, are permitted provided that the following conditions 8204861Sdes * are met: 9204861Sdes * 1. Redistributions of source code must retain the above copyright 10204861Sdes * notice, this list of conditions and the following disclaimer. 11204861Sdes * 2. Redistributions in binary form must reproduce the above copyright 12204861Sdes * notice, this list of conditions and the following disclaimer in the 13204861Sdes * documentation and/or other materials provided with the distribution. 14204861Sdes * 3. Neither the name of the University nor the names of its contributors 15204861Sdes * may be used to endorse or promote products derived from this software 16204861Sdes * without specific prior written permission. 17204861Sdes * 18204861Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19204861Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20204861Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21204861Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22204861Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23204861Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24204861Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25204861Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26204861Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27204861Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28204861Sdes * SUCH DAMAGE. 29204861Sdes */ 30204861Sdes 31204861Sdes/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */ 32204861Sdes 33204861Sdes#include "includes.h" 34204861Sdes 35204861Sdes#include <sys/types.h> 36204861Sdes 37204861Sdes#include <grp.h> 38204861Sdes#include <pwd.h> 39204861Sdes#include <stdio.h> 40204861Sdes#include <stdlib.h> 41204861Sdes#include <string.h> 42204861Sdes 43204861Sdes#define NCACHE 64 /* power of 2 */ 44204861Sdes#define MASK (NCACHE - 1) /* bits to store with */ 45204861Sdes 46204861Sdes#ifndef HAVE_USER_FROM_UID 47204861Sdeschar * 48204861Sdesuser_from_uid(uid_t uid, int nouser) 49204861Sdes{ 50204861Sdes static struct ncache { 51204861Sdes uid_t uid; 52204861Sdes char *name; 53204861Sdes } c_uid[NCACHE]; 54204861Sdes static int pwopen; 55204861Sdes static char nbuf[15]; /* 32 bits == 10 digits */ 56204861Sdes struct passwd *pw; 57204861Sdes struct ncache *cp; 58204861Sdes 59204861Sdes cp = c_uid + (uid & MASK); 60204861Sdes if (cp->uid != uid || cp->name == NULL) { 61204861Sdes if (pwopen == 0) { 62204861Sdes#ifdef HAVE_SETPASSENT 63204861Sdes setpassent(1); 64204861Sdes#endif 65204861Sdes pwopen = 1; 66204861Sdes } 67204861Sdes if ((pw = getpwuid(uid)) == NULL) { 68204861Sdes if (nouser) 69204861Sdes return (NULL); 70204861Sdes (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); 71204861Sdes } 72204861Sdes cp->uid = uid; 73204861Sdes if (cp->name != NULL) 74204861Sdes free(cp->name); 75204861Sdes cp->name = strdup(pw ? pw->pw_name : nbuf); 76204861Sdes } 77204861Sdes return (cp->name); 78204861Sdes} 79204861Sdes#endif 80204861Sdes 81204861Sdes#ifndef HAVE_GROUP_FROM_GID 82204861Sdeschar * 83204861Sdesgroup_from_gid(gid_t gid, int nogroup) 84204861Sdes{ 85204861Sdes static struct ncache { 86204861Sdes gid_t gid; 87204861Sdes char *name; 88204861Sdes } c_gid[NCACHE]; 89204861Sdes static int gropen; 90204861Sdes static char nbuf[15]; /* 32 bits == 10 digits */ 91204861Sdes struct group *gr; 92204861Sdes struct ncache *cp; 93204861Sdes 94204861Sdes cp = c_gid + (gid & MASK); 95204861Sdes if (cp->gid != gid || cp->name == NULL) { 96204861Sdes if (gropen == 0) { 97204861Sdes#ifdef HAVE_SETGROUPENT 98204861Sdes setgroupent(1); 99204861Sdes#endif 100204861Sdes gropen = 1; 101204861Sdes } 102204861Sdes if ((gr = getgrgid(gid)) == NULL) { 103204861Sdes if (nogroup) 104204861Sdes return (NULL); 105204861Sdes (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); 106204861Sdes } 107204861Sdes cp->gid = gid; 108204861Sdes if (cp->name != NULL) 109204861Sdes free(cp->name); 110204861Sdes cp->name = strdup(gr ? gr->gr_name : nbuf); 111204861Sdes } 112204861Sdes return (cp->name); 113204861Sdes} 114204861Sdes#endif 115