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
|
74 kumpf 1.2 }
75
76 return 0;
77 }
78
79 /*
80 **==============================================================================
81 **
82 ** ReadPidFile()
83 **
84 **==============================================================================
85 */
86
87 static int ReadPidFile(const char* path, int* pid)
88 {
89 FILE* is = fopen(path, "r");
90
91 if (!is)
92 return -1;
93
94 *pid = 0;
95 kumpf 1.2
96 fscanf(is, "%d\n", pid);
97 fclose(is);
98
99 if (*pid == 0)
100 return -1;
101
102 return 0;
103 }
104
105 /*
106 **==============================================================================
107 **
108 ** TestCimServerProcess()
109 **
110 ** Returns 0 if cimserver process is running.
111 **
112 **==============================================================================
113 */
114
115 int TestCimServerProcess()
116 kumpf 1.2 {
117 int pid;
118 char name[EXECUTOR_BUFFER_SIZE];
119
120 if (ReadPidFile(PEGASUS_CIMSERVER_START_FILE, &pid) != 0)
121 return -1;
122
123 if (GetProcessName(pid, name) != 0 || strcmp(name, CIMSERVERMAIN) != 0)
124 return -1;
125
126 return 0;
127 }
128
129 /*
130 **==============================================================================
131 **
132 ** ExecShutdown()
133 **
134 **==============================================================================
135 */
136
137 kumpf 1.2 void ExecShutdown()
138 {
139 char* tmpArgv[3];
140 const char* cimshutdownPath;
141 const char* shutdownTimeout;
142
143 /* Get shutdownTimeout configuration parameter. */
144
145 if ((shutdownTimeout = FindMacro("shutdownTimeout")) == NULL)
146 Fatal(FL, "failed to resolve shutdownTimeout");
147
148 /* Get absolute CIMSHUTDOWN program name. */
149
150 if ((cimshutdownPath = FindMacro("cimshutdownPath")) == NULL)
151 Fatal(FL, "failed to resolve cimshutdownPath");
152
153 /* Create argument list. */
154
155 tmpArgv[0] = CIMSHUTDOWN;
156 tmpArgv[1] = (char*)shutdownTimeout;
157 tmpArgv[2] = 0;
158 kumpf 1.2
159 /* Exec CIMSHUTDOWN program. */
160
161 /* Flawfinder: ignore */
162 execv(cimshutdownPath, tmpArgv);
163 Fatal(FL, "failed to exec %s", cimshutdownPath);
164 }
165
166 /*
167 **==============================================================================
168 **
169 ** DefineExecutorMacros()
170 **
171 ** Define macros used by the executor.
172 **
173 **==============================================================================
174 */
175
176 void DefineExecutorMacros()
177 {
178 /* Define ${internalBinDir} */
179 kumpf 1.2 {
180 char path[EXECUTOR_BUFFER_SIZE];
181
182 if (GetPegasusInternalBinDir(path) != 0)
183 Fatal(FL, "failed to resolve internal pegasus bin directory");
184
185 DefineMacro("internalBinDir", path);
186 }
187
188 /* Define ${cimservermain} */
189
190 DefineMacro("cimservermain", CIMSERVERMAIN);
191
192 /* Define ${cimprovagt} */
193
194 DefineMacro("cimprovagt", CIMPROVAGT);
195
196 /* Define ${cimshutdown} */
197
198 DefineMacro("cimshutdown", CIMSHUTDOWN);
199
200 kumpf 1.2 /* Define ${cimservera} */
201
202 DefineMacro("cimservera", CIMSERVERA);
203
204 /* Define ${cimservermainPath} */
205 {
206 char path[EXECUTOR_BUFFER_SIZE];
207
208 if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
209 Fatal(FL, "failed to resolve cimservermainPath");
210
211 DefineMacro("cimservermainPath", path);
212 }
213
214 /* Define ${cimprovagtPath} */
215 {
216 char path[EXECUTOR_BUFFER_SIZE];
217
218 if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
219 Fatal(FL, "failed to resolve cimprovagtPath");
220
221 kumpf 1.2 DefineMacro("cimprovagtPath", path);
222 }
223
224 /* Define ${cimshutdownPath} */
225 {
226 char path[EXECUTOR_BUFFER_SIZE];
227
228 if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
229 Fatal(FL, "failed to resolve cimshutdownPath");
230
231 DefineMacro("cimshutdownPath", path);
232 }
233
234 /* Define ${cimserveraPath} */
235 {
236 char path[EXECUTOR_BUFFER_SIZE];
237
238 if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
239 Fatal(FL, "failed to resolve cimserveraPath");
240
241 DefineMacro("cimserveraPath", path);
242 kumpf 1.2 }
243
244 /* Define ${shutdownTimeout} */
245
246 {
247 char buffer[EXECUTOR_BUFFER_SIZE];
248
249 if (GetConfigParam("shutdownTimeout", buffer) != 0)
250 Strlcpy(buffer, "5", sizeof(buffer));
251
252 DefineMacro("shutdownTimeout", buffer);
253 }
254
255 /* Define ${currentConfigFilePath} */
256 {
257 char path[EXECUTOR_BUFFER_SIZE];
258
259 if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
260 {
261 Fatal(FL, "GetHomedPath() failed on \"%s\"",
262 PEGASUS_CURRENT_CONFIG_FILE_PATH);
263 kumpf 1.2 }
264
265 DefineMacro("currentConfigFilePath", path);
266 }
267
268 /* Define ${plannedConfigFilePath} */
269 {
270 char path[EXECUTOR_BUFFER_SIZE];
271
272 if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) != 0)
273 {
274 Fatal(FL, "GetHomedPath() failed on \"%s\"",
275 PEGASUS_PLANNED_CONFIG_FILE_PATH);
276 }
277
278 DefineMacro("plannedConfigFilePath", path);
279 }
280
281 /* Define ${passwordFilePath} */
282
283 if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
284 kumpf 1.2 Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
285
286 /* Define ${sslKeyFilePath} */
287
288 if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
289 Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
290
291 /* Define ${sslTrustStore} */
292
293 if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
294 Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
295
296 /* Define ${crlStore} */
297
298 if (DefineConfigPathMacro("crlStore", "crl") != 0)
299 Fatal(FL, "missing \"crlStore\" configuration parameter.");
300
301 /* Define ${privilegedUser} */
302
303 DefineMacro("privilegedUser", "root");
304
305 kumpf 1.2 /* Define ${cimserverUser} */
306
307 DefineMacro("cimserverUser", PEGASUS_CIMSERVERMAIN_USER);
308 }
309
310 /*
311 **==============================================================================
312 **
313 ** main()
314 **
315 **==============================================================================
316 */
317
318 int main(int argc, char** argv)
319 {
320 const char* cimservermainPath;
321 int pair[2];
322 char username[EXECUTOR_BUFFER_SIZE];
323 int childPid;
324 struct Options options;
325
326 kumpf 1.2 /* Get options. */
327
328 GetOptions(&argc, &argv, &options);
329
330 /* Save argc-argv as globals. */
331
332 globals.argc = argc;
333 globals.argv = argv;
334
335 /* Define macros needed by the executor. */
336
337 DefineExecutorMacros();
338
339 /* If shuting down, then run CIMSHUTDOWN client. */
340
341 if (options.shutdown)
342 ExecShutdown();
343
344 /* Process --policy and --macros options. */
345
346 if (options.dump)
347 kumpf 1.2 {
348 DumpPolicy(1);
349 DumpMacros();
350 exit(0);
351 }
352
353 /* Get absolute CIMSERVERMAIN program name. */
354
355 if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
356 Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
357
358 /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
359 * the following options are given: -v, --version, -h, --help (these are
360 * passed through to CIMSERVERMAIN).
361 */
362
363 if (!options.version && !options.help && TestCimServerProcess() == 0)
364 {
365 fprintf(stderr,
366 "%s: cimserver is already running (the PID found in the file "
367 "\"%s\" corresponds to an existing process named \"%s\").\n\n",
368 kumpf 1.2 globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
369
370 exit(1);
371 }
372
373 /* Get enableAuthentication configuration option. */
374
375 {
376 char buffer[EXECUTOR_BUFFER_SIZE];
377
378 if (GetConfigParam("enableAuthentication", buffer) == 0 &&
379 strcasecmp(buffer, "true") == 0)
380 {
381 globals.enableAuthentication = 1;
382 }
383 }
384
385 /* Create a socket pair for communicating with the child process. */
386
387 if (CreateSocketPair(pair) != 0)
388 Fatal(FL, "Failed to create socket pair");
389 kumpf 1.2
390 CloseOnExec(pair[1]);
391
392 /* Get the log-level from the configuration parameter. */
393
394 GetLogLevel(argc, argv);
395
396 /* Open the log. */
397
398 OpenLog("cimserver");
399
400 Log(LL_INFORMATION, "starting");
401
402 /* Be sure this process is running as root (otherwise fail). */
403
404 if (setuid(0) != 0 || setgid(0) != 0)
405 Fatal(FL, "attempted to run program as non-root user");
406
407 /* Warn if authentication not enabled (suspicious use of executor). */
408
409 if (!globals.enableAuthentication)
410 kumpf 1.2 Log(LL_WARNING, "authentication is NOT enabled");
411 else
412 Log(LL_TRACE, "authentication is enabled");
413
414 /* Print user info. */
415
416 if (GetUserName(getuid(), username) != 0)
417 Fatal(FL, "cannot resolve user from uid=%d", getuid());
418
419 Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
420 username, (int)getuid(), (int)getgid());
421
422 /* Determine user for running CIMSERVERMAIN. */
423
|