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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2