(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 sushma.fernandes 1.9     Log(LL_TRACE, "Basic authentication attempt: username = %s, "
688                              "successful = %s", 
689                              request.username, status == 0 ? "TRUE" : "FALSE" );
690 kumpf            1.2 
691                          /* Send response message. */
692                      
693                          response.status = status;
694                      
695 kumpf            1.4     WriteExecutorResponse(sock, &response, sizeof(response));
696 kumpf            1.2 }
697                      
698                      /*
699                      **==============================================================================
700                      **
701                      ** HandleValidateUserRequest()
702                      **
703                      **==============================================================================
704                      */
705                      
706                      static void HandleValidateUserRequest(int sock)
707                      {
708                          int status;
709                          struct ExecutorValidateUserResponse response;
710                          struct ExecutorValidateUserRequest request;
711                      
712                          memset(&response, 0, sizeof(response));
713                      
714                          /* Read the request message. */
715                      
716 kumpf            1.4     ReadExecutorRequest(sock, &request, sizeof(request));
717 kumpf            1.2 
718                          /* Validate the user. */
719                      
720                          Log(LL_TRACE,
721                              "HandleValidateUserRequest(): username=%s", request.username);
722                      
723                          /* Get the uid for the username. */
724                      
725                          status = 0;
726                      
727                      #if defined(PEGASUS_PAM_AUTHENTICATION)
728                      
729                          if (PAMValidateUser(request.username) != 0)
730                              status = -1;
731                      
732                      #else /* !PEGASUS_PAM_AUTHENTICATION */
733                      
734                          do
735                          {
736                              const char* path = FindMacro("passwordFilePath");
737                      
738 kumpf            1.2         if (!path)
739                              {
740                                  status = -1;
741                                  break;
742                              }
743                      
744                              if (CheckPasswordFile(path, request.username, NULL) != 0)
745                              {
746                                  status = -1;
747                                  break;
748                              }
749                          }
750                          while (0);
751                      
752                      #endif /* !PEGASUS_PAM_AUTHENTICATION */
753                      
754                          /* Send response message. */
755                      
756                          response.status = status;
757                      
758 kumpf            1.4     WriteExecutorResponse(sock, &response, sizeof(response));
759 kumpf            1.2 }
760                      
761                      /*
762                      **==============================================================================
763                      **
764                      ** HandleChallengeLocalRequest()
765                      **
766                      **==============================================================================
767                      */
768                      
769                      static void HandleChallengeLocalRequest(int sock)
770                      {
771                          char challenge[EXECUTOR_BUFFER_SIZE];
772                          struct ExecutorChallengeLocalRequest request;
773                          struct ExecutorChallengeLocalResponse response;
774                      
775                          memset(&response, 0, sizeof(response));
776                      
777                          /* Read the request message. */
778                      
779 kumpf            1.4     ReadExecutorRequest(sock, &request, sizeof(request));
780 kumpf            1.2 
781                          Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
782                      
783                          /* Perform operation. */
784                      
785 kumpf            1.4     response.status = StartLocalAuthentication(request.user, challenge);
786 kumpf            1.2 
787 kumpf            1.4     /* Send response message. */
788                      
789 sushma.fernandes 1.9     if (response.status == 0)
790 kumpf            1.4     {
791 kumpf            1.2         Strlcpy(response.challenge, challenge, sizeof(response.challenge));
792 kumpf            1.4     }
793 kumpf            1.2 
794 kumpf            1.4     WriteExecutorResponse(sock, &response, sizeof(response));
795 kumpf            1.2 }
796                      
797                      /*
798                      **==============================================================================
799                      **
800                      ** HandleAuthenticateLocalRequest()
801                      **
802                      **==============================================================================
803                      */
804                      
805                      static void HandleAuthenticateLocalRequest(int sock)
806                      {
807                          int status;
808                          struct ExecutorAuthenticateLocalRequest request;
809                          struct ExecutorAuthenticateLocalResponse response;
810                      
811                          memset(&response, 0, sizeof(response));
812                      
813                          /* Read the request message. */
814                      
815 kumpf            1.4     ReadExecutorRequest(sock, &request, sizeof(request));
816 kumpf            1.2 
817                          Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
818                      
819                          /* Perform operation. */
820                      
821                          status = FinishLocalAuthentication(request.challenge, request.response);
822                      
823                          /* Send response. */
824                      
825                          response.status = status;
826                      
827 kumpf            1.4     WriteExecutorResponse(sock, &response, sizeof(response));
828 kumpf            1.2 }
829                      
830                      /*
831                      **==============================================================================
832                      **
833 kumpf            1.5 ** HandleUpdateLogLevelRequest()
834                      **
835                      **==============================================================================
836                      */
837                      
838                      static void HandleUpdateLogLevelRequest(int sock)
839                      {
840                          int status;
841                          struct ExecutorUpdateLogLevelRequest request;
842                          struct ExecutorUpdateLogLevelResponse response;
843                      
844                          memset(&response, 0, sizeof(response));
845                      
846                          /* Read the request message. */
847                      
848                          ReadExecutorRequest(sock, &request, sizeof(request));
849                      
850                          /* Log request. */
851                      
852                          Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
853                              request.logLevel);
854 kumpf            1.5 
855                          /* Perform operation. */
856                      
857                          status = SetLogLevel(request.logLevel);
858                      
859                          if (status == -1)
860                              Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
861                      
862                          /* Send response message. */
863                      
864                          response.status = status;
865                      
866                          WriteExecutorResponse(sock, &response, sizeof(response));
867                      }
868                      
869                      /*
870                      **==============================================================================
871                      **
872 kumpf            1.2 ** Parent()
873                      **
874                      **     The parent process (cimserver).
875                      **
876                      **==============================================================================
877                      */
878                      
879                      void Parent(int sock, int childPid, int bindVerbose)
880                      {
881                          /* Handle Ctrl-C. */
882                      
883                          signal(SIGINT, _sigHandler);
884                      
885                          /* Catch SIGTERM, sent by kill program. */
886                      
887                          signal(SIGTERM, _sigHandler);
888                      
889                          /*
890                           * Ignore SIGPIPE, which occurs if a child with whom the executor shares
891                           * a local domain socket unexpectedly dies. In such a case, the socket
892                           * read/write functions will return an error. There are two child processes
893 kumpf            1.2      * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
894                           */
895                      
896                          signal(SIGPIPE, SIG_IGN);
897                      
898                          /* Save child PID globally; it is used by Exit() function. */
899                      
900                          globals.childPid = childPid;
901                      
902                          /* Prepares socket into non-blocking I/O. */
903                      
904                          SetNonBlocking(sock);
905                      
906                          /* Process client requests until client exists. */
907                      
908                          for (;;)
909                          {
910                              size_t n;
911                              struct ExecutorRequestHeader header;
912                      
913                              /* Receive request header. */
914 kumpf            1.2 
915                              n = RecvNonBlock(sock, &header, sizeof(header));
916                      
917                              if (n == 0)
918                              {
919                                  /*
920                                   * Either client closed its end of the pipe (possibly by exiting)
921                                   * or we caught a SIGTERM.
922                                   */
923                                  break;
924                              }
925                      
926                              if (n != sizeof(header))
927                                  Fatal(FL, "Failed to read header");
928                      
929                              /* Dispatch request. */
930                      
931                              switch ((enum ExecutorMessageCode)header.code)
932                              {
933                                  case EXECUTOR_PING_MESSAGE:
934                                      HandlePingRequest(sock);
935 kumpf            1.2                 break;
936                      
937                                  case EXECUTOR_OPEN_FILE_MESSAGE:
938                                      HandleOpenFileRequest(sock);
939                                      break;
940                      
941                                  case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
942                                      HandleStartProviderAgentRequest(sock);
943                                      break;
944                      
945                                  case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
946                                      HandleDaemonizeExecutorRequest(sock, bindVerbose);
947                                      break;
948                      
949                                  case EXECUTOR_RENAME_FILE_MESSAGE:
950                                      HandleRenameFileRequest(sock);
951                                      break;
952                      
953                                  case EXECUTOR_REMOVE_FILE_MESSAGE:
954                                      HandleRemoveFileRequest(sock);
955                                      break;
956 kumpf            1.2 
957                                  case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
958                                      HandleAuthenticatePasswordRequest(sock);
959                                      break;
960                      
961                                  case EXECUTOR_VALIDATE_USER_MESSAGE:
962                                      HandleValidateUserRequest(sock);
963                                      break;
964                      
965                                  case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
966                                      HandleChallengeLocalRequest(sock);
967                                      break;
968                      
969                                  case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
970                                      HandleAuthenticateLocalRequest(sock);
971                                      break;
972                      
973 kumpf            1.5             case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
974                                      HandleUpdateLogLevelRequest(sock);
975                                      break;
976                      
977 kumpf            1.2             default:
978                                      Fatal(FL, "Invalid request code: %d", header.code);
979                                      break;
980                              }
981                          }
982                      
983                          /* Reached due to socket EOF, SIGTERM, or SIGINT. */
984                      
985                          Exit(0);
986                      }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2