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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2