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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2