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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2