(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                  
  62                  #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
  63 dl.meetei   1.28 #include <Executor/Strlcpy.h>
  64 kumpf       1.2  # 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 karl        1.27 #  if defined(PEGASUS_HAS_SIGNALS) && \
 506                        !(defined(PEGASUS_DISABLE_PROV_USERCTXT) || defined(PEGASUS_OS_ZOS))
 507 kumpf       1.18         // 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                  
 514 thilo.boehm 1.16         PEG_METHOD_EXIT();
 515 kumpf       1.2          return 0;
 516                  
 517 kumpf       1.6  # endif /* POSIX CASE */
 518                  
 519                  #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
 520                  
 521                          // Out-of-Process providers are never started by the cimserver process
 522                          // when Privilege Separation is enabled.
 523                          return -1;
 524                  
 525                  #endif
 526 kumpf       1.2      }
 527                  
 528                      virtual int daemonizeExecutor()
 529                      {
 530                          return -1;
 531                      }
 532                  
 533 marek       1.26 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 534                      virtual int reapProviderAgent(int)
 535 kumpf       1.2      {
 536 marek       1.26         // Out-of-Process providers are never started by the cimserver process
 537                          // when Privilege Separation is enabled.
 538                          return -1;
 539                      }
 540                  #else  /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is NOT defined */
 541 karl        1.27 # if defined(PEGASUS_HAS_SIGNALS) && \
 542                       (defined(PEGASUS_DISABLE_PROV_USERCTXT) || defined(PEGASUS_OS_ZOS))
 543 marek       1.26     virtual int reapProviderAgent(int pid)
 544                      {
 545                          int status = 0;
 546 kumpf       1.18         // When provider user context is enabled, this is done in
 547                          // startProviderAgent().
 548 kumpf       1.2          while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
 549 marek       1.26         {
 550                          };
 551                          return status;
 552                      }
 553 karl        1.27 # else
 554 marek       1.26     virtual int reapProviderAgent(int)
 555                      {
 556                          return 0;
 557                      }
 558 kumpf       1.6  # endif
 559 marek       1.26 #endif
 560 kumpf       1.2  
 561                  
 562 marek       1.26 #if defined(PEGASUS_PAM_AUTHENTICATION)
 563 kumpf       1.2      virtual int authenticatePassword(
 564                          const char* username,
 565                          const char* password)
 566                      {
 567                          return PAMAuthenticate(username, password);
 568 marek       1.26     }
 569                      
 570                      virtual int validateUser(
 571                          const char* username)
 572                      {
 573                          return PAMValidateUser(username);
 574                      }
 575                  #else    
 576                      virtual int authenticatePassword(
 577                          const char*,
 578                          const char*)
 579                      {
 580 kumpf       1.2          // ATTN: not handled so don't call in this case.
 581                          return -1;
 582                      }
 583 marek       1.26     
 584 kumpf       1.2      virtual int validateUser(
 585 marek       1.26         const char*)
 586 kumpf       1.2      {
 587                          // ATTN: not handled so don't call in this case.
 588                          return -1;
 589 marek       1.26     }
 590 kumpf       1.12 #endif
 591 kumpf       1.2  
 592                      virtual int challengeLocal(
 593 marek       1.26         const char*,
 594                          char[EXECUTOR_BUFFER_SIZE])
 595 kumpf       1.2      {
 596                          // ATTN: not handled so don't call in this case.
 597                          return -1;
 598                      }
 599                  
 600                      virtual int authenticateLocal(
 601 marek       1.26         const char*,
 602                          const char*)
 603 kumpf       1.2      {
 604                          // ATTN: not handled so don't call in this case.
 605                          return -1;
 606                      }
 607                  
 608 kumpf       1.8      virtual int updateLogLevel(
 609 marek       1.26         const char*)
 610 kumpf       1.8      {
 611                          // If Privilege Separation is not enabled, we don't need to update
 612                          // the log level in the Executor.
 613                          return 0;
 614                      }
 615                  
 616 kumpf       1.2  private:
 617                  
 618                      Mutex _mutex;
 619                  };
 620                  
 621                  ////////////////////////////////////////////////////////////////////////////////
 622                  //
 623                  //
 624                  // class ExecutorSocketImpl : public ExecutorImpl
 625                  //
 626                  //
 627                  ////////////////////////////////////////////////////////////////////////////////
 628                  
 629                  #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
 630                  
 631                  class ExecutorSocketImpl : public ExecutorImpl
 632                  {
 633                  public:
 634                  
 635                      ExecutorSocketImpl(int sock) : _sock(sock)
 636                      {
 637 kumpf       1.2      }
 638                  
 639                      virtual ~ExecutorSocketImpl()
 640                      {
 641                      }
 642                  
 643                      virtual int detectExecutor()
 644                      {
 645                          return 0;
 646                      }
 647                  
 648                      virtual int ping()
 649                      {
 650                          AutoMutex autoMutex(_mutex);
 651                  
 652 kumpf       1.9          // Send request header:
 653 kumpf       1.2  
 654                          ExecutorRequestHeader header;
 655                          header.code = EXECUTOR_PING_MESSAGE;
 656                  
 657 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 658 kumpf       1.2              return -1;
 659                  
 660                          ExecutorPingResponse response;
 661                  
 662 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 663 kumpf       1.2              return -1;
 664                  
 665                          if (response.magic == EXECUTOR_PING_MAGIC)
 666                              return 0;
 667                  
 668                          return -1;
 669                      }
 670                  
 671                      virtual FILE* openFile(
 672                          const char* path,
 673                          int mode)
 674                      {
 675                          AutoMutex autoMutex(_mutex);
 676                  
 677                          if (mode != 'r' && mode != 'w' && mode != 'a')
 678                              return NULL;
 679                  
 680 kumpf       1.9          // Send request header:
 681 kumpf       1.2  
 682                          ExecutorRequestHeader header;
 683                          header.code = EXECUTOR_OPEN_FILE_MESSAGE;
 684                  
 685 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 686 kumpf       1.2              return NULL;
 687                  
 688 kumpf       1.9          // Send request body.
 689 kumpf       1.2  
 690                          ExecutorOpenFileRequest request;
 691                          memset(&request, 0, sizeof(request));
 692                          Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 693                          request.mode = mode;
 694                  
 695 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 696 kumpf       1.2              return NULL;
 697                  
 698                          // Receive the response
 699                  
 700                          ExecutorOpenFileResponse response;
 701                  
 702 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 703 kumpf       1.2              return NULL;
 704                  
 705                          // Receive descriptor (if response successful).
 706                  
 707                          if (response.status == 0)
 708                          {
 709                              int fds[1];
 710                  
 711                              if (RecvDescriptorArray(_sock, fds, 1) != 0)
 712                                  return NULL;
 713                  
 714                              if (fds[0] == -1)
 715                                  return NULL;
 716                              else
 717                              {
 718                                  if (mode == 'r')
 719                                      return fdopen(fds[0], "rb");
 720                                  else
 721                                      return fdopen(fds[0], "wb");
 722                              }
 723                          }
 724 kumpf       1.2  
 725                          return NULL;
 726                      }
 727                  
 728                      virtual int renameFile(
 729                          const char* oldPath,
 730                          const char* newPath)
 731                      {
 732                          AutoMutex autoMutex(_mutex);
 733                  
 734 kumpf       1.9          // Send request header:
 735 kumpf       1.2  
 736                          ExecutorRequestHeader header;
 737                          header.code = EXECUTOR_RENAME_FILE_MESSAGE;
 738                  
 739 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 740 kumpf       1.2              return -1;
 741                  
 742 kumpf       1.9          // Send request body.
 743 kumpf       1.2  
 744                          ExecutorRenameFileRequest request;
 745                          memset(&request, 0, sizeof(request));
 746                          Strlcpy(request.oldPath, oldPath, EXECUTOR_BUFFER_SIZE);
 747                          Strlcpy(request.newPath, newPath, EXECUTOR_BUFFER_SIZE);
 748                  
 749 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 750 kumpf       1.2              return -1;
 751                  
 752                          // Receive the response
 753                  
 754                          ExecutorRenameFileResponse response;
 755                  
 756 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 757 kumpf       1.2              return -1;
 758                  
 759                          return response.status;
 760                      }
 761                  
 762                      virtual int removeFile(
 763                          const char* path)
 764                      {
 765                          AutoMutex autoMutex(_mutex);
 766                  
 767 kumpf       1.9          // Send request header:
 768 kumpf       1.2  
 769                          ExecutorRequestHeader header;
 770                          header.code = EXECUTOR_REMOVE_FILE_MESSAGE;
 771                  
 772 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 773 kumpf       1.2              return -1;
 774                  
 775 kumpf       1.9          // Send request body.
 776 kumpf       1.2  
 777                          ExecutorRemoveFileRequest request;
 778                          memset(&request, 0, sizeof(request));
 779                          Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
 780                  
 781 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 782 kumpf       1.2              return -1;
 783                  
 784                          // Receive the response
 785                  
 786                          ExecutorRemoveFileResponse response;
 787                  
 788 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 789 kumpf       1.2              return -1;
 790                  
 791                          return response.status;
 792                      }
 793                  
 794                      virtual int startProviderAgent(
 795 s.kodali    1.25         unsigned short bitness,
 796 kumpf       1.2          const char* module,
 797                          const String& pegasusHome,
 798                          const String& userName,
 799                          int& pid,
 800                          AnonymousPipe*& readPipe,
 801                          AnonymousPipe*& writePipe)
 802                      {
 803                          AutoMutex autoMutex(_mutex);
 804                  
 805                          readPipe = 0;
 806                          writePipe = 0;
 807                  
 808                          // Reject strings longer than EXECUTOR_BUFFER_SIZE.
 809                  
 810 kumpf       1.3          size_t moduleNameLength = strlen(module);
 811                  
 812                          if (moduleNameLength >= EXECUTOR_BUFFER_SIZE)
 813                              return -1;
 814                  
 815                          CString userNameCString = userName.getCString();
 816                          size_t userNameLength = strlen(userNameCString);
 817 kumpf       1.2  
 818 kumpf       1.3          if (userNameLength >= EXECUTOR_BUFFER_SIZE)
 819 kumpf       1.2              return -1;
 820                  
 821 kumpf       1.9          // Send request header:
 822 kumpf       1.2  
 823                          ExecutorRequestHeader header;
 824                          header.code = EXECUTOR_START_PROVIDER_AGENT_MESSAGE;
 825                  
 826 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 827 kumpf       1.2              return -1;
 828                  
 829 kumpf       1.9          // Send request body.
 830 kumpf       1.2  
 831                          ExecutorStartProviderAgentRequest request;
 832                          memset(&request, 0, sizeof(request));
 833 kumpf       1.3          memcpy(request.module, module, moduleNameLength);
 834                          memcpy(request.userName, userNameCString, userNameLength);
 835 s.kodali    1.25         request.moduleBitness = bitness;
 836 kumpf       1.2  
 837 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 838 kumpf       1.2              return -1;
 839                  
 840                          // Receive the response
 841                  
 842                          ExecutorStartProviderAgentResponse response;
 843                  
 844 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 845 kumpf       1.2              return -1;
 846                  
 847                          // Check response status and pid.
 848                  
 849                          if (response.status != 0)
 850                              return -1;
 851                  
 852                          // Get pid:
 853                  
 854                          pid = response.pid;
 855                  
 856                          // Receive descriptors.
 857                  
 858                          int descriptors[2];
 859                          int result = RecvDescriptorArray(_sock, descriptors, 2);
 860                  
 861                          if (result == 0)
 862                          {
 863                              int readFd = descriptors[0];
 864                              int writeFd = descriptors[1];
 865                  
 866 kumpf       1.2              // Create to and from AnonymousPipe instances to correspond to
 867                              // the pipe descriptors created above.
 868                  
 869                              char readFdStr[32];
 870                              char writeFdStr[32];
 871                              sprintf(readFdStr, "%d", readFd);
 872                              sprintf(writeFdStr, "%d", writeFd);
 873                  
 874                              readPipe = new AnonymousPipe(readFdStr, 0);
 875                              writePipe = new AnonymousPipe(0, writeFdStr);
 876                          }
 877                  
 878                          return result;
 879                      }
 880                  
 881                      virtual int daemonizeExecutor()
 882                      {
 883                          AutoMutex autoMutex(_mutex);
 884                  
 885 kumpf       1.9          // Send request header:
 886 kumpf       1.2  
 887                          ExecutorRequestHeader header;
 888                          header.code = EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE;
 889                  
 890 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 891 kumpf       1.2              return -1;
 892                  
 893                          // Receive the response
 894                  
 895                          ExecutorDaemonizeExecutorResponse response;
 896                  
 897 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 898 kumpf       1.2              return -1;
 899                  
 900                          return response.status;
 901                      }
 902                  
 903                      virtual int reapProviderAgent(
 904                          int pid)
 905                      {
 906 kumpf       1.10         // The Executor process automatically cleans up all its child
 907                          // processes, so it does not need to explicitly harvest the
 908                          // exit status of the cimprovagt processes it starts.
 909 kumpf       1.2  
 910 kumpf       1.10         return 0;
 911 kumpf       1.2      }
 912                  
 913                      virtual int authenticatePassword(
 914                          const char* username,
 915                          const char* password)
 916                      {
 917                          AutoMutex autoMutex(_mutex);
 918                  
 919 kumpf       1.9          // Send request header:
 920 kumpf       1.2  
 921                          ExecutorRequestHeader header;
 922                          header.code = EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE;
 923                  
 924 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 925 kumpf       1.2              return -1;
 926                  
 927 kumpf       1.9          // Send request body.
 928 kumpf       1.2  
 929                          ExecutorAuthenticatePasswordRequest request;
 930                          memset(&request, 0, sizeof(request));
 931                          Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 932                          Strlcpy(request.password, password, EXECUTOR_BUFFER_SIZE);
 933                  
 934 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 935 kumpf       1.2              return -1;
 936                  
 937                          // Receive the response
 938                  
 939                          ExecutorAuthenticatePasswordResponse response;
 940                  
 941 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 942 kumpf       1.2              return -1;
 943                  
 944                          return response.status;
 945                      }
 946                  
 947                      virtual int validateUser(
 948                          const char* username)
 949                      {
 950                          AutoMutex autoMutex(_mutex);
 951                  
 952 kumpf       1.9          // Send request header:
 953 kumpf       1.2  
 954                          ExecutorRequestHeader header;
 955                          header.code = EXECUTOR_VALIDATE_USER_MESSAGE;
 956                  
 957 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 958 kumpf       1.2              return -1;
 959                  
 960 kumpf       1.9          // Send request body.
 961 kumpf       1.2  
 962                          ExecutorValidateUserRequest request;
 963                          memset(&request, 0, sizeof(request));
 964                          Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
 965                  
 966 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
 967 kumpf       1.2              return -1;
 968                  
 969                          // Receive the response
 970                  
 971                          ExecutorValidateUserResponse response;
 972                  
 973 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
 974 kumpf       1.2              return -1;
 975                  
 976                          return response.status;
 977                      }
 978                  
 979                      virtual int challengeLocal(
 980                          const char* username,
 981                          char challengeFilePath[EXECUTOR_BUFFER_SIZE])
 982                      {
 983                          AutoMutex autoMutex(_mutex);
 984                  
 985 kumpf       1.9          // Send request header:
 986 kumpf       1.2  
 987                          ExecutorRequestHeader header;
 988                          header.code = EXECUTOR_CHALLENGE_LOCAL_MESSAGE;
 989                  
 990 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
 991 kumpf       1.2              return -1;
 992                  
 993 kumpf       1.9          // Send request body.
 994 kumpf       1.2  
 995                          ExecutorChallengeLocalRequest request;
 996                          memset(&request, 0, sizeof(request));
 997                          Strlcpy(request.user, username, EXECUTOR_BUFFER_SIZE);
 998                  
 999 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1000 kumpf       1.2              return -1;
1001                  
1002                          // Receive the response
1003                  
1004                          ExecutorChallengeLocalResponse response;
1005                  
1006 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
1007 kumpf       1.2              return -1;
1008                  
1009                          Strlcpy(challengeFilePath, response.challenge, EXECUTOR_BUFFER_SIZE);
1010                  
1011                          return response.status;
1012                      }
1013                  
1014                      virtual int authenticateLocal(
1015                          const char* challengeFilePath,
1016                          const char* response)
1017                      {
1018                          AutoMutex autoMutex(_mutex);
1019                  
1020 kumpf       1.9          // Send request header:
1021 kumpf       1.2  
1022                          ExecutorRequestHeader header;
1023                          header.code = EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE;
1024                  
1025 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1026 kumpf       1.2              return -1;
1027                  
1028 kumpf       1.9          // Send request body.
1029 kumpf       1.2  
1030                          ExecutorAuthenticateLocalRequest request;
1031                          memset(&request, 0, sizeof(request));
1032                          Strlcpy(request.challenge, challengeFilePath, EXECUTOR_BUFFER_SIZE);
1033                          Strlcpy(request.response, response, EXECUTOR_BUFFER_SIZE);
1034                  
1035 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1036 kumpf       1.2              return -1;
1037                  
1038                          // Receive the response
1039                  
1040                          ExecutorAuthenticateLocalResponse response_;
1041                  
1042 kumpf       1.9          if (RecvBlock(_sock, &response_, sizeof(response_)) !=
1043                                  sizeof(response_))
1044                          {
1045 kumpf       1.2              return -1;
1046 kumpf       1.9          }
1047 kumpf       1.2  
1048                          return response_.status;
1049                      }
1050                  
1051 kumpf       1.8      virtual int updateLogLevel(
1052                          const char* logLevel)
1053                      {
1054                          AutoMutex autoMutex(_mutex);
1055                  
1056 kumpf       1.9          // Send request header:
1057 kumpf       1.8  
1058                          ExecutorRequestHeader header;
1059                          header.code = EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE;
1060                  
1061 kumpf       1.9          if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
1062 kumpf       1.8              return -1;
1063                  
1064 kumpf       1.9          // Send request body:
1065 kumpf       1.8  
1066                          ExecutorUpdateLogLevelRequest request;
1067                          memset(&request, 0, sizeof(request));
1068                          Strlcpy(request.logLevel, logLevel, EXECUTOR_BUFFER_SIZE);
1069                  
1070 kumpf       1.9          if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
1071 kumpf       1.8              return -1;
1072                  
1073                          // Receive the response
1074                  
1075                          ExecutorUpdateLogLevelResponse response;
1076                  
1077 kumpf       1.9          if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
1078 kumpf       1.8              return -1;
1079                  
1080                          return response.status;
1081                      }
1082                  
1083 kumpf       1.2  private:
1084                  
1085                      int _sock;
1086                      Mutex _mutex;
1087                  };
1088                  
1089                  #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1090                  
1091                  ////////////////////////////////////////////////////////////////////////////////
1092                  //
1093                  //
1094                  // class Executor
1095                  //
1096                  //
1097                  ////////////////////////////////////////////////////////////////////////////////
1098                  
1099                  static int _executorSock = -1;
1100 kumpf       1.5  static AutoPtr<ExecutorImpl> _executorImpl;
1101 kumpf       1.7  static Once _executorImplOnce = PEGASUS_ONCE_INITIALIZER;
1102 kumpf       1.2  
1103 kumpf       1.7  static void _initExecutorImpl()
1104 kumpf       1.2  {
1105                  #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1106 kumpf       1.7      if (_executorSock == -1)
1107                          _executorImpl.reset(new ExecutorLoopbackImpl());
1108                      else
1109                          _executorImpl.reset(new ExecutorSocketImpl(_executorSock));
1110 kumpf       1.2  #else
1111 kumpf       1.7      _executorImpl.reset(new ExecutorLoopbackImpl());
1112 kumpf       1.2  #endif
1113                  }
1114                  
1115                  void Executor::setSock(int sock)
1116                  {
1117                      _executorSock = sock;
1118                  }
1119                  
1120                  int Executor::detectExecutor()
1121                  {
1122 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1123                      return _executorImpl->detectExecutor();
1124 kumpf       1.2  }
1125                  
1126                  int Executor::ping()
1127                  {
1128 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1129                      return _executorImpl->ping();
1130 kumpf       1.2  }
1131                  
1132                  FILE* Executor::openFile(
1133                      const char* path,
1134                      int mode)
1135                  {
1136 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1137                      return _executorImpl->openFile(path, mode);
1138 kumpf       1.2  }
1139                  
1140                  int Executor::renameFile(
1141                      const char* oldPath,
1142                      const char* newPath)
1143                  {
1144 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1145                      return _executorImpl->renameFile(oldPath, newPath);
1146 kumpf       1.2  }
1147                  
1148                  int Executor::removeFile(
1149                      const char* path)
1150                  {
1151 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1152                      return _executorImpl->removeFile(path);
1153 kumpf       1.2  }
1154                  
1155                  int Executor::startProviderAgent(
1156 s.kodali    1.25     unsigned short bitness,
1157 kumpf       1.2      const char* module,
1158                      const String& pegasusHome,
1159                      const String& userName,
1160                      int& pid,
1161                      AnonymousPipe*& readPipe,
1162                      AnonymousPipe*& writePipe)
1163                  {
1164 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1165 s.kodali    1.25     return _executorImpl->startProviderAgent(bitness,
1166 kumpf       1.3          module, pegasusHome, userName, pid, readPipe, writePipe);
1167 kumpf       1.2  }
1168                  
1169                  int Executor::daemonizeExecutor()
1170                  {
1171 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1172                      return _executorImpl->daemonizeExecutor();
1173 kumpf       1.2  }
1174                  
1175                  int Executor::reapProviderAgent(
1176                      int pid)
1177                  {
1178 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1179                      return _executorImpl->reapProviderAgent(pid);
1180 kumpf       1.2  }
1181                  
1182                  int Executor::authenticatePassword(
1183                      const char* username,
1184                      const char* password)
1185                  {
1186 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1187                      return _executorImpl->authenticatePassword(username, password);
1188 kumpf       1.2  }
1189                  
1190                  int Executor::validateUser(
1191                      const char* username)
1192                  {
1193 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1194                      return _executorImpl->validateUser(username);
1195 kumpf       1.2  }
1196                  
1197                  int Executor::challengeLocal(
1198                      const char* user,
1199                      char challengeFilePath[EXECUTOR_BUFFER_SIZE])
1200                  {
1201 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1202                      return _executorImpl->challengeLocal(user, challengeFilePath);
1203 kumpf       1.2  }
1204                  
1205                  int Executor::authenticateLocal(
1206                      const char* challengeFilePath,
1207                      const char* response)
1208                  {
1209 kumpf       1.7      once(&_executorImplOnce, _initExecutorImpl);
1210                      return _executorImpl->authenticateLocal(challengeFilePath, response);
1211 kumpf       1.2  }
1212                  
1213 kumpf       1.8  int Executor::updateLogLevel(
1214                      const char* logLevel)
1215                  {
1216                      once(&_executorImplOnce, _initExecutorImpl);
1217                      return _executorImpl->updateLogLevel(logLevel);
1218                  }
1219                  
1220 kumpf       1.2  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2