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