Merge branch 'sam'
[freeradius.git] / src / main / exec.c
1 /*
2  * @file exec.c
3  * @brief Execute external programs.
4  *
5  * Version:     $Id$
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 2 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * Copyright 2000-2004,2006  The FreeRADIUS server project
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/rad_assert.h>
29
30 #include <sys/file.h>
31
32 #include <fcntl.h>
33 #include <ctype.h>
34 #include <signal.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
82  * @return PID of the child process, -1 on error.
83  */
84 pid_t radius_start_program(const char *cmd, REQUEST *request,
85                         int exec_wait,
86                         int *input_fd,
87                         int *output_fd,
88                         VALUE_PAIR *input_pairs,
89                         int shell_escape)
90 {
91         const char *from;
92         char *to;
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 = -1;
102         int i;
103         int left;
104         char *argv[MAX_ARGV];
105         char argv_buf[4096];
106 #define MAX_ENVP 1024
107         char *envp[MAX_ENVP];
108         char mycmd[1024];
109
110         if (strlen(cmd) > (sizeof(mycmd) - 1)) {
111                 radlog(L_ERR|L_CONS, "Command line is too long");
112                 return -1;
113         }
114
115         /*
116          *      Check for bad escapes.
117          */
118         if (cmd[strlen(cmd) - 1] == '\\') {
119                 radlog(L_ERR|L_CONS, "Command line has final backslash, without a following character");
120                 return -1;
121         }
122
123         strlcpy(mycmd, cmd, sizeof(mycmd));
124
125         /*
126          *      Split the string into argv's BEFORE doing radius_xlat...
127          */
128         from = cmd;
129         to = mycmd;
130         argc = 0;
131         while (*from) {
132                 int length;
133
134                 /*
135                  *      Skip spaces.
136                  */
137                 if ((*from == ' ') || (*from == '\t')) {
138                         from++;
139                         continue;
140                 }
141
142                 argv[argc] = to;
143                 argc++;
144
145                 if (argc >= (MAX_ARGV - 1)) break;
146
147                 /*
148                  *      Copy the argv over to our buffer.
149                  */
150                 while (*from && (*from != ' ') && (*from != '\t')) {
151                         if (to >= mycmd + sizeof(mycmd) - 1) {
152                                 return -1; /* ran out of space */
153                         }
154
155                         switch (*from) {
156                         case '"':
157                         case '\'':
158                                 length = rad_copy_string(to, from);
159                                 if (length < 0) {
160                                         radlog(L_ERR|L_CONS, "Invalid string passed as argument for external program");
161                                         return -1;
162                                 }
163                                 from += length;
164                                 to += length;
165                                 break;
166
167                         case '%':
168                                 if (from[1] == '{') {
169                                         *(to++) = *(from++);
170
171                                         length = rad_copy_variable(to, from);
172                                         if (length < 0) {
173                                                 radlog(L_ERR|L_CONS, "Invalid variable expansion passed as argument for external program");
174                                                 return -1;
175                                         }
176                                         from += length;
177                                         to += length;
178                                 } else { /* FIXME: catch %%{ ? */
179                                         *(to++) = *(from++);
180                                 }
181                                 break;
182
183                         case '\\':
184                                 if (from[1] == ' ') from++;
185                                 /* FALL-THROUGH */
186
187                         default:
188                                 *(to++) = *(from++);
189                         }
190                 } /* end of string, or found a space */
191
192                 *(to++) = '\0'; /* terminate the string */
193         }
194
195         /*
196          *      We have to have SOMETHING, at least.
197          */
198         if (argc <= 0) {
199                 radlog(L_ERR, "Exec-Program: empty command line.");
200                 return -1;
201         }
202
203         /*
204          *      Expand each string, as appropriate.
205          */
206         to = argv_buf;
207         left = sizeof(argv_buf);
208         for (i = 0; i < argc; i++) {
209                 int sublen;
210
211                 /*
212                  *      Don't touch argv's which won't be translated.
213                  */
214                 if (strchr(argv[i], '%') == NULL) continue;
215
216                 if (!request) continue;
217
218                 sublen = radius_xlat(to, left - 1, argv[i], request, NULL);
219                 if (sublen <= 0) {
220                         /*
221                          *      Fail to be backwards compatible.
222                          *
223                          *      It's yucky, but it won't break anything,
224                          *      and it won't cause security problems.
225                          */
226                         sublen = 0;
227                 }
228
229                 argv[i] = to;
230                 to += sublen;
231                 *(to++) = '\0';
232                 left -= sublen;
233                 left--;
234
235                 if (left <= 0) {
236                         radlog(L_ERR, "Exec-Program: Ran out of space while expanding arguments.");
237                         return -1;
238                 }
239         }
240         argv[argc] = NULL;
241
242 #ifndef __MINGW32__
243         /*
244          *      Open a pipe for child/parent communication, if necessary.
245          */
246         if (exec_wait) {
247                 if (input_fd) {
248                         if (pipe(to_child) != 0) {
249                                 radlog(L_ERR|L_CONS, "Couldn't open pipe to child: %s",
250                                        strerror(errno));
251                                 return -1;
252                         }
253                 }
254                 if (output_fd) {
255                         if (pipe(from_child) != 0) {
256                                 radlog(L_ERR|L_CONS, "Couldn't open pipe from child: %s",
257                                        strerror(errno));
258                                 /* safe because these either need closing or are == -1 */
259                                 close(to_child[0]);
260                                 close(to_child[1]);
261                                 return -1;
262                         }
263                 }
264         }
265
266         envp[0] = NULL;
267
268         if (input_pairs) {
269                 int envlen;
270                 char buffer[1024];
271
272                 /*
273                  *      Set up the environment variables in the
274                  *      parent, so we don't call libc functions that
275                  *      hold mutexes.  They might be locked when we fork,
276                  *      and will remain locked in the child.
277                  */
278                 envlen = 0;
279
280                 for (vp = input_pairs; vp != NULL; vp = vp->next) {
281                         /*
282                          *      Hmm... maybe we shouldn't pass the
283                          *      user's password in an environment
284                          *      variable...
285                          */
286                         snprintf(buffer, sizeof(buffer), "%s=", vp->name);
287                         if (shell_escape) {
288                                 for (p = buffer; *p != '='; p++) {
289                                         if (*p == '-') {
290                                                 *p = '_';
291                                         } else if (isalpha((int) *p)) {
292                                                 *p = toupper(*p);
293                                         }
294                                 }
295                         }
296
297                         n = strlen(buffer);
298                         vp_prints_value(buffer+n, sizeof(buffer) - n, vp, shell_escape);
299
300                         envp[envlen++] = strdup(buffer);
301
302                         /*
303                          *      Don't add too many attributes.
304                          */
305                         if (envlen == (MAX_ENVP - 1)) break;
306                 }
307                 envp[envlen] = NULL;
308         }
309
310         if (exec_wait) {
311                 pid = rad_fork();       /* remember PID */
312         } else {
313                 pid = fork();           /* don't wait */
314         }
315
316         if (pid == 0) {
317                 int devnull;
318
319                 /*
320                  *      Child process.
321                  *
322                  *      We try to be fail-safe here. So if ANYTHING
323                  *      goes wrong, we exit with status 1.
324                  */
325
326                 /*
327                  *      Open STDIN to /dev/null
328                  */
329                 devnull = open("/dev/null", O_RDWR);
330                 if (devnull < 0) {
331                         radlog(L_ERR|L_CONS, "Failed opening /dev/null: %s\n",
332                                strerror(errno));
333                         exit(1);
334                 }
335
336                 /*
337                  *      Only massage the pipe handles if the parent
338                  *      has created them.
339                  */
340                 if (exec_wait) {
341
342                         if (input_fd) {
343                                 close(to_child[1]);
344                                 dup2(to_child[0], STDIN_FILENO);
345                         } else {
346                                 dup2(devnull, STDIN_FILENO);
347                         }
348
349                         if (output_fd) {
350                                 close(from_child[0]);
351                                 dup2(from_child[1], STDOUT_FILENO);
352                         } else {
353                                 dup2(devnull, STDOUT_FILENO);
354                         }
355
356                 } else {        /* no pipe, STDOUT should be /dev/null */
357                         dup2(devnull, STDIN_FILENO);
358                         dup2(devnull, STDOUT_FILENO);
359                 }
360
361                 /*
362                  *      If we're not debugging, then we can't do
363                  *      anything with the error messages, so we throw
364                  *      them away.
365                  *
366                  *      If we are debugging, then we want the error
367                  *      messages to go to the STDERR of the server.
368                  */
369                 if (debug_flag == 0) {
370                         dup2(devnull, STDERR_FILENO);
371                 }
372                 close(devnull);
373
374                 /*
375                  *      The server may have MANY FD's open.  We don't
376                  *      want to leave dangling FD's for the child process
377                  *      to play funky games with, so we close them.
378                  */
379                 closefrom(3);
380
381                 execve(argv[0], argv, envp);
382                 radlog(L_ERR, "Exec-Program: FAILED to execute %s: %s",
383                        argv[0], strerror(errno));
384                 exit(1);
385         }
386
387         /*
388          *      Free child environment variables
389          */
390         for (i = 0; envp[i] != NULL; i++) {
391                 free(envp[i]);
392         }
393
394         /*
395          *      Parent process.
396          */
397         if (pid < 0) {
398                 radlog(L_ERR|L_CONS, "Couldn't fork %s: %s",
399                        argv[0], strerror(errno));
400                 if (exec_wait) {
401                         /* safe because these either need closing or are == -1 */
402                         close(to_child[0]);
403                         close(to_child[1]);
404                         close(from_child[0]);
405                         close(from_child[0]);
406                 }
407                 return -1;
408         }
409
410         /*
411          *      We're not waiting, exit, and ignore any child's status.
412          */
413         if (exec_wait) {
414                 /*
415                  *      Close the ends of the pipe(s) the child is using
416                  *      return the ends of the pipe(s) our caller wants
417                  *
418                  */
419                 if (input_fd) {
420                         *input_fd = to_child[1];
421                         close(to_child[0]);
422                 }
423                 if (output_fd) {
424                         *output_fd = from_child[0];
425                         close(from_child[1]);
426                 }
427         }
428
429         return pid;
430 #else
431         if (exec_wait) {
432                 radlog(L_ERR, "Exec-Program-Wait is not supported");
433                 return -1;
434         }
435         
436         {
437                 /*
438                  *      The _spawn and _exec families of functions are
439                  *      found in Windows compiler libraries for
440                  *      portability from UNIX. There is a variety of
441                  *      functions, including the ability to pass
442                  *      either a list or array of parameters, to
443                  *      search in the PATH or otherwise, and whether
444                  *      or not to pass an environment (a set of
445                  *      environment variables). Using _spawn, you can
446                  *      also specify whether you want the new process
447                  *      to close your program (_P_OVERLAY), to wait
448                  *      until the new process is finished (_P_WAIT) or
449                  *      for the two to run concurrently (_P_NOWAIT).
450                  
451                  *      _spawn and _exec are useful for instances in
452                  *      which you have simple requirements for running
453                  *      the program, don't want the overhead of the
454                  *      Windows header file, or are interested
455                  *      primarily in portability.
456                  */
457
458                 /*
459                  *      FIXME: check return code... what is it?
460                  */
461                 _spawnve(_P_NOWAIT, argv[0], argv, envp);
462         }
463
464         return 0;
465 #endif
466 }
467
468 /** Read from the child process.
469  *
470  * @param fd file descriptor to read from.
471  * @param pid pid of child, will be reaped if it dies.
472  * @param timeout amount of time to wait, in seconds.
473  * @param answer buffer to write into.
474  * @param left length of buffer.
475  * @return -1 on error, or length of output.
476  */
477 int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer,
478                             int left)
479 {
480         int done = 0;
481 #ifndef __MINGW32__
482         int status;
483         struct timeval start;
484 #ifdef O_NONBLOCK
485         int nonblock = TRUE;
486 #endif
487
488 #ifdef O_NONBLOCK
489         /*
490          *      Try to set it non-blocking.
491          */
492         do {
493                 int flags;
494                 
495                 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0)  {
496                         nonblock = FALSE;
497                         break;
498                 }
499                 
500                 flags |= O_NONBLOCK;
501                 if( fcntl(fd, F_SETFL, flags) < 0) {
502                         nonblock = FALSE;
503                         break;
504                 }
505         } while (0);
506 #endif
507
508
509         /*
510          *      Read from the pipe until we doesn't get any more or
511          *      until the message is full.
512          */
513         gettimeofday(&start, NULL);
514         while (1) {
515                 int rcode;
516                 fd_set fds;
517                 struct timeval when, elapsed, wake;
518
519                 FD_ZERO(&fds);
520                 FD_SET(fd, &fds);
521
522                 gettimeofday(&when, NULL);
523                 tv_sub(&when, &start, &elapsed);
524                 if (elapsed.tv_sec >= timeout) goto too_long;
525                 
526                 when.tv_sec = timeout;
527                 when.tv_usec = 0;
528                 tv_sub(&when, &elapsed, &wake);
529
530                 rcode = select(fd + 1, &fds, NULL, NULL, &wake);
531                 if (rcode == 0) {
532                 too_long:
533                         radlog(L_ERR, "Child PID %u is taking too much time: forcing failure and killing child.", pid);
534                         kill(pid, SIGTERM);
535                         close(fd); /* should give SIGPIPE to child, too */
536
537                         /*
538                          *      Clean up the child entry.
539                          */
540                         rad_waitpid(pid, &status);
541                         return -1;
542                 }
543                 if (rcode < 0) {
544                         if (errno == EINTR) continue;
545                         break;
546                 }
547
548 #ifdef O_NONBLOCK
549                 /*
550                  *      Read as many bytes as possible.  The kernel
551                  *      will return the number of bytes available.
552                  */
553                 if (nonblock) {
554                         status = read(fd, answer + done, left);
555                 } else 
556 #endif
557                         /*
558                          *      There's at least 1 byte ready: read it.
559                          */
560                         status = read(fd, answer + done, 1);
561
562                 /*
563                  *      Nothing more to read: stop.
564                  */
565                 if (status == 0) {
566                         break;
567                 }
568
569                 /*
570                  *      Error: See if we have to continue.
571                  */
572                 if (status < 0) {
573                         /*
574                          *      We were interrupted: continue reading.
575                          */
576                         if (errno == EINTR) {
577                                 continue;
578                         }
579
580                         /*
581                          *      There was another error.  Most likely
582                          *      The child process has finished, and
583                          *      exited.
584                          */
585                         break;
586                 }
587
588                 done += status;
589                 left -= status;
590                 if (left <= 0) break;
591         }
592 #endif  /* __MINGW32__ */
593         return done;
594 }
595
596 /** Execute a program.
597  *
598  * @param cmd Command to execute. This is parsed into argv[] parts,
599  *      then each individual argv part is xlat'ed.
600  * @param request current request.
601  * @param exec_wait set to 1 if you want to read from or write to child
602  * @param user_msg buffer to append plaintext (non valuepair) output.
603  * @param msg_len length of user_msg buffer.
604  * @param input_pairs list of value pairs - these will be put into
605  *      the environment variables of the child.
606  * @param[out] output_pairs list of value pairs - child stdout will be
607  *      parsed and added into this list of value pairs.
608  * @param shell_escape
609  * @return 0 if exec_wait==0, exit code if exec_wait!=0, -1 on error.
610  */
611 int radius_exec_program(const char *cmd, REQUEST *request,
612                         int exec_wait,
613                         char *user_msg, int msg_len,
614                         VALUE_PAIR *input_pairs,
615                         VALUE_PAIR **output_pairs,
616                         int shell_escape)
617 {
618         pid_t pid;
619         int from_child;
620 #ifndef __MINGW32__
621         VALUE_PAIR *vp;
622         char *p;
623         pid_t child_pid;
624         int comma = 0;
625         int status;
626         int n, done;
627         char answer[4096];
628 #endif
629
630         pid = radius_start_program(cmd, request, exec_wait, NULL, &from_child, input_pairs, shell_escape);
631         if (pid < 0) {
632                 return -1;
633         }
634
635         if (!exec_wait)
636                 return 0;
637
638 #ifndef __MINGW32__
639         done = radius_readfrom_program(from_child, pid, 10, answer, sizeof(answer));
640         if (done < 0) {
641                 /*
642                  * failure - radius_readfrom_program will
643                  * have called close(from_child) for us
644                  */
645                 DEBUG("failed to read from child output");
646                 return 1;
647
648         }
649         answer[done] = 0;
650
651
652         /*
653          *      Make sure that the writer can't block while writing to
654          *      a pipe that no one is reading from anymore.
655          */
656         close(from_child);
657
658         DEBUG2("Exec-Program output: %s", answer);
659
660         /*
661          *      Parse the output, if any.
662          */
663         if (done) {
664                 n = T_OP_INVALID;
665                 if (output_pairs) {
666                         /*
667                          *      For backwards compatibility, first check
668                          *      for plain text (user_msg).
669                          */
670                         vp = NULL;
671                         n = userparse(answer, &vp);
672                         if (vp) {
673                                 pairfree(&vp);
674                         }
675                 }
676
677                 if (n == T_OP_INVALID) {
678                         DEBUG("Exec-Program-Wait: plaintext: %s", answer);
679                         if (user_msg) {
680                                 strlcpy(user_msg, answer, msg_len);
681                         }
682                 } else {
683                         /*
684                          *      HACK: Replace '\n' with ',' so that
685                          *      userparse() can parse the buffer in
686                          *      one go (the proper way would be to
687                          *      fix userparse(), but oh well).
688                          */
689                         for (p = answer; *p; p++) {
690                                 if (*p == '\n') {
691                                         *p = comma ? ' ' : ',';
692                                         p++;
693                                         comma = 0;
694                                 }
695                                 if (*p == ',') comma++;
696                         }
697
698                         /*
699                          *      Replace any trailing comma by a NUL.
700                          */
701                         if (answer[strlen(answer) - 1] == ',') {
702                                 answer[strlen(answer) - 1] = '\0';
703                         }
704
705                         radlog(L_DBG,"Exec-Program-Wait: value-pairs: %s", answer);
706                         if (userparse(answer, &vp) == T_OP_INVALID) {
707                                 radlog(L_ERR, "Exec-Program-Wait: %s: unparsable reply", cmd);
708
709                         } else {
710                                 /*
711                                  *      Tell the caller about the value
712                                  *      pairs.
713                                  */
714                                 *output_pairs = vp;
715                         }
716                 } /* else the answer was a set of VP's, not a text message */
717         } /* else we didn't read anything from the child */
718
719         /*
720          *      Call rad_waitpid (should map to waitpid on non-threaded
721          *      or single-server systems).
722          */
723         child_pid = rad_waitpid(pid, &status);
724         if (child_pid == 0) {
725                 radlog(L_DBG, "Exec-Program: Timeout waiting for child");
726                 return 2;
727         }
728
729         if (child_pid == pid) {
730                 if (WIFEXITED(status)) {
731                         status = WEXITSTATUS(status);
732                         radlog(L_DBG, "Exec-Program: returned: %d", status);
733                         return status;
734                 }
735         }
736
737         radlog(L_ERR|L_CONS, "Exec-Program: Abnormal child exit: %s",
738                strerror(errno));
739 #endif  /* __MINGW32__ */
740
741         return 1;
742 }
743
744 void exec_trigger(REQUEST *request, CONF_SECTION *cs, const char *name)
745 {
746         CONF_SECTION *subcs;
747         CONF_ITEM *ci;
748         CONF_PAIR *cp;
749         const char *attr;
750         const char *value;
751         VALUE_PAIR *vp;
752
753         /*
754          *      Use global "trigger" section if no local config is given.
755          */
756         if (!cs) {
757                 cs = mainconfig.config;
758                 attr = name;
759         } else {
760                 /*
761                  *      Try to use pair name, rather than reference.
762                  */
763                 attr = strrchr(name, '.');
764                 if (attr) {
765                         attr++;
766                 } else {
767                         attr = name;
768                 }
769         }
770
771         /*
772          *      Find local "trigger" subsection.  If it isn't found,
773          *      try using the global "trigger" section, and reset the
774          *      reference to the full path, rather than the sub-path.
775          */
776         subcs = cf_section_sub_find(cs, "trigger");
777         if (!subcs && (cs != mainconfig.config)) {
778                 subcs = cf_section_sub_find(mainconfig.config, "trigger");
779                 attr = name;
780         }
781
782         if (!subcs) {
783                 DEBUG3("No trigger subsection: ignoring trigger %s", name);
784                 return;
785         }
786
787         ci = cf_reference_item(subcs, mainconfig.config, attr);
788         if (!ci) {
789                 DEBUG3("No such item in trigger section: %s", attr);
790                 return;
791         }
792
793         if (!cf_item_is_pair(ci)) {
794                 DEBUG2("Trigger is not a configuration variable: %s", attr);
795                 return;
796         }
797
798         cp = cf_itemtopair(ci);
799         if (!cp) return;
800
801         value = cf_pair_value(cp);
802         if (!value) {
803                 DEBUG2("Trigger has no value: %s", name);
804                 return;
805         }
806
807         /*
808          *      May be called for Status-Server packets.
809          */
810         vp = NULL;
811         if (request && request->packet) vp = request->packet->vps;
812
813         DEBUG("Trigger %s -> %s", name, value);
814         radius_exec_program(value, request, 0, NULL, 0, vp, NULL, 1);
815 }