summaryrefslogtreecommitdiff
path: root/user/unix
diff options
context:
space:
mode:
authorJeff Trawick <trawick@apache.org>2001-07-20 13:35:27 +0000
committerJeff Trawick <trawick@apache.org>2001-07-20 13:35:27 +0000
commitffd95bc10053c1c7add1ca2a7b6fe3a444d50267 (patch)
tree276b22b3cc45fc702fcff666d0bde8a95aeccb10 /user/unix
parented1a57275f790d512b92738cd3eaec4d8d9e4c38 (diff)
downloadapr-ffd95bc10053c1c7add1ca2a7b6fe3a444d50267.tar.gz
getpwnam_safe() must be provided with the struct passwd and char
buffer to provide to getpwnam_r()... otherwise, the struct passwd and the data pointed to by it (e.g., pw_name) are no longer valid storage when getpwnam_safe() returns git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@61973 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'user/unix')
-rw-r--r--user/unix/userinfo.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/user/unix/userinfo.c b/user/unix/userinfo.c
index 5aae6e8ee..154164aab 100644
--- a/user/unix/userinfo.c
+++ b/user/unix/userinfo.c
@@ -66,17 +66,22 @@
#include <unistd.h> /* for _POSIX_THREAD_SAFE_FUNCTIONS */
#endif
+#define PWBUF_SIZE 512
+
static apr_status_t getpwnam_safe(const char *username,
- struct passwd **pw)
+ struct passwd *pw,
+ char pwbuf[PWBUF_SIZE])
{
+ struct passwd *pwptr;
#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
- struct passwd pwd;
- char pwbuf[512];
-
- if (getpwnam_r(username, &pwd, pwbuf, sizeof(pwbuf), pw)) {
+ if (!getpwnam_r(username, pw, pwbuf, PWBUF_SIZE, &pwptr)) {
+ /* nothing extra to do on success */
#else
- if ((*pw = getpwnam(username)) == NULL) {
+ if ((pwptr = getpwnam(username)) != NULL) {
+ memcpy(pw, pwptr, sizeof *pw);
#endif
+ }
+ else {
if (errno == 0) {
/* this can happen with getpwnam() on FreeBSD 4.3 */
return APR_EGENERAL;
@@ -90,17 +95,18 @@ APR_DECLARE(apr_status_t) apr_get_home_directory(char **dirname,
const char *username,
apr_pool_t *p)
{
- struct passwd *pw;
+ struct passwd pw;
+ char pwbuf[PWBUF_SIZE];
apr_status_t rv;
- if ((rv = getpwnam_safe(username, &pw)) != APR_SUCCESS)
+ if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS)
return rv;
#ifdef OS2
/* Need to manually add user name for OS/2 */
- *dirname = apr_pstrcat(p, pw->pw_dir, pw->pw_name, NULL);
+ *dirname = apr_pstrcat(p, pw.pw_dir, pw.pw_name, NULL);
#else
- *dirname = apr_pstrdup(p, pw->pw_dir);
+ *dirname = apr_pstrdup(p, pw.pw_dir);
#endif
return APR_SUCCESS;
}
@@ -108,14 +114,15 @@ APR_DECLARE(apr_status_t) apr_get_home_directory(char **dirname,
APR_DECLARE(apr_status_t) apr_get_userid(apr_uid_t *uid, apr_gid_t *gid,
const char *username, apr_pool_t *p)
{
- struct passwd *pw;
+ struct passwd pw;
+ char pwbuf[PWBUF_SIZE];
apr_status_t rv;
- if ((rv = getpwnam_safe(username, &pw)) != APR_SUCCESS)
+ if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS)
return rv;
- *uid = pw->pw_uid;
- *gid = pw->pw_gid;
+ *uid = pw.pw_uid;
+ *gid = pw.pw_gid;
return APR_SUCCESS;
}
@@ -125,7 +132,7 @@ APR_DECLARE(apr_status_t) apr_get_username(char **username, apr_uid_t userid, ap
struct passwd *pw;
#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
struct passwd pwd;
- char pwbuf[512];
+ char pwbuf[PWBUF_SIZE];
if (getpwuid_r(userid, &pwd, pwbuf, sizeof(pwbuf), &pw)) {
#else
@@ -140,16 +147,17 @@ APR_DECLARE(apr_status_t) apr_get_username(char **username, apr_uid_t userid, ap
APR_DECLARE(apr_status_t) apr_get_user_passwd(char **passwd,
const char *username, apr_pool_t *p)
{
- struct passwd *pw;
+ struct passwd pw;
+ char pwbuf[PWBUF_SIZE];
apr_status_t rv;
- if ((rv = getpwnam_safe(username, &pw)) != APR_SUCCESS)
+ if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS)
return rv;
#if defined(__MVS__) /* silly hack, but this function will be replaced soon anyway */
*passwd = "x"; /* same as many Linux (and Solaris and more) boxes these days */
#else
- *passwd = apr_pstrdup(p, pw->pw_passwd);
+ *passwd = apr_pstrdup(p, pw.pw_passwd);
#endif
return APR_SUCCESS;