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