[PATCH] Added configurable timeout to rlm_exec.

Philipp Hug philipp at hug.cx
Mon Sep 24 10:27:36 CEST 2012


---
 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



More information about the Freeradius-Devel mailing list