- Implement pwcache_userdb(3), which changes the routines that

user_from_uid(3) and uid_from_user(3) use to lookup user information.
- Implement pwcache_groupdb(3), which changes the routines that
  group_from_gid(3) and gid_from_group(3) use to lookup group information.
- Ensure that private functions in pwcache.c are declared static
- Use strlcpy(3) instead of strncpy(3)
This commit is contained in:
lukem 2002-01-24 02:46:32 +00:00
parent d4da6dc52d
commit 463cd54319
7 changed files with 330 additions and 59 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: grp.h,v 1.14 1998/07/28 16:27:48 mycroft Exp $ */
/* $NetBSD: grp.h,v 1.15 2002/01/24 02:46:33 lukem Exp $ */
/*-
* Copyright (c) 1989, 1993
@ -71,6 +71,9 @@ void setgrfile __P((const char *));
int setgroupent __P((int));
const char *group_from_gid __P((gid_t, int));
int gid_from_group __P((const char *, gid_t *));
int pwcache_groupdb(int (*)(int), void (*)(void),
struct group * (*)(const char *),
struct group * (*)(gid_t));
#endif
__END_DECLS

View File

@ -1,4 +1,4 @@
/* $NetBSD: pwd.h,v 1.23 2001/10/23 00:25:20 lukem Exp $ */
/* $NetBSD: pwd.h,v 1.24 2002/01/24 02:46:32 lukem Exp $ */
/*-
* Copyright (c) 1989, 1993
@ -110,6 +110,9 @@ int pw_scan __P((char *bp, struct passwd *pw, int *flags));
int setpassent __P((int));
const char *user_from_uid __P((uid_t, int));
int uid_from_user __P((const char *, uid_t *));
int pwcache_userdb(int (*)(int), void (*)(void),
struct passwd * (*)(const char *),
struct passwd * (*)(uid_t));
#endif
__END_DECLS

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.108 2001/05/07 17:25:57 kleink Exp $
# $NetBSD: Makefile.inc,v 1.109 2002/01/24 02:46:35 lukem Exp $
# from: @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
# gen sources
@ -94,6 +94,7 @@ MLINKS+=popen.3 pclose.3
MLINKS+=psignal.3 sys_siglist.3 psignal.3 sys_signame.3
MLINKS+=pwcache.3 user_from_uid.3 pwcache.3 group_from_gid.3
MLINKS+=pwcache.3 uid_from_user.3 pwcache.3 gid_from_group.3
MLINKS+=pwcache.3 pwcache_userdb.3 pwcache.3 pwcache_groupdb.3
MLINKS+=scandir.3 alphasort.3
MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
setjmp.3 longjmperror.3 setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3

View File

@ -1,4 +1,4 @@
.\" $NetBSD: pwcache.3,v 1.10 2001/09/16 02:30:25 wiz Exp $
.\" $NetBSD: pwcache.3,v 1.11 2002/01/24 02:46:35 lukem Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -31,9 +31,42 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\"
.\" @(#)pwcache.3 8.1 (Berkeley) 6/9/93
.\"
.Dd July 28, 1998
.Dd January 24, 2002
.Dt PWCACHE 3
.Os
.Sh NAME
@ -49,11 +82,15 @@
.Fn user_from_uid "uid_t uid" "int nouser"
.Ft int
.Fn uid_from_user "const char *name" "uid_t *uid"
.Ft int
.Fn pwcache_userdb "int (*setpassent)(int)" "void (*endpwent)(void)" "struct passwd * (*getpwnam)(const char *)" "struct passwd * (*getpwuid)(uid_t)"
.Fd #include <grp.h>
.Ft const char *
.Fn group_from_gid "gid_t gid" "int nogroup"
.Ft int
.Fn gid_from_group "const char *name" "gid_t *gid"
.Ft int
.Fn pwcache_groupdb "int (*setgroupent)(int)" "void (*endgrent)(void)" "struct group * (*getgrnam)(const char *)" "struct group * (*getgrgid)(gid_t)"
.Sh DESCRIPTION
The
.Fn user_from_uid
@ -124,6 +161,48 @@ the
function returns -1; otherwise it stores the gid at the location pointed to by
.Fa gid
and returns 0.
.Pp
The
.Fn pwcache_userdb
function changes the user database access routines which
.Fn user_from_uid
and
.Fn uid_from_user
call to search for users.
The caches are flushed and the existing
.Fn endpwent
method is called before switching to the new routines.
.Fa getpwnam
and
.Fa getpwuid
must be provided, and
.Fa setpassent
and
.Fa endpwent
may be
.Dv NULL
pointers.
.Pp
The
.Fn pwcache_groupdb
function changes the group database access routines which
.Fn group_from_gid
and
.Fn gid_from_group
call to search for groups.
The caches are flushed and the existing
.Fn endgrent
method is called before switching to the new routines.
.Fa getgrnam
and
.Fa getgrgid
must be provided, and
.Fa setgroupent
and
.Fa endgrent
may be
.Dv NULL
pointers.
.Sh SEE ALSO
.Xr getgrgid 3 ,
.Xr getgrnam 3 ,
@ -143,3 +222,10 @@ and
.Fn gid_from_group
functions first appeared in
.Nx 1.4 .
.Pp
The
.Fn pwcache_userdb
and
.Fn pwcache_groupdb
functions first appeared in
.Nx 1.6 .

View File

@ -1,4 +1,4 @@
/* $NetBSD: pwcache.c,v 1.16 2002/01/04 14:50:29 lukem Exp $ */
/* $NetBSD: pwcache.c,v 1.17 2002/01/24 02:46:35 lukem Exp $ */
/*-
* Copyright (c) 1992 Keith Muller.
@ -37,12 +37,45 @@
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: pwcache.c,v 1.16 2002/01/04 14:50:29 lukem Exp $");
__RCSID("$NetBSD: pwcache.c,v 1.17 2002/01/24 02:46:35 lukem Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -64,6 +97,8 @@ __RCSID("$NetBSD: pwcache.c,v 1.16 2002/01/04 14:50:29 lukem Exp $");
#ifdef __weak_alias
__weak_alias(user_from_uid,_user_from_uid)
__weak_alias(group_from_gid,_group_from_gid)
__weak_alias(pwcache_userdb,_pwcache_userdb)
__weak_alias(pwcache_groupdb,_pwcache_groupdb)
#endif
/*
@ -73,18 +108,41 @@ __weak_alias(group_from_gid,_group_from_gid)
* these routines cache BOTH hits and misses, a major performance improvement
*/
static int pwopn = 0; /* is password file open */
static int gropn = 0; /* is group file open */
static UIDC **uidtb = NULL; /* uid to name cache */
static GIDC **gidtb = NULL; /* gid to name cache */
static UIDC **usrtb = NULL; /* user name to uid cache */
static GIDC **grptb = NULL; /* group name to gid cache */
/*
* function pointers to various name lookup routines.
* these may be changed as necessary.
*/
static int (*_pwcache_setgroupent)(int) = setgroupent;
static void (*_pwcache_endgrent)(void) = endgrent;
static struct group * (*_pwcache_getgrnam)(const char *) = getgrnam;
static struct group * (*_pwcache_getgrgid)(gid_t) = getgrgid;
static int (*_pwcache_setpassent)(int) = setpassent;
static void (*_pwcache_endpwent)(void) = endpwent;
static struct passwd * (*_pwcache_getpwnam)(const char *) = getpwnam;
static struct passwd * (*_pwcache_getpwuid)(uid_t) = getpwuid;
/*
* internal state
*/
static int pwopn; /* is password file open */
static int gropn; /* is group file open */
static UIDC **uidtb; /* uid to name cache */
static GIDC **gidtb; /* gid to name cache */
static UIDC **usrtb; /* user name to uid cache */
static GIDC **grptb; /* group name to gid cache */
static int uidtb_fail; /* uidtb_start() failed ? */
static int gidtb_fail; /* gidtb_start() failed ? */
static int usrtb_fail; /* usrtb_start() failed ? */
static int grptb_fail; /* grptb_start() failed ? */
static u_int st_hash(const char *, size_t, int);
static int uidtb_start(void);
static int gidtb_start(void);
static int usrtb_start(void);
static int grptb_start(void);
static u_int st_hash(const char *, size_t, int);
static int uidtb_start(void);
static int gidtb_start(void);
static int usrtb_start(void);
static int grptb_start(void);
static u_int
st_hash(const char *name, size_t len, int tabsz)
@ -107,18 +165,16 @@ st_hash(const char *name, size_t len, int tabsz)
* Return:
* 0 if ok, -1 otherwise
*/
static int
uidtb_start(void)
{
static int fail = 0;
if (uidtb != NULL)
return (0);
if (fail)
if (uidtb_fail)
return (-1);
if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
++fail;
++uidtb_fail;
return (-1);
}
return (0);
@ -130,18 +186,16 @@ uidtb_start(void)
* Return:
* 0 if ok, -1 otherwise
*/
int
static int
gidtb_start(void)
{
static int fail = 0;
if (gidtb != NULL)
return (0);
if (fail)
if (gidtb_fail)
return (-1);
if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
++fail;
++gidtb_fail;
return (-1);
}
return (0);
@ -153,18 +207,16 @@ gidtb_start(void)
* Return:
* 0 if ok, -1 otherwise
*/
int
static int
usrtb_start(void)
{
static int fail = 0;
if (usrtb != NULL)
return (0);
if (fail)
if (usrtb_fail)
return (-1);
if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
++fail;
++usrtb_fail;
return (-1);
}
return (0);
@ -176,18 +228,16 @@ usrtb_start(void)
* Return:
* 0 if ok, -1 otherwise
*/
int
static int
grptb_start(void)
{
static int fail = 0;
if (grptb != NULL)
return (0);
if (fail)
if (grptb_fail)
return (-1);
if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
++fail;
++grptb_fail;
return (-1);
}
return (0);
@ -230,14 +280,15 @@ user_from_uid(uid_t uid, int noname)
* No entry for this uid, we will add it
*/
if (!pwopn) {
setpassent(1);
if (_pwcache_setpassent != NULL)
(*_pwcache_setpassent)(1);
++pwopn;
}
if (ptr == NULL)
*pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
if ((pw = getpwuid(uid)) == NULL) {
if ((pw = (*_pwcache_getpwuid)(uid)) == NULL) {
/*
* no match for this uid in the local password file
* a string that is the uid in numberic format
@ -256,8 +307,7 @@ user_from_uid(uid_t uid, int noname)
if (ptr == NULL)
return (pw->pw_name);
ptr->uid = uid;
(void)strncpy(ptr->name, pw->pw_name, UNMLEN);
ptr->name[UNMLEN-1] = '\0';
(void)strlcpy(ptr->name, pw->pw_name, UNMLEN);
ptr->valid = VALID;
}
return (ptr->name);
@ -300,14 +350,15 @@ group_from_gid(gid_t gid, int noname)
* No entry for this gid, we will add it
*/
if (!gropn) {
setgroupent(1);
if (_pwcache_setgroupent != NULL)
(*_pwcache_setgroupent)(1);
++gropn;
}
if (ptr == NULL)
*pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
if ((gr = getgrgid(gid)) == NULL) {
if ((gr = (*_pwcache_getgrgid)(gid)) == NULL) {
/*
* no match for this gid in the local group file, put in
* a string that is the gid in numberic format
@ -326,8 +377,7 @@ group_from_gid(gid_t gid, int noname)
if (ptr == NULL)
return (gr->gr_name);
ptr->gid = gid;
(void)strncpy(ptr->name, gr->gr_name, GNMLEN);
ptr->name[GNMLEN-1] = '\0';
(void)strlcpy(ptr->name, gr->gr_name, GNMLEN);
ptr->valid = VALID;
}
return (ptr->name);
@ -370,7 +420,8 @@ uid_from_user(const char *name, uid_t *uid)
}
if (!pwopn) {
setpassent(1);
if (_pwcache_setpassent != NULL)
(*_pwcache_setpassent)(1);
++pwopn;
}
@ -382,14 +433,13 @@ uid_from_user(const char *name, uid_t *uid)
* or store the matching uid
*/
if (ptr == NULL) {
if ((pw = getpwnam(name)) == NULL)
if ((pw = (*_pwcache_getpwnam)(name)) == NULL)
return (-1);
*uid = pw->pw_uid;
return (0);
}
(void)strncpy(ptr->name, name, UNMLEN);
ptr->name[UNMLEN-1] = '\0';
if ((pw = getpwnam(name)) == NULL) {
(void)strlcpy(ptr->name, name, UNMLEN);
if ((pw = (*_pwcache_getpwnam)(name)) == NULL) {
ptr->valid = INVALID;
return (-1);
}
@ -435,7 +485,8 @@ gid_from_group(const char *name, gid_t *gid)
}
if (!gropn) {
setgroupent(1);
if (_pwcache_setgroupent != NULL)
(*_pwcache_setgroupent)(1);
++gropn;
}
@ -447,15 +498,14 @@ gid_from_group(const char *name, gid_t *gid)
* or store the matching gid
*/
if (ptr == NULL) {
if ((gr = getgrnam(name)) == NULL)
if ((gr = (*_pwcache_getgrnam)(name)) == NULL)
return (-1);
*gid = gr->gr_gid;
return (0);
}
(void)strncpy(ptr->name, name, GNMLEN);
ptr->name[GNMLEN-1] = '\0';
if ((gr = getgrnam(name)) == NULL) {
(void)strlcpy(ptr->name, name, GNMLEN);
if ((gr = (*_pwcache_getgrnam)(name)) == NULL) {
ptr->valid = INVALID;
return (-1);
}
@ -463,3 +513,129 @@ gid_from_group(const char *name, gid_t *gid)
*gid = ptr->gid = gr->gr_gid;
return (0);
}
#define FLUSHTB(arr, len, fail) \
do { \
if (arr != NULL) { \
for (i = 0; i < len; i++) \
if (arr[i] != NULL) \
free(arr[i]); \
arr = NULL; \
} \
fail = 0; \
} while (/* CONSTCOND */0);
int
pwcache_userdb(
int (*a_setpassent)(int),
void (*a_endpwent)(void),
struct passwd * (*a_getpwnam)(const char *),
struct passwd * (*a_getpwuid)(uid_t))
{
int i;
/* a_setpassent and a_endpwent may be NULL */
if (a_getpwnam == NULL || a_getpwuid == NULL)
return (-1);
if (_pwcache_endpwent != NULL)
(*_pwcache_endpwent)();
FLUSHTB(uidtb, UID_SZ, uidtb_fail);
FLUSHTB(usrtb, UNM_SZ, usrtb_fail);
pwopn = 0;
_pwcache_setpassent = a_setpassent;
_pwcache_endpwent = a_endpwent;
_pwcache_getpwnam = a_getpwnam;
_pwcache_getpwuid = a_getpwuid;
return (0);
}
int
pwcache_groupdb(
int (*a_setgroupent)(int),
void (*a_endgrent)(void),
struct group * (*a_getgrnam)(const char *),
struct group * (*a_getgrgid)(gid_t))
{
int i;
/* a_setgroupent and a_endgrent may be NULL */
if (a_getgrnam == NULL || a_getgrgid == NULL)
return (-1);
if (_pwcache_endgrent != NULL)
(*_pwcache_endgrent)();
FLUSHTB(gidtb, GID_SZ, gidtb_fail);
FLUSHTB(grptb, GNM_SZ, grptb_fail);
gropn = 0;
_pwcache_setgroupent = a_setgroupent;
_pwcache_endgrent = a_endgrent;
_pwcache_getgrnam = a_getgrnam;
_pwcache_getgrgid = a_getgrgid;
return (0);
}
#ifdef TEST_PWCACHE
struct passwd *
test_getpwnam(const char *name)
{
static struct passwd foo;
memset(&foo, 0, sizeof(foo));
if (strcmp(name, "toor") == 0) {
foo.pw_uid = 666;
return &foo;
}
return (getpwnam(name));
}
int
main(int argc, char *argv[])
{
uid_t u;
int r, i;
printf("pass 1 (default userdb)\n");
for (i = 1; i < argc; i++) {
printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n",
i, pwopn, usrtb_fail, usrtb);
r = uid_from_user(argv[i], &u);
if (r == -1)
printf(" uid_from_user %s: failed\n", argv[i]);
else
printf(" uid_from_user %s: %d\n", argv[i], u);
}
printf("pass 1 finish: pwopn %d usrtb_fail %d usrtb %p\n",
pwopn, usrtb_fail, usrtb);
puts("");
printf("pass 2 (replacement userdb)\n");
printf("pwcache_userdb returned %d\n",
pwcache_userdb(setpassent, test_getpwnam, getpwuid));
printf("pwopn %d usrtb_fail %d usrtb %p\n", pwopn, usrtb_fail, usrtb);
for (i = 1; i < argc; i++) {
printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n",
i, pwopn, usrtb_fail, usrtb);
u = -1;
r = uid_from_user(argv[i], &u);
if (r == -1)
printf(" uid_from_user %s: failed\n", argv[i]);
else
printf(" uid_from_user %s: %d\n", argv[i], u);
}
printf("pass 2 finish: pwopn %d usrtb_fail %d usrtb %p\n",
pwopn, usrtb_fail, usrtb);
puts("");
printf("pass 3 (null pointers)\n");
printf("pwcache_userdb returned %d\n",
pwcache_userdb(NULL, NULL, NULL));
return (0);
}
#endif /* TEST_PWCACHE */

View File

@ -1,7 +1,7 @@
/* $NetBSD: namespace.h,v 1.69 2002/01/14 00:55:57 thorpej Exp $ */
/* $NetBSD: namespace.h,v 1.70 2002/01/24 02:46:34 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -357,6 +357,8 @@
#define pread _pread
#define psignal _psignal
#define putenv _putenv
#define pwcache_userdb _pwcache_userdb
#define pwcache_groupdb _pwcache_groupdb
#define pwrite _pwrite
#define qabs _qabs
#define qdiv _qdiv

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.111 2001/12/07 11:49:58 yamt Exp $
# $NetBSD: shlib_version,v 1.112 2002/01/24 02:46:34 lukem Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -9,4 +9,4 @@
# - libc/gen/timezone.c: remove; __timezone13 -> timezone.
#
major=12
minor=81
minor=82