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 if (CheckOpenFilePolicy(request.path, request.mode) != 0)
176 {
177 response.status = -1;
178 break;
179 }
180
181 kumpf 1.2 /* Open file. */
182
183 switch (request.mode)
184 {
185 case 'r':
186 fd = open(request.path, O_RDONLY);
187 break;
188
189 case 'w':
190 fd = open(
191 request.path,
192 O_WRONLY | O_CREAT | O_TRUNC,
193 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */
194 break;
195
196 case 'a':
197 {
198 fd = open(
199 request.path,
200 O_WRONLY | O_CREAT | O_APPEND,
201 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */
202 kumpf 1.2 break;
203 }
204 }
205
206 if (fd == -1)
207 response.status = -1;
208 }
209 while (0);
210
211 /* Log failure. */
212
213 if (response.status != 0)
214 {
215 Log(LL_WARNING, "open(\"%s\", '%c') failed",
216 request.path, request.mode);
217 }
218
219 /* Send response. */
220
|
221 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
222 kumpf 1.2
223 /* Send descriptor to calling process (if any to send). */
224
225 if (response.status == 0)
226 {
227 int descriptors[1];
228 descriptors[0] = fd;
229 SendDescriptorArray(sock, descriptors, 1);
230 close(fd);
231 }
232 }
233
234 /*
235 **==============================================================================
236 **
237 ** HandleStartProviderAgentRequest()
238 **
239 **==============================================================================
240 */
241
242 static void HandleStartProviderAgentRequest(int sock)
243 kumpf 1.2 {
244 int status;
|
245 kumpf 1.3 int uid;
246 int gid;
|
247 kumpf 1.2 int pid;
248 int to[2];
249 int from[2];
250 struct ExecutorStartProviderAgentResponse response;
251 struct ExecutorStartProviderAgentRequest request;
252
253 memset(&response, 0, sizeof(response));
254
255 /* Read request. */
256
|
257 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
258 kumpf 1.2
259 /* Log request. */
260
261 Log(LL_TRACE, "HandleStartProviderAgentRequest(): "
|
262 kumpf 1.3 "module=%s userName=%s", request.module, request.userName);
|
263 kumpf 1.2
264 /* Process request. */
265
266 status = 0;
267 pid = -1;
268
269 do
270 {
271 /* Resolve full path of CIMPROVAGT. */
272
273 const char* path;
274
275 if ((path = FindMacro("cimprovagtPath")) == NULL)
276 Fatal(FL, "Failed to locate %s program", CIMPROVAGT);
277
|
278 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
279
280 /* Look up the user ID and group ID of the specified user. */
281
282 if (GetUserInfo(request.userName, &uid, &gid) != 0)
283 {
284 status = -1;
285 break;
286 }
287
288 Log(LL_TRACE, "cimprovagt user context: "
289 "userName=%s uid=%d gid=%d", request.userName, uid, gid);
290
291 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
292
|
293 kumpf 1.2 /* Create "to-agent" pipe: */
294
295 if (pipe(to) != 0)
296 {
297 status = -1;
298 break;
299 }
300
301 /* Create "from-agent" pipe: */
302
303 if (pipe(from) != 0)
304 {
305 status = -1;
306 break;
307 }
308
309 /* Fork process: */
310
311 pid = fork();
312
313 if (pid < 0)
314 kumpf 1.2 {
315 Log(LL_SEVERE, "fork failed");
316 status = -1;
317 break;
318 }
319
320 /* If child: */
321
322 if (pid == 0)
323 {
324 struct rlimit rlim;
325 char arg1[32];
326 char arg2[32];
327
328 /* Close unused pipe descriptors: */
329
330 close(to[1]);
331 close(from[0]);
332
333 /*
334 * Close unused descriptors. Leave stdin, stdout, stderr, and the
335 kumpf 1.2 * child's pipe descriptors open.
336 */
337
338 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
339 {
340 int i;
341
342 for (i = 3; i < (int)rlim.rlim_cur; i++)
343 {
344 if (i != to[0] && i != from[1])
345 close(i);
346 }
347 }
348
|
349 kumpf 1.3 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
350
351 if ((int)getgid() != gid)
352 {
353 if (setgid((gid_t)gid) != 0)
354 {
355 Log(LL_SEVERE, "setgid(%d) failed\n", gid);
356 _exit(1);
357 }
358 }
|
359 kumpf 1.2
|
360 kumpf 1.3 if ((int)getuid() != uid)
|
361 kumpf 1.2 {
|
362 kumpf 1.3 if (initgroups(request.userName, gid) != 0)
|
363 kumpf 1.2 {
|
364 kumpf 1.3 Log(LL_SEVERE, "initgroups(%s, %d) failed\n",
365 request.userName,
366 gid);
367 _exit(1);
|
368 kumpf 1.2 }
369
|
370 kumpf 1.3 if (setuid((uid_t)uid) != 0)
|
371 kumpf 1.2 {
|
372 kumpf 1.3 Log(LL_SEVERE, "setuid(%d) failed\n", uid);
373 _exit(1);
|
374 kumpf 1.2 }
375 }
376
377 Log(LL_TRACE, "starting %s on module %s as user %s",
|
378 kumpf 1.3 path, request.module, request.userName);
|
379 kumpf 1.2
|
380 kumpf 1.3 #endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
|
381 kumpf 1.2
382 /* Exec the CIMPROVAGT program. */
383
384 sprintf(arg1, "%d", to[0]);
385 sprintf(arg2, "%d", from[1]);
386
387 Log(LL_TRACE, "execl(%s, %s, %s, %s, %s)\n",
388 path, path, arg1, arg2, request.module);
389
390 /* Flawfinder: ignore */
391 execl(path, path, arg1, arg2, request.module, (char*)0);
392
393 Log(LL_SEVERE, "execl(%s, %s, %s, %s, %s): failed\n",
394 path, path, arg1, arg2, request.module);
|
395 kumpf 1.5 _exit(1);
|
396 kumpf 1.2 }
397 }
398 while (0);
399
400 /* Close unused pipe descriptors. */
401
402 close(to[0]);
403 close(from[1]);
404
405 /* Send response. */
406
407 response.status = status;
408 response.pid = pid;
409
|
410 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
411 kumpf 1.2
412 /* Send descriptors to calling process. */
413
414 if (response.status == 0)
415 {
416 int descriptors[2];
417 descriptors[0] = from[0];
418 descriptors[1] = to[1];
419
420 SendDescriptorArray(sock, descriptors, 2);
421 close(from[0]);
422 close(to[1]);
423 }
424 }
425
426 /*
427 **==============================================================================
428 **
429 ** HandleDaemonizeExecutorRequest()
430 **
431 **==============================================================================
432 kumpf 1.2 */
433
434 static void HandleDaemonizeExecutorRequest(int sock, int bindVerbose)
435 {
436 struct ExecutorDaemonizeExecutorResponse response;
437 int pid;
438
439 memset(&response, 0, sizeof(response));
440
441 Log(LL_TRACE, "HandleDaemonizeExecutorRequest()");
442
443 /* Fork (parent exits; child continues) */
444 /* (Ensures we are not a session leader so that setsid() will succeed.) */
445
446 pid = fork();
447
448 if (pid < 0)
449 {
450 response.status = -1;
451 Fatal(FL, "fork() failed");
452 }
453 kumpf 1.2
454 if (pid > 0)
455 _exit(0);
456
457 /* Become session leader (so that our child process will not be one) */
458
459 if (setsid() < 0)
460 {
461 response.status = -1;
462 Fatal(FL, "setsid() failed");
463 }
464
465 /* Ignore SIGHUP: */
466
467 signal(SIGHUP, SIG_IGN);
468
469 /* Fork again (so we are not a session leader because our parent is): */
470
471 pid = fork();
472
473 if (pid < 0)
474 kumpf 1.2 {
475 response.status = -1;
476 Fatal(FL, "fork() failed");
477 }
478
479 if (pid > 0)
480 _exit(0);
481
482 /* Catch SIGTERM: */
483
484 signal(SIGTERM, _sigHandler);
485
486 /* Make root the current directory. */
487
488 chdir("/");
489
490 if (!bindVerbose)
491 {
492 /* Close these file descriptors (stdin, stdout, stderr). */
493
494 close(0);
495 kumpf 1.2 close(1);
496 close(2);
497
498 /* Direct standard input, output, and error to /dev/null: */
499
500 open("/dev/null", O_RDONLY);
501 open("/dev/null", O_RDWR);
502 open("/dev/null", O_RDWR);
503 }
504
505 response.status = 0;
506
|
507 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
508 kumpf 1.2 }
509
510 /*
511 **==============================================================================
512 **
513 ** HandleRenameFileRequest()
514 **
515 **==============================================================================
516 */
517
518 static void HandleRenameFileRequest(int sock)
519 {
520 struct ExecutorRenameFileResponse response;
521 struct ExecutorRenameFileRequest request;
522
523 memset(&response, 0, sizeof(response));
524
525 /* Read the request message. */
526
|
527 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
528 kumpf 1.2
529 /* Log request. */
530
531 Log(LL_TRACE, "HandleRenameFileRequest(): oldPath=%s newPath=%s",
532 request.oldPath, request.newPath);
533
534 /* Perform the operation: */
535
536 response.status = 0;
537
538 do
539 {
540 /* Check the policy. */
541
542 if (CheckRenameFilePolicy(request.oldPath, request.newPath) != 0)
543 {
544 response.status = -1;
545 break;
546 }
547
548 /* Rename the file. */
549 kumpf 1.2
550 if (rename(request.oldPath, request.newPath) != 0)
551 {
552 response.status = -1;
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 ** HandleRemoveFileRequest()
567 **
568 **==============================================================================
569 */
570
571 static void HandleRemoveFileRequest(int sock)
572 {
573 struct ExecutorRemoveFileRequest request;
574 struct ExecutorRemoveFileResponse response;
575
576 memset(&response, 0, sizeof(response));
577
578 /* Read the request message. */
579
|
580 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
581 kumpf 1.2
582 /* Log request. */
583
584 Log(LL_TRACE, "HandleRemoveFileRequest(): path=%s", request.path);
585
586 response.status = 0;
587
588 do
589 {
590 /* Check the policy. */
591
592 if (CheckRemoveFilePolicy(request.path) != 0)
593 {
594 response.status = -1;
595 break;
596 }
597
598 /* Remove the file. */
599
600 if (unlink(request.path) != 0)
601 {
602 kumpf 1.2 response.status = -1;
603 Log(LL_WARNING, "unlink(%s) failed", request.path);
604 break;
605 }
606 }
607 while (0);
608
609 /* Send response message. */
610
|
611 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
612 kumpf 1.2 }
613
614 /*
615 **==============================================================================
616 **
617 ** HandleReapProviderAgentRequest()
618 **
619 **==============================================================================
620 */
621
622 static void HandleReapProviderAgentRequest(int sock)
623 {
624 int status;
625 struct ExecutorReapProviderAgentRequest request;
626 struct ExecutorReapProviderAgentResponse response;
627
628 memset(&response, 0, sizeof(response));
629
630 /* Read the request message. */
631
|
632 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
633 kumpf 1.2
634 /* Log request. */
635
636 Log(LL_TRACE, "HandleReapProviderAgentRequest(): pid=%d", request.pid);
637
638 /* Perform operation. */
639
640 status = 0;
641
642 do
643 {
644 /* Wait on the PID. */
645
646 EXECUTOR_RESTART(waitpid(request.pid, 0, 0), status);
647
648 if (status == -1)
649 Log(LL_WARNING, "waitpid(%d, 0, 0) failed", request.pid);
650 }
651 while (0);
652
653 /* Send response message. */
654 kumpf 1.2
655 response.status = status;
656
|
657 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
658 kumpf 1.2 }
659
660 /*
661 **==============================================================================
662 **
663 ** HandleAuthenticatePasswordRequest()
664 **
665 **==============================================================================
666 */
667
668 static void HandleAuthenticatePasswordRequest(int sock)
669 {
670 int status;
671 struct ExecutorAuthenticatePasswordRequest request;
672 struct ExecutorAuthenticatePasswordResponse response;
673 int gid;
674 int uid;
675
676 memset(&response, 0, sizeof(response));
677
678 /* Read the request message. */
679 kumpf 1.2
|
680 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
681 kumpf 1.2
682 /* Log request. */
683
684 Log(LL_TRACE, "HandleAuthenticatePasswordRequest(): username=%s",
685 request.username);
686
687 /* Perform the operation: */
688
689 status = 0;
690
691 do
692 {
693 if (GetUserInfo(request.username, &uid, &gid) != 0)
694 {
695 status = -1;
696 break;
697 }
698
699 #if defined(PEGASUS_PAM_AUTHENTICATION)
700
701 if (PAMAuthenticate(request.username, request.password) != 0)
702 kumpf 1.2 {
703 status = -1;
704 break;
705 }
706
707
708 #else /* !PEGASUS_PAM_AUTHENTICATION */
709
710 {
711 const char* path = FindMacro("passwordFilePath");
712
713 if (!path)
714 {
715 status = -1;
716 break;
717 }
718
719 if (CheckPasswordFile(
720 path, request.username, request.password) != 0)
721 {
722 status = -1;
723 kumpf 1.2 break;
724 }
725 }
726
727 #endif /* !PEGASUS_PAM_AUTHENTICATION */
728 }
729 while (0);
730
731 if (status != 0)
732 {
733 Log(LL_WARNING, "Basic authentication failed for username %s",
734 request.username);
735 }
736 else
737 {
738 Log(LL_TRACE, "Basic authentication succeeded for username %s",
739 request.username);
740 }
741
742 /* Send response message. */
743
744 kumpf 1.2 response.status = status;
745
|
746 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
747 kumpf 1.2 }
748
749 /*
750 **==============================================================================
751 **
752 ** HandleValidateUserRequest()
753 **
754 **==============================================================================
755 */
756
757 static void HandleValidateUserRequest(int sock)
758 {
759 int status;
760 struct ExecutorValidateUserResponse response;
761 struct ExecutorValidateUserRequest request;
762
763 memset(&response, 0, sizeof(response));
764
765 /* Read the request message. */
766
|
767 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
768 kumpf 1.2
769 /* Validate the user. */
770
771 Log(LL_TRACE,
772 "HandleValidateUserRequest(): username=%s", request.username);
773
774 /* Get the uid for the username. */
775
776 status = 0;
777
778 #if defined(PEGASUS_PAM_AUTHENTICATION)
779
780 if (PAMValidateUser(request.username) != 0)
781 status = -1;
782
783 #else /* !PEGASUS_PAM_AUTHENTICATION */
784
785 do
786 {
787 const char* path = FindMacro("passwordFilePath");
788
789 kumpf 1.2 if (!path)
790 {
791 status = -1;
792 break;
793 }
794
795 if (CheckPasswordFile(path, request.username, NULL) != 0)
796 {
797 status = -1;
798 break;
799 }
800 }
801 while (0);
802
803 #endif /* !PEGASUS_PAM_AUTHENTICATION */
804
805 if (status != 0)
806 Log(LL_WARNING, "User validation failed on %s", request.username);
807
808 /* Send response message. */
809
810 kumpf 1.2 response.status = status;
811
|
812 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
813 kumpf 1.2 }
814
815 /*
816 **==============================================================================
817 **
818 ** HandleChallengeLocalRequest()
819 **
820 **==============================================================================
821 */
822
823 static void HandleChallengeLocalRequest(int sock)
824 {
825 char challenge[EXECUTOR_BUFFER_SIZE];
826 struct ExecutorChallengeLocalRequest request;
827 struct ExecutorChallengeLocalResponse response;
828
829 memset(&response, 0, sizeof(response));
830
831 /* Read the request message. */
832
|
833 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
834 kumpf 1.2
835 Log(LL_TRACE, "HandleChallengeLocalRequest(): user=%s", request.user);
836
837 /* Perform operation. */
838
|
839 kumpf 1.4 response.status = StartLocalAuthentication(request.user, challenge);
|
840 kumpf 1.2
|
841 kumpf 1.4 /* Send response message. */
842
843 if (response.status != 0)
|
844 kumpf 1.2 {
845 Log(LL_WARNING, "Local authentication failed for user \"%s\"",
846 request.user);
847 }
|
848 kumpf 1.4 else
849 {
|
850 kumpf 1.2 Strlcpy(response.challenge, challenge, sizeof(response.challenge));
|
851 kumpf 1.4 }
|
852 kumpf 1.2
|
853 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
854 kumpf 1.2 }
855
856 /*
857 **==============================================================================
858 **
859 ** HandleAuthenticateLocalRequest()
860 **
861 **==============================================================================
862 */
863
864 static void HandleAuthenticateLocalRequest(int sock)
865 {
866 int status;
867 struct ExecutorAuthenticateLocalRequest request;
868 struct ExecutorAuthenticateLocalResponse response;
869
870 memset(&response, 0, sizeof(response));
871
872 /* Read the request message. */
873
|
874 kumpf 1.4 ReadExecutorRequest(sock, &request, sizeof(request));
|
875 kumpf 1.2
876 Log(LL_TRACE, "HandleAuthenticateLocalRequest()");
877
878 /* Perform operation. */
879
880 status = FinishLocalAuthentication(request.challenge, request.response);
881
882 /* Log result. */
883
884 if (status != 0)
885 {
886 Log(LL_WARNING, "Local authentication failed");
887 }
888
889 /* Send response. */
890
891 response.status = status;
892
|
893 kumpf 1.4 WriteExecutorResponse(sock, &response, sizeof(response));
|
894 kumpf 1.2 }
895
896 /*
897 **==============================================================================
898 **
|
899 kumpf 1.5 ** HandleUpdateLogLevelRequest()
900 **
901 **==============================================================================
902 */
903
904 static void HandleUpdateLogLevelRequest(int sock)
905 {
906 int status;
907 struct ExecutorUpdateLogLevelRequest request;
908 struct ExecutorUpdateLogLevelResponse response;
909
910 memset(&response, 0, sizeof(response));
911
912 /* Read the request message. */
913
914 ReadExecutorRequest(sock, &request, sizeof(request));
915
916 /* Log request. */
917
918 Log(LL_TRACE, "HandleUpdateLogLevelRequest(): logLevel=%s",
919 request.logLevel);
920 kumpf 1.5
921 /* Perform operation. */
922
923 status = SetLogLevel(request.logLevel);
924
925 if (status == -1)
926 Log(LL_WARNING, "SetLogLevel(%d) failed", request.logLevel);
927
928 /* Send response message. */
929
930 response.status = status;
931
932 WriteExecutorResponse(sock, &response, sizeof(response));
933 }
934
935 /*
936 **==============================================================================
937 **
|
938 kumpf 1.2 ** Parent()
939 **
940 ** The parent process (cimserver).
941 **
942 **==============================================================================
943 */
944
945 void Parent(int sock, int childPid, int bindVerbose)
946 {
947 /* Handle Ctrl-C. */
948
949 signal(SIGINT, _sigHandler);
950
951 /* Catch SIGTERM, sent by kill program. */
952
953 signal(SIGTERM, _sigHandler);
954
955 /*
956 * Ignore SIGPIPE, which occurs if a child with whom the executor shares
957 * a local domain socket unexpectedly dies. In such a case, the socket
958 * read/write functions will return an error. There are two child processes
959 kumpf 1.2 * the executor talks to over sockets: CIMSERVERA and CIMSERVERMAIN.
960 */
961
962 signal(SIGPIPE, SIG_IGN);
963
964 /* Save child PID globally; it is used by Exit() function. */
965
966 globals.childPid = childPid;
967
968 /* Prepares socket into non-blocking I/O. */
969
970 SetNonBlocking(sock);
971
972 /* Process client requests until client exists. */
973
974 for (;;)
975 {
976 size_t n;
977 struct ExecutorRequestHeader header;
978
979 /* Receive request header. */
980 kumpf 1.2
981 n = RecvNonBlock(sock, &header, sizeof(header));
982
983 if (n == 0)
984 {
985 /*
986 * Either client closed its end of the pipe (possibly by exiting)
987 * or we caught a SIGTERM.
988 */
989 break;
990 }
991
992 if (n != sizeof(header))
993 Fatal(FL, "Failed to read header");
994
995 /* Dispatch request. */
996
997 switch ((enum ExecutorMessageCode)header.code)
998 {
999 case EXECUTOR_PING_MESSAGE:
1000 HandlePingRequest(sock);
1001 kumpf 1.2 break;
1002
1003 case EXECUTOR_OPEN_FILE_MESSAGE:
1004 HandleOpenFileRequest(sock);
1005 break;
1006
1007 case EXECUTOR_START_PROVIDER_AGENT_MESSAGE:
1008 HandleStartProviderAgentRequest(sock);
1009 break;
1010
1011 case EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE:
1012 HandleDaemonizeExecutorRequest(sock, bindVerbose);
1013 break;
1014
1015 case EXECUTOR_RENAME_FILE_MESSAGE:
1016 HandleRenameFileRequest(sock);
1017 break;
1018
1019 case EXECUTOR_REMOVE_FILE_MESSAGE:
1020 HandleRemoveFileRequest(sock);
1021 break;
1022 kumpf 1.2
|
1023 kumpf 1.5 case EXECUTOR_REAP_PROVIDER_AGENT_MESSAGE:
|
1024 kumpf 1.2 HandleReapProviderAgentRequest(sock);
1025 break;
1026
1027 case EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE:
1028 HandleAuthenticatePasswordRequest(sock);
1029 break;
1030
1031 case EXECUTOR_VALIDATE_USER_MESSAGE:
1032 HandleValidateUserRequest(sock);
1033 break;
1034
1035 case EXECUTOR_CHALLENGE_LOCAL_MESSAGE:
1036 HandleChallengeLocalRequest(sock);
1037 break;
1038
1039 case EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE:
1040 HandleAuthenticateLocalRequest(sock);
1041 break;
1042
|
1043 kumpf 1.5 case EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE:
1044 HandleUpdateLogLevelRequest(sock);
1045 break;
1046
|
1047 kumpf 1.2 default:
1048 Fatal(FL, "Invalid request code: %d", header.code);
1049 break;
1050 }
1051 }
1052
1053 /* Reached due to socket EOF, SIGTERM, or SIGINT. */
1054
1055 Exit(0);
1056 }
|