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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2