1 kumpf 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 kumpf 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <cstdio>
35 #include <cstdlib>
36 #include <cstring>
37
38 #include <Pegasus/Common/Config.h>
39
40 #if defined(PEGASUS_OS_TYPE_WINDOWS)
41 # include <windows.h>
42 #else
43 kumpf 1.2 # include <unistd.h>
44 # include <sys/types.h>
45 # include <sys/time.h>
46 # include <sys/resource.h>
47 #endif
48
49 #if defined(PEGASUS_HAS_SIGNALS)
50 # include <sys/wait.h>
51 #endif
52
53 #include <Pegasus/Common/Constants.h>
54 #include <Pegasus/Common/Mutex.h>
|
55 kumpf 1.7 #include <Pegasus/Common/Once.h>
|
56 kumpf 1.2 #include <Pegasus/Common/FileSystem.h>
57 #include <Pegasus/Common/String.h>
58 #include <Pegasus/Common/Tracer.h>
|
59 kumpf 1.3 #include <Pegasus/Common/System.h>
|
60 kumpf 1.2 #include <Pegasus/Common/Executor.h>
61
62 #include <Executor/Strlcpy.h>
63
64 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
65 # include <Executor/Socket.h>
66 # include <Executor/Messages.h>
67 #endif
68
69 #if defined(PEGASUS_PAM_AUTHENTICATION)
70 # include <Executor/PAMAuth.h>
71 #endif
72
|
73 ouyang.jian 1.11 #ifdef PEGASUS_OS_PASE
74 # include <as400_protos.h> // For fork400()
75 #endif
76
|
77 kumpf 1.2 PEGASUS_NAMESPACE_BEGIN
78
79 ////////////////////////////////////////////////////////////////////////////////
80 //
81 //
82 // class ExecutorImpl
83 //
84 //
85 ////////////////////////////////////////////////////////////////////////////////
86
87 class ExecutorImpl
88 {
89 public:
90
91 virtual ~ExecutorImpl()
92 {
93 }
94
95 virtual int detectExecutor() = 0;
96
97 virtual int ping() = 0;
98 kumpf 1.2
99 virtual FILE* openFile(
100 const char* path,
101 int mode) = 0;
102
103 virtual int renameFile(
104 const char* oldPath,
105 const char* newPath) = 0;
106
107 virtual int removeFile(
108 const char* path) = 0;
109
110 virtual int startProviderAgent(
111 const char* module,
112 const String& pegasusHome,
113 const String& userName,
114 int& pid,
115 AnonymousPipe*& readPipe,
116 AnonymousPipe*& writePipe) = 0;
117
118 virtual int daemonizeExecutor() = 0;
119 kumpf 1.2
120 virtual int reapProviderAgent(
121 int pid) = 0;
122
123 virtual int authenticatePassword(
124 const char* username,
125 const char* password) = 0;
126
127 virtual int validateUser(
128 const char* username) = 0;
129
130 virtual int challengeLocal(
131 const char* username,
132 char challengeFilePath[EXECUTOR_BUFFER_SIZE]) = 0;
133
134 virtual int authenticateLocal(
135 const char* challengeFilePath,
136 const char* response) = 0;
|
137 kumpf 1.8
138 virtual int updateLogLevel(
139 const char* logLevel) = 0;
|
140 kumpf 1.2 };
141
142 ////////////////////////////////////////////////////////////////////////////////
143 //
144 //
145 // class ExecutorLoopbackImpl
146 //
147 //
148 ////////////////////////////////////////////////////////////////////////////////
149
150 class ExecutorLoopbackImpl : public ExecutorImpl
151 {
152 public:
153
154 virtual ~ExecutorLoopbackImpl()
155 {
156 }
157
158 virtual int detectExecutor()
159 {
160 return -1;
161 kumpf 1.2 }
162
163 virtual int ping()
164 {
165 return -1;
166 }
167
168 virtual FILE* openFile(
169 const char* path,
170 int mode)
171 {
172 switch (mode)
173 {
174 case 'r':
175 return fopen(path, "rb");
176
177 case 'w':
178 return fopen(path, "wb");
179
180 case 'a':
181 return fopen(path, "a+");
182 kumpf 1.2
183 default:
184 return NULL;
185 }
186 }
187
188 virtual int renameFile(
189 const char* oldPath,
190 const char* newPath)
191 {
192 return FileSystem::renameFile(oldPath, newPath) ? 0 : -1;
193 }
194
195
196 virtual int removeFile(
197 const char* path)
198 {
199 return FileSystem::removeFile(path) ? 0 : -1;
200 }
201
202
203 kumpf 1.2 virtual int startProviderAgent(
204 const char* module,
205 const String& pegasusHome,
206 const String& userName,
207 int& pid,
208 AnonymousPipe*& readPipe,
209 AnonymousPipe*& writePipe)
210 {
|
211 kumpf 1.6 #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
|
212 kumpf 1.2
|
213 kumpf 1.6 # if defined(PEGASUS_OS_TYPE_WINDOWS)
|
214 kumpf 1.2
215 AutoMutex autoMutex(_mutex);
216
217 // Set output parameters in case of failure.
218
219 pid = 0;
220 readPipe = 0;
221 writePipe = 0;
222
223 // Create pipes. Export handles to string.
224
225 AutoPtr<AnonymousPipe> pipeFromAgent(new AnonymousPipe());
226 AutoPtr<AnonymousPipe> pipeToAgent(new AnonymousPipe());
227
228 char readHandle[32];
229 char writeHandle[32];
230 pipeToAgent->exportReadHandle(readHandle);
231 pipeFromAgent->exportWriteHandle(writeHandle);
232
233 // Initialize PROCESS_INFORMATION.
234
235 kumpf 1.2 PROCESS_INFORMATION piProcInfo;
236 ZeroMemory(&piProcInfo, sizeof (PROCESS_INFORMATION));
237
238 // Initialize STARTUPINFO.
239
240 STARTUPINFO siStartInfo;
241 ZeroMemory(&siStartInfo, sizeof (STARTUPINFO));
242 siStartInfo.cb = sizeof (STARTUPINFO);
243
244 // Build full path of "cimprovagt" program.
245
246 String path = FileSystem::getAbsolutePath(
247 pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);
248
249 // Format command line.
250
251 char cmdLine[2048];
252
253 sprintf(cmdLine, "\"%s\" %s %s \"%s\"",
254 (const char*)path.getCString(),
255 readHandle,
256 kumpf 1.2 writeHandle,
257 module);
258
259 // Create provider agent proess.
260
261 if (!CreateProcess (
262 NULL, //
263 cmdLine, // command line
264 NULL, // process security attributes
265 NULL, // primary thread security attributes
266 TRUE, // handles are inherited
267 0, // creation flags
268 NULL, // use parent's environment
269 NULL, // use parent's current directory
270 &siStartInfo, // STARTUPINFO
271 &piProcInfo)) // PROCESS_INFORMATION
272 {
273 return -1;
274 }
275
276 CloseHandle(piProcInfo.hProcess);
277 kumpf 1.2 CloseHandle(piProcInfo.hThread);
278
279 // Close our copies of the agent's ends of the pipes
280
281 pipeToAgent->closeReadHandle();
282 pipeFromAgent->closeWriteHandle();
283
284 readPipe = pipeFromAgent.release();
285 writePipe = pipeToAgent.release();
286
287 return 0;
288
|
289 kumpf 1.6 # else /* POSIX CASE FOLLOWS */
|
290 kumpf 1.2
291 AutoMutex autoMutex(_mutex);
292
293 // Initialize output parameters in case of error.
294
295 pid = -1;
296 readPipe = 0;
297 writePipe = 0;
298
299 // Pipes:
300
301 int to[2];
302 int from[2];
303
304 do
305 {
306 // Resolve full path of "cimprovagt".
307
308 String path = FileSystem::getAbsolutePath(
309 pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);
310
|
311 kumpf 1.6 # if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
|
312 kumpf 1.3
313 PEGASUS_UID_T newUid = (PEGASUS_UID_T)-1;
314 PEGASUS_GID_T newGid = (PEGASUS_GID_T)-1;
315
316 if (userName != System::getEffectiveUserName())
317 {
318 if (!System::lookupUserId(
319 userName.getCString(), newUid, newGid))
320 {
321 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
322 "System::lookupUserId(%s) failed.",
323 (const char*)userName.getCString()));
324 return -1;
325 }
326 }
327
|
328 kumpf 1.6 # endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
|
329 kumpf 1.3
|
330 kumpf 1.2 // Create "to-agent" pipe:
331
332 if (pipe(to) != 0)
333 return -1;
334
335 // Create "from-agent" pipe:
336
337 if (pipe(from) != 0)
338 return -1;
339
340 // Fork process:
341
|
342 kumpf 1.6 # if defined(PEGASUS_OS_VMS)
|
343 kumpf 1.2 pid = (int)vfork();
|
344 ouyang.jian 1.11 # elif defined(PEGASUS_OS_PASE)
345 pid = (int)fork400("QUMEPRVAGT",0);
|
346 kumpf 1.6 # else
|
347 kumpf 1.2 pid = (int)fork();
|
348 kumpf 1.6 # endif
|
349 kumpf 1.2
350 if (pid < 0)
351 return -1;
352
353 // If child proceses.
354
355 if (pid == 0)
356 {
|
357 kumpf 1.6 # if !defined(PEGASUS_OS_VMS)
|
358 kumpf 1.2 // Close unused pipe descriptors:
359
360 close(to[1]);
361 close(from[0]);
362
363
364 // Close unused descriptors. Leave stdin, stdout, stderr,
365 // and the child's pipe descriptors open.
366
367 struct rlimit rlim;
368
369 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
370 {
371 for (int i = 3; i < int(rlim.rlim_cur); i++)
372 {
373 if (i != to[0] && i != from[1])
374 close(i);
375 }
376 }
377
|
378 kumpf 1.6 # endif /* !defined(PEGASUS_OS_VMS) */
|
379 kumpf 1.3
|
380 kumpf 1.6 # if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
|
381 kumpf 1.2
382 // Set uid and gid for the new provider agent process.
383
|
384 kumpf 1.3 if (newUid != (PEGASUS_UID_T)-1 && newGid != (PEGASUS_GID_T)-1)
|
385 kumpf 1.2 {
|
386 kumpf 1.3 if (!System::changeUserContext_SingleThreaded(
387 userName.getCString(), newUid, newGid))
|
388 kumpf 1.2 {
389 return -1;
390 }
391 }
392
|
393 kumpf 1.6 # endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
|
394 kumpf 1.2
395 // Exec the cimprovagt program.
396
397 char arg1[32];
398 char arg2[32];
399 sprintf(arg1, "%d", to[0]);
400 sprintf(arg2, "%d", from[1]);
401
402 {
403 CString cstr = path.getCString();
404 if (execl(cstr, cstr, arg1, arg2, module, (char*)0) == -1)
405 {
406 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
407 "execl() failed. errno = %d.", errno));
408 _exit(1);
409 }
410 }
411 }
412 }
413 while (0);
414
415 kumpf 1.2 // Close unused pipe descriptors.
416
417 close(to[0]);
418 close(from[1]);
419
420 // Set output parameters.
421
422 int readFd = from[0];
423 int writeFd = to[1];
424
425 // Create to and from AnonymousPipe instances to correspond to the pipe
426 // descriptors created above.
427
428 char readFdStr[32];
429 char writeFdStr[32];
430 sprintf(readFdStr, "%d", readFd);
431 sprintf(writeFdStr, "%d", writeFd);
432
433 readPipe = new AnonymousPipe(readFdStr, 0);
434 writePipe = new AnonymousPipe(0, writeFdStr);
435
436 kumpf 1.2 return 0;
437
|
438 kumpf 1.6 # endif /* POSIX CASE */
439
440 #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
441
442 // Out-of-Process providers are never started by the cimserver process
443 // when Privilege Separation is enabled.
444 return -1;
445
446 #endif
|
447 kumpf 1.2 }
448
449 virtual int daemonizeExecutor()
450 {
451 return -1;
452 }
453
454 virtual int reapProviderAgent(
455 int pid)
456 {
|
457 kumpf 1.6 #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
458
|
459 kumpf 1.2 int status = 0;
460
|
461 kumpf 1.6 # if defined(PEGASUS_HAS_SIGNALS)
|
462 kumpf 1.2 while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
463 ;
|
464 kumpf 1.6 # endif
|
465 kumpf 1.2
466 return status;
|
467 kumpf 1.6
468 #else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */
469
470 // Out-of-Process providers are never started by the cimserver process
471 // when Privilege Separation is enabled.
472 return -1;
473
474 #endif
|
475 kumpf 1.2 }
476
477 virtual int authenticatePassword(
478 const char* username,
479 const char* password)
480 {
481 #if defined(PEGASUS_PAM_AUTHENTICATION)
482 return PAMAuthenticate(username, password);
483 #else
484 // ATTN: not handled so don't call in this case.
485 return -1;
486 #endif
487 }
488
489 virtual int validateUser(
490 const char* username)
491 {
492 #if defined(PEGASUS_PAM_AUTHENTICATION)
493 return PAMValidateUser(username);
494 #else
495 // ATTN: not handled so don't call in this case.
496 kumpf 1.2 return -1;
497 #endif
498 }
499
500 virtual int challengeLocal(
501 const char* username,
502 char challengeFilePath[EXECUTOR_BUFFER_SIZE])
503 {
504 // ATTN: not handled so don't call in this case.
505 return -1;
506 }
507
508 virtual int authenticateLocal(
509 const char* challengeFilePath,
510 const char* response)
511 {
512 // ATTN: not handled so don't call in this case.
513 return -1;
514 }
515
|
516 kumpf 1.8 virtual int updateLogLevel(
517 const char* logLevel)
518 {
519 // If Privilege Separation is not enabled, we don't need to update
520 // the log level in the Executor.
521 return 0;
522 }
523
|
524 kumpf 1.2 private:
525
526 Mutex _mutex;
527 };
528
529 ////////////////////////////////////////////////////////////////////////////////
530 //
531 //
532 // class ExecutorSocketImpl : public ExecutorImpl
533 //
534 //
535 ////////////////////////////////////////////////////////////////////////////////
536
537 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
538
539 class ExecutorSocketImpl : public ExecutorImpl
540 {
541 public:
542
543 ExecutorSocketImpl(int sock) : _sock(sock)
544 {
545 kumpf 1.2 }
546
547 virtual ~ExecutorSocketImpl()
548 {
549 }
550
551 virtual int detectExecutor()
552 {
553 return 0;
554 }
555
556 virtual int ping()
557 {
558 AutoMutex autoMutex(_mutex);
559
|
560 kumpf 1.9 // Send request header:
|
561 kumpf 1.2
562 ExecutorRequestHeader header;
563 header.code = EXECUTOR_PING_MESSAGE;
564
|
565 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
566 kumpf 1.2 return -1;
567
568 ExecutorPingResponse response;
569
|
570 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
571 kumpf 1.2 return -1;
572
573 if (response.magic == EXECUTOR_PING_MAGIC)
574 return 0;
575
576 return -1;
577 }
578
579 virtual FILE* openFile(
580 const char* path,
581 int mode)
582 {
583 AutoMutex autoMutex(_mutex);
584
585 if (mode != 'r' && mode != 'w' && mode != 'a')
586 return NULL;
587
|
588 kumpf 1.9 // Send request header:
|
589 kumpf 1.2
590 ExecutorRequestHeader header;
591 header.code = EXECUTOR_OPEN_FILE_MESSAGE;
592
|
593 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
594 kumpf 1.2 return NULL;
595
|
596 kumpf 1.9 // Send request body.
|
597 kumpf 1.2
598 ExecutorOpenFileRequest request;
599 memset(&request, 0, sizeof(request));
600 Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
601 request.mode = mode;
602
|
603 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
604 kumpf 1.2 return NULL;
605
606 // Receive the response
607
608 ExecutorOpenFileResponse response;
609
|
610 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
611 kumpf 1.2 return NULL;
612
613 // Receive descriptor (if response successful).
614
615 if (response.status == 0)
616 {
617 int fds[1];
618
619 if (RecvDescriptorArray(_sock, fds, 1) != 0)
620 return NULL;
621
622 if (fds[0] == -1)
623 return NULL;
624 else
625 {
626 if (mode == 'r')
627 return fdopen(fds[0], "rb");
628 else
629 return fdopen(fds[0], "wb");
630 }
631 }
632 kumpf 1.2
633 return NULL;
634 }
635
636 virtual int renameFile(
637 const char* oldPath,
638 const char* newPath)
639 {
640 AutoMutex autoMutex(_mutex);
641
|
642 kumpf 1.9 // Send request header:
|
643 kumpf 1.2
644 ExecutorRequestHeader header;
645 header.code = EXECUTOR_RENAME_FILE_MESSAGE;
646
|
647 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
648 kumpf 1.2 return -1;
649
|
650 kumpf 1.9 // Send request body.
|
651 kumpf 1.2
652 ExecutorRenameFileRequest request;
653 memset(&request, 0, sizeof(request));
654 Strlcpy(request.oldPath, oldPath, EXECUTOR_BUFFER_SIZE);
655 Strlcpy(request.newPath, newPath, EXECUTOR_BUFFER_SIZE);
656
|
657 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
658 kumpf 1.2 return -1;
659
660 // Receive the response
661
662 ExecutorRenameFileResponse response;
663
|
664 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
665 kumpf 1.2 return -1;
666
667 return response.status;
668 }
669
670 virtual int removeFile(
671 const char* path)
672 {
673 AutoMutex autoMutex(_mutex);
674
|
675 kumpf 1.9 // Send request header:
|
676 kumpf 1.2
677 ExecutorRequestHeader header;
678 header.code = EXECUTOR_REMOVE_FILE_MESSAGE;
679
|
680 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
681 kumpf 1.2 return -1;
682
|
683 kumpf 1.9 // Send request body.
|
684 kumpf 1.2
685 ExecutorRemoveFileRequest request;
686 memset(&request, 0, sizeof(request));
687 Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
688
|
689 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
690 kumpf 1.2 return -1;
691
692 // Receive the response
693
694 ExecutorRemoveFileResponse response;
695
|
696 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
697 kumpf 1.2 return -1;
698
699 return response.status;
700 }
701
702 virtual int startProviderAgent(
703 const char* module,
704 const String& pegasusHome,
705 const String& userName,
706 int& pid,
707 AnonymousPipe*& readPipe,
708 AnonymousPipe*& writePipe)
709 {
710 AutoMutex autoMutex(_mutex);
711
712 readPipe = 0;
713 writePipe = 0;
714
715 // Reject strings longer than EXECUTOR_BUFFER_SIZE.
716
|
717 kumpf 1.3 size_t moduleNameLength = strlen(module);
718
719 if (moduleNameLength >= EXECUTOR_BUFFER_SIZE)
720 return -1;
721
722 CString userNameCString = userName.getCString();
723 size_t userNameLength = strlen(userNameCString);
|
724 kumpf 1.2
|
725 kumpf 1.3 if (userNameLength >= EXECUTOR_BUFFER_SIZE)
|
726 kumpf 1.2 return -1;
727
|
728 kumpf 1.9 // Send request header:
|
729 kumpf 1.2
730 ExecutorRequestHeader header;
731 header.code = EXECUTOR_START_PROVIDER_AGENT_MESSAGE;
732
|
733 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
734 kumpf 1.2 return -1;
735
|
736 kumpf 1.9 // Send request body.
|
737 kumpf 1.2
738 ExecutorStartProviderAgentRequest request;
739 memset(&request, 0, sizeof(request));
|
740 kumpf 1.3 memcpy(request.module, module, moduleNameLength);
741 memcpy(request.userName, userNameCString, userNameLength);
|
742 kumpf 1.2
|
743 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
744 kumpf 1.2 return -1;
745
746 // Receive the response
747
748 ExecutorStartProviderAgentResponse response;
749
|
750 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
751 kumpf 1.2 return -1;
752
753 // Check response status and pid.
754
755 if (response.status != 0)
756 return -1;
757
758 // Get pid:
759
760 pid = response.pid;
761
762 // Receive descriptors.
763
764 int descriptors[2];
765 int result = RecvDescriptorArray(_sock, descriptors, 2);
766
767 if (result == 0)
768 {
769 int readFd = descriptors[0];
770 int writeFd = descriptors[1];
771
772 kumpf 1.2 // Create to and from AnonymousPipe instances to correspond to
773 // the pipe descriptors created above.
774
775 char readFdStr[32];
776 char writeFdStr[32];
777 sprintf(readFdStr, "%d", readFd);
778 sprintf(writeFdStr, "%d", writeFd);
779
780 readPipe = new AnonymousPipe(readFdStr, 0);
781 writePipe = new AnonymousPipe(0, writeFdStr);
782 }
783
784 return result;
785 }
786
787 virtual int daemonizeExecutor()
788 {
789 AutoMutex autoMutex(_mutex);
790
|
791 kumpf 1.9 // Send request header:
|
792 kumpf 1.2
793 ExecutorRequestHeader header;
794 header.code = EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE;
795
|
796 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
797 kumpf 1.2 return -1;
798
799 // Receive the response
800
801 ExecutorDaemonizeExecutorResponse response;
802
|
803 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
804 kumpf 1.2 return -1;
805
806 return response.status;
807 }
808
809 virtual int reapProviderAgent(
810 int pid)
811 {
|
812 kumpf 1.10 // The Executor process automatically cleans up all its child
813 // processes, so it does not need to explicitly harvest the
814 // exit status of the cimprovagt processes it starts.
|
815 kumpf 1.2
|
816 kumpf 1.10 return 0;
|
817 kumpf 1.2 }
818
819 virtual int authenticatePassword(
820 const char* username,
821 const char* password)
822 {
823 AutoMutex autoMutex(_mutex);
824
|
825 kumpf 1.9 // Send request header:
|
826 kumpf 1.2
827 ExecutorRequestHeader header;
828 header.code = EXECUTOR_AUTHENTICATE_PASSWORD_MESSAGE;
829
|
830 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
831 kumpf 1.2 return -1;
832
|
833 kumpf 1.9 // Send request body.
|
834 kumpf 1.2
835 ExecutorAuthenticatePasswordRequest request;
836 memset(&request, 0, sizeof(request));
837 Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
838 Strlcpy(request.password, password, EXECUTOR_BUFFER_SIZE);
839
|
840 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
841 kumpf 1.2 return -1;
842
843 // Receive the response
844
845 ExecutorAuthenticatePasswordResponse response;
846
|
847 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
848 kumpf 1.2 return -1;
849
850 return response.status;
851 }
852
853 virtual int validateUser(
854 const char* username)
855 {
856 AutoMutex autoMutex(_mutex);
857
|
858 kumpf 1.9 // Send request header:
|
859 kumpf 1.2
860 ExecutorRequestHeader header;
861 header.code = EXECUTOR_VALIDATE_USER_MESSAGE;
862
|
863 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
864 kumpf 1.2 return -1;
865
|
866 kumpf 1.9 // Send request body.
|
867 kumpf 1.2
868 ExecutorValidateUserRequest request;
869 memset(&request, 0, sizeof(request));
870 Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
871
|
872 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
873 kumpf 1.2 return -1;
874
875 // Receive the response
876
877 ExecutorValidateUserResponse response;
878
|
879 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
880 kumpf 1.2 return -1;
881
882 return response.status;
883 }
884
885 virtual int challengeLocal(
886 const char* username,
887 char challengeFilePath[EXECUTOR_BUFFER_SIZE])
888 {
889 AutoMutex autoMutex(_mutex);
890
|
891 kumpf 1.9 // Send request header:
|
892 kumpf 1.2
893 ExecutorRequestHeader header;
894 header.code = EXECUTOR_CHALLENGE_LOCAL_MESSAGE;
895
|
896 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
897 kumpf 1.2 return -1;
898
|
899 kumpf 1.9 // Send request body.
|
900 kumpf 1.2
901 ExecutorChallengeLocalRequest request;
902 memset(&request, 0, sizeof(request));
903 Strlcpy(request.user, username, EXECUTOR_BUFFER_SIZE);
904
|
905 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
906 kumpf 1.2 return -1;
907
908 // Receive the response
909
910 ExecutorChallengeLocalResponse response;
911
|
912 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
913 kumpf 1.2 return -1;
914
915 Strlcpy(challengeFilePath, response.challenge, EXECUTOR_BUFFER_SIZE);
916
917 return response.status;
918 }
919
920 virtual int authenticateLocal(
921 const char* challengeFilePath,
922 const char* response)
923 {
924 AutoMutex autoMutex(_mutex);
925
|
926 kumpf 1.9 // Send request header:
|
927 kumpf 1.2
928 ExecutorRequestHeader header;
929 header.code = EXECUTOR_AUTHENTICATE_LOCAL_MESSAGE;
930
|
931 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
932 kumpf 1.2 return -1;
933
|
934 kumpf 1.9 // Send request body.
|
935 kumpf 1.2
936 ExecutorAuthenticateLocalRequest request;
937 memset(&request, 0, sizeof(request));
938 Strlcpy(request.challenge, challengeFilePath, EXECUTOR_BUFFER_SIZE);
939 Strlcpy(request.response, response, EXECUTOR_BUFFER_SIZE);
940
|
941 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
942 kumpf 1.2 return -1;
943
944 // Receive the response
945
946 ExecutorAuthenticateLocalResponse response_;
947
|
948 kumpf 1.9 if (RecvBlock(_sock, &response_, sizeof(response_)) !=
949 sizeof(response_))
950 {
|
951 kumpf 1.2 return -1;
|
952 kumpf 1.9 }
|
953 kumpf 1.2
954 return response_.status;
955 }
956
|
957 kumpf 1.8 virtual int updateLogLevel(
958 const char* logLevel)
959 {
960 AutoMutex autoMutex(_mutex);
961
|
962 kumpf 1.9 // Send request header:
|
963 kumpf 1.8
964 ExecutorRequestHeader header;
965 header.code = EXECUTOR_UPDATE_LOG_LEVEL_MESSAGE;
966
|
967 kumpf 1.9 if (SendBlock(_sock, &header, sizeof(header)) != sizeof(header))
|
968 kumpf 1.8 return -1;
969
|
970 kumpf 1.9 // Send request body:
|
971 kumpf 1.8
972 ExecutorUpdateLogLevelRequest request;
973 memset(&request, 0, sizeof(request));
974 Strlcpy(request.logLevel, logLevel, EXECUTOR_BUFFER_SIZE);
975
|
976 kumpf 1.9 if (SendBlock(_sock, &request, sizeof(request)) != sizeof(request))
|
977 kumpf 1.8 return -1;
978
979 // Receive the response
980
981 ExecutorUpdateLogLevelResponse response;
982
|
983 kumpf 1.9 if (RecvBlock(_sock, &response, sizeof(response)) != sizeof(response))
|
984 kumpf 1.8 return -1;
985
986 return response.status;
987 }
988
|
989 kumpf 1.2 private:
990
991 int _sock;
992 Mutex _mutex;
993 };
994
995 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
996
997 ////////////////////////////////////////////////////////////////////////////////
998 //
999 //
1000 // class Executor
1001 //
1002 //
1003 ////////////////////////////////////////////////////////////////////////////////
1004
1005 static int _executorSock = -1;
|
1006 kumpf 1.5 static AutoPtr<ExecutorImpl> _executorImpl;
|
1007 kumpf 1.7 static Once _executorImplOnce = PEGASUS_ONCE_INITIALIZER;
|
1008 kumpf 1.2
|
1009 kumpf 1.7 static void _initExecutorImpl()
|
1010 kumpf 1.2 {
1011 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
|
1012 kumpf 1.7 if (_executorSock == -1)
1013 _executorImpl.reset(new ExecutorLoopbackImpl());
1014 else
1015 _executorImpl.reset(new ExecutorSocketImpl(_executorSock));
|
1016 kumpf 1.2 #else
|
1017 kumpf 1.7 _executorImpl.reset(new ExecutorLoopbackImpl());
|
1018 kumpf 1.2 #endif
1019 }
1020
1021 void Executor::setSock(int sock)
1022 {
1023 _executorSock = sock;
1024 }
1025
1026 int Executor::detectExecutor()
1027 {
|
1028 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1029 return _executorImpl->detectExecutor();
|
1030 kumpf 1.2 }
1031
1032 int Executor::ping()
1033 {
|
1034 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1035 return _executorImpl->ping();
|
1036 kumpf 1.2 }
1037
1038 FILE* Executor::openFile(
1039 const char* path,
1040 int mode)
1041 {
|
1042 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1043 return _executorImpl->openFile(path, mode);
|
1044 kumpf 1.2 }
1045
1046 int Executor::renameFile(
1047 const char* oldPath,
1048 const char* newPath)
1049 {
|
1050 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1051 return _executorImpl->renameFile(oldPath, newPath);
|
1052 kumpf 1.2 }
1053
1054 int Executor::removeFile(
1055 const char* path)
1056 {
|
1057 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1058 return _executorImpl->removeFile(path);
|
1059 kumpf 1.2 }
1060
1061 int Executor::startProviderAgent(
1062 const char* module,
1063 const String& pegasusHome,
1064 const String& userName,
1065 int& pid,
1066 AnonymousPipe*& readPipe,
1067 AnonymousPipe*& writePipe)
1068 {
|
1069 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1070 return _executorImpl->startProviderAgent(
|
1071 kumpf 1.3 module, pegasusHome, userName, pid, readPipe, writePipe);
|
1072 kumpf 1.2 }
1073
1074 int Executor::daemonizeExecutor()
1075 {
|
1076 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1077 return _executorImpl->daemonizeExecutor();
|
1078 kumpf 1.2 }
1079
1080 int Executor::reapProviderAgent(
1081 int pid)
1082 {
|
1083 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1084 return _executorImpl->reapProviderAgent(pid);
|
1085 kumpf 1.2 }
1086
1087 int Executor::authenticatePassword(
1088 const char* username,
1089 const char* password)
1090 {
|
1091 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1092 return _executorImpl->authenticatePassword(username, password);
|
1093 kumpf 1.2 }
1094
1095 int Executor::validateUser(
1096 const char* username)
1097 {
|
1098 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1099 return _executorImpl->validateUser(username);
|
1100 kumpf 1.2 }
1101
1102 int Executor::challengeLocal(
1103 const char* user,
1104 char challengeFilePath[EXECUTOR_BUFFER_SIZE])
1105 {
|
1106 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1107 return _executorImpl->challengeLocal(user, challengeFilePath);
|
1108 kumpf 1.2 }
1109
1110 int Executor::authenticateLocal(
1111 const char* challengeFilePath,
1112 const char* response)
1113 {
|
1114 kumpf 1.7 once(&_executorImplOnce, _initExecutorImpl);
1115 return _executorImpl->authenticateLocal(challengeFilePath, response);
|
1116 kumpf 1.2 }
1117
|
1118 kumpf 1.8 int Executor::updateLogLevel(
1119 const char* logLevel)
1120 {
1121 once(&_executorImplOnce, _initExecutorImpl);
1122 return _executorImpl->updateLogLevel(logLevel);
1123 }
1124
|
1125 kumpf 1.2 PEGASUS_NAMESPACE_END
|