]> granicus.if.org Git - apache/blob - os/bs2000/os.c
Porting to BS2000: the antique interface (BS2000Account) no longer exists
[apache] / os / bs2000 / os.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 /*
60  * This file will include OS specific functions which are not inlineable.
61  * Any inlineable functions should be defined in os-inline.c instead.
62  */
63
64 #ifdef _OSD_POSIX
65
66 #include "os.h"
67
68 #include "httpd.h"
69 #include "http_config.h"
70 #include "http_log.h"
71 #include "apr_lib.h"
72
73 #define USER_LEN 8
74
75 typedef enum
76 {
77     bs2_unknown,     /* not initialized yet. */
78     bs2_noFORK,      /* no fork() because -X flag was specified */
79     bs2_FORK,        /* only fork() because uid != 0 */
80     bs2_UFORK        /* Normally, ufork() is used to switch identities. */
81 } bs2_ForkType;
82
83 static bs2_ForkType forktype = bs2_unknown;
84
85
86 static void ap_str_toupper(char *str)
87 {
88     while (*str) {
89         *str = apr_toupper(*str);
90         ++str;
91     }
92 }
93
94 /* Determine the method for forking off a child in such a way as to
95  * set both the POSIX and BS2000 user id's to the unprivileged user.
96  */
97 static bs2_ForkType os_forktype(int one_process)
98 {
99     /* have we checked the OS version before? If yes return the previous
100      * result - the OS release isn't going to change suddenly!
101      */
102     if (forktype == bs2_unknown) {
103         /* not initialized yet */
104
105         /* No fork if the one_process option was set */
106         if (one_process) {
107             forktype = bs2_noFORK;
108         }
109         /* If the user is unprivileged, use the normal fork() only. */
110         else if (getuid() != 0) {
111             forktype = bs2_FORK;
112         }
113         else
114             forktype = bs2_UFORK;
115     }
116     return forktype;
117 }
118
119
120
121 /* This routine complements the setuid() call: it causes the BS2000 job
122  * environment to be switched to the target user's user id.
123  * That is important if CGI scripts try to execute native BS2000 commands.
124  */
125 int os_init_job_environment(server_rec *server, const char *user_name, int one_process)
126 {
127     bs2_ForkType            type = os_forktype(one_process);
128
129     /* We can be sure that no change to uid==0 is possible because of
130      * the checks in http_core.c:set_user()
131      */
132
133     if (one_process) {
134
135         type = forktype = bs2_noFORK;
136
137         ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
138                      "The debug mode of Apache should only "
139                      "be started by an unprivileged user!");
140         return 0;
141     }
142
143     return 0;
144 }
145
146 /* BS2000 requires a "special" version of fork() before a setuid() call */
147 pid_t os_fork(const char *user)
148 {
149     pid_t pid;
150     char  username[USER_LEN+1];
151
152     switch (os_forktype(0)) {
153
154       case bs2_FORK:
155         pid = fork();
156         break;
157
158       case bs2_UFORK:
159         apr_cpystrn(username, user, sizeof username);
160
161         /* Make user name all upper case - for some versions of ufork() */
162         ap_str_toupper(username);
163
164         pid = ufork(username);
165         if (pid == -1 && errno == EPERM) {
166             ap_log_error(APLOG_MARK, APLOG_EMERG, errno,
167                          NULL, "ufork: Possible mis-configuration "
168                          "for user %s - Aborting.", user);
169             exit(1);
170         }
171         break;
172
173       default:
174         pid = 0;
175         break;
176     }
177
178     return pid;
179 }
180
181 #else /* _OSD_POSIX */
182 void bs2000_os_is_not_here()
183 {
184 }
185 #endif /* _OSD_POSIX */