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