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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2