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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2