diff options
-rw-r--r-- | modules/generators/mod_suexec.c | 1 | ||||
-rw-r--r-- | modules/mappers/mod_userdir.c | 2 | ||||
-rw-r--r-- | os/unix/Makefile.in | 2 | ||||
-rw-r--r-- | os/unix/unixd.c | 69 | ||||
-rw-r--r-- | os/unix/unixd.h | 14 |
5 files changed, 85 insertions, 3 deletions
diff --git a/modules/generators/mod_suexec.c b/modules/generators/mod_suexec.c index f33ed77d14..b03e27f679 100644 --- a/modules/generators/mod_suexec.c +++ b/modules/generators/mod_suexec.c @@ -61,7 +61,6 @@ #include "http_core.h" #include "http_request.h" #include "apr_strings.h" -#include "suexec.h" #include "unixd.h" module MODULE_VAR_EXPORT suexec_module; diff --git a/modules/mappers/mod_userdir.c b/modules/mappers/mod_userdir.c index 308f3798c4..cec849bd39 100644 --- a/modules/mappers/mod_userdir.c +++ b/modules/mappers/mod_userdir.c @@ -101,7 +101,7 @@ #include "http_config.h" #include "http_request.h" #ifdef HAVE_UNIX_SUEXEC -#include "suexec.h" /* Contains the suexec_identity hook used on Unix */ +#include "unixd.h" /* Contains the suexec_identity hook used on Unix */ #endif #ifdef HAVE_PWD_H #include <pwd.h> diff --git a/os/unix/Makefile.in b/os/unix/Makefile.in index 521f298464..63596967db 100644 --- a/os/unix/Makefile.in +++ b/os/unix/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libos.la -LTLIBRARY_SOURCES = os-inline.c unixd.c suexec.c +LTLIBRARY_SOURCES = os-inline.c unixd.c include $(top_srcdir)/build/ltlib.mk diff --git a/os/unix/unixd.c b/os/unix/unixd.c index d70b3fd5cc..1b8a465ab8 100644 --- a/os/unix/unixd.c +++ b/os/unix/unixd.c @@ -62,6 +62,10 @@ #include "http_main.h" #include "http_log.h" #include "unixd.h" +#include "os.h" +#include "ap_mpm.h" +#include "apr_thread_proc.h" +#include "apr_strings.h" #ifdef HAVE_PWD_H #include <pwd.h> #endif @@ -414,3 +418,68 @@ AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, #endif } +AP_HOOK_STRUCT( + AP_HOOK_LINK(get_suexec_identity) +) + +AP_IMPLEMENT_HOOK_RUN_FIRST(ap_unix_identity_t *, get_suexec_identity, + (const request_rec *r), (r), NULL) + +static apr_status_t ap_unix_create_privileged_process( + apr_proc_t *newproc, const char *progname, + char *const *args, char **env, + apr_procattr_t *attr, ap_unix_identity_t *ugid, + apr_pool_t *p) +{ + int i = 0; + char **newargs; + char *newprogname; + char *execuser, *execgroup; + + if (!unixd_config.suexec_enabled) { + return apr_create_process(newproc, progname, args, env, attr, p); + } + + execuser = apr_psprintf(p, "%ld", (long) ugid->uid); + execgroup = apr_psprintf(p, "%ld", (long) ugid->gid); + + if (!execuser || !execgroup) { + return APR_ENOMEM; + } + + i = 0; + if (args) { + while (args[i]) { + i++; + } + } + newargs = apr_palloc(p, sizeof(char *) * (i + 4)); + newprogname = SUEXEC_BIN; + newargs[0] = SUEXEC_BIN; + newargs[1] = execuser; + newargs[2] = execgroup; + newargs[3] = apr_pstrdup(p, progname); + + i = 0; + do { + newargs[i + 4] = args[i]; + } while (args[i++]); + + return apr_create_process(newproc, newprogname, newargs, env, attr, p); +} + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process(const request_rec *r, + apr_proc_t *newproc, const char *progname, + char *const *args, char **env, + apr_procattr_t *attr, apr_pool_t *p) +{ + ap_unix_identity_t *ugid = ap_run_get_suexec_identity(r); + + if (ugid == NULL) { + return apr_create_process(newproc, progname, args, env, attr, p); + } + + return ap_unix_create_privileged_process(newproc, progname, args, env, + attr, ugid, p); +} + diff --git a/os/unix/unixd.h b/os/unix/unixd.h index d8ac46f87b..9bf16f8154 100644 --- a/os/unix/unixd.h +++ b/os/unix/unixd.h @@ -64,6 +64,20 @@ #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif +#include "ap_hooks.h" +#include "apr_thread_proc.h" + +#include <pwd.h> +#include <grp.h> +#include <sys/types.h> + +typedef struct { + uid_t uid; + gid_t gid; +} ap_unix_identity_t; + +AP_DECLARE_HOOK(ap_unix_identity_t *, get_suexec_identity,(const request_rec *r) +) /* common stuff that unix MPMs will want */ |