1 kumpf 1.2 /*
2 //%2006////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
5 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
6 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
7 // IBM Corp.; EMC Corporation, The Open Group.
8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
9 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
10 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
11 // EMC Corporation; VERITAS Software Corporation; The Open Group.
12 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
13 // EMC Corporation; Symantec Corporation; The Open Group.
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a copy
16 // of this software and associated documentation files (the "Software"), to
17 // deal in the Software without restriction, including without limitation the
18 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
19 // sell copies of the Software, and to permit persons to whom the Software is
20 // furnished to do so, subject to the following conditions:
21 //
22 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
24 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 //%/////////////////////////////////////////////////////////////////////////////
32 */
33 #include <sys/time.h>
34 #include <sys/resource.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <string.h>
39 #include <fcntl.h>
40 #include <sys/wait.h>
41 #include <unistd.h>
42 #include <signal.h>
|
43 kumpf 1.3 #include <grp.h>
|
44 kumpf 1.2 #include "Parent.h"
45 #include "Log.h"
46 #include "Messages.h"
47 #include "Socket.h"
48 #include "Fatal.h"
49 #include "Globals.h"
50 #include "Path.h"
51 #include "User.h"
52 #include "Exit.h"
53 #include "Strlcpy.h"
54 #include "LocalAuth.h"
55 #include "Strlcat.h"
56 #include "PasswordFile.h"
57 #include "Policy.h"
58 #include "Macro.h"
59
60 #if defined(PEGASUS_PAM_AUTHENTICATION)
61 # include "PAMAuth.h"
62 #endif
63
64 /*
65 kumpf 1.2 **==============================================================================
66 **
67 ** _sigHandler()
68 **
69 ** Signal handler for SIGTERM.
70 **
71 **==============================================================================
72 */
73
74 static void _sigHandler(int signum)
75 {
76 globals.signalMask |= (1 << signum);
77 }
78
79 /*
80 **==============================================================================
81 **
|
82 kumpf 1.4 ** ReadExecutorRequest()
83 **
84 ** Read a request of the specified size from the specified socket into the
85 ** buffer provided.
86 **
87 **==============================================================================
88 */
89
90 static void ReadExecutorRequest(int sock, void* buffer, size_t size)
91 {
92 if (RecvNonBlock(sock, buffer, size) != (ssize_t)size)
93 {
94 Fatal(FL, "Failed to read request");
95 }
96 }
97
98 /*
99 **==============================================================================
100 **
101 ** WriteExecutorResponse()
102 **
103 kumpf 1.4 ** Write a response of the specified size from the given buffer onto the
104 ** specified socket.
105 **
106 **==============================================================================
107 */
108
109 static void WriteExecutorResponse(int sock, const void* buffer, size_t size)
110 {
111 if (SendNonBlock(sock, buffer, size) != (ssize_t)size)
112 {
113 Fatal(FL, "Failed to write response");
114 }
115 }
116
117 /*
118 **==============================================================================
119 **
|
120 kumpf 1.2 ** HandlePingRequest()
121 **
122 ** Handle ping request.
123 **
124 **==============================================================================
125 */
126
127 static void HandlePingRequest(int sock)
128 {
129 struct ExecutorPingResponse response;
130
131 memset(&response, 0, sizeof(response));
132 response.magic = EXECUTOR_PING_MAGIC;
133
134 Log(LL_TRACE, "HandlePingRequest()");
135
|
136 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
137 kumpf 1.2 }
138
139 /*
140 **==============================================================================
141 **
142 ** HandleOpenFileRequest()
143 **
144 ** Handle a request from a child to open a file.
145 **
146 **==============================================================================
147 */
148
149 static void HandleOpenFileRequest(int sock)
150 {
151 struct ExecutorOpenFileRequest request;
152 struct ExecutorOpenFileResponse response;
153 int fd;
154
155 memset(&response, 0, sizeof(response));
156
157 /* Read the request message. */
158 kumpf 1.2
|
159 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
160 kumpf 1.2
161 /* Log the request. */
162
163 Log(LL_TRACE, "HandleOpenFileRequest(): path=\"%s\", mode='%c'",
164 request.path, request.mode);
165
166 /* Perform the operation. */
167
168 response.status = 0;
169 fd = -1;
170
171 do
172 {
173 /* Check the policy. */
174
|
175 kumpf 1.6 unsigned long permissions = 0;
176
177 if (CheckOpenFilePolicy(request.path, request.mode, &permissions) != 0)
|
178 kumpf 1.2 {
179 response.status = -1;
180 break;
181 }
182
183 /* Open file. */
184
185 switch (request.mode)
186 {
187 case 'r':
188 fd = open(request.path, O_RDONLY);
189 break;
190
191 case 'w':
192 fd = open(
193 request.path,
194 O_WRONLY | O_CREAT | O_TRUNC,
|
195 kumpf 1.6 permissions);
|
196 kumpf 1.2 break;
197
198 case 'a':
199 {
200 fd = open(
201 request.path,
202 O_WRONLY | O_CREAT | O_APPEND,
|
203 kumpf 1.6 permissions);
|
204 kumpf 1.2 break;
205 }
206 }
207
208 if (fd == -1)
209 response.status = -1;
210 }
211 while (0);
212
213 /* Log failure. */
214
215 if (response.status != 0)
216 {
217 Log(LL_WARNING, "open(\"%s\", '%c') failed",
218 request.path, request.mode);
219 }
220
221 /* Send response. */
222
|
223 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
224 kumpf 1.2
225 /* Send descriptor to calling process (if any to send). */
226
227 if (response.status == 0)
228 {
229 int descriptors[1];
230 descriptors[0] = fd;
231 SendDescriptorArray(sock, descriptors, 1);
232 close(fd);
233 }
234 }
235
236 /*
237 **==============================================================================
238 **
239 ** HandleStartProviderAgentRequest()
240 **
241 **==============================================================================
242 */
243
244 static void HandleStartProviderAgentRequest(int sock)
245 kumpf 1.2 {
246 int status;
|
247 kumpf 1.3 int uid;
248 int gid;
|
249 kumpf 1.2 int pid;
250 int to[2];
251 int from[2];
252 struct ExecutorStartProviderAgentResponse response;
253 struct ExecutorStartProviderAgentRequest request;
254
255 memset(&response, 0, sizeof(response));
256
257 /* Read request. */
258
|
259 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
260 kumpf 1.2
261 /* Log request. */
262
263 Log(LL_TRACE, "HandleStartProviderAgentRequest(): "
|
264 kumpf 1.3 "module=%s userName=%s", request.module, request.userName);
|
265 kumpf 1.2
266 /* Process request. */
267
268 status = 0;
269 pid = -1;
270
271 do
272 {
273 /* Resolve full path of CIMPROVAGT. */
274
275 const char* path;
276
277 if ((path = FindMacro("cimprovagtPath")) == NULL)
278 Fatal(FL, "Failed to locate %s program", CIMPROVAGT);
279
|
280 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
281
282 /* Look up the user ID and group ID of the specified user. */
283
284 if (GetUserInfo(request.userName, &uid, &gid) != 0)
285 {
286 status = -1;
287 break;
288 }
289
290 Log(LL_TRACE, "cimprovagt user context: "
291 "userName=%s uid=%d gid=%d", request.userName, uid, gid);
292
293 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
294
|
295 kumpf 1.2 /* Create "to-agent" pipe: */
296
297 if (pipe(to) != 0)
298 {
299 status = -1;
300 break;
301 }
302
303 /* Create "from-agent" pipe: */
304
305 if (pipe(from) != 0)
306 {
307 status = -1;
308 break;
309 }
310
311 /* Fork process: */
312
313 pid = fork();
314
315 if (pid < 0)
316 kumpf 1.2 {
317 Log(LL_SEVERE, "fork failed");
318 status = -1;
319 break;
320 }
321
322 /* If child: */
323
324 if (pid == 0)
325 {
326 struct rlimit rlim;
327 char arg1[32];
328 char arg2[32];
329
330 /* Close unused pipe descriptors: */
331
332 close(to[1]);
333 close(from[0]);
334
335 /*
336 * Close unused descriptors. Leave stdin, stdout, stderr, and the
337 kumpf 1.2 * child's pipe descriptors open.
338 */
339
340 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
341 {
342 int i;
343
344 for (i = 3; i < (int)rlim.rlim_cur; i++)
345 {
346 if (i != to[0] && i != from[1])
347 close(i);
348 }
349 }
350
|
351 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
352
353 if ((int)getgid() != gid)
354 {
355 if (setgid((gid_t)gid) != 0)
356 {
357 Log(LL_SEVERE, "setgid(%d) failed\n", gid);
358 _exit(1);
359 }
360 }
|
361 kumpf 1.2
|
362 kumpf 1.3 if ((int)getuid() != uid)
|
363 kumpf 1.2 {
|
364 kumpf 1.3 if (initgroups(request.userName, gid) != 0)
|
365 kumpf 1.2 {
|
366 kumpf 1.3 Log(LL_SEVERE, "initgroups(%s, %d) failed\n",
367 request.userName,
368 gid);
369 _exit(1);
|
370 kumpf 1.2 }
371
|
372 kumpf 1.3 if (setuid((uid_t)uid) != 0)
|
373 kumpf 1.2 {
|
374 kumpf 1.3 Log(LL_SEVERE, "setuid(%d) failed\n", uid);
375 _exit(1);
|
376 kumpf 1.2 }
377 }
378
379 Log(LL_TRACE, "starting %s on module %s as user %s",
|
380 kumpf 1.3 path, request.module, request.userName);
|
381 kumpf 1.2
|
382 kumpf 1.3 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
|
383 kumpf 1.2
384 /* Exec the CIMPROVAGT program. */
385
386 sprintf(arg1, "%d", to[0]);
387 sprintf(arg2, "%d", from[1]);
388
389 Log(LL_TRACE, "execl(%s, %s, %s, %s, %s)\n",
390 path, path, arg1, arg2, request.module);
391
392 /* Flawfinder: ignore */
393 execl(path, path, arg1, arg2, request.module, (char*)0);
394
395 Log(LL_SEVERE, "execl(%s, %s, %s, %s, %s): failed\n",
396 path, path, arg1, arg2, request.module);
|
397 kumpf 1.5 _exit(1);
|
398 kumpf 1.2 }
399 }
400 while (0);
401
402 /* Close unused pipe descriptors. */
403
404 close(to[0]);
405 close(from[1]);
406
407 /* Send response. */
408
409 response.status = status;
410 response.pid = pid;
411
|
412 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
413 kumpf 1.2
414 /* Send descriptors to calling process. */
415
416 if (response.status == 0)
417 {
418 int descriptors[2];
419 descriptors[0] = from[0];
420 descriptors[1] = to[1];
421
422 SendDescriptorArray(sock, descriptors, 2);
423 close(from[0]);
424 close(to[1]);
425 }
426 }
427
428 /*
429 **==============================================================================
430 **
431 ** HandleDaemonizeExecutorRequest()
432 **
433 **==============================================================================
434 kumpf 1.2 */
435
436 static void HandleDaemonizeExecutorRequest(int sock, int bindVerbose)
437 {
438 struct ExecutorDaemonizeExecutorResponse response;
439 int pid;
440
441 memset(&response, 0, sizeof(response));
442
443 Log(LL_TRACE, "HandleDaemonizeExecutorRequest()");
444
445 /* Fork (parent exits; child continues) */
446 /* (Ensures we are not a session leader so that setsid() will succeed.) */
447
448 pid = fork();
449
450 if (pid < 0)
451 {
452 response.status = -1;
453 Fatal(FL, "fork() failed");
454 }
455 kumpf 1.2
456 if (pid > 0)
457 _exit(0);
458
459 /* Become session leader (so that our child process will not be one) */
460
461 if (setsid() < 0)
462 {
463 response.status = -1;
464 Fatal(FL, "setsid() failed");
465 }
466
467 /* Ignore SIGHUP: */
468
469 signal(SIGHUP, SIG_IGN);
470
|
471 kumpf 1.7 /* Ignore SIGCHLD: */
472
473 signal(SIGCHLD, SIG_IGN);
474
|
475 kumpf 1.2 /* Fork again (so we are not a session leader because our parent is): */
476
477 pid = fork();
478
479 if (pid < 0)
480 {
481 response.status = -1;
482 Fatal(FL, "fork() failed");
483 }
484
485 if (pid > 0)
486 _exit(0);
487
488 /* Catch SIGTERM: */
489
490 signal(SIGTERM, _sigHandler);
491
492 /* Make root the current directory. */
493
494 chdir("/");
495
496 kumpf 1.2 if (!bindVerbose)
497 {
498 /* Close these file descriptors (stdin, stdout, stderr). */
499
500 close(0);
501 close(1);
502 close(2);
503
504 /* Direct standard input, output, and error to /dev/null: */
505
506 open("/dev/null", O_RDONLY);
507 open("/dev/null", O_RDWR);
508 open("/dev/null", O_RDWR);
509 }
510
511 response.status = 0;
512
|
513 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
514 kumpf 1.2 }
515
516 /*
517 **==============================================================================
518 **
519 ** HandleRenameFileRequest()
520 **
521 **==============================================================================
522 */
523
524 static void HandleRenameFileRequest(int sock)
525 {
526 struct ExecutorRenameFileResponse response;
527 struct ExecutorRenameFileRequest request;
528
529 memset(&response, 0, sizeof(response));
530
531 /* Read the request message. */
532
|
533 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
534 kumpf 1.2
535 /* Log request. */
536
537 Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
538 request.oldPath, request.newPath);
539
540 /* Perform the operation: */
541
542 response.status = 0;
543
544 do
545 {
546 /* Check the policy. */
547
548 if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
549 {
550 response.status = -1;
551 break;
552 }
553
554 /* Rename the file. */
555 kumpf 1.2
556 if (rename(request.oldPath, request.newPath) != 0)
557 {
558 response.status = -1;
559 break;
560 }
561 }
562 while (0);
563
564 /* Send response message. */
565
|
566 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
567 kumpf 1.2 }
568
569 /*
570 **==============================================================================
571 **
572 ** HandleRemoveFileRequest()
573 **
574 **==============================================================================
575 */
576
577 static void HandleRemoveFileRequest(int sock)
578 {
579 struct ExecutorRemoveFileRequest request;
580 struct ExecutorRemoveFileResponse response;
581
582 memset(&response, 0, sizeof(response));
583
584 /* Read the request message. */
585
|
586 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
587 kumpf 1.2
588 /* Log request. */
589
590 Log(LL_TRACE, "HandleRemoveFileRequest(): path=%s", request.path);
591
592 response.status = 0;
593
594 do
595 {
596 /* Check the policy. */
597
598 if (CheckRemoveFilePolicy(request.path) != 0)
599 {
600 response.status = -1;
601 break;
602 }
603
604 /* Remove the file. */
605
606 if (unlink(request.path) != 0)
607 {
608 kumpf 1.2 response.status = -1;
609 Log(LL_WARNING, "unlink(%s) failed", request.path);
610 break;
611 }
612 }
613 while (0);
614
615 /* Send response message. */
616
|
617 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
618 kumpf 1.2 }
619
620 /*
621 **==============================================================================
622 **
623 ** HandleAuthenticatePasswordRequest()
624 **
625 **==============================================================================
626 */
627
628 static void HandleAuthenticatePasswordRequest(int sock)
629 {
630 int status;
631 struct ExecutorAuthenticatePasswordRequest request;
632 struct ExecutorAuthenticatePasswordResponse response;
633 int gid;
634 int uid;
635
636 memset(&response, 0, sizeof(response));
637
638 /* Read the request message. */
639 kumpf 1.2
|
640 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
641 kumpf 1.2
642 /* Log request. */
643
644 Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
645 request.username);
646
647 /* Perform the operation: */
648
649 status = 0;
650
651 do
652 {
653 if (GetUserInfo(request.username, &uid, &gid) != 0)
654 {
655 status = -1;
656 break;
657 }
658
659 #if defined(PEGASUS_PAM_AUTHENTICATION)
660
661 if (PAMAuthenticate(request.username, request.password) != 0)
662 kumpf 1.2 {
663 status = -1;
664 break;
665 }
666
667
668 #else /* !PEGASUS_PAM_AUTHENTICATION */
669
670 {
671 const char* path = FindMacro("passwordFilePath");
672
673 if (!path)
674 {
675 status = -1;
676 break;
677 }
678
679 if (CheckPasswordFile(
680 path, request.username, request.password) != 0)
681 {
682 status = -1;
683 kumpf 1.2 break;
684 }
685 }
686
687 #endif /* !PEGASUS_PAM_AUTHENTICATION */
688 }
689 while (0);
690
691 if (status != 0)
692 {
693 Log(LL_WARNING, "Basic authentication failed for username %s",
694 request.username);
695 }
696 else
697 {
698 Log(LL_TRACE, "Basic authentication succeeded for username %s",
699 request.username);
700 }
701
702 /* Send response message. */
703
704 kumpf 1.2 response.status = status;
705
|
706 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
707 kumpf 1.2 }
708
709 /*
710 **==============================================================================
711 **
712 ** HandleValidateUserRequest()
713 **
714 **==============================================================================
715 */
716
717 static void HandleValidateUserRequest(int sock)
718 {
719 int status;
720 struct ExecutorValidateUserResponse response;
721 struct ExecutorValidateUserRequest request;
722
723 memset(&response, 0, sizeof(response));
724
725 /* Read the request message. */
726
|
727 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
728 kumpf 1.2
729 /* Validate the user. */
730
731 Log(LL_TRACE,
732 "HandleValidateUserRequest(): username=%s", request.username);
733
734 /* Get the uid for the username. */
735
736 status = 0;
737
738 #if defined(PEGASUS_PAM_AUTHENTICATION)
739
740 if (PAMValidateUser(request.username) != 0)
741 status = -1;
742
743 #else /* !PEGASUS_PAM_AUTHENTICATION */
744
745 do
746 {
747 const char* path = FindMacro("passwordFilePath");
748
749 kumpf 1.2 if (!path)
750 {
751 status = -1;
752 break;
753 }
754
755 if (CheckPasswordFile(path, request.username, NULL) != 0)
756 {
757 status = -1;
758 break;
759 }
760 }
761 while (0);
762
763 #endif /* !PEGASUS_PAM_AUTHENTICATION */
764
765 if (status != 0)
766 Log(LL_WARNING, "User validation failed on %s", request.username);
767
768 /* Send response message. */
769
770 kumpf 1.2 response.status = status;
771
|
772 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
773 kumpf 1.2 }
774
775 /*
776 **==============================================================================
777 **
778 ** HandleChallengeLocalRequest()
779 **
780 **==============================================================================
781 */
782
783 static void HandleChallengeLocalRequest(int sock)
784 {
785 char challenge[EXECUTOR_BUFFER_SIZE];
786 struct ExecutorChallengeLocalRequest request;
787 struct ExecutorChallengeLocalResponse response;
788
789 memset(&response, 0, sizeof(response));
790
791 /* Read the request message. */
792
|
793 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
794 kumpf 1.2
795 Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
796
797 /* Perform operation. */
798
|
799 kumpf 1.4 response.status = StartLocalAuthentication(request.user, challenge);
|
800 kumpf 1.2
|
801 kumpf 1.4 /* Send response message. */
802
803 if (response.status != 0)
|
804 kumpf 1.2 {
805 Log(LL_WARNING, "Local authentication failed for user \"%s\"",
806 request.user);
807 }
|
808 kumpf 1.4 else
809 {
|
810 kumpf 1.2 Strlcpy(response.challenge, challenge, sizeof(response.challenge));
|
811 kumpf 1.4 }
|
812 kumpf 1.2
|
813 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
814 kumpf 1.2 }
815
816 /*
817 **==============================================================================
818 **
819 ** HandleAuthenticateLocalRequest()
820 **
821 **==============================================================================
822 */
823
824 static void HandleAuthenticateLocalRequest(int sock)
825 {
826 int status;
827 struct ExecutorAuthenticateLocalRequest request;
828 struct ExecutorAuthenticateLocalResponse response;
829
830 memset(&response, 0, sizeof(response));
831
832 /* Read the request message. */
833
|
834 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
835 kumpf 1.2
836 Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
837
838 /* Perform operation. */
839
840 status = FinishLocalAuthentication(request.challenge, request.response);
841
842 /* Log result. */
843
844 if (status != 0)
845 {
846 Log(LL_WARNING, "Local authentication failed");
847 }
848
849 /* Send response. */
850
851 response.status = status;
852
|
853 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
854 kumpf 1.2 }
855
856 /*
857 **==============================================================================
858 **
|
859 kumpf 1.5 ** HandleUpdateLogLevelRequest()
860 **
861 **==============================================================================
862 */
863
864 static void HandleUpdateLogLevelRequest(int sock)
865 {
866 int status;
867 struct ExecutorUpdateLogLevelRequest request;
868 struct ExecutorUpdateLogLevelResponse response;
869
870 memset(&response, 0, sizeof(response));
871
872 /* Read the request message. */
873
874 ReadExecutorRequest(sock, &request, sizeof(request));
875
876 /* Log request. */
877
878 Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
879 request.logLevel);
880 kumpf 1.5
881 /* Perform operation. */
882
883 status = SetLogLevel(request.logLevel);
884
885 if (status == -1)
886 Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
887
888 /* Send response message. */
889
890 response.status = status;
891
892 WriteExecutorResponse(sock, &response, sizeof(response));
893 }
894
895 /*
896 **==============================================================================
897 **
|
898 kumpf 1.2 ** Parent()
899 **
900 ** The parent process (cimserver).
901 **
902 **==============================================================================
903 */
904
905 void Parent(int sock, int childPid, int bindVerbose)
906 {
907 /* Handle Ctrl-C. */
908
909 signal(SIGINT, _sigHandler);
910
911 /* Catch SIGTERM, sent by kill program. */
912
913 signal(SIGTERM, _sigHandler);
914
915 /*
916 * Ignore SIGPIPE, which occurs if a child with whom the executor shares
917 * a local domain socket unexpectedly dies. In such a case, the socket
918 * read/write functions will return an error. There are two child processes
919 kumpf 1.2 * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
920 */
921
922 signal(SIGPIPE, SIG_IGN);
923
924 /* Save child PID globally; it is used by Exit() function. */
925
926 globals.childPid = childPid;
927
928 /* Prepares socket into non-blocking I/O. */
929
930 SetNonBlocking(sock);
931
932 /* Process client requests until client exists. */
933
934 for (;;)
935 {
936 size_t n;
937 struct ExecutorRequestHeader header;
938
939 /* Receive request header. */
940 kumpf 1.2
941 n = RecvNonBlock(sock, &header, sizeof(header));
942
943 if (n == 0)
944 {
945 /*
946 * Either client closed its end of the pipe (possibly by exiting)
947 * or we caught a SIGTERM.
948 */
949 break;
950 }
951
952 if (n != sizeof(header))
953 Fatal(FL, "Failed to read header");
954
955 /* Dispatch request. */
956
957 switch ((enum ExecutorMessageCode)header.code)
958 {
959 case EXECUTOR_PING_MESSAGE:
960 HandlePingRequest(sock);
961 kumpf 1.2 break;
962
963 case EXECUTOR_OPEN_FILE_MESSAGE:
964 HandleOpenFileRequest(sock);
965 break;
966
967 case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
968 HandleStartProviderAgentRequest(sock);
969 break;
970
971 case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
972 HandleDaemonizeExecutorRequest(sock, bindVerbose);
973 break;
974
975 case EXECUTOR_RENAME_FILE_MESSAGE:
976 HandleRenameFileRequest(sock);
977 break;
978
979 case EXECUTOR_REMOVE_FILE_MESSAGE:
980 HandleRemoveFileRequest(sock);
981 break;
982 kumpf 1.2
983 case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
984 HandleAuthenticatePasswordRequest(sock);
985 break;
986
987 case EXECUTOR_VALIDATE_USER_MESSAGE:
988 HandleValidateUserRequest(sock);
989 break;
990
991 case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
992 HandleChallengeLocalRequest(sock);
993 break;
994
995 case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
996 HandleAuthenticateLocalRequest(sock);
997 break;
998
|
999 kumpf 1.5 case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
1000 HandleUpdateLogLevelRequest(sock);
1001 break;
1002
|
1003 kumpf 1.2 default:
1004 Fatal(FL, "Invalid request code: %d", header.code);
1005 break;
1006 }
1007 }
1008
1009 /* Reached due to socket EOF, SIGTERM, or SIGINT. */
1010
1011 Exit(0);
1012 }
|