More GCC *sigh*
[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
83  * @return PID of the child process, -1 on error.
84  */
85 pid_t radius_start_program(const char *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         const char *argv[MAX_ARGV];
103         char **argv_p;
104         char argv_buf[4096];
105 #define MAX_ENVP 1024
106         char *envp[MAX_ENVP];
107         
108         memcpy(&argv_p, &argv, sizeof(argv_p));
109
110         argc = rad_expand_xlat(request, cmd, MAX_ARGV, argv, 1, sizeof(argv_buf), argv_buf);
111         if (argc <= 0) {
112                 RDEBUG("invalid command line '%s'.", cmd);
113                 return -1;
114         }
115
116
117 #ifndef NDEBUG
118         if (debug_flag > 2) {
119                 RDEBUG3("executing cmd %s", cmd);
120                 for (i = 0; i < argc; i++) {
121                         RDEBUG3("\t[%d] %s", i, argv[i]);
122                 }
123         }
124 #endif
125
126 #ifndef __MINGW32__
127         /*
128          *      Open a pipe for child/parent communication, if necessary.
129          */
130         if (exec_wait) {
131                 if (input_fd) {
132                         if (pipe(to_child) != 0) {
133                                 RDEBUG("Couldn't open pipe to child: %s", strerror(errno));
134                                 return -1;
135                         }
136                 }
137                 if (output_fd) {
138                         if (pipe(from_child) != 0) {
139                                 RDEBUG("Couldn't open pipe from child: %s", strerror(errno));
140                                 /* safe because these either need closing or are == -1 */
141                                 close(to_child[0]);
142                                 close(to_child[1]);
143                                 return -1;
144                         }
145                 }
146         }
147
148         envp[0] = NULL;
149
150         if (input_pairs) {
151                 int envlen;
152                 char buffer[1024];
153
154                 /*
155                  *      Set up the environment variables in the
156                  *      parent, so we don't call libc functions that
157                  *      hold mutexes.  They might be locked when we fork,
158                  *      and will remain locked in the child.
159                  */
160                 envlen = 0;
161
162                 for (vp = input_pairs; vp != NULL; vp = vp->next) {
163                         /*
164                          *      Hmm... maybe we shouldn't pass the
165                          *      user's password in an environment
166                          *      variable...
167                          */
168                         snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
169                         if (shell_escape) {
170                                 for (p = buffer; *p != '='; p++) {
171                                         if (*p == '-') {
172                                                 *p = '_';
173                                         } else if (isalpha((int) *p)) {
174                                                 *p = toupper(*p);
175                                         }
176                                 }
177                         }
178
179                         n = strlen(buffer);
180                         vp_prints_value(buffer+n, sizeof(buffer) - n, vp, shell_escape);
181
182                         envp[envlen++] = strdup(buffer);
183
184                         /*
185                          *      Don't add too many attributes.
186                          */
187                         if (envlen == (MAX_ENVP - 1)) break;
188                 }
189                 envp[envlen] = NULL;
190         }
191
192         if (exec_wait) {
193                 pid = rad_fork();       /* remember PID */
194         } else {
195                 pid = fork();           /* don't wait */
196         }
197
198         if (pid == 0) {
199                 int devnull;
200
201                 /*
202                  *      Child process.
203                  *
204                  *      We try to be fail-safe here. So if ANYTHING
205                  *      goes wrong, we exit with status 1.
206                  */
207
208                 /*
209                  *      Open STDIN to /dev/null
210                  */
211                 devnull = open("/dev/null", O_RDWR);
212                 if (devnull < 0) {
213                         RDEBUG("Failed opening /dev/null: %s\n", strerror(errno));
214                         
215                         exit(1);
216                 }
217
218                 /*
219                  *      Only massage the pipe handles if the parent
220                  *      has created them.
221                  */
222                 if (exec_wait) {
223
224                         if (input_fd) {
225                                 close(to_child[1]);
226                                 dup2(to_child[0], STDIN_FILENO);
227                         } else {
228                                 dup2(devnull, STDIN_FILENO);
229                         }
230
231                         if (output_fd) {
232                                 close(from_child[0]);
233                                 dup2(from_child[1], STDOUT_FILENO);
234                         } else {
235                                 dup2(devnull, STDOUT_FILENO);
236                         }
237
238                 } else {        /* no pipe, STDOUT should be /dev/null */
239                         dup2(devnull, STDIN_FILENO);
240                         dup2(devnull, STDOUT_FILENO);
241                 }
242
243                 /*
244                  *      If we're not debugging, then we can't do
245                  *      anything with the error messages, so we throw
246                  *      them away.
247                  *
248                  *      If we are debugging, then we want the error
249                  *      messages to go to the STDERR of the server.
250                  */
251                 if (debug_flag == 0) {
252                         dup2(devnull, STDERR_FILENO);
253                 }
254                 close(devnull);
255
256                 /*
257                  *      The server may have MANY FD's open.  We don't
258                  *      want to leave dangling FD's for the child process
259                  *      to play funky games with, so we close them.
260                  */
261                 closefrom(3);
262
263                 execve(argv_p[0], argv_p, envp);
264                 RDEBUGW("Failed to execute %s: %s", argv[0], strerror(errno));
265                 exit(1);
266         }
267
268         /*
269          *      Free child environment variables
270          */
271         for (i = 0; envp[i] != NULL; i++) {
272                 free(envp[i]);
273         }
274
275         /*
276          *      Parent process.
277          */
278         if (pid < 0) {
279                 RDEBUG("Couldn't fork %s: %s", argv[0], strerror(errno));
280                 if (exec_wait) {
281                         /* safe because these either need closing or are == -1 */
282                         close(to_child[0]);
283                         close(to_child[1]);
284                         close(from_child[0]);
285                         close(from_child[0]);
286                 }
287                 return -1;
288         }
289
290         /*
291          *      We're not waiting, exit, and ignore any child's status.
292          */
293         if (exec_wait) {
294                 /*
295                  *      Close the ends of the pipe(s) the child is using
296                  *      return the ends of the pipe(s) our caller wants
297                  *
298                  */
299                 if (input_fd) {
300                         *input_fd = to_child[1];
301                         close(to_child[0]);
302                 }
303                 if (output_fd) {
304                         *output_fd = from_child[0];
305                         close(from_child[1]);
306                 }
307         }
308
309         return pid;
310 #else
311         if (exec_wait) {
312                 RDEBUG("Wait is not supported");
313                 return -1;
314         }
315         
316         {
317                 /*
318                  *      The _spawn and _exec families of functions are
319                  *      found in Windows compiler libraries for
320                  *      portability from UNIX. There is a variety of
321                  *      functions, including the ability to pass
322                  *      either a list or array of parameters, to
323                  *      search in the PATH or otherwise, and whether
324                  *      or not to pass an environment (a set of
325                  *      environment variables). Using _spawn, you can
326                  *      also specify whether you want the new process
327                  *      to close your program (_P_OVERLAY), to wait
328                  *      until the new process is finished (_P_WAIT) or
329                  *      for the two to run concurrently (_P_NOWAIT).
330                 
331                  *      _spawn and _exec are useful for instances in
332                  *      which you have simple requirements for running
333                  *      the program, don't want the overhead of the
334                  *      Windows header file, or are interested
335                  *      primarily in portability.
336                  */
337
338                 /*
339                  *      FIXME: check return code... what is it?
340                  */
341                 _spawnve(_P_NOWAIT, argv[0], argv, envp);
342         }
343
344         return 0;
345 #endif
346 }
347
348 /** Read from the child process.
349  *
350  * @param request The current request.
351  * @param fd file descriptor to read from.
352  * @param pid pid of child, will be reaped if it dies.
353  * @param timeout amount of time to wait, in seconds.
354  * @param answer buffer to write into.
355  * @param left length of buffer.
356  * @return -1 on error, or length of output.
357  */
358 int radius_readfrom_program(REQUEST *request, int fd, pid_t pid, int timeout,
359                             char *answer, int left)
360 {
361         int done = 0;
362 #ifndef __MINGW32__
363         int status;
364         struct timeval start;
365 #ifdef O_NONBLOCK
366         int nonblock = TRUE;
367 #endif
368
369 #ifdef O_NONBLOCK
370         /*
371          *      Try to set it non-blocking.
372          */
373         do {
374                 int flags;
375                 
376                 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0)  {
377                         nonblock = FALSE;
378                         break;
379                 }
380                 
381                 flags |= O_NONBLOCK;
382                 if( fcntl(fd, F_SETFL, flags) < 0) {
383                         nonblock = FALSE;
384                         break;
385                 }
386         } while (0);
387 #endif
388
389
390         /*
391          *      Read from the pipe until we doesn't get any more or
392          *      until the message is full.
393          */
394         gettimeofday(&start, NULL);
395         while (1) {
396                 int rcode;
397                 fd_set fds;
398                 struct timeval when, elapsed, wake;
399
400                 FD_ZERO(&fds);
401                 FD_SET(fd, &fds);
402
403                 gettimeofday(&when, NULL);
404                 tv_sub(&when, &start, &elapsed);
405                 if (elapsed.tv_sec >= timeout) goto too_long;
406                 
407                 when.tv_sec = timeout;
408                 when.tv_usec = 0;
409                 tv_sub(&when, &elapsed, &wake);
410
411                 rcode = select(fd + 1, &fds, NULL, NULL, &wake);
412                 if (rcode == 0) {
413                 too_long:
414                         RDEBUG("Child PID %u is taking too much time: forcing failure and killing child.", pid);
415                         kill(pid, SIGTERM);
416                         close(fd); /* should give SIGPIPE to child, too */
417
418                         /*
419                          *      Clean up the child entry.
420                          */
421                         rad_waitpid(pid, &status);
422                         return -1;
423                 }
424                 if (rcode < 0) {
425                         if (errno == EINTR) continue;
426                         break;
427                 }
428
429 #ifdef O_NONBLOCK
430                 /*
431                  *      Read as many bytes as possible.  The kernel
432                  *      will return the number of bytes available.
433                  */
434                 if (nonblock) {
435                         status = read(fd, answer + done, left);
436                 } else
437 #endif
438                         /*
439                          *      There's at least 1 byte ready: read it.
440                          */
441                         status = read(fd, answer + done, 1);
442
443                 /*
444                  *      Nothing more to read: stop.
445                  */
446                 if (status == 0) {
447                         break;
448                 }
449
450                 /*
451                  *      Error: See if we have to continue.
452                  */
453                 if (status < 0) {
454                         /*
455                          *      We were interrupted: continue reading.
456                          */
457                         if (errno == EINTR) {
458                                 continue;
459                         }
460
461                         /*
462                          *      There was another error.  Most likely
463                          *      The child process has finished, and
464                          *      exited.
465                          */
466                         break;
467                 }
468
469                 done += status;
470                 left -= status;
471                 if (left <= 0) break;
472         }
473 #endif  /* __MINGW32__ */
474         return done;
475 }
476
477 /** Execute a program.
478  *
479  * @param cmd Command to execute. This is parsed into argv[] parts,
480  *      then each individual argv part is xlat'ed.
481  * @param request current request.
482  * @param exec_wait set to 1 if you want to read from or write to child
483  * @param user_msg buffer to append plaintext (non valuepair) output.
484  * @param msg_len length of user_msg buffer.
485  * @param input_pairs list of value pairs - these will be put into
486  *      the environment variables of the child.
487  * @param[out] output_pairs list of value pairs - child stdout will be
488  *      parsed and added into this list of value pairs.
489  * @param shell_escape
490  * @return 0 if exec_wait==0, exit code if exec_wait!=0, -1 on error.
491  */
492 int radius_exec_program(const char *cmd, REQUEST *request,
493                         int exec_wait,
494                         char *user_msg, int msg_len,
495                         VALUE_PAIR *input_pairs,
496                         VALUE_PAIR **output_pairs,
497                         int shell_escape)
498 {
499         pid_t pid;
500         int from_child;
501 #ifndef __MINGW32__
502         VALUE_PAIR *vp;
503         char *p;
504         pid_t child_pid;
505         int comma = 0;
506         int status;
507         int n, done;
508         char answer[4096];
509 #endif
510
511         pid = radius_start_program(cmd, request, exec_wait, NULL, &from_child, input_pairs, shell_escape);
512         if (pid < 0) {
513                 return -1;
514         }
515
516         if (!exec_wait)
517                 return 0;
518
519 #ifndef __MINGW32__
520         done = radius_readfrom_program(request, from_child, pid, 10, answer, sizeof(answer));
521         if (done < 0) {
522                 /*
523                  * failure - radius_readfrom_program will
524                  * have called close(from_child) for us
525                  */
526                 DEBUG("Failed to read from child output");
527                 return 1;
528
529         }
530         answer[done] = 0;
531
532
533         /*
534          *      Make sure that the writer can't block while writing to
535          *      a pipe that no one is reading from anymore.
536          */
537         close(from_child);
538
539         RDEBUG2("Program output is %s", answer);
540
541         /*
542          *      Parse the output, if any.
543          */
544         if (done) {
545                 n = T_OP_INVALID;
546                 if (output_pairs) {
547                         /*
548                          *      For backwards compatibility, first check
549                          *      for plain text (user_msg).
550                          */
551                         vp = NULL;
552                         n = userparse(request, answer, &vp);
553                         if (vp) {
554                                 pairfree(&vp);
555                         }
556                 }
557
558                 if (n == T_OP_INVALID) {
559                         if (user_msg) {
560                                 strlcpy(user_msg, answer, msg_len);
561                         }
562                 } else {
563                         /*
564                          *      HACK: Replace '\n' with ',' so that
565                          *      userparse() can parse the buffer in
566                          *      one go (the proper way would be to
567                          *      fix userparse(), but oh well).
568                          */
569                         for (p = answer; *p; p++) {
570                                 if (*p == '\n') {
571                                         *p = comma ? ' ' : ',';
572                                         p++;
573                                         comma = 0;
574                                 }
575                                 if (*p == ',') comma++;
576                         }
577
578                         /*
579                          *      Replace any trailing comma by a NUL.
580                          */
581                         if (answer[strlen(answer) - 1] == ',') {
582                                 answer[strlen(answer) - 1] = '\0';
583                         }
584
585                         if (userparse(request, answer, &vp) == T_OP_INVALID) {
586                                 RDEBUGE("Unparsable reply from '%s'", cmd);
587
588                         } else {
589                                 /*
590                                  *      Tell the caller about the value
591                                  *      pairs.
592                                  */
593                                 *output_pairs = vp;
594                         }
595                 } /* else the answer was a set of VP's, not a text message */
596         } /* else we didn't read anything from the child */
597
598         /*
599          *      Call rad_waitpid (should map to waitpid on non-threaded
600          *      or single-server systems).
601          */
602         child_pid = rad_waitpid(pid, &status);
603         if (child_pid == 0) {
604                 RDEBUGE("Timeout waiting for child");
605                 return 2;
606         }
607
608         if (child_pid == pid) {
609                 if (WIFEXITED(status)) {
610                         status = WEXITSTATUS(status);
611                         if (status != 0) {
612                                 RDEBUGE("Child returned error %d", status);
613                                 return status;
614                         }
615                         
616                         RDEBUG("Child executed successfully");
617                         return 0;
618                 }
619         }
620
621         RDEBUGE("Abnormal child exit: %s", strerror(errno));
622 #endif  /* __MINGW32__ */
623
624         return 1;
625 }
626
627 static void time_free(void *data)
628 {
629         free(data);
630 }
631
632 void exec_trigger(REQUEST *request, CONF_SECTION *cs, const char *name, int quench)
633 {
634         CONF_SECTION *subcs;
635         CONF_ITEM *ci;
636         CONF_PAIR *cp;
637         const char *attr;
638         const char *value;
639         VALUE_PAIR *vp;
640
641         /*
642          *      Use global "trigger" section if no local config is given.
643          */
644         if (!cs) {
645                 cs = mainconfig.config;
646                 attr = name;
647         } else {
648                 /*
649                  *      Try to use pair name, rather than reference.
650                  */
651                 attr = strrchr(name, '.');
652                 if (attr) {
653                         attr++;
654                 } else {
655                         attr = name;
656                 }
657         }
658
659         /*
660          *      Find local "trigger" subsection.  If it isn't found,
661          *      try using the global "trigger" section, and reset the
662          *      reference to the full path, rather than the sub-path.
663          */
664         subcs = cf_section_sub_find(cs, "trigger");
665         if (!subcs && (cs != mainconfig.config)) {
666                 subcs = cf_section_sub_find(mainconfig.config, "trigger");
667                 attr = name;
668         }
669
670         if (!subcs) return;
671
672         ci = cf_reference_item(subcs, mainconfig.config, attr);
673         if (!ci) {
674                 RDEBUG3("No such item in trigger section: %s", attr);
675                 return;
676         }
677
678         if (!cf_item_is_pair(ci)) {
679                 RDEBUG2("Trigger is not a configuration variable: %s", attr);
680                 return;
681         }
682
683         cp = cf_itemtopair(ci);
684         if (!cp) return;
685
686         value = cf_pair_value(cp);
687         if (!value) {
688                 RDEBUG2("Trigger has no value: %s", name);
689                 return;
690         }
691
692         /*
693          *      May be called for Status-Server packets.
694          */
695         vp = NULL;
696         if (request && request->packet) vp = request->packet->vps;
697
698         /*
699          *      Perform periodic quenching.
700          */
701         if (quench) {
702                 time_t *last_time;
703
704                 last_time = cf_data_find(cs, value);
705                 if (!last_time) {
706                         last_time = rad_malloc(sizeof(*last_time));
707                         *last_time = 0;
708
709                         if (cf_data_add(cs, value, last_time, time_free) < 0) {
710                                 free(last_time);
711                                 last_time = NULL;
712                         }
713                 }
714
715                 /*
716                  *      Send the quenched traps at most once per second.
717                  */
718                 if (last_time) {
719                         time_t now = time(NULL);
720                         if (*last_time == now) return;
721
722                         *last_time = now;
723                 }
724         }
725
726         RDEBUG("Trigger %s -> %s", name, value);
727         radius_exec_program(value, request, 0, NULL, 0, vp, NULL, 1);
728 }