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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2