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