1 mike 1.1.2.1 //%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 mike 1.1.2.1 // 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 <cstdlib>
37 #include <cstring>
38
39 #if defined(PEGASUS_OS_TYPE_WINDOWS)
40 # include <windows.h>
41 #else
42 # include <sys/types.h>
43 mike 1.1.2.1 # include <sys/socket.h>
44 # include <unistd.h>
45 # include <fcntl.h>
46 # include <sys/wait.h>
47 # include <unistd.h>
48 # include <sys/time.h>
49 # include <sys/resource.h>
50 #endif
51
52 #include "Constants.h"
53 #include "Executor.h"
54 #include "Mutex.h"
55 #include "FileSystem.h"
56 #include "String.h"
|
57 mike 1.1.2.5 #include <Executor/Strlcpy.h>
58 #include <Executor/Strlcat.h>
|
59 mike 1.1.2.1
60 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
|
61 mike 1.1.2.5 # include <Executor/Messages.h>
|
62 mike 1.1.2.1 #endif
63
64 #if defined(PEGASUS_PAM_AUTHENTICATION)
65 # include <Pegasus/Security/Cimservera/cimservera.h>
66 #endif
67
68 PEGASUS_NAMESPACE_BEGIN
69
70 static int _sock = -1;
71 static Mutex _mutex;
72
|
73 mike 1.1.2.2 static int _getSock()
74 {
75 int sock;
76 _mutex.lock();
77 sock = _sock;
78 _mutex.unlock();
79 return sock;
80 }
81
|
82 mike 1.1.2.1 ////////////////////////////////////////////////////////////////////////////////
83 ////////////////////////////////////////////////////////////////////////////////
84 ////
85 //// InProcess stubs:
86 ////
87 ////////////////////////////////////////////////////////////////////////////////
88 ////////////////////////////////////////////////////////////////////////////////
89
90 static int InProcess_ping()
91 {
92 // Nothing to do.
93 return 0;
94 }
95
96 FILE* InProcess_openFile(
97 const char* path,
98 int mode)
99 {
100 switch (mode)
101 {
102 case 'r':
103 mike 1.1.2.1 return fopen(path, "rb");
104
105 case 'w':
106 return fopen(path, "wb");
107
108 default:
109 return NULL;
110 }
111 }
112
113 static int InProcess_renameFile(
114 const char* oldPath,
115 const char* newPath)
116 {
117 return FileSystem::renameFile(oldPath, newPath) ? 0 : -1;
118 }
119
120 static int InProcess_removeFile(
121 const char* path)
122 {
123 return FileSystem::removeFile(path) ? 0 : -1;
124 mike 1.1.2.1 }
125
126 static int _getProviderAgentPath(String& path)
127 {
128 // ATTN: is this really a sufficient replacement for getHomedPath().
129 // Does getHomedPath() use the configuration file?
130
131 path = PEGASUS_PROVIDER_AGENT_PROC_NAME;
132
133 if (path[0] != '/')
134 {
135 const char* env = getenv("PEGASUS_HOME");
136
137 if (!env)
138 return -1;
139
140 path = String(env) + String("/") + path;
141 }
142
143 return 0;
144 }
145 mike 1.1.2.1
146 #if defined(PEGASUS_OS_TYPE_WINDOWS)
147
148 static int InProcess_startProviderAgent(
149 const char* module,
150 int uid,
151 int gid,
152 int& pid,
153 AnonymousPipe*& readPipe,
154 AnonymousPipe*& writePipe)
155 {
156 AutoMutex autoMutex(_mutex);
157
158 // Set output parameters in case of failure.
159
160 pid = 0;
161 readPipe = 0;
162 writePipe = 0;
163
164 // Create pipes. Export handles to string.
165
166 mike 1.1.2.1 AnonymousPipe* pipeFromAgent = new AnonymousPipe();
167 AnonymousPipe* pipeToAgent = new AnonymousPipe();
168
169 char readHandle[32];
170 char writeHandle[32];
171 pipeToAgent->exportReadHandle(readHandle);
172 pipeFromAgent->exportWriteHandle(writeHandle);
173
174 // Initialize PROCESS_INFORMATION.
175
176 PROCESS_INFORMATION piProcInfo;
177 ZeroMemory(&piProcInfo, sizeof (PROCESS_INFORMATION));
178
179 // Initialize STARTUPINFO.
180
181 STARTUPINFO siStartInfo;
182 ZeroMemory(&siStartInfo, sizeof (STARTUPINFO));
183 siStartInfo.cb = sizeof (STARTUPINFO);
184
185 // Build full path of "cimprovagt" program.
186
187 mike 1.1.2.1 String path;
188
189 if (_getProviderAgentPath(path) != 0)
190 {
191 delete pipeToAgent;
192 delete pipeFromAgent;
193 return -1;
194 }
195
196 // Format command line.
197
198 char cmdLine[2048];
199
200 sprintf(cmdLine, "\"%s\" %s %s \"%s\"",
201 (const char*)path.getCString(),
202 readHandle,
203 writeHandle,
204 module);
205
206 // Create provider agent proess.
207
208 mike 1.1.2.1 if (!CreateProcess (
209 NULL, //
210 cmdLine, // command line
211 NULL, // process security attributes
212 NULL, // primary thread security attributes
213 TRUE, // handles are inherited
214 0, // creation flags
215 NULL, // use parent's environment
216 NULL, // use parent's current directory
217 &siStartInfo, // STARTUPINFO
218 &piProcInfo)) // PROCESS_INFORMATION
219 {
220 delete pipeToAgent;
221 delete pipeFromAgent;
222 return -1;
223 }
224
225 CloseHandle(piProcInfo.hProcess);
226 CloseHandle(piProcInfo.hThread);
227
228 // Close our copies of the agent's ends of the pipes
229 mike 1.1.2.1
230 pipeToAgent->closeReadHandle();
231 pipeFromAgent->closeWriteHandle();
232
233 readPipe = pipeFromAgent;
234 writePipe = pipeToAgent;
235
236 return 0;
237 }
238
239 #elif defined(PEGASUS_OS_OS400)
240
241 static int InProcess_startProviderAgent(
242 const char* module,
243 int uid,
244 int gid,
245 int& pid,
246 AnonymousPipe*& readPipe,
247 AnonymousPipe*& writePipe)
248 {
249 // ATTN: no implementation for OS400.
250 mike 1.1.2.1 return -1;
251 }
252
253 #else /* POSIX CASE FOLLOWS */
254
255 static int InProcess_startProviderAgent(
256 const char* module,
257 int uid,
258 int gid,
259 int& pid,
260 AnonymousPipe*& readPipe,
261 AnonymousPipe*& writePipe)
262 {
263 AutoMutex autoMutex(_mutex);
264
265 // Initialize output parameters in case of error.
266
267 pid = -1;
268 readPipe = 0;
269 writePipe = 0;
270
271 mike 1.1.2.1 // Pipes:
272
273 int to[2];
274 int from[2];
275
276 do
277 {
278 // Resolve full path of "cimprovagt".
279
280 String path;
281
282 if (_getProviderAgentPath(path) != 0)
283 return -1;
284
285 // Create "to-agent" pipe:
286
287 if (pipe(to) != 0)
288 return -1;
289
290 // Create "from-agent" pipe:
291
292 mike 1.1.2.1 if (pipe(from) != 0)
293 return -1;
294
295 // Fork process:
296
297 #if !defined(PEGASUS_OS_VMS)
298 pid = (int)vfork();
299 #else
300 pid = (int)fork();
301 #endif
302
303 if (pid < 0)
304 return -1;
305
306 // If child proceses.
307
308 if (pid == 0)
309 {
310 // Close unused pipe descriptors:
311
312 close(to[1]);
313 mike 1.1.2.1 close(from[0]);
314
315 #if !defined(PEGASUS_OS_VMS)
316
317 // Close unused descriptors. Leave stdin, stdout, stderr, and the
318 // child's pipe descriptors open.
319
320 struct rlimit rlim;
321
322 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
323 {
324 for (int i = 3; i < int(rlim.rlim_cur); i++)
325 {
326 if (i != to[0] && i != from[1])
327 close(i);
328 }
329 }
330
331 #endif /* !defined(PEGASUS_OS_VMS) */
332
333 // Set uid and gid for the new provider agent process.
334 mike 1.1.2.1
335 # if !defined(PEGASUS_DISABLE_PROV_USERCTXT)
336
337 if (uid != -1 && gid != -1)
338 {
339 if ((int)getgid() != gid)
340 {
341 // ATTN: log failure!
342 setgid(gid);
343 }
344
345 if ((int)getuid() != uid)
346 {
347 // ATTN: log failure!
348 setuid(uid);
349 }
350 }
351
352 # endif /* !defined(PEGASUS_DISABLE_PROV_USERCTXT) */
353
354 // Exec the cimprovagt program.
355 mike 1.1.2.1
356 char arg1[32];
357 char arg2[32];
358 sprintf(arg1, "%d", to[0]);
359 sprintf(arg2, "%d", from[1]);
360
361 {
362 CString cstr = path.getCString();
363 execl(cstr, cstr, arg1, arg2, module, (char*)0);
364 _exit(1);
365 }
366
367 // ATTN: log failure!
368 }
369 }
370 while (0);
371
372 // Close unused pipe descriptors.
373
374 close(to[0]);
375 close(from[1]);
376 mike 1.1.2.1
377 // Set output parameters.
378
379 int readFd = from[0];
380 int writeFd = to[1];
381
382 // Create to and from AnonymousPipe instances to correspond to the pipe
383 // descriptors created above.
384
385 char readFdStr[32];
386 char writeFdStr[32];
387 sprintf(readFdStr, "%d", readFd);
388 sprintf(writeFdStr, "%d", writeFd);
389
390 readPipe = new AnonymousPipe(readFdStr, 0);
391 writePipe = new AnonymousPipe(0, writeFdStr);
392
393 return 0;
394 }
395
396 #endif /* !defined(START_PROVIDER_AGENT) */
397 mike 1.1.2.1
398 static int InProcess_daemonizeExecutor()
399 {
400 // Nothing to do.
401 return 0;
402 }
403
404 static int InProcess_changeOwner(
405 const char* path,
406 const char* owner)
407 {
408 return FileSystem::changeFileOwner(path, owner) ? 0 : -1;
409 }
410
411 static int InProcess_waitPid(
412 int pid)
413 {
414 int status;
415
416 while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
417 ;
418 mike 1.1.2.1
419 return status;
420 }
421
422 static int InProcess_pamAuthenticate(
423 const char* username,
424 const char* password)
425 {
426 #if defined(PEGASUS_PAM_AUTHENTICATION)
427 return PAMAuthenticate(username, password);
428 #else
429 return -1;
430 #endif
431 }
432
433 static int InProcess_pamValidateUser(
434 const char* username)
435 {
436 #if defined(PEGASUS_PAM_AUTHENTICATION)
437 return PAMValidateUser(username);
438 #else
439 mike 1.1.2.1 return -1;
440 #endif
441 }
442
443 ////////////////////////////////////////////////////////////////////////////////
444 ////////////////////////////////////////////////////////////////////////////////
445 ////
446 //// Out-of-process stubs.
447 ////
448 ////////////////////////////////////////////////////////////////////////////////
449 ////////////////////////////////////////////////////////////////////////////////
450
451 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
452
|
453 mike 1.1.2.3 //==============================================================================
454 //
455 // _recv()
456 //
457 // Receives *size* bytes from the given socket.
458 //
459 //==============================================================================
460
461 static ssize_t _recv(int sock, void* buffer, size_t size)
462 {
463 size_t r = size;
464 char* p = (char*)buffer;
465
466 if (size == 0)
467 return -1;
468
469 while (r)
470 {
471 ssize_t n;
472
|
473 mike 1.1.2.4 EXECUTOR_RESTART(read(sock, p, r), n);
|
474 mike 1.1.2.3
475 if (n == -1)
476 return -1;
477 else if (n == 0)
478 return size - r;
479
480 r -= n;
481 p += n;
482 }
483
484 return size - r;
485 }
486
487 //==============================================================================
488 //
489 // _send()
490 //
491 // Sends *size* bytes on the given socket.
492 //
493 //==============================================================================
494
495 mike 1.1.2.3 static ssize_t _send(int sock, void* buffer, size_t size)
496 {
497 size_t r = size;
498 char* p = (char*)buffer;
499
500 while (r)
501 {
502 ssize_t n;
|
503 mike 1.1.2.4 EXECUTOR_RESTART(write(sock, p, r), n);
|
504 mike 1.1.2.3
505 if (n == -1)
506 return -1;
507 else if (n == 0)
508 return size - r;
509
510 r -= n;
511 p += n;
512 }
513
514 return size - r;
515 }
516
|
517 mike 1.1.2.1 static int _receiveDescriptorArray(int sock, int descriptors[], size_t count)
518 {
519 // This control data begins with a cmsghdr struct followed by the data
520 // (a descriptor in this case). The union ensures that the data is aligned
521 // suitably for the leading cmsghdr struct. The descriptor itself is
522 // properly aligned since the cmsghdr ends on a boundary that is suitably
523 // aligned for any type (including int).
524 //
525 // ControlData = [ cmsghdr | int ]
526
527 size_t size = CMSG_SPACE(sizeof(int) * count);
528 char* data = (char*)malloc(size);
529
530 // Define a msghdr that refers to the control data, which is filled in
531 // by calling recvmsg() below.
532
533 msghdr mh;
534 memset(&mh, 0, sizeof(mh));
535 mh.msg_control = data;
536 mh.msg_controllen = size;
537
538 mike 1.1.2.1 // The other process sends a single-byte message. This byte is not
539 // used since we only need the control data (the descriptor) but we
540 // must request at least one byte from recvmsg().
541
542 struct iovec iov[1];
543 memset(iov, 0, sizeof(iov));
544
545 char dummy;
546 iov[0].iov_base = &dummy;
547 iov[0].iov_len = 1;
548 mh.msg_iov = iov;
549 mh.msg_iovlen = 1;
550
551 // Receive the message from the other process.
552
553 ssize_t n = recvmsg(sock, &mh, 0);
554
555 if (n <= 0)
556 return -1;
557
558 // Get a pointer to control message. Return if the header is null or does
559 mike 1.1.2.1 // not contain what we expect.
560
561 cmsghdr* cmh = CMSG_FIRSTHDR(&mh);
562
563 if (!cmh ||
564 cmh->cmsg_len != CMSG_LEN(sizeof(int) * count) ||
565 cmh->cmsg_level != SOL_SOCKET ||
566 cmh->cmsg_type != SCM_RIGHTS)
567 {
568 return -1;
569 }
570
571 // Copy the data:
572
573 memcpy(descriptors, CMSG_DATA(cmh), sizeof(int) * count);
574
575 return 0;
576 }
577
578 static int OutOfProcess_ping()
579 {
580 mike 1.1.2.1 AutoMutex autoMutex(_mutex);
581
|
582 mike 1.1.2.3 // _send request header:
|
583 mike 1.1.2.1
584 ExecutorRequestHeader header;
|
585 mike 1.1.2.5 header.code = EXECUTOR_PING_MESSAGE;
|
586 mike 1.1.2.1
|
587 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
588 mike 1.1.2.1 return -1;
589
590 ExecutorPingResponse response;
591
|
592 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
593 mike 1.1.2.1 return -1;
594
595 if (response.magic == EXECUTOR_PING_MAGIC)
596 return 0;
597
598 return -1;
599 }
600
601 FILE* OutOfProcess_openFile(
602 const char* path,
603 int mode)
604 {
605 AutoMutex autoMutex(_mutex);
606
607 if (mode != 'r' && mode != 'w')
608 return NULL;
609
|
610 mike 1.1.2.3 // _send request header:
|
611 mike 1.1.2.1
612 ExecutorRequestHeader header;
|
613 mike 1.1.2.5 header.code = EXECUTOR_OPEN_FILE_MESSAGE;
|
614 mike 1.1.2.1
|
615 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
616 mike 1.1.2.1 return NULL;
617
|
618 mike 1.1.2.3 // _send request body.
|
619 mike 1.1.2.1
620 ExecutorOpenFileRequest request;
621 memset(&request, 0, sizeof(request));
622 Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
623 request.mode = mode;
624
|
625 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
626 mike 1.1.2.1 return NULL;
627
628 // Receive the response
629
630 ExecutorOpenFileResponse response;
631
|
632 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
633 mike 1.1.2.1 return NULL;
634
635 // Receive descriptor (if response successful).
636
637 if (response.status == 0)
638 {
639 int fds[1];
640
|
641 mike 1.1.2.2 if (_receiveDescriptorArray(_getSock(), fds, 1) != 0)
|
642 mike 1.1.2.1 return NULL;
643
644 if (fds[0] == -1)
645 return NULL;
646 else
647 {
648 if (mode == 'r')
649 return fdopen(fds[0], "rb");
650 else
651 return fdopen(fds[0], "wb");
652 }
653 }
654
655 return NULL;
656 }
657
658 static int OutOfProcess_renameFile(
659 const char* oldPath,
660 const char* newPath)
661 {
662 AutoMutex autoMutex(_mutex);
663 mike 1.1.2.1
|
664 mike 1.1.2.3 // _send request header:
|
665 mike 1.1.2.1
666 ExecutorRequestHeader header;
|
667 mike 1.1.2.5 header.code = EXECUTOR_RENAME_FILE_MESSAGE;
|
668 mike 1.1.2.1
|
669 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
670 mike 1.1.2.1 return -1;
671
|
672 mike 1.1.2.3 // _send request body.
|
673 mike 1.1.2.1
674 ExecutorRenameFileRequest request;
675 memset(&request, 0, sizeof(request));
676 Strlcpy(request.oldPath, oldPath, EXECUTOR_BUFFER_SIZE);
677 Strlcpy(request.newPath, newPath, EXECUTOR_BUFFER_SIZE);
678
|
679 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
680 mike 1.1.2.1 return -1;
681
682 // Receive the response
683
684 ExecutorRenameFileResponse response;
685
|
686 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
687 mike 1.1.2.1 return -1;
688
689 return response.status;
690 }
691
692 static int OutOfProcess_removeFile(
693 const char* path)
694 {
695 AutoMutex autoMutex(_mutex);
696
|
697 mike 1.1.2.3 // _send request header:
|
698 mike 1.1.2.1
699 ExecutorRequestHeader header;
|
700 mike 1.1.2.5 header.code = EXECUTOR_REMOVE_FILE_MESSAGE;
|
701 mike 1.1.2.1
|
702 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
703 mike 1.1.2.1 return -1;
704
|
705 mike 1.1.2.3 // _send request body.
|
706 mike 1.1.2.1
707 ExecutorRemoveFileRequest request;
708 memset(&request, 0, sizeof(request));
709 Strlcpy(request.path, path, EXECUTOR_BUFFER_SIZE);
710
|
711 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
712 mike 1.1.2.1 return -1;
713
714 // Receive the response
715
716 ExecutorRemoveFileResponse response;
717
|
718 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
719 mike 1.1.2.1 return -1;
720
721 return response.status;
722 }
723
724 static int OutOfProcess_startProviderAgent(
725 const char* module,
726 int uid,
727 int gid,
728 int& pid,
729 AnonymousPipe*& readPipe,
730 AnonymousPipe*& writePipe)
731 {
732 AutoMutex autoMutex(_mutex);
733
734 readPipe = 0;
735 writePipe = 0;
736
737 // Reject strings longer than EXECUTOR_BUFFER_SIZE.
738
739 size_t n = strlen(module);
740 mike 1.1.2.1
741 if (n >= EXECUTOR_BUFFER_SIZE)
742 return -1;
743
|
744 mike 1.1.2.3 // _send request header:
|
745 mike 1.1.2.1
746 ExecutorRequestHeader header;
|
747 mike 1.1.2.5 header.code = EXECUTOR_START_PROVIDER_AGENT_MESSAGE;
|
748 mike 1.1.2.1
|
749 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
750 mike 1.1.2.1 return -1;
751
|
752 mike 1.1.2.3 // _send request body.
|
753 mike 1.1.2.1
754 ExecutorStartProviderAgentRequest request;
755 memset(&request, 0, sizeof(request));
756 memcpy(request.module, module, n);
757 request.uid = uid;
758 request.gid = gid;
759
|
760 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
761 mike 1.1.2.1 return -1;
762
763 // Receive the response
764
765 ExecutorStartProviderAgentResponse response;
766
|
767 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
768 mike 1.1.2.1 return -1;
769
770 // Check response status and pid.
771
772 if (response.status != 0)
773 return -1;
774
775 // Get pid:
776
777 pid = response.pid;
778
779 // Receive descriptors.
780
781 int descriptors[2];
|
782 mike 1.1.2.2 int result = _receiveDescriptorArray(_getSock(), descriptors, 2);
|
783 mike 1.1.2.1
784 if (result == 0)
785 {
786 int readFd = descriptors[0];
787 int writeFd = descriptors[1];
788
789 // Create to and from AnonymousPipe instances to correspond to the pipe
790 // descriptors created above.
791
792 char readFdStr[32];
793 char writeFdStr[32];
794 sprintf(readFdStr, "%d", readFd);
795 sprintf(writeFdStr, "%d", writeFd);
796
797 readPipe = new AnonymousPipe(readFdStr, 0);
798 writePipe = new AnonymousPipe(0, writeFdStr);
799 }
800
801 return result;
802 }
803
804 mike 1.1.2.1 static int OutOfProcess_daemonizeExecutor()
805 {
806 AutoMutex autoMutex(_mutex);
807
|
808 mike 1.1.2.3 // _send request header:
|
809 mike 1.1.2.1
810 ExecutorRequestHeader header;
|
811 mike 1.1.2.5 header.code = EXECUTOR_DAEMONIZE_EXECUTOR_MESSAGE;
|
812 mike 1.1.2.1
|
813 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
814 mike 1.1.2.1 return -1;
815
816 // Receive the response
817
818 ExecutorDaemonizeExecutorResponse response;
819
|
820 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
821 mike 1.1.2.1 return -1;
822
823 return response.status;
824 }
825
|
826 mike 1.1.2.5 static int OutOfProcess_waitPid(
827 int pid)
|
828 mike 1.1.2.1 {
829 AutoMutex autoMutex(_mutex);
830
|
831 mike 1.1.2.3 // _send request header:
|
832 mike 1.1.2.1
833 ExecutorRequestHeader header;
|
834 mike 1.1.2.5 header.code = EXECUTOR_WAIT_PID_MESSAGE;
|
835 mike 1.1.2.1
|
836 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
837 mike 1.1.2.1 return -1;
838
|
839 mike 1.1.2.3 // _send request body:
|
840 mike 1.1.2.1
|
841 mike 1.1.2.5 ExecutorWaitPidRequest request;
842 request.pid = pid;
|
843 mike 1.1.2.1
|
844 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
845 mike 1.1.2.1 return -1;
846
847 // Receive the response
848
|
849 mike 1.1.2.5 ExecutorWaitPidResponse response;
|
850 mike 1.1.2.1
|
851 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
852 mike 1.1.2.1 return -1;
853
854 return response.status;
855 }
856
|
857 mike 1.1.2.5 static int OutOfProcess_pamAuthenticate(
858 const char* username,
859 const char* password)
|
860 mike 1.1.2.1 {
861 AutoMutex autoMutex(_mutex);
862
|
863 mike 1.1.2.3 // _send request header:
|
864 mike 1.1.2.1
865 ExecutorRequestHeader header;
|
866 mike 1.1.2.5 header.code = EXECUTOR_PAM_AUTHENTICATE_MESSAGE;
|
867 mike 1.1.2.1
|
868 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
869 mike 1.1.2.1 return -1;
870
|
871 mike 1.1.2.5 // _send request body.
|
872 mike 1.1.2.1
|
873 mike 1.1.2.5 ExecutorPAMAuthenticateRequest request;
874 memset(&request, 0, sizeof(request));
875 Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
876 Strlcpy(request.password, password, EXECUTOR_BUFFER_SIZE);
|
877 mike 1.1.2.1
|
878 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
879 mike 1.1.2.1 return -1;
880
881 // Receive the response
882
|
883 mike 1.1.2.5 ExecutorPAMAuthenticateResponse response;
|
884 mike 1.1.2.1
|
885 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
886 mike 1.1.2.1 return -1;
887
888 return response.status;
889 }
890
|
891 mike 1.1.2.5 static int OutOfProcess_pamValidateUser(
892 const char* username)
|
893 mike 1.1.2.1 {
894 AutoMutex autoMutex(_mutex);
895
|
896 mike 1.1.2.3 // _send request header:
|
897 mike 1.1.2.1
898 ExecutorRequestHeader header;
|
899 mike 1.1.2.5 header.code = EXECUTOR_PAM_VALIDATE_USER_MESSAGE;
|
900 mike 1.1.2.1
|
901 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
902 mike 1.1.2.1 return -1;
903
|
904 mike 1.1.2.3 // _send request body.
|
905 mike 1.1.2.1
|
906 mike 1.1.2.5 ExecutorPAMValidateUserRequest request;
|
907 mike 1.1.2.1 memset(&request, 0, sizeof(request));
908 Strlcpy(request.username, username, EXECUTOR_BUFFER_SIZE);
909
|
910 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
911 mike 1.1.2.1 return -1;
912
913 // Receive the response
914
|
915 mike 1.1.2.5 ExecutorPAMValidateUserResponse response;
|
916 mike 1.1.2.1
|
917 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
918 mike 1.1.2.1 return -1;
919
920 return response.status;
921 }
922
|
923 mike 1.1.2.5 int OutOfProcess_startLocalAuth(
924 const char* user,
925 char path[EXECUTOR_BUFFER_SIZE],
926 SessionKey* key)
|
927 mike 1.1.2.1 {
928 AutoMutex autoMutex(_mutex);
929
|
930 mike 1.1.2.3 // _send request header:
|
931 mike 1.1.2.1
932 ExecutorRequestHeader header;
|
933 mike 1.1.2.5 header.code = EXECUTOR_START_LOCAL_AUTH_MESSAGE;
|
934 mike 1.1.2.1
|
935 mike 1.1.2.3 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
|
936 mike 1.1.2.1 return -1;
937
|
938 mike 1.1.2.3 // _send request body.
|
939 mike 1.1.2.1
|
940 mike 1.1.2.5 ExecutorStartLocalAuthRequest request;
|
941 mike 1.1.2.1 memset(&request, 0, sizeof(request));
|
942 mike 1.1.2.5 Strlcpy(request.user, user, EXECUTOR_BUFFER_SIZE);
|
943 mike 1.1.2.1
|
944 mike 1.1.2.3 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
|
945 mike 1.1.2.1 return -1;
946
947 // Receive the response
948
|
949 mike 1.1.2.5 ExecutorStartLocalAuthResponse response;
950
951 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
952 return -1;
953
954 Strlcpy(key->data, response.key, sizeof(key->data));
955 Strlcpy(path, response.path, EXECUTOR_BUFFER_SIZE);
956
957 return response.status;
958 }
959
960 int OutOfProcess_finishLocalAuth(
961 const SessionKey* key,
962 const char* token,
963 SessionKey* newKey)
964 {
965 AutoMutex autoMutex(_mutex);
966
967 // _send request header:
968
969 ExecutorRequestHeader header;
970 mike 1.1.2.5 header.code = EXECUTOR_FINISH_LOCAL_AUTH_MESSAGE;
971
972 if (_send(_getSock(), &header, sizeof(header)) != sizeof(header))
973 return -1;
974
975 // _send request body.
976
977 ExecutorFinishLocalAuthRequest request;
978 memset(&request, 0, sizeof(request));
979 Strlcpy(request.key, key->data, EXECUTOR_BUFFER_SIZE);
980 Strlcpy(request.token, token, EXECUTOR_BUFFER_SIZE);
981
982 if (_send(_getSock(), &request, sizeof(request)) != sizeof(request))
983 return -1;
984
985 // Receive the response
986
987 ExecutorFinishLocalAuthResponse response;
|
988 mike 1.1.2.1
|
989 mike 1.1.2.3 if (_recv(_getSock(), &response, sizeof(response)) != sizeof(response))
|
990 mike 1.1.2.1 return -1;
991
|
992 mike 1.1.2.5 Strlcpy(newKey->data, response.key, sizeof(newKey->data));
993
|
994 mike 1.1.2.1 return response.status;
995 }
996
997 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
998
999 ////////////////////////////////////////////////////////////////////////////////
1000 ////////////////////////////////////////////////////////////////////////////////
1001 ////
1002 //// Executor Methods:
1003 ////
1004 ////////////////////////////////////////////////////////////////////////////////
1005 ////////////////////////////////////////////////////////////////////////////////
1006
|
1007 mike 1.1.2.2 void Executor::setSock(int sock)
|
1008 mike 1.1.2.1 {
|
1009 mike 1.1.2.2 _mutex.lock();
|
1010 mike 1.1.2.1 _sock = sock;
|
1011 mike 1.1.2.2 _mutex.unlock();
|
1012 mike 1.1.2.1 }
1013
|
1014 mike 1.1.2.5 int Executor::detectExecutor()
1015 {
1016 if (_getSock() == -1)
1017 return -1;
1018 else
1019 return 0;
1020 }
1021
|
1022 mike 1.1.2.1 int Executor::ping()
1023 {
|
1024 mike 1.1.2.2 if (_getSock() == -1)
|
1025 mike 1.1.2.1 return InProcess_ping();
1026
1027 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1028 return OutOfProcess_ping();
1029 #else
1030 return -1;
1031 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1032 }
1033
1034 FILE* Executor::openFile(
1035 const char* path,
1036 int mode)
1037 {
|
1038 mike 1.1.2.2 if (_getSock() == -1)
|
1039 mike 1.1.2.1 return InProcess_openFile(path, mode);
1040
1041 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1042 return OutOfProcess_openFile(path, mode);
1043 #else
1044 return -1;
1045 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1046 }
1047
1048 int Executor::renameFile(
1049 const char* oldPath,
1050 const char* newPath)
1051 {
|
1052 mike 1.1.2.2 if (_getSock() == -1)
|
1053 mike 1.1.2.1 return InProcess_renameFile(oldPath, newPath);
1054
1055 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1056 return OutOfProcess_renameFile(oldPath, newPath);
1057 #else
1058 return -1;
1059 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1060 }
1061
1062 int Executor::removeFile(
1063 const char* path)
1064 {
|
1065 mike 1.1.2.2 if (_getSock() == -1)
|
1066 mike 1.1.2.1 return InProcess_removeFile(path);
1067
1068 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1069 return OutOfProcess_removeFile(path);
1070 #else
1071 return -1;
1072 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1073 }
1074
1075 int Executor::startProviderAgent(
1076 const char* module,
1077 int uid,
1078 int gid,
1079 int& pid,
1080 AnonymousPipe*& readPipe,
1081 AnonymousPipe*& writePipe)
1082 {
|
1083 mike 1.1.2.2 if (_getSock() == -1)
|
1084 mike 1.1.2.1 return InProcess_startProviderAgent(
1085 module, uid, gid, pid, readPipe, writePipe);
1086
1087 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1088 return OutOfProcess_startProviderAgent(
1089 module, uid, gid, pid, readPipe, writePipe);
1090 #else
1091 return -1;
1092 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1093 }
1094
1095 int Executor::daemonizeExecutor()
1096 {
|
1097 mike 1.1.2.2 if (_getSock() == -1)
|
1098 mike 1.1.2.1 return InProcess_daemonizeExecutor();
1099
1100 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1101 return OutOfProcess_daemonizeExecutor();
1102 #else
1103 return -1;
1104 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1105 }
1106
1107 int Executor::waitPid(
1108 int pid)
1109 {
|
1110 mike 1.1.2.2 if (_getSock() == -1)
|
1111 mike 1.1.2.1 return InProcess_waitPid(pid);
1112
1113 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1114 return OutOfProcess_waitPid(pid);
1115 #else
1116 return -1;
1117 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1118 }
1119
1120 int Executor::pamAuthenticate(
1121 const char* username,
1122 const char* password)
1123 {
|
1124 mike 1.1.2.2 if (_getSock() == -1)
|
1125 mike 1.1.2.1 return InProcess_pamAuthenticate(username, password);
1126
1127 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1128 return OutOfProcess_pamAuthenticate(username, password);
1129 #else
1130 return -1;
1131 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1132 }
1133
1134 int Executor::pamValidateUser(
1135 const char* username)
1136 {
|
1137 mike 1.1.2.2 if (_getSock() == -1)
|
1138 mike 1.1.2.1 return InProcess_pamValidateUser(username);
1139
1140 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1141 return OutOfProcess_pamValidateUser(username);
1142 #else
1143 return -1;
1144 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1145 }
1146
|
1147 mike 1.1.2.5 int Executor::startLocalAuth(
1148 const char* user,
1149 char path[EXECUTOR_BUFFER_SIZE],
1150 SessionKey* key)
1151 {
1152 if (_getSock() == -1)
1153 return -1;
1154
1155 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1156 return OutOfProcess_startLocalAuth(user, path, key);
1157 #else
1158 return -1;
1159 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1160 }
1161
1162 int Executor::finishLocalAuth(
1163 const SessionKey* key,
1164 const char* token,
1165 SessionKey* newKey)
1166 {
1167 if (_getSock() == -1)
1168 mike 1.1.2.5 return -1;
1169
1170 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1171 return OutOfProcess_finishLocalAuth(key, token, newKey);
1172 #else
1173 return -1;
1174 #endif /* defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
1175 }
1176
|
1177 mike 1.1.2.1 PEGASUS_NAMESPACE_END
|