diff options
author | David Leonard <d@cvs.openbsd.org> | 2000-04-25 12:21:06 +0000 |
---|---|---|
committer | David Leonard <d@cvs.openbsd.org> | 2000-04-25 12:21:06 +0000 |
commit | 42a3e3db30a7ec02d6dc29d9879f2124a0123876 (patch) | |
tree | 851eddfa1c72819d6dd1d805b3aeef49b2d5b0af /lib/libc/gen | |
parent | f16688857dfc72f7a7535288147532bdc4eda2f3 (diff) |
getpw*_r()
Diffstat (limited to 'lib/libc/gen')
-rw-r--r-- | lib/libc/gen/Makefile.inc | 5 | ||||
-rw-r--r-- | lib/libc/gen/getpwent.3 | 45 | ||||
-rw-r--r-- | lib/libc/gen/getpwent.c | 142 |
3 files changed, 179 insertions, 13 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 48086f5a9d4..963b3c6afab 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.22 2000/03/23 22:22:00 d Exp $ +# $OpenBSD: Makefile.inc,v 1.23 2000/04/25 12:21:05 d Exp $ # gen sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gen ${LIBCSRCDIR}/gen @@ -83,7 +83,8 @@ MLINKS+=gethostname.3 sethostname.3 MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 innetgr.3 \ getnetgrent.3 setnetgrent.3 MLINKS+=getpwent.3 endpwent.3 getpwent.3 setpassent.3 getpwent.3 getpwnam.3 \ - getpwent.3 getpwuid.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3 + getpwent.3 getpwuid.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3 \ + getpwent.3 getpwuid_r.3 getpwent.3 getpwnam_r.3 MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 getttyent.3 setttyent.3 MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3 MLINKS+=glob.3 globfree.3 diff --git a/lib/libc/gen/getpwent.3 b/lib/libc/gen/getpwent.3 index 879c1a41739..96e8bebfb4d 100644 --- a/lib/libc/gen/getpwent.3 +++ b/lib/libc/gen/getpwent.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: getpwent.3,v 1.11 2000/04/18 03:01:27 aaron Exp $ +.\" $OpenBSD: getpwent.3,v 1.12 2000/04/25 12:21:05 d Exp $ .\" .\" Copyright (c) 1988, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -37,7 +37,9 @@ .Sh NAME .Nm getpwent , .Nm getpwnam , +.Nm getpwnam_r , .Nm getpwuid , +.Nm getpwuid_r , .Nm setpassent , .Nm setpwent , .Nm endpwent @@ -49,9 +51,13 @@ .Fn getpwent void .Ft struct passwd * .Fn getpwnam "const char *login" +.Ft int +.Fn getpwnam_r "const char *login" "struct passwd *pwd" "char *buffer" "size_t bufsize" "struct passwd **result" .Ft struct passwd * .Fn getpwuid "uid_t uid" .Ft int +.Fn getpwuid_r "uid_t uid" "struct passwd *pwd" "char *buffer" "size_t bufsize" "struct passwd **result" +.Ft int .Fn setpassent "int stayopen" .Ft void .Fn setpwent void @@ -129,6 +135,29 @@ If the process which calls them has an effective UID of 0, the encrypted password will be returned, otherwise, the password field of the returned structure will point to the string .Ql * . +.Pp +The +.Fn getpwuid_r +and +.Fn getpwnam_r +functions both update the passwd structure pointed to by +.Fa pwd +and store a pointer to that structure at the location pointed to by +.Fa result . +The structure shall contain an entry from the user database with a matching +.Fa uid +or +.Fa login . +Storage referenced by the structure shall be allocated from the memory +provided with the +.Fa buffer +parameter, which is +.Fa bufsize +characters in size. +.\" The maximum size needed for this buffer can be determined with the +.\" _SC_GETPW_R_SIZE_MAX +.\" .Xr sysconf 2 +.\" parameter. .Sh RETURN VALUES The functions .Fn getpwent , @@ -146,6 +175,20 @@ and .Fn setpwent functions have no return value. +The functions +.Fn getpwuid_r +and +.Fn getpwnam_r +return a null pointer in the location pointed to by +.Fa result +and return the error number +on error or if the requested entry is not found. +The error value +.Ev ERANGE +is returned if insufficient storage was supplied via +.Fa buffer +and +.Fa bufsize. .Sh FILES .Bl -tag -width /etc/master.passwd -compact .It Pa /etc/pwd.db diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 0351abd9f26..3b2cc4082ae 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -33,7 +33,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getpwent.c,v 1.17 1999/09/15 08:57:25 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: getpwent.c,v 1.18 2000/04/25 12:21:05 d Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -56,6 +56,9 @@ static char rcsid[] = "$OpenBSD: getpwent.c,v 1.17 1999/09/15 08:57:25 deraadt E #include <rpcsvc/ypclnt.h> #include "ypinternal.h" #endif +#include "thread_private.h" + +_THREAD_PRIVATE_MUTEX(pw); static struct passwd _pw_passwd; /* password structure */ static DB *_pw_db; /* password database */ @@ -97,6 +100,9 @@ struct _ypexclude { }; static struct _ypexclude *__ypexclude = (struct _ypexclude *)NULL; +static struct passwd *getpwnam_unlocked __P((const char *)); +static struct passwd *getpwuid_unlocked __P((uid_t)); + /* * Using DB for this just wastes too damn much memory. */ @@ -320,8 +326,13 @@ getpwent() const char *user, *host, *dom; #endif - if (!_pw_db && !__initdb()) + _THREAD_PRIVATE_MUTEX_LOCK(pw); + + if (!_pw_db && !__initdb()) { + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return ((struct passwd *)NULL); + } + #ifdef YP if (__getpwent_has_yppw == -1) @@ -426,6 +437,7 @@ again: __ypline[datalen] = '\0'; if (__ypparse(&_pw_passwd, __ypline)) goto again; + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return &_pw_passwd; } #endif @@ -479,8 +491,10 @@ again: } } #endif + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return &_pw_passwd; } + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (struct passwd *)NULL; } @@ -566,8 +580,8 @@ __has_ypmaster() } #endif -struct passwd * -getpwnam(name) +static struct passwd * +getpwnam_unlocked(name) const char *name; { DBT key; @@ -744,13 +758,9 @@ pwnam_netgrp: return (rval ? &_pw_passwd : (struct passwd *)NULL); } -struct passwd * -#ifdef __STDC__ -getpwuid(uid_t uid) -#else -getpwuid(uid) +static struct passwd * +getpwuid_unlocked (uid) uid_t uid; -#endif { DBT key; char bf[sizeof(_pw_keynum) + 1]; @@ -924,10 +934,119 @@ pwuid_netgrp: return (rval ? &_pw_passwd : (struct passwd *)NULL); } +/* XXX copy static storage into user's buffer */ +static int +fill_reent(src, pwd, buffer, bufsize, result) + struct passwd *src; + struct passwd *pwd; + char *buffer; + size_t bufsize; + struct passwd **result; +{ + int len; + + *result = NULL; + if (src == NULL) { + if (errno == 0) + return ENOENT; + return errno; + } + +#define fill_alloc(field) \ + if (src->field == NULL) \ + pwd->field = NULL; \ + else { \ + len = strlen(src->field) + 1; \ + if (len > bufsize) \ + return ERANGE; \ + memcpy(buffer, src->field, len); \ + pwd->field = buffer; \ + buffer += len; \ + bufsize -= len; \ + } + + fill_alloc(pw_name) + fill_alloc(pw_passwd) + pwd->pw_uid = src->pw_uid; + pwd->pw_gid = src->pw_gid; + pwd->pw_change = src->pw_change; + fill_alloc(pw_class) + fill_alloc(pw_gecos) + fill_alloc(pw_dir) + fill_alloc(pw_shell) + pwd->pw_expire = src->pw_expire; + +#undef fill_alloc + + *result = pwd; + return 0; +} + +struct passwd * +getpwnam(name) + const char *name; +{ + struct passwd *ret; + + _THREAD_PRIVATE_MUTEX_LOCK(pw); + ret = getpwnam_unlocked(name); + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); + return ret; +} + +int +getpwnam_r(name, pwd, buffer, bufsize, result) + const char *name; + struct passwd *pwd; + char *buffer; + size_t bufsize; + struct passwd **result; +{ + int error; + struct passwd *pw; + + _THREAD_PRIVATE_MUTEX_LOCK(pw); + pw = getpwnam_unlocked(name); + error = fill_reent(pw, pwd, buffer, bufsize, result); + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); + return error; +} + +struct passwd * +getpwuid(uid) + uid_t uid; +{ + struct passwd *ret; + + _THREAD_PRIVATE_MUTEX_LOCK(pw); + ret = getpwuid_unlocked(uid); + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); + return ret; +} + +int +getpwuid_r(uid, pwd, buffer, bufsize, result) + uid_t uid; + struct passwd *pwd; + char *buffer; + size_t bufsize; + struct passwd **result; +{ + int error; + struct passwd *pw; + + _THREAD_PRIVATE_MUTEX_LOCK(pw); + pw = getpwuid_unlocked(uid); + error = fill_reent(pw, pwd, buffer, bufsize, result); + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); + return error; +} + int setpassent(stayopen) int stayopen; { + _THREAD_PRIVATE_MUTEX_LOCK(pw); _pw_keynum = 0; _pw_stayopen = stayopen; #ifdef YP @@ -938,6 +1057,7 @@ setpassent(stayopen) __ypexclude_free(); __ypproto = (struct passwd *)NULL; #endif + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (1); } @@ -950,6 +1070,7 @@ setpwent() void endpwent() { + _THREAD_PRIVATE_MUTEX_LOCK(pw); _pw_keynum = 0; if (_pw_db) { (void)(_pw_db->close)(_pw_db); @@ -963,6 +1084,7 @@ endpwent() __ypexclude_free(); __ypproto = (struct passwd *)NULL; #endif + _THREAD_PRIVATE_MUTEX_UNLOCK(pw); } static int |