You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Jason Riedy <ej...@cise.ufl.edu> on 1998/03/03 00:32:32 UTC

suexec/1905: Allow modules to set user:group for execution.

>Number:         1905
>Category:       suexec
>Synopsis:       Allow modules to set user:group for execution.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          change-request
>Submitter-Id:   apache
>Arrival-Date:   Mon Mar  2 15:40:00 PST 1998
>Last-Modified:
>Originator:     ejr@cise.ufl.edu
>Organization:
apache
>Release:        1.3b5
>Environment:
SunOS cave 5.6 Generic sun4u sparc SUNW,Ultra-2
>Description:
Rather than patch the core to provide finer control over 
suid execution (PR 1769), why not allow modules to control
by whom programs are run?

The included patch should do just that, looking for
information in suexec_module request_config data.  This
could have gone in the notes table, but I wanted to pass
the uid/gid.  Packing and unpacking numbers into notes 
would have felt like more of a kludge than having an
empty suexec_module (well, ok, I didn't think about it
until after I wrote it), but it might be a good idea.
Also, the default behavior is unchanged.

I've tested this with a (not included) module that sends the 
username/groupname of the cgi script (or including file for 
exec cmds) to suexec.  It seems to work with my modified suexec 
(which logs to syslog & uses slightly weaker restrictions).

BTW, dealing with XBitHack and ScriptAlias is a pain.  My
module acts as a handler for CGI & shtml types to avoid being
called on every access.  I had to snarf the code from mod_cgi
and mod_include.  Not pretty.  Some modules may want to export
a few functions, perhaps with the modulename prepended.

In case the patch doesn't come through, it'll be at
http://www.cise.ufl.edu/~ejr/suexec_module.patch .  It's just
a cvs diff -u, so it won't apply perfectly from the top level.

Jason
>How-To-Repeat:

>Fix:
Index: apache-1.3-code/include/suexec_module.h
diff -u /dev/null apache-1.3-code/include/suexec_module.h:1.1
--- /dev/null	Mon Mar  2 17:26:27 1998
+++ apache-1.3-code/include/suexec_module.h	Mon Mar  2 13:51:41 1998
@@ -0,0 +1,9 @@
+typedef struct {
+    char *username;
+    uid_t uid;
+    char *groupname;
+    gid_t gid;
+    int paranoia;       /* if not 1, a notice will be issued */
+} suexec_req_data;
+
+extern module suexec_module;
Index: apache-1.3-code/main/Makefile.tmpl
diff -u apache-1.3-code/main/Makefile.tmpl:1.1.1.1 apache-1.3-code/main/Makefile.tmpl:1.2
--- apache-1.3-code/main/Makefile.tmpl:1.1.1.1	Mon Mar  2 10:42:41 1998
+++ apache-1.3-code/main/Makefile.tmpl	Mon Mar  2 13:52:50 1998
@@ -12,7 +12,7 @@
 OBJS= alloc.o http_main.o http_core.o http_config.o http_request.o \
   http_log.o http_protocol.o rfc1413.o util.o util_script.o buff.o \
   md5c.o util_md5.o explain.o http_bprintf.o util_date.o \
-  fnmatch.o http_vhost.o
+  fnmatch.o http_vhost.o suexec_module.o
 
 .c.o:
 	$(CC) -c $(INCLUDES) $(CFLAGS) $(SPACER) $<
Index: apache-1.3-code/main/suexec_module.c
diff -u /dev/null apache-1.3-code/main/suexec_module.c:1.1
--- /dev/null	Mon Mar  2 17:26:28 1998
+++ apache-1.3-code/main/suexec_module.c	Mon Mar  2 13:51:54 1998
@@ -0,0 +1,30 @@
+#include "httpd.h"
+#include "http_config.h"
+#include "http_request.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_conf_globals.h"
+#include "suexec_module.h"
+
+module suexec_module = {
+    STANDARD_MODULE_STUFF,
+    NULL,			/* initializer */
+    NULL,			/* create per-directory config structure */
+    NULL,			/* merge per-directory config structures */
+    NULL,			/* create per-server config structure */
+    NULL,			/* merge per-server config structures */
+    NULL,			/* command table */
+    NULL,			/* handlers */
+    NULL,			/* translate_handler */
+    NULL,			/* check_user_id */
+    NULL,			/* check auth */
+    NULL,			/* check access */
+    NULL,			/* type_checker */
+    NULL,		        /* pre-run fixups */
+    NULL,			/* logger */
+    NULL,			/* header parser */
+    NULL,			/* child_init */
+    NULL,			/* child_exit */
+    NULL			/* post_read_request */
+};
Index: apache-1.3-code/main/util_script.c
diff -u apache-1.3-code/main/util_script.c:1.1.1.1 apache-1.3-code/main/util_script.c:1.2
--- apache-1.3-code/main/util_script.c:1.1.1.1	Mon Mar  2 10:42:43 1998
+++ apache-1.3-code/main/util_script.c	Mon Mar  2 13:52:02 1998
@@ -62,6 +62,7 @@
 #include "http_request.h"	/* for sub_req_lookup_uri() */
 #include "util_script.h"
 #include "util_date.h"		/* For parseHTTPdate() */
+#include "suexec_module.h"
 
 /*
  * Various utility functions which are common to a whole lot of
@@ -794,10 +795,40 @@
 	return (pid);
     }
 #else
-    if (suexec_enabled &&
-	((r->server->server_uid != user_id) ||
-	 (r->server->server_gid != group_id) ||
-	 (!strncmp("/~", r->uri, 2)))) {
+    if (suexec_enabled) {
+      suexec_req_data *req_data =
+	(suexec_req_data *) get_module_config(r->request_config,
+					      &suexec_module);
+
+      if (NULL != req_data) {
+	if (1 != req_data->paranoia) {
+	  aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r->server,
+		      "call_exec: %s:%s (set non-standard) executing "
+		      "%s", req_data->username, req_data->groupname,
+		      argv0);
+	}
+
+	if ((user_id != req_data->uid) || (group_id != req_data->gid)) {
+	  if (shellcmd) {
+	    execle(SUEXEC_BIN, SUEXEC_BIN, req_data->username,
+		   req_data->groupname, argv0, NULL, env);
+	  }
+	  else if ((!r->args) || (!r->args[0]) || (ind(r->args, '=') >= 0)) {
+	    execle(SUEXEC_BIN, SUEXEC_BIN, req_data->username,
+		   req_data->groupname, argv0, NULL, env);
+	  }
+	  else {
+	    execve(SUEXEC_BIN,
+		   create_argv(r->pool, SUEXEC_BIN, req_data->username,
+			       req_data->groupname,
+			       argv0, r->args),
+		   env);
+	  }
+	}
+      }
+      else if ((r->server->server_uid != user_id) ||
+	       (r->server->server_gid != group_id) ||
+	       (!strncmp("/~", r->uri, 2))) {
 
 	char *execuser, *grpname;
 	struct passwd *pw;
@@ -858,6 +889,7 @@
 			       argv0, r->args),
 		   env);
 	}
+      }
     }
     else {
 	if (shellcmd)
%0
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <ap...@Apache.Org> in the Cc line ]
[and leave the subject line UNCHANGED.  This is not done]
[automatically because of the potential for mail loops. ]