(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               if (!bindVerbose)
 493               {
 494                   /* Close these file descriptors (stdin, stdout, stderr). */
 495           
 496 kumpf 1.2         close(0);
 497                   close(1);
 498                   close(2);
 499           
 500                   /* Direct standard input, output, and error to /dev/null: */
 501           
 502                   open("/dev/null", O_RDONLY);
 503                   open("/dev/null", O_RDWR);
 504                   open("/dev/null", O_RDWR);
 505               }
 506           
 507               response.status = 0;
 508           
 509 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 510 kumpf 1.2 }
 511           
 512           /*
 513           **==============================================================================
 514           **
 515           ** HandleRenameFileRequest()
 516           **
 517           **==============================================================================
 518           */
 519           
 520           static void HandleRenameFileRequest(int sock)
 521           {
 522               struct ExecutorRenameFileResponse response;
 523               struct ExecutorRenameFileRequest request;
 524           
 525               memset(&response, 0, sizeof(response));
 526           
 527               /* Read the request message. */
 528           
 529 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 530 kumpf 1.2 
 531               /* Log request. */
 532           
 533               Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
 534                   request.oldPath, request.newPath);
 535           
 536               /* Perform the operation: */
 537           
 538               response.status = 0;
 539           
 540               do
 541               {
 542                   /* Check the policy. */
 543           
 544                   if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
 545                   {
 546                       response.status = -1;
 547                       break;
 548                   }
 549           
 550                   /* Rename the file. */
 551 kumpf 1.2 
 552                   if (rename(request.oldPath, request.newPath) != 0)
 553                   {
 554                       response.status = -1;
 555                       break;
 556                   }
 557               }
 558               while (0);
 559           
 560               /* Send response message. */
 561           
 562 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 563 kumpf 1.2 }
 564           
 565           /*
 566           **==============================================================================
 567           **
 568           ** HandleRemoveFileRequest()
 569           **
 570           **==============================================================================
 571           */
 572           
 573           static void HandleRemoveFileRequest(int sock)
 574           {
 575               struct ExecutorRemoveFileRequest request;
 576               struct ExecutorRemoveFileResponse response;
 577           
 578               memset(&response, 0, sizeof(response));
 579           
 580               /* Read the request message. */
 581           
 582 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 583 kumpf 1.2 
 584               /* Log request. */
 585           
 586               Log(LL_TRACE, "HandleRemoveFileRequest(): path=%s", request.path);
 587           
 588               response.status = 0;
 589           
 590               do
 591               {
 592                   /* Check the policy. */
 593           
 594                   if (CheckRemoveFilePolicy(request.path) != 0)
 595                   {
 596                       response.status = -1;
 597                       break;
 598                   }
 599           
 600                   /* Remove the file. */
 601           
 602                   if (unlink(request.path) != 0)
 603                   {
 604 kumpf 1.2             response.status = -1;
 605                       Log(LL_WARNING, "unlink(%s) failed", request.path);
 606                       break;
 607                   }
 608               }
 609               while (0);
 610           
 611               /* Send response message. */
 612           
 613 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 614 kumpf 1.2 }
 615           
 616           /*
 617           **==============================================================================
 618           **
 619           ** HandleAuthenticatePasswordRequest()
 620           **
 621           **==============================================================================
 622           */
 623           
 624           static void HandleAuthenticatePasswordRequest(int sock)
 625           {
 626               int status;
 627               struct ExecutorAuthenticatePasswordRequest request;
 628               struct ExecutorAuthenticatePasswordResponse response;
 629               int gid;
 630               int uid;
 631           
 632               memset(&response, 0, sizeof(response));
 633           
 634               /* Read the request message. */
 635 kumpf 1.2 
 636 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 637 kumpf 1.2 
 638               /* Log request. */
 639           
 640               Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
 641                   request.username);
 642           
 643               /* Perform the operation: */
 644           
 645               status = 0;
 646           
 647               do
 648               {
 649                   if (GetUserInfo(request.username, &uid, &gid) != 0)
 650                   {
 651                       status = -1;
 652                       break;
 653                   }
 654           
 655           #if defined(PEGASUS_PAM_AUTHENTICATION)
 656           
 657                   if (PAMAuthenticate(request.username, request.password) != 0)
 658 kumpf 1.2         {
 659                       status = -1;
 660                       break;
 661                   }
 662           
 663           
 664           #else /* !PEGASUS_PAM_AUTHENTICATION */
 665           
 666                   {
 667                       const char* path = FindMacro("passwordFilePath");
 668           
 669                       if (!path)
 670                       {
 671                           status = -1;
 672                           break;
 673                       }
 674           
 675                       if (CheckPasswordFile(
 676                           path, request.username, request.password) != 0)
 677                       {
 678                           status = -1;
 679 kumpf 1.2                 break;
 680                       }
 681                   }
 682           
 683           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 684               }
 685               while (0);
 686           
 687               if (status != 0)
 688               {
 689                   Log(LL_WARNING, "Basic authentication failed for username %s",
 690                       request.username);
 691               }
 692               else
 693               {
 694                   Log(LL_TRACE, "Basic authentication succeeded for username %s",
 695                       request.username);
 696               }
 697           
 698               /* Send response message. */
 699           
 700 kumpf 1.2     response.status = status;
 701           
 702 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 703 kumpf 1.2 }
 704           
 705           /*
 706           **==============================================================================
 707           **
 708           ** HandleValidateUserRequest()
 709           **
 710           **==============================================================================
 711           */
 712           
 713           static void HandleValidateUserRequest(int sock)
 714           {
 715               int status;
 716               struct ExecutorValidateUserResponse response;
 717               struct ExecutorValidateUserRequest request;
 718           
 719               memset(&response, 0, sizeof(response));
 720           
 721               /* Read the request message. */
 722           
 723 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 724 kumpf 1.2 
 725               /* Validate the user. */
 726           
 727               Log(LL_TRACE,
 728                   "HandleValidateUserRequest(): username=%s", request.username);
 729           
 730               /* Get the uid for the username. */
 731           
 732               status = 0;
 733           
 734           #if defined(PEGASUS_PAM_AUTHENTICATION)
 735           
 736               if (PAMValidateUser(request.username) != 0)
 737                   status = -1;
 738           
 739           #else /* !PEGASUS_PAM_AUTHENTICATION */
 740           
 741               do
 742               {
 743                   const char* path = FindMacro("passwordFilePath");
 744           
 745 kumpf 1.2         if (!path)
 746                   {
 747                       status = -1;
 748                       break;
 749                   }
 750           
 751                   if (CheckPasswordFile(path, request.username, NULL) != 0)
 752                   {
 753                       status = -1;
 754                       break;
 755                   }
 756               }
 757               while (0);
 758           
 759           #endif /* !PEGASUS_PAM_AUTHENTICATION */
 760           
 761               if (status != 0)
 762                   Log(LL_WARNING, "User validation failed on %s", request.username);
 763           
 764               /* Send response message. */
 765           
 766 kumpf 1.2     response.status = status;
 767           
 768 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 769 kumpf 1.2 }
 770           
 771           /*
 772           **==============================================================================
 773           **
 774           ** HandleChallengeLocalRequest()
 775           **
 776           **==============================================================================
 777           */
 778           
 779           static void HandleChallengeLocalRequest(int sock)
 780           {
 781               char challenge[EXECUTOR_BUFFER_SIZE];
 782               struct ExecutorChallengeLocalRequest request;
 783               struct ExecutorChallengeLocalResponse response;
 784           
 785               memset(&response, 0, sizeof(response));
 786           
 787               /* Read the request message. */
 788           
 789 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 790 kumpf 1.2 
 791               Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
 792           
 793               /* Perform operation. */
 794           
 795 kumpf 1.4     response.status = StartLocalAuthentication(request.user, challenge);
 796 kumpf 1.2 
 797 kumpf 1.4     /* Send response message. */
 798           
 799               if (response.status != 0)
 800 kumpf 1.2     {
 801                   Log(LL_WARNING, "Local authentication failed for user \"%s\"",
 802                       request.user);
 803               }
 804 kumpf 1.4     else
 805               {
 806 kumpf 1.2         Strlcpy(response.challenge, challenge, sizeof(response.challenge));
 807 kumpf 1.4     }
 808 kumpf 1.2 
 809 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 810 kumpf 1.2 }
 811           
 812           /*
 813           **==============================================================================
 814           **
 815           ** HandleAuthenticateLocalRequest()
 816           **
 817           **==============================================================================
 818           */
 819           
 820           static void HandleAuthenticateLocalRequest(int sock)
 821           {
 822               int status;
 823               struct ExecutorAuthenticateLocalRequest request;
 824               struct ExecutorAuthenticateLocalResponse response;
 825           
 826               memset(&response, 0, sizeof(response));
 827           
 828               /* Read the request message. */
 829           
 830 kumpf 1.4     ReadExecutorRequest(sock, &request, sizeof(request));
 831 kumpf 1.2 
 832               Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
 833           
 834               /* Perform operation. */
 835           
 836               status = FinishLocalAuthentication(request.challenge, request.response);
 837           
 838               /* Log result. */
 839           
 840               if (status != 0)
 841               {
 842                   Log(LL_WARNING, "Local authentication failed");
 843               }
 844           
 845               /* Send response. */
 846           
 847               response.status = status;
 848           
 849 kumpf 1.4     WriteExecutorResponse(sock, &response, sizeof(response));
 850 kumpf 1.2 }
 851           
 852           /*
 853           **==============================================================================
 854           **
 855 kumpf 1.5 ** HandleUpdateLogLevelRequest()
 856           **
 857           **==============================================================================
 858           */
 859           
 860           static void HandleUpdateLogLevelRequest(int sock)
 861           {
 862               int status;
 863               struct ExecutorUpdateLogLevelRequest request;
 864               struct ExecutorUpdateLogLevelResponse response;
 865           
 866               memset(&response, 0, sizeof(response));
 867           
 868               /* Read the request message. */
 869           
 870               ReadExecutorRequest(sock, &request, sizeof(request));
 871           
 872               /* Log request. */
 873           
 874               Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
 875                   request.logLevel);
 876 kumpf 1.5 
 877               /* Perform operation. */
 878           
 879               status = SetLogLevel(request.logLevel);
 880           
 881               if (status == -1)
 882                   Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
 883           
 884               /* Send response message. */
 885           
 886               response.status = status;
 887           
 888               WriteExecutorResponse(sock, &response, sizeof(response));
 889           }
 890           
 891           /*
 892           **==============================================================================
 893           **
 894 kumpf 1.2 ** Parent()
 895           **
 896           **     The parent process (cimserver).
 897           **
 898           **==============================================================================
 899           */
 900           
 901           void Parent(int sock, int childPid, int bindVerbose)
 902           {
 903               /* Handle Ctrl-C. */
 904           
 905               signal(SIGINT, _sigHandler);
 906           
 907               /* Catch SIGTERM, sent by kill program. */
 908           
 909               signal(SIGTERM, _sigHandler);
 910           
 911               /*
 912                * Ignore SIGPIPE, which occurs if a child with whom the executor shares
 913                * a local domain socket unexpectedly dies. In such a case, the socket
 914                * read/write functions will return an error. There are two child processes
 915 kumpf 1.2      * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
 916                */
 917           
 918               signal(SIGPIPE, SIG_IGN);
 919           
 920               /* Save child PID globally; it is used by Exit() function. */
 921           
 922               globals.childPid = childPid;
 923           
 924               /* Prepares socket into non-blocking I/O. */
 925           
 926               SetNonBlocking(sock);
 927           
 928               /* Process client requests until client exists. */
 929           
 930               for (;;)
 931               {
 932                   size_t n;
 933                   struct ExecutorRequestHeader header;
 934           
 935                   /* Receive request header. */
 936 kumpf 1.2 
 937                   n = RecvNonBlock(sock, &header, sizeof(header));
 938           
 939                   if (n == 0)
 940                   {
 941                       /*
 942                        * Either client closed its end of the pipe (possibly by exiting)
 943                        * or we caught a SIGTERM.
 944                        */
 945                       break;
 946                   }
 947           
 948                   if (n != sizeof(header))
 949                       Fatal(FL, "Failed to read header");
 950           
 951                   /* Dispatch request. */
 952           
 953                   switch ((enum ExecutorMessageCode)header.code)
 954                   {
 955                       case EXECUTOR_PING_MESSAGE:
 956                           HandlePingRequest(sock);
 957 kumpf 1.2                 break;
 958           
 959                       case EXECUTOR_OPEN_FILE_MESSAGE:
 960                           HandleOpenFileRequest(sock);
 961                           break;
 962           
 963                       case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
 964                           HandleStartProviderAgentRequest(sock);
 965                           break;
 966           
 967                       case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
 968                           HandleDaemonizeExecutorRequest(sock, bindVerbose);
 969                           break;
 970           
 971                       case EXECUTOR_RENAME_FILE_MESSAGE:
 972                           HandleRenameFileRequest(sock);
 973                           break;
 974           
 975                       case EXECUTOR_REMOVE_FILE_MESSAGE:
 976                           HandleRemoveFileRequest(sock);
 977                           break;
 978 kumpf 1.2 
 979                       case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
 980                           HandleAuthenticatePasswordRequest(sock);
 981                           break;
 982           
 983                       case EXECUTOR_VALIDATE_USER_MESSAGE:
 984                           HandleValidateUserRequest(sock);
 985                           break;
 986           
 987                       case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
 988                           HandleChallengeLocalRequest(sock);
 989                           break;
 990           
 991                       case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
 992                           HandleAuthenticateLocalRequest(sock);
 993                           break;
 994           
 995 kumpf 1.5             case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
 996                           HandleUpdateLogLevelRequest(sock);
 997                           break;
 998           
 999 kumpf 1.2             default:
1000                           Fatal(FL, "Invalid request code: %d", header.code);
1001                           break;
1002                   }
1003               }
1004           
1005               /* Reached due to socket EOF, SIGTERM, or SIGINT. */
1006           
1007               Exit(0);
1008           }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2