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

  1 kumpf 1.2 /*
  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 kumpf 1.2 // 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 kumpf 1.7.2.3 #include <signal.h>
 39               #include <time.h>
 40 kumpf 1.2     #include "Config.h"
 41               #include "Child.h"
 42               #include "Parent.h"
 43               #include "User.h"
 44               #include "Fatal.h"
 45               #include "Process.h"
 46               #include "Path.h"
 47               #include "Globals.h"
 48               #include "Socket.h"
 49               #include "Strlcpy.h"
 50               #include "Strlcat.h"
 51               #include "Log.h"
 52               #include "Policy.h"
 53               #include "Macro.h"
 54               #include "Assert.h"
 55               #include "Options.h"
 56 kumpf 1.7.2.1 #include <Pegasus/Common/PegasusVersion.h>
 57 kumpf 1.2     
 58 kumpf 1.7.2.3 #define CIMSERVER_COMMAND_TIMEOUT_SECONDS 240
 59               
 60 kumpf 1.2     /*
 61               **==============================================================================
 62               **
 63               ** GetServerUser
 64               **
 65               **     Determine which user to run CIMSERVERMAIN as.
 66               **
 67               **==============================================================================
 68               */
 69               
 70 kumpf 1.3     int GetServerUser(const char** userName, int* uid, int* gid)
 71 kumpf 1.2     {
 72 kumpf 1.3         *userName = PEGASUS_CIMSERVERMAIN_USER;
 73 kumpf 1.2     
 74 kumpf 1.3         if (GetUserInfo(*userName, uid, gid) != 0)
 75 kumpf 1.2         {
 76                       Fatal(FL,
 77                           "The %s user \"%s\" does not exist.",
 78 kumpf 1.3                 CIMSERVERMAIN, *userName);
 79 kumpf 1.2         }
 80               
 81                   return 0;
 82               }
 83               
 84               /*
 85               **==============================================================================
 86               **
 87               ** ExecShutdown()
 88               **
 89               **==============================================================================
 90               */
 91               
 92 kumpf 1.5     void ExecShutdown(void)
 93 kumpf 1.2     {
 94                   char* tmpArgv[3];
 95                   const char* cimshutdownPath;
 96                   const char* shutdownTimeout;
 97               
 98                   /* Get shutdownTimeout configuration parameter. */
 99               
100                   if ((shutdownTimeout = FindMacro("shutdownTimeout")) == NULL)
101                       Fatal(FL, "failed to resolve shutdownTimeout");
102               
103                   /* Get absolute CIMSHUTDOWN program name. */
104               
105                   if ((cimshutdownPath = FindMacro("cimshutdownPath")) == NULL)
106                       Fatal(FL, "failed to resolve cimshutdownPath");
107               
108                   /* Create argument list. */
109               
110                   tmpArgv[0] = CIMSHUTDOWN;
111                   tmpArgv[1] = (char*)shutdownTimeout;
112                   tmpArgv[2] = 0;
113               
114 kumpf 1.2         /* Exec CIMSHUTDOWN program. */
115               
116                   /* Flawfinder: ignore */
117                   execv(cimshutdownPath, tmpArgv);
118                   Fatal(FL, "failed to exec %s", cimshutdownPath);
119               }
120               
121               /*
122               **==============================================================================
123               **
124               ** DefineExecutorMacros()
125               **
126               **     Define macros used by the executor.
127               **
128               **==============================================================================
129               */
130               
131 kumpf 1.5     void DefineExecutorMacros(void)
132 kumpf 1.2     {
133                   /* Define ${internalBinDir} */
134                   {
135                       char path[EXECUTOR_BUFFER_SIZE];
136               
137                       if (GetPegasusInternalBinDir(path) != 0)
138                           Fatal(FL, "failed to resolve internal pegasus bin directory");
139               
140                       DefineMacro("internalBinDir", path);
141                   }
142               
143                   /* Define ${cimservermain} */
144               
145                   DefineMacro("cimservermain", CIMSERVERMAIN);
146               
147                   /* Define ${cimprovagt} */
148               
149                   DefineMacro("cimprovagt", CIMPROVAGT);
150               
151                   /* Define ${cimshutdown} */
152               
153 kumpf 1.2         DefineMacro("cimshutdown", CIMSHUTDOWN);
154               
155                   /* Define ${cimservera} */
156               
157                   DefineMacro("cimservera", CIMSERVERA);
158               
159                   /* Define ${cimservermainPath} */
160                   {
161                       char path[EXECUTOR_BUFFER_SIZE];
162               
163                       if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
164                           Fatal(FL, "failed to resolve cimservermainPath");
165               
166                       DefineMacro("cimservermainPath", path);
167                   }
168               
169                   /* Define ${cimprovagtPath} */
170                   {
171                       char path[EXECUTOR_BUFFER_SIZE];
172               
173                       if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
174 kumpf 1.2                 Fatal(FL, "failed to resolve cimprovagtPath");
175               
176                       DefineMacro("cimprovagtPath", path);
177                   }
178               
179                   /* Define ${cimshutdownPath} */
180                   {
181                       char path[EXECUTOR_BUFFER_SIZE];
182               
183                       if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
184                           Fatal(FL, "failed to resolve cimshutdownPath");
185               
186                       DefineMacro("cimshutdownPath", path);
187                   }
188               
189                   /* Define ${cimserveraPath} */
190                   {
191                       char path[EXECUTOR_BUFFER_SIZE];
192               
193                       if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
194                           Fatal(FL, "failed to resolve cimserveraPath");
195 kumpf 1.2     
196                       DefineMacro("cimserveraPath", path);
197                   }
198               
199                   /* Define ${shutdownTimeout} */
200               
201                   {
202                       char buffer[EXECUTOR_BUFFER_SIZE];
203               
204                       if (GetConfigParam("shutdownTimeout", buffer) != 0)
205 kumpf 1.7             {
206                           Strlcpy(
207                               buffer,
208                               PEGASUS_DEFAULT_SHUTDOWN_TIMEOUT_SECONDS_STRING,
209                               sizeof(buffer));
210                       }
211 kumpf 1.2     
212                       DefineMacro("shutdownTimeout", buffer);
213                   }
214               
215                   /* Define ${currentConfigFilePath} */
216                   {
217                       char path[EXECUTOR_BUFFER_SIZE];
218               
219                       if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
220                       {
221                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
222                               PEGASUS_CURRENT_CONFIG_FILE_PATH);
223                       }
224               
225                       DefineMacro("currentConfigFilePath", path);
226                   }
227               
228                   /* Define ${plannedConfigFilePath} */
229                   {
230                       char path[EXECUTOR_BUFFER_SIZE];
231               
232 kumpf 1.2             if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) != 0)
233                       {
234                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
235                               PEGASUS_PLANNED_CONFIG_FILE_PATH);
236                       }
237               
238                       DefineMacro("plannedConfigFilePath", path);
239                   }
240               
241                   /* Define ${passwordFilePath} */
242               
243                   if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
244                       Fatal(FL, "missing \"passwordFilePath\" 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 kumpf 1.2         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               ** main()
266               **
267               **==============================================================================
268               */
269               
270               int main(int argc, char** argv)
271               {
272                   const char* cimservermainPath;
273                   int pair[2];
274 kumpf 1.7.2.3     int initCompletePipe[2];
275                   int pid;
276 kumpf 1.2         char username[EXECUTOR_BUFFER_SIZE];
277 kumpf 1.6         const char* childUserName;
278                   int childUid;
279                   int childGid;
280 kumpf 1.2         int childPid;
281                   struct Options options;
282               
283                   /* Get options. */
284               
285                   GetOptions(&argc, &argv, &options);
286               
287                   /* Save argc-argv as globals. */
288               
289                   globals.argc = argc;
290                   globals.argv = argv;
291               
292 kumpf 1.6         /* Open the log. */
293               
294                   OpenLog("cimserver");
295               
296 kumpf 1.2         /* Define macros needed by the executor. */
297               
298                   DefineExecutorMacros();
299               
300 kumpf 1.6         /* If shutting down, then run CIMSHUTDOWN client. */
301 kumpf 1.2     
302                   if (options.shutdown)
303                       ExecShutdown();
304               
305                   /* Process --policy and --macros options. */
306               
307                   if (options.dump)
308                   {
309 kumpf 1.4             DumpPolicy(stdout, 1);
310                       DumpMacros(stdout);
311 kumpf 1.2             exit(0);
312                   }
313               
314                   /* Get absolute CIMSERVERMAIN program name. */
315               
316                   if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
317                       Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
318               
319                   /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
320                    * the following options are given: -v, --version, -h, --help (these are
321                    * passed through to CIMSERVERMAIN).
322                    */
323               
324 kumpf 1.4         if (!options.version &&
325                       !options.help &&
326                       TestProcessRunning(PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN) == 0)
327 kumpf 1.2         {
328                       fprintf(stderr,
329                           "%s: cimserver is already running (the PID found in the file "
330                           "\"%s\" corresponds to an existing process named \"%s\").\n\n",
331                           globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
332               
333                       exit(1);
334                   }
335               
336                   /* Get enableAuthentication configuration option. */
337               
338                   {
339                       char buffer[EXECUTOR_BUFFER_SIZE];
340               
341                       if (GetConfigParam("enableAuthentication", buffer) == 0 &&
342                           strcasecmp(buffer, "true") == 0)
343                       {
344                           globals.enableAuthentication = 1;
345                       }
346                   }
347               
348 kumpf 1.4         /* Initialize the log-level from the configuration parameter. */
349 kumpf 1.2     
350 kumpf 1.4         InitLogLevel();
351 kumpf 1.2     
352                   Log(LL_INFORMATION, "starting");
353               
354                   /* Be sure this process is running as root (otherwise fail). */
355               
356                   if (setuid(0) != 0 || setgid(0) != 0)
357                       Fatal(FL, "attempted to run program as non-root user");
358               
359                   /* Warn if authentication not enabled (suspicious use of executor). */
360               
361                   if (!globals.enableAuthentication)
362                       Log(LL_WARNING, "authentication is NOT enabled");
363                   else
364                       Log(LL_TRACE, "authentication is enabled");
365               
366                   /* Print user info. */
367               
368                   if (GetUserName(getuid(), username) != 0)
369                       Fatal(FL, "cannot resolve user from uid=%d", getuid());
370               
371                   Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
372 kumpf 1.2             username, (int)getuid(), (int)getgid());
373               
374 mateus.baur 1.7.2.2     /* Change the current directory */
375                     
376                     #if (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX)) \
377                         && defined(PEGASUS_USE_RELEASE_DIRS)
378                         chdir(PEGASUS_CORE_DIR);
379                     #else
380                         chdir("/");
381                     #endif
382                     
383 kumpf       1.7.2.3     /* Create a pipe for communicating with cimserver daemon process. */
384                     
385                         if (pipe(initCompletePipe) != 0)
386                             Fatal(FL, "Failed to create pipe");
387                     
388                         CloseOnExec(initCompletePipe[0]);
389                         CloseOnExec(initCompletePipe[1]);
390                     
391                         /* Fork to ensure we are not a session leader so setsid() will succeed. */
392                     
393                         pid = fork();
394                     
395                         if (pid < 0)
396                         {
397                             Fatal(FL, "fork() failed");
398                         }
399                     
400                         if (pid > 0)
401                         {
402                             /* Wait until daemon writes an exit code or closes the pipe. */
403                     
404 kumpf       1.7.2.3         char exitRC;
405                             ssize_t result;
406                             time_t startTime;
407                             time_t now;
408                     
409                             close(initCompletePipe[1]);
410                             SetNonBlocking(initCompletePipe[0]);
411                             time(&startTime);
412                     
413                             do
414                             {
415                                 time(&now);
416                                 result = WaitForReadEnable(
417                                     initCompletePipe[0],
418                                     (CIMSERVER_COMMAND_TIMEOUT_SECONDS - (now - startTime)) * 1000);
419                             } while (result == -1 && errno == EINTR);
420                     
421                             if (result == 0)
422                             {
423                                 fprintf(stderr,
424                                     "The cimserver command timed out waiting for the CIM server "
425 kumpf       1.7.2.3                     "to start.");
426                                 _exit(0);
427                             }
428                     
429                             EXECUTOR_RESTART(read(initCompletePipe[0], &exitRC, 1), result);
430                             if (result <= 0)
431                             {
432                                 exitRC = 1;
433                             }
434                             _exit(exitRC);
435                         }
436                     
437                         close(initCompletePipe[0]);
438                     
439                         /* Become session leader (so that our child process will not be one) */
440                     
441                         if (setsid() < 0)
442                         {
443                             Fatal(FL, "setsid() failed");
444                         }
445                     
446 kumpf       1.7.2.3     /* Ignore SIGHUP: */
447                     
448                         signal(SIGHUP, SIG_IGN);
449                     
450                         /* Ignore SIGCHLD: */
451                     
452                         signal(SIGCHLD, SIG_IGN);
453                     
454                         /* Ignore SIGPIPE: */
455                     
456                         signal(SIGPIPE, SIG_IGN);
457                     
458                         /* Fork cimserver daemon process (not a session leader since parent is). */
459                     
460                         pid = fork();
461                     
462                         if (pid < 0)
463                         {
464                             Fatal(FL, "fork() failed");
465                         }
466                     
467 kumpf       1.7.2.3     if (pid > 0)
468                         {
469                             _exit(0);
470                         }
471                     
472 kumpf       1.2         /* Determine user for running CIMSERVERMAIN. */
473                     
474 kumpf       1.6         GetServerUser(&childUserName, &childUid, &childGid);
475 kumpf       1.2     
476 kumpf       1.7.2.3     /* Create a socket pair for communicating with the child process. */
477                     
478                         if (CreateSocketPair(pair) != 0)
479                             Fatal(FL, "Failed to create socket pair");
480                     
481                         CloseOnExec(pair[1]);
482                     
483 kumpf       1.2         /* Fork child process. */
484                     
485                         childPid = fork();
486                     
487                         if (childPid == 0)
488                         {
489                             /* Child. */
490                             close(pair[1]);
491 kumpf       1.3             Child(
492                                 argc,
493                                 argv,
494                                 cimservermainPath,
495 kumpf       1.6                 childUserName,
496                                 childUid,
497                                 childGid,
498 kumpf       1.3                 pair[0]);
499 kumpf       1.2         }
500                         else if (childPid > 0)
501                         {
502                             /* Parent. */
503                             close(pair[0]);
504 kumpf       1.7.2.3         Parent(pair[1], initCompletePipe[1], childPid, options.bindVerbose);
505 kumpf       1.2         }
506                         else
507                         {
508                             Fatal(FL, "fork() failed");
509                         }
510                     
511                         return 0;
512                     }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2