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