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