diff -urN Makefile.in Makefile.in --- Makefile.in 2005-11-13 01:33:15.000000000 -0500 +++ Makefile.in 2010-05-27 01:03:29.000000000 -0400 @@ -4,7 +4,7 @@ PROGRAM_NAME = $(progname) PROGRAM_SOURCES = modules.c -PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) +PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) -llve PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c PROGRAM_DEPENDENCIES = \ server/libmain.la \ diff -urN modules/generators/mod_cgid.c modules/generators/mod_cgid.c --- modules/generators/mod_cgid.c 2010-05-27 11:53:46.000000000 -0400 +++ modules/generators/mod_cgid.c 2010-05-27 11:53:42.000000000 -0400 @@ -737,9 +737,37 @@ /* We have a valid identity, and can be sure that * cgid_suexec_id_doer will return a valid ugid */ - rc = ap_os_create_privileged_process(r, procnew, argv0, argv, - (const char * const *)env, - procattr, ptrans); + if (suexec_lve_enabled) { + int lve_id = -1; + ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); + if (ugid != NULL) lve_id = ugid->uid; + if (lve_id > 0) { + int re; + uint32_t p_cookie; + re = lve_enter(suexec_lve, lve_id, -1, -1, &p_cookie); + if (re) { + ap_log_error(APLOG_MARK, APLOG_ERR, OK, r->server, + "mod_cgid:exec: Error on LVE %d enter %d", lve_id, re); + return 40005;//TODO: better error code/message + } + rc = ap_os_create_privileged_process(r, procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + if (re=lve_leave(suexec_lve, &p_cookie)) { + ap_log_error(APLOG_MARK, APLOG_ERR, OK, r->server, + "mod_cgid:exec: Error on LVE %d exit %d", lve_id, re); + exit(-1); + } + } else { + rc = ap_os_create_privileged_process(r, procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + } + } else { + rc = ap_os_create_privileged_process(r, procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + } } else { rc = apr_proc_create(procnew, argv0, argv, (const char * const *)env, @@ -1271,7 +1299,7 @@ return cleanup_nonchild_process(info->r, pid); } -static int cgid_handler(request_rec *r) +static int _cgid_handler(request_rec *r) { conn_rec *c = r->connection; int retval, nph, dbpos = 0; @@ -1287,9 +1315,6 @@ struct cleanup_script_info *info; apr_status_t rv; - if (strcmp(r->handler,CGI_MAGIC_TYPE) && strcmp(r->handler,"cgi-script")) - return DECLINED; - conf = ap_get_module_config(r->server->module_config, &cgid_module); is_included = !strcmp(r->protocol, "INCLUDED"); @@ -1527,6 +1552,37 @@ return OK; /* NOT r->status, even if it has changed. */ } +static int cgid_handler(request_rec *r) { + if (strcmp(r->handler,CGI_MAGIC_TYPE) && strcmp(r->handler,"cgi-script")) + return DECLINED; + if (suexec_lve_enabled) { + ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); + uint32_t p_cookie; + int lve_id = -1; + int rc; + if (ugid != NULL) { + lve_id = ugid->uid; + } + if (lve_id > 0) { + rc = lve_enter(suexec_lve, lve_id, -1, -1, &p_cookie); + if(rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, OK, r->server, + "mod_cgid:handler: Error on LVE %d enter %d", lve_id, rc); + return HTTP_SERVICE_UNAVAILABLE; + } + int rv = _cgid_handler(r); + if (lve_leave(suexec_lve, &p_cookie)) { + ap_log_error(APLOG_MARK, APLOG_ERR, OK, r->server, + "mod_cgid: Error on LVE %d exit %d", lve_id, rc); + //error exiting, lets kill it + exit(-1); + } + return rv; + } + } + return _cgid_handler(r); +} + diff -urN os/unix/unixd.c os/unix/unixd.c --- os/unix/unixd.c 2010-05-27 11:53:46.000000000 -0400 +++ os/unix/unixd.c 2010-05-27 11:39:35.000000000 -0400 @@ -52,6 +52,36 @@ #endif unixd_config_rec unixd_config; +struct liblve *suexec_lve; +int suexec_lve_enabled = 0; + + + +/* Set LVE enabled priviledges */ +const char *set_enable_suexec_lve(cmd_parms *cmd, void *dummy, int flag) { + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + suexec_lve_enabled = flag; + if (suexec_lve_enabled) { + int rc; + if (suexec_lve == NULL) { + rc = lve_instance_init(NULL); + suexec_lve = malloc(rc);//todo implement + } + rc = lve_instance_init(suexec_lve); + if (rc != 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + NULL, "suExec: Unable to initialize LVE"); + exit(1); + } + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, + "suEXEC LVE %s", suexec_lve_enabled?"enabled":"disabled"); + return NULL; +} /* Set group privileges. * diff -urN os/unix/unixd.h os/unix/unixd.h --- os/unix/unixd.h 2006-07-11 23:38:44.000000000 -0400 +++ os/unix/unixd.h 2010-05-27 11:20:54.000000000 -0400 @@ -48,6 +48,11 @@ #include #endif +#include + +extern struct liblve *suexec_lve; +extern int suexec_lve_enabled; + typedef struct { uid_t uid; gid_t gid; @@ -77,6 +82,7 @@ AP_DECLARE(int) unixd_setup_child(void); AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp); +AP_DECLARE(const char *) set_enable_suexec_lve(cmd_parms *cmd, void *dummy, int flag); AP_DECLARE(const char *) unixd_set_user(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, @@ -108,6 +114,8 @@ #endif /* HAVE_KILLPG */ #define UNIX_DAEMON_COMMANDS \ +AP_INIT_FLAG("SuexecEnableLVE", set_enable_suexec_lve, NULL, RSRC_CONF, \ + "SuexecEnable LVE"), \ AP_INIT_TAKE1("User", unixd_set_user, NULL, RSRC_CONF, \ "Effective user id for this server"), \ AP_INIT_TAKE1("Group", unixd_set_group, NULL, RSRC_CONF, \