Blame os/bs2000/os.c

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * This file will include OS specific functions which are not inlineable.
Packit 90a5c9
 * Any inlineable functions should be defined in os-inline.c instead.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
#ifdef _OSD_POSIX
Packit 90a5c9
Packit 90a5c9
#include "os.h"
Packit 90a5c9
Packit 90a5c9
#include "httpd.h"
Packit 90a5c9
#include "http_config.h"
Packit 90a5c9
#include "http_log.h"
Packit 90a5c9
#include "apr_lib.h"
Packit 90a5c9
Packit 90a5c9
#define USER_LEN 8
Packit 90a5c9
Packit 90a5c9
APLOG_USE_MODULE(core);
Packit 90a5c9
Packit 90a5c9
typedef enum
Packit 90a5c9
{
Packit 90a5c9
    bs2_unknown,     /* not initialized yet. */
Packit 90a5c9
    bs2_noFORK,      /* no fork() because -X flag was specified */
Packit 90a5c9
    bs2_FORK,        /* only fork() because uid != 0 */
Packit 90a5c9
    bs2_UFORK        /* Normally, ufork() is used to switch identities. */
Packit 90a5c9
} bs2_ForkType;
Packit 90a5c9
Packit 90a5c9
static bs2_ForkType forktype = bs2_unknown;
Packit 90a5c9
Packit 90a5c9
/* Determine the method for forking off a child in such a way as to
Packit 90a5c9
 * set both the POSIX and BS2000 user id's to the unprivileged user.
Packit 90a5c9
 */
Packit 90a5c9
static bs2_ForkType os_forktype(int one_process)
Packit 90a5c9
{
Packit 90a5c9
    /* have we checked the OS version before? If yes return the previous
Packit 90a5c9
     * result - the OS release isn't going to change suddenly!
Packit 90a5c9
     */
Packit 90a5c9
    if (forktype == bs2_unknown) {
Packit 90a5c9
        /* not initialized yet */
Packit 90a5c9
Packit 90a5c9
        /* No fork if the one_process option was set */
Packit 90a5c9
        if (one_process) {
Packit 90a5c9
            forktype = bs2_noFORK;
Packit 90a5c9
        }
Packit 90a5c9
        /* If the user is unprivileged, use the normal fork() only. */
Packit 90a5c9
        else if (getuid() != 0) {
Packit 90a5c9
            forktype = bs2_FORK;
Packit 90a5c9
        }
Packit 90a5c9
        else
Packit 90a5c9
            forktype = bs2_UFORK;
Packit 90a5c9
    }
Packit 90a5c9
    return forktype;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
/* This routine complements the setuid() call: it causes the BS2000 job
Packit 90a5c9
 * environment to be switched to the target user's user id.
Packit 90a5c9
 * That is important if CGI scripts try to execute native BS2000 commands.
Packit 90a5c9
 */
Packit 90a5c9
int os_init_job_environment(server_rec *server, const char *user_name, int one_process)
Packit 90a5c9
{
Packit 90a5c9
    bs2_ForkType            type = os_forktype(one_process);
Packit 90a5c9
Packit 90a5c9
    /* We can be sure that no change to uid==0 is possible because of
Packit 90a5c9
     * the checks in http_core.c:set_user()
Packit 90a5c9
     */
Packit 90a5c9
Packit 90a5c9
    if (one_process) {
Packit 90a5c9
Packit 90a5c9
        type = forktype = bs2_noFORK;
Packit 90a5c9
Packit 90a5c9
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, APLOGNO(02170)
Packit 90a5c9
                     "The debug mode of Apache should only "
Packit 90a5c9
                     "be started by an unprivileged user!");
Packit 90a5c9
        return 0;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return 0;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/* BS2000 requires a "special" version of fork() before a setuid() call */
Packit 90a5c9
pid_t os_fork(const char *user)
Packit 90a5c9
{
Packit 90a5c9
    pid_t pid;
Packit 90a5c9
    char  username[USER_LEN+1];
Packit 90a5c9
Packit 90a5c9
    switch (os_forktype(0)) {
Packit 90a5c9
Packit 90a5c9
      case bs2_FORK:
Packit 90a5c9
        pid = fork();
Packit 90a5c9
        break;
Packit 90a5c9
Packit 90a5c9
      case bs2_UFORK:
Packit 90a5c9
        apr_cpystrn(username, user, sizeof username);
Packit 90a5c9
Packit 90a5c9
        /* Make user name all upper case - for some versions of ufork() */
Packit 90a5c9
        ap_str_toupper(username);
Packit 90a5c9
Packit 90a5c9
        pid = ufork(username);
Packit 90a5c9
        if (pid == -1 && errno == EPERM) {
Packit 90a5c9
            ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
Packit 90a5c9
                         APLOGNO(02171) "ufork: Possible mis-configuration "
Packit 90a5c9
                         "for user %s - Aborting.", user);
Packit 90a5c9
            exit(1);
Packit 90a5c9
        }
Packit 90a5c9
        break;
Packit 90a5c9
Packit 90a5c9
      default:
Packit 90a5c9
        pid = 0;
Packit 90a5c9
        break;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return pid;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#else /* _OSD_POSIX */
Packit 90a5c9
void bs2000_os_is_not_here()
Packit 90a5c9
{
Packit 90a5c9
}
Packit 90a5c9
#endif /* _OSD_POSIX */