/[vps]/baselayout-vserver/trunk/src/core/src/runscript.c
Gentoo

Contents of /baselayout-vserver/trunk/src/core/src/runscript.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 127 - (show annotations) (download) (as text)
Fri Dec 2 10:56:06 2005 UTC (12 years, 6 months ago) by phreak
File MIME type: text/x-csrc
File size: 5687 byte(s)
Import the latest baselayout changes. Merging revision 1658.
1 /*
2 * runscript.c
3 * Handle launching of Gentoo init scripts.
4 *
5 * Copyright 1999-2004 Gentoo Foundation
6 * Distributed under the terms of the GNU General Public License v2
7 * $Header$
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <dlfcn.h>
18
19 #include "librcscripts/rcscripts.h"
20 #include "librcscripts/debug.h"
21 #include "librcscripts/misc.h"
22
23 #define IS_SBIN_RC() ((caller) && (0 == strcmp(caller, SBIN_RC)))
24
25 static void (*selinux_run_init_old) (void);
26 static void (*selinux_run_init_new) (int argc, char **argv);
27
28 extern char **environ;
29
30 void setup_selinux(int argc, char **argv) {
31 void *lib_handle = NULL;
32
33 lib_handle = dlopen(SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
34 if (NULL != lib_handle) {
35 selinux_run_init_old = dlsym(lib_handle, "selinux_runscript");
36 selinux_run_init_new = dlsym(lib_handle, "selinux_runscript2");
37
38 /* Use new run_init if it exists, else fall back to old */
39 if (NULL != selinux_run_init_new)
40 selinux_run_init_new(argc, argv);
41 else if (NULL != selinux_run_init_old)
42 selinux_run_init_old();
43 else {
44 /* This shouldnt happen... probably corrupt lib */
45 fprintf(stderr, "Run_init is missing from runscript_selinux.so!\n");
46 exit(127);
47 }
48 }
49 }
50
51 char **get_whitelist(char **whitelist, char *filename) {
52 char *buf = NULL;
53 char *tmp_buf = NULL;
54 char *tmp_p = NULL;
55 char *token = NULL;
56 size_t lenght = 0;
57 int count = 0;
58 int current = 0;
59
60 if (-1 == file_map(filename, &buf, &lenght))
61 return NULL;
62
63 while (current < lenght) {
64 count = buf_get_line(buf, lenght, current);
65
66 tmp_buf = strndup(&buf[current], count);
67 if (NULL == tmp_buf) {
68 DBG_MSG("Failed to allocate temporary buffer!\n");
69 goto error;
70 }
71 tmp_p = tmp_buf;
72
73 /* Strip leading spaces/tabs */
74 while ((tmp_p[0] == ' ') || (tmp_p[0] == '\t'))
75 tmp_p++;
76
77 /* Get entry - we do not want comments, and only the first word
78 * on a line is valid */
79 token = strsep(&tmp_p, "# \t");
80 if (NULL != token && '\0' != token[0]) {
81 tmp_p = strndup(token, strlen(token));
82 STRING_LIST_ADD(whitelist, tmp_p, error);
83 }
84
85 current += count + 1;
86 free(tmp_buf);
87 /* Set to NULL in case we error out above and have
88 * to free below */
89 tmp_buf = NULL;
90 }
91
92
93 file_unmap(buf, lenght);
94
95 return whitelist;
96
97 error:
98 if (NULL != tmp_buf)
99 free(tmp_buf);
100 file_unmap(buf, lenght);
101 STRING_LIST_FREE(whitelist);
102
103 return NULL;
104 }
105
106 char **filter_environ(char *caller) {
107 char **myenv = NULL;
108 char **whitelist = NULL;
109 char *env_name = NULL;
110 int check_profile = 1;
111 int count = 0;
112
113 if (NULL != getenv(SOFTLEVEL) && !IS_SBIN_RC())
114 /* Called from /sbin/rc, but not /sbin/rc itself, so current
115 * environment should be fine */
116 return environ;
117
118 if (1 == is_file(SYS_WHITELIST, 1))
119 whitelist = get_whitelist(whitelist, SYS_WHITELIST);
120 else
121 EWARN("System environment whitelist missing!\n");
122
123 if (1 == is_file(USR_WHITELIST, 1))
124 whitelist = get_whitelist(whitelist, USR_WHITELIST);
125
126 if (NULL == whitelist)
127 /* If no whitelist is present, revert to old behaviour */
128 return environ;
129
130 if (1 != is_file(PROFILE_ENV, 1))
131 /* XXX: Maybe warn here? */
132 check_profile = 0;
133
134 STRING_LIST_FOR_EACH(whitelist, env_name, count) {
135 char *env_var = NULL;
136 char *tmp_p = NULL;
137 int env_len = 0;
138
139 env_var = getenv(env_name);
140 if (NULL != env_var)
141 goto add_entry;
142
143 if (1 == check_profile) {
144 char *tmp_env_name = NULL;
145 int tmp_len = 0;
146
147 /* The entries in PROFILE_ENV is of the form:
148 * export VAR_NAME=value */
149 tmp_len = strlen(env_name) + strlen("export ") + 1;
150 tmp_env_name = calloc(tmp_len, sizeof(char *));
151 if (NULL == tmp_env_name) {
152 DBG_MSG("Failed to allocate temporary buffer!\n");
153 goto error;
154 }
155 snprintf(tmp_env_name, tmp_len, "export %s", env_name);
156
157 /* Clear errno so that subsequent calls do not trigger
158 * DBG_MSG */
159 errno = 0;
160 env_var = get_cnf_entry(PROFILE_ENV, tmp_env_name);
161 free(tmp_env_name);
162 if (NULL == env_var && ENOMSG != errno)
163 goto error;
164 else if (NULL != env_var)
165 goto add_entry;
166 }
167
168 continue;
169
170 add_entry:
171 env_len = strlen(env_name) + strlen(env_var) + 2;
172 tmp_p = calloc(env_len, sizeof(char *));
173 if (NULL == tmp_p) {
174 DBG_MSG("Failed to allocate temporary buffer!\n");
175 goto error;
176 }
177 snprintf(tmp_p, env_len, "%s=%s", env_name, env_var);
178 STRING_LIST_ADD(myenv, tmp_p, error);
179 }
180
181 STRING_LIST_FREE(whitelist);
182
183 if (NULL == myenv)
184 /* If all else fails, just add a default PATH */
185 STRING_LIST_ADD(myenv, strdup(DEFAULT_PATH), error);
186
187 return myenv;
188
189 error:
190 STRING_LIST_FREE(myenv);
191 STRING_LIST_FREE(whitelist);
192
193 return NULL;
194 }
195
196 int main(int argc, char *argv[]) {
197 char *myargs[32];
198 char **myenv = NULL;
199 char *caller = argv[1];
200 int new = 1;
201
202 /* Need to be /bin/bash, else BASH is invalid */
203 myargs[0] = "/bin/bash";
204 while (argv[new] != 0) {
205 myargs[new] = argv[new];
206 new++;
207 }
208 myargs[new] = NULL;
209
210 /* Do not do help for /sbin/rc */
211 if (argc < 3 && !IS_SBIN_RC()) {
212 execv(RCSCRIPT_HELP, myargs);
213 exit(1);
214 }
215
216 /* Setup a filtered environment according to the whitelist */
217 myenv = filter_environ(caller);
218 if (NULL == myenv) {
219 EWARN("%s: Failed to filter the environment!\n", caller);
220 /* XXX: Might think to bail here, but it could mean the system
221 * is rendered unbootable, so rather not */
222 myenv = environ;
223 }
224
225 /* Ok, we are ready to go, so setup selinux if applicable */
226 setup_selinux(argc, argv);
227
228 if (!IS_SBIN_RC()) {
229 if (execve("/sbin/runscript.sh", myargs, myenv) < 0)
230 exit(1);
231 } else {
232 if (execve("/bin/bash", myargs, myenv) < 0)
233 exit(1);
234 }
235
236 return 0;
237 }

  ViewVC Help
Powered by ViewVC 1.1.20