X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Frlm_exec%2Frlm_exec.c;h=bf6252138377ba116b1513627b260ce4103e9af3;hb=9960563934a7da222528a1d82224aecc207c8aa8;hp=b4173351cf1598c81f3fb76e2789a9a305492d61;hpb=5ff99bdaa7ace707534675577bef24879467a225;p=freeradius.git diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index b417335..bf62521 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -24,12 +24,6 @@ #include RCSID("$Id$") -#include - -#include -#include -#include - #include #include @@ -38,6 +32,7 @@ RCSID("$Id$") */ typedef struct rlm_exec_t { char *xlat_name; + int bare; int wait; char *program; char *input; @@ -93,6 +88,7 @@ static VALUE_PAIR **decode_string(REQUEST *request, const char *string) return &request->reply->vps; } +#ifdef WITH_PROXY if (strcmp(string, "proxy-request") == 0) { if (!request->proxy) return NULL; @@ -104,6 +100,7 @@ static VALUE_PAIR **decode_string(REQUEST *request, const char *string) return &request->proxy_reply->vps; } +#endif if (strcmp(string, "config") == 0) { return &request->config_items; @@ -120,13 +117,14 @@ static VALUE_PAIR **decode_string(REQUEST *request, const char *string) /* * Do xlat of strings. */ -static int exec_xlat(void *instance, REQUEST *request, - char *fmt, char *out, int outlen, +static size_t exec_xlat(void *instance, REQUEST *request, + char *fmt, char *out, size_t outlen, UNUSED RADIUS_ESCAPE_STRING func) { int result; rlm_exec_t *inst = instance; VALUE_PAIR **input_pairs; + char *p; input_pairs = decode_string(request, inst->input); if (!input_pairs) { @@ -139,15 +137,19 @@ static int exec_xlat(void *instance, REQUEST *request, /* * FIXME: Do xlat of program name? */ - DEBUG2("rlm_exec (%s): Executing %s", inst->xlat_name, fmt); + RDEBUG2("Executing %s", fmt); result = radius_exec_program(fmt, request, inst->wait, out, outlen, *input_pairs, NULL, inst->shell_escape); - DEBUG2("rlm_exec (%s): result %d", inst->xlat_name, result); + RDEBUG2("result %d", result); if (result != 0) { out[0] = '\0'; return 0; } + for (p = out; *p != '\0'; p++) { + if (*p < ' ') *p = ' '; + } + return strlen(out); } @@ -164,14 +166,6 @@ static int exec_detach(void *instance) free(inst->xlat_name); } - /* - * Free the strings. - */ - if (inst->program) free(inst->program); - if (inst->input) free(inst->input); - if (inst->output) free(inst->output); - if (inst->packet_type) free(inst->packet_type); - free(inst); return 0; } @@ -232,15 +226,6 @@ static int exec_instantiate(CONF_SECTION *conf, void **instance) } /* - * Sanity check the config. If we're told to wait, - * then the output pairs should be defined. - */ - if (inst->wait && - (inst->output == NULL)) { - radlog(L_INFO, "rlm_exec: wait=yes but no output defined. Did you mean output=none?"); - } - - /* * Get the packet type on which to execute */ if (!inst->packet_type) { @@ -248,7 +233,7 @@ static int exec_instantiate(CONF_SECTION *conf, void **instance) } else { DICT_VALUE *dval; - dval = dict_valbyname(PW_PACKET_TYPE, inst->packet_type); + dval = dict_valbyname(PW_PACKET_TYPE, 0, inst->packet_type); if (!dval) { radlog(L_ERR, "rlm_exec: Unknown packet type %s: See list of VALUEs for Packet-Type in share/dictionary", inst->packet_type); exec_detach(inst); @@ -258,8 +243,10 @@ static int exec_instantiate(CONF_SECTION *conf, void **instance) } xlat_name = cf_section_name2(conf); - if (xlat_name == NULL) + if (xlat_name == NULL) { xlat_name = cf_section_name1(conf); + inst->bare = 1; + } if (xlat_name){ inst->xlat_name = strdup(xlat_name); xlat_register(xlat_name, exec_xlat, inst); @@ -295,13 +282,16 @@ static int exec_dispatch(void *instance, REQUEST *request) */ if (!((inst->packet_code == 0) || (request->packet->code == inst->packet_code) || - (request->reply->code == inst->packet_code) || - (request->proxy && + (request->reply->code == inst->packet_code) +#ifdef WITH_PROXY + || (request->proxy && (request->proxy->code == inst->packet_code)) || (request->proxy_reply && - (request->proxy_reply->code == inst->packet_code)))) { - DEBUG2(" rlm_exec (%s): Packet type is not %s. Not executing.", - inst->xlat_name, inst->packet_type); + (request->proxy_reply->code == inst->packet_code)) +#endif + )) { + RDEBUG2("Packet type is not %s. Not executing.", + inst->packet_type); return RLM_MODULE_NOOP; } @@ -311,12 +301,18 @@ static int exec_dispatch(void *instance, REQUEST *request) input_pairs = decode_string(request, inst->input); output_pairs = decode_string(request, inst->output); + if (!input_pairs) { + RDEBUG2("WARNING: Possible parse error in %s", + inst->input); + return RLM_MODULE_NOOP; + } + /* * It points to the attribute list, but the attribute * list is empty. */ - if (input_pairs && !*input_pairs) { - DEBUG2("rlm_exec (%s): WARNING! Input pairs are empty. No attributes will be passed to the script", inst->xlat_name); + if (!*input_pairs) { + RDEBUG2("WARNING! Input pairs are empty. No attributes will be passed to the script"); } /* @@ -370,14 +366,18 @@ static int exec_postauth(void *instance, REQUEST *request) VALUE_PAIR *vp, *tmp; rlm_exec_t *inst = (rlm_exec_t *) instance; - vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM); + vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM, 0); if (vp) { exec_wait = 0; - } else if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) { + } else if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT, 0)) != NULL) { exec_wait = 1; } - if (!vp) goto dispatch; + if (!vp) { + if (!inst->program) return RLM_MODULE_NOOP; + + return exec_dispatch(instance, request); + } tmp = NULL; result = radius_exec_program(vp->vp_strvalue, request, exec_wait, @@ -397,8 +397,8 @@ static int exec_postauth(void *instance, REQUEST *request) */ tmp = pairmake("Reply-Message", "Access denied (external check failed)", T_OP_SET); pairadd(&request->reply->vps, tmp); - - DEBUG2("Login incorrect (external check failed)"); + + RDEBUG2("Login incorrect (external check failed)"); request->reply->code = PW_AUTHENTICATION_REJECT; return RLM_MODULE_REJECT; @@ -410,14 +410,48 @@ static int exec_postauth(void *instance, REQUEST *request) * exit status. */ request->reply->code = PW_AUTHENTICATION_REJECT; - DEBUG2("Login incorrect (external check said so)"); + RDEBUG2("Login incorrect (external check said so)"); return RLM_MODULE_REJECT; } - dispatch: - if (!inst->program) return RLM_MODULE_NOOP; + return RLM_MODULE_OK; +} + +/* + * First, look for Exec-Program && Exec-Program-Wait. + * + * Then, call exec_dispatch. + */ +static int exec_accounting(void *instance, REQUEST *request) +{ + int result; + int exec_wait = 0; + VALUE_PAIR *vp; + rlm_exec_t *inst = (rlm_exec_t *) instance; + + /* + * The "bare" exec module takes care of handling + * Exec-Program and Exec-Program-Wait. + */ + if (!inst->bare) return exec_dispatch(instance, request); + + vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM, 0); + if (vp) { + exec_wait = 0; + + } else if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT, 0)) != NULL) { + exec_wait = 1; + } + if (!vp) return RLM_MODULE_NOOP; + + result = radius_exec_program(vp->vp_strvalue, request, exec_wait, + NULL, 0, request->packet->vps, NULL, + inst->shell_escape); + if (result != 0) { + return RLM_MODULE_REJECT; + } - return exec_dispatch(instance, request); + return RLM_MODULE_OK; } /* @@ -432,17 +466,21 @@ static int exec_postauth(void *instance, REQUEST *request) module_t rlm_exec = { RLM_MODULE_INIT, "exec", /* Name */ - RLM_TYPE_THREAD_SAFE, /* type */ + RLM_TYPE_CHECK_CONFIG_SAFE, /* type */ exec_instantiate, /* instantiation */ exec_detach, /* detach */ { exec_dispatch, /* authentication */ exec_dispatch, /* authorization */ exec_dispatch, /* pre-accounting */ - exec_dispatch, /* accounting */ + exec_accounting, /* accounting */ NULL, /* check simul */ exec_dispatch, /* pre-proxy */ exec_dispatch, /* post-proxy */ exec_postauth /* post-auth */ +#ifdef WITH_COA + , exec_dispatch, + exec_dispatch +#endif }, };