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.
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.
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
21 * @brief Execute external programs.
23 * @copyright 2000-2004,2006 The FreeRADIUS server project
26 #include <freeradius-devel/ident.h>
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/rad_assert.h>
38 #ifdef HAVE_SYS_WAIT_H
39 # include <sys/wait.h>
42 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
45 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
48 #define MAX_ARGV (256)
51 static void tv_sub(struct timeval *end, struct timeval *start,
52 struct timeval *elapsed)
54 elapsed->tv_sec = end->tv_sec - start->tv_sec;
55 if (elapsed->tv_sec > 0) {
57 elapsed->tv_usec = USEC;
61 elapsed->tv_usec += end->tv_usec;
62 elapsed->tv_usec -= start->tv_usec;
64 if (elapsed->tv_usec >= USEC) {
65 elapsed->tv_usec -= USEC;
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.
84 * @return PID of the child process, -1 on error.
86 pid_t radius_start_program(const char *cmd, REQUEST *request,
90 VALUE_PAIR *input_pairs,
99 int to_child[2] = {-1, -1};
100 int from_child[2] = {-1, -1};
106 char *argv[MAX_ARGV];
108 #define MAX_ENVP 1024
109 char *envp[MAX_ENVP];
112 if (strlen(cmd) > (sizeof(mycmd) - 1)) {
113 radlog(L_ERR, "Command line is too long");
118 * Check for bad escapes.
120 if (cmd[strlen(cmd) - 1] == '\\') {
121 radlog(L_ERR, "Command line has final backslash, without a following character");
125 strlcpy(mycmd, cmd, sizeof(mycmd));
128 * Split the string into argv's BEFORE doing radius_xlat...
139 if ((*from == ' ') || (*from == '\t')) {
147 if (argc >= (MAX_ARGV - 1)) break;
150 * Copy the argv over to our buffer.
152 while (*from && (*from != ' ') && (*from != '\t')) {
153 if (to >= mycmd + sizeof(mycmd) - 1) {
154 return -1; /* ran out of space */
160 length = rad_copy_string(to, from);
162 radlog(L_ERR, "Invalid string passed as argument for external program");
170 if (from[1] == '{') {
173 length = rad_copy_variable(to, from);
175 radlog(L_ERR, "Invalid variable expansion passed as argument for external program");
180 } else { /* FIXME: catch %%{ ? */
186 if (from[1] == ' ') from++;
192 } /* end of string, or found a space */
194 *(to++) = '\0'; /* terminate the string */
198 * We have to have SOMETHING, at least.
201 radlog(L_ERR, "Exec-Program: empty command line.");
206 * Expand each string, as appropriate.
209 left = sizeof(argv_buf);
210 for (i = 0; i < argc; i++) {
214 * Don't touch argv's which won't be translated.
216 if (strchr(argv[i], '%') == NULL) continue;
218 if (!request) continue;
220 sublen = radius_xlat(to, left - 1, argv[i], request, NULL, NULL);
223 * Fail to be backwards compatible.
225 * It's yucky, but it won't break anything,
226 * and it won't cause security problems.
238 radlog(L_ERR, "Exec-Program: Ran out of space while expanding arguments.");
246 * Open a pipe for child/parent communication, if necessary.
250 if (pipe(to_child) != 0) {
251 radlog(L_ERR, "Couldn't open pipe to child: %s",
257 if (pipe(from_child) != 0) {
258 radlog(L_ERR, "Couldn't open pipe from child: %s",
260 /* safe because these either need closing or are == -1 */
275 * Set up the environment variables in the
276 * parent, so we don't call libc functions that
277 * hold mutexes. They might be locked when we fork,
278 * and will remain locked in the child.
282 for (vp = input_pairs; vp != NULL; vp = vp->next) {
284 * Hmm... maybe we shouldn't pass the
285 * user's password in an environment
288 snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
290 for (p = buffer; *p != '='; p++) {
293 } else if (isalpha((int) *p)) {
300 vp_prints_value(buffer+n, sizeof(buffer) - n, vp, shell_escape);
302 envp[envlen++] = strdup(buffer);
305 * Don't add too many attributes.
307 if (envlen == (MAX_ENVP - 1)) break;
313 pid = rad_fork(); /* remember PID */
315 pid = fork(); /* don't wait */
324 * We try to be fail-safe here. So if ANYTHING
325 * goes wrong, we exit with status 1.
329 * Open STDIN to /dev/null
331 devnull = open("/dev/null", O_RDWR);
333 radlog(L_ERR, "Failed opening /dev/null: %s\n",
339 * Only massage the pipe handles if the parent
346 dup2(to_child[0], STDIN_FILENO);
348 dup2(devnull, STDIN_FILENO);
352 close(from_child[0]);
353 dup2(from_child[1], STDOUT_FILENO);
355 dup2(devnull, STDOUT_FILENO);
358 } else { /* no pipe, STDOUT should be /dev/null */
359 dup2(devnull, STDIN_FILENO);
360 dup2(devnull, STDOUT_FILENO);
364 * If we're not debugging, then we can't do
365 * anything with the error messages, so we throw
368 * If we are debugging, then we want the error
369 * messages to go to the STDERR of the server.
371 if (debug_flag == 0) {
372 dup2(devnull, STDERR_FILENO);
377 * The server may have MANY FD's open. We don't
378 * want to leave dangling FD's for the child process
379 * to play funky games with, so we close them.
383 execve(argv[0], argv, envp);
384 radlog(L_ERR, "Exec-Program: FAILED to execute %s: %s",
385 argv[0], strerror(errno));
390 * Free child environment variables
392 for (i = 0; envp[i] != NULL; i++) {
400 radlog(L_ERR, "Couldn't fork %s: %s",
401 argv[0], strerror(errno));
403 /* safe because these either need closing or are == -1 */
406 close(from_child[0]);
407 close(from_child[0]);
413 * We're not waiting, exit, and ignore any child's status.
417 * Close the ends of the pipe(s) the child is using
418 * return the ends of the pipe(s) our caller wants
422 *input_fd = to_child[1];
426 *output_fd = from_child[0];
427 close(from_child[1]);
434 radlog(L_ERR, "Exec-Program-Wait is not supported");
440 * The _spawn and _exec families of functions are
441 * found in Windows compiler libraries for
442 * portability from UNIX. There is a variety of
443 * functions, including the ability to pass
444 * either a list or array of parameters, to
445 * search in the PATH or otherwise, and whether
446 * or not to pass an environment (a set of
447 * environment variables). Using _spawn, you can
448 * also specify whether you want the new process
449 * to close your program (_P_OVERLAY), to wait
450 * until the new process is finished (_P_WAIT) or
451 * for the two to run concurrently (_P_NOWAIT).
453 * _spawn and _exec are useful for instances in
454 * which you have simple requirements for running
455 * the program, don't want the overhead of the
456 * Windows header file, or are interested
457 * primarily in portability.
461 * FIXME: check return code... what is it?
463 _spawnve(_P_NOWAIT, argv[0], argv, envp);
470 /** Read from the child process.
472 * @param fd file descriptor to read from.
473 * @param pid pid of child, will be reaped if it dies.
474 * @param timeout amount of time to wait, in seconds.
475 * @param answer buffer to write into.
476 * @param left length of buffer.
477 * @return -1 on error, or length of output.
479 int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer,
485 struct timeval start;
492 * Try to set it non-blocking.
497 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
503 if( fcntl(fd, F_SETFL, flags) < 0) {
512 * Read from the pipe until we doesn't get any more or
513 * until the message is full.
515 gettimeofday(&start, NULL);
519 struct timeval when, elapsed, wake;
524 gettimeofday(&when, NULL);
525 tv_sub(&when, &start, &elapsed);
526 if (elapsed.tv_sec >= timeout) goto too_long;
528 when.tv_sec = timeout;
530 tv_sub(&when, &elapsed, &wake);
532 rcode = select(fd + 1, &fds, NULL, NULL, &wake);
535 radlog(L_ERR, "Child PID %u is taking too much time: forcing failure and killing child.", pid);
537 close(fd); /* should give SIGPIPE to child, too */
540 * Clean up the child entry.
542 rad_waitpid(pid, &status);
546 if (errno == EINTR) continue;
552 * Read as many bytes as possible. The kernel
553 * will return the number of bytes available.
556 status = read(fd, answer + done, left);
560 * There's at least 1 byte ready: read it.
562 status = read(fd, answer + done, 1);
565 * Nothing more to read: stop.
572 * Error: See if we have to continue.
576 * We were interrupted: continue reading.
578 if (errno == EINTR) {
583 * There was another error. Most likely
584 * The child process has finished, and
592 if (left <= 0) break;
594 #endif /* __MINGW32__ */
598 /** Execute a program.
600 * @param cmd Command to execute. This is parsed into argv[] parts,
601 * then each individual argv part is xlat'ed.
602 * @param request current request.
603 * @param exec_wait set to 1 if you want to read from or write to child
604 * @param user_msg buffer to append plaintext (non valuepair) output.
605 * @param msg_len length of user_msg buffer.
606 * @param input_pairs list of value pairs - these will be put into
607 * the environment variables of the child.
608 * @param[out] output_pairs list of value pairs - child stdout will be
609 * parsed and added into this list of value pairs.
610 * @param shell_escape
611 * @return 0 if exec_wait==0, exit code if exec_wait!=0, -1 on error.
613 int radius_exec_program(const char *cmd, REQUEST *request,
615 char *user_msg, int msg_len,
616 VALUE_PAIR *input_pairs,
617 VALUE_PAIR **output_pairs,
632 pid = radius_start_program(cmd, request, exec_wait, NULL, &from_child, input_pairs, shell_escape);
641 done = radius_readfrom_program(from_child, pid, 10, answer, sizeof(answer));
644 * failure - radius_readfrom_program will
645 * have called close(from_child) for us
647 DEBUG("failed to read from child output");
655 * Make sure that the writer can't block while writing to
656 * a pipe that no one is reading from anymore.
660 DEBUG2("Exec-Program output: %s", answer);
663 * Parse the output, if any.
669 * For backwards compatibility, first check
670 * for plain text (user_msg).
673 n = userparse(answer, &vp);
679 if (n == T_OP_INVALID) {
680 DEBUG("Exec-Program-Wait: plaintext: %s", answer);
682 strlcpy(user_msg, answer, msg_len);
686 * HACK: Replace '\n' with ',' so that
687 * userparse() can parse the buffer in
688 * one go (the proper way would be to
689 * fix userparse(), but oh well).
691 for (p = answer; *p; p++) {
693 *p = comma ? ' ' : ',';
697 if (*p == ',') comma++;
701 * Replace any trailing comma by a NUL.
703 if (answer[strlen(answer) - 1] == ',') {
704 answer[strlen(answer) - 1] = '\0';
707 radlog(L_DBG,"Exec-Program-Wait: value-pairs: %s", answer);
708 if (userparse(answer, &vp) == T_OP_INVALID) {
709 radlog(L_ERR, "Exec-Program-Wait: %s: unparsable reply", cmd);
713 * Tell the caller about the value
718 } /* else the answer was a set of VP's, not a text message */
719 } /* else we didn't read anything from the child */
722 * Call rad_waitpid (should map to waitpid on non-threaded
723 * or single-server systems).
725 child_pid = rad_waitpid(pid, &status);
726 if (child_pid == 0) {
727 radlog(L_DBG, "Exec-Program: Timeout waiting for child");
731 if (child_pid == pid) {
732 if (WIFEXITED(status)) {
733 status = WEXITSTATUS(status);
734 radlog(L_DBG, "Exec-Program: returned: %d", status);
739 radlog(L_ERR, "Exec-Program: Abnormal child exit: %s",
741 #endif /* __MINGW32__ */
746 static void time_free(void *data)
751 void exec_trigger(REQUEST *request, CONF_SECTION *cs, const char *name, int quench)
761 * Use global "trigger" section if no local config is given.
764 cs = mainconfig.config;
768 * Try to use pair name, rather than reference.
770 attr = strrchr(name, '.');
779 * Find local "trigger" subsection. If it isn't found,
780 * try using the global "trigger" section, and reset the
781 * reference to the full path, rather than the sub-path.
783 subcs = cf_section_sub_find(cs, "trigger");
784 if (!subcs && (cs != mainconfig.config)) {
785 subcs = cf_section_sub_find(mainconfig.config, "trigger");
791 ci = cf_reference_item(subcs, mainconfig.config, attr);
793 DEBUG3("No such item in trigger section: %s", attr);
797 if (!cf_item_is_pair(ci)) {
798 DEBUG2("Trigger is not a configuration variable: %s", attr);
802 cp = cf_itemtopair(ci);
805 value = cf_pair_value(cp);
807 DEBUG2("Trigger has no value: %s", name);
812 * May be called for Status-Server packets.
815 if (request && request->packet) vp = request->packet->vps;
818 * Perform periodic quenching.
823 last_time = cf_data_find(cs, value);
825 last_time = rad_malloc(sizeof(*last_time));
828 if (cf_data_add(cs, value, last_time, time_free) < 0) {
835 * Send the quenched traps at most once per second.
838 time_t now = time(NULL);
839 if (*last_time == now) return;
845 DEBUG("Trigger %s -> %s", name, value);
846 radius_exec_program(value, request, 0, NULL, 0, vp, NULL, 1);