(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 kumpf 1.6         unsigned long permissions = 0;
 176           
 177                   if (CheckOpenFilePolicy(request.path, request.mode, &permissions) != 0)
 178 kumpf 1.2         {
 179                       response.status = -1;
 180                       break;
 181                   }
 182           
 183                   /* Open file. */
 184           
 185                   switch (request.mode)
 186                   {
 187                       case 'r':
 188                           fd = open(request.path, O_RDONLY);
 189                           break;
 190           
 191                       case 'w':
 192                           fd = open(
 193                               request.path,
 194                               O_WRONLY | O_CREAT | O_TRUNC,
 195 kumpf 1.6                     permissions);
 196 kumpf 1.2                 break;
 197           
 198                       case 'a':
 199                       {
 200                           fd = open(
 201                               request.path,
 202                               O_WRONLY | O_CREAT | O_APPEND,
 203 kumpf 1.6                     permissions);
 204 kumpf 1.2                 break;
 205                       }
 206                   }
 207           
 208                   if (fd == -1)
 209                       response.status = -1;
 210               }
 211               while (0);
 212           
 213               /* Log failure. */
 214           
 215               if (response.status != 0)
 216               {
 217                   Log(LL_WARNING, "open(\"%s\", '%c') failed",
 218                       request.path, request.mode);
 219               }
 220           
 221               /* Send response. */
 222           
 223 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 224 kumpf 1.2 
 225               /* Send descriptor to calling process (if any to send). */
 226           
 227               if (response.status == 0)
 228               {
 229                   int descriptors[1];
 230                   descriptors[0] = fd;
 231                   SendDescriptorArray(sock, descriptors, 1);
 232                   close(fd);
 233               }
 234           }
 235           
 236           /*
 237           **==============================================================================
 238           **
 239           ** HandleStartProviderAgentRequest()
 240           **
 241           **==============================================================================
 242           */
 243           
 244           static void HandleStartProviderAgentRequest(int sock)
 245 kumpf 1.2 {
 246               int status;
 247 kumpf 1.3     int uid;
 248               int gid;
 249 kumpf 1.2     int pid;
 250               int to[2];
 251               int from[2];
 252               struct ExecutorStartProviderAgentResponse response;
 253               struct ExecutorStartProviderAgentRequest request;
 254           
 255               memset(&response, 0, sizeof(response));
 256           
 257               /* Read request. */
 258           
 259 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 260 kumpf 1.2 
 261               /* Log request. */
 262           
 263               Log(LL_TRACE, "HandleStartProviderAgentRequest(): "
 264 kumpf 1.3         "module=%s userName=%s", request.module, request.userName);
 265 kumpf 1.2 
 266               /* Process request. */
 267           
 268               status = 0;
 269               pid = -1;
 270           
 271               do
 272               {
 273                   /* Resolve full path of CIMPROVAGT. */
 274           
 275                   const char* path;
 276           
 277                   if ((path = FindMacro("cimprovagtPath")) == NULL)
 278                       Fatal(FL, "Failed to locate %s program", CIMPROVAGT);
 279           
 280 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
 281           
 282                   /* Look up the user ID and group ID of the specified user. */
 283           
 284                   if (GetUserInfo(request.userName, &uid, &gid) != 0)
 285                   {
 286                       status = -1;
 287                       break;
 288                   }
 289           
 290                   Log(LL_TRACE, "cimprovagt user context: "
 291                       "userName=%s uid=%d gid=%d", request.userName, uid, gid);
 292           
 293           #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 294           
 295 kumpf 1.2         /* Create "to-agent" pipe: */
 296           
 297                   if (pipe(to) != 0)
 298                   {
 299                       status = -1;
 300                       break;
 301                   }
 302           
 303                   /* Create "from-agent" pipe: */
 304           
 305                   if (pipe(from) != 0)
 306                   {
 307                       status = -1;
 308                       break;
 309                   }
 310           
 311                   /* Fork process: */
 312           
 313                   pid = fork();
 314           
 315                   if (pid < 0)
 316 kumpf 1.2         {
 317                       Log(LL_SEVERE, "fork failed");
 318                       status = -1;
 319                       break;
 320                   }
 321           
 322                   /* If child: */
 323           
 324                   if (pid == 0)
 325                   {
 326                       struct rlimit rlim;
 327                       char arg1[32];
 328                       char arg2[32];
 329           
 330                       /* Close unused pipe descriptors: */
 331           
 332                       close(to[1]);
 333                       close(from[0]);
 334           
 335                       /*
 336                        * Close unused descriptors. Leave stdin, stdout, stderr, and the
 337 kumpf 1.2              * child's pipe descriptors open.
 338                        */
 339           
 340                       if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
 341                       {
 342                           int i;
 343           
 344                           for (i = 3; i < (int)rlim.rlim_cur; i++)
 345                           {
 346                               if (i != to[0] && i != from[1])
 347                                   close(i);
 348                           }
 349                       }
 350           
 351 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
 352           
 353                       if ((int)getgid() != gid)
 354                       {
 355                           if (setgid((gid_t)gid) != 0)
 356                           {
 357                               Log(LL_SEVERE, "setgid(%d) failed\n", gid);
 358                               _exit(1);
 359                           }
 360                       }
 361 kumpf 1.2 
 362 kumpf 1.3             if ((int)getuid() != uid)
 363 kumpf 1.2             {
 364 kumpf 1.3                 if (initgroups(request.userName, gid) != 0)
 365 kumpf 1.2                 {
 366 kumpf 1.3                     Log(LL_SEVERE, "initgroups(%s, %d) failed\n",
 367                                   request.userName,
 368                                   gid);
 369                               _exit(1);
 370 kumpf 1.2                 }
 371           
 372 kumpf 1.3                 if (setuid((uid_t)uid) != 0)
 373 kumpf 1.2                 {
 374 kumpf 1.3                     Log(LL_SEVERE, "setuid(%d) failed\n", uid);
 375                               _exit(1);
 376 kumpf 1.2                 }
 377                       }
 378           
 379                       Log(LL_TRACE, "starting %s on module %s as user %s",
 380 kumpf 1.3                 path, request.module, request.userName);
 381 kumpf 1.2 
 382 kumpf 1.3 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
 383 kumpf 1.2 
 384                       /* Exec the CIMPROVAGT program. */
 385           
 386                       sprintf(arg1, "%d", to[0]);
 387                       sprintf(arg2, "%d", from[1]);
 388           
 389                       Log(LL_TRACE, "execl(%s, %s, %s, %s, %s)\n",
 390                           path, path, arg1, arg2, request.module);
 391           
 392                       /* Flawfinder: ignore */
 393                       execl(path, path, arg1, arg2, request.module, (char*)0);
 394           
 395                       Log(LL_SEVERE, "execl(%s, %s, %s, %s, %s): failed\n",
 396                           path, path, arg1, arg2, request.module);
 397 kumpf 1.5             _exit(1);
 398 kumpf 1.2         }
 399               }
 400               while (0);
 401           
 402               /* Close unused pipe descriptors. */
 403           
 404               close(to[0]);
 405               close(from[1]);
 406           
 407               /* Send response. */
 408           
 409               response.status = status;
 410               response.pid = pid;
 411           
 412 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 413 kumpf 1.2 
 414               /* Send descriptors to calling process. */
 415           
 416               if (response.status == 0)
 417               {
 418                   int descriptors[2];
 419                   descriptors[0] = from[0];
 420                   descriptors[1] = to[1];
 421           
 422                   SendDescriptorArray(sock, descriptors, 2);
 423                   close(from[0]);
 424                   close(to[1]);
 425               }
 426           }
 427           
 428           /*
 429           **==============================================================================
 430           **
 431           ** HandleDaemonizeExecutorRequest()
 432           **
 433           **==============================================================================
 434 kumpf 1.2 */
 435           
 436           static void HandleDaemonizeExecutorRequest(int sock, int bindVerbose)
 437           {
 438               struct ExecutorDaemonizeExecutorResponse response;
 439               int pid;
 440           
 441               memset(&response, 0, sizeof(response));
 442           
 443               Log(LL_TRACE, "HandleDaemonizeExecutorRequest()");
 444           
 445               /* Fork (parent exits; child continues) */
 446               /* (Ensures we are not a session leader so that setsid() will succeed.) */
 447           
 448               pid = fork();
 449           
 450               if (pid < 0)
 451               {
 452                   response.status = -1;
 453                   Fatal(FL, "fork() failed");
 454               }
 455 kumpf 1.2 
 456               if (pid > 0)
 457                   _exit(0);
 458           
 459               /* Become session leader (so that our child process will not be one) */
 460           
 461               if (setsid() < 0)
 462               {
 463                   response.status = -1;
 464                   Fatal(FL, "setsid() failed");
 465               }
 466           
 467               /* Ignore SIGHUP: */
 468           
 469               signal(SIGHUP, SIG_IGN);
 470           
 471 kumpf 1.7     /* Ignore SIGCHLD: */
 472           
 473               signal(SIGCHLD, SIG_IGN);
 474           
 475 kumpf 1.2     /* Fork again (so we are not a session leader because our parent is): */
 476           
 477               pid = fork();
 478           
 479               if (pid < 0)
 480               {
 481                   response.status = -1;
 482                   Fatal(FL, "fork() failed");
 483               }
 484           
 485               if (pid > 0)
 486                   _exit(0);
 487           
 488               /* Catch SIGTERM: */
 489           
 490               signal(SIGTERM, _sigHandler);
 491           
 492               /* Make root the current directory. */
 493           
 494               chdir("/");
 495           
 496 kumpf 1.2     if (!bindVerbose)
 497               {
 498                   /* Close these file descriptors (stdin, stdout, stderr). */
 499           
 500                   close(0);
 501                   close(1);
 502                   close(2);
 503           
 504                   /* Direct standard input, output, and error to /dev/null: */
 505           
 506                   open("/dev/null", O_RDONLY);
 507                   open("/dev/null", O_RDWR);
 508                   open("/dev/null", O_RDWR);
 509               }
 510           
 511               response.status = 0;
 512           
 513 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 514 kumpf 1.2 }
 515           
 516           /*
 517           **==============================================================================
 518           **
 519           ** HandleRenameFileRequest()
 520           **
 521           **==============================================================================
 522           */
 523           
 524           static void HandleRenameFileRequest(int sock)
 525           {
 526               struct ExecutorRenameFileResponse response;
 527               struct ExecutorRenameFileRequest request;
 528           
 529               memset(&response, 0, sizeof(response));
 530           
 531               /* Read the request message. */
 532           
 533 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 534 kumpf 1.2 
 535               /* Log request. */
 536           
 537               Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
 538                   request.oldPath, request.newPath);
 539           
 540               /* Perform the operation: */
 541           
 542               response.status = 0;
 543           
 544               do
 545               {
 546                   /* Check the policy. */
 547           
 548                   if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
 549                   {
 550                       response.status = -1;
 551                       break;
 552                   }
 553           
 554                   /* Rename the file. */
 555 kumpf 1.2 
 556                   if (rename(request.oldPath, request.newPath) != 0)
 557                   {
 558                       response.status = -1;
 559                       break;
 560                   }
 561               }
 562               while (0);
 563           
 564               /* Send response message. */
 565           
 566 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 567 kumpf 1.2 }
 568           
 569           /*
 570           **==============================================================================
 571           **
 572           ** HandleRemoveFileRequest()
 573           **
 574           **==============================================================================
 575           */
 576           
 577           static void HandleRemoveFileRequest(int sock)
 578           {
 579               struct ExecutorRemoveFileRequest request;
 580               struct ExecutorRemoveFileResponse response;
 581           
 582               memset(&response, 0, sizeof(response));
 583           
 584               /* Read the request message. */
 585           
 586 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 587 kumpf 1.2 
 588               /* Log request. */
 589           
 590               Log(LL_TRACE, "HandleRemoveFileRequest(): path=%s", request.path);
 591           
 592               response.status = 0;
 593           
 594               do
 595               {
 596                   /* Check the policy. */
 597           
 598                   if (CheckRemoveFilePolicy(request.path) != 0)
 599                   {
 600                       response.status = -1;
 601                       break;
 602                   }
 603           
 604                   /* Remove the file. */
 605           
 606                   if (unlink(request.path) != 0)
 607                   {
 608 kumpf 1.2             response.status = -1;
 609                       Log(LL_WARNING, "unlink(%s) failed", request.path);
 610                       break;
 611                   }
 612               }
 613               while (0);
 614           
 615               /* Send response message. */
 616           
 617 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 618 kumpf 1.2 }
 619           
 620           /*
 621           **==============================================================================
 622           **
 623           ** HandleAuthenticatePasswordRequest()
 624           **
 625           **==============================================================================
 626           */
 627           
 628           static void HandleAuthenticatePasswordRequest(int sock)
 629           {
 630               int status;
 631               struct ExecutorAuthenticatePasswordRequest request;
 632               struct ExecutorAuthenticatePasswordResponse response;
 633               int gid;
 634               int uid;
 635           
 636               memset(&response, 0, sizeof(response));
 637           
 638               /* Read the request message. */
 639 kumpf 1.2 
 640 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 641 kumpf 1.2 
 642               /* Log request. */
 643           
 644               Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
 645                   request.username);
 646           
 647               /* Perform the operation: */
 648           
 649               status = 0;
 650           
 651               do
 652               {
 653                   if (GetUserInfo(request.username, &uid, &gid) != 0)
 654                   {
 655                       status = -1;
 656                       break;
 657                   }
 658           
 659           #if defined(PEGASUS_PAM_AUTHENTICATION)
 660           
 661                   if (PAMAuthenticate(request.username, request.password) != 0)
 662 kumpf 1.2         {
 663                       status = -1;
 664                       break;
 665                   }
 666           
 667           
 668           #else /* !PEGASUS_PAM_AUTHENTICATION */
 669           
 670                   {
 671                       const char* path = FindMacro("passwordFilePath");
 672           
 673                       if (!path)
 674                       {
 675                           status = -1;
 676                           break;
 677                       }
 678           
 679                       if (CheckPasswordFile(
 680                           path, request.username, request.password) != 0)
 681                       {
 682                           status = -1;
 683 kumpf 1.2                 break;
 684                       }
 685                   }
 686           
 687           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 688               }
 689               while (0);
 690           
 691               if (status != 0)
 692               {
 693                   Log(LL_WARNING, "Basic authentication failed for username %s",
 694                       request.username);
 695               }
 696               else
 697               {
 698                   Log(LL_TRACE, "Basic authentication succeeded for username %s",
 699                       request.username);
 700               }
 701           
 702               /* Send response message. */
 703           
 704 kumpf 1.2     response.status = status;
 705           
 706 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 707 kumpf 1.2 }
 708           
 709           /*
 710           **==============================================================================
 711           **
 712           ** HandleValidateUserRequest()
 713           **
 714           **==============================================================================
 715           */
 716           
 717           static void HandleValidateUserRequest(int sock)
 718           {
 719               int status;
 720               struct ExecutorValidateUserResponse response;
 721               struct ExecutorValidateUserRequest request;
 722           
 723               memset(&response, 0, sizeof(response));
 724           
 725               /* Read the request message. */
 726           
 727 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 728 kumpf 1.2 
 729               /* Validate the user. */
 730           
 731               Log(LL_TRACE,
 732                   "HandleValidateUserRequest(): username=%s", request.username);
 733           
 734               /* Get the uid for the username. */
 735           
 736               status = 0;
 737           
 738           #if defined(PEGASUS_PAM_AUTHENTICATION)
 739           
 740               if (PAMValidateUser(request.username) != 0)
 741                   status = -1;
 742           
 743           #else /* !PEGASUS_PAM_AUTHENTICATION */
 744           
 745               do
 746               {
 747                   const char* path = FindMacro("passwordFilePath");
 748           
 749 kumpf 1.2         if (!path)
 750                   {
 751                       status = -1;
 752                       break;
 753                   }
 754           
 755                   if (CheckPasswordFile(path, request.username, NULL) != 0)
 756                   {
 757                       status = -1;
 758                       break;
 759                   }
 760               }
 761               while (0);
 762           
 763           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 764           
 765               if (status != 0)
 766                   Log(LL_WARNING, "User validation failed on %s", request.username);
 767           
 768               /* Send response message. */
 769           
 770 kumpf 1.2     response.status = status;
 771           
 772 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 773 kumpf 1.2 }
 774           
 775           /*
 776           **==============================================================================
 777           **
 778           ** HandleChallengeLocalRequest()
 779           **
 780           **==============================================================================
 781           */
 782           
 783           static void HandleChallengeLocalRequest(int sock)
 784           {
 785               char challenge[EXECUTOR_BUFFER_SIZE];
 786               struct ExecutorChallengeLocalRequest request;
 787               struct ExecutorChallengeLocalResponse response;
 788           
 789               memset(&response, 0, sizeof(response));
 790           
 791               /* Read the request message. */
 792           
 793 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 794 kumpf 1.2 
 795               Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
 796           
 797               /* Perform operation. */
 798           
 799 kumpf 1.4     response.status = StartLocalAuthentication(request.user, challenge);
 800 kumpf 1.2 
 801 kumpf 1.4     /* Send response message. */
 802           
 803               if (response.status != 0)
 804 kumpf 1.2     {
 805                   Log(LL_WARNING, "Local authentication failed for user \"%s\"",
 806                       request.user);
 807               }
 808 kumpf 1.4     else
 809               {
 810 kumpf 1.2         Strlcpy(response.challenge, challenge, sizeof(response.challenge));
 811 kumpf 1.4     }
 812 kumpf 1.2 
 813 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 814 kumpf 1.2 }
 815           
 816           /*
 817           **==============================================================================
 818           **
 819           ** HandleAuthenticateLocalRequest()
 820           **
 821           **==============================================================================
 822           */
 823           
 824           static void HandleAuthenticateLocalRequest(int sock)
 825           {
 826               int status;
 827               struct ExecutorAuthenticateLocalRequest request;
 828               struct ExecutorAuthenticateLocalResponse response;
 829           
 830               memset(&response, 0, sizeof(response));
 831           
 832               /* Read the request message. */
 833           
 834 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 835 kumpf 1.2 
 836               Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
 837           
 838               /* Perform operation. */
 839           
 840               status = FinishLocalAuthentication(request.challenge, request.response);
 841           
 842               /* Log result. */
 843           
 844               if (status != 0)
 845               {
 846                   Log(LL_WARNING, "Local authentication failed");
 847               }
 848           
 849               /* Send response. */
 850           
 851               response.status = status;
 852           
 853 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 854 kumpf 1.2 }
 855           
 856           /*
 857           **==============================================================================
 858           **
 859 kumpf 1.5 ** HandleUpdateLogLevelRequest()
 860           **
 861           **==============================================================================
 862           */
 863           
 864           static void HandleUpdateLogLevelRequest(int sock)
 865           {
 866               int status;
 867               struct ExecutorUpdateLogLevelRequest request;
 868               struct ExecutorUpdateLogLevelResponse response;
 869           
 870               memset(&response, 0, sizeof(response));
 871           
 872               /* Read the request message. */
 873           
 874               ReadExecutorRequest(sock, &request, sizeof(request));
 875           
 876               /* Log request. */
 877           
 878               Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
 879                   request.logLevel);
 880 kumpf 1.5 
 881               /* Perform operation. */
 882           
 883               status = SetLogLevel(request.logLevel);
 884           
 885               if (status == -1)
 886                   Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
 887           
 888               /* Send response message. */
 889           
 890               response.status = status;
 891           
 892               WriteExecutorResponse(sock, &response, sizeof(response));
 893           }
 894           
 895           /*
 896           **==============================================================================
 897           **
 898 kumpf 1.2 ** Parent()
 899           **
 900           **     The parent process (cimserver).
 901           **
 902           **==============================================================================
 903           */
 904           
 905           void Parent(int sock, int childPid, int bindVerbose)
 906           {
 907               /* Handle Ctrl-C. */
 908           
 909               signal(SIGINT, _sigHandler);
 910           
 911               /* Catch SIGTERM, sent by kill program. */
 912           
 913               signal(SIGTERM, _sigHandler);
 914           
 915               /*
 916                * Ignore SIGPIPE, which occurs if a child with whom the executor shares
 917                * a local domain socket unexpectedly dies. In such a case, the socket
 918                * read/write functions will return an error. There are two child processes
 919 kumpf 1.2      * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
 920                */
 921           
 922               signal(SIGPIPE, SIG_IGN);
 923           
 924               /* Save child PID globally; it is used by Exit() function. */
 925           
 926               globals.childPid = childPid;
 927           
 928               /* Prepares socket into non-blocking I/O. */
 929           
 930               SetNonBlocking(sock);
 931           
 932               /* Process client requests until client exists. */
 933           
 934               for (;;)
 935               {
 936                   size_t n;
 937                   struct ExecutorRequestHeader header;
 938           
 939                   /* Receive request header. */
 940 kumpf 1.2 
 941                   n = RecvNonBlock(sock, &header, sizeof(header));
 942           
 943                   if (n == 0)
 944                   {
 945                       /*
 946                        * Either client closed its end of the pipe (possibly by exiting)
 947                        * or we caught a SIGTERM.
 948                        */
 949                       break;
 950                   }
 951           
 952                   if (n != sizeof(header))
 953                       Fatal(FL, "Failed to read header");
 954           
 955                   /* Dispatch request. */
 956           
 957                   switch ((enum ExecutorMessageCode)header.code)
 958                   {
 959                       case EXECUTOR_PING_MESSAGE:
 960                           HandlePingRequest(sock);
 961 kumpf 1.2                 break;
 962           
 963                       case EXECUTOR_OPEN_FILE_MESSAGE:
 964                           HandleOpenFileRequest(sock);
 965                           break;
 966           
 967                       case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
 968                           HandleStartProviderAgentRequest(sock);
 969                           break;
 970           
 971                       case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
 972                           HandleDaemonizeExecutorRequest(sock, bindVerbose);
 973                           break;
 974           
 975                       case EXECUTOR_RENAME_FILE_MESSAGE:
 976                           HandleRenameFileRequest(sock);
 977                           break;
 978           
 979                       case EXECUTOR_REMOVE_FILE_MESSAGE:
 980                           HandleRemoveFileRequest(sock);
 981                           break;
 982 kumpf 1.2 
 983                       case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
 984                           HandleAuthenticatePasswordRequest(sock);
 985                           break;
 986           
 987                       case EXECUTOR_VALIDATE_USER_MESSAGE:
 988                           HandleValidateUserRequest(sock);
 989                           break;
 990           
 991                       case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
 992                           HandleChallengeLocalRequest(sock);
 993                           break;
 994           
 995                       case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
 996                           HandleAuthenticateLocalRequest(sock);
 997                           break;
 998           
 999 kumpf 1.5             case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
1000                           HandleUpdateLogLevelRequest(sock);
1001                           break;
1002           
1003 kumpf 1.2             default:
1004                           Fatal(FL, "Invalid request code: %d", header.code);
1005                           break;
1006                   }
1007               }
1008           
1009               /* Reached due to socket EOF, SIGTERM, or SIGINT. */
1010           
1011               Exit(0);
1012           }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2