--- scripts/exec-program-wait | 1 + src/include/radiusd.h | 3 ++- src/main/evaluate.c | 2 +- src/main/exec.c | 6 ++++-- src/main/modcall.c | 2 +- src/main/tls.c | 4 ++-- src/modules/rlm_exec/rlm_exec.c | 10 ++++++---- src/modules/rlm_mschap/rlm_mschap.c | 1 + 8 files changed, 18 insertions(+), 11 deletions(-) diff --git a/scripts/exec-program-wait b/scripts/exec-program-wait index ea303bc..db3ea73 100755 --- a/scripts/exec-program-wait +++ b/scripts/exec-program-wait @@ -17,6 +17,7 @@ # exec { # program = "/path/to/program/exec-program-wait" # wait = yes +# timeout = 10 # input_pairs = request # output_pairs = reply # } diff --git a/src/include/radiusd.h b/src/include/radiusd.h index 686bef6..b15c110 100644 --- a/src/include/radiusd.h +++ b/src/include/radiusd.h @@ -674,6 +674,7 @@ int rad_authenticate (REQUEST *); int rad_postauth(REQUEST *); /* exec.c */ +#define RADIUS_EXEC_DEFAULT_TIMEOUT 10 pid_t radius_start_program(const char *cmd, REQUEST *request, int exec_wait, int *input_fd, @@ -681,7 +682,7 @@ pid_t radius_start_program(const char *cmd, REQUEST *request, VALUE_PAIR *input_pairs, int shell_escape); int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer, int left); -int radius_exec_program(const char *, REQUEST *, int, +int radius_exec_program(const char *, REQUEST *, int exec_wait, int timeout, char *user_msg, int msg_len, VALUE_PAIR *input_pairs, VALUE_PAIR **output_pairs, diff --git a/src/main/evaluate.c b/src/main/evaluate.c index 99fa7a0..29a1d35 100644 --- a/src/main/evaluate.c +++ b/src/main/evaluate.c @@ -80,7 +80,7 @@ static const char *expand_string(char *buffer, size_t sizeof_buffer, return value; case T_BACK_QUOTED_STRING: - result = radius_exec_program(value, request, 1, + result = radius_exec_program(value, request, 1, RADIUS_EXEC_DEFAULT_TIMEOUT, buffer, sizeof_buffer, NULL, NULL, 0); if (result != 0) { diff --git a/src/main/exec.c b/src/main/exec.c index 16155d8..a13685e 100644 --- a/src/main/exec.c +++ b/src/main/exec.c @@ -599,6 +599,7 @@ int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer, * then each individual argv part is xlat'ed. * @param request current request. * @param exec_wait set to 1 if you want to read from or write to child + * @param timeout Seconds to wait before terminating child * @param user_msg buffer to append plaintext (non valuepair) output. * @param msg_len length of user_msg buffer. * @param input_pairs list of value pairs - these will be put into @@ -610,6 +611,7 @@ int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer, */ int radius_exec_program(const char *cmd, REQUEST *request, int exec_wait, + int timeout, char *user_msg, int msg_len, VALUE_PAIR *input_pairs, VALUE_PAIR **output_pairs, @@ -636,7 +638,7 @@ int radius_exec_program(const char *cmd, REQUEST *request, return 0; #ifndef __MINGW32__ - done = radius_readfrom_program(from_child, pid, 10, answer, sizeof(answer)); + done = radius_readfrom_program(from_child, pid, timeout, answer, sizeof(answer)); if (done < 0) { /* * failure - radius_readfrom_program will @@ -844,5 +846,5 @@ void exec_trigger(REQUEST *request, CONF_SECTION *cs, const char *name, int quen } DEBUG("Trigger %s -> %s", name, value); - radius_exec_program(value, request, 0, NULL, 0, vp, NULL, 1); + radius_exec_program(value, request, 0, 0, NULL, 0, vp, NULL, 1); } diff --git a/src/main/modcall.c b/src/main/modcall.c index 5e74334..8c9a639 100644 --- a/src/main/modcall.c +++ b/src/main/modcall.c @@ -631,7 +631,7 @@ int modcall(int component, modcallable *c, REQUEST *request) } else { RDEBUG("`%s`", mx->xlat_name); radius_exec_program(mx->xlat_name, request, - 0, NULL, 0, + 0, 0, NULL, 0, request->packet->vps, NULL, 1); } diff --git a/src/main/tls.c b/src/main/tls.c index 44fdb21..6825205 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -1587,7 +1587,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx) RDEBUG("Verifying client certificate: %s", conf->verify_client_cert_cmd); if (radius_exec_program(conf->verify_client_cert_cmd, - request, 1, NULL, 0, + request, 1, RADIUS_EXEC_DEFAULT_TIMEOUT, NULL, 0, request->packet->vps, NULL, 1) != 0) { radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) fails external verification!", common_name); @@ -2137,7 +2137,7 @@ fr_tls_server_conf_t *tls_server_conf_parse(CONF_SECTION *cs) if ((stat(conf->make_cert_command, &buf) == 0) && (stat(conf->certificate_file, &buf) < 0) && (errno == ENOENT) && - (radius_exec_program(conf->make_cert_command, NULL, 1, + (radius_exec_program(conf->make_cert_command, NULL, 1, RADIUS_EXEC_DEFAULT_TIMEOUT, NULL, 0, NULL, NULL, 0) != 0)) { goto error; } diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index 5f16319..9ab7e08 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -34,6 +34,7 @@ typedef struct rlm_exec_t { char *xlat_name; int bare; int wait; + int timeout; char *program; char *input; char *output; @@ -53,6 +54,7 @@ typedef struct rlm_exec_t { */ static const CONF_PARSER module_config[] = { { "wait", PW_TYPE_BOOLEAN, offsetof(rlm_exec_t,wait), NULL, "yes" }, + { "timeout", PW_TYPE_INTEGER, offsetof(rlm_exec_t,timeout), NULL, "10" }, { "program", PW_TYPE_STRING_PTR, offsetof(rlm_exec_t,program), NULL, NULL }, { "input_pairs", PW_TYPE_STRING_PTR, @@ -138,7 +140,7 @@ static size_t exec_xlat(void *instance, REQUEST *request, * FIXME: Do xlat of program name? */ RDEBUG2("Executing %s", fmt); - result = radius_exec_program(fmt, request, inst->wait, + result = radius_exec_program(fmt, request, inst->wait, inst->timeout, out, outlen, *input_pairs, NULL, inst->shell_escape); RDEBUG2("result %d", result); if (result != 0) { @@ -327,7 +329,7 @@ static int exec_dispatch(void *instance, REQUEST *request) * into something else. */ result = radius_exec_program(inst->program, request, - inst->wait, NULL, 0, + inst->wait, inst->timeout, NULL, 0, *input_pairs, &answer, inst->shell_escape); if (result < 0) { radlog(L_ERR, "rlm_exec (%s): External script failed", @@ -380,7 +382,7 @@ static int exec_postauth(void *instance, REQUEST *request) } tmp = NULL; - result = radius_exec_program(vp->vp_strvalue, request, exec_wait, + result = radius_exec_program(vp->vp_strvalue, request, exec_wait, inst->timeout, NULL, 0, request->packet->vps, &tmp, inst->shell_escape); @@ -444,7 +446,7 @@ static int exec_accounting(void *instance, REQUEST *request) } if (!vp) return RLM_MODULE_NOOP; - result = radius_exec_program(vp->vp_strvalue, request, exec_wait, + result = radius_exec_program(vp->vp_strvalue, request, exec_wait, inst->timeout, NULL, 0, request->packet->vps, NULL, inst->shell_escape); if (result != 0) { diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index d56636b..da7065c 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -1089,6 +1089,7 @@ static int do_mschap(rlm_mschap_t *inst, */ result = radius_exec_program(inst->ntlm_auth, request, TRUE, /* wait */ + RADIUS_EXEC_DEFAULT_TIMEOUT, buffer, sizeof(buffer), NULL, NULL, 1); if (result != 0) { -- 1.7.2.5