(file) Return to main.c CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Executor

  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.8 #include "Macro.h"
 51 mike  1.1.2.1 
 52               /*
 53               **==============================================================================
 54               **
 55               ** GetServerUser
 56               **
 57               **     Determine which user to run cimservermain as.
 58               **
 59 mike  1.1.2.4 **     Note: this algorithm is no longer in use.
 60               **
 61 mike  1.1.2.1 **==============================================================================
 62               */
 63               
 64 mike  1.1.2.4 int GetServerUser(int* uid, int* gid)
 65 mike  1.1.2.1 {
 66 mike  1.1.2.4     const char* username = PEGASUS_CIMSERVERMAIN_USER;
 67 mike  1.1.2.1 
 68 mike  1.1.2.4     if (GetUserInfo(username, uid, gid) != 0)
 69 mike  1.1.2.1     {
 70 mike  1.1.2.4         Fatal(FL, 
 71                           "The cimservermain user does not exist: \"%s\". Please create "
 72                           "a system user with that name or use an OpenPegasus build that "
 73                           "disables privilege separation.", username);
 74 mike  1.1.2.1     }
 75               
 76                   return -1;
 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 mike  1.1.2.1 
 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 mike  1.1.2.1 {
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 mike  1.1.2.6 void ExecShutdown(int argc, char** argv)
138 mike  1.1.2.1 {
139                   char* tmpArgv[3];
140 mike  1.1.2.6     char cimshutdownPath[EXECUTOR_BUFFER_SIZE];
141                   char shutdownTimeout[EXECUTOR_BUFFER_SIZE];
142 mike  1.1.2.1 
143 mike  1.1.2.6     /* Get shutdownTimeout configuration parameter. */
144 mike  1.1.2.1 
145 mike  1.1.2.6     if (GetConfigParam(argc, argv, "shutdownTimeout", shutdownTimeout) != 0)
146                       Strlcpy(shutdownTimeout, "5", sizeof(shutdownTimeout));
147               
148                   /* Get absolute cimshutdown program name. */
149 mike  1.1.2.1 
150                   if (GetInternalPegasusProgramPath(CIMSHUTDOWN, cimshutdownPath) != 0)
151                       Fatal(FL, "Failed to locate Pegasus program: %s", CIMSHUTDOWN);
152               
153                   /* Create argument list. */
154               
155                   tmpArgv[0] = CIMSHUTDOWN;
156 mike  1.1.2.6     tmpArgv[1] = shutdownTimeout;
157 mike  1.1.2.1     tmpArgv[2] = 0;
158               
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 mike  1.1.2.8 ** DefineExecutorMacros()
170               **
171               **     Define macros used by the executor.
172               **
173               **==============================================================================
174               */
175               
176               void DefineExecutorMacros()
177               {
178                   /* Define ${internalBinDir} */
179                   {
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 ${cimservermainPath} */
189                   {
190 mike  1.1.2.8         char path[EXECUTOR_BUFFER_SIZE];
191               
192                       if (ExpandMacros("${internalBinDir}/cimservermain", path) != 0)
193                           Fatal(FL, "failed to resolve cimserver main path");
194               
195                       DefineMacro("cimservermainPath", path);
196                   }
197               
198                   /* Define ${cimprovagtPath} */
199                   {
200                       char path[EXECUTOR_BUFFER_SIZE];
201               
202                       if (ExpandMacros("${internalBinDir}/cimprovagt", path) != 0)
203                           Fatal(FL, "failed to resolve cimserver main path");
204               
205                       DefineMacro("cimprovagtPath", path);
206                   }
207               
208                   /* Define ${cimserveraPath} */
209                   {
210                       char path[EXECUTOR_BUFFER_SIZE];
211 mike  1.1.2.8 
212                       if (ExpandMacros("${internalBinDir}/cimservera", path) != 0)
213                           Fatal(FL, "failed to resolve cimserver main path");
214               
215                       DefineMacro("cimserveraPath", path);
216                   }
217               
218                   /* Define ${currentConfigFilePath} */
219                   {
220                       char path[EXECUTOR_BUFFER_SIZE];
221               
222                       if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
223                       {
224                           Fatal(FL, "GetHomedPath() failed on \"%s\"", 
225                               PEGASUS_CURRENT_CONFIG_FILE_PATH);
226                       }
227               
228                       DefineMacro("currentConfigFilePath", path);
229                   }
230               
231                   /* Define ${repositoryDir} */
232 mike  1.1.2.8 
233                   if (DefineConfigPathMacro("repositoryDir", PEGASUS_REPOSITORY_DIR) != 0)
234                       Fatal(FL, "missing \"repositoryDir\" configuration parameter.");
235               
236                   /* Define ${passwordFilePath} */
237               
238                   if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
239                       Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
240               
241                   /* Define ${traceFilePath} */
242               
243                   if (DefineConfigPathMacro("traceFilePath", NULL) != 0)
244                       Fatal(FL, "missing \"traceFilePath\" configuration parameter.");
245               
246                   /* Define ${sslKeyFilePath} */
247               
248                   if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
249                       Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
250               
251                   /* Define ${sslTrustStore} */
252               
253 mike  1.1.2.8     if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
254                       Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
255               
256                   /* Define ${crlStore} */
257               
258                   if (DefineConfigPathMacro("crlStore", "crl") != 0)
259                       Fatal(FL, "missing \"crlStore\" configuration parameter.");
260               }
261               
262               /*
263               **==============================================================================
264               **
265               ** TestFlagOption()
266               **
267               **     Check whether argv contains the given option. Return 0 if so. Else
268               **     return -1. Remove the argument from the list if the *remove* argument
269               **     is non-zero.
270               **
271               **         if (TestFlagOption(&argc, &argv, "--help", 0) == 0)
272               **         {
273               **         }
274 mike  1.1.2.8 **
275               **==============================================================================
276               */
277               
278               int TestFlagOption(int* argc_, char*** argv_, const char* option, int remove)
279               {
280                   int argc = *argc_;
281                   char** argv = *argv_;
282                   int i;
283               
284                   for (i = 0; i < argc; i++)
285                   {
286                       if (strcmp(argv[i], option) == 0)
287                       {
288                           if (remove)
289                           {
290                               memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
291                               argc--;
292                           }
293               
294                           *argc_ = argc;
295 mike  1.1.2.8             *argv_ = argv;
296                           return 0;
297                       }
298                   }
299               
300                   /* Not found */
301                   return -1;
302               }
303               
304               /*
305               **==============================================================================
306               **
307 mike  1.1.2.1 ** main()
308               **
309               **==============================================================================
310               */
311               
312               void doit();
313               
314               int main(int argc, char** argv)
315               {
316                   int i;
317                   char cimservermainPath[EXECUTOR_BUFFER_SIZE];
318                   int pair[2];
319                   char username[EXECUTOR_BUFFER_SIZE];
320                   int childPid;
321                   int perror;
322 mike  1.1.2.6     long shutdownTimeout;
323 mike  1.1.2.8     const char* repositoryDir;
324 mike  1.1.2.1 
325                   /* Save as global so it can be used in error and log messages. */
326               
327 mike  1.1.2.8     globals.argc = argc;
328                   globals.argv = argv;
329 mike  1.1.2.1 
330                   /* If shuting down, then run "cimshutdown" client. */
331               
332 mike  1.1.2.8     if (TestFlagOption(&argc, &argv, "-s", 0) == 0)
333                       ExecShutdown(argc, argv);
334               
335                   /* Define macros needed by the executor. */
336               
337                   DefineExecutorMacros();
338               
339                   /* Check for --dump-policy option. */
340               
341                   if (TestFlagOption(&argc, &argv, "--dump-policy", 0) == 0)
342 mike  1.1.2.1     {
343 mike  1.1.2.8         DumpPolicy(1);
344                       putchar('\n');
345                       exit(0);
346                   }
347               
348                   /* Check for --dump-macros option. */
349               
350                   if (TestFlagOption(&argc, &argv, "--dump-macros", 0) == 0)
351                   {
352                       DumpMacros();
353                       putchar('\n');
354                       exit(0);
355 mike  1.1.2.1     }
356               
357 mike  1.1.2.6     /* Get absolute cimservermain program name. */
358               
359                   if (GetInternalPegasusProgramPath(CIMSERVERMAIN, cimservermainPath) != 0)
360                       Fatal(FL, "Failed to locate Pegasus program: %s", CIMSERVERMAIN);
361               
362 mike  1.1.2.1     /* If CIMSERVERMAIN is already running, warn and exit now. */
363               
364                   if (TestCimServerProcess() == 0)
365                   {
366                       fprintf(stderr,
367                           "%s: cimserver is already running (the PID found in the file "
368                           "\"%s\" corresponds to an existing process named \"%s\").\n\n",
369 mike  1.1.2.8             globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
370 mike  1.1.2.1 
371                       exit(1);
372                   }
373               
374 mike  1.1.2.2     /* Get enableAuthentication configuration option. */
375               
376                   {
377                       char buffer[EXECUTOR_BUFFER_SIZE];
378               
379                       if (GetConfigParam(argc, argv, "enableAuthentication", buffer) == 0 &&
380                           strcasecmp(buffer, "true") == 0)
381                       {
382                           globals.enableAuthentication = 1;
383                       }
384                   }
385               
386 mike  1.1.2.1     /* Create a socket pair for communicating with the child process. */
387               
388                   if (CreateSocketPair(pair) != 0)
389 mike  1.1.2.5         Fatal(FL, "Failed to create socket pair");
390 mike  1.1.2.1 
391                   CloseOnExec(pair[1]);
392               
393                   /* Get the log-level from the configuration parameter. */
394               
395                   GetLogLevel(argc, argv);
396               
397 mike  1.1.2.8     /* Extract --perror option (directs syslog output to stderr). */
398 mike  1.1.2.1 
399                   perror = 0;
400               
401 mike  1.1.2.8     if (TestFlagOption(&argc, &argv, "--perror", 1) == 0)
402                       perror = 1;
403 mike  1.1.2.1 
404                   /* Open the log. */
405               
406                   OpenLog("cimexecutor", perror);
407               
408                   Log(LL_INFORMATION, "starting");
409               
410                   /* Be sure this process is running as root (otherwise fail). */
411               
412                   if (setuid(0) != 0 || setgid(0) != 0)
413                   {
414                       Log(LL_FATAL, "attempted to run program as non-root user");
415 mike  1.1.2.8         fprintf(stderr, 
416                           "%s: this program must be run as root\n", globals.argv[0]);
417 mike  1.1.2.1         exit(0);
418                   }
419               
420 mike  1.1.2.2     /* Warn if authentication not enabled (strange use of executor if not). */
421               
422                   if (!globals.enableAuthentication)
423                       Log(LL_WARNING, "authentication is NOT enabled");
424                   else
425 mike  1.1.2.3         Log(LL_TRACE, "authentication is enabled");
426 mike  1.1.2.2 
427 mike  1.1.2.1     /* Print user info. */
428               
429                   if (GetUserName(getuid(), username) != 0)
430                       Fatal(FL, "cannot resolve user from uid=%d", getuid());
431               
432                   Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
433                       username, (int)getuid(), (int)getgid());
434               
435                   /* Determine user for running cimservermain. */
436               
437 mike  1.1.2.4     GetServerUser(&globals.childUid, &globals.childGid);
438 mike  1.1.2.1 
439 mike  1.1.2.8     /* Get repositoryDir for child. */
440               
441                   if ((repositoryDir = FindMacro("repositoryDir")) == NULL)
442                       Fatal(FL, "failed to find repositoryDir macro");
443               
444 mike  1.1.2.1     /* Fork child process. */
445               
446                   childPid = fork();
447               
448                   if (childPid == 0)
449                   {
450                       /* Child. */
451                       close(pair[1]);
452 mike  1.1.2.8         Child(argc, argv, cimservermainPath, globals.childUid, 
453                           globals.childGid, pair[0], repositoryDir);
454 mike  1.1.2.1     }
455                   else if (childPid > 0)
456                   {
457                       /* Parent. */
458                       close(pair[0]);
459                       Parent(pair[1], childPid);
460                   }
461                   else
462                   {
463                       Fatal(FL, "fork() failed");
464                   }
465               
466                   return 0;
467               }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2