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