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