]> granicus.if.org Git - apache/blob - os/beos/beosd.c
commit David's beos port.
[apache] / os / beos / beosd.c
1 /* ====================================================================
2  * Copyright (c) 1998-1999 The Apache Group.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer. 
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the Apache Group
19  *    for use in the Apache HTTP server project (http://www.apache.org/)."
20  *
21  * 4. The names "Apache Server" and "Apache Group" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    apache@apache.org.
25  *
26  * 5. Products derived from this software may not be called "Apache"
27  *    nor may "Apache" appear in their names without prior written
28  *    permission of the Apache Group.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the Apache Group
33  *    for use in the Apache HTTP server project (http://www.apache.org/)."
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Group and was originally based
51  * on public domain software written at the National Center for
52  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
53  * For more information on the Apache Group and the Apache HTTP server
54  * project, please see <http://www.apache.org/>.
55  *
56  */
57
58 #include "httpd.h"
59 #include "http_config.h"
60 #include "http_main.h"
61 #include "http_log.h"
62 #include "unixd.h"
63
64 unixd_config_rec unixd_config;
65
66 void unixd_detach(void)
67 {
68     int x;
69     pid_t pgrp;
70
71     chdir("/");
72
73     if ((x = fork()) > 0)
74         exit(0);
75     else if (x == -1) {
76         perror("fork");
77         fprintf(stderr, "%s: unable to fork new process\n", ap_server_argv0);
78         exit(1);
79     }
80     RAISE_SIGSTOP(DETACH);
81
82 #ifndef NO_SETSID
83     if ((pgrp = setsid()) == -1) {
84         perror("setsid");
85         fprintf(stderr, "%s: setsid failed\n", ap_server_argv0);
86         exit(1);
87     }
88 #else
89     if ((pgrp = setpgrp(getpid(), 0)) == -1) {
90         perror("setpgrp");
91         fprintf(stderr, "%s: setpgrp failed\n", ap_server_argv0);
92         exit(1);
93     }
94 #endif
95
96     /* close out the standard file descriptors */
97     if (freopen("/dev/null", "r", stdin) == NULL) {
98         fprintf(stderr, "%s: unable to replace stdin with /dev/null: %s\n",
99                 ap_server_argv0, strerror(errno));
100         /* continue anyhow -- note we can't close out descriptor 0 because we
101          * have nothing to replace it with, and if we didn't have a descriptor
102          * 0 the next file would be created with that value ... leading to
103          * havoc.
104          */
105     }
106     if (freopen("/dev/null", "w", stdout) == NULL) {
107         fprintf(stderr, "%s: unable to replace stdout with /dev/null: %s\n",
108                 ap_server_argv0, strerror(errno));
109     }
110     /* stderr is a tricky one, we really want it to be the error_log,
111      * but we haven't opened that yet.  So leave it alone for now and it'll
112      * be reopened moments later.
113      */
114 }
115
116 /* Set group privileges.
117  *
118  * Note that we use the username as set in the config files, rather than
119  * the lookup of to uid --- the same uid may have multiple passwd entries,
120  * with different sets of groups for each.
121  */
122
123 static int set_group_privs(void)
124 {
125     if (!geteuid()) {
126         char *name;
127
128         /* Get username if passed as a uid */
129
130         if (unixd_config.user_name[0] == '#') {
131             struct passwd *ent;
132             uid_t uid = atoi(&unixd_config.user_name[1]);
133
134             if ((ent = getpwuid(uid)) == NULL) {
135                 ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
136                          "getpwuid: couldn't determine user name from uid %u, "
137                          "you probably need to modify the User directive",
138                          (unsigned)uid);
139                 return -1;
140             }
141
142             name = ent->pw_name;
143         }
144         else
145             name = unixd_config.user_name;
146
147         if (setgid(unixd_config.group_id) == -1) {
148             ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
149                         "setgid: unable to set group id to Group %u",
150                         (unsigned)unixd_config.group_id);
151             return -1;
152         }
153
154         /* Reset `groups' attributes. */
155
156         if (initgroups(name, unixd_config.group_id) == -1) {
157             ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
158                         "initgroups: unable to set groups for User %s "
159                         "and Group %u", name, (unsigned)unixd_config.group_id);
160             return -1;
161         }
162     }
163     return 0;
164 }
165
166
167 int unixd_setup_child(void)
168 {
169     if (set_group_privs()) {
170         return -1;
171     }
172
173     /* Only try to switch if we're running as root */
174     if (!geteuid() && (
175         setuid(unixd_config.user_id) == -1)) {
176         ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
177                     "setuid: unable to change uid");
178         return -1;
179     }
180     return 0;
181 }
182
183
184 const char *unixd_set_user(cmd_parms *cmd, void *dummy, char *arg)
185 {
186     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
187     if (err != NULL) {
188         return err;
189     }
190
191     unixd_config.user_name = arg;
192     unixd_config.user_id = ap_uname2id(arg);
193 #if !defined (BIG_SECURITY_HOLE) && !defined (OS2)
194     if (unixd_config.user_id == 0) {
195         return "Error:\tApache has not been designed to serve pages while\n"
196                 "\trunning as root.  There are known race conditions that\n"
197                 "\twill allow any local user to read any file on the system.\n"
198                 "\tIf you still desire to serve pages as root then\n"
199                 "\tadd -DBIG_SECURITY_HOLE to the EXTRA_CFLAGS line in your\n"
200                 "\tsrc/Configuration file and rebuild the server.  It is\n"
201                 "\tstrongly suggested that you instead modify the User\n"
202                 "\tdirective in your httpd.conf file to list a non-root\n"
203                 "\tuser.\n";
204     }
205 #endif
206
207     return NULL;
208 }
209
210 const char *unixd_set_group(cmd_parms *cmd, void *dummy, char *arg)
211 {
212     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
213     if (err != NULL) {
214         return err;
215     }
216
217     unixd_config.group_id = ap_gname2id(arg);
218
219     return NULL;
220 }
221
222 void unixd_pre_config(void)
223 {
224     unixd_config.user_name = DEFAULT_USER;
225     unixd_config.user_id = ap_uname2id(DEFAULT_USER);
226     unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
227 }