]> granicus.if.org Git - apache/blobdiff - os/bs2000/os.c
* os/unix/unixd.h: Use extern "C" linkage.
[apache] / os / bs2000 / os.c
index 591d96414c564f9450c088c7515fede93fd45429..b62b66872347553ad79994a7986008ea4eaa99c8 100644 (file)
@@ -1,59 +1,17 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
+/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
+ * applicable.
  *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * Portions of this software are based upon public domain software
- * originally written at the National Center for Supercomputing Applications,
- * University of Illinois, Urbana-Champaign.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 /*
  * Any inlineable functions should be defined in os-inline.c instead.
  */
 
-#include "httpd.h"
-#include "http_core.h"
+#ifdef _OSD_POSIX
+
 #include "os.h"
 
-/* Check the Content-Type to decide if conversion is needed */
-int ap_checkconv(struct request_rec *r)
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "apr_lib.h"
+
+#define USER_LEN 8
+
+typedef enum
 {
-    int convert_to_ascii;
-    const char *type;
-
-    /* To make serving of "raw ASCII text" files easy (they serve faster 
-     * since they don't have to be converted from EBCDIC), a new
-     * "magic" type prefix was invented: text/x-ascii-{plain,html,...}
-     * If we detect one of these content types here, we simply correct
-     * the type to the real text/{plain,html,...} type. Otherwise, we
-     * set a flag that translation is required later on.
-     */
+    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;
 
-    type = (r->content_type == NULL) ? ap_default_type(r) : r->content_type;
 
-    /* If no content type is set then treat it as (ebcdic) text/plain */
-    convert_to_ascii = (type == NULL);
+static void ap_str_toupper(char *str)
+{
+    while (*str) {
+        *str = apr_toupper(*str);
+        ++str;
+    }
+}
 
-    /* Conversion is applied to text/ files only, if ever. */
-    if (type && (strncasecmp(type, "text/", 5) == 0 ||
-                strncasecmp(type, "message/", 8) == 0)) {
-       if (strncasecmp(type, ASCIITEXT_MAGIC_TYPE_PREFIX,
-                       sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0)
-           r->content_type = ap_pstrcat(r->pool, "text/",
-                                        type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1,
-                                        NULL);
+/* 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
-           /* translate EBCDIC to ASCII */
-           convert_to_ascii = 1;
+            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;
     }
-    /* Enable conversion if it's a text document */
-    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii);
 
-    return convert_to_ascii;
+    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;
+}
+
+#else /* _OSD_POSIX */
+void bs2000_os_is_not_here()
+{
+}
+#endif /* _OSD_POSIX */