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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2