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.1 /* Create a socket pair for communicating with the child process. */
219
220 if (CreateSocketPair(pair) != 0)
221 Fatal(FL, "failed to create socket pair");
222
223 CloseOnExec(pair[1]);
224
225 /* Get the log-level from the configuration parameter. */
226
227 GetLogLevel(argc, argv);
228
229 /* Extract -p (perror) option. */
230
231 perror = 0;
232
233 for (i = 0; i < argc; i++)
234 {
235 if (strcmp(argv[i], "-p") == 0)
236 {
237 perror = 1;
238 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
239 mike 1.1.2.1 argc--;
240 break;
241 }
242 }
243
244 /* Open the log. */
245
246 OpenLog("cimexecutor", perror);
247
248 Log(LL_INFORMATION, "starting");
249
250 /* Be sure this process is running as root (otherwise fail). */
251
252 if (setuid(0) != 0 || setgid(0) != 0)
253 {
254 Log(LL_FATAL, "attempted to run program as non-root user");
|
255 mike 1.1.2.2 fprintf(stderr, "%s: this program must be run as root\n", globals.arg0);
|
256 mike 1.1.2.1 exit(0);
257 }
258
|
259 mike 1.1.2.2 /* Warn if authentication not enabled (strange use of executor if not). */
260
261 if (!globals.enableAuthentication)
262 Log(LL_WARNING, "authentication is NOT enabled");
263 else
|
264 mike 1.1.2.3 Log(LL_TRACE, "authentication is enabled");
|
265 mike 1.1.2.2
|
266 mike 1.1.2.1 /* Print user info. */
267
268 if (GetUserName(getuid(), username) != 0)
269 Fatal(FL, "cannot resolve user from uid=%d", getuid());
270
271 Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
272 username, (int)getuid(), (int)getgid());
273
274 /* Determine user for running cimservermain. */
275
|
276 mike 1.1.2.4 GetServerUser(&globals.childUid, &globals.childGid);
|
277 mike 1.1.2.1
278 /* Fork child process. */
279
280 childPid = fork();
281
282 if (childPid == 0)
283 {
284 /* Child. */
285 close(pair[1]);
286 Child(argc, argv,
|
287 mike 1.1.2.2 cimservermainPath, globals.childUid, globals.childGid, pair[0]);
|
288 mike 1.1.2.1 }
289 else if (childPid > 0)
290 {
291 /* Parent. */
292 close(pair[0]);
293 Parent(pair[1], childPid);
294 }
295 else
296 {
297 Fatal(FL, "fork() failed");
298 }
299
300 return 0;
301 }
|