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

  1 kumpf 1.2 /*
  2 martin 1.14 //%LICENSE////////////////////////////////////////////////////////////////
  3 martin 1.15 //
  4 martin 1.14 // Licensed to The Open Group (TOG) under one or more contributor license
  5             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  6             // this work for additional information regarding copyright ownership.
  7             // Each contributor licenses this file to you under the OpenPegasus Open
  8             // Source License; you may not use this file except in compliance with the
  9             // License.
 10 martin 1.15 //
 11 martin 1.14 // Permission is hereby granted, free of charge, to any person obtaining a
 12             // copy of this software and associated documentation files (the "Software"),
 13             // to deal in the Software without restriction, including without limitation
 14             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 15             // and/or sell copies of the Software, and to permit persons to whom the
 16             // Software is furnished to do so, subject to the following conditions:
 17 martin 1.15 //
 18 martin 1.14 // The above copyright notice and this permission notice shall be included
 19             // in all copies or substantial portions of the Software.
 20 martin 1.15 //
 21 martin 1.14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 22 martin 1.15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 23 martin 1.14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 24             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 25             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 26             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 27             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 28 martin 1.15 //
 29 martin 1.14 //////////////////////////////////////////////////////////////////////////
 30 kumpf  1.2  */
 31 martin 1.14 
 32 kumpf  1.2  #include <stdio.h>
 33             #include <sys/types.h>
 34             #include <sys/stat.h>
 35             #include <unistd.h>
 36             #include <string.h>
 37 kumpf  1.10 #include <signal.h>
 38             #include <time.h>
 39 kumpf  1.2  #include "Config.h"
 40             #include "Child.h"
 41             #include "Parent.h"
 42             #include "User.h"
 43             #include "Fatal.h"
 44             #include "Process.h"
 45             #include "Path.h"
 46             #include "Globals.h"
 47             #include "Socket.h"
 48             #include "Strlcpy.h"
 49             #include "Strlcat.h"
 50             #include "Log.h"
 51             #include "Policy.h"
 52             #include "Macro.h"
 53             #include "Assert.h"
 54             #include "Options.h"
 55 kumpf  1.8  #include <Pegasus/Common/PegasusVersion.h>
 56 kumpf  1.2  
 57 kumpf  1.10 #define CIMSERVER_COMMAND_TIMEOUT_SECONDS 240
 58             
 59 s.kodali 1.17 #ifdef PEGASUS_FLAVOR
 60               # define CIMSERVER_LOG_IDENTITY "cimserver" PEGASUS_FLAVOR
 61               #else
 62               # define CIMSERVER_LOG_IDENTITY "cimserver"
 63               #endif
 64               
 65 kumpf    1.2  /*
 66               **==============================================================================
 67               **
 68               ** GetServerUser
 69               **
 70               **     Determine which user to run CIMSERVERMAIN as.
 71               **
 72               **==============================================================================
 73               */
 74               
 75 kumpf    1.3  int GetServerUser(const char** userName, int* uid, int* gid)
 76 kumpf    1.2  {
 77 kumpf    1.3      *userName = PEGASUS_CIMSERVERMAIN_USER;
 78 kumpf    1.2  
 79 kumpf    1.3      if (GetUserInfo(*userName, uid, gid) != 0)
 80 kumpf    1.2      {
 81                       Fatal(FL,
 82                           "The %s user \"%s\" does not exist.",
 83 kumpf    1.3              CIMSERVERMAIN, *userName);
 84 kumpf    1.2      }
 85               
 86                   return 0;
 87               }
 88               
 89               /*
 90               **==============================================================================
 91               **
 92               ** ExecShutdown()
 93               **
 94               **==============================================================================
 95               */
 96               
 97 kumpf    1.5  void ExecShutdown(void)
 98 kumpf    1.2  {
 99                   char* tmpArgv[3];
100                   const char* cimshutdownPath;
101                   const char* shutdownTimeout;
102               
103                   /* Get shutdownTimeout configuration parameter. */
104               
105                   if ((shutdownTimeout = FindMacro("shutdownTimeout")) == NULL)
106                       Fatal(FL, "failed to resolve shutdownTimeout");
107               
108                   /* Get absolute CIMSHUTDOWN program name. */
109               
110                   if ((cimshutdownPath = FindMacro("cimshutdownPath")) == NULL)
111                       Fatal(FL, "failed to resolve cimshutdownPath");
112               
113                   /* Create argument list. */
114               
115                   tmpArgv[0] = CIMSHUTDOWN;
116                   tmpArgv[1] = (char*)shutdownTimeout;
117                   tmpArgv[2] = 0;
118               
119 kumpf    1.2      /* Exec CIMSHUTDOWN program. */
120               
121                   /* Flawfinder: ignore */
122                   execv(cimshutdownPath, tmpArgv);
123                   Fatal(FL, "failed to exec %s", cimshutdownPath);
124               }
125               
126               /*
127               **==============================================================================
128               **
129               ** DefineExecutorMacros()
130               **
131               **     Define macros used by the executor.
132               **
133               **==============================================================================
134               */
135               
136 kumpf    1.5  void DefineExecutorMacros(void)
137 kumpf    1.2  {
138                   /* Define ${internalBinDir} */
139                   {
140                       char path[EXECUTOR_BUFFER_SIZE];
141               
142                       if (GetPegasusInternalBinDir(path) != 0)
143                           Fatal(FL, "failed to resolve internal pegasus bin directory");
144               
145                       DefineMacro("internalBinDir", path);
146                   }
147               
148                   /* Define ${cimservermain} */
149               
150                   DefineMacro("cimservermain", CIMSERVERMAIN);
151               
152                   /* Define ${cimprovagt} */
153               
154                   DefineMacro("cimprovagt", CIMPROVAGT);
155               
156 s.kodali 1.19     /* Define ${cimprovagt} */
157               
158                   DefineMacro("cimprovagt32", CIMPROVAGT32);
159               
160 kumpf    1.2      /* Define ${cimshutdown} */
161               
162                   DefineMacro("cimshutdown", CIMSHUTDOWN);
163               
164                   /* Define ${cimservera} */
165               
166                   DefineMacro("cimservera", CIMSERVERA);
167               
168                   /* Define ${cimservermainPath} */
169                   {
170                       char path[EXECUTOR_BUFFER_SIZE];
171               
172                       if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
173                           Fatal(FL, "failed to resolve cimservermainPath");
174               
175                       DefineMacro("cimservermainPath", path);
176                   }
177               
178                   /* Define ${cimprovagtPath} */
179                   {
180                       char path[EXECUTOR_BUFFER_SIZE];
181 kumpf    1.2  
182                       if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
183                           Fatal(FL, "failed to resolve cimprovagtPath");
184               
185                       DefineMacro("cimprovagtPath", path);
186                   }
187               
188 s.kodali 1.19     /* Define ${cimprovagt32Path} */
189                   {
190                       char path[EXECUTOR_BUFFER_SIZE];
191               
192                       if (ExpandMacros("${internalBinDir}/${cimprovagt32}", path) != 0)
193                           Fatal(FL, "failed to resolve cimprovagt32Path");
194               
195                       DefineMacro("cimprovagt32Path", path);
196                   }
197               
198 kumpf    1.2      /* Define ${cimshutdownPath} */
199                   {
200                       char path[EXECUTOR_BUFFER_SIZE];
201               
202                       if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
203                           Fatal(FL, "failed to resolve cimshutdownPath");
204               
205                       DefineMacro("cimshutdownPath", path);
206                   }
207               
208                   /* Define ${cimserveraPath} */
209                   {
210                       char path[EXECUTOR_BUFFER_SIZE];
211               
212                       if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
213                           Fatal(FL, "failed to resolve cimserveraPath");
214               
215                       DefineMacro("cimserveraPath", path);
216                   }
217               
218                   /* Define ${shutdownTimeout} */
219 kumpf    1.2  
220                   {
221                       char buffer[EXECUTOR_BUFFER_SIZE];
222               
223                       if (GetConfigParam("shutdownTimeout", buffer) != 0)
224 kumpf    1.7          {
225                           Strlcpy(
226                               buffer,
227                               PEGASUS_DEFAULT_SHUTDOWN_TIMEOUT_SECONDS_STRING,
228                               sizeof(buffer));
229                       }
230 kumpf    1.2  
231                       DefineMacro("shutdownTimeout", buffer);
232                   }
233               
234                   /* Define ${currentConfigFilePath} */
235                   {
236                       char path[EXECUTOR_BUFFER_SIZE];
237               
238                       if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
239                       {
240                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
241                               PEGASUS_CURRENT_CONFIG_FILE_PATH);
242                       }
243               
244                       DefineMacro("currentConfigFilePath", path);
245                   }
246               
247                   /* Define ${plannedConfigFilePath} */
248                   {
249                       char path[EXECUTOR_BUFFER_SIZE];
250               
251 kumpf    1.2          if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) != 0)
252                       {
253                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
254                               PEGASUS_PLANNED_CONFIG_FILE_PATH);
255                       }
256               
257                       DefineMacro("plannedConfigFilePath", path);
258                   }
259               
260                   /* Define ${passwordFilePath} */
261               
262                   if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
263                       Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
264               
265                   /* Define ${sslKeyFilePath} */
266               
267                   if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
268                       Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
269               
270                   /* Define ${sslTrustStore} */
271               
272 kumpf    1.2      if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
273                       Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
274               
275                   /* Define ${crlStore} */
276               
277                   if (DefineConfigPathMacro("crlStore", "crl") != 0)
278                       Fatal(FL, "missing \"crlStore\" configuration parameter.");
279 sahana.prabhakar 1.18 
280                           /* Define ${localAuthDir} */
281                           if(DefineMacro("localAuthDir",PEGASUS_LOCAL_AUTH_DIR) != 0)
282                               Fatal(FL, "missing \"localAuthDir\" configuration parameter.");
283 kumpf            1.2  }
284                       
285                       /*
286                       **==============================================================================
287                       **
288                       ** main()
289                       **
290                       **==============================================================================
291                       */
292                       
293 s.kodali         1.17 
294 kumpf            1.2  int main(int argc, char** argv)
295                       {
296                           const char* cimservermainPath;
297 kumpf            1.11     const char* workingDirectory;
298 kumpf            1.2      int pair[2];
299 kumpf            1.10     int initCompletePipe[2];
300                           int pid;
301 kumpf            1.2      char username[EXECUTOR_BUFFER_SIZE];
302 kumpf            1.6      const char* childUserName;
303                           int childUid;
304                           int childGid;
305 kumpf            1.2      int childPid;
306                           struct Options options;
307                       
308                           /* Get options. */
309                       
310                           GetOptions(&argc, &argv, &options);
311                       
312                           /* Save argc-argv as globals. */
313                       
314                           globals.argc = argc;
315                           globals.argv = argv;
316                       
317 kumpf            1.6      /* Open the log. */
318                       
319 s.kodali         1.17     OpenLog(CIMSERVER_LOG_IDENTITY);
320 kumpf            1.6  
321 kumpf            1.2      /* Define macros needed by the executor. */
322                       
323                           DefineExecutorMacros();
324                       
325 kumpf            1.6      /* If shutting down, then run CIMSHUTDOWN client. */
326 kumpf            1.2  
327                           if (options.shutdown)
328                               ExecShutdown();
329                       
330                           /* Process --policy and --macros options. */
331                       
332                           if (options.dump)
333                           {
334 kumpf            1.4          DumpPolicy(stdout, 1);
335                               DumpMacros(stdout);
336 kumpf            1.2          exit(0);
337                           }
338                       
339                           /* Get absolute CIMSERVERMAIN program name. */
340                       
341                           if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
342                               Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
343                       
344                           /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
345                            * the following options are given: -v, --version, -h, --help (these are
346                            * passed through to CIMSERVERMAIN).
347                            */
348                       
349 denise.eckstein  1.16     if (!options.version && !options.help)
350                           {
351                               int isRunning = (TestProcessRunning(
352                                   PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN) == 0);
353                               if (options.status)
354                               {
355                                   if (isRunning)
356                                   {
357                                       fprintf(stderr, "CIM Server is running.\n");
358                                       exit(0);
359                                   } 
360                                   else
361                                   {
362                                       fprintf(stderr, "CIM Server is not running.\n");
363                                       exit(2);
364                                   }
365                               }
366                               else if (isRunning)
367                               {
368                                   fprintf(stderr,
369                                       "%s: cimserver is already running (the PID found in the file "
370 denise.eckstein  1.16                 "\"%s\" corresponds to an existing process named \"%s\").\n\n",
371                                       globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);  
372                                   exit(1);
373                               }
374                           } 
375 kumpf            1.2  
376                           /* Get enableAuthentication configuration option. */
377                       
378                           {
379                               char buffer[EXECUTOR_BUFFER_SIZE];
380                       
381                               if (GetConfigParam("enableAuthentication", buffer) == 0 &&
382                                   strcasecmp(buffer, "true") == 0)
383                               {
384                                   globals.enableAuthentication = 1;
385                               }
386                           }
387                       
388 kumpf            1.4      /* Initialize the log-level from the configuration parameter. */
389 kumpf            1.2  
390 kumpf            1.4      InitLogLevel();
391 kumpf            1.2  
392 denise.eckstein  1.13     Log(LL_TRACE, "starting");
393 kumpf            1.2  
394                           /* Be sure this process is running as root (otherwise fail). */
395                       
396                           if (setuid(0) != 0 || setgid(0) != 0)
397                               Fatal(FL, "attempted to run program as non-root user");
398                       
399                           /* Warn if authentication not enabled (suspicious use of executor). */
400                       
401                           if (!globals.enableAuthentication)
402                               Log(LL_WARNING, "authentication is NOT enabled");
403                           else
404                               Log(LL_TRACE, "authentication is enabled");
405                       
406                           /* Print user info. */
407                       
408                           if (GetUserName(getuid(), username) != 0)
409                               Fatal(FL, "cannot resolve user from uid=%d", getuid());
410                       
411                           Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
412                               username, (int)getuid(), (int)getgid());
413                       
414 mateus.baur      1.9      /* Change the current directory */
415                       
416 kumpf            1.11 #if defined(PEGASUS_USE_RELEASE_DIRS) && defined(PEGASUS_CORE_DIR)
417                           workingDirectory = PEGASUS_CORE_DIR;
418 denise.eckstein  1.12 #elif defined(PEGASUS_DEBUG)
419                           workingDirectory = getenv("PEGASUS_TMP");
420 mateus.baur      1.9  #endif
421 denise.eckstein  1.12     if (workingDirectory == NULL)
422                           {
423                               workingDirectory = "/";
424                           }
425 kumpf            1.11     if (chdir(workingDirectory) != 0)
426                           {
427                               Log(LL_WARNING, "Failed to change working directory to %s",
428                                   workingDirectory);
429                           }
430                       
431 kumpf            1.10     /* Create a pipe for communicating with cimserver daemon process. */
432                       
433                           if (pipe(initCompletePipe) != 0)
434                               Fatal(FL, "Failed to create pipe");
435                       
436                           CloseOnExec(initCompletePipe[0]);
437                           CloseOnExec(initCompletePipe[1]);
438                       
439                           /* Fork to ensure we are not a session leader so setsid() will succeed. */
440                       
441                           pid = fork();
442                       
443                           if (pid < 0)
444                           {
445                               Fatal(FL, "fork() failed");
446                           }
447                       
448                           if (pid > 0)
449                           {
450                               /* Wait until daemon writes an exit code or closes the pipe. */
451                       
452 kumpf            1.10         char exitRC;
453                               ssize_t result;
454                               time_t startTime;
455                               time_t now;
456                       
457                               close(initCompletePipe[1]);
458                               SetNonBlocking(initCompletePipe[0]);
459                               time(&startTime);
460                       
461                               do
462                               {
463                                   time(&now);
464                                   result = WaitForReadEnable(
465                                       initCompletePipe[0],
466                                       (CIMSERVER_COMMAND_TIMEOUT_SECONDS - (now - startTime)) * 1000);
467                               } while (result == -1 && errno == EINTR);
468                       
469                               if (result == 0)
470                               {
471                                   fprintf(stderr,
472                                       "The cimserver command timed out waiting for the CIM server "
473 kumpf            1.10                     "to start.");
474                                   _exit(0);
475                               }
476                       
477                               EXECUTOR_RESTART(read(initCompletePipe[0], &exitRC, 1), result);
478                               if (result <= 0)
479                               {
480                                   exitRC = 1;
481                               }
482                               _exit(exitRC);
483                           }
484                       
485                           close(initCompletePipe[0]);
486                       
487                           /* Become session leader (so that our child process will not be one) */
488                       
489                           if (setsid() < 0)
490                           {
491                               Fatal(FL, "setsid() failed");
492                           }
493                       
494 kumpf            1.10     /* Ignore SIGHUP: */
495                       
496                           signal(SIGHUP, SIG_IGN);
497                       
498                           /* Ignore SIGCHLD: */
499                       
500                           signal(SIGCHLD, SIG_IGN);
501                       
502                           /* Ignore SIGPIPE: */
503                       
504                           signal(SIGPIPE, SIG_IGN);
505                       
506                           /* Fork cimserver daemon process (not a session leader since parent is). */
507                       
508                           pid = fork();
509                       
510                           if (pid < 0)
511                           {
512                               Fatal(FL, "fork() failed");
513                           }
514                       
515 kumpf            1.10     if (pid > 0)
516                           {
517                               _exit(0);
518                           }
519                       
520 kumpf            1.2      /* Determine user for running CIMSERVERMAIN. */
521                       
522 kumpf            1.6      GetServerUser(&childUserName, &childUid, &childGid);
523 kumpf            1.2  
524 kumpf            1.10     /* Create a socket pair for communicating with the child process. */
525                       
526                           if (CreateSocketPair(pair) != 0)
527                               Fatal(FL, "Failed to create socket pair");
528                       
529                           CloseOnExec(pair[1]);
530                       
531 kumpf            1.2      /* Fork child process. */
532                       
533                           childPid = fork();
534                       
535                           if (childPid == 0)
536                           {
537                               /* Child. */
538                               close(pair[1]);
539 kumpf            1.3          Child(
540                                   argc,
541                                   argv,
542                                   cimservermainPath,
543 kumpf            1.6              childUserName,
544                                   childUid,
545                                   childGid,
546 kumpf            1.3              pair[0]);
547 kumpf            1.2      }
548                           else if (childPid > 0)
549                           {
550                               /* Parent. */
551                               close(pair[0]);
552 kumpf            1.10         Parent(pair[1], initCompletePipe[1], childPid, options.bindVerbose);
553 kumpf            1.2      }
554                           else
555                           {
556                               Fatal(FL, "fork() failed");
557                           }
558                       
559                           return 0;
560                       }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2