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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2