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