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