/[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 236 - (show annotations) (download) (as text)
Tue Feb 14 13:00:44 2006 UTC (8 years, 2 months ago) by phreak
File MIME type: text/x-csrc
File size: 4842 byte(s)
Merging r1881
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
21 #define IS_SBIN_RC() ((caller) && (0 == strcmp (caller, SBIN_RC)))
22
23 static void (*selinux_run_init_old) (void);
24 static void (*selinux_run_init_new) (int argc, char **argv);
25
26 #if defined(WANT_SELINUX)
27 void setup_selinux (int argc, char **argv);
28 #endif
29 char ** filter_environ (char *caller);
30
31 extern char **environ;
32
33 #if defined(WANT_SELINUX)
34 void
35 setup_selinux (int argc, char **argv)
36 {
37 void *lib_handle = NULL;
38
39 lib_handle = dlopen (SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
40 if (NULL != lib_handle)
41 {
42 selinux_run_init_old = dlsym (lib_handle, "selinux_runscript");
43 selinux_run_init_new = dlsym (lib_handle, "selinux_runscript2");
44
45 /* Use new run_init if it exists, else fall back to old */
46 if (NULL != selinux_run_init_new)
47 selinux_run_init_new (argc, argv);
48 else if (NULL != selinux_run_init_old)
49 selinux_run_init_old ();
50 else
51 {
52 /* This shouldnt happen... probably corrupt lib */
53 fprintf (stderr, "Run_init is missing from runscript_selinux.so!\n");
54 exit (127);
55 }
56 }
57 }
58 #endif
59
60 char **
61 filter_environ (char *caller)
62 {
63 char **myenv = NULL;
64 char **whitelist = NULL;
65 char *env_name = NULL;
66 int check_profile = 1;
67 int count = 0;
68
69 if (NULL != getenv (SOFTLEVEL) && !IS_SBIN_RC ())
70 /* Called from /sbin/rc, but not /sbin/rc itself, so current
71 * environment should be fine */
72 return environ;
73
74 if (1 == is_file (SYS_WHITELIST, 1))
75 whitelist = get_list_file (whitelist, SYS_WHITELIST);
76 else
77 EWARN ("System environment whitelist missing!\n");
78
79 if (1 == is_file (USR_WHITELIST, 1))
80 whitelist = get_list_file (whitelist, USR_WHITELIST);
81
82 if (NULL == whitelist)
83 /* If no whitelist is present, revert to old behaviour */
84 return environ;
85
86 if (1 != is_file (PROFILE_ENV, 1))
87 /* XXX: Maybe warn here? */
88 check_profile = 0;
89
90 str_list_for_each_item (whitelist, env_name, count)
91 {
92 char *env_var = NULL;
93 char *tmp_p = NULL;
94 int env_len = 0;
95
96 env_var = getenv (env_name);
97 if (NULL != env_var)
98 goto add_entry;
99
100 if (1 == check_profile)
101 {
102 char *tmp_env_name = NULL;
103 int tmp_len = 0;
104
105 /* The entries in PROFILE_ENV is of the form:
106 * export VAR_NAME=value */
107 tmp_len = strlen (env_name) + strlen ("export ") + 1;
108 tmp_env_name = xcalloc (tmp_len, sizeof (char *));
109 if (NULL == tmp_env_name)
110 goto error;
111
112 snprintf (tmp_env_name, tmp_len, "export %s", env_name);
113
114 env_var = get_cnf_entry (PROFILE_ENV, tmp_env_name);
115 free (tmp_env_name);
116 if ((NULL == env_var) && (0 != errno) && (ENOMSG != errno))
117 goto error;
118 else if (NULL != env_var)
119 goto add_entry;
120 }
121
122 continue;
123
124 add_entry:
125 env_len = strlen (env_name) + strlen (env_var) + 2;
126 tmp_p = xcalloc (env_len, sizeof (char *));
127 if (NULL == tmp_p)
128 goto error;
129
130 snprintf (tmp_p, env_len, "%s=%s", env_name, env_var);
131 str_list_add_item (myenv, tmp_p, error);
132 }
133
134 str_list_free (whitelist);
135
136 if (NULL == myenv)
137 {
138 char *tmp_str;
139
140 tmp_str = xstrndup (DEFAULT_PATH, strlen (DEFAULT_PATH));
141 if (NULL == tmp_str)
142 goto error;
143
144 /* If all else fails, just add a default PATH */
145 str_list_add_item (myenv, strdup (DEFAULT_PATH), error);
146 }
147
148 return myenv;
149
150 error:
151 str_list_free (myenv);
152 str_list_free (whitelist);
153
154 return NULL;
155 }
156
157 int
158 main (int argc, char *argv[])
159 {
160 char *myargs[32];
161 char **myenv = NULL;
162 char *caller = argv[1];
163 int new = 1;
164
165 /* Need to be /bin/bash, else BASH is invalid */
166 myargs[0] = "/bin/bash";
167 while (argv[new] != 0)
168 {
169 myargs[new] = argv[new];
170 new++;
171 }
172 myargs[new] = NULL;
173
174 /* Do not do help for /sbin/rc */
175 if (argc < 3 && !IS_SBIN_RC ())
176 {
177 execv (RCSCRIPT_HELP, myargs);
178 exit (1);
179 }
180
181 /* Setup a filtered environment according to the whitelist */
182 myenv = filter_environ (caller);
183 if (NULL == myenv)
184 {
185 EWARN ("%s: Failed to filter the environment!\n", caller);
186 /* XXX: Might think to bail here, but it could mean the system
187 * is rendered unbootable, so rather not */
188 myenv = environ;
189 }
190
191 #if defined(WANT_SELINUX)
192 /* Ok, we are ready to go, so setup selinux if applicable */
193 setup_selinux (argc, argv);
194 #endif
195
196 if (!IS_SBIN_RC ())
197 {
198 if (execve ("/sbin/runscript.sh", myargs, myenv) < 0)
199 exit (1);
200 }
201 else
202 {
203 if (execve ("/bin/bash", myargs, myenv) < 0)
204 exit (1);
205 }
206
207 return 0;
208 }

  ViewVC Help
Powered by ViewVC 1.1.20