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 globals.signalMask |= (1 << signum);
77 }
78
79 /*
80 kumpf 1.2 **==============================================================================
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 kumpf 1.11 char toPipeArg[32];
327 char fromPipeArg[32];
328 /* The user context is set here; no need to do it in cimprovagt. */
329 const char* setUserContextFlag = "0";
|
330 kumpf 1.2
331 /* Close unused pipe descriptors: */
332
333 close(to[1]);
334 close(from[0]);
335
|
336 kumpf 1.10 /* Redirect terminal I/O if required and not yet daemonized. */
337
338 if (globals.initCompletePipe != -1 && !globals.bindVerbose)
339 {
340 RedirectTerminalIO();
341 }
342
|
343 kumpf 1.2 /*
344 * Close unused descriptors. Leave stdin, stdout, stderr, and the
345 * child's pipe descriptors open.
346 */
347
|
348 kumpf 1.10 CloseUnusedDescriptors(to[0], from[1]);
|
349 kumpf 1.2
|
350 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
351
|
352 kumpf 1.10 SetUserContext(request.userName, uid, gid);
|
353 kumpf 1.2
354 Log(LL_TRACE, "starting %s on module %s as user %s",
|
355 kumpf 1.3 path, request.module, request.userName);
|
356 kumpf 1.2
|
357 kumpf 1.3 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
|
358 kumpf 1.2
359 /* Exec the CIMPROVAGT program. */
360
|
361 kumpf 1.11 sprintf(toPipeArg, "%d", to[0]);
362 sprintf(fromPipeArg, "%d", from[1]);
|
363 kumpf 1.2
|
364 kumpf 1.11 Log(LL_TRACE, "execl(%s, %s, %s, %s, %s, %s, %s)\n",
365 path,
366 path,
367 setUserContextFlag,
368 toPipeArg,
369 fromPipeArg,
370 request.userName,
371 request.module);
|
372 kumpf 1.2
373 /* Flawfinder: ignore */
|
374 kumpf 1.11 execl(
375 path,
376 path,
377 setUserContextFlag,
378 toPipeArg,
379 fromPipeArg,
380 request.userName,
381 request.module,
382 (char*)0);
383
384 Log(LL_SEVERE, "execl(%s, %s, %s, %s, %s, %s, %s): failed\n",
385 path,
386 path,
387 setUserContextFlag,
388 toPipeArg,
389 fromPipeArg,
390 request.userName,
391 request.module);
|
392 kumpf 1.5 _exit(1);
|
393 kumpf 1.2 }
394 }
395 while (0);
396
397 /* Close unused pipe descriptors. */
398
399 close(to[0]);
400 close(from[1]);
401
402 /* Send response. */
403
404 response.status = status;
405 response.pid = pid;
406
|
407 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
408 kumpf 1.2
409 /* Send descriptors to calling process. */
410
411 if (response.status == 0)
412 {
413 int descriptors[2];
414 descriptors[0] = from[0];
415 descriptors[1] = to[1];
416
417 SendDescriptorArray(sock, descriptors, 2);
418 close(from[0]);
419 close(to[1]);
420 }
421 }
422
423 /*
424 **==============================================================================
425 **
426 ** HandleDaemonizeExecutorRequest()
427 **
428 **==============================================================================
429 kumpf 1.2 */
430
|
431 kumpf 1.10 static void HandleDaemonizeExecutorRequest(int sock)
|
432 kumpf 1.2 {
433 struct ExecutorDaemonizeExecutorResponse response;
434 int pid;
435
436 memset(&response, 0, sizeof(response));
437
438 Log(LL_TRACE, "HandleDaemonizeExecutorRequest()");
439
|
440 kumpf 1.10 if (!globals.bindVerbose)
|
441 kumpf 1.2 {
|
442 kumpf 1.10 RedirectTerminalIO();
|
443 kumpf 1.2 }
444
|
445 kumpf 1.10 if (globals.initCompletePipe != -1)
|
446 kumpf 1.2 {
|
447 kumpf 1.10 ssize_t result;
|
448 kumpf 1.2
|
449 kumpf 1.10 EXECUTOR_RESTART(write(globals.initCompletePipe, "\0", 1), result);
450 close(globals.initCompletePipe);
451 globals.initCompletePipe = -1;
|
452 kumpf 1.2 }
453
454 response.status = 0;
455
|
456 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
457 kumpf 1.2 }
458
459 /*
460 **==============================================================================
461 **
462 ** HandleRenameFileRequest()
463 **
464 **==============================================================================
465 */
466
467 static void HandleRenameFileRequest(int sock)
468 {
469 struct ExecutorRenameFileResponse response;
470 struct ExecutorRenameFileRequest request;
471
472 memset(&response, 0, sizeof(response));
473
474 /* Read the request message. */
475
|
476 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
477 kumpf 1.2
478 /* Log request. */
479
480 Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
481 request.oldPath, request.newPath);
482
483 /* Perform the operation: */
484
485 response.status = 0;
486
487 do
488 {
489 /* Check the policy. */
490
491 if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
492 {
493 response.status = -1;
494 break;
495 }
496
497 /* Rename the file. */
498 kumpf 1.2
499 if (rename(request.oldPath, request.newPath) != 0)
500 {
501 response.status = -1;
502 break;
503 }
504 }
505 while (0);
506
507 /* Send response message. */
508
|
509 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
510 kumpf 1.2 }
511
512 /*
513 **==============================================================================
514 **
515 ** HandleRemoveFileRequest()
516 **
517 **==============================================================================
518 */
519
520 static void HandleRemoveFileRequest(int sock)
521 {
522 struct ExecutorRemoveFileRequest request;
523 struct ExecutorRemoveFileResponse response;
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, "HandleRemoveFileRequest(): path=%s", request.path);
534
535 response.status = 0;
536
537 do
538 {
539 /* Check the policy. */
540
541 if (CheckRemoveFilePolicy(request.path) != 0)
542 {
543 response.status = -1;
544 break;
545 }
546
547 /* Remove the file. */
548
549 if (unlink(request.path) != 0)
550 {
551 kumpf 1.2 response.status = -1;
552 Log(LL_WARNING, "unlink(%s) failed", request.path);
553 break;
554 }
555 }
556 while (0);
557
558 /* Send response message. */
559
|
560 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
561 kumpf 1.2 }
562
563 /*
564 **==============================================================================
565 **
566 ** HandleAuthenticatePasswordRequest()
567 **
568 **==============================================================================
569 */
570
571 static void HandleAuthenticatePasswordRequest(int sock)
572 {
573 int status;
574 struct ExecutorAuthenticatePasswordRequest request;
575 struct ExecutorAuthenticatePasswordResponse response;
576 int gid;
577 int uid;
578
579 memset(&response, 0, sizeof(response));
580
581 /* Read the request message. */
582 kumpf 1.2
|
583 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
584 kumpf 1.2
585 /* Log request. */
586
587 Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
588 request.username);
589
590 /* Perform the operation: */
591
592 status = 0;
593
594 do
595 {
596 if (GetUserInfo(request.username, &uid, &gid) != 0)
597 {
598 status = -1;
599 break;
600 }
601
602 #if defined(PEGASUS_PAM_AUTHENTICATION)
603
604 if (PAMAuthenticate(request.username, request.password) != 0)
605 kumpf 1.2 {
606 status = -1;
607 break;
608 }
609
610
611 #else /* !PEGASUS_PAM_AUTHENTICATION */
612
613 {
614 const char* path = FindMacro("passwordFilePath");
615
616 if (!path)
617 {
618 status = -1;
619 break;
620 }
621
622 if (CheckPasswordFile(
623 path, request.username, request.password) != 0)
624 {
625 status = -1;
626 kumpf 1.2 break;
627 }
628 }
629
630 #endif /* !PEGASUS_PAM_AUTHENTICATION */
631 }
632 while (0);
633
|
634 sushma.fernandes 1.9 Log(LL_TRACE, "Basic authentication attempt: username = %s, "
635 "successful = %s",
636 request.username, status == 0 ? "TRUE" : "FALSE" );
|
637 kumpf 1.2
638 /* Send response message. */
639
640 response.status = status;
641
|
642 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
643 kumpf 1.2 }
644
645 /*
646 **==============================================================================
647 **
648 ** HandleValidateUserRequest()
649 **
650 **==============================================================================
651 */
652
653 static void HandleValidateUserRequest(int sock)
654 {
655 int status;
656 struct ExecutorValidateUserResponse response;
657 struct ExecutorValidateUserRequest request;
658
659 memset(&response, 0, sizeof(response));
660
661 /* Read the request message. */
662
|
663 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
664 kumpf 1.2
665 /* Validate the user. */
666
667 Log(LL_TRACE,
668 "HandleValidateUserRequest(): username=%s", request.username);
669
670 /* Get the uid for the username. */
671
672 status = 0;
673
674 #if defined(PEGASUS_PAM_AUTHENTICATION)
675
676 if (PAMValidateUser(request.username) != 0)
677 status = -1;
678
679 #else /* !PEGASUS_PAM_AUTHENTICATION */
680
681 do
682 {
683 const char* path = FindMacro("passwordFilePath");
684
685 kumpf 1.2 if (!path)
686 {
687 status = -1;
688 break;
689 }
690
691 if (CheckPasswordFile(path, request.username, NULL) != 0)
692 {
693 status = -1;
694 break;
695 }
696 }
697 while (0);
698
699 #endif /* !PEGASUS_PAM_AUTHENTICATION */
700
701 /* Send response message. */
702
703 response.status = status;
704
|
705 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
706 kumpf 1.2 }
707
708 /*
709 **==============================================================================
710 **
711 ** HandleChallengeLocalRequest()
712 **
713 **==============================================================================
714 */
715
716 static void HandleChallengeLocalRequest(int sock)
717 {
718 char challenge[EXECUTOR_BUFFER_SIZE];
719 struct ExecutorChallengeLocalRequest request;
720 struct ExecutorChallengeLocalResponse response;
721
722 memset(&response, 0, sizeof(response));
723
724 /* Read the request message. */
725
|
726 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
727 kumpf 1.2
728 Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
729
730 /* Perform operation. */
731
|
732 kumpf 1.4 response.status = StartLocalAuthentication(request.user, challenge);
|
733 kumpf 1.2
|
734 kumpf 1.4 /* Send response message. */
735
|
736 sushma.fernandes 1.9 if (response.status == 0)
|
737 kumpf 1.4 {
|
738 kumpf 1.2 Strlcpy(response.challenge, challenge, sizeof(response.challenge));
|
739 kumpf 1.4 }
|
740 kumpf 1.2
|
741 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
742 kumpf 1.2 }
743
744 /*
745 **==============================================================================
746 **
747 ** HandleAuthenticateLocalRequest()
748 **
749 **==============================================================================
750 */
751
752 static void HandleAuthenticateLocalRequest(int sock)
753 {
754 int status;
755 struct ExecutorAuthenticateLocalRequest request;
756 struct ExecutorAuthenticateLocalResponse response;
757
758 memset(&response, 0, sizeof(response));
759
760 /* Read the request message. */
761
|
762 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
763 kumpf 1.2
764 Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
765
766 /* Perform operation. */
767
768 status = FinishLocalAuthentication(request.challenge, request.response);
769
770 /* Send response. */
771
772 response.status = status;
773
|
774 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
775 kumpf 1.2 }
776
777 /*
778 **==============================================================================
779 **
|
780 kumpf 1.5 ** HandleUpdateLogLevelRequest()
781 **
782 **==============================================================================
783 */
784
785 static void HandleUpdateLogLevelRequest(int sock)
786 {
787 int status;
788 struct ExecutorUpdateLogLevelRequest request;
789 struct ExecutorUpdateLogLevelResponse response;
790
791 memset(&response, 0, sizeof(response));
792
793 /* Read the request message. */
794
795 ReadExecutorRequest(sock, &request, sizeof(request));
796
797 /* Log request. */
798
799 Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
800 request.logLevel);
801 kumpf 1.5
802 /* Perform operation. */
803
804 status = SetLogLevel(request.logLevel);
805
806 if (status == -1)
807 Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
808
809 /* Send response message. */
810
811 response.status = status;
812
813 WriteExecutorResponse(sock, &response, sizeof(response));
814 }
815
816 /*
817 **==============================================================================
818 **
|
819 kumpf 1.2 ** Parent()
820 **
821 ** The parent process (cimserver).
822 **
823 **==============================================================================
824 */
825
|
826 kumpf 1.10 void Parent(int sock, int initCompletePipe, int childPid, int bindVerbose)
|
827 kumpf 1.2 {
828 /* Handle Ctrl-C. */
829
830 signal(SIGINT, _sigHandler);
831
832 /* Catch SIGTERM, sent by kill program. */
833
834 signal(SIGTERM, _sigHandler);
835
836 /*
837 * Ignore SIGPIPE, which occurs if a child with whom the executor shares
838 * a local domain socket unexpectedly dies. In such a case, the socket
839 * read/write functions will return an error. There are two child processes
840 * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
841 */
842
843 signal(SIGPIPE, SIG_IGN);
844
845 /* Save child PID globally; it is used by Exit() function. */
846
847 globals.childPid = childPid;
848 kumpf 1.2
|
849 kumpf 1.10 /* Save initCompletePipe; it is used at daemonization. */
850
851 globals.initCompletePipe = initCompletePipe;
852
853 /* Save bindVerbose; it is used at daemonization and cimprovagt start. */
854
855 globals.bindVerbose = bindVerbose;
856
|
857 kumpf 1.2 /* Prepares socket into non-blocking I/O. */
858
859 SetNonBlocking(sock);
860
861 /* Process client requests until client exists. */
862
863 for (;;)
864 {
865 size_t n;
866 struct ExecutorRequestHeader header;
867
868 /* Receive request header. */
869
870 n = RecvNonBlock(sock, &header, sizeof(header));
871
872 if (n == 0)
873 {
874 /*
875 * Either client closed its end of the pipe (possibly by exiting)
876 * or we caught a SIGTERM.
877 */
878 kumpf 1.2 break;
879 }
880
881 if (n != sizeof(header))
882 Fatal(FL, "Failed to read header");
883
884 /* Dispatch request. */
885
886 switch ((enum ExecutorMessageCode)header.code)
887 {
888 case EXECUTOR_PING_MESSAGE:
889 HandlePingRequest(sock);
890 break;
891
892 case EXECUTOR_OPEN_FILE_MESSAGE:
893 HandleOpenFileRequest(sock);
894 break;
895
896 case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
897 HandleStartProviderAgentRequest(sock);
898 break;
899 kumpf 1.2
900 case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
|
901 kumpf 1.10 HandleDaemonizeExecutorRequest(sock);
|
902 kumpf 1.2 break;
903
904 case EXECUTOR_RENAME_FILE_MESSAGE:
905 HandleRenameFileRequest(sock);
906 break;
907
908 case EXECUTOR_REMOVE_FILE_MESSAGE:
909 HandleRemoveFileRequest(sock);
910 break;
911
912 case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
913 HandleAuthenticatePasswordRequest(sock);
914 break;
915
916 case EXECUTOR_VALIDATE_USER_MESSAGE:
917 HandleValidateUserRequest(sock);
918 break;
919
920 case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
921 HandleChallengeLocalRequest(sock);
922 break;
923 kumpf 1.2
924 case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
925 HandleAuthenticateLocalRequest(sock);
926 break;
927
|
928 kumpf 1.5 case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
929 HandleUpdateLogLevelRequest(sock);
930 break;
931
|
932 kumpf 1.2 default:
933 Fatal(FL, "Invalid request code: %d", header.code);
934 break;
935 }
936 }
937
938 /* Reached due to socket EOF, SIGTERM, or SIGINT. */
939
940 Exit(0);
941 }
|