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

   1 kumpf 1.2 //%2006////////////////////////////////////////////////////////////////////////
   2           //
   3           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   6           // IBM Corp.; EMC Corporation, The Open Group.
   7           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12           // EMC Corporation; Symantec Corporation; The Open Group.
  13           //
  14           // Permission is hereby granted, free of charge, to any person obtaining a copy
  15           // of this software and associated documentation files (the "Software"), to
  16           // deal in the Software without restriction, including without limitation the
  17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  18           // sell copies of the Software, and to permit persons to whom the Software is
  19           // furnished to do so, subject to the following conditions:
  20           // 
  21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  22 kumpf 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29           //
  30           //==============================================================================
  31           //
  32           //%/////////////////////////////////////////////////////////////////////////////
  33           
  34           #include <cstdio>
  35           #include <cstdlib>
  36           #include <cstring>
  37           
  38           #include <Pegasus/Common/Config.h>
  39           
  40           #if defined(PEGASUS_OS_TYPE_WINDOWS)
  41           # include <windows.h>
  42           #else
  43 kumpf 1.2 # include <unistd.h>
  44 thilo.boehm 1.16 # include <errno.h>
  45 kumpf       1.2  # include <sys/types.h>
  46                  # include <sys/time.h>
  47                  # include <sys/resource.h>
  48                  #endif
  49                  
  50                  #if defined(PEGASUS_HAS_SIGNALS)
  51                  # include <sys/wait.h>
  52                  #endif
  53                  
  54                  #include <Pegasus/Common/Constants.h>
  55                  #include <Pegasus/Common/Mutex.h>
  56 kumpf       1.7  #include <Pegasus/Common/Once.h>
  57 kumpf       1.2  #include <Pegasus/Common/FileSystem.h>
  58                  #include <Pegasus/Common/String.h>
  59                  #include <Pegasus/Common/Tracer.h>
  60 kumpf       1.3  #include <Pegasus/Common/System.h>
  61 kumpf       1.2  #include <Pegasus/Common/Executor.h>
  62                  
  63                  #include <Executor/Strlcpy.h>
  64                  
  65                  #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
  66                  # include <Executor/Socket.h>
  67                  # include <Executor/Messages.h>
  68                  #endif
  69                  
  70                  #if defined(PEGASUS_PAM_AUTHENTICATION)
  71                  # include <Executor/PAMAuth.h>
  72                  #endif
  73                  
  74 ouyang.jian 1.11 #ifdef PEGASUS_OS_PASE
  75                  # include <as400_protos.h> // For fork400()
  76                  #endif
  77                  
  78 kumpf       1.17 #ifdef PEGASUS_OS_ZOS
  79                  # include <spawn.h>
  80                  #endif
  81                  
  82 kumpf       1.2  PEGASUS_NAMESPACE_BEGIN
  83                  
  84                  ////////////////////////////////////////////////////////////////////////////////
  85                  //
  86                  //
  87                  // class ExecutorImpl
  88                  //
  89                  //
  90                  ////////////////////////////////////////////////////////////////////////////////
  91                  
  92                  class ExecutorImpl
  93                  {
  94                  public:
  95                  
  96                      virtual ~ExecutorImpl()
  97                      {
  98                      }
  99                  
 100                      virtual int detectExecutor() = 0;
 101                  
 102                      virtual int ping() = 0;
 103 kumpf       1.2  
 104                      virtual FILE* openFile(
 105                          const char* path,
 106                          int mode) = 0;
 107                  
 108                      virtual int renameFile(
 109                          const char* oldPath,
 110                          const char* newPath) = 0;
 111                  
 112                      virtual int removeFile(
 113                          const char* path) = 0;
 114                  
 115                      virtual int startProviderAgent(
 116                          const char* module,
 117                          const String& pegasusHome,
 118                          const String& userName,
 119                          int& pid,
 120                          AnonymousPipe*& readPipe,
 121                          AnonymousPipe*& writePipe) = 0;
 122                  
 123                      virtual int daemonizeExecutor() = 0;
 124 kumpf       1.2  
 125                      virtual int reapProviderAgent(
 126                          int pid) = 0;
 127                  
 128                      virtual int authenticatePassword(
 129                          const char* username,
 130                          const char* password) = 0;
 131                  
 132                      virtual int validateUser(
 133                          const char* username) = 0;
 134                  
 135                      virtual int challengeLocal(
 136                          const char* username,
 137                          char challengeFilePath[EXECUTOR_BUFFER_SIZE]) = 0;
 138                  
 139                      virtual int authenticateLocal(
 140                          const char* challengeFilePath,
 141                          const char* response) = 0;
 142 kumpf       1.8  
 143                      virtual int updateLogLevel(
 144                          const char* logLevel) = 0;
 145 kumpf       1.2  };
 146                  
 147                  ////////////////////////////////////////////////////////////////////////////////
 148                  //
 149                  //
 150                  // class ExecutorLoopbackImpl
 151                  //
 152                  //
 153                  ////////////////////////////////////////////////////////////////////////////////
 154                  
 155                  class ExecutorLoopbackImpl : public ExecutorImpl
 156                  {
 157                  public:
 158                  
 159                      virtual ~ExecutorLoopbackImpl()
 160                      {
 161                      }
 162                  
 163                      virtual int detectExecutor()
 164                      {
 165                          return -1;
 166 kumpf       1.2      }
 167                  
 168                      virtual int ping()
 169                      {
 170                          return -1;
 171                      }
 172                  
 173                      virtual FILE* openFile(
 174                          const char* path,
 175                          int mode)
 176                      {
 177                          switch (mode)
 178                          {
 179                              case 'r':
 180 carson.hovey 1.15                 return fopen(path, "r");
 181 kumpf        1.2  
 182                               case 'w':
 183 carson.hovey 1.15                 return fopen(path, "w");
 184 kumpf        1.2  
 185                               case 'a':
 186 carson.hovey 1.15                 return fopen(path, "a+");
 187 kumpf        1.2  
 188                               default:
 189                                   return NULL;
 190                           }
 191                       }
 192                   
 193                       virtual int renameFile(
 194                           const char* oldPath,
 195                           const char* newPath)
 196                       {
 197                           return FileSystem::renameFile(oldPath, newPath) ? 0 : -1;
 198                       }
 199                   
 200                   
 201                       virtual int removeFile(
 202                           const char* path)
 203                       {
 204                           return FileSystem::removeFile(path) ? 0 : -1;
 205                       }
 206                   
 207                   
 208 kumpf        1.2      virtual int startProviderAgent(
 209                           const char* module,
 210                           const String& pegasusHome,
 211                           const String& userName,
 212                           int& pid,
 213                           AnonymousPipe*& readPipe,
 214                           AnonymousPipe*& writePipe)
 215                       {
 216 thilo.boehm  1.16         PEG_METHOD_ENTER(TRC_SERVER,"ExecutorLoopbackImpl::startProviderAgent");
 217 kumpf        1.18 
 218 kumpf        1.6  #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 219 kumpf        1.2  
 220 kumpf        1.18         // Resolve full path of "cimprovagt" program.
 221                   
 222                           String path = FileSystem::getAbsolutePath(
 223                               pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);
 224                   
 225                           // Create CString handles for cimprovagt arguments
 226                   
 227                           CString agentProgramPath = path.getCString();
 228                           CString userNameCString = userName.getCString();
 229                   
 230                   # if defined(PEGASUS_DISABLE_PROV_USERCTXT)
 231                           const char* setUserContextFlag = "0";    // False
 232                   # else
 233                           const char* setUserContextFlag = "1";    // True
 234                   # endif
 235                   
 236 kumpf        1.6  # if defined(PEGASUS_OS_TYPE_WINDOWS)
 237 kumpf        1.2  
 238                           AutoMutex autoMutex(_mutex);
 239                   
 240                           // Set output parameters in case of failure.
 241                   
 242                           pid = 0;
 243                           readPipe = 0;
 244                           writePipe = 0;
 245                   
 246                           // Create pipes. Export handles to string.
 247                   
 248                           AutoPtr<AnonymousPipe> pipeFromAgent(new AnonymousPipe());
 249                           AutoPtr<AnonymousPipe> pipeToAgent(new AnonymousPipe());
 250                   
 251                           char readHandle[32];
 252                           char writeHandle[32];
 253                           pipeToAgent->exportReadHandle(readHandle);
 254                           pipeFromAgent->exportWriteHandle(writeHandle);
 255                   
 256                           // Initialize PROCESS_INFORMATION.
 257                   
 258 kumpf        1.2          PROCESS_INFORMATION piProcInfo;
 259                           ZeroMemory(&piProcInfo, sizeof (PROCESS_INFORMATION));
 260                   
 261                           // Initialize STARTUPINFO.
 262                   
 263                           STARTUPINFO siStartInfo;
 264                           ZeroMemory(&siStartInfo, sizeof (STARTUPINFO));
 265                           siStartInfo.cb = sizeof (STARTUPINFO);
 266                   
 267                           // Format command line.
 268                   
 269                           char cmdLine[2048];
 270                   
 271 kumpf        1.18         sprintf(cmdLine, "\"%s\" %s %s %s \"%s\" \"%s\"",
 272                               (const char*)agentProgramPath,
 273                               setUserContextFlag,
 274 kumpf        1.2              readHandle,
 275                               writeHandle,
 276 kumpf        1.18             (const char*)userNameCString,
 277 kumpf        1.2              module);
 278                   
 279                           //  Create provider agent proess.
 280                   
 281                           if (!CreateProcess (
 282                               NULL,          //
 283                               cmdLine,       //  command line
 284                               NULL,          //  process security attributes
 285                               NULL,          //  primary thread security attributes
 286                               TRUE,          //  handles are inherited
 287                               0,             //  creation flags
 288                               NULL,          //  use parent's environment
 289                               NULL,          //  use parent's current directory
 290                               &siStartInfo,  //  STARTUPINFO
 291                               &piProcInfo))  //  PROCESS_INFORMATION
 292                           {
 293 thilo.boehm  1.16             PEG_METHOD_EXIT();
 294 kumpf        1.2              return -1;
 295                           }
 296                   
 297                           CloseHandle(piProcInfo.hProcess);
 298                           CloseHandle(piProcInfo.hThread);
 299                   
 300                           // Close our copies of the agent's ends of the pipes
 301                   
 302                           pipeToAgent->closeReadHandle();
 303                           pipeFromAgent->closeWriteHandle();
 304                   
 305                           readPipe = pipeFromAgent.release();
 306                           writePipe = pipeToAgent.release();
 307                   
 308 thilo.boehm  1.16         PEG_METHOD_EXIT();
 309 kumpf        1.2          return 0;
 310                   
 311 kumpf        1.6  # else /* POSIX CASE FOLLOWS */
 312 thilo.boehm  1.16         
 313 kumpf        1.2          AutoMutex autoMutex(_mutex);
 314                   
 315                           // Initialize output parameters in case of error.
 316                   
 317                           pid = -1;
 318                           readPipe = 0;
 319                           writePipe = 0;
 320                   
 321                           // Pipes:
 322                   
 323                           int to[2];
 324                           int from[2];
 325 kumpf        1.18         char toPipeArg[32];
 326                           char fromPipeArg[32];
 327 thilo.boehm  1.16 
 328 kumpf        1.2          do
 329                           {
 330                               // Create "to-agent" pipe:
 331                   
 332                               if (pipe(to) != 0)
 333 thilo.boehm  1.16             {
 334                                   PEG_METHOD_EXIT();
 335 kumpf        1.2                  return -1;
 336 thilo.boehm  1.16             }
 337                                   
 338 kumpf        1.2              // Create "from-agent" pipe:
 339                   
 340                               if (pipe(from) != 0)
 341 thilo.boehm  1.16             {
 342                                   PEG_METHOD_EXIT();
 343 kumpf        1.2                  return -1;
 344 thilo.boehm  1.16             }
 345                   
 346 kumpf        1.18             // Initialize the cimprovagt pipe arguments:
 347                   
 348                               sprintf(toPipeArg, "%d", to[0]);
 349                               sprintf(fromPipeArg, "%d", from[1]);
 350                   
 351 thilo.boehm  1.16             // Start provider agent:
 352                   
 353                   #  if defined(PEGASUS_OS_ZOS)
 354 kumpf        1.18             // zOS uses __spawn2() instead of fork() to start provider agent
 355                   
 356                               struct __inheritance inherit;
 357                               const char *c_argv[7];
 358                   
 359                               c_argv[0] = agentProgramPath;
 360                               c_argv[1] = setUserContextFlag;
 361                               c_argv[2] = toPipeArg;
 362                               c_argv[3] = fromPipeArg;
 363                               c_argv[4] = userNameCString;
 364                               c_argv[5] = module; 
 365                               c_argv[6] = NULL;
 366 thilo.boehm  1.16 
 367                               // reset the inherit structure
 368                               memset(&inherit,0,sizeof(inherit));
 369                   
 370                               // The provider agent should get a defined JobName.
 371                               inherit.flags=SPAWN_SETJOBNAME;
 372                               memcpy( inherit.jobname,"CFZOOPA ",
 373                                       sizeof(inherit.jobname));
 374                               
 375                               PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 376 kumpf        1.18                 "Starting provider agent: %s %s %s %s %s %s %s",
 377                                   (const char*)agentProgramPath,
 378                                   c_argv[0],
 379                                   c_argv[1],
 380                                   c_argv[2],
 381                                   c_argv[3],
 382                                   c_argv[4],
 383                                   c_argv[5]));
 384 kumpf        1.2  
 385 kumpf        1.18             pid = __spawn2(agentProgramPath,0,NULL,&inherit,
 386 thilo.boehm  1.16                            c_argv,(const char **)environ);
 387 kumpf        1.2  
 388 thilo.boehm  1.16             if (pid < 0)
 389                               {
 390                                   PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 391                                       "Spawn of provider agent fails:%s "
 392                                           "( errno %d , reason code %08X )", 
 393                                       strerror(errno) ,errno,__errno2()));
 394                                   PEG_METHOD_EXIT();
 395                                   return -1;
 396                               }
 397                   
 398 kumpf        1.18 #  else    // !defined(PEGASUS_OS_ZOS)
 399                   
 400                   #   if defined(PEGASUS_OS_VMS)
 401 kumpf        1.2              pid = (int)vfork();
 402 kumpf        1.18 #   elif defined(PEGASUS_OS_PASE)
 403 ouyang.jian  1.11             pid = (int)fork400("QUMEPRVAGT",0);
 404 kumpf        1.18 #   else
 405 kumpf        1.2              pid = (int)fork();
 406 kumpf        1.18 #   endif
 407 thilo.boehm  1.16 
 408 kumpf        1.2              if (pid < 0)
 409 thilo.boehm  1.16             {
 410                                   PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 411                                        "Fork for provider agent fails: errno = %d",errno)); 
 412                                   PEG_METHOD_EXIT();
 413 kumpf        1.2                  return -1;
 414 thilo.boehm  1.16             }
 415                                   
 416 kumpf        1.2              if (pid == 0)
 417                               {
 418 kumpf        1.18                 // Child process
 419                   
 420 thilo.boehm  1.16 #   if !defined(PEGASUS_OS_VMS)
 421 kumpf        1.2                  // Close unused pipe descriptors:
 422                   
 423                                   close(to[1]);
 424                                   close(from[0]);
 425                   
 426                                   // Close unused descriptors. Leave stdin, stdout, stderr,
 427                                   // and the child's pipe descriptors open.
 428                   
 429                                   struct rlimit rlim;
 430                   
 431                                   if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
 432                                   {
 433                                       for (int i = 3; i < int(rlim.rlim_cur); i++)
 434                                       {
 435                                           if (i != to[0] && i != from[1])
 436                                               close(i);
 437                                       }
 438                                   }
 439                   
 440 thilo.boehm  1.16 #   endif /* !defined(PEGASUS_OS_VMS) */
 441 kumpf        1.3  
 442 kumpf        1.2                  // Exec the cimprovagt program.
 443                   
 444                                   {
 445 kumpf        1.18                     if (execl(
 446                                               agentProgramPath,
 447                                               agentProgramPath,
 448                                               setUserContextFlag,
 449                                               toPipeArg,
 450                                               fromPipeArg,
 451                                               (const char*)userNameCString,
 452                                               module,
 453                                               (char*)0) == -1)
 454 kumpf        1.2                      {
 455 thilo.boehm  1.16                         PEG_TRACE((TRC_SERVER, Tracer::LEVEL2,
 456 kumpf        1.2                              "execl() failed.  errno = %d.", errno));
 457                                           _exit(1);
 458                                       }
 459                                   }
 460                               }
 461 kumpf        1.18 #  endif /* PEGASUS_OS_ZOS */
 462 kumpf        1.2          }
 463                           while (0);
 464                   
 465 kumpf        1.18         PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 466                               "Provider agent started: pid(%d).", pid));
 467                   
 468 kumpf        1.2          // Close unused pipe descriptors.
 469                   
 470                           close(to[0]);
 471                           close(from[1]);
 472                   
 473                           // Set output parameters.
 474                   
 475                           int readFd = from[0];
 476                           int writeFd = to[1];
 477                   
 478                           // Create to and from AnonymousPipe instances to correspond to the pipe
 479                           // descriptors created above.
 480                   
 481                           char readFdStr[32];
 482                           char writeFdStr[32];
 483                           sprintf(readFdStr, "%d", readFd);
 484                           sprintf(writeFdStr, "%d", writeFd);
 485                   
 486                           readPipe = new AnonymousPipe(readFdStr, 0);
 487                           writePipe = new AnonymousPipe(0, writeFdStr);
 488                   
 489 kumpf        1.18 #  if defined(PEGASUS_HAS_SIGNALS)
 490                   #   if !defined(PEGASUS_DISABLE_PROV_USERCTXT) && !defined(PEGASUS_OS_ZOS)
 491                           // The cimprovagt forks and returns right away.  Clean up the zombie
 492                           // process now instead of in reapProviderAgent().
 493                           int status = 0;
 494                           while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
 495                               ;
 496                   #   endif
 497                   #  endif
 498                   
 499 thilo.boehm  1.16         PEG_METHOD_EXIT();
 500 kumpf        1.2          return 0;
 501                   
 502 kumpf        1.6  # endif /* POSIX CASE */
 503                   
 504                   #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
 505                   
 506                           // Out-of-Process providers are never started by the cimserver process
 507                           // when Privilege Separation is enabled.
 508                           return -1;
 509                   
 510                   #endif
 511 kumpf        1.2      }
 512                   
 513                       virtual int daemonizeExecutor()
 514                       {
 515                           return -1;
 516                       }
 517                   
 518                       virtual int reapProviderAgent(
 519                           int pid)
 520                       {
 521 kumpf        1.6  #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 522                   
 523 kumpf        1.2          int status = 0;
 524                   
 525 kumpf        1.6  # if defined(PEGASUS_HAS_SIGNALS)
 526 kumpf        1.18 #  if defined(PEGASUS_DISABLE_PROV_USERCTXT) || defined(PEGASUS_OS_ZOS)
 527                           // When provider user context is enabled, this is done in
 528                           // startProviderAgent().
 529 kumpf        1.2          while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
 530                               ;
 531 kumpf        1.18 #  endif
 532 kumpf        1.6  # endif
 533 kumpf        1.2  
 534                           return status;
 535 kumpf        1.6  
 536                   #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
 537                   
 538                           // Out-of-Process providers are never started by the cimserver process
 539                           // when Privilege Separation is enabled.
 540                           return -1;
 541                   
 542                   #endif
 543 kumpf        1.2      }
 544                   
 545                       virtual int authenticatePassword(
 546                           const char* username,
 547                           const char* password)
 548                       {
 549                   #if defined(PEGASUS_PAM_AUTHENTICATION)
 550                           return PAMAuthenticate(username, password);
 551                   #else
 552                           // ATTN: not handled so don't call in this case.
 553                           return -1;
 554                   #endif
 555                       }
 556                   
 557                       virtual int validateUser(
 558                           const char* username)
 559                       {
 560 kumpf        1.12 #if defined(PEGASUS_PAM_AUTHENTICATION)
 561 kumpf        1.2          return PAMValidateUser(username);
 562 kumpf        1.12 #else
 563 kumpf        1.2          // ATTN: not handled so don't call in this case.
 564                           return -1;
 565 kumpf        1.12 #endif
 566 kumpf        1.2      }
 567                   
 568                       virtual int challengeLocal(
 569                           const char* username,
 570                           char challengeFilePath[EXECUTOR_BUFFER_SIZE])
 571                       {
 572                           // ATTN: not handled so don't call in this case.
 573                           return -1;
 574                       }
 575                   
 576                       virtual int authenticateLocal(
 577                           const char* challengeFilePath,
 578                           const char* response)
 579                       {
 580                           // ATTN: not handled so don't call in this case.
 581                           return -1;
 582                       }
 583                   
 584 kumpf        1.8      virtual int updateLogLevel(
 585                           const char* logLevel)
 586                       {
 587                           // If Privilege Separation is not enabled, we don't need to update
 588                           // the log level in the Executor.
 589                           return 0;
 590                       }
 591                   
 592 kumpf        1.2  private:
 593                   
 594                       Mutex _mutex;
 595                   };
 596                   
 597                   ////////////////////////////////////////////////////////////////////////////////
 598                   //
 599                   //
 600                   // class ExecutorSocketImpl : public ExecutorImpl
 601                   //
 602                   //
 603                   ////////////////////////////////////////////////////////////////////////////////
 604                   
 605                   #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 606                   
 607                   class ExecutorSocketImpl : public ExecutorImpl
 608                   {
 609                   public:
 610                   
 611                       ExecutorSocketImpl(int sock) : _sock(sock)
 612                       {
 613 kumpf        1.2      }
 614                   
 615                       virtual ~ExecutorSocketImpl()
 616                       {
 617                       }
 618                   
 619                       virtual int detectExecutor()
 620                       {
 621                           return 0;
 622                       }
 623                   
 624                       virtual int ping()
 625                       {
 626                           AutoMutex autoMutex(_mutex);
 627                   
 628 kumpf        1.9          // Send request header:
 629 kumpf        1.2  
 630                           ExecutorRequestHeader header;
 631                           header.code = EXECUTOR_PING_MESSAGE;
 632                   
 633 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 634 kumpf        1.2              return -1;
 635                   
 636                           ExecutorPingResponse response;
 637                   
 638 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 639 kumpf        1.2              return -1;
 640                   
 641                           if (response.magic == EXECUTOR_PING_MAGIC)
 642                               return 0;
 643                   
 644                           return -1;
 645                       }
 646                   
 647                       virtual FILE* openFile(
 648                           const char* path,
 649                           int mode)
 650                       {
 651                           AutoMutex autoMutex(_mutex);
 652                   
 653                           if (mode != 'r' && mode != 'w' && mode != 'a')
 654                               return NULL;
 655                   
 656 kumpf        1.9          // Send request header:
 657 kumpf        1.2  
 658                           ExecutorRequestHeader header;
 659                           header.code = EXECUTOR_OPEN_FILE_MESSAGE;
 660                   
 661 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 662 kumpf        1.2              return NULL;
 663                   
 664 kumpf        1.9          // Send request body.
 665 kumpf        1.2  
 666                           ExecutorOpenFileRequest request;
 667                           memset(&request, 0, sizeof(request));
 668                           Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 669                           request.mode = mode;
 670                   
 671 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 672 kumpf        1.2              return NULL;
 673                   
 674                           // Receive the response
 675                   
 676                           ExecutorOpenFileResponse response;
 677                   
 678 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 679 kumpf        1.2              return NULL;
 680                   
 681                           // Receive descriptor (if response successful).
 682                   
 683                           if (response.status == 0)
 684                           {
 685                               int fds[1];
 686                   
 687                               if (RecvDescriptorArray(_sock, fds, 1) != 0)
 688                                   return NULL;
 689                   
 690                               if (fds[0] == -1)
 691                                   return NULL;
 692                               else
 693                               {
 694                                   if (mode == 'r')
 695                                       return fdopen(fds[0], "rb");
 696                                   else
 697                                       return fdopen(fds[0], "wb");
 698                               }
 699                           }
 700 kumpf        1.2  
 701                           return NULL;
 702                       }
 703                   
 704                       virtual int renameFile(
 705                           const char* oldPath,
 706                           const char* newPath)
 707                       {
 708                           AutoMutex autoMutex(_mutex);
 709                   
 710 kumpf        1.9          // Send request header:
 711 kumpf        1.2  
 712                           ExecutorRequestHeader header;
 713                           header.code = EXECUTOR_RENAME_FILE_MESSAGE;
 714                   
 715 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 716 kumpf        1.2              return -1;
 717                   
 718 kumpf        1.9          // Send request body.
 719 kumpf        1.2  
 720                           ExecutorRenameFileRequest request;
 721                           memset(&request, 0, sizeof(request));
 722                           Strlcpy(request.oldPath, oldPath, EXECUTOR_BUFFER_SIZE);
 723                           Strlcpy(request.newPath, newPath, EXECUTOR_BUFFER_SIZE);
 724                   
 725 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 726 kumpf        1.2              return -1;
 727                   
 728                           // Receive the response
 729                   
 730                           ExecutorRenameFileResponse response;
 731                   
 732 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 733 kumpf        1.2              return -1;
 734                   
 735                           return response.status;
 736                       }
 737                   
 738                       virtual int removeFile(
 739                           const char* path)
 740                       {
 741                           AutoMutex autoMutex(_mutex);
 742                   
 743 kumpf        1.9          // Send request header:
 744 kumpf        1.2  
 745                           ExecutorRequestHeader header;
 746                           header.code = EXECUTOR_REMOVE_FILE_MESSAGE;
 747                   
 748 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 749 kumpf        1.2              return -1;
 750                   
 751 kumpf        1.9          // Send request body.
 752 kumpf        1.2  
 753                           ExecutorRemoveFileRequest request;
 754                           memset(&request, 0, sizeof(request));
 755                           Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 756                   
 757 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 758 kumpf        1.2              return -1;
 759                   
 760                           // Receive the response
 761                   
 762                           ExecutorRemoveFileResponse response;
 763                   
 764 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 765 kumpf        1.2              return -1;
 766                   
 767                           return response.status;
 768                       }
 769                   
 770                       virtual int startProviderAgent(
 771                           const char* module,
 772                           const String& pegasusHome,
 773                           const String& userName,
 774                           int& pid,
 775                           AnonymousPipe*& readPipe,
 776                           AnonymousPipe*& writePipe)
 777                       {
 778                           AutoMutex autoMutex(_mutex);
 779                   
 780                           readPipe = 0;
 781                           writePipe = 0;
 782                   
 783                           // Reject strings longer than EXECUTOR_BUFFER_SIZE.
 784                   
 785 kumpf        1.3          size_t moduleNameLength = strlen(module);
 786                   
 787                           if (moduleNameLength >= EXECUTOR_BUFFER_SIZE)
 788                               return -1;
 789                   
 790                           CString userNameCString = userName.getCString();
 791                           size_t userNameLength = strlen(userNameCString);
 792 kumpf        1.2  
 793 kumpf        1.3          if (userNameLength >= EXECUTOR_BUFFER_SIZE)
 794 kumpf        1.2              return -1;
 795                   
 796 kumpf        1.9          // Send request header:
 797 kumpf        1.2  
 798                           ExecutorRequestHeader header;
 799                           header.code = EXECUTOR_START_PROVIDER_AGENT_MESSAGE;
 800                   
 801 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 802 kumpf        1.2              return -1;
 803                   
 804 kumpf        1.9          // Send request body.
 805 kumpf        1.2  
 806                           ExecutorStartProviderAgentRequest request;
 807                           memset(&request, 0, sizeof(request));
 808 kumpf        1.3          memcpy(request.module, module, moduleNameLength);
 809                           memcpy(request.userName, userNameCString, userNameLength);
 810 kumpf        1.2  
 811 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 812 kumpf        1.2              return -1;
 813                   
 814                           // Receive the response
 815                   
 816                           ExecutorStartProviderAgentResponse response;
 817                   
 818 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 819 kumpf        1.2              return -1;
 820                   
 821                           // Check response status and pid.
 822                   
 823                           if (response.status != 0)
 824                               return -1;
 825                   
 826                           // Get pid:
 827                   
 828                           pid = response.pid;
 829                   
 830                           // Receive descriptors.
 831                   
 832                           int descriptors[2];
 833                           int result = RecvDescriptorArray(_sock, descriptors, 2);
 834                   
 835                           if (result == 0)
 836                           {
 837                               int readFd = descriptors[0];
 838                               int writeFd = descriptors[1];
 839                   
 840 kumpf        1.2              // Create to and from AnonymousPipe instances to correspond to
 841                               // the pipe descriptors created above.
 842                   
 843                               char readFdStr[32];
 844                               char writeFdStr[32];
 845                               sprintf(readFdStr, "%d", readFd);
 846                               sprintf(writeFdStr, "%d", writeFd);
 847                   
 848                               readPipe = new AnonymousPipe(readFdStr, 0);
 849                               writePipe = new AnonymousPipe(0, writeFdStr);
 850                           }
 851                   
 852                           return result;
 853                       }
 854                   
 855                       virtual int daemonizeExecutor()
 856                       {
 857                           AutoMutex autoMutex(_mutex);
 858                   
 859 kumpf        1.9          // Send request header:
 860 kumpf        1.2  
 861                           ExecutorRequestHeader header;
 862                           header.code = EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE;
 863                   
 864 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 865 kumpf        1.2              return -1;
 866                   
 867                           // Receive the response
 868                   
 869                           ExecutorDaemonizeExecutorResponse response;
 870                   
 871 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 872 kumpf        1.2              return -1;
 873                   
 874                           return response.status;
 875                       }
 876                   
 877                       virtual int reapProviderAgent(
 878                           int pid)
 879                       {
 880 kumpf        1.10         // The Executor process automatically cleans up all its child
 881                           // processes, so it does not need to explicitly harvest the
 882                           // exit status of the cimprovagt processes it starts.
 883 kumpf        1.2  
 884 kumpf        1.10         return 0;
 885 kumpf        1.2      }
 886                   
 887                       virtual int authenticatePassword(
 888                           const char* username,
 889                           const char* password)
 890                       {
 891                           AutoMutex autoMutex(_mutex);
 892                   
 893 kumpf        1.9          // Send request header:
 894 kumpf        1.2  
 895                           ExecutorRequestHeader header;
 896                           header.code = EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE;
 897                   
 898 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 899 kumpf        1.2              return -1;
 900                   
 901 kumpf        1.9          // Send request body.
 902 kumpf        1.2  
 903                           ExecutorAuthenticatePasswordRequest request;
 904                           memset(&request, 0, sizeof(request));
 905                           Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 906                           Strlcpy(request.password, password, EXECUTOR_BUFFER_SIZE);
 907                   
 908 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 909 kumpf        1.2              return -1;
 910                   
 911                           // Receive the response
 912                   
 913                           ExecutorAuthenticatePasswordResponse response;
 914                   
 915 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 916 kumpf        1.2              return -1;
 917                   
 918                           return response.status;
 919                       }
 920                   
 921                       virtual int validateUser(
 922                           const char* username)
 923                       {
 924                           AutoMutex autoMutex(_mutex);
 925                   
 926 kumpf        1.9          // Send request header:
 927 kumpf        1.2  
 928                           ExecutorRequestHeader header;
 929                           header.code = EXECUTOR_VALIDATE_USER_MESSAGE;
 930                   
 931 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 932 kumpf        1.2              return -1;
 933                   
 934 kumpf        1.9          // Send request body.
 935 kumpf        1.2  
 936                           ExecutorValidateUserRequest request;
 937                           memset(&request, 0, sizeof(request));
 938                           Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 939                   
 940 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 941 kumpf        1.2              return -1;
 942                   
 943                           // Receive the response
 944                   
 945                           ExecutorValidateUserResponse response;
 946                   
 947 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 948 kumpf        1.2              return -1;
 949                   
 950                           return response.status;
 951                       }
 952                   
 953                       virtual int challengeLocal(
 954                           const char* username,
 955                           char challengeFilePath[EXECUTOR_BUFFER_SIZE])
 956                       {
 957                           AutoMutex autoMutex(_mutex);
 958                   
 959 kumpf        1.9          // Send request header:
 960 kumpf        1.2  
 961                           ExecutorRequestHeader header;
 962                           header.code = EXECUTOR_CHALLENGE_LOCAL_MESSAGE;
 963                   
 964 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 965 kumpf        1.2              return -1;
 966                   
 967 kumpf        1.9          // Send request body.
 968 kumpf        1.2  
 969                           ExecutorChallengeLocalRequest request;
 970                           memset(&request, 0, sizeof(request));
 971                           Strlcpy(request.user, username, EXECUTOR_BUFFER_SIZE);
 972                   
 973 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 974 kumpf        1.2              return -1;
 975                   
 976                           // Receive the response
 977                   
 978                           ExecutorChallengeLocalResponse response;
 979                   
 980 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 981 kumpf        1.2              return -1;
 982                   
 983                           Strlcpy(challengeFilePath, response.challenge, EXECUTOR_BUFFER_SIZE);
 984                   
 985                           return response.status;
 986                       }
 987                   
 988                       virtual int authenticateLocal(
 989                           const char* challengeFilePath,
 990                           const char* response)
 991                       {
 992                           AutoMutex autoMutex(_mutex);
 993                   
 994 kumpf        1.9          // Send request header:
 995 kumpf        1.2  
 996                           ExecutorRequestHeader header;
 997                           header.code = EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE;
 998                   
 999 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1000 kumpf        1.2              return -1;
1001                   
1002 kumpf        1.9          // Send request body.
1003 kumpf        1.2  
1004                           ExecutorAuthenticateLocalRequest request;
1005                           memset(&request, 0, sizeof(request));
1006                           Strlcpy(request.challenge, challengeFilePath, EXECUTOR_BUFFER_SIZE);
1007                           Strlcpy(request.response, response, EXECUTOR_BUFFER_SIZE);
1008                   
1009 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1010 kumpf        1.2              return -1;
1011                   
1012                           // Receive the response
1013                   
1014                           ExecutorAuthenticateLocalResponse response_;
1015                   
1016 kumpf        1.9          if (RecvBlock(_sock, &response_, sizeof(response_)) !=
1017                                   sizeof(response_))
1018                           {
1019 kumpf        1.2              return -1;
1020 kumpf        1.9          }
1021 kumpf        1.2  
1022                           return response_.status;
1023                       }
1024                   
1025 kumpf        1.8      virtual int updateLogLevel(
1026                           const char* logLevel)
1027                       {
1028                           AutoMutex autoMutex(_mutex);
1029                   
1030 kumpf        1.9          // Send request header:
1031 kumpf        1.8  
1032                           ExecutorRequestHeader header;
1033                           header.code = EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE;
1034                   
1035 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1036 kumpf        1.8              return -1;
1037                   
1038 kumpf        1.9          // Send request body:
1039 kumpf        1.8  
1040                           ExecutorUpdateLogLevelRequest request;
1041                           memset(&request, 0, sizeof(request));
1042                           Strlcpy(request.logLevel, logLevel, EXECUTOR_BUFFER_SIZE);
1043                   
1044 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1045 kumpf        1.8              return -1;
1046                   
1047                           // Receive the response
1048                   
1049                           ExecutorUpdateLogLevelResponse response;
1050                   
1051 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
1052 kumpf        1.8              return -1;
1053                   
1054                           return response.status;
1055                       }
1056                   
1057 kumpf        1.2  private:
1058                   
1059                       int _sock;
1060                       Mutex _mutex;
1061                   };
1062                   
1063                   #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1064                   
1065                   ////////////////////////////////////////////////////////////////////////////////
1066                   //
1067                   //
1068                   // class Executor
1069                   //
1070                   //
1071                   ////////////////////////////////////////////////////////////////////////////////
1072                   
1073                   static int _executorSock = -1;
1074 kumpf        1.5  static AutoPtr<ExecutorImpl> _executorImpl;
1075 kumpf        1.7  static Once _executorImplOnce = PEGASUS_ONCE_INITIALIZER;
1076 kumpf        1.2  
1077 kumpf        1.7  static void _initExecutorImpl()
1078 kumpf        1.2  {
1079                   #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1080 kumpf        1.7      if (_executorSock == -1)
1081                           _executorImpl.reset(new ExecutorLoopbackImpl());
1082                       else
1083                           _executorImpl.reset(new ExecutorSocketImpl(_executorSock));
1084 kumpf        1.2  #else
1085 kumpf        1.7      _executorImpl.reset(new ExecutorLoopbackImpl());
1086 kumpf        1.2  #endif
1087                   }
1088                   
1089                   void Executor::setSock(int sock)
1090                   {
1091                       _executorSock = sock;
1092                   }
1093                   
1094                   int Executor::detectExecutor()
1095                   {
1096 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1097                       return _executorImpl->detectExecutor();
1098 kumpf        1.2  }
1099                   
1100                   int Executor::ping()
1101                   {
1102 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1103                       return _executorImpl->ping();
1104 kumpf        1.2  }
1105                   
1106                   FILE* Executor::openFile(
1107                       const char* path,
1108                       int mode)
1109                   {
1110 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1111                       return _executorImpl->openFile(path, mode);
1112 kumpf        1.2  }
1113                   
1114                   int Executor::renameFile(
1115                       const char* oldPath,
1116                       const char* newPath)
1117                   {
1118 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1119                       return _executorImpl->renameFile(oldPath, newPath);
1120 kumpf        1.2  }
1121                   
1122                   int Executor::removeFile(
1123                       const char* path)
1124                   {
1125 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1126                       return _executorImpl->removeFile(path);
1127 kumpf        1.2  }
1128                   
1129                   int Executor::startProviderAgent(
1130                       const char* module,
1131                       const String& pegasusHome,
1132                       const String& userName,
1133                       int& pid,
1134                       AnonymousPipe*& readPipe,
1135                       AnonymousPipe*& writePipe)
1136                   {
1137 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1138                       return _executorImpl->startProviderAgent(
1139 kumpf        1.3          module, pegasusHome, userName, pid, readPipe, writePipe);
1140 kumpf        1.2  }
1141                   
1142                   int Executor::daemonizeExecutor()
1143                   {
1144 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1145                       return _executorImpl->daemonizeExecutor();
1146 kumpf        1.2  }
1147                   
1148                   int Executor::reapProviderAgent(
1149                       int pid)
1150                   {
1151 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1152                       return _executorImpl->reapProviderAgent(pid);
1153 kumpf        1.2  }
1154                   
1155                   int Executor::authenticatePassword(
1156                       const char* username,
1157                       const char* password)
1158                   {
1159 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1160                       return _executorImpl->authenticatePassword(username, password);
1161 kumpf        1.2  }
1162                   
1163                   int Executor::validateUser(
1164                       const char* username)
1165                   {
1166 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1167                       return _executorImpl->validateUser(username);
1168 kumpf        1.2  }
1169                   
1170                   int Executor::challengeLocal(
1171                       const char* user,
1172                       char challengeFilePath[EXECUTOR_BUFFER_SIZE])
1173                   {
1174 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1175                       return _executorImpl->challengeLocal(user, challengeFilePath);
1176 kumpf        1.2  }
1177                   
1178                   int Executor::authenticateLocal(
1179                       const char* challengeFilePath,
1180                       const char* response)
1181                   {
1182 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1183                       return _executorImpl->authenticateLocal(challengeFilePath, response);
1184 kumpf        1.2  }
1185                   
1186 kumpf        1.8  int Executor::updateLogLevel(
1187                       const char* logLevel)
1188                   {
1189                       once(&_executorImplOnce, _initExecutorImpl);
1190                       return _executorImpl->updateLogLevel(logLevel);
1191                   }
1192                   
1193 kumpf        1.2  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2