1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter#include "apr_strings.h" 18251875Speter#include "apr_portable.h" 19251875Speter#include "apr_user.h" 20251875Speter#include "apr_private.h" 21251875Speter#ifdef HAVE_PWD_H 22251875Speter#include <pwd.h> 23251875Speter#endif 24251875Speter#if APR_HAVE_SYS_TYPES_H 25251875Speter#include <sys/types.h> 26251875Speter#endif 27251875Speter#if APR_HAVE_UNISTD_H 28251875Speter#include <unistd.h> /* for _POSIX_THREAD_SAFE_FUNCTIONS */ 29251875Speter#endif 30251875Speter#define APR_WANT_MEMFUNC 31251875Speter#include "apr_want.h" 32251875Speter 33251875Speter#define PWBUF_SIZE 2048 34251875Speter 35251875Speterstatic apr_status_t getpwnam_safe(const char *username, 36251875Speter struct passwd *pw, 37251875Speter char pwbuf[PWBUF_SIZE]) 38251875Speter{ 39251875Speter struct passwd *pwptr; 40251875Speter#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R) 41251875Speter apr_status_t rv; 42251875Speter 43251875Speter /* POSIX defines getpwnam_r() et al to return the error number 44251875Speter * rather than set errno, and requires pwptr to be set to NULL if 45251875Speter * the entry is not found, imply that "not found" is not an error 46251875Speter * condition; some implementations do return 0 with pwptr set to 47251875Speter * NULL. */ 48251875Speter rv = getpwnam_r(username, pw, pwbuf, PWBUF_SIZE, &pwptr); 49251875Speter if (rv) { 50251875Speter return rv; 51251875Speter } 52251875Speter if (pwptr == NULL) { 53251875Speter return APR_ENOENT; 54251875Speter } 55251875Speter#else 56251875Speter /* Some platforms (e.g. FreeBSD 4.x) do not set errno on NULL "not 57251875Speter * found" return values for the non-threadsafe function either. */ 58251875Speter errno = 0; 59251875Speter if ((pwptr = getpwnam(username)) != NULL) { 60251875Speter memcpy(pw, pwptr, sizeof *pw); 61251875Speter } 62251875Speter else { 63251875Speter return errno ? errno : APR_ENOENT; 64251875Speter } 65251875Speter#endif 66251875Speter return APR_SUCCESS; 67251875Speter} 68251875Speter 69251875SpeterAPR_DECLARE(apr_status_t) apr_uid_homepath_get(char **dirname, 70251875Speter const char *username, 71251875Speter apr_pool_t *p) 72251875Speter{ 73251875Speter struct passwd pw; 74251875Speter char pwbuf[PWBUF_SIZE]; 75251875Speter apr_status_t rv; 76251875Speter 77251875Speter if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS) 78251875Speter return rv; 79251875Speter 80251875Speter#ifdef OS2 81251875Speter /* Need to manually add user name for OS/2 */ 82251875Speter *dirname = apr_pstrcat(p, pw.pw_dir, pw.pw_name, NULL); 83251875Speter#else 84251875Speter *dirname = apr_pstrdup(p, pw.pw_dir); 85251875Speter#endif 86251875Speter return APR_SUCCESS; 87251875Speter} 88251875Speter 89251875Speter 90251875Speter 91251875SpeterAPR_DECLARE(apr_status_t) apr_uid_current(apr_uid_t *uid, 92251875Speter apr_gid_t *gid, 93251875Speter apr_pool_t *p) 94251875Speter{ 95251875Speter *uid = getuid(); 96251875Speter *gid = getgid(); 97251875Speter 98251875Speter return APR_SUCCESS; 99251875Speter} 100251875Speter 101251875Speter 102251875Speter 103251875Speter 104251875SpeterAPR_DECLARE(apr_status_t) apr_uid_get(apr_uid_t *uid, apr_gid_t *gid, 105251875Speter const char *username, apr_pool_t *p) 106251875Speter{ 107251875Speter struct passwd pw; 108251875Speter char pwbuf[PWBUF_SIZE]; 109251875Speter apr_status_t rv; 110251875Speter 111251875Speter if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS) 112251875Speter return rv; 113251875Speter 114251875Speter *uid = pw.pw_uid; 115251875Speter *gid = pw.pw_gid; 116251875Speter 117251875Speter return APR_SUCCESS; 118251875Speter} 119251875Speter 120251875SpeterAPR_DECLARE(apr_status_t) apr_uid_name_get(char **username, apr_uid_t userid, 121251875Speter apr_pool_t *p) 122251875Speter{ 123251875Speter struct passwd *pw; 124251875Speter#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R) 125251875Speter struct passwd pwd; 126251875Speter char pwbuf[PWBUF_SIZE]; 127251875Speter apr_status_t rv; 128251875Speter 129251875Speter rv = getpwuid_r(userid, &pwd, pwbuf, sizeof(pwbuf), &pw); 130251875Speter if (rv) { 131251875Speter return rv; 132251875Speter } 133251875Speter 134251875Speter if (pw == NULL) { 135251875Speter return APR_ENOENT; 136251875Speter } 137251875Speter 138251875Speter#else 139251875Speter errno = 0; 140251875Speter if ((pw = getpwuid(userid)) == NULL) { 141251875Speter return errno ? errno : APR_ENOENT; 142251875Speter } 143251875Speter#endif 144251875Speter *username = apr_pstrdup(p, pw->pw_name); 145251875Speter return APR_SUCCESS; 146251875Speter} 147