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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2