]> granicus.if.org Git - apache/commitdiff
Further unixd hacks to remove duplication between old-unixd and mod_unixd,
authorNick Kew <niq@apache.org>
Tue, 4 Nov 2008 00:44:56 +0000 (00:44 +0000)
committerNick Kew <niq@apache.org>
Tue, 4 Nov 2008 00:44:56 +0000 (00:44 +0000)
and get it working with old MPMS[1] + mod_unixd.  It's still an uneasy
split, as some modules (mod_cgid, suexec)[2] also use unixd.
More thinking+hacking due.

[1] Should be prefork/worker/event, but only worker is tested.
[2] cgid is OK, suexec is untested.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@711146 13f79535-47bb-0310-9956-ffa450edef68

modules/arch/unix/mod_unixd.c
os/unix/unixd.c
os/unix/unixd.h
server/mpm/experimental/event/event.c
server/mpm/prefork/prefork.c
server/mpm/worker/worker.c

index 487748bdf8554f318055cd791e9096939a5119cc..54239a4b0d5ce5b1cc95eeb5097101982b455517 100644 (file)
 #define DEFAULT_GROUP "#-1"
 #endif
 
+#if 0
 typedef struct {
   const char *user_name;
   uid_t user_id;
   gid_t group_id;
   const char *chroot_dir;
 } unixd_config_t;
+#else
+#include "unixd.h"
+#endif
 
 
-unixd_config_t unixd_config;
+//unixd_config_t unixd_config;
 
 /* Set group privileges.
  *
@@ -273,12 +277,22 @@ static int
 unixd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                  apr_pool_t *ptemp)
 {
+    apr_finfo_t wrapper;
     unixd_config.user_name = DEFAULT_USER;
     unixd_config.user_id = ap_uname2id(DEFAULT_USER);
     unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
 
     unixd_config.chroot_dir = NULL; /* none */
 
+    /* Check for suexec */
+    unixd_config.suexec_enabled = 0;
+    if ((apr_stat(&wrapper, SUEXEC_BIN, APR_FINFO_NORM, ptemp))
+         == APR_SUCCESS) {
+        if ((wrapper.protection & APR_USETID) && wrapper.user == 0) {
+            unixd_config.suexec_enabled = 1;
+        }
+    }
+
     sys_privileges_handlers(1);
     return OK;
 }
@@ -311,3 +325,74 @@ module AP_MODULE_DECLARE_DATA unixd_module = {
     unixd_cmds,
     unixd_hooks
 };
+
+AP_DECLARE(int) unixd_setup_child(void)
+{
+    if (set_group_privs()) {
+        return -1;
+    }
+
+    if (NULL != unixd_config.chroot_dir) {
+        if (geteuid()) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                         "Cannot chroot when not started as root");
+            return -1;
+        }
+        if (chdir(unixd_config.chroot_dir) != 0) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                         "Can't chdir to %s", unixd_config.chroot_dir);
+            return -1;
+        }
+        if (chroot(unixd_config.chroot_dir) != 0) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                         "Can't chroot to %s", unixd_config.chroot_dir);
+            return -1;
+        }
+        if (chdir("/") != 0) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                         "Can't chdir to new root");
+            return -1;
+        }
+    }
+
+#ifdef MPE
+    /* Only try to switch if we're running as MANAGER.SYS */
+    if (geteuid() == 1 && unixd_config.user_id > 1) {
+        GETPRIVMODE();
+        if (setuid(unixd_config.user_id) == -1) {
+            GETUSERMODE();
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                        "setuid: unable to change to uid: %ld",
+                        (long) unixd_config.user_id);
+            exit(1);
+        }
+        GETUSERMODE();
+    }
+#else
+    /* Only try to switch if we're running as root */
+    if (!geteuid() && (
+#ifdef _OSD_POSIX
+        os_init_job_environment(NULL, unixd_config.user_name, ap_exists_config_define("DEBUG")) != 0 ||
+#endif
+        setuid(unixd_config.user_id) == -1)) {
+        ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                    "setuid: unable to change to uid: %ld",
+                    (long) unixd_config.user_id);
+        return -1;
+    }
+#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
+    /* this applies to Linux 2.4+ */
+#ifdef AP_MPM_WANT_SET_COREDUMPDIR
+    if (ap_coredumpdir_configured) {
+        if (prctl(PR_SET_DUMPABLE, 1)) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+                         "set dumpable failed - this child will not coredump"
+                         " after software errors");
+        }
+    }
+#endif
+#endif
+#endif
+    return 0;
+}
+
index 3e3ba7823eb3f036eb9937e92588309068d8de03..bd0baeb163f2149aeb0ee290d366ac1d9374b09f 100644 (file)
 
 unixd_config_rec unixd_config;
 
-/* Set group privileges.
- *
- * Note that we use the username as set in the config files, rather than
- * the lookup of to uid --- the same uid may have multiple passwd entries,
- * with different sets of groups for each.
- */
-
-static int set_group_privs(void)
-{
-    if (!geteuid()) {
-        const char *name;
-
-        /* Get username if passed as a uid */
-
-        if (unixd_config.user_name[0] == '#') {
-            struct passwd *ent;
-            uid_t uid = atol(&unixd_config.user_name[1]);
-
-            if ((ent = getpwuid(uid)) == NULL) {
-                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "getpwuid: couldn't determine user name from uid %ld, "
-                         "you probably need to modify the User directive",
-                         (long)uid);
-                return -1;
-            }
-
-            name = ent->pw_name;
-        }
-        else
-            name = unixd_config.user_name;
-
-#if !defined(OS2) && !defined(TPF)
-        /* OS/2 and TPF don't support groups. */
-
-        /*
-         * Set the GID before initgroups(), since on some platforms
-         * setgid() is known to zap the group list.
-         */
-        if (setgid(unixd_config.group_id) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                        "setgid: unable to set group id to Group %u",
-                        (unsigned)unixd_config.group_id);
-            return -1;
-        }
-
-        /* Reset `groups' attributes. */
-
-        if (initgroups(name, unixd_config.group_id) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                        "initgroups: unable to set groups for User %s "
-                        "and Group %u", name, (unsigned)unixd_config.group_id);
-            return -1;
-        }
-#endif /* !defined(OS2) && !defined(TPF) */
-    }
-    return 0;
-}
-
-
-AP_DECLARE(int) unixd_setup_child(void)
-{
-    if (set_group_privs()) {
-        return -1;
-    }
-
-    if (NULL != unixd_config.chroot_dir) {
-        if (geteuid()) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "Cannot chroot when not started as root");
-            return -1;
-        }
-        if (chdir(unixd_config.chroot_dir) != 0) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "Can't chdir to %s", unixd_config.chroot_dir);
-            return -1;
-        }
-        if (chroot(unixd_config.chroot_dir) != 0) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "Can't chroot to %s", unixd_config.chroot_dir);
-            return -1;
-        }
-        if (chdir("/") != 0) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "Can't chdir to new root");
-            return -1;
-        }
-    }
-
-#ifdef MPE
-    /* Only try to switch if we're running as MANAGER.SYS */
-    if (geteuid() == 1 && unixd_config.user_id > 1) {
-        GETPRIVMODE();
-        if (setuid(unixd_config.user_id) == -1) {
-            GETUSERMODE();
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                        "setuid: unable to change to uid: %ld",
-                        (long) unixd_config.user_id);
-            exit(1);
-        }
-        GETUSERMODE();
-    }
-#else
-    /* Only try to switch if we're running as root */
-    if (!geteuid() && (
-#ifdef _OSD_POSIX
-        os_init_job_environment(NULL, unixd_config.user_name, ap_exists_config_define("DEBUG")) != 0 ||
-#endif
-        setuid(unixd_config.user_id) == -1)) {
-        ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                    "setuid: unable to change to uid: %ld",
-                    (long) unixd_config.user_id);
-        return -1;
-    }
-#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
-    /* this applies to Linux 2.4+ */
-#ifdef AP_MPM_WANT_SET_COREDUMPDIR
-    if (ap_coredumpdir_configured) {
-        if (prctl(PR_SET_DUMPABLE, 1)) {
-            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
-                         "set dumpable failed - this child will not coredump"
-                         " after software errors");
-        }
-    }
-#endif
-#endif
-#endif
-    return 0;
-}
-
-
-AP_DECLARE(const char *) unixd_set_user(cmd_parms *cmd, void *dummy,
-                                        const char *arg)
-{
-    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
-    if (err != NULL) {
-        return err;
-    }
-
-    unixd_config.user_name = arg;
-    unixd_config.user_id = ap_uname2id(arg);
-#if !defined (BIG_SECURITY_HOLE) && !defined (OS2)
-    if (unixd_config.user_id == 0) {
-        return "Error:\tApache has not been designed to serve pages while\n"
-                "\trunning as root.  There are known race conditions that\n"
-                "\twill allow any local user to read any file on the system.\n"
-                "\tIf you still desire to serve pages as root then\n"
-                "\tadd -DBIG_SECURITY_HOLE to the CFLAGS env variable\n"
-                "\tand then rebuild the server.\n"
-                "\tIt is strongly suggested that you instead modify the User\n"
-                "\tdirective in your httpd.conf file to list a non-root\n"
-                "\tuser.\n";
-    }
-#endif
-
-    return NULL;
-}
-
-AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy,
-                                         const char *arg)
-{
-    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
-    if (err != NULL) {
-        return err;
-    }
-
-    unixd_config.group_id = ap_gname2id(arg);
-
-    return NULL;
-}
-AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy,
-                                              const char *arg)
-{
-    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
-    if (err != NULL) {
-        return err;
-    }
-    if (!ap_is_directory(cmd->pool, arg)) {
-        return "ChrootDir must be a valid directory";
-    }
-
-    unixd_config.chroot_dir = arg;
-    return NULL;
-}
-
-AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp)
-{
-    apr_finfo_t wrapper;
-
-    unixd_config.user_name = DEFAULT_USER;
-    unixd_config.user_id = ap_uname2id(DEFAULT_USER);
-    unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
-    
-    unixd_config.chroot_dir = NULL; /* none */
-
-    /* Check for suexec */
-    unixd_config.suexec_enabled = 0;
-    if ((apr_stat(&wrapper, SUEXEC_BIN,
-                  APR_FINFO_NORM, ptemp)) != APR_SUCCESS) {
-        return;
-    }
-
-    if ((wrapper.protection & APR_USETID) && wrapper.user == 0) {
-        unixd_config.suexec_enabled = 1;
-    }
-}
-
 
 AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit,
                            const char *arg, const char * arg2, int type)
index a916f0f50d663ca9162a19413673ba26b53ae884..c165d15944166c41d573740983dad75f9912f0fa 100644 (file)
@@ -80,15 +80,8 @@ typedef struct {
 } unixd_config_rec;
 AP_DECLARE_DATA extern unixd_config_rec unixd_config;
 
-AP_DECLARE(int) unixd_setup_child(void);
-AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp);
-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, 
-                                         const char *arg);
-AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy, 
-                                              const char *arg);
-                                        
+AP_DECLARE(int) unixd_setup_child(void);  /* mod_cgid needs this */
+
 #if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS)
 AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit,
                            const char *arg, const char * arg2, int type);
index bef7b85e399e1e4427a8aefa7d82ac2a6998343c..ce59bbd31534603ee68dc91a583f4db8fef3dcfa 100644 (file)
@@ -2358,7 +2358,6 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
         parent_pid = ap_my_pid = getpid();
     }
 
-    unixd_pre_config(ptemp);
     ap_listen_pre_config();
     ap_daemons_to_start = DEFAULT_START_DAEMON;
     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
@@ -2718,7 +2717,6 @@ static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
 }
 
 static const command_rec event_cmds[] = {
-    UNIX_DAEMON_COMMANDS,
     LISTEN_COMMANDS,
     AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
                   "Number of child processes launched at server startup"),
index 28cfcfdca981a24b4746297735add2dfcb20b140..326d4d36276efa6c7a742d3b0d4421875b35217a 100644 (file)
@@ -1279,7 +1279,6 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp
         parent_pid = ap_my_pid = getpid();
     }
 
-    unixd_pre_config(ptemp);
     ap_listen_pre_config();
     ap_daemons_to_start = DEFAULT_START_DAEMON;
     ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
@@ -1498,7 +1497,6 @@ static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *ar
 }
 
 static const command_rec prefork_cmds[] = {
-UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
               "Number of child processes launched at server startup"),
index 16ade8fcac99e6c278c832fdb38fefa8f21eb6fa..fd71aa9aac97358ac092377bfc9d6ab91c1264e9 100644 (file)
@@ -1940,7 +1940,6 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
         parent_pid = ap_my_pid = getpid();
     }
 
-    unixd_pre_config(ptemp);
     ap_listen_pre_config();
     ap_daemons_to_start = DEFAULT_START_DAEMON;
     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
@@ -2299,7 +2298,6 @@ static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *ar
 }
 
 static const command_rec worker_cmds[] = {
-UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
   "Number of child processes launched at server startup"),