From: Alan T. DeKok Date: Mon, 25 Sep 2017 17:47:48 +0000 (-0400) Subject: add "process" callback X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=089a7067b268ceb7ada5488d219a0fedee72c4f1;p=thirdparty%2Ffreeradius-server.git add "process" callback which just runs 'recv' and 'send' sections, with no second name --- diff --git a/src/modules/proto_detail/all.mk b/src/modules/proto_detail/all.mk index f272eec009b..8beba1c590a 100644 --- a/src/modules/proto_detail/all.mk +++ b/src/modules/proto_detail/all.mk @@ -1 +1 @@ -SUBMAKEFILES := proto_detail.mk +SUBMAKEFILES := proto_detail.mk proto_detail_process.mk diff --git a/src/modules/proto_detail/proto_detail_process.c b/src/modules/proto_detail/proto_detail_process.c new file mode 100644 index 00000000000..62a74249365 --- /dev/null +++ b/src/modules/proto_detail/proto_detail_process.c @@ -0,0 +1,215 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * $Id$ + * @file proto_detail_process.c + * @brief Detail file processing + * + * @copyright 2017 The FreeRADIUS server project. + * @copyright 2017 Alan DeKok (aland@deployingradius.com) + */ +#include +#include +#include +#include +#include +#include + +static fr_io_final_t mod_process(REQUEST *request, fr_io_action_t action) +{ + VALUE_PAIR *vp; + rlm_rcode_t rcode; + CONF_SECTION *unlang; + fr_dict_enum_t const *dv; + fr_dict_attr_t const *da = NULL; + + REQUEST_VERIFY(request); + + /* + * Pass this through asynchronously to the module which + * is waiting for something to happen. + */ + if (action != FR_IO_ACTION_RUN) { + unlang_signal(request, (fr_state_action_t) action); + return FR_IO_DONE; + } + + switch (request->request_state) { + case REQUEST_INIT: + radlog_request(L_DBG, L_DBG_LVL_1, request, "Received %s ID %i", + fr_packet_codes[request->packet->code], request->packet->id); + rdebug_proto_pair_list(L_DBG_LVL_1, request, request->packet->vps, ""); + + request->component = "radius"; + + unlang = cf_section_find(request->server_cs, "recv", NULL); + if (!unlang) { + REDEBUG("Failed to find 'recv' section"); + return FR_IO_FAIL; + } + + RDEBUG("Running 'recv' from file %s", cf_filename(unlang)); + unlang_push_section(request, unlang, RLM_MODULE_NOOP); + + request->request_state = REQUEST_RECV; + /* FALL-THROUGH */ + + case REQUEST_RECV: + rcode = unlang_interpret_continue(request); + + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_IO_DONE; + + if (rcode == RLM_MODULE_YIELD) return FR_IO_YIELD; + + rad_assert(request->log.unlang_indent == 0); + + switch (rcode) { + /* + * The module has a number of OK return codes. + */ + case RLM_MODULE_NOOP: + case RLM_MODULE_OK: + case RLM_MODULE_UPDATED: + request->reply->code = FR_CODE_ACCOUNTING_RESPONSE; + break; + + case RLM_MODULE_HANDLED: + break; + + /* + * The module failed, or said the request is + * invalid, therefore we stop here. + */ + case RLM_MODULE_FAIL: + case RLM_MODULE_INVALID: + case RLM_MODULE_NOTFOUND: + case RLM_MODULE_REJECT: + case RLM_MODULE_USERLOCK: + default: + return FR_IO_FAIL; + } + + /* + * Allow for over-ride of reply code. + */ + vp = fr_pair_find_by_num(request->reply->vps, 0, FR_PACKET_TYPE, TAG_ANY); + if (vp) request->reply->code = vp->vp_uint32; + + if (!da) da = fr_dict_attr_by_num(NULL, 0, FR_PACKET_TYPE); + rad_assert(da != NULL); + + dv = fr_dict_enum_by_value(NULL, da, fr_box_uint32(request->reply->code)); + unlang = NULL; + if (dv) unlang = cf_section_find(request->server_cs, "send", dv->alias); + + if (!unlang) goto send_reply; + + RDEBUG("Running 'send %s' from file %s", cf_section_name2(unlang), cf_filename(unlang)); + unlang_push_section(request, unlang, RLM_MODULE_NOOP); + + request->request_state = REQUEST_SEND; + /* FALL-THROUGH */ + + case REQUEST_SEND: + rcode = unlang_interpret_continue(request); + + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_IO_DONE; + + if (rcode == RLM_MODULE_YIELD) return FR_IO_YIELD; + + rad_assert(request->log.unlang_indent == 0); + + switch (rcode) { + case RLM_MODULE_NOOP: + case RLM_MODULE_OK: + case RLM_MODULE_UPDATED: + case RLM_MODULE_HANDLED: + /* reply is already set */ + break; + + default: + request->reply->code = 0; + break; + } + + send_reply: + /* + * Check for "do not respond". + */ + if (request->reply->code == FR_CODE_DO_NOT_RESPOND) { + RDEBUG("Not sending reply to client."); + return FR_IO_DONE; + } + + /* + * This is an internally generated request. Don't print IP addresses. + */ + if (request->parent) { + radlog_request(L_DBG, L_DBG_LVL_1, request, "Sent %s ID %i", + fr_packet_codes[request->reply->code], request->reply->id); + rdebug_proto_pair_list(L_DBG_LVL_1, request, request->reply->vps, ""); + return FR_IO_DONE; + } + + if (RDEBUG_ENABLED) common_packet_debug(request, request->reply, false); + break; + + default: + return FR_IO_FAIL; + } + + return FR_IO_REPLY; +} + + +static int mod_instantiate(UNUSED void *instance, CONF_SECTION *listen_cs) +{ + int rcode; + CONF_SECTION *server_cs; + + rad_assert(listen_cs); + + server_cs = cf_item_to_section(cf_parent(listen_cs)); + rad_assert(strcmp(cf_section_name1(server_cs), "server") == 0); + + rcode = unlang_compile_subsection(server_cs, "recv", NULL, MOD_AUTHORIZE); + if (rcode < 0) return rcode; + if (rcode == 0) { + cf_log_err(server_cs, "Failed finding 'recv { ... }' section of virtual server %s", + cf_section_name2(server_cs)); + return -1; + } + + rcode = unlang_compile_subsection(server_cs, "send", NULL, MOD_POST_AUTH); + if (rcode < 0) return rcode; + + rcode = unlang_compile_subsection(server_cs, "send", "Do-Not-Respond", MOD_POST_AUTH); + if (rcode < 0) return rcode; + + rcode = unlang_compile_subsection(server_cs, "send", "Protocol-Error", MOD_POST_AUTH); + if (rcode < 0) return rcode; + + return 0; +} + +extern fr_app_process_t proto_detail_process; +fr_app_process_t proto_detail_process = { + .magic = RLM_MODULE_INIT, + .name = "detail_process", + .instantiate = mod_instantiate, + .process = mod_process, +}; diff --git a/src/modules/proto_detail/proto_detail_process.mk b/src/modules/proto_detail/proto_detail_process.mk new file mode 100644 index 00000000000..e9d0982e010 --- /dev/null +++ b/src/modules/proto_detail/proto_detail_process.mk @@ -0,0 +1,9 @@ +TARGETNAME := proto_detail_process + +ifneq "$(TARGETNAME)" "" +TARGET := $(TARGETNAME).a +endif + +SOURCES := proto_detail_process.c + +TGT_PREREQS := libfreeradius-util.a libfreeradius-radius.a