1 mike 1.1.2.1 /*
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 mike 1.1.2.1 // 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 mike 1.1.2.1 #include "Process.h"
44 #include "Path.h"
45 #include "Globals.h"
46 #include "Socket.h"
|
47 mike 1.1.2.6 #include "Strlcpy.h"
|
48 mike 1.1.2.1 #include "Log.h"
|
49 mike 1.1.2.7 #include "Policy.h"
|
50 mike 1.1.2.1
51 /*
52 **==============================================================================
53 **
54 ** GetServerUser
55 **
56 ** Determine which user to run cimservermain as.
57 **
|
58 mike 1.1.2.4 ** Note: this algorithm is no longer in use.
59 **
|
60 mike 1.1.2.1 **==============================================================================
61 */
62
|
63 mike 1.1.2.4 int GetServerUser(int* uid, int* gid)
|
64 mike 1.1.2.1 {
|
65 mike 1.1.2.4 const char* username = PEGASUS_CIMSERVERMAIN_USER;
|
66 mike 1.1.2.1
|
67 mike 1.1.2.4 if (GetUserInfo(username, uid, gid) != 0)
|
68 mike 1.1.2.1 {
|
69 mike 1.1.2.4 Fatal(FL,
70 "The cimservermain user does not exist: \"%s\". Please create "
71 "a system user with that name or use an OpenPegasus build that "
72 "disables privilege separation.", username);
|
73 mike 1.1.2.1 }
74
75 return -1;
76 }
77
78 /*
79 **==============================================================================
80 **
81 ** ReadPidFile()
82 **
83 **==============================================================================
84 */
85
86 static int ReadPidFile(const char* path, int* pid)
87 {
88 FILE* is = fopen(path, "r");
89
90 if (!is)
91 return -1;
92
93 *pid = 0;
94 mike 1.1.2.1
95 fscanf(is, "%d\n", pid);
96 fclose(is);
97
98 if (*pid == 0)
99 return -1;
100
101 return 0;
102 }
103
104 /*
105 **==============================================================================
106 **
107 ** TestCimServerProcess()
108 **
109 ** Returns 0 if cimserver process is running.
110 **
111 **==============================================================================
112 */
113
114 int TestCimServerProcess()
115 mike 1.1.2.1 {
116 int pid;
117 char name[EXECUTOR_BUFFER_SIZE];
118
119 if (ReadPidFile(PEGASUS_CIMSERVER_START_FILE, &pid) != 0)
120 return -1;
121
122 if (GetProcessName(pid, name) != 0 || strcmp(name, CIMSERVERMAIN) != 0)
123 return -1;
124
125 return 0;
126 }
127
128 /*
129 **==============================================================================
130 **
131 ** ExecShutdown()
132 **
133 **==============================================================================
134 */
135
|
136 mike 1.1.2.6 void ExecShutdown(int argc, char** argv)
|
137 mike 1.1.2.1 {
138 char* tmpArgv[3];
|
139 mike 1.1.2.6 char cimshutdownPath[EXECUTOR_BUFFER_SIZE];
140 char shutdownTimeout[EXECUTOR_BUFFER_SIZE];
|
141 mike 1.1.2.1
|
142 mike 1.1.2.6 /* Get shutdownTimeout configuration parameter. */
|
143 mike 1.1.2.1
|
144 mike 1.1.2.6 if (GetConfigParam(argc, argv, "shutdownTimeout", shutdownTimeout) != 0)
145 Strlcpy(shutdownTimeout, "5", sizeof(shutdownTimeout));
146
147 /* Get absolute cimshutdown program name. */
|
148 mike 1.1.2.1
149 if (GetInternalPegasusProgramPath(CIMSHUTDOWN, cimshutdownPath) != 0)
150 Fatal(FL, "Failed to locate Pegasus program: %s", CIMSHUTDOWN);
151
152 /* Create argument list. */
153
154 tmpArgv[0] = CIMSHUTDOWN;
|
155 mike 1.1.2.6 tmpArgv[1] = shutdownTimeout;
|
156 mike 1.1.2.1 tmpArgv[2] = 0;
157
158 /* Exec CIMSHUTDOWN program. */
159
160 /* Flawfinder: ignore */
161 execv(cimshutdownPath, tmpArgv);
162 Fatal(FL, "failed to exec %s", cimshutdownPath);
163 }
164
165 /*
166 **==============================================================================
167 **
168 ** main()
169 **
170 **==============================================================================
171 */
172
173 void doit();
174
175 int main(int argc, char** argv)
176 {
177 mike 1.1.2.1 int i;
178 char cimservermainPath[EXECUTOR_BUFFER_SIZE];
179 int pair[2];
180 char username[EXECUTOR_BUFFER_SIZE];
181 int childPid;
182 int perror;
|
183 mike 1.1.2.6 long shutdownTimeout;
|
184 mike 1.1.2.1
185 /* Save as global so it can be used in error and log messages. */
186
|
187 mike 1.1.2.2 globals.arg0 = argv[0];
|
188 mike 1.1.2.1
189 /* If shuting down, then run "cimshutdown" client. */
190
191 for (i = 0; i < argc; i++)
192 {
193 if (strcmp(argv[i], "-s") == 0)
|
194 mike 1.1.2.6 ExecShutdown(argc, argv);
|
195 mike 1.1.2.1 }
196
|
197 mike 1.1.2.6 /* Get absolute cimservermain program name. */
198
199 if (GetInternalPegasusProgramPath(CIMSERVERMAIN, cimservermainPath) != 0)
200 Fatal(FL, "Failed to locate Pegasus program: %s", CIMSERVERMAIN);
201
|
202 mike 1.1.2.1 /* If CIMSERVERMAIN is already running, warn and exit now. */
203
204 if (TestCimServerProcess() == 0)
205 {
206 fprintf(stderr,
207 "%s: cimserver is already running (the PID found in the file "
208 "\"%s\" corresponds to an existing process named \"%s\").\n\n",
|
209 mike 1.1.2.2 globals.arg0, PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
|
210 mike 1.1.2.1
211 exit(1);
212 }
213
|
214 mike 1.1.2.2 /* Get enableAuthentication configuration option. */
215
216 {
217 char buffer[EXECUTOR_BUFFER_SIZE];
218
219 if (GetConfigParam(argc, argv, "enableAuthentication", buffer) == 0 &&
220 strcasecmp(buffer, "true") == 0)
221 {
222 globals.enableAuthentication = 1;
223 }
224 }
225
|
226 mike 1.1.2.7 /* Locate password file. */
|
227 mike 1.1.2.5
228 if (LocatePasswordFile(argc, argv, globals.passwordFilePath) != 0)
229 Fatal(FL, "Failed to locate password file");
230
|
231 mike 1.1.2.7 /* Locate key file. */
232
233 if (LocateKeyFile(argc, argv, globals.sslKeyFilePath) != 0)
234 Fatal(FL, "Failed to locate key file");
235
236 /* Locate the path of directory to contain trace files. */
237
238 if (LocateTraceFilePath(argc, argv, globals.traceFilePath) != 0)
239 Fatal(FL, "Failed to locate trace file path");
240
241 /* Locate the sslTrustStore. */
242
243 if (LocateSslTrustStore(argc, argv, globals.sslTrustStore) != 0)
244 Fatal(FL, "Failed to locate SSL trust store");
245
246 /* Locate the crlStore . */
247
248 if (LocateCrlStore(argc, argv, globals.crlStore) != 0)
249 Fatal(FL, "Failed to locate crl store");
250
251 /* Define macros needed by policy facility. */
252 mike 1.1.2.7
253 DefinePolicyMacros();
254
|
255 mike 1.1.2.1 /* Create a socket pair for communicating with the child process. */
256
257 if (CreateSocketPair(pair) != 0)
|
258 mike 1.1.2.5 Fatal(FL, "Failed to create socket pair");
|
259 mike 1.1.2.1
260 CloseOnExec(pair[1]);
261
262 /* Get the log-level from the configuration parameter. */
263
264 GetLogLevel(argc, argv);
265
266 /* Extract -p (perror) option. */
267
268 perror = 0;
269
270 for (i = 0; i < argc; i++)
271 {
272 if (strcmp(argv[i], "-p") == 0)
273 {
274 perror = 1;
275 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
276 argc--;
277 break;
278 }
279 }
280 mike 1.1.2.1
281 /* Open the log. */
282
283 OpenLog("cimexecutor", perror);
284
285 Log(LL_INFORMATION, "starting");
286
287 /* Be sure this process is running as root (otherwise fail). */
288
289 if (setuid(0) != 0 || setgid(0) != 0)
290 {
291 Log(LL_FATAL, "attempted to run program as non-root user");
|
292 mike 1.1.2.2 fprintf(stderr, "%s: this program must be run as root\n", globals.arg0);
|
293 mike 1.1.2.1 exit(0);
294 }
295
|
296 mike 1.1.2.2 /* Warn if authentication not enabled (strange use of executor if not). */
297
298 if (!globals.enableAuthentication)
299 Log(LL_WARNING, "authentication is NOT enabled");
300 else
|
301 mike 1.1.2.3 Log(LL_TRACE, "authentication is enabled");
|
302 mike 1.1.2.2
|
303 mike 1.1.2.1 /* Print user info. */
304
305 if (GetUserName(getuid(), username) != 0)
306 Fatal(FL, "cannot resolve user from uid=%d", getuid());
307
308 Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
309 username, (int)getuid(), (int)getgid());
310
311 /* Determine user for running cimservermain. */
312
|
313 mike 1.1.2.4 GetServerUser(&globals.childUid, &globals.childGid);
|
314 mike 1.1.2.1
315 /* Fork child process. */
316
317 childPid = fork();
318
319 if (childPid == 0)
320 {
321 /* Child. */
322 close(pair[1]);
323 Child(argc, argv,
|
324 mike 1.1.2.2 cimservermainPath, globals.childUid, globals.childGid, pair[0]);
|
325 mike 1.1.2.1 }
326 else if (childPid > 0)
327 {
328 /* Parent. */
329 close(pair[0]);
330 Parent(pair[1], childPid);
331 }
332 else
333 {
334 Fatal(FL, "fork() failed");
335 }
336
337 return 0;
338 }
|