(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                   /* Define ${cimshutdown} */
157               
158 kumpf    1.2      DefineMacro("cimshutdown", CIMSHUTDOWN);
159               
160                   /* Define ${cimservera} */
161               
162                   DefineMacro("cimservera", CIMSERVERA);
163               
164                   /* Define ${cimservermainPath} */
165                   {
166                       char path[EXECUTOR_BUFFER_SIZE];
167               
168                       if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
169                           Fatal(FL, "failed to resolve cimservermainPath");
170               
171                       DefineMacro("cimservermainPath", path);
172                   }
173               
174                   /* Define ${cimprovagtPath} */
175                   {
176                       char path[EXECUTOR_BUFFER_SIZE];
177               
178                       if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
179 kumpf    1.2              Fatal(FL, "failed to resolve cimprovagtPath");
180               
181                       DefineMacro("cimprovagtPath", path);
182                   }
183               
184                   /* Define ${cimshutdownPath} */
185                   {
186                       char path[EXECUTOR_BUFFER_SIZE];
187               
188                       if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
189                           Fatal(FL, "failed to resolve cimshutdownPath");
190               
191                       DefineMacro("cimshutdownPath", path);
192                   }
193               
194                   /* Define ${cimserveraPath} */
195                   {
196                       char path[EXECUTOR_BUFFER_SIZE];
197               
198                       if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
199                           Fatal(FL, "failed to resolve cimserveraPath");
200 kumpf    1.2  
201                       DefineMacro("cimserveraPath", path);
202                   }
203               
204                   /* Define ${shutdownTimeout} */
205               
206                   {
207                       char buffer[EXECUTOR_BUFFER_SIZE];
208               
209                       if (GetConfigParam("shutdownTimeout", buffer) != 0)
210 kumpf    1.7          {
211                           Strlcpy(
212                               buffer,
213                               PEGASUS_DEFAULT_SHUTDOWN_TIMEOUT_SECONDS_STRING,
214                               sizeof(buffer));
215                       }
216 kumpf    1.2  
217                       DefineMacro("shutdownTimeout", buffer);
218                   }
219               
220                   /* Define ${currentConfigFilePath} */
221                   {
222                       char path[EXECUTOR_BUFFER_SIZE];
223               
224                       if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
225                       {
226                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
227                               PEGASUS_CURRENT_CONFIG_FILE_PATH);
228                       }
229               
230                       DefineMacro("currentConfigFilePath", path);
231                   }
232               
233                   /* Define ${plannedConfigFilePath} */
234                   {
235                       char path[EXECUTOR_BUFFER_SIZE];
236               
237 kumpf    1.2          if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) != 0)
238                       {
239                           Fatal(FL, "GetHomedPath() failed on \"%s\"",
240                               PEGASUS_PLANNED_CONFIG_FILE_PATH);
241                       }
242               
243                       DefineMacro("plannedConfigFilePath", path);
244                   }
245               
246                   /* Define ${passwordFilePath} */
247               
248                   if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
249                       Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
250               
251                   /* Define ${sslKeyFilePath} */
252               
253                   if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
254                       Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
255               
256                   /* Define ${sslTrustStore} */
257               
258 kumpf    1.2      if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
259                       Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
260               
261                   /* Define ${crlStore} */
262               
263                   if (DefineConfigPathMacro("crlStore", "crl") != 0)
264                       Fatal(FL, "missing \"crlStore\" configuration parameter.");
265 sahana.prabhakar 1.18 
266                           /* Define ${localAuthDir} */
267                           if(DefineMacro("localAuthDir",PEGASUS_LOCAL_AUTH_DIR) != 0)
268                               Fatal(FL, "missing \"localAuthDir\" configuration parameter.");
269 kumpf            1.2  }
270                       
271                       /*
272                       **==============================================================================
273                       **
274                       ** main()
275                       **
276                       **==============================================================================
277                       */
278                       
279 s.kodali         1.17 
280 kumpf            1.2  int main(int argc, char** argv)
281                       {
282                           const char* cimservermainPath;
283 kumpf            1.11     const char* workingDirectory;
284 kumpf            1.2      int pair[2];
285 kumpf            1.10     int initCompletePipe[2];
286                           int pid;
287 kumpf            1.2      char username[EXECUTOR_BUFFER_SIZE];
288 kumpf            1.6      const char* childUserName;
289                           int childUid;
290                           int childGid;
291 kumpf            1.2      int childPid;
292                           struct Options options;
293                       
294                           /* Get options. */
295                       
296                           GetOptions(&argc, &argv, &options);
297                       
298                           /* Save argc-argv as globals. */
299                       
300                           globals.argc = argc;
301                           globals.argv = argv;
302                       
303 kumpf            1.6      /* Open the log. */
304                       
305 s.kodali         1.17     OpenLog(CIMSERVER_LOG_IDENTITY);
306 kumpf            1.6  
307 kumpf            1.2      /* Define macros needed by the executor. */
308                       
309                           DefineExecutorMacros();
310                       
311 kumpf            1.6      /* If shutting down, then run CIMSHUTDOWN client. */
312 kumpf            1.2  
313                           if (options.shutdown)
314                               ExecShutdown();
315                       
316                           /* Process --policy and --macros options. */
317                       
318                           if (options.dump)
319                           {
320 kumpf            1.4          DumpPolicy(stdout, 1);
321                               DumpMacros(stdout);
322 kumpf            1.2          exit(0);
323                           }
324                       
325                           /* Get absolute CIMSERVERMAIN program name. */
326                       
327                           if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
328                               Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
329                       
330                           /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
331                            * the following options are given: -v, --version, -h, --help (these are
332                            * passed through to CIMSERVERMAIN).
333                            */
334                       
335 denise.eckstein  1.16     if (!options.version && !options.help)
336                           {
337                               int isRunning = (TestProcessRunning(
338                                   PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN) == 0);
339                               if (options.status)
340                               {
341                                   if (isRunning)
342                                   {
343                                       fprintf(stderr, "CIM Server is running.\n");
344                                       exit(0);
345                                   } 
346                                   else
347                                   {
348                                       fprintf(stderr, "CIM Server is not running.\n");
349                                       exit(2);
350                                   }
351                               }
352                               else if (isRunning)
353                               {
354                                   fprintf(stderr,
355                                       "%s: cimserver is already running (the PID found in the file "
356 denise.eckstein  1.16                 "\"%s\" corresponds to an existing process named \"%s\").\n\n",
357                                       globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);  
358                                   exit(1);
359                               }
360                           } 
361 kumpf            1.2  
362                           /* Get enableAuthentication configuration option. */
363                       
364                           {
365                               char buffer[EXECUTOR_BUFFER_SIZE];
366                       
367                               if (GetConfigParam("enableAuthentication", buffer) == 0 &&
368                                   strcasecmp(buffer, "true") == 0)
369                               {
370                                   globals.enableAuthentication = 1;
371                               }
372                           }
373                       
374 kumpf            1.4      /* Initialize the log-level from the configuration parameter. */
375 kumpf            1.2  
376 kumpf            1.4      InitLogLevel();
377 kumpf            1.2  
378 denise.eckstein  1.13     Log(LL_TRACE, "starting");
379 kumpf            1.2  
380                           /* Be sure this process is running as root (otherwise fail). */
381                       
382                           if (setuid(0) != 0 || setgid(0) != 0)
383                               Fatal(FL, "attempted to run program as non-root user");
384                       
385                           /* Warn if authentication not enabled (suspicious use of executor). */
386                       
387                           if (!globals.enableAuthentication)
388                               Log(LL_WARNING, "authentication is NOT enabled");
389                           else
390                               Log(LL_TRACE, "authentication is enabled");
391                       
392                           /* Print user info. */
393                       
394                           if (GetUserName(getuid(), username) != 0)
395                               Fatal(FL, "cannot resolve user from uid=%d", getuid());
396                       
397                           Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
398                               username, (int)getuid(), (int)getgid());
399                       
400 mateus.baur      1.9      /* Change the current directory */
401                       
402 kumpf            1.11 #if defined(PEGASUS_USE_RELEASE_DIRS) && defined(PEGASUS_CORE_DIR)
403                           workingDirectory = PEGASUS_CORE_DIR;
404 denise.eckstein  1.12 #elif defined(PEGASUS_DEBUG)
405                           workingDirectory = getenv("PEGASUS_TMP");
406 mateus.baur      1.9  #endif
407 denise.eckstein  1.12     if (workingDirectory == NULL)
408                           {
409                               workingDirectory = "/";
410                           }
411 kumpf            1.11     if (chdir(workingDirectory) != 0)
412                           {
413                               Log(LL_WARNING, "Failed to change working directory to %s",
414                                   workingDirectory);
415                           }
416                       
417 kumpf            1.10     /* Create a pipe for communicating with cimserver daemon process. */
418                       
419                           if (pipe(initCompletePipe) != 0)
420                               Fatal(FL, "Failed to create pipe");
421                       
422                           CloseOnExec(initCompletePipe[0]);
423                           CloseOnExec(initCompletePipe[1]);
424                       
425                           /* Fork to ensure we are not a session leader so setsid() will succeed. */
426                       
427                           pid = fork();
428                       
429                           if (pid < 0)
430                           {
431                               Fatal(FL, "fork() failed");
432                           }
433                       
434                           if (pid > 0)
435                           {
436                               /* Wait until daemon writes an exit code or closes the pipe. */
437                       
438 kumpf            1.10         char exitRC;
439                               ssize_t result;
440                               time_t startTime;
441                               time_t now;
442                       
443                               close(initCompletePipe[1]);
444                               SetNonBlocking(initCompletePipe[0]);
445                               time(&startTime);
446                       
447                               do
448                               {
449                                   time(&now);
450                                   result = WaitForReadEnable(
451                                       initCompletePipe[0],
452                                       (CIMSERVER_COMMAND_TIMEOUT_SECONDS - (now - startTime)) * 1000);
453                               } while (result == -1 && errno == EINTR);
454                       
455                               if (result == 0)
456                               {
457                                   fprintf(stderr,
458                                       "The cimserver command timed out waiting for the CIM server "
459 kumpf            1.10                     "to start.");
460                                   _exit(0);
461                               }
462                       
463                               EXECUTOR_RESTART(read(initCompletePipe[0], &exitRC, 1), result);
464                               if (result <= 0)
465                               {
466                                   exitRC = 1;
467                               }
468                               _exit(exitRC);
469                           }
470                       
471                           close(initCompletePipe[0]);
472                       
473                           /* Become session leader (so that our child process will not be one) */
474                       
475                           if (setsid() < 0)
476                           {
477                               Fatal(FL, "setsid() failed");
478                           }
479                       
480 kumpf            1.10     /* Ignore SIGHUP: */
481                       
482                           signal(SIGHUP, SIG_IGN);
483                       
484                           /* Ignore SIGCHLD: */
485                       
486                           signal(SIGCHLD, SIG_IGN);
487                       
488                           /* Ignore SIGPIPE: */
489                       
490                           signal(SIGPIPE, SIG_IGN);
491                       
492                           /* Fork cimserver daemon process (not a session leader since parent is). */
493                       
494                           pid = fork();
495                       
496                           if (pid < 0)
497                           {
498                               Fatal(FL, "fork() failed");
499                           }
500                       
501 kumpf            1.10     if (pid > 0)
502                           {
503                               _exit(0);
504                           }
505                       
506 kumpf            1.2      /* Determine user for running CIMSERVERMAIN. */
507                       
508 kumpf            1.6      GetServerUser(&childUserName, &childUid, &childGid);
509 kumpf            1.2  
510 kumpf            1.10     /* Create a socket pair for communicating with the child process. */
511                       
512                           if (CreateSocketPair(pair) != 0)
513                               Fatal(FL, "Failed to create socket pair");
514                       
515                           CloseOnExec(pair[1]);
516                       
517 kumpf            1.2      /* Fork child process. */
518                       
519                           childPid = fork();
520                       
521                           if (childPid == 0)
522                           {
523                               /* Child. */
524                               close(pair[1]);
525 kumpf            1.3          Child(
526                                   argc,
527                                   argv,
528                                   cimservermainPath,
529 kumpf            1.6              childUserName,
530                                   childUid,
531                                   childGid,
532 kumpf            1.3              pair[0]);
533 kumpf            1.2      }
534                           else if (childPid > 0)
535                           {
536                               /* Parent. */
537                               close(pair[0]);
538 kumpf            1.10         Parent(pair[1], initCompletePipe[1], childPid, options.bindVerbose);
539 kumpf            1.2      }
540                           else
541                           {
542                               Fatal(FL, "fork() failed");
543                           }
544                       
545                           return 0;
546                       }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2