From: Jeff Trawick Date: Tue, 16 Sep 2003 01:00:07 +0000 (+0000) Subject: merge this fix from 2.1-dev: X-Git-Tag: 2.0.48~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0c23f384bfe7864b1c8dac022fd54c7c74ea06d;p=thirdparty%2Fapache%2Fhttpd.git merge this fix from 2.1-dev: *) Unix: Handle permissions settings for flock-based mutexes in unixd_set_global|proc_mutex_perms(). Allow the functions to be called for any type of mutex. PR 20312 Reviewed by: Justin, Greg git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@101246 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index f1a74bdde06..04b46252520 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 2.0.48 + *) Unix: Handle permissions settings for flock-based mutexes in + unixd_set_global|proc_mutex_perms(). Allow the functions to be + called for any type of mutex. PR 20312 [Jeff Trawick] + *) ab: Work over non-loopback on Unix again. PR 21495. [Jeff Trawick] *) Fix a misleading message from the some of the threaded MPMs when diff --git a/STATUS b/STATUS index c8f79a87a1f..56b04f95bf0 100644 --- a/STATUS +++ b/STATUS @@ -1,5 +1,5 @@ APACHE 2.0 STATUS: -*-text-*- -Last modified at [$Date: 2003/09/15 23:19:15 $] +Last modified at [$Date: 2003/09/16 01:00:07 $] Release: @@ -198,25 +198,6 @@ PATCHES TO PORT FROM 2.1 shows breakage on Solaris which can't -lcrypto -lssl without the extra pkgconfig/openssl.pc Libs: * foo } - * Unix: Handle permissions settings for flock-based mutexes in - unixd_set_global|proc_mutex_perms(). Allow the functions to - be called for any type of mutex. PR 20312 - modules/mappers/mod_rewrite.c 1.153 - modules/ssl/mod_ssl.h 1.136 - modules/ssl/ssl_engine_config.c 1.81 - modules/ssl/ssl_engine_mutex.c 1.26 - os/unix/unixd.c 1.58 - os/unix/unixd.h 1.38 - +1: trawick, jerenkrantz, gregames - 0: jim (it seems to me that the locking mech itself - should have the required flags to determine whether - uid/gid and chown is required, rather than placing - that knowledge in unixd.c (kind of what is done for - the SSL stuff already with ChownMutexFile). Thus - unixd would simply check those out and do what is - required rather than having internal APR knowledge - it shouldn't). - * Backport wildcard ExpiresByType from 2.0.46 +1: ken, stoddard diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 81589aec603..ec73642f1fd 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -118,6 +118,7 @@ #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) #include "unixd.h" +#define MOD_REWRITE_SET_MUTEX_PERMS /* XXX Apache should define something */ #endif /* @@ -1017,7 +1018,7 @@ static int post_config(apr_pool_t *p, return HTTP_INTERNAL_SERVER_ERROR; } -#if APR_USE_SYSVSEM_SERIALIZE +#ifdef MOD_REWRITE_SET_MUTEX_PERMS rv = unixd_set_global_mutex_perms(rewrite_log_lock); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, @@ -3599,7 +3600,7 @@ static apr_status_t rewritelock_create(server_rec *s, apr_pool_t *p) return rc; } -#if APR_USE_SYSVSEM_SERIALIZE +#ifdef MOD_REWRITE_SET_MUTEX_PERMS rc = unixd_set_global_mutex_perms(rewrite_mapr_lock_acquire); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h index 07ef64382e4..c75d608a929 100644 --- a/modules/ssl/mod_ssl.h +++ b/modules/ssl/mod_ssl.h @@ -437,7 +437,6 @@ typedef struct { ssl_mutexmode_t nMutexMode; apr_lockmech_e nMutexMech; const char *szMutexFile; - BOOL ChownMutexFile; apr_global_mutex_t *pMutex; apr_array_header_t *aRandSeed; apr_hash_t *tVHostKeys; diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index c5af50f64a3..e5373b81e07 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -101,7 +101,6 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) mc->nMutexMode = SSL_MUTEXMODE_UNSET; mc->nMutexMech = APR_LOCK_DEFAULT; mc->szMutexFile = NULL; - mc->ChownMutexFile = FALSE; mc->pMutex = NULL; mc->aRandSeed = apr_array_make(pool, 4, sizeof(ssl_randseed_t)); @@ -402,7 +401,6 @@ const char *ssl_cmd_SSLMutex(cmd_parms *cmd, mc->nMutexMech = APR_LOCK_FLOCK; mc->szMutexFile = apr_psprintf(mc->pPool, "%s.%lu", file, (unsigned long)getpid()); - mc->ChownMutexFile = TRUE; } #endif #if APR_HAS_FCNTL_SERIALIZE @@ -449,7 +447,6 @@ const char *ssl_cmd_SSLMutex(cmd_parms *cmd, mc->nMutexMode = SSL_MUTEXMODE_USED; #if APR_HAS_FLOCK_SERIALIZE mc->nMutexMech = APR_LOCK_FLOCK; - mc->ChownMutexFile = TRUE; #endif #if APR_HAS_FCNTL_SERIALIZE mc->nMutexMech = APR_LOCK_FCNTL; diff --git a/modules/ssl/ssl_engine_mutex.c b/modules/ssl/ssl_engine_mutex.c index a1c095ab590..c123d8dbdcc 100644 --- a/modules/ssl/ssl_engine_mutex.c +++ b/modules/ssl/ssl_engine_mutex.c @@ -63,6 +63,7 @@ #include "mod_ssl.h" #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) #include "unixd.h" +#define MOD_SSL_SET_MUTEX_PERMS /* XXX Apache should define something */ #endif int ssl_mutex_init(server_rec *s, apr_pool_t *p) @@ -84,25 +85,14 @@ int ssl_mutex_init(server_rec *s, apr_pool_t *p) "Cannot create SSLMutex"); return FALSE; } -#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) - if (mc->szMutexFile && mc->ChownMutexFile == TRUE) - chown(mc->szMutexFile, unixd_config.user_id, -1); -#endif -#if APR_HAS_SYSVSEM_SERIALIZE -#if APR_USE_SYSVSEM_SERIALIZE - if (mc->nMutexMech == APR_LOCK_DEFAULT || - mc->nMutexMech == APR_LOCK_SYSVSEM) { -#else - if (mc->nMutexMech == APR_LOCK_SYSVSEM) { -#endif - rv = unixd_set_global_mutex_perms(mc->pMutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Could not set permissions on ssl_mutex; check User " - "and Group directives"); - return FALSE; - } +#ifdef MOD_SSL_SET_MUTEX_PERMS + rv = unixd_set_global_mutex_perms(mc->pMutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Could not set permissions on ssl_mutex; check User " + "and Group directives"); + return FALSE; } #endif return TRUE; diff --git a/os/unix/unixd.c b/os/unix/unixd.c index 11feda653c3..d5b6c90b8e9 100644 --- a/os/unix/unixd.c +++ b/os/unix/unixd.c @@ -417,35 +417,70 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process( attr, ugid, p); } +/* XXX move to APR and externalize (but implement differently :) ) */ +static apr_lockmech_e proc_mutex_mech(apr_proc_mutex_t *pmutex) +{ + const char *mechname = apr_proc_mutex_name(pmutex); + + if (!strcmp(mechname, "sysvsem")) { + return APR_LOCK_SYSVSEM; + } + else if (!strcmp(mechname, "flock")) { + return APR_LOCK_FLOCK; + } + return APR_LOCK_DEFAULT; +} + AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) { -/* MPM shouldn't call us unless we're actually using a SysV sem; - * this is just to avoid compile issues on systems without that - * feature - */ + if (!geteuid()) { + apr_lockmech_e mech = proc_mutex_mech(pmutex); + + switch(mech) { #if APR_HAS_SYSVSEM_SERIALIZE - apr_os_proc_mutex_t ospmutex; + case APR_LOCK_SYSVSEM: + { + apr_os_proc_mutex_t ospmutex; #if !APR_HAVE_UNION_SEMUN - union semun { - long val; - struct semid_ds *buf; - ushort *array; - }; + union semun { + long val; + struct semid_ds *buf; + ushort *array; + }; #endif - union semun ick; - struct semid_ds buf; - - if (!geteuid()) { - apr_os_proc_mutex_get(&ospmutex, pmutex); - buf.sem_perm.uid = unixd_config.user_id; - buf.sem_perm.gid = unixd_config.group_id; - buf.sem_perm.mode = 0600; - ick.buf = &buf; - if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) { - return errno; + union semun ick; + struct semid_ds buf; + + apr_os_proc_mutex_get(&ospmutex, pmutex); + buf.sem_perm.uid = unixd_config.user_id; + buf.sem_perm.gid = unixd_config.group_id; + buf.sem_perm.mode = 0600; + ick.buf = &buf; + if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) { + return errno; + } } - } + break; +#endif +#if APR_HAS_FLOCK_SERIALIZE + case APR_LOCK_FLOCK: + { + const char *lockfile = apr_proc_mutex_lockfile(pmutex); + + if (lockfile) { + if (chown(lockfile, unixd_config.user_id, + -1 /* no gid change */) < 0) { + return errno; + } + } + } + break; #endif + default: + /* do nothing */ + break; + } + } return APR_SUCCESS; } diff --git a/os/unix/unixd.h b/os/unix/unixd.h index ba18098542b..1f3f4691e99 100644 --- a/os/unix/unixd.h +++ b/os/unix/unixd.h @@ -120,6 +120,16 @@ AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg, const char * arg2, int type); #endif + +/** + * One of the functions to set mutex permissions should be called in + * the parent process on platforms that switch identity when the + * server is started as root. + * If the child init logic is performed before switching identity + * (e.g., MPM setup for an accept mutex), it should only be called + * for SysV semaphores. Otherwise, it is safe to call it for all + * mutex types. + */ AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex); AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex); AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans);