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