1 kumpf 1.2 /*
2 //%2006////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
5 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
6 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
7 // IBM Corp.; EMC Corporation, The Open Group.
8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
9 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
10 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
11 // EMC Corporation; VERITAS Software Corporation; The Open Group.
12 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
13 // EMC Corporation; Symantec Corporation; The Open Group.
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a copy
16 // of this software and associated documentation files (the "Software"), to
17 // deal in the Software without restriction, including without limitation the
18 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
19 // sell copies of the Software, and to permit persons to whom the Software is
20 // furnished to do so, subject to the following conditions:
21 //
22 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
24 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 //%/////////////////////////////////////////////////////////////////////////////
32 */
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include "Config.h"
39 #include "Child.h"
40 #include "Parent.h"
41 #include "User.h"
42 #include "Fatal.h"
43 kumpf 1.2 #include "Process.h"
44 #include "Path.h"
45 #include "Globals.h"
46 #include "Socket.h"
47 #include "Strlcpy.h"
48 #include "Strlcat.h"
49 #include "Log.h"
50 #include "Policy.h"
51 #include "Macro.h"
52 #include "Assert.h"
53 #include "Options.h"
54
55 /*
56 **==============================================================================
57 **
58 ** GetServerUser
59 **
60 ** Determine which user to run CIMSERVERMAIN as.
61 **
62 **==============================================================================
63 */
64 kumpf 1.2
|
65 kumpf 1.3 int GetServerUser(const char** userName, int* uid, int* gid)
|
66 kumpf 1.2 {
|
67 kumpf 1.3 *userName = PEGASUS_CIMSERVERMAIN_USER;
|
68 kumpf 1.2
|
69 kumpf 1.3 if (GetUserInfo(*userName, uid, gid) != 0)
|
70 kumpf 1.2 {
71 Fatal(FL,
72 "The %s user \"%s\" does not exist.",
|
73 kumpf 1.3 CIMSERVERMAIN, *userName);
|
74 kumpf 1.2 }
75
76 return 0;
77 }
78
79 /*
80 **==============================================================================
81 **
82 ** ExecShutdown()
83 **
84 **==============================================================================
85 */
86
|
87 kumpf 1.5 void ExecShutdown(void)
|
88 kumpf 1.2 {
89 char* tmpArgv[3];
90 const char* cimshutdownPath;
91 const char* shutdownTimeout;
92
93 /* Get shutdownTimeout configuration parameter. */
94
95 if ((shutdownTimeout = FindMacro("shutdownTimeout")) == NULL)
96 Fatal(FL, "failed to resolve shutdownTimeout");
97
98 /* Get absolute CIMSHUTDOWN program name. */
99
100 if ((cimshutdownPath = FindMacro("cimshutdownPath")) == NULL)
101 Fatal(FL, "failed to resolve cimshutdownPath");
102
103 /* Create argument list. */
104
105 tmpArgv[0] = CIMSHUTDOWN;
106 tmpArgv[1] = (char*)shutdownTimeout;
107 tmpArgv[2] = 0;
108
109 kumpf 1.2 /* Exec CIMSHUTDOWN program. */
110
111 /* Flawfinder: ignore */
112 execv(cimshutdownPath, tmpArgv);
113 Fatal(FL, "failed to exec %s", cimshutdownPath);
114 }
115
116 /*
117 **==============================================================================
118 **
119 ** DefineExecutorMacros()
120 **
121 ** Define macros used by the executor.
122 **
123 **==============================================================================
124 */
125
|
126 kumpf 1.5 void DefineExecutorMacros(void)
|
127 kumpf 1.2 {
128 /* Define ${internalBinDir} */
129 {
130 char path[EXECUTOR_BUFFER_SIZE];
131
132 if (GetPegasusInternalBinDir(path) != 0)
133 Fatal(FL, "failed to resolve internal pegasus bin directory");
134
135 DefineMacro("internalBinDir", path);
136 }
137
138 /* Define ${cimservermain} */
139
140 DefineMacro("cimservermain", CIMSERVERMAIN);
141
142 /* Define ${cimprovagt} */
143
144 DefineMacro("cimprovagt", CIMPROVAGT);
145
146 /* Define ${cimshutdown} */
147
148 kumpf 1.2 DefineMacro("cimshutdown", CIMSHUTDOWN);
149
150 /* Define ${cimservera} */
151
152 DefineMacro("cimservera", CIMSERVERA);
153
154 /* Define ${cimservermainPath} */
155 {
156 char path[EXECUTOR_BUFFER_SIZE];
157
158 if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
159 Fatal(FL, "failed to resolve cimservermainPath");
160
161 DefineMacro("cimservermainPath", path);
162 }
163
164 /* Define ${cimprovagtPath} */
165 {
166 char path[EXECUTOR_BUFFER_SIZE];
167
168 if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
169 kumpf 1.2 Fatal(FL, "failed to resolve cimprovagtPath");
170
171 DefineMacro("cimprovagtPath", path);
172 }
173
174 /* Define ${cimshutdownPath} */
175 {
176 char path[EXECUTOR_BUFFER_SIZE];
177
178 if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
179 Fatal(FL, "failed to resolve cimshutdownPath");
180
181 DefineMacro("cimshutdownPath", path);
182 }
183
184 /* Define ${cimserveraPath} */
185 {
186 char path[EXECUTOR_BUFFER_SIZE];
187
188 if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
189 Fatal(FL, "failed to resolve cimserveraPath");
190 kumpf 1.2
191 DefineMacro("cimserveraPath", path);
192 }
193
194 /* Define ${shutdownTimeout} */
195
196 {
197 char buffer[EXECUTOR_BUFFER_SIZE];
198
199 if (GetConfigParam("shutdownTimeout", buffer) != 0)
|
200 kumpf 1.7 {
201 Strlcpy(
202 buffer,
203 PEGASUS_DEFAULT_SHUTDOWN_TIMEOUT_SECONDS_STRING,
204 sizeof(buffer));
205 }
|
206 kumpf 1.2
207 DefineMacro("shutdownTimeout", buffer);
208 }
209
210 /* Define ${currentConfigFilePath} */
211 {
212 char path[EXECUTOR_BUFFER_SIZE];
213
214 if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
215 {
216 Fatal(FL, "GetHomedPath() failed on \"%s\"",
217 PEGASUS_CURRENT_CONFIG_FILE_PATH);
218 }
219
220 DefineMacro("currentConfigFilePath", path);
221 }
222
223 /* Define ${plannedConfigFilePath} */
224 {
225 char path[EXECUTOR_BUFFER_SIZE];
226
227 kumpf 1.2 if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) != 0)
228 {
229 Fatal(FL, "GetHomedPath() failed on \"%s\"",
230 PEGASUS_PLANNED_CONFIG_FILE_PATH);
231 }
232
233 DefineMacro("plannedConfigFilePath", path);
234 }
235
236 /* Define ${passwordFilePath} */
237
238 if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
239 Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
240
241 /* Define ${sslKeyFilePath} */
242
243 if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
244 Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
245
246 /* Define ${sslTrustStore} */
247
248 kumpf 1.2 if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
249 Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
250
251 /* Define ${crlStore} */
252
253 if (DefineConfigPathMacro("crlStore", "crl") != 0)
254 Fatal(FL, "missing \"crlStore\" configuration parameter.");
255 }
256
257 /*
258 **==============================================================================
259 **
260 ** main()
261 **
262 **==============================================================================
263 */
264
265 int main(int argc, char** argv)
266 {
267 const char* cimservermainPath;
268 int pair[2];
269 kumpf 1.2 char username[EXECUTOR_BUFFER_SIZE];
|
270 kumpf 1.6 const char* childUserName;
271 int childUid;
272 int childGid;
|
273 kumpf 1.2 int childPid;
274 struct Options options;
275
276 /* Get options. */
277
278 GetOptions(&argc, &argv, &options);
279
280 /* Save argc-argv as globals. */
281
282 globals.argc = argc;
283 globals.argv = argv;
284
|
285 kumpf 1.6 /* Open the log. */
286
287 OpenLog("cimserver");
288
|
289 kumpf 1.2 /* Define macros needed by the executor. */
290
291 DefineExecutorMacros();
292
|
293 kumpf 1.6 /* If shutting down, then run CIMSHUTDOWN client. */
|
294 kumpf 1.2
295 if (options.shutdown)
296 ExecShutdown();
297
298 /* Process --policy and --macros options. */
299
300 if (options.dump)
301 {
|
302 kumpf 1.4 DumpPolicy(stdout, 1);
303 DumpMacros(stdout);
|
304 kumpf 1.2 exit(0);
305 }
306
307 /* Get absolute CIMSERVERMAIN program name. */
308
309 if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
310 Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
311
312 /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
313 * the following options are given: -v, --version, -h, --help (these are
314 * passed through to CIMSERVERMAIN).
315 */
316
|
317 kumpf 1.4 if (!options.version &&
318 !options.help &&
319 TestProcessRunning(PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN) == 0)
|
320 kumpf 1.2 {
321 fprintf(stderr,
322 "%s: cimserver is already running (the PID found in the file "
323 "\"%s\" corresponds to an existing process named \"%s\").\n\n",
324 globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
325
326 exit(1);
327 }
328
329 /* Get enableAuthentication configuration option. */
330
331 {
332 char buffer[EXECUTOR_BUFFER_SIZE];
333
334 if (GetConfigParam("enableAuthentication", buffer) == 0 &&
335 strcasecmp(buffer, "true") == 0)
336 {
337 globals.enableAuthentication = 1;
338 }
339 }
340
341 kumpf 1.2 /* Create a socket pair for communicating with the child process. */
342
343 if (CreateSocketPair(pair) != 0)
344 Fatal(FL, "Failed to create socket pair");
345
346 CloseOnExec(pair[1]);
347
|
348 kumpf 1.4 /* Initialize the log-level from the configuration parameter. */
|
349 kumpf 1.2
|
350 kumpf 1.4 InitLogLevel();
|
351 kumpf 1.2
352 Log(LL_INFORMATION, "starting");
353
354 /* Be sure this process is running as root (otherwise fail). */
355
356 if (setuid(0) != 0 || setgid(0) != 0)
357 Fatal(FL, "attempted to run program as non-root user");
358
359 /* Warn if authentication not enabled (suspicious use of executor). */
360
361 if (!globals.enableAuthentication)
362 Log(LL_WARNING, "authentication is NOT enabled");
363 else
364 Log(LL_TRACE, "authentication is enabled");
365
366 /* Print user info. */
367
368 if (GetUserName(getuid(), username) != 0)
369 Fatal(FL, "cannot resolve user from uid=%d", getuid());
370
371 Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
372 kumpf 1.2 username, (int)getuid(), (int)getgid());
373
374 /* Determine user for running CIMSERVERMAIN. */
375
|
376 kumpf 1.6 GetServerUser(&childUserName, &childUid, &childGid);
|
377 kumpf 1.2
378 /* Fork child process. */
379
380 childPid = fork();
381
382 if (childPid == 0)
383 {
384 /* Child. */
385 close(pair[1]);
|
386 kumpf 1.3 Child(
387 argc,
388 argv,
389 cimservermainPath,
|
390 kumpf 1.6 childUserName,
391 childUid,
392 childGid,
|
393 kumpf 1.3 pair[0]);
|
394 kumpf 1.2 }
395 else if (childPid > 0)
396 {
397 /* Parent. */
398 close(pair[0]);
399 Parent(pair[1], childPid, options.bindVerbose);
400 }
401 else
402 {
403 Fatal(FL, "fork() failed");
404 }
405
406 return 0;
407 }
|