Merge pull request #1377 from skids/virtualize_state
[freeradius.git] / src / main / exec.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16
17 /*
18  * $Id$
19  *
20  * @file exec.c
21  * @brief Execute external programs.
22  *
23  * @copyright 2000-2004,2006  The FreeRADIUS server project
24  */
25
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/rad_assert.h>
30
31 #include <sys/file.h>
32
33 #include <fcntl.h>
34 #include <ctype.h>
35
36 #ifdef HAVE_SYS_WAIT_H
37 #       include <sys/wait.h>
38 #endif
39 #ifndef WEXITSTATUS
40 #       define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
41 #endif
42 #ifndef WIFEXITED
43 #       define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
44 #endif
45
46 #define MAX_ARGV (256)
47
48 #define USEC 1000000
49 static void tv_sub(struct timeval *end, struct timeval *start,
50                    struct timeval *elapsed)
51 {
52         elapsed->tv_sec = end->tv_sec - start->tv_sec;
53         if (elapsed->tv_sec > 0) {
54                 elapsed->tv_sec--;
55                 elapsed->tv_usec = USEC;
56         } else {
57                 elapsed->tv_usec = 0;
58         }
59         elapsed->tv_usec += end->tv_usec;
60         elapsed->tv_usec -= start->tv_usec;
61
62         if (elapsed->tv_usec >= USEC) {
63                 elapsed->tv_usec -= USEC;
64                 elapsed->tv_sec++;
65         }
66 }
67
68
69 /** Start a process
70  *
71  * @param cmd Command to execute. This is parsed into argv[] parts,
72  *      then each individual argv part is xlat'ed.
73  * @param request Current reuqest
74  * @param exec_wait set to 1 if you want to read from or write to child
75  * @param[in,out] input_fd pointer to int, receives the stdin file.
76  *      descriptor. Set to NULL and the child will have /dev/null on stdin
77  * @param[in,out] output_fd pinter to int, receives the stdout file
78  *      descriptor. Set to NULL and child will have /dev/null on stdout.
79  * @param input_pairs list of value pairs - these will be put into
80  *      the environment variables of the child.
81  * @param shell_escape values before passing them as arguments.
82  * @return PID of the child process, -1 on error.
83  */
84 pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
85                            int *input_fd, int *output_fd,
86                            VALUE_PAIR *input_pairs, bool shell_escape)
87 {
88 #ifndef __MINGW32__
89         char *p;
90         VALUE_PAIR *vp;
91         int n;
92         int to_child[2] = {-1, -1};
93         int from_child[2] = {-1, -1};
94         pid_t pid;
95 #endif
96         int             argc;
97         int             i;
98         char const      **argv_p;
99         char            *argv[MAX_ARGV], **argv_start = argv;
100         char            argv_buf[4096];
101 #define MAX_ENVP 1024
102         char *envp[MAX_ENVP];
103         int envlen = 0;
104
105         /*
106          *      Stupid array decomposition...
107          *
108          *      If we do memcpy(&argv_p, &argv, sizeof(argv_p)) src ends up being a char **
109          *      pointing to the value of the first element.
110          */
111         memcpy(&argv_p, &argv_start, sizeof(argv_p));
112         argc = rad_expand_xlat(request, cmd, MAX_ARGV, argv_p, true, sizeof(argv_buf), argv_buf);
113         if (argc <= 0) {
114                 DEBUG("invalid command line '%s'.", cmd);
115                 return -1;
116         }
117
118
119 #ifndef NDEBUG
120         if (rad_debug_lvl > 2) {
121                 DEBUG3("executing cmd %s", cmd);
122                 for (i = 0; i < argc; i++) {
123                         DEBUG3("\t[%d] %s", i, argv[i]);
124                 }
125         }
126 #endif
127
128 #ifndef __MINGW32__
129         /*
130          *      Open a pipe for child/parent communication, if necessary.
131          */
132         if (exec_wait) {
133                 if (input_fd) {
134                         if (pipe(to_child) != 0) {
135                                 DEBUG("Couldn't open pipe to child: %s", fr_syserror(errno));
136                                 return -1;
137                         }
138                 }
139                 if (output_fd) {
140                         if (pipe(from_child) != 0) {
141                                 DEBUG("Couldn't open pipe from child: %s", fr_syserror(errno));
142                                 /* safe because these either need closing or are == -1 */
143                                 close(to_child[0]);
144                                 close(to_child[1]);
145                                 return -1;
146                         }
147                 }
148         }
149
150         envp[0] = NULL;
151
152         if (input_pairs) {
153                 vp_cursor_t cursor;
154                 char buffer[1024];
155
156                 /*
157                  *      Set up the environment variables in the
158                  *      parent, so we don't call libc functions that
159                  *      hold mutexes.  They might be locked when we fork,
160                  *      and will remain locked in the child.
161                  */
162                 for (vp = fr_cursor_init(&cursor, &input_pairs);
163                      vp;
164                      vp = fr_cursor_next(&cursor)) {
165                         /*
166                          *      Hmm... maybe we shouldn't pass the
167                          *      user's password in an environment
168                          *      variable...
169                          */
170                         snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
171                         if (shell_escape) {
172                                 for (p = buffer; *p != '='; p++) {
173                                         if (*p == '-') {
174                                                 *p = '_';
175                                         } else if (isalpha((int) *p)) {
176                                                 *p = toupper(*p);
177                                         }
178                                 }
179                         }
180
181                         n = strlen(buffer);
182                         vp_prints_value(buffer + n, sizeof(buffer) - n, vp, shell_escape ? '"' : 0);
183
184                         envp[envlen++] = strdup(buffer);
185
186                         /*
187                          *      Don't add too many attributes.
188                          */
189                         if (envlen == (MAX_ENVP - 1)) break;
190
191                         /*
192                          *      NULL terminate for execve
193                          */
194                         envp[envlen] = NULL;
195                 }
196         }
197
198         if (exec_wait) {
199                 pid = rad_fork();       /* remember PID */
200         } else {
201                 pid = fork();           /* don't wait */
202         }
203
204         if (pid == 0) {
205                 int devnull;
206
207                 /*
208                  *      Child process.
209                  *
210                  *      We try to be fail-safe here. So if ANYTHING
211                  *      goes wrong, we exit with status 1.
212                  */
213
214                 /*
215                  *      Open STDIN to /dev/null
216                  */
217                 devnull = open("/dev/null", O_RDWR);
218                 if (devnull < 0) {
219                         DEBUG("Failed opening /dev/null: %s\n", fr_syserror(errno));
220
221                         /*
222                          *      Where the status code is interpreted as a module rcode
223                          *      one is subtracted from it, to allow 0 to equal success
224                          *
225                          *      2 is RLM_MODULE_FAIL + 1
226                          */
227                         exit(2);
228                 }
229
230                 /*
231                  *      Only massage the pipe handles if the parent
232                  *      has created them.
233                  */
234                 if (exec_wait) {
235                         if (input_fd) {
236                                 close(to_child[1]);
237                                 dup2(to_child[0], STDIN_FILENO);
238                         } else {
239                                 dup2(devnull, STDIN_FILENO);
240                         }
241
242                         if (output_fd) {
243                                 close(from_child[0]);
244                                 dup2(from_child[1], STDOUT_FILENO);
245                         } else {
246                                 dup2(devnull, STDOUT_FILENO);
247                         }
248
249                 } else {        /* no pipe, STDOUT should be /dev/null */
250                         dup2(devnull, STDIN_FILENO);
251                         dup2(devnull, STDOUT_FILENO);
252                 }
253
254                 /*
255                  *      If we're not debugging, then we can't do
256                  *      anything with the error messages, so we throw
257                  *      them away.
258                  *
259                  *      If we are debugging, then we want the error
260                  *      messages to go to the STDERR of the server.
261                  */
262                 if (rad_debug_lvl == 0) {
263                         dup2(devnull, STDERR_FILENO);
264                 }
265                 close(devnull);
266
267                 /*
268                  *      The server may have MANY FD's open.  We don't
269                  *      want to leave dangling FD's for the child process
270                  *      to play funky games with, so we close them.
271                  */
272                 closefrom(3);
273
274                 /*
275                  *      I swear the signature for execve is wrong and should
276                  *      take 'char const * const argv[]'.
277                  *
278                  *      Note: execve(), unlike system(), treats all the space
279                  *      delimited arguments as literals, so there's no need
280                  *      to perform additional escaping.
281                  */
282                 execve(argv[0], argv, envp);
283                 printf("Failed to execute \"%s\": %s", argv[0], fr_syserror(errno)); /* fork output will be captured */
284
285                 /*
286                  *      Where the status code is interpreted as a module rcode
287                  *      one is subtracted from it, to allow 0 to equal success
288                  *
289                  *      2 is RLM_MODULE_FAIL + 1
290                  */
291                 exit(2);
292         }
293
294         /*
295          *      Free child environment variables
296          */
297         for (i = 0; i < envlen; i++) {
298                 free(envp[i]);
299         }
300
301         /*
302          *      Parent process.
303          */
304         if (pid < 0) {
305                 DEBUG("Couldn't fork %s: %s", argv[0], fr_syserror(errno));
306                 if (exec_wait) {
307                         /* safe because these either need closing or are == -1 */
308                         close(to_child[0]);
309                         close(to_child[1]);
310                         close(from_child[0]);
311                         close(from_child[1]);
312                 }
313                 return -1;
314         }
315
316         /*
317          *      We're not waiting, exit, and ignore any child's status.
318          */
319         if (exec_wait) {
320                 /*
321                  *      Close the ends of the pipe(s) the child is using
322                  *      return the ends of the pipe(s) our caller wants
323                  *
324                  */
325                 if (input_fd) {
326                         *input_fd = to_child[1];
327                         close(to_child[0]);
328                 }
329                 if (output_fd) {
330                         *output_fd = from_child[0];
331                         close(from_child[1]);
332                 }
333         }
334
335         return pid;
336 #else
337         if (exec_wait) {
338                 DEBUG("Wait is not supported");
339                 return -1;
340         }
341
342         {
343                 /*
344                  *      The _spawn and _exec families of functions are
345                  *      found in Windows compiler libraries for
346                  *      portability from UNIX. There is a variety of
347                  *      functions, including the ability to pass
348                  *      either a list or array of parameters, to
349                  *      search in the PATH or otherwise, and whether
350                  *      or not to pass an environment (a set of
351                  *      environment variables). Using _spawn, you can
352                  *      also specify whether you want the new process
353                  *      to close your program (_P_OVERLAY), to wait
354                  *      until the new process is finished (_P_WAIT) or
355                  *      for the two to run concurrently (_P_NOWAIT).
356
357                  *      _spawn and _exec are useful for instances in
358                  *      which you have simple requirements for running
359                  *      the program, don't want the overhead of the
360                  *      Windows header file, or are interested
361                  *      primarily in portability.
362                  */
363
364                 /*
365                  *      FIXME: check return code... what is it?
366                  */
367                 _spawnve(_P_NOWAIT, argv[0], argv, envp);
368         }
369
370         return 0;
371 #endif
372 }
373
374 /** Read from the child process.
375  *
376  * @param fd file descriptor to read from.
377  * @param pid pid of child, will be reaped if it dies.
378  * @param timeout amount of time to wait, in seconds.
379  * @param answer buffer to write into.
380  * @param left length of buffer.
381  * @return -1 on error, or length of output.
382  */
383 int radius_readfrom_program(int fd, pid_t pid, int timeout,
384                             char *answer, int left)
385 {
386         int done = 0;
387 #ifndef __MINGW32__
388         int status;
389         struct timeval start;
390 #ifdef O_NONBLOCK
391         bool nonblock = true;
392 #endif
393
394 #ifdef O_NONBLOCK
395         /*
396          *      Try to set it non-blocking.
397          */
398         do {
399                 int flags;
400
401                 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0)  {
402                         nonblock = false;
403                         break;
404                 }
405
406                 flags |= O_NONBLOCK;
407                 if( fcntl(fd, F_SETFL, flags) < 0) {
408                         nonblock = false;
409                         break;
410                 }
411         } while (0);
412 #endif
413
414
415         /*
416          *      Read from the pipe until we doesn't get any more or
417          *      until the message is full.
418          */
419         gettimeofday(&start, NULL);
420         while (1) {
421                 int rcode;
422                 fd_set fds;
423                 struct timeval when, elapsed, wake;
424
425                 FD_ZERO(&fds);
426                 FD_SET(fd, &fds);
427
428                 gettimeofday(&when, NULL);
429                 tv_sub(&when, &start, &elapsed);
430                 if (elapsed.tv_sec >= timeout) goto too_long;
431
432                 when.tv_sec = timeout;
433                 when.tv_usec = 0;
434                 tv_sub(&when, &elapsed, &wake);
435
436                 rcode = select(fd + 1, &fds, NULL, NULL, &wake);
437                 if (rcode == 0) {
438                 too_long:
439                         DEBUG("Child PID %u is taking too much time: forcing failure and killing child.", (unsigned int) pid);
440                         kill(pid, SIGTERM);
441                         close(fd); /* should give SIGPIPE to child, too */
442
443                         /*
444                          *      Clean up the child entry.
445                          */
446                         rad_waitpid(pid, &status);
447                         return -1;
448                 }
449                 if (rcode < 0) {
450                         if (errno == EINTR) continue;
451                         break;
452                 }
453
454 #ifdef O_NONBLOCK
455                 /*
456                  *      Read as many bytes as possible.  The kernel
457                  *      will return the number of bytes available.
458                  */
459                 if (nonblock) {
460                         status = read(fd, answer + done, left);
461                 } else
462 #endif
463                         /*
464                          *      There's at least 1 byte ready: read it.
465                          */
466                         status = read(fd, answer + done, 1);
467
468                 /*
469                  *      Nothing more to read: stop.
470                  */
471                 if (status == 0) {
472                         break;
473                 }
474
475                 /*
476                  *      Error: See if we have to continue.
477                  */
478                 if (status < 0) {
479                         /*
480                          *      We were interrupted: continue reading.
481                          */
482                         if (errno == EINTR) {
483                                 continue;
484                         }
485
486                         /*
487                          *      There was another error.  Most likely
488                          *      The child process has finished, and
489                          *      exited.
490                          */
491                         break;
492                 }
493
494                 done += status;
495                 left -= status;
496                 if (left <= 0) break;
497         }
498 #endif  /* __MINGW32__ */
499
500         /* Strip trailing new lines */
501         while ((done > 0) && (answer[done - 1] == '\n')) {
502                 answer[--done] = '\0';
503         }
504
505         return done;
506 }
507
508 /** Execute a program.
509  *
510  * @param[in,out] ctx to allocate new VALUE_PAIR (s) in.
511  * @param[out] out buffer to append plaintext (non valuepair) output.
512  * @param[in] outlen length of out buffer.
513  * @param[out] output_pairs list of value pairs - child stdout will be parsed and added into this list
514  *      of value pairs.
515  * @param[in] request Current request (may be NULL).
516  * @param[in] cmd Command to execute. This is parsed into argv[] parts, then each individual argv part
517  *      is xlat'ed.
518  * @param[in] input_pairs list of value pairs - these will be available in the environment of the child.
519  * @param[in] exec_wait set to 1 if you want to read from or write to child.
520  * @param[in] shell_escape values before passing them as arguments.
521  * @param[in] timeout amount of time to wait, in seconds.
522
523  * @return 0 if exec_wait==0, exit code if exec_wait!=0, -1 on error.
524  */
525 int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, VALUE_PAIR **output_pairs,
526                         REQUEST *request, char const *cmd, VALUE_PAIR *input_pairs,
527                         bool exec_wait, bool shell_escape, int timeout)
528
529 {
530         pid_t pid;
531         int from_child;
532 #ifndef __MINGW32__
533         char *p;
534         pid_t child_pid;
535         int comma = 0;
536         int status, ret = 0;
537         ssize_t len;
538         char answer[4096];
539 #endif
540
541         RDEBUG2("Executing: %s:", cmd);
542
543         if (out) *out = '\0';
544
545         pid = radius_start_program(cmd, request, exec_wait, NULL, &from_child, input_pairs, shell_escape);
546         if (pid < 0) {
547                 return -1;
548         }
549
550         if (!exec_wait) {
551                 return 0;
552         }
553
554 #ifndef __MINGW32__
555         len = radius_readfrom_program(from_child, pid, timeout, answer, sizeof(answer));
556         if (len < 0) {
557                 /*
558                  *      Failure - radius_readfrom_program will
559                  *      have called close(from_child) for us
560                  */
561                 RERROR("Failed to read from child output");
562                 return -1;
563
564         }
565         answer[len] = '\0';
566
567         /*
568          *      Make sure that the writer can't block while writing to
569          *      a pipe that no one is reading from anymore.
570          */
571         close(from_child);
572
573         if (len == 0) {
574                 goto wait;
575         }
576
577         /*
578          *      Parse the output, if any.
579          */
580         if (output_pairs) {
581                 /*
582                  *      HACK: Replace '\n' with ',' so that
583                  *      fr_pair_list_afrom_str() can parse the buffer in
584                  *      one go (the proper way would be to
585                  *      fix fr_pair_list_afrom_str(), but oh well).
586                  */
587                 for (p = answer; *p; p++) {
588                         if (*p == '\n') {
589                                 *p = comma ? ' ' : ',';
590                                 p++;
591                                 comma = 0;
592                         }
593                         if (*p == ',') {
594                                 comma++;
595                         }
596                 }
597
598                 /*
599                  *      Replace any trailing comma by a NUL.
600                  */
601                 if (answer[len - 1] == ',') {
602                         answer[--len] = '\0';
603                 }
604
605                 if (fr_pair_list_afrom_str(ctx, answer, output_pairs) == T_INVALID) {
606                         RERROR("Failed parsing output from: %s: %s", cmd, fr_strerror());
607                         strlcpy(out, answer, len);
608                         ret = -1;
609                 }
610         /*
611          *      We've not been told to extract output pairs,
612          *      just copy the programs output to the out
613          *      buffer.
614          */
615
616         } else if (out) {
617                 strlcpy(out, answer, outlen);
618         }
619
620         /*
621          *      Call rad_waitpid (should map to waitpid on non-threaded
622          *      or single-server systems).
623          */
624 wait:
625         child_pid = rad_waitpid(pid, &status);
626         if (child_pid == 0) {
627                 RERROR("Timeout waiting for child");
628
629                 return -2;
630         }
631
632         if (child_pid == pid) {
633                 if (WIFEXITED(status)) {
634                         status = WEXITSTATUS(status);
635                         if ((status != 0) || (ret < 0)) {
636                                 RERROR("Program returned code (%d) and output '%s'", status, answer);
637                         } else {
638                                 RDEBUG2("Program returned code (%d) and output '%s'", status, answer);
639                         }
640
641                         return ret < 0 ? ret : status;
642                 }
643         }
644
645         RERROR("Abnormal child exit: %s", fr_syserror(errno));
646 #endif  /* __MINGW32__ */
647
648         return -1;
649 }