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