Patch attachted arose in two parts; originally it was a trivial patch
to allow SuexecUserGroup directives in <directory> blocks, because
a few people needed it, not least a large client ;) It effectively
means it's possible to execute different parts of a [virtual] host
as different users. 

The problem then of course is what to do about disabling this
for sub-directories, and the question of letting the site admin
over-ride suexec generally (like mod_userdir) ... which led
to extending the hook itself. This arose pretty much as the
result of PR9038 (see the text). 

The change to the hook (allow a module to defer to the next one,
or kill the ugid lookup there and then) make the get_identity
hook more useful to modules in general. 

If I can get a non-I'm-crazy response, I'm contemplating a patch to 
mod_rewrite to allow setting the suexec user/group, this will solve 
some very complicated mapping problems we're having on a > 2000 user 
system (using suexec for each, right now we have to symlink everyones 
public_html from an NFS /home, uggh).

This (mod_rewrite stuff) would also help solve the mass vhosting 
suexec problems somewhat, or at least make it a lot easier.

Back to this patch though, things this patch allows;

<VirtualHost foo>
SuexecUserGroup  vuser vgroup
DocumentRoot /www/foo/
...

<Directory /www/foo/bar>
SuexecUserGroup baruser bargroup
</Directory>

<Directory /www/foo/system>
SuexecUserGroup none
</Directory>

Can also do things like;

Userdir public_html

<Directory /home/colmmacc/public_html>
SuexecUserGroup none
</Directory>

Basically allow the site admin full control over where runs as who.
This would also close the ancient PR2760 (from the old bugdb), and
also in the STATUS file that can be removed anyway; 

  921 , suexec now checks cwd first, and has a dedicated logfile
  1120, this is covered by the patch proposed by me much much
        further up the STATUS
  1905, this has been possible since 2.0
  2360, this is basically the perchild mpm

I suspect 2573 and 1268 can be removed, but can't find the bug text.

Now, back to PR1120. Is anyone intrested to see "#exec cmd" working
for suexec ? I may clean up the 15-month old dodgy-patch of mine 
properly.

-- 
Colm MacCárthaigh                        Public Key: [EMAIL PROTECTED]
[EMAIL PROTECTED]                                         http://www.stdlib.net/
Index: docs/manual/mod/mod_suexec.html.en
===================================================================
RCS file: /home/cvspublic/httpd-2.0/docs/manual/mod/mod_suexec.html.en,v
retrieving revision 1.17
diff -u -u -r1.17 mod_suexec.html.en
--- docs/manual/mod/mod_suexec.html.en  29 May 2003 16:13:26 -0000      1.17
+++ docs/manual/mod/mod_suexec.html.en  31 Aug 2003 23:43:37 -0000
@@ -49,7 +49,7 @@
 <table class="directive">
 <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>User and 
group permissions for CGI programs</td></tr>
 <tr><th><a 
href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SuexecUserGroup <em>User 
Group</em></code></td></tr>
-<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, 
virtual host</td></tr>
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, 
virtual host, directory</td></tr>
 <tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
 <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_suexec</td></tr>
 <tr><th><a 
href="directive-dict.html#Compatibility">Compatibility:</a></th><td>SuexecUserGroup is 
only available in 2.0 and
@@ -64,6 +64,24 @@
     <div class="example"><h3>Example</h3><p><code>
     
     SuexecUserGroup nobody nogroup
+    </code></p></div>
+
+    <p>When given the single argument <em>none</em> within a 
+    <em>directory</em> context the use of suexec will be disabled.</p>
+
+    <div class="example"><h3>Example</h3><p><code>
+    
+    &lt;Directory /www&gt;<br />
+    <span class="indent">
+        SuexecUserGroup nobody nogroup<br />
+    </span>
+    &lt;/Directory&gt;<br />
+    <br />
+    &lt;Directory /www/system/&gt;<br />
+    <span class="indent">
+        SuexecUserGroup none<br />
+    </span>
+    &lt;/Directory&gt;
     </code></p></div>
 
 
Index: docs/manual/mod/mod_suexec.xml
===================================================================
RCS file: /home/cvspublic/httpd-2.0/docs/manual/mod/mod_suexec.xml,v
retrieving revision 1.7
diff -u -u -r1.7 mod_suexec.xml
--- docs/manual/mod/mod_suexec.xml      11 Apr 2003 01:25:53 -0000      1.7
+++ docs/manual/mod/mod_suexec.xml      31 Aug 2003 23:43:37 -0000
@@ -26,7 +26,7 @@
 <description>User and group permissions for CGI programs</description>
 <syntax>SuexecUserGroup <em>User Group</em></syntax>
 <contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<context>virtual host</context> <context>directory</context></contextlist>
 <compatibility>SuexecUserGroup is only available in 2.0 and
 later.</compatibility>
 
@@ -40,6 +40,24 @@
     <example>
     <title>Example</title>
     SuexecUserGroup nobody nogroup
+    </example>
+
+    <p>When given the single argument <em>none</em> within a 
+    <em>directory</em> context the use of suexec will be disabled.</p>
+
+    <example>
+    <title>Example</title>
+    &lt;Directory /www&gt;<br />
+    <indent>
+        SuexecUserGroup nobody nogroup<br />
+    </indent>
+    &lt;/Directory&gt;<br />
+    <br />
+    &lt;Directory /www/system/&gt;<br />
+    <indent>
+        SuexecUserGroup none<br />
+    </indent>
+    &lt;/Directory&gt;
     </example>
 
 </usage>
Index: docs/manual/mod/quickreference.html.en
===================================================================
RCS file: /home/cvspublic/httpd-2.0/docs/manual/mod/quickreference.html.en,v
retrieving revision 1.95
diff -u -u -r1.95 quickreference.html.en
--- docs/manual/mod/quickreference.html.en      29 Aug 2003 00:32:16 -0000      1.95
+++ docs/manual/mod/quickreference.html.en      31 Aug 2003 23:43:37 -0000
@@ -663,7 +663,7 @@
 Certificate verification</td></tr>
 <tr><td><a href="mpm_common.html#startservers">StartServers 
<var>number</var></a></td><td /><td>s</td><td>M</td></tr><tr><td class="descr" 
colspan="4">Number of child server processes created at startup</td></tr>
 <tr class="odd"><td><a href="mpm_common.html#startthreads">StartThreads 
<var>number</var></a></td><td /><td>s</td><td>M</td></tr><tr class="odd"><td 
class="descr" colspan="4">Number of threads created on startup</td></tr>
-<tr><td><a href="mod_suexec.html#suexecusergroup">SuexecUserGroup <em>User 
Group</em></a></td><td /><td>sv</td><td>E</td></tr><tr><td class="descr" 
colspan="4">User and group permissions for CGI programs</td></tr>
+<tr><td><a href="mod_suexec.html#suexecusergroup">SuexecUserGroup <em>User 
Group</em></a></td><td /><td>svd</td><td>E</td></tr><tr><td class="descr" 
colspan="4">User and group permissions for CGI programs</td></tr>
 <tr class="odd"><td><a href="mpm_common.html#threadlimit" id="T" name="T">ThreadLimit 
<var>number</var></a></td><td /><td>s</td><td>M</td></tr><tr class="odd"><td 
class="descr" colspan="4">Sets the upper limit on the configurable number of threads
 per child process</td></tr>
 <tr><td><a href="mpm_common.html#threadsperchild">ThreadsPerChild 
<var>number</var></a></td><td /><td>s</td><td>M</td></tr><tr><td class="descr" 
colspan="4">Number of threads created by each child process</td></tr>
Index: modules/generators/mod_suexec.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/generators/mod_suexec.c,v
retrieving revision 1.16
diff -u -u -r1.16 mod_suexec.c
--- modules/generators/mod_suexec.c     3 Feb 2003 17:53:03 -0000       1.16
+++ modules/generators/mod_suexec.c     31 Aug 2003 23:43:39 -0000
@@ -77,7 +77,7 @@
 {
     suexec_config_t *cfg = apr_palloc(p, sizeof(suexec_config_t));
 
-    cfg->active = 0;
+    cfg->action = SUEXEC_DISABLE;
     return cfg;
 }
 
@@ -102,16 +102,23 @@
                                    const char *uid, const char *gid)
 {
     suexec_config_t *cfg = (suexec_config_t *) mconfig;
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    const char *err = ap_check_cmd_context(cmd, 
NOT_IN_LOCATION|NOT_IN_FILES|NOT_IN_LIMIT);
 
     if (err != NULL) {
         return err;
     }
     if (unixd_config.suexec_enabled) {
-        cfg->ugid.uid = ap_uname2id(uid);
-        cfg->ugid.gid = ap_gname2id(gid);
-        cfg->ugid.userdir = 0;
-        cfg->active = 1;
+        if (gid == NULL) {
+            if (strcasecmp(uid, "none")) {
+                return "Invalid argument for SuexecUserGroup Directive";
+            } 
+            cfg->action = SUEXEC_DENY;
+        } else {
+            cfg->ugid.uid = ap_uname2id(uid);
+            cfg->ugid.gid = ap_gname2id(gid);
+            cfg->ugid.userdir = 0;
+            cfg->action = SUEXEC_ENABLE;
+        }
     }
     else {
         fprintf(stderr,
@@ -120,12 +127,23 @@
     return NULL;
 }
 
-static ap_unix_identity_t *get_suexec_id_doer(const request_rec *r)
+static int get_suexec_id_doer(const request_rec *r, ap_unix_identity_t **ugid)
 {
     suexec_config_t *cfg =
     (suexec_config_t *) ap_get_module_config(r->per_dir_config, &suexec_module);
 
-    return cfg->active ? &cfg->ugid : NULL;
+    *ugid == NULL;
+
+    if (cfg->action == SUEXEC_DENY) {
+        return SUEXEC_DONE;
+    } 
+
+    if (cfg->action == SUEXEC_ENABLE) {
+        *ugid = &cfg->ugid;
+        return SUEXEC_OK;
+    }
+
+    return SUEXEC_CONTINUE;
 }
 
 #define SUEXEC_POST_CONFIG_USERDATA "suexec_post_config_userdata"
@@ -157,14 +175,17 @@
 {
     /* XXX - Another important reason not to allow this in .htaccess is that
      * the ap_[ug]name2id() is not thread-safe */
-    AP_INIT_TAKE2("SuexecUserGroup", set_suexec_ugid, NULL, RSRC_CONF,
-      "User and group for spawned processes"),
+    AP_INIT_TAKE12("SuexecUserGroup", set_suexec_ugid, NULL, 
+                   RSRC_CONF|ACCESS_CONF, 
+       "User and group for spawned processes"),
     { NULL }
 };
 
 static void suexec_hooks(apr_pool_t *p)
 {
-    ap_hook_get_suexec_identity(get_suexec_id_doer,NULL,NULL,APR_HOOK_MIDDLE);
+    static const char * const aszSucc[] = { "mod_userdir.c", NULL };
+
+    ap_hook_get_suexec_identity(get_suexec_id_doer,NULL,aszSucc,APR_HOOK_MIDDLE);
     ap_hook_post_config(suexec_post_config,NULL,NULL,APR_HOOK_MIDDLE);
 }
 
Index: modules/generators/mod_suexec.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/generators/mod_suexec.h,v
retrieving revision 1.4
diff -u -u -r1.4 mod_suexec.h
--- modules/generators/mod_suexec.h     3 Feb 2003 17:53:03 -0000       1.4
+++ modules/generators/mod_suexec.h     31 Aug 2003 23:43:39 -0000
@@ -59,6 +59,6 @@
 
 typedef struct {
     ap_unix_identity_t ugid;
-    int active;
+    enum { SUEXEC_ENABLE, SUEXEC_DISABLE, SUEXEC_DENY } action;
 } suexec_config_t;
 
Index: modules/mappers/mod_userdir.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_userdir.c,v
retrieving revision 1.53
diff -u -u -r1.53 mod_userdir.c
--- modules/mappers/mod_userdir.c       3 Feb 2003 17:53:06 -0000       1.53
+++ modules/mappers/mod_userdir.c       31 Aug 2003 23:43:39 -0000
@@ -362,27 +362,33 @@
 }
 
 #ifdef HAVE_UNIX_SUEXEC
-static ap_unix_identity_t *get_suexec_id_doer(const request_rec *r)
+static int get_suexec_id_doer(const request_rec *r, ap_unix_identity_t **ugid)
 {
-    ap_unix_identity_t *ugid = NULL;
-#if APR_HAS_USER
+#ifndef APR_HAS_USER
+    *ugid = NULL;
+
+    return SUEXEC_CONTINUE;
+#else
     const char *username = apr_table_get(r->notes, "mod_userdir_user");
 
+    *ugid = NULL;
+
     if (username == NULL) {
-        return NULL;
+        return SUEXEC_CONTINUE;
     }
 
-    if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t *))) == NULL) {
-        return NULL;
+    if ((*ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t *))) == NULL) {
+        return SUEXEC_CONTINUE;
     }
 
-    if (apr_get_userid(&ugid->uid, &ugid->gid, username, r->pool) != APR_SUCCESS) {
-        return NULL;
+    if (apr_get_userid(&(*ugid)->uid, &(*ugid)->gid, username, r->pool) != 
APR_SUCCESS) {
+        return SUEXEC_CONTINUE;
     }
 
-    ugid->userdir = 1;
+    (*ugid)->userdir = 1;
+    
+    return SUEXEC_OK;
 #endif 
-    return ugid;
 }
 #endif /* HAVE_UNIX_SUEXEC */
 
Index: os/unix/unixd.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/os/unix/unixd.c,v
retrieving revision 1.58
diff -u -u -r1.58 unixd.c
--- os/unix/unixd.c     7 Jun 2003 19:50:01 -0000       1.58
+++ os/unix/unixd.c     31 Aug 2003 23:43:39 -0000
@@ -327,8 +327,8 @@
                APR_HOOK_LINK(get_suexec_identity)
 )
 
-AP_IMPLEMENT_HOOK_RUN_FIRST(ap_unix_identity_t *, get_suexec_identity,
-                         (const request_rec *r), (r), NULL)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, get_suexec_identity,
+ (const request_rec *r, ap_unix_identity_t **ugid), (r, ugid), SUEXEC_CONTINUE)
 
 static apr_status_t ap_unix_create_privileged_process(
                               apr_proc_t *newproc, const char *progname,
@@ -407,14 +407,14 @@
     const char * const *env,
     apr_procattr_t *attr, apr_pool_t *p)
 {
-    ap_unix_identity_t *ugid = ap_run_get_suexec_identity(r);
+    ap_unix_identity_t *ugid; 
+ 
+    if (ap_run_get_suexec_identity(r, &ugid) == SUEXEC_OK && ugid != NULL) {
+        return ap_unix_create_privileged_process(newproc, progname, args, env,
+                                                 attr, ugid, p);
+    } 
 
-    if (ugid == NULL) {
-        return apr_proc_create(newproc, progname, args, env, attr, p);
-    }
-
-    return ap_unix_create_privileged_process(newproc, progname, args, env,
-                                              attr, ugid, p);
+    return apr_proc_create(newproc, progname, args, env, attr, p);
 }
 
 /* XXX move to APR and externalize (but implement differently :) ) */
Index: os/unix/unixd.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/os/unix/unixd.h,v
retrieving revision 1.38
diff -u -u -r1.38 unixd.h
--- os/unix/unixd.h     7 Jun 2003 19:50:01 -0000       1.38
+++ os/unix/unixd.h     31 Aug 2003 23:43:39 -0000
@@ -88,7 +88,18 @@
     int userdir;
 } ap_unix_identity_t;
 
-AP_DECLARE_HOOK(ap_unix_identity_t *, get_suexec_identity,(const request_rec *r))
+
+/* ugid is non-null */
+#define SUEXEC_OK            0
+
+/* ugid is null, try the next module. */
+#define SUEXEC_CONTINUE      1
+
+/* ugid is NULL, don't do any further processing. */
+#define SUEXEC_DONE          2
+
+AP_DECLARE_HOOK(int, get_suexec_identity, 
+                              (const request_rec *r, ap_unix_identity_t **ugid))
 
 /* common stuff that unix MPMs will want */
 

Reply via email to