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