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

  ViewVC Help
Powered by ViewVC 1.1.20