From 0f413a829c0e44fe59342150cc2bc946acc68de8 Mon Sep 17 00:00:00 2001 From: Jean-Frederic Clere Date: Fri, 1 Oct 2004 16:03:08 +0000 Subject: [PATCH] Move the few BS2000 specific in unixd.c git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@105361 13f79535-47bb-0310-9956-ffa450edef68 --- os/config.m4 | 2 +- os/unix/os.h | 4 ++ os/unix/unixd.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) diff --git a/os/config.m4 b/os/config.m4 index 8dbe925fda..e4757b0891 100644 --- a/os/config.m4 +++ b/os/config.m4 @@ -11,7 +11,7 @@ case $host in ;; bs2000*) OS="unix" - OS_DIR=bs2000 # only the OS_DIR is platform specific. + OS_DIR=$OS ;; *cygwin*) OS="cygwin" diff --git a/os/unix/os.h b/os/unix/os.h index 322ad8f1a6..a78324fba9 100644 --- a/os/unix/os.h +++ b/os/unix/os.h @@ -23,4 +23,8 @@ #define PLATFORM "Unix" #endif +#ifdef _OSD_POSIX +pid_t os_fork(const char *user); +#endif + #endif /* !APACHE_OS_H */ diff --git a/os/unix/unixd.c b/os/unix/unixd.c index 1d4c770bf0..3521718d1c 100644 --- a/os/unix/unixd.c +++ b/os/unix/unixd.c @@ -457,11 +457,26 @@ AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, { apr_socket_t *csd; apr_status_t status; +#ifdef _OSD_POSIX + int sockdes; +#endif *accepted = NULL; status = apr_socket_accept(&csd, lr->sd, ptrans); if (status == APR_SUCCESS) { *accepted = csd; +#ifdef _OSD_POSIX + apr_os_sock_get(&sockdes, csd); + if (sockdes >= FD_SETSIZE) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "new file descriptor %d is too large; you probably need " + "to rebuild Apache with a larger FD_SETSIZE " + "(currently %d)", + sockdes, FD_SETSIZE); + apr_socket_close(csd); + return APR_EINTR; + } +#endif return APR_SUCCESS; } @@ -585,3 +600,118 @@ AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, return status; } + +#ifdef _OSD_POSIX + +#include "apr_lib.h" + +#define USER_LEN 8 + +typedef enum +{ + bs2_unknown, /* not initialized yet. */ + bs2_noFORK, /* no fork() because -X flag was specified */ + bs2_FORK, /* only fork() because uid != 0 */ + bs2_UFORK /* Normally, ufork() is used to switch identities. */ +} bs2_ForkType; + +static bs2_ForkType forktype = bs2_unknown; + + +static void ap_str_toupper(char *str) +{ + while (*str) { + *str = apr_toupper(*str); + ++str; + } +} + +/* Determine the method for forking off a child in such a way as to + * set both the POSIX and BS2000 user id's to the unprivileged user. + */ +static bs2_ForkType os_forktype(int one_process) +{ + /* have we checked the OS version before? If yes return the previous + * result - the OS release isn't going to change suddenly! + */ + if (forktype == bs2_unknown) { + /* not initialized yet */ + + /* No fork if the one_process option was set */ + if (one_process) { + forktype = bs2_noFORK; + } + /* If the user is unprivileged, use the normal fork() only. */ + else if (getuid() != 0) { + forktype = bs2_FORK; + } + else + forktype = bs2_UFORK; + } + return forktype; +} + + + +/* This routine complements the setuid() call: it causes the BS2000 job + * environment to be switched to the target user's user id. + * That is important if CGI scripts try to execute native BS2000 commands. + */ +int os_init_job_environment(server_rec *server, const char *user_name, int one_process) +{ + bs2_ForkType type = os_forktype(one_process); + + /* We can be sure that no change to uid==0 is possible because of + * the checks in http_core.c:set_user() + */ + + if (one_process) { + + type = forktype = bs2_noFORK; + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, + "The debug mode of Apache should only " + "be started by an unprivileged user!"); + return 0; + } + + return 0; +} + +/* BS2000 requires a "special" version of fork() before a setuid() call */ +pid_t os_fork(const char *user) +{ + pid_t pid; + char username[USER_LEN+1]; + + switch (os_forktype(0)) { + + case bs2_FORK: + pid = fork(); + break; + + case bs2_UFORK: + apr_cpystrn(username, user, sizeof username); + + /* Make user name all upper case - for some versions of ufork() */ + ap_str_toupper(username); + + pid = ufork(username); + if (pid == -1 && errno == EPERM) { + ap_log_error(APLOG_MARK, APLOG_EMERG, errno, + NULL, "ufork: Possible mis-configuration " + "for user %s - Aborting.", user); + exit(1); + } + break; + + default: + pid = 0; + break; + } + + return pid; +} + +#endif /* _OSD_POSIX */ + -- 2.40.0