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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2