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