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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2