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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2