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

   1 kumpf 1.2 /*
   2           //%2006////////////////////////////////////////////////////////////////////////
   3           //
   4           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   5           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   6           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   7           // IBM Corp.; EMC Corporation, The Open Group.
   8           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   9           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  10           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  11           // EMC Corporation; VERITAS Software Corporation; The Open Group.
  12           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  13           // EMC Corporation; Symantec Corporation; The Open Group.
  14           //
  15           // Permission is hereby granted, free of charge, to any person obtaining a copy
  16           // of this software and associated documentation files (the "Software"), to
  17           // deal in the Software without restriction, including without limitation the
  18           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  19           // sell copies of the Software, and to permit persons to whom the Software is
  20           // furnished to do so, subject to the following conditions:
  21           // 
  22 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  23           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  24           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  25           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  26           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  27           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30           //
  31           //%/////////////////////////////////////////////////////////////////////////////
  32           */
  33           #include <sys/time.h>
  34           #include <sys/resource.h>
  35           #include <sys/types.h>
  36           #include <sys/stat.h>
  37           #include <errno.h>
  38           #include <string.h>
  39           #include <fcntl.h>
  40           #include <sys/wait.h>
  41           #include <unistd.h>
  42           #include <signal.h>
  43 kumpf 1.3 #include <grp.h>
  44 kumpf 1.2 #include "Parent.h"
  45           #include "Log.h"
  46           #include "Messages.h"
  47           #include "Socket.h"
  48           #include "Fatal.h"
  49           #include "Globals.h"
  50           #include "Path.h"
  51           #include "User.h"
  52           #include "Exit.h"
  53           #include "Strlcpy.h"
  54           #include "LocalAuth.h"
  55           #include "Strlcat.h"
  56           #include "PasswordFile.h"
  57           #include "Policy.h"
  58           #include "Macro.h"
  59           
  60           #if defined(PEGASUS_PAM_AUTHENTICATION)
  61           # include "PAMAuth.h"
  62           #endif
  63           
  64           /*
  65 kumpf 1.2 **==============================================================================
  66           **
  67           ** _sigHandler()
  68           **
  69           **     Signal handler for SIGTERM.
  70           **
  71           **==============================================================================
  72           */
  73           
  74           static void _sigHandler(int signum)
  75           {
  76               globals.signalMask |= (1 << signum);
  77           }
  78           
  79           /*
  80           **==============================================================================
  81           **
  82 kumpf 1.4 ** ReadExecutorRequest()
  83           **
  84           **     Read a request of the specified size from the specified socket into the
  85           **     buffer provided.
  86           **
  87           **==============================================================================
  88           */
  89           
  90           static void ReadExecutorRequest(int sock, void* buffer, size_t size)
  91           {
  92               if (RecvNonBlock(sock, buffer, size) != (ssize_t)size)
  93               {
  94                   Fatal(FL, "Failed to read request");
  95               }
  96           }
  97           
  98           /*
  99           **==============================================================================
 100           **
 101           ** WriteExecutorResponse()
 102           **
 103 kumpf 1.4 **     Write a response of the specified size from the given buffer onto the
 104           **     specified socket.
 105           **
 106           **==============================================================================
 107           */
 108           
 109           static void WriteExecutorResponse(int sock, const void* buffer, size_t size)
 110           {
 111               if (SendNonBlock(sock, buffer, size) != (ssize_t)size)
 112               {
 113                   Fatal(FL, "Failed to write response");
 114               }
 115           }
 116           
 117           /*
 118           **==============================================================================
 119           **
 120 kumpf 1.2 ** HandlePingRequest()
 121           **
 122           **     Handle ping request.
 123           **
 124           **==============================================================================
 125           */
 126           
 127           static void HandlePingRequest(int sock)
 128           {
 129               struct ExecutorPingResponse response;
 130           
 131               memset(&response, 0, sizeof(response));
 132               response.magic = EXECUTOR_PING_MAGIC;
 133           
 134               Log(LL_TRACE, "HandlePingRequest()");
 135           
 136 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 137 kumpf 1.2 }
 138           
 139           /*
 140           **==============================================================================
 141           **
 142           ** HandleOpenFileRequest()
 143           **
 144           **     Handle a request from a child to open a file.
 145           **
 146           **==============================================================================
 147           */
 148           
 149           static void HandleOpenFileRequest(int sock)
 150           {
 151               struct ExecutorOpenFileRequest request;
 152               struct ExecutorOpenFileResponse response;
 153               int fd;
 154           
 155               memset(&response, 0, sizeof(response));
 156           
 157               /* Read the request message. */
 158 kumpf 1.2 
 159 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 160 kumpf 1.2 
 161               /* Log the request. */
 162           
 163               Log(LL_TRACE, "HandleOpenFileRequest(): path=\"%s\", mode='%c'",
 164                   request.path, request.mode);
 165           
 166               /* Perform the operation. */
 167           
 168               response.status = 0;
 169               fd = -1;
 170           
 171               do
 172               {
 173                   /* Check the policy. */
 174           
 175                   if (CheckOpenFilePolicy(request.path, request.mode) != 0)
 176                   {
 177                       response.status = -1;
 178                       break;
 179                   }
 180           
 181 kumpf 1.2         /* Open file. */
 182           
 183                   switch (request.mode)
 184                   {
 185                       case 'r':
 186                           fd = open(request.path, O_RDONLY);
 187                           break;
 188           
 189                       case 'w':
 190                           fd = open(
 191                               request.path,
 192                               O_WRONLY | O_CREAT | O_TRUNC,
 193                               S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */
 194                           break;
 195           
 196                       case 'a':
 197                       {
 198                           fd = open(
 199                               request.path,
 200                               O_WRONLY | O_CREAT | O_APPEND,
 201                               S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */
 202 kumpf 1.2                 break;
 203                       }
 204                   }
 205           
 206                   if (fd == -1)
 207                       response.status = -1;
 208               }
 209               while (0);
 210           
 211               /* Log failure. */
 212           
 213               if (response.status != 0)
 214               {
 215                   Log(LL_WARNING, "open(\"%s\", '%c') failed",
 216                       request.path, request.mode);
 217               }
 218           
 219               /* Send response. */
 220           
 221 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 222 kumpf 1.2 
 223               /* Send descriptor to calling process (if any to send). */
 224           
 225               if (response.status == 0)
 226               {
 227                   int descriptors[1];
 228                   descriptors[0] = fd;
 229                   SendDescriptorArray(sock, descriptors, 1);
 230                   close(fd);
 231               }
 232           }
 233           
 234           /*
 235           **==============================================================================
 236           **
 237           ** HandleStartProviderAgentRequest()
 238           **
 239           **==============================================================================
 240           */
 241           
 242           static void HandleStartProviderAgentRequest(int sock)
 243 kumpf 1.2 {
 244               int status;
 245 kumpf 1.3     int uid;
 246               int gid;
 247 kumpf 1.2     int pid;
 248               int to[2];
 249               int from[2];
 250               struct ExecutorStartProviderAgentResponse response;
 251               struct ExecutorStartProviderAgentRequest request;
 252           
 253               memset(&response, 0, sizeof(response));
 254           
 255               /* Read request. */
 256           
 257 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 258 kumpf 1.2 
 259               /* Log request. */
 260           
 261               Log(LL_TRACE, "HandleStartProviderAgentRequest(): "
 262 kumpf 1.3         "module=%s userName=%s", request.module, request.userName);
 263 kumpf 1.2 
 264               /* Process request. */
 265           
 266               status = 0;
 267               pid = -1;
 268           
 269               do
 270               {
 271                   /* Resolve full path of CIMPROVAGT. */
 272           
 273                   const char* path;
 274           
 275                   if ((path = FindMacro("cimprovagtPath")) == NULL)
 276                       Fatal(FL, "Failed to locate %s program", CIMPROVAGT);
 277           
 278 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
 279           
 280                   /* Look up the user ID and group ID of the specified user. */
 281           
 282                   if (GetUserInfo(request.userName, &uid, &gid) != 0)
 283                   {
 284                       status = -1;
 285                       break;
 286                   }
 287           
 288                   Log(LL_TRACE, "cimprovagt user context: "
 289                       "userName=%s uid=%d gid=%d", request.userName, uid, gid);
 290           
 291           #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 292           
 293 kumpf 1.2         /* Create "to-agent" pipe: */
 294           
 295                   if (pipe(to) != 0)
 296                   {
 297                       status = -1;
 298                       break;
 299                   }
 300           
 301                   /* Create "from-agent" pipe: */
 302           
 303                   if (pipe(from) != 0)
 304                   {
 305                       status = -1;
 306                       break;
 307                   }
 308           
 309                   /* Fork process: */
 310           
 311                   pid = fork();
 312           
 313                   if (pid < 0)
 314 kumpf 1.2         {
 315                       Log(LL_SEVERE, "fork failed");
 316                       status = -1;
 317                       break;
 318                   }
 319           
 320                   /* If child: */
 321           
 322                   if (pid == 0)
 323                   {
 324                       struct rlimit rlim;
 325                       char arg1[32];
 326                       char arg2[32];
 327           
 328                       /* Close unused pipe descriptors: */
 329           
 330                       close(to[1]);
 331                       close(from[0]);
 332           
 333                       /*
 334                        * Close unused descriptors. Leave stdin, stdout, stderr, and the
 335 kumpf 1.2              * child's pipe descriptors open.
 336                        */
 337           
 338                       if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
 339                       {
 340                           int i;
 341           
 342                           for (i = 3; i < (int)rlim.rlim_cur; i++)
 343                           {
 344                               if (i != to[0] && i != from[1])
 345                                   close(i);
 346                           }
 347                       }
 348           
 349 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
 350           
 351                       if ((int)getgid() != gid)
 352                       {
 353                           if (setgid((gid_t)gid) != 0)
 354                           {
 355                               Log(LL_SEVERE, "setgid(%d) failed\n", gid);
 356                               _exit(1);
 357                           }
 358                       }
 359 kumpf 1.2 
 360 kumpf 1.3             if ((int)getuid() != uid)
 361 kumpf 1.2             {
 362 kumpf 1.3                 if (initgroups(request.userName, gid) != 0)
 363 kumpf 1.2                 {
 364 kumpf 1.3                     Log(LL_SEVERE, "initgroups(%s, %d) failed\n",
 365                                   request.userName,
 366                                   gid);
 367                               _exit(1);
 368 kumpf 1.2                 }
 369           
 370 kumpf 1.3                 if (setuid((uid_t)uid) != 0)
 371 kumpf 1.2                 {
 372 kumpf 1.3                     Log(LL_SEVERE, "setuid(%d) failed\n", uid);
 373                               _exit(1);
 374 kumpf 1.2                 }
 375                       }
 376           
 377                       Log(LL_TRACE, "starting %s on module %s as user %s",
 378 kumpf 1.3                 path, request.module, request.userName);
 379 kumpf 1.2 
 380 kumpf 1.3 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 381 kumpf 1.2 
 382                       /* Exec the CIMPROVAGT program. */
 383           
 384                       sprintf(arg1, "%d", to[0]);
 385                       sprintf(arg2, "%d", from[1]);
 386           
 387                       Log(LL_TRACE, "execl(%s, %s, %s, %s, %s)\n",
 388                           path, path, arg1, arg2, request.module);
 389           
 390                       /* Flawfinder: ignore */
 391                       execl(path, path, arg1, arg2, request.module, (char*)0);
 392           
 393                       Log(LL_SEVERE, "execl(%s, %s, %s, %s, %s): failed\n",
 394                           path, path, arg1, arg2, request.module);
 395 kumpf 1.5             _exit(1);
 396 kumpf 1.2         }
 397               }
 398               while (0);
 399           
 400               /* Close unused pipe descriptors. */
 401           
 402               close(to[0]);
 403               close(from[1]);
 404           
 405               /* Send response. */
 406           
 407               response.status = status;
 408               response.pid = pid;
 409           
 410 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 411 kumpf 1.2 
 412               /* Send descriptors to calling process. */
 413           
 414               if (response.status == 0)
 415               {
 416                   int descriptors[2];
 417                   descriptors[0] = from[0];
 418                   descriptors[1] = to[1];
 419           
 420                   SendDescriptorArray(sock, descriptors, 2);
 421                   close(from[0]);
 422                   close(to[1]);
 423               }
 424           }
 425           
 426           /*
 427           **==============================================================================
 428           **
 429           ** HandleDaemonizeExecutorRequest()
 430           **
 431           **==============================================================================
 432 kumpf 1.2 */
 433           
 434           static void HandleDaemonizeExecutorRequest(int sock, int bindVerbose)
 435           {
 436               struct ExecutorDaemonizeExecutorResponse response;
 437               int pid;
 438           
 439               memset(&response, 0, sizeof(response));
 440           
 441               Log(LL_TRACE, "HandleDaemonizeExecutorRequest()");
 442           
 443               /* Fork (parent exits; child continues) */
 444               /* (Ensures we are not a session leader so that setsid() will succeed.) */
 445           
 446               pid = fork();
 447           
 448               if (pid < 0)
 449               {
 450                   response.status = -1;
 451                   Fatal(FL, "fork() failed");
 452               }
 453 kumpf 1.2 
 454               if (pid > 0)
 455                   _exit(0);
 456           
 457               /* Become session leader (so that our child process will not be one) */
 458           
 459               if (setsid() < 0)
 460               {
 461                   response.status = -1;
 462                   Fatal(FL, "setsid() failed");
 463               }
 464           
 465               /* Ignore SIGHUP: */
 466           
 467               signal(SIGHUP, SIG_IGN);
 468           
 469               /* Fork again (so we are not a session leader because our parent is): */
 470           
 471               pid = fork();
 472           
 473               if (pid < 0)
 474 kumpf 1.2     {
 475                   response.status = -1;
 476                   Fatal(FL, "fork() failed");
 477               }
 478           
 479               if (pid > 0)
 480                   _exit(0);
 481           
 482               /* Catch SIGTERM: */
 483           
 484               signal(SIGTERM, _sigHandler);
 485           
 486               /* Make root the current directory. */
 487           
 488               chdir("/");
 489           
 490               if (!bindVerbose)
 491               {
 492                   /* Close these file descriptors (stdin, stdout, stderr). */
 493           
 494                   close(0);
 495 kumpf 1.2         close(1);
 496                   close(2);
 497           
 498                   /* Direct standard input, output, and error to /dev/null: */
 499           
 500                   open("/dev/null", O_RDONLY);
 501                   open("/dev/null", O_RDWR);
 502                   open("/dev/null", O_RDWR);
 503               }
 504           
 505               response.status = 0;
 506           
 507 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 508 kumpf 1.2 }
 509           
 510           /*
 511           **==============================================================================
 512           **
 513           ** HandleRenameFileRequest()
 514           **
 515           **==============================================================================
 516           */
 517           
 518           static void HandleRenameFileRequest(int sock)
 519           {
 520               struct ExecutorRenameFileResponse response;
 521               struct ExecutorRenameFileRequest request;
 522           
 523               memset(&response, 0, sizeof(response));
 524           
 525               /* Read the request message. */
 526           
 527 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 528 kumpf 1.2 
 529               /* Log request. */
 530           
 531               Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
 532                   request.oldPath, request.newPath);
 533           
 534               /* Perform the operation: */
 535           
 536               response.status = 0;
 537           
 538               do
 539               {
 540                   /* Check the policy. */
 541           
 542                   if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
 543                   {
 544                       response.status = -1;
 545                       break;
 546                   }
 547           
 548                   /* Rename the file. */
 549 kumpf 1.2 
 550                   if (rename(request.oldPath, request.newPath) != 0)
 551                   {
 552                       response.status = -1;
 553                       break;
 554                   }
 555               }
 556               while (0);
 557           
 558               /* Send response message. */
 559           
 560 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 561 kumpf 1.2 }
 562           
 563           /*
 564           **==============================================================================
 565           **
 566           ** HandleRemoveFileRequest()
 567           **
 568           **==============================================================================
 569           */
 570           
 571           static void HandleRemoveFileRequest(int sock)
 572           {
 573               struct ExecutorRemoveFileRequest request;
 574               struct ExecutorRemoveFileResponse response;
 575           
 576               memset(&response, 0, sizeof(response));
 577           
 578               /* Read the request message. */
 579           
 580 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 581 kumpf 1.2 
 582               /* Log request. */
 583           
 584               Log(LL_TRACE, "HandleRemoveFileRequest(): path=%s", request.path);
 585           
 586               response.status = 0;
 587           
 588               do
 589               {
 590                   /* Check the policy. */
 591           
 592                   if (CheckRemoveFilePolicy(request.path) != 0)
 593                   {
 594                       response.status = -1;
 595                       break;
 596                   }
 597           
 598                   /* Remove the file. */
 599           
 600                   if (unlink(request.path) != 0)
 601                   {
 602 kumpf 1.2             response.status = -1;
 603                       Log(LL_WARNING, "unlink(%s) failed", request.path);
 604                       break;
 605                   }
 606               }
 607               while (0);
 608           
 609               /* Send response message. */
 610           
 611 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 612 kumpf 1.2 }
 613           
 614           /*
 615           **==============================================================================
 616           **
 617           ** HandleReapProviderAgentRequest()
 618           **
 619           **==============================================================================
 620           */
 621           
 622           static void HandleReapProviderAgentRequest(int sock)
 623           {
 624               int status;
 625               struct ExecutorReapProviderAgentRequest request;
 626               struct ExecutorReapProviderAgentResponse response;
 627           
 628               memset(&response, 0, sizeof(response));
 629           
 630               /* Read the request message. */
 631           
 632 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 633 kumpf 1.2 
 634               /* Log request. */
 635           
 636               Log(LL_TRACE, "HandleReapProviderAgentRequest(): pid=%d", request.pid);
 637           
 638               /* Perform operation. */
 639           
 640               status = 0;
 641           
 642               do
 643               {
 644                   /* Wait on the PID. */
 645           
 646                   EXECUTOR_RESTART(waitpid(request.pid, 0, 0), status);
 647           
 648                   if (status == -1)
 649                       Log(LL_WARNING, "waitpid(%d, 0, 0) failed", request.pid);
 650               }
 651               while (0);
 652           
 653               /* Send response message. */
 654 kumpf 1.2 
 655               response.status = status;
 656           
 657 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 658 kumpf 1.2 }
 659           
 660           /*
 661           **==============================================================================
 662           **
 663           ** HandleAuthenticatePasswordRequest()
 664           **
 665           **==============================================================================
 666           */
 667           
 668           static void HandleAuthenticatePasswordRequest(int sock)
 669           {
 670               int status;
 671               struct ExecutorAuthenticatePasswordRequest request;
 672               struct ExecutorAuthenticatePasswordResponse response;
 673               int gid;
 674               int uid;
 675           
 676               memset(&response, 0, sizeof(response));
 677           
 678               /* Read the request message. */
 679 kumpf 1.2 
 680 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 681 kumpf 1.2 
 682               /* Log request. */
 683           
 684               Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
 685                   request.username);
 686           
 687               /* Perform the operation: */
 688           
 689               status = 0;
 690           
 691               do
 692               {
 693                   if (GetUserInfo(request.username, &uid, &gid) != 0)
 694                   {
 695                       status = -1;
 696                       break;
 697                   }
 698           
 699           #if defined(PEGASUS_PAM_AUTHENTICATION)
 700           
 701                   if (PAMAuthenticate(request.username, request.password) != 0)
 702 kumpf 1.2         {
 703                       status = -1;
 704                       break;
 705                   }
 706           
 707           
 708           #else /* !PEGASUS_PAM_AUTHENTICATION */
 709           
 710                   {
 711                       const char* path = FindMacro("passwordFilePath");
 712           
 713                       if (!path)
 714                       {
 715                           status = -1;
 716                           break;
 717                       }
 718           
 719                       if (CheckPasswordFile(
 720                           path, request.username, request.password) != 0)
 721                       {
 722                           status = -1;
 723 kumpf 1.2                 break;
 724                       }
 725                   }
 726           
 727           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 728               }
 729               while (0);
 730           
 731               if (status != 0)
 732               {
 733                   Log(LL_WARNING, "Basic authentication failed for username %s",
 734                       request.username);
 735               }
 736               else
 737               {
 738                   Log(LL_TRACE, "Basic authentication succeeded for username %s",
 739                       request.username);
 740               }
 741           
 742               /* Send response message. */
 743           
 744 kumpf 1.2     response.status = status;
 745           
 746 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 747 kumpf 1.2 }
 748           
 749           /*
 750           **==============================================================================
 751           **
 752           ** HandleValidateUserRequest()
 753           **
 754           **==============================================================================
 755           */
 756           
 757           static void HandleValidateUserRequest(int sock)
 758           {
 759               int status;
 760               struct ExecutorValidateUserResponse response;
 761               struct ExecutorValidateUserRequest request;
 762           
 763               memset(&response, 0, sizeof(response));
 764           
 765               /* Read the request message. */
 766           
 767 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 768 kumpf 1.2 
 769               /* Validate the user. */
 770           
 771               Log(LL_TRACE,
 772                   "HandleValidateUserRequest(): username=%s", request.username);
 773           
 774               /* Get the uid for the username. */
 775           
 776               status = 0;
 777           
 778           #if defined(PEGASUS_PAM_AUTHENTICATION)
 779           
 780               if (PAMValidateUser(request.username) != 0)
 781                   status = -1;
 782           
 783           #else /* !PEGASUS_PAM_AUTHENTICATION */
 784           
 785               do
 786               {
 787                   const char* path = FindMacro("passwordFilePath");
 788           
 789 kumpf 1.2         if (!path)
 790                   {
 791                       status = -1;
 792                       break;
 793                   }
 794           
 795                   if (CheckPasswordFile(path, request.username, NULL) != 0)
 796                   {
 797                       status = -1;
 798                       break;
 799                   }
 800               }
 801               while (0);
 802           
 803           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 804           
 805               if (status != 0)
 806                   Log(LL_WARNING, "User validation failed on %s", request.username);
 807           
 808               /* Send response message. */
 809           
 810 kumpf 1.2     response.status = status;
 811           
 812 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 813 kumpf 1.2 }
 814           
 815           /*
 816           **==============================================================================
 817           **
 818           ** HandleChallengeLocalRequest()
 819           **
 820           **==============================================================================
 821           */
 822           
 823           static void HandleChallengeLocalRequest(int sock)
 824           {
 825               char challenge[EXECUTOR_BUFFER_SIZE];
 826               struct ExecutorChallengeLocalRequest request;
 827               struct ExecutorChallengeLocalResponse response;
 828           
 829               memset(&response, 0, sizeof(response));
 830           
 831               /* Read the request message. */
 832           
 833 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 834 kumpf 1.2 
 835               Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
 836           
 837               /* Perform operation. */
 838           
 839 kumpf 1.4     response.status = StartLocalAuthentication(request.user, challenge);
 840 kumpf 1.2 
 841 kumpf 1.4     /* Send response message. */
 842           
 843               if (response.status != 0)
 844 kumpf 1.2     {
 845                   Log(LL_WARNING, "Local authentication failed for user \"%s\"",
 846                       request.user);
 847               }
 848 kumpf 1.4     else
 849               {
 850 kumpf 1.2         Strlcpy(response.challenge, challenge, sizeof(response.challenge));
 851 kumpf 1.4     }
 852 kumpf 1.2 
 853 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 854 kumpf 1.2 }
 855           
 856           /*
 857           **==============================================================================
 858           **
 859           ** HandleAuthenticateLocalRequest()
 860           **
 861           **==============================================================================
 862           */
 863           
 864           static void HandleAuthenticateLocalRequest(int sock)
 865           {
 866               int status;
 867               struct ExecutorAuthenticateLocalRequest request;
 868               struct ExecutorAuthenticateLocalResponse response;
 869           
 870               memset(&response, 0, sizeof(response));
 871           
 872               /* Read the request message. */
 873           
 874 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 875 kumpf 1.2 
 876               Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
 877           
 878               /* Perform operation. */
 879           
 880               status = FinishLocalAuthentication(request.challenge, request.response);
 881           
 882               /* Log result. */
 883           
 884               if (status != 0)
 885               {
 886                   Log(LL_WARNING, "Local authentication failed");
 887               }
 888           
 889               /* Send response. */
 890           
 891               response.status = status;
 892           
 893 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 894 kumpf 1.2 }
 895           
 896           /*
 897           **==============================================================================
 898           **
 899 kumpf 1.5 ** HandleUpdateLogLevelRequest()
 900           **
 901           **==============================================================================
 902           */
 903           
 904           static void HandleUpdateLogLevelRequest(int sock)
 905           {
 906               int status;
 907               struct ExecutorUpdateLogLevelRequest request;
 908               struct ExecutorUpdateLogLevelResponse response;
 909           
 910               memset(&response, 0, sizeof(response));
 911           
 912               /* Read the request message. */
 913           
 914               ReadExecutorRequest(sock, &request, sizeof(request));
 915           
 916               /* Log request. */
 917           
 918               Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
 919                   request.logLevel);
 920 kumpf 1.5 
 921               /* Perform operation. */
 922           
 923               status = SetLogLevel(request.logLevel);
 924           
 925               if (status == -1)
 926                   Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
 927           
 928               /* Send response message. */
 929           
 930               response.status = status;
 931           
 932               WriteExecutorResponse(sock, &response, sizeof(response));
 933           }
 934           
 935           /*
 936           **==============================================================================
 937           **
 938 kumpf 1.2 ** Parent()
 939           **
 940           **     The parent process (cimserver).
 941           **
 942           **==============================================================================
 943           */
 944           
 945           void Parent(int sock, int childPid, int bindVerbose)
 946           {
 947               /* Handle Ctrl-C. */
 948           
 949               signal(SIGINT, _sigHandler);
 950           
 951               /* Catch SIGTERM, sent by kill program. */
 952           
 953               signal(SIGTERM, _sigHandler);
 954           
 955               /*
 956                * Ignore SIGPIPE, which occurs if a child with whom the executor shares
 957                * a local domain socket unexpectedly dies. In such a case, the socket
 958                * read/write functions will return an error. There are two child processes
 959 kumpf 1.2      * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
 960                */
 961           
 962               signal(SIGPIPE, SIG_IGN);
 963           
 964               /* Save child PID globally; it is used by Exit() function. */
 965           
 966               globals.childPid = childPid;
 967           
 968               /* Prepares socket into non-blocking I/O. */
 969           
 970               SetNonBlocking(sock);
 971           
 972               /* Process client requests until client exists. */
 973           
 974               for (;;)
 975               {
 976                   size_t n;
 977                   struct ExecutorRequestHeader header;
 978           
 979                   /* Receive request header. */
 980 kumpf 1.2 
 981                   n = RecvNonBlock(sock, &header, sizeof(header));
 982           
 983                   if (n == 0)
 984                   {
 985                       /*
 986                        * Either client closed its end of the pipe (possibly by exiting)
 987                        * or we caught a SIGTERM.
 988                        */
 989                       break;
 990                   }
 991           
 992                   if (n != sizeof(header))
 993                       Fatal(FL, "Failed to read header");
 994           
 995                   /* Dispatch request. */
 996           
 997                   switch ((enum ExecutorMessageCode)header.code)
 998                   {
 999                       case EXECUTOR_PING_MESSAGE:
1000                           HandlePingRequest(sock);
1001 kumpf 1.2                 break;
1002           
1003                       case EXECUTOR_OPEN_FILE_MESSAGE:
1004                           HandleOpenFileRequest(sock);
1005                           break;
1006           
1007                       case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
1008                           HandleStartProviderAgentRequest(sock);
1009                           break;
1010           
1011                       case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
1012                           HandleDaemonizeExecutorRequest(sock, bindVerbose);
1013                           break;
1014           
1015                       case EXECUTOR_RENAME_FILE_MESSAGE:
1016                           HandleRenameFileRequest(sock);
1017                           break;
1018           
1019                       case EXECUTOR_REMOVE_FILE_MESSAGE:
1020                           HandleRemoveFileRequest(sock);
1021                           break;
1022 kumpf 1.2 
1023 kumpf 1.5             case EXECUTOR_REAP_PROVIDER_AGENT_MESSAGE:
1024 kumpf 1.2                 HandleReapProviderAgentRequest(sock);
1025                           break;
1026           
1027                       case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
1028                           HandleAuthenticatePasswordRequest(sock);
1029                           break;
1030           
1031                       case EXECUTOR_VALIDATE_USER_MESSAGE:
1032                           HandleValidateUserRequest(sock);
1033                           break;
1034           
1035                       case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
1036                           HandleChallengeLocalRequest(sock);
1037                           break;
1038           
1039                       case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
1040                           HandleAuthenticateLocalRequest(sock);
1041                           break;
1042           
1043 kumpf 1.5             case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
1044                           HandleUpdateLogLevelRequest(sock);
1045                           break;
1046           
1047 kumpf 1.2             default:
1048                           Fatal(FL, "Invalid request code: %d", header.code);
1049                           break;
1050                   }
1051               }
1052           
1053               /* Reached due to socket EOF, SIGTERM, or SIGINT. */
1054           
1055               Exit(0);
1056           }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2