(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.6  #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 218 kumpf        1.2  
 219 kumpf        1.6  # if defined(PEGASUS_OS_TYPE_WINDOWS)
 220 kumpf        1.2  
 221                           AutoMutex autoMutex(_mutex);
 222                   
 223                           // Set output parameters in case of failure.
 224                   
 225                           pid = 0;
 226                           readPipe = 0;
 227                           writePipe = 0;
 228                   
 229                           // Create pipes. Export handles to string.
 230                   
 231                           AutoPtr<AnonymousPipe> pipeFromAgent(new AnonymousPipe());
 232                           AutoPtr<AnonymousPipe> pipeToAgent(new AnonymousPipe());
 233                   
 234                           char readHandle[32];
 235                           char writeHandle[32];
 236                           pipeToAgent->exportReadHandle(readHandle);
 237                           pipeFromAgent->exportWriteHandle(writeHandle);
 238                   
 239                           // Initialize PROCESS_INFORMATION.
 240                   
 241 kumpf        1.2          PROCESS_INFORMATION piProcInfo;
 242                           ZeroMemory(&piProcInfo, sizeof (PROCESS_INFORMATION));
 243                   
 244                           // Initialize STARTUPINFO.
 245                   
 246                           STARTUPINFO siStartInfo;
 247                           ZeroMemory(&siStartInfo, sizeof (STARTUPINFO));
 248                           siStartInfo.cb = sizeof (STARTUPINFO);
 249                   
 250                           // Build full path of "cimprovagt" program.
 251                   
 252                           String path = FileSystem::getAbsolutePath(
 253                               pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);
 254                   
 255                           // Format command line.
 256                   
 257                           char cmdLine[2048];
 258                   
 259                           sprintf(cmdLine, "\"%s\" %s %s \"%s\"",
 260                               (const char*)path.getCString(),
 261                               readHandle,
 262 kumpf        1.2              writeHandle,
 263                               module);
 264                   
 265                           //  Create provider agent proess.
 266                   
 267                           if (!CreateProcess (
 268                               NULL,          //
 269                               cmdLine,       //  command line
 270                               NULL,          //  process security attributes
 271                               NULL,          //  primary thread security attributes
 272                               TRUE,          //  handles are inherited
 273                               0,             //  creation flags
 274                               NULL,          //  use parent's environment
 275                               NULL,          //  use parent's current directory
 276                               &siStartInfo,  //  STARTUPINFO
 277                               &piProcInfo))  //  PROCESS_INFORMATION
 278                           {
 279 thilo.boehm  1.16             PEG_METHOD_EXIT();
 280 kumpf        1.2              return -1;
 281                           }
 282                   
 283                           CloseHandle(piProcInfo.hProcess);
 284                           CloseHandle(piProcInfo.hThread);
 285                   
 286                           // Close our copies of the agent's ends of the pipes
 287                   
 288                           pipeToAgent->closeReadHandle();
 289                           pipeFromAgent->closeWriteHandle();
 290                   
 291                           readPipe = pipeFromAgent.release();
 292                           writePipe = pipeToAgent.release();
 293                   
 294 thilo.boehm  1.16         PEG_METHOD_EXIT();
 295 kumpf        1.2          return 0;
 296                   
 297 kumpf        1.6  # else /* POSIX CASE FOLLOWS */
 298 thilo.boehm  1.16         
 299 kumpf        1.2          AutoMutex autoMutex(_mutex);
 300                   
 301                           // Initialize output parameters in case of error.
 302                   
 303                           pid = -1;
 304                           readPipe = 0;
 305                           writePipe = 0;
 306                   
 307                           // Pipes:
 308                   
 309                           int to[2];
 310                           int from[2];
 311                   
 312 thilo.boehm  1.16 #  if defined(PEGASUS_OS_ZOS)
 313                           // zOS is using __spawn2() instead of frok()
 314                           struct __inheritance inherit;
 315                           const char *c_argv[5];
 316                           char arg1[32];
 317                           char arg2[32];
 318                   
 319                   #  endif
 320                   
 321 kumpf        1.2          do
 322                           {
 323                               // Resolve full path of "cimprovagt".
 324                   
 325                               String path = FileSystem::getAbsolutePath(
 326                                   pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);
 327                   
 328 r.kieninger  1.13 #  if !defined(PEGASUS_DISABLE_PROV_USERCTXT) && !defined(PEGASUS_OS_ZOS)
 329 kumpf        1.3  
 330                               PEGASUS_UID_T newUid = (PEGASUS_UID_T)-1;
 331                               PEGASUS_GID_T newGid = (PEGASUS_GID_T)-1;
 332                   
 333                               if (userName != System::getEffectiveUserName())
 334                               {
 335                                   if (!System::lookupUserId(
 336                                            userName.getCString(), newUid, newGid))
 337                                   {
 338 thilo.boehm  1.16                     PEG_TRACE((TRC_SERVER, Tracer::LEVEL2,
 339                                           "System::lookupUserId(%s) for provider user "
 340                                               "context failed.",
 341 kumpf        1.3                          (const char*)userName.getCString()));
 342 thilo.boehm  1.16                     PEG_METHOD_EXIT();
 343 kumpf        1.3                      return -1;
 344                                   }
 345                               }
 346                   
 347 kumpf        1.6  #  endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 348 kumpf        1.3  
 349 kumpf        1.2              // Create "to-agent" pipe:
 350                   
 351                               if (pipe(to) != 0)
 352 thilo.boehm  1.16             {
 353                                   PEG_METHOD_EXIT();
 354 kumpf        1.2                  return -1;
 355 thilo.boehm  1.16             }
 356                                   
 357 kumpf        1.2  
 358                               // Create "from-agent" pipe:
 359                   
 360                               if (pipe(from) != 0)
 361 thilo.boehm  1.16             {
 362                                   PEG_METHOD_EXIT();
 363 kumpf        1.2                  return -1;
 364 thilo.boehm  1.16             }
 365                   
 366                               // Start provider agent:
 367                   
 368                   #  if defined(PEGASUS_OS_ZOS)
 369                               // zOS is using __spawn2() to start provider agent
 370                               sprintf(arg1, "%d", to[0]);
 371                               sprintf(arg2, "%d", from[1]);
 372                   
 373                               CString program_name = path.getCString();
 374                   
 375                               c_argv[0] = program_name;
 376                               c_argv[1] = arg1;
 377                               c_argv[2] = arg2;
 378                               c_argv[3] = module; 
 379                               c_argv[4] = NULL;
 380                   
 381                               // reset the inherit structure
 382                               memset(&inherit,0,sizeof(inherit));
 383                   
 384                               // The provider agent should get a defined JobName.
 385 thilo.boehm  1.16             inherit.flags=SPAWN_SETJOBNAME;
 386                               memcpy( inherit.jobname,"CFZOOPA ",
 387                                       sizeof(inherit.jobname));
 388                               
 389                               CString program = path.getCString();
 390                   
 391                               PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 392                                          "Starting provider agent: %s %s %s %s %s",
 393                                          program,program_name,arg1,arg2,module));
 394 kumpf        1.2  
 395 thilo.boehm  1.16             pid = __spawn2(program,0,NULL,&inherit,
 396                                              c_argv,(const char **)environ);
 397 kumpf        1.2  
 398 thilo.boehm  1.16             if (pid < 0)
 399                               {
 400                                   PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 401                                       "Spawn of provider agent fails:%s "
 402                                           "( errno %d , reason code %08X )", 
 403                                       strerror(errno) ,errno,__errno2()));
 404                                   PEG_METHOD_EXIT();
 405                                   return -1;
 406                               }
 407                   
 408                   #  elif defined(PEGASUS_OS_VMS)
 409 kumpf        1.2              pid = (int)vfork();
 410 thilo.boehm  1.16 #  elif defined(PEGASUS_OS_PASE)
 411 ouyang.jian  1.11             pid = (int)fork400("QUMEPRVAGT",0);
 412 kumpf        1.6  #  else
 413 kumpf        1.2              pid = (int)fork();
 414 kumpf        1.6  #  endif
 415 kumpf        1.2  
 416 thilo.boehm  1.16 #  if !defined(PEGASUS_OS_ZOS)
 417                   
 418 kumpf        1.2              if (pid < 0)
 419 thilo.boehm  1.16             {
 420                                   PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 421                                        "Fork for provider agent fails: errno = %d",errno)); 
 422                                   PEG_METHOD_EXIT();
 423 kumpf        1.2                  return -1;
 424 thilo.boehm  1.16             }
 425                                   
 426 kumpf        1.2              // If child proceses.
 427                               if (pid == 0)
 428                               {
 429 thilo.boehm  1.16 #   if !defined(PEGASUS_OS_VMS)
 430 kumpf        1.2                  // Close unused pipe descriptors:
 431                   
 432                                   close(to[1]);
 433                                   close(from[0]);
 434                   
 435                   
 436                                   // Close unused descriptors. Leave stdin, stdout, stderr,
 437                                   // and the child's pipe descriptors open.
 438                   
 439                                   struct rlimit rlim;
 440                   
 441                                   if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
 442                                   {
 443                                       for (int i = 3; i < int(rlim.rlim_cur); i++)
 444                                       {
 445                                           if (i != to[0] && i != from[1])
 446                                               close(i);
 447                                       }
 448                                   }
 449                   
 450 thilo.boehm  1.16 #   endif /* !defined(PEGASUS_OS_VMS) */
 451 kumpf        1.3  
 452 thilo.boehm  1.16 #   if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
 453 kumpf        1.2  
 454                                   // Set uid and gid for the new provider agent process.
 455                   
 456 kumpf        1.3                  if (newUid != (PEGASUS_UID_T)-1 && newGid != (PEGASUS_GID_T)-1)
 457 kumpf        1.2                  {
 458 kumpf        1.3                      if (!System::changeUserContext_SingleThreaded(
 459                                                userName.getCString(), newUid, newGid))
 460 kumpf        1.2                      {
 461                                           return -1;
 462                                       }
 463                                   }
 464                   
 465 thilo.boehm  1.16 #   endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 466 kumpf        1.2  
 467                                   // Exec the cimprovagt program.
 468                   
 469                                   char arg1[32];
 470                                   char arg2[32];
 471                                   sprintf(arg1, "%d", to[0]);
 472                                   sprintf(arg2, "%d", from[1]);
 473                   
 474                                   {
 475                                       CString cstr = path.getCString();
 476                                       if (execl(cstr, cstr, arg1, arg2, module, (char*)0) == -1)
 477                                       {
 478 thilo.boehm  1.16                         PEG_TRACE((TRC_SERVER, Tracer::LEVEL2,
 479 kumpf        1.2                              "execl() failed.  errno = %d.", errno));
 480                                           _exit(1);
 481                                       }
 482                                   }
 483                               }
 484 thilo.boehm  1.16 #  else  /* PEGASUS_OS_ZOS */
 485                               if (pid > 0)
 486                               {
 487                                   PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
 488                                        "Provider agent started suggessfully: Pid(%d).",pid));
 489                                   break;
 490                               }
 491                   #endif /* PEGASUS_OS_ZOS */
 492                   
 493 kumpf        1.2          }
 494                           while (0);
 495                   
 496                           // Close unused pipe descriptors.
 497                   
 498                           close(to[0]);
 499                           close(from[1]);
 500                   
 501                           // Set output parameters.
 502                   
 503                           int readFd = from[0];
 504                           int writeFd = to[1];
 505                   
 506                           // Create to and from AnonymousPipe instances to correspond to the pipe
 507                           // descriptors created above.
 508                   
 509                           char readFdStr[32];
 510                           char writeFdStr[32];
 511                           sprintf(readFdStr, "%d", readFd);
 512                           sprintf(writeFdStr, "%d", writeFd);
 513                   
 514 kumpf        1.2          readPipe = new AnonymousPipe(readFdStr, 0);
 515                           writePipe = new AnonymousPipe(0, writeFdStr);
 516                   
 517 thilo.boehm  1.16         PEG_METHOD_EXIT();
 518 kumpf        1.2          return 0;
 519                   
 520 kumpf        1.6  # endif /* POSIX CASE */
 521                   
 522                   #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
 523                   
 524                           // Out-of-Process providers are never started by the cimserver process
 525                           // when Privilege Separation is enabled.
 526                           return -1;
 527                   
 528                   #endif
 529 kumpf        1.2      }
 530                   
 531                       virtual int daemonizeExecutor()
 532                       {
 533                           return -1;
 534                       }
 535                   
 536                       virtual int reapProviderAgent(
 537                           int pid)
 538                       {
 539 kumpf        1.6  #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 540                   
 541 kumpf        1.2          int status = 0;
 542                   
 543 kumpf        1.6  # if defined(PEGASUS_HAS_SIGNALS)
 544 kumpf        1.2          while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
 545                               ;
 546 kumpf        1.6  # endif
 547 kumpf        1.2  
 548                           return status;
 549 kumpf        1.6  
 550                   #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
 551                   
 552                           // Out-of-Process providers are never started by the cimserver process
 553                           // when Privilege Separation is enabled.
 554                           return -1;
 555                   
 556                   #endif
 557 kumpf        1.2      }
 558                   
 559                       virtual int authenticatePassword(
 560                           const char* username,
 561                           const char* password)
 562                       {
 563                   #if defined(PEGASUS_PAM_AUTHENTICATION)
 564                           return PAMAuthenticate(username, password);
 565                   #else
 566                           // ATTN: not handled so don't call in this case.
 567                           return -1;
 568                   #endif
 569                       }
 570                   
 571                       virtual int validateUser(
 572                           const char* username)
 573                       {
 574 kumpf        1.12 #if defined(PEGASUS_PAM_AUTHENTICATION)
 575 kumpf        1.2          return PAMValidateUser(username);
 576 kumpf        1.12 #else
 577 kumpf        1.2          // ATTN: not handled so don't call in this case.
 578                           return -1;
 579 kumpf        1.12 #endif
 580 kumpf        1.2      }
 581                   
 582                       virtual int challengeLocal(
 583                           const char* username,
 584                           char challengeFilePath[EXECUTOR_BUFFER_SIZE])
 585                       {
 586                           // ATTN: not handled so don't call in this case.
 587                           return -1;
 588                       }
 589                   
 590                       virtual int authenticateLocal(
 591                           const char* challengeFilePath,
 592                           const char* response)
 593                       {
 594                           // ATTN: not handled so don't call in this case.
 595                           return -1;
 596                       }
 597                   
 598 kumpf        1.8      virtual int updateLogLevel(
 599                           const char* logLevel)
 600                       {
 601                           // If Privilege Separation is not enabled, we don't need to update
 602                           // the log level in the Executor.
 603                           return 0;
 604                       }
 605                   
 606 kumpf        1.2  private:
 607                   
 608                       Mutex _mutex;
 609                   };
 610                   
 611                   ////////////////////////////////////////////////////////////////////////////////
 612                   //
 613                   //
 614                   // class ExecutorSocketImpl : public ExecutorImpl
 615                   //
 616                   //
 617                   ////////////////////////////////////////////////////////////////////////////////
 618                   
 619                   #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 620                   
 621                   class ExecutorSocketImpl : public ExecutorImpl
 622                   {
 623                   public:
 624                   
 625                       ExecutorSocketImpl(int sock) : _sock(sock)
 626                       {
 627 kumpf        1.2      }
 628                   
 629                       virtual ~ExecutorSocketImpl()
 630                       {
 631                       }
 632                   
 633                       virtual int detectExecutor()
 634                       {
 635                           return 0;
 636                       }
 637                   
 638                       virtual int ping()
 639                       {
 640                           AutoMutex autoMutex(_mutex);
 641                   
 642 kumpf        1.9          // Send request header:
 643 kumpf        1.2  
 644                           ExecutorRequestHeader header;
 645                           header.code = EXECUTOR_PING_MESSAGE;
 646                   
 647 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 648 kumpf        1.2              return -1;
 649                   
 650                           ExecutorPingResponse response;
 651                   
 652 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 653 kumpf        1.2              return -1;
 654                   
 655                           if (response.magic == EXECUTOR_PING_MAGIC)
 656                               return 0;
 657                   
 658                           return -1;
 659                       }
 660                   
 661                       virtual FILE* openFile(
 662                           const char* path,
 663                           int mode)
 664                       {
 665                           AutoMutex autoMutex(_mutex);
 666                   
 667                           if (mode != 'r' && mode != 'w' && mode != 'a')
 668                               return NULL;
 669                   
 670 kumpf        1.9          // Send request header:
 671 kumpf        1.2  
 672                           ExecutorRequestHeader header;
 673                           header.code = EXECUTOR_OPEN_FILE_MESSAGE;
 674                   
 675 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 676 kumpf        1.2              return NULL;
 677                   
 678 kumpf        1.9          // Send request body.
 679 kumpf        1.2  
 680                           ExecutorOpenFileRequest request;
 681                           memset(&request, 0, sizeof(request));
 682                           Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 683                           request.mode = mode;
 684                   
 685 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 686 kumpf        1.2              return NULL;
 687                   
 688                           // Receive the response
 689                   
 690                           ExecutorOpenFileResponse response;
 691                   
 692 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 693 kumpf        1.2              return NULL;
 694                   
 695                           // Receive descriptor (if response successful).
 696                   
 697                           if (response.status == 0)
 698                           {
 699                               int fds[1];
 700                   
 701                               if (RecvDescriptorArray(_sock, fds, 1) != 0)
 702                                   return NULL;
 703                   
 704                               if (fds[0] == -1)
 705                                   return NULL;
 706                               else
 707                               {
 708                                   if (mode == 'r')
 709                                       return fdopen(fds[0], "rb");
 710                                   else
 711                                       return fdopen(fds[0], "wb");
 712                               }
 713                           }
 714 kumpf        1.2  
 715                           return NULL;
 716                       }
 717                   
 718                       virtual int renameFile(
 719                           const char* oldPath,
 720                           const char* newPath)
 721                       {
 722                           AutoMutex autoMutex(_mutex);
 723                   
 724 kumpf        1.9          // Send request header:
 725 kumpf        1.2  
 726                           ExecutorRequestHeader header;
 727                           header.code = EXECUTOR_RENAME_FILE_MESSAGE;
 728                   
 729 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 730 kumpf        1.2              return -1;
 731                   
 732 kumpf        1.9          // Send request body.
 733 kumpf        1.2  
 734                           ExecutorRenameFileRequest request;
 735                           memset(&request, 0, sizeof(request));
 736                           Strlcpy(request.oldPath, oldPath, EXECUTOR_BUFFER_SIZE);
 737                           Strlcpy(request.newPath, newPath, EXECUTOR_BUFFER_SIZE);
 738                   
 739 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 740 kumpf        1.2              return -1;
 741                   
 742                           // Receive the response
 743                   
 744                           ExecutorRenameFileResponse response;
 745                   
 746 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 747 kumpf        1.2              return -1;
 748                   
 749                           return response.status;
 750                       }
 751                   
 752                       virtual int removeFile(
 753                           const char* path)
 754                       {
 755                           AutoMutex autoMutex(_mutex);
 756                   
 757 kumpf        1.9          // Send request header:
 758 kumpf        1.2  
 759                           ExecutorRequestHeader header;
 760                           header.code = EXECUTOR_REMOVE_FILE_MESSAGE;
 761                   
 762 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 763 kumpf        1.2              return -1;
 764                   
 765 kumpf        1.9          // Send request body.
 766 kumpf        1.2  
 767                           ExecutorRemoveFileRequest request;
 768                           memset(&request, 0, sizeof(request));
 769                           Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 770                   
 771 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 772 kumpf        1.2              return -1;
 773                   
 774                           // Receive the response
 775                   
 776                           ExecutorRemoveFileResponse response;
 777                   
 778 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 779 kumpf        1.2              return -1;
 780                   
 781                           return response.status;
 782                       }
 783                   
 784                       virtual int startProviderAgent(
 785                           const char* module,
 786                           const String& pegasusHome,
 787                           const String& userName,
 788                           int& pid,
 789                           AnonymousPipe*& readPipe,
 790                           AnonymousPipe*& writePipe)
 791                       {
 792                           AutoMutex autoMutex(_mutex);
 793                   
 794                           readPipe = 0;
 795                           writePipe = 0;
 796                   
 797                           // Reject strings longer than EXECUTOR_BUFFER_SIZE.
 798                   
 799 kumpf        1.3          size_t moduleNameLength = strlen(module);
 800                   
 801                           if (moduleNameLength >= EXECUTOR_BUFFER_SIZE)
 802                               return -1;
 803                   
 804                           CString userNameCString = userName.getCString();
 805                           size_t userNameLength = strlen(userNameCString);
 806 kumpf        1.2  
 807 kumpf        1.3          if (userNameLength >= EXECUTOR_BUFFER_SIZE)
 808 kumpf        1.2              return -1;
 809                   
 810 kumpf        1.9          // Send request header:
 811 kumpf        1.2  
 812                           ExecutorRequestHeader header;
 813                           header.code = EXECUTOR_START_PROVIDER_AGENT_MESSAGE;
 814                   
 815 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 816 kumpf        1.2              return -1;
 817                   
 818 kumpf        1.9          // Send request body.
 819 kumpf        1.2  
 820                           ExecutorStartProviderAgentRequest request;
 821                           memset(&request, 0, sizeof(request));
 822 kumpf        1.3          memcpy(request.module, module, moduleNameLength);
 823                           memcpy(request.userName, userNameCString, userNameLength);
 824 kumpf        1.2  
 825 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 826 kumpf        1.2              return -1;
 827                   
 828                           // Receive the response
 829                   
 830                           ExecutorStartProviderAgentResponse response;
 831                   
 832 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 833 kumpf        1.2              return -1;
 834                   
 835                           // Check response status and pid.
 836                   
 837                           if (response.status != 0)
 838                               return -1;
 839                   
 840                           // Get pid:
 841                   
 842                           pid = response.pid;
 843                   
 844                           // Receive descriptors.
 845                   
 846                           int descriptors[2];
 847                           int result = RecvDescriptorArray(_sock, descriptors, 2);
 848                   
 849                           if (result == 0)
 850                           {
 851                               int readFd = descriptors[0];
 852                               int writeFd = descriptors[1];
 853                   
 854 kumpf        1.2              // Create to and from AnonymousPipe instances to correspond to
 855                               // the pipe descriptors created above.
 856                   
 857                               char readFdStr[32];
 858                               char writeFdStr[32];
 859                               sprintf(readFdStr, "%d", readFd);
 860                               sprintf(writeFdStr, "%d", writeFd);
 861                   
 862                               readPipe = new AnonymousPipe(readFdStr, 0);
 863                               writePipe = new AnonymousPipe(0, writeFdStr);
 864                           }
 865                   
 866                           return result;
 867                       }
 868                   
 869                       virtual int daemonizeExecutor()
 870                       {
 871                           AutoMutex autoMutex(_mutex);
 872                   
 873 kumpf        1.9          // Send request header:
 874 kumpf        1.2  
 875                           ExecutorRequestHeader header;
 876                           header.code = EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE;
 877                   
 878 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 879 kumpf        1.2              return -1;
 880                   
 881                           // Receive the response
 882                   
 883                           ExecutorDaemonizeExecutorResponse response;
 884                   
 885 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 886 kumpf        1.2              return -1;
 887                   
 888                           return response.status;
 889                       }
 890                   
 891                       virtual int reapProviderAgent(
 892                           int pid)
 893                       {
 894 kumpf        1.10         // The Executor process automatically cleans up all its child
 895                           // processes, so it does not need to explicitly harvest the
 896                           // exit status of the cimprovagt processes it starts.
 897 kumpf        1.2  
 898 kumpf        1.10         return 0;
 899 kumpf        1.2      }
 900                   
 901                       virtual int authenticatePassword(
 902                           const char* username,
 903                           const char* password)
 904                       {
 905                           AutoMutex autoMutex(_mutex);
 906                   
 907 kumpf        1.9          // Send request header:
 908 kumpf        1.2  
 909                           ExecutorRequestHeader header;
 910                           header.code = EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE;
 911                   
 912 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 913 kumpf        1.2              return -1;
 914                   
 915 kumpf        1.9          // Send request body.
 916 kumpf        1.2  
 917                           ExecutorAuthenticatePasswordRequest request;
 918                           memset(&request, 0, sizeof(request));
 919                           Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 920                           Strlcpy(request.password, password, EXECUTOR_BUFFER_SIZE);
 921                   
 922 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 923 kumpf        1.2              return -1;
 924                   
 925                           // Receive the response
 926                   
 927                           ExecutorAuthenticatePasswordResponse response;
 928                   
 929 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 930 kumpf        1.2              return -1;
 931                   
 932                           return response.status;
 933                       }
 934                   
 935                       virtual int validateUser(
 936                           const char* username)
 937                       {
 938                           AutoMutex autoMutex(_mutex);
 939                   
 940 kumpf        1.9          // Send request header:
 941 kumpf        1.2  
 942                           ExecutorRequestHeader header;
 943                           header.code = EXECUTOR_VALIDATE_USER_MESSAGE;
 944                   
 945 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 946 kumpf        1.2              return -1;
 947                   
 948 kumpf        1.9          // Send request body.
 949 kumpf        1.2  
 950                           ExecutorValidateUserRequest request;
 951                           memset(&request, 0, sizeof(request));
 952                           Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 953                   
 954 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 955 kumpf        1.2              return -1;
 956                   
 957                           // Receive the response
 958                   
 959                           ExecutorValidateUserResponse response;
 960                   
 961 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 962 kumpf        1.2              return -1;
 963                   
 964                           return response.status;
 965                       }
 966                   
 967                       virtual int challengeLocal(
 968                           const char* username,
 969                           char challengeFilePath[EXECUTOR_BUFFER_SIZE])
 970                       {
 971                           AutoMutex autoMutex(_mutex);
 972                   
 973 kumpf        1.9          // Send request header:
 974 kumpf        1.2  
 975                           ExecutorRequestHeader header;
 976                           header.code = EXECUTOR_CHALLENGE_LOCAL_MESSAGE;
 977                   
 978 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 979 kumpf        1.2              return -1;
 980                   
 981 kumpf        1.9          // Send request body.
 982 kumpf        1.2  
 983                           ExecutorChallengeLocalRequest request;
 984                           memset(&request, 0, sizeof(request));
 985                           Strlcpy(request.user, username, EXECUTOR_BUFFER_SIZE);
 986                   
 987 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 988 kumpf        1.2              return -1;
 989                   
 990                           // Receive the response
 991                   
 992                           ExecutorChallengeLocalResponse response;
 993                   
 994 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 995 kumpf        1.2              return -1;
 996                   
 997                           Strlcpy(challengeFilePath, response.challenge, EXECUTOR_BUFFER_SIZE);
 998                   
 999                           return response.status;
1000                       }
1001                   
1002                       virtual int authenticateLocal(
1003                           const char* challengeFilePath,
1004                           const char* response)
1005                       {
1006                           AutoMutex autoMutex(_mutex);
1007                   
1008 kumpf        1.9          // Send request header:
1009 kumpf        1.2  
1010                           ExecutorRequestHeader header;
1011                           header.code = EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE;
1012                   
1013 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1014 kumpf        1.2              return -1;
1015                   
1016 kumpf        1.9          // Send request body.
1017 kumpf        1.2  
1018                           ExecutorAuthenticateLocalRequest request;
1019                           memset(&request, 0, sizeof(request));
1020                           Strlcpy(request.challenge, challengeFilePath, EXECUTOR_BUFFER_SIZE);
1021                           Strlcpy(request.response, response, EXECUTOR_BUFFER_SIZE);
1022                   
1023 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1024 kumpf        1.2              return -1;
1025                   
1026                           // Receive the response
1027                   
1028                           ExecutorAuthenticateLocalResponse response_;
1029                   
1030 kumpf        1.9          if (RecvBlock(_sock, &response_, sizeof(response_)) !=
1031                                   sizeof(response_))
1032                           {
1033 kumpf        1.2              return -1;
1034 kumpf        1.9          }
1035 kumpf        1.2  
1036                           return response_.status;
1037                       }
1038                   
1039 kumpf        1.8      virtual int updateLogLevel(
1040                           const char* logLevel)
1041                       {
1042                           AutoMutex autoMutex(_mutex);
1043                   
1044 kumpf        1.9          // Send request header:
1045 kumpf        1.8  
1046                           ExecutorRequestHeader header;
1047                           header.code = EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE;
1048                   
1049 kumpf        1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1050 kumpf        1.8              return -1;
1051                   
1052 kumpf        1.9          // Send request body:
1053 kumpf        1.8  
1054                           ExecutorUpdateLogLevelRequest request;
1055                           memset(&request, 0, sizeof(request));
1056                           Strlcpy(request.logLevel, logLevel, EXECUTOR_BUFFER_SIZE);
1057                   
1058 kumpf        1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1059 kumpf        1.8              return -1;
1060                   
1061                           // Receive the response
1062                   
1063                           ExecutorUpdateLogLevelResponse response;
1064                   
1065 kumpf        1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
1066 kumpf        1.8              return -1;
1067                   
1068                           return response.status;
1069                       }
1070                   
1071 kumpf        1.2  private:
1072                   
1073                       int _sock;
1074                       Mutex _mutex;
1075                   };
1076                   
1077                   #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1078                   
1079                   ////////////////////////////////////////////////////////////////////////////////
1080                   //
1081                   //
1082                   // class Executor
1083                   //
1084                   //
1085                   ////////////////////////////////////////////////////////////////////////////////
1086                   
1087                   static int _executorSock = -1;
1088 kumpf        1.5  static AutoPtr<ExecutorImpl> _executorImpl;
1089 kumpf        1.7  static Once _executorImplOnce = PEGASUS_ONCE_INITIALIZER;
1090 kumpf        1.2  
1091 kumpf        1.7  static void _initExecutorImpl()
1092 kumpf        1.2  {
1093                   #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1094 kumpf        1.7      if (_executorSock == -1)
1095                           _executorImpl.reset(new ExecutorLoopbackImpl());
1096                       else
1097                           _executorImpl.reset(new ExecutorSocketImpl(_executorSock));
1098 kumpf        1.2  #else
1099 kumpf        1.7      _executorImpl.reset(new ExecutorLoopbackImpl());
1100 kumpf        1.2  #endif
1101                   }
1102                   
1103                   void Executor::setSock(int sock)
1104                   {
1105                       _executorSock = sock;
1106                   }
1107                   
1108                   int Executor::detectExecutor()
1109                   {
1110 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1111                       return _executorImpl->detectExecutor();
1112 kumpf        1.2  }
1113                   
1114                   int Executor::ping()
1115                   {
1116 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1117                       return _executorImpl->ping();
1118 kumpf        1.2  }
1119                   
1120                   FILE* Executor::openFile(
1121                       const char* path,
1122                       int mode)
1123                   {
1124 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1125                       return _executorImpl->openFile(path, mode);
1126 kumpf        1.2  }
1127                   
1128                   int Executor::renameFile(
1129                       const char* oldPath,
1130                       const char* newPath)
1131                   {
1132 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1133                       return _executorImpl->renameFile(oldPath, newPath);
1134 kumpf        1.2  }
1135                   
1136                   int Executor::removeFile(
1137                       const char* path)
1138                   {
1139 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1140                       return _executorImpl->removeFile(path);
1141 kumpf        1.2  }
1142                   
1143                   int Executor::startProviderAgent(
1144                       const char* module,
1145                       const String& pegasusHome,
1146                       const String& userName,
1147                       int& pid,
1148                       AnonymousPipe*& readPipe,
1149                       AnonymousPipe*& writePipe)
1150                   {
1151 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1152                       return _executorImpl->startProviderAgent(
1153 kumpf        1.3          module, pegasusHome, userName, pid, readPipe, writePipe);
1154 kumpf        1.2  }
1155                   
1156                   int Executor::daemonizeExecutor()
1157                   {
1158 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1159                       return _executorImpl->daemonizeExecutor();
1160 kumpf        1.2  }
1161                   
1162                   int Executor::reapProviderAgent(
1163                       int pid)
1164                   {
1165 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1166                       return _executorImpl->reapProviderAgent(pid);
1167 kumpf        1.2  }
1168                   
1169                   int Executor::authenticatePassword(
1170                       const char* username,
1171                       const char* password)
1172                   {
1173 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1174                       return _executorImpl->authenticatePassword(username, password);
1175 kumpf        1.2  }
1176                   
1177                   int Executor::validateUser(
1178                       const char* username)
1179                   {
1180 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1181                       return _executorImpl->validateUser(username);
1182 kumpf        1.2  }
1183                   
1184                   int Executor::challengeLocal(
1185                       const char* user,
1186                       char challengeFilePath[EXECUTOR_BUFFER_SIZE])
1187                   {
1188 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1189                       return _executorImpl->challengeLocal(user, challengeFilePath);
1190 kumpf        1.2  }
1191                   
1192                   int Executor::authenticateLocal(
1193                       const char* challengeFilePath,
1194                       const char* response)
1195                   {
1196 kumpf        1.7      once(&_executorImplOnce, _initExecutorImpl);
1197                       return _executorImpl->authenticateLocal(challengeFilePath, response);
1198 kumpf        1.2  }
1199                   
1200 kumpf        1.8  int Executor::updateLogLevel(
1201                       const char* logLevel)
1202                   {
1203                       once(&_executorImplOnce, _initExecutorImpl);
1204                       return _executorImpl->updateLogLevel(logLevel);
1205                   }
1206                   
1207 kumpf        1.2  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2