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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2