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