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