From: Arran Cudbard-Bell Date: Mon, 5 Apr 2021 23:01:51 +0000 (+0100) Subject: Not all requests have clients X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77f9ac8f4e0af8c78d085cff26f6c5fffa16ede3;p=thirdparty%2Ffreeradius-server.git Not all requests have clients --- diff --git a/src/bin/unit_test_module.c b/src/bin/unit_test_module.c index 0fbc6fabee4..38a9ed591c5 100644 --- a/src/bin/unit_test_module.c +++ b/src/bin/unit_test_module.c @@ -163,7 +163,6 @@ static request_t *request_from_file(TALLOC_CTX *ctx, FILE *fp, RADCLIENT *client } request->client = client; - request->number = number++; request->name = talloc_typed_asprintf(request, "%" PRIu64, request->number); request->el = el; diff --git a/src/lib/server/client.c b/src/lib/server/client.c index 8e13f2b5dfe..94287f2b5dc 100644 --- a/src/lib/server/client.c +++ b/src/lib/server/client.c @@ -1102,3 +1102,18 @@ RADCLIENT *client_read(char const *filename, CONF_SECTION *server_cs, bool check return c; } + +/** Search up a list of requests trying to locate one which has a client + * + */ +RADCLIENT *client_from_request(request_t *request) +{ + RADCLIENT *client; + request_t *parent = request; + + do { + client = parent->client; + } while (!client && (parent = request->parent)); + + return client; +} diff --git a/src/lib/server/client.h b/src/lib/server/client.h index fc1c1941fa8..5dfc5f11178 100644 --- a/src/lib/server/client.h +++ b/src/lib/server/client.h @@ -143,6 +143,7 @@ RADCLIENT *client_findbynumber(RADCLIENT_LIST const *clients, int number); RADCLIENT *client_read(char const *filename, CONF_SECTION *server_cs, bool check_dns); +RADCLIENT *client_from_request(request_t *request); #ifdef __cplusplus } #endif diff --git a/src/lib/server/request.c b/src/lib/server/request.c index 28ac9140b4e..94eeb36ae8f 100644 --- a/src/lib/server/request.c +++ b/src/lib/server/request.c @@ -553,7 +553,7 @@ request_t *_request_local_alloc(char const *file, int line, TALLOC_CTX *ctx, */ int request_detach(request_t *child) { - request_t *request = child->parent; + request_t *request = child->parent; /* * Already detached or not detachable @@ -561,7 +561,7 @@ int request_detach(request_t *child) if (request_is_detached(child)) return 0; if (!request_is_detachable(child)) { - RERROR("Request is not detachable"); + fr_strerror_const("Request is not detachable"); return -1; } diff --git a/src/lib/server/request.h b/src/lib/server/request.h index c963248164a..5ec78c62660 100644 --- a/src/lib/server/request.h +++ b/src/lib/server/request.h @@ -150,7 +150,7 @@ typedef enum { #define request_is_external(_x) ((_x)->type == REQUEST_TYPE_EXTERNAL) #define request_is_internal(_x) ((_x)->type == REQUEST_TYPE_INTERNAL) #define request_is_detached(_x) ((_x)->type == REQUEST_TYPE_DETACHED) -#define request_is_detachable(_x) ((_x)->flags.detachable == 1) +#define request_is_detachable(_x) ((_x)->flags.detachable) struct request_s { #ifndef NDEBUG diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index 3c38b060b21..8af40cc90c3 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -944,7 +944,7 @@ void unlang_interpret_signal(request_t *request, fr_state_signal_t action) case FR_SIGNAL_DETACH: unlang_interpret_request_detach(request); /* Tell our caller that the request is being detached */ - request_detach(request); /* Finish detaching the request */ + if (request_detach(request) < 0) RPEDEBUG("Failed detaching request"); break; default: diff --git a/src/lib/unlang/parallel.c b/src/lib/unlang/parallel.c index 216c2df741d..e7793775f19 100644 --- a/src/lib/unlang/parallel.c +++ b/src/lib/unlang/parallel.c @@ -346,7 +346,9 @@ static unlang_action_t unlang_parallel_process(rlm_rcode_t *p_result, request_t * Detach the child, and insert * it into the backlog. */ - if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(request) < 0)) { + if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(child) < 0)) { + request = child; + RPEDEBUG("Failed detaching request"); talloc_free(child); RETURN_MODULE_FAIL; diff --git a/src/lib/unlang/subrequest_child.c b/src/lib/unlang/subrequest_child.c index 0dcc707f781..e220e6ccda5 100644 --- a/src/lib/unlang/subrequest_child.c +++ b/src/lib/unlang/subrequest_child.c @@ -330,16 +330,19 @@ int unlang_subrequest_child_push(rlm_rcode_t *out, request_t *child, return 0; } -int unlang_subrequest_child_push_and_detach(request_t *child) +int unlang_subrequest_child_push_and_detach(request_t *request) { /* * Ensures the child is setup correctly and adds * it into the runnable queue of whatever owns * the interpreter. */ - interpret_child_init(child); + interpret_child_init(request); - if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(child) < 0)) return -1; + if ((unlang_subrequest_lifetime_set(request) < 0) || (request_detach(request) < 0)) { + RPEDEBUG("Failed detaching request"); + return -1; + } return 0; } diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index f6b96fae181..ae631ffdac5 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -675,10 +675,11 @@ static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_dcursor_t *out, * Some non-packet expansions */ if (tmpl_da(vpt) == attr_client_shortname) { - if (!request->client || !request->client->shortname) return XLAT_ACTION_DONE; + RADCLIENT *client = client_from_request(request); + if (!client || !client->shortname) return XLAT_ACTION_DONE; MEM(value = fr_value_box_alloc_null(ctx)); - if (fr_value_box_bstrdup_buffer(ctx, value, tmpl_da(vpt), request->client->shortname, false) < 0) { + if (fr_value_box_bstrdup_buffer(ctx, value, tmpl_da(vpt), client->shortname, false) < 0) { error: talloc_free(value); return XLAT_ACTION_FAIL; @@ -735,9 +736,10 @@ static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_value_box_memdup(ctx, value, tmpl_da(vpt), packet->vector, sizeof(packet->vector), true); } else if (tmpl_da(vpt) == attr_client_ip_address) { - if (request->client) { + RADCLIENT *client = client_from_request(request); + if (client) { MEM(value = fr_value_box_alloc_null(ctx)); - fr_value_box_ipaddr(value, NULL, &request->client->ipaddr, false); /* Enum might not match type */ + fr_value_box_ipaddr(value, NULL, &client->ipaddr, false); /* Enum might not match type */ goto done; } goto src_ip_address; diff --git a/src/listen/dhcpv4/proto_dhcpv4.c b/src/listen/dhcpv4/proto_dhcpv4.c index b4d1585e78c..aa69c2c8f4c 100644 --- a/src/listen/dhcpv4/proto_dhcpv4.c +++ b/src/listen/dhcpv4/proto_dhcpv4.c @@ -227,7 +227,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d /* * Set the rest of the fields. */ - memcpy(&request->client, &client, sizeof(client)); /* const issues */ + request->client = UNCONST(RADCLIENT *, client); request->packet->socket = address->socket; fr_socket_addr_swap(&request->reply->socket, &address->socket); diff --git a/src/listen/dhcpv6/proto_dhcpv6.c b/src/listen/dhcpv6/proto_dhcpv6.c index b2a516575f3..18becba2dab 100644 --- a/src/listen/dhcpv6/proto_dhcpv6.c +++ b/src/listen/dhcpv6/proto_dhcpv6.c @@ -227,7 +227,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d /* * Set the rest of the fields. */ - memcpy(&request->client, &client, sizeof(client)); /* const issues */ + request->client = UNCONST(RADCLIENT *, client); request->packet->socket = address->socket; fr_socket_addr_swap(&request->reply->socket, &address->socket); diff --git a/src/listen/radius/proto_radius.c b/src/listen/radius/proto_radius.c index 321bcfc8908..37405d55f88 100644 --- a/src/listen/radius/proto_radius.c +++ b/src/listen/radius/proto_radius.c @@ -235,7 +235,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d /* * Set the rest of the fields. */ - memcpy(&request->client, &client, sizeof(client)); /* const issues */ + request->client = UNCONST(RADCLIENT *, client); request->packet->socket = address->socket; fr_socket_addr_swap(&request->reply->socket, &address->socket); diff --git a/src/listen/tacacs/proto_tacacs.c b/src/listen/tacacs/proto_tacacs.c index e4356e8bb83..a619ce5a4d3 100644 --- a/src/listen/tacacs/proto_tacacs.c +++ b/src/listen/tacacs/proto_tacacs.c @@ -236,7 +236,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d /* * Set the rest of the fields. */ - memcpy(&request->client, &client, sizeof(client)); /* const issues */ + request->client = UNCONST(RADCLIENT *, client); request->packet->socket = address->socket; fr_socket_addr_swap(&request->reply->socket, &address->socket); diff --git a/src/listen/vmps/proto_vmps.c b/src/listen/vmps/proto_vmps.c index e2af2f40e46..7a16f624403 100644 --- a/src/listen/vmps/proto_vmps.c +++ b/src/listen/vmps/proto_vmps.c @@ -219,7 +219,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d /* * Set the rest of the fields. */ - memcpy(&request->client, &client, sizeof(client)); /* const issues */ + request->client = UNCONST(RADCLIENT *, client); request->packet->socket = address->socket; fr_socket_addr_swap(&request->reply->socket, &address->socket); diff --git a/src/modules/rlm_client/rlm_client.c b/src/modules/rlm_client/rlm_client.c index 8649a069b38..df48833eb75 100644 --- a/src/modules/rlm_client/rlm_client.c +++ b/src/modules/rlm_client/rlm_client.c @@ -165,7 +165,11 @@ static rlm_rcode_t map_proc_client(UNUSED void *mod_inst, UNUSED void *proc_inst } } } else { - client = request->client; + client = client_from_request(request); + if (!client) { + REDEBUG("No client associated with this request"); + return RLM_MODULE_FAIL; + } } uctx.cs = client->cs; @@ -246,20 +250,20 @@ static xlat_action_t xlat_client(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t * return XLAT_ACTION_FAIL; } } else { - client = request->client; + client = client_from_request(request); if (!client) { - RERROR("No client associated with this request"); - return XLAT_ACTION_FAIL; + REDEBUG("No client associated with this request"); + return RLM_MODULE_FAIL; } } cp = cf_pair_find(client->cs, field->vb_strvalue); if (!cp || !(value = cf_pair_value(cp))) { - if (strcmp(field->vb_strvalue, "shortname") == 0 && request->client->shortname) { - value = request->client->shortname; + if (strcmp(field->vb_strvalue, "shortname") == 0 && client->shortname) { + value = client->shortname; } - else if (strcmp(field->vb_strvalue, "nas_type") == 0 && request->client->nas_type) { - value = request->client->nas_type; + else if (strcmp(field->vb_strvalue, "nas_type") == 0 && client->nas_type) { + value = client->nas_type; } if (!value) return XLAT_ACTION_DONE; } @@ -281,11 +285,11 @@ static xlat_action_t xlat_client(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t * */ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request) { - size_t length; - char const *value; - CONF_PAIR *cp; - RADCLIENT *c; - char buffer[2048]; + size_t length; + char const *value; + CONF_PAIR *cp; + char buffer[2048]; + RADCLIENT *client; /* * Ensure we're only being called from the main thread, @@ -297,12 +301,13 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNU RETURN_MODULE_NOOP; } - if (!request->client || !request->client->cs) { + client = client_from_request(request); + if (!client || !client->cs) { REDEBUG("Unknown client definition"); RETURN_MODULE_NOOP; } - cp = cf_pair_find(request->client->cs, "directory"); + cp = cf_pair_find(client->cs, "directory"); if (!cp) { REDEBUG("No directory configuration in the client"); RETURN_MODULE_NOOP; @@ -326,16 +331,16 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNU /* * Read the buffer and generate the client. */ - if (!request->client->server) RETURN_MODULE_FAIL; + if (!client->server) RETURN_MODULE_FAIL; - c = client_read(buffer, request->client->server_cs, true); - if (!c) RETURN_MODULE_FAIL; + client = client_read(buffer, client->server_cs, true); + if (!client) RETURN_MODULE_FAIL; /* * Replace the client. This is more than a bit of a * hack. */ - request->client = c; + request->client = client; RETURN_MODULE_OK; } diff --git a/src/modules/rlm_opendirectory/rlm_opendirectory.c b/src/modules/rlm_opendirectory/rlm_opendirectory.c index 44530c8764a..21bde248af6 100644 --- a/src/modules/rlm_opendirectory/rlm_opendirectory.c +++ b/src/modules/rlm_opendirectory/rlm_opendirectory.c @@ -387,7 +387,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod rlm_opendirectory_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_opendirectory_t); struct passwd *userdata = NULL; int ismember = 0; - RADCLIENT *rad_client = NULL; + RADCLIENT *client = NULL; uuid_t uuid; uuid_t guid_sacl; uuid_t guid_nasgroup; @@ -422,23 +422,23 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod /* resolve client access list */ uuid_clear(guid_nasgroup); - rad_client = request->client; + client = client_from_request(request); #if 0 - if (rad_client->community[0] != '\0' ) { + if (client->community[0] != '\0' ) { /* * The "community" can be a GUID (Globally Unique ID) or * a group name */ - if (uuid_parse(rad_client->community, guid_nasgroup) != 0) { + if (uuid_parse(client->community, guid_nasgroup) != 0) { /* attempt to resolve the name */ - groupdata = getgrnam(rad_client->community); + groupdata = getgrnam(client->community); if (!groupdata) { - REDEBUG("The group \"%s\" does not exist on this system", rad_client->community); + REDEBUG("The group \"%s\" does not exist on this system", client->community); RETURN_MODULE_FAIL; } err = mbr_gid_to_uuid(groupdata->gr_gid, guid_nasgroup); if (err != 0) { - REDEBUG("The group \"%s\" does not have a GUID", rad_client->community); + REDEBUG("The group \"%s\" does not have a GUID", client->community); RETURN_MODULE_FAIL; } } @@ -446,7 +446,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod else #endif { - if (!rad_client) { + if (!client) { RDEBUG2("The client record could not be found for host %s", fr_inet_ntoh(&request->packet->socket.inet.src_ipaddr, host_ipaddr, sizeof(host_ipaddr))); } else { diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 745956de0e5..19057faae09 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -435,6 +435,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul rlm_radius_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_radius_thread_t); rlm_rcode_t rcode; unlang_action_t ua; + RADCLIENT *client; void *rctx = NULL; @@ -464,7 +465,8 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul RETURN_MODULE_FAIL; } - if (request->client->dynamic && !request->client->active) { + client = client_from_request(request); + if (client && client->dynamic && !client->active) { REDEBUG("Cannot proxy packets which define dynamic clients"); RETURN_MODULE_FAIL; } diff --git a/src/modules/rlm_radutmp/rlm_radutmp.c b/src/modules/rlm_radutmp/rlm_radutmp.c index ef17561f33a..4ae03ecb8b6 100644 --- a/src/modules/rlm_radutmp/rlm_radutmp.c +++ b/src/modules/rlm_radutmp/rlm_radutmp.c @@ -195,6 +195,7 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo char *filename = NULL; char *expanded = NULL; + RADCLIENT *client; if (request->dict != dict_radius) RETURN_MODULE_NOOP; @@ -294,18 +295,24 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo * originator's IP address. */ if (ut.nas_address == htonl(INADDR_NONE)) { + client = client_from_request(request); + if (!client) goto no_client; + ut.nas_address = request->packet->socket.inet.src_ipaddr.addr.v4.s_addr; - nas = request->client->shortname; + nas = client->shortname; } else if (request->packet->socket.inet.src_ipaddr.addr.v4.s_addr == ut.nas_address) { /* might be a client, might not be. */ - nas = request->client->shortname; + client = client_from_request(request); + if (!client) goto no_client; + nas = client->shortname; /* * The NAS isn't a client, it's behind * a proxy server. In that case, just * get the IP address. */ } else { + no_client: nas = inet_ntop(AF_INET, &ut.nas_address, ip_name, sizeof(ip_name)); } diff --git a/src/modules/rlm_unix/rlm_unix.c b/src/modules/rlm_unix/rlm_unix.c index d001bffab03..1d393c3f9d7 100644 --- a/src/modules/rlm_unix/rlm_unix.c +++ b/src/modules/rlm_unix/rlm_unix.c @@ -344,7 +344,7 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo struct utmp ut; time_t t; char buf[64]; - char const *s; + char const *s = NULL; int delay = 0; int status = -1; int nas_address = 0; @@ -354,7 +354,7 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo #endif uint32_t nas_port = 0; bool port_seen = true; - + RADCLIENT *client; /* * No radwtmp. Don't do anything. @@ -442,7 +442,9 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo if (nas_address == 0) { nas_address = request->packet->socket.inet.src_ipaddr.addr.v4.s_addr; } - s = request->client->shortname; + + client = client_from_request(request); + if (client) s = client->shortname; if (!s || s[0] == 0) s = uue(&(nas_address)); #ifdef __linux__ diff --git a/src/process/radius/base.c b/src/process/radius/base.c index 1f84b7363b0..523f2c7a1c1 100644 --- a/src/process/radius/base.c +++ b/src/process/radius/base.c @@ -203,6 +203,7 @@ static char *auth_name(char *buf, size_t buflen, request_t *request) fr_pair_t *pair; uint32_t port = 0; /* RFC 2865 NAS-Port is 4 bytes */ char const *tls = ""; + RADCLIENT *client = client_from_request(request); cli = fr_pair_find_by_da(&request->request_pairs, attr_calling_station_id); @@ -212,7 +213,7 @@ static char *auth_name(char *buf, size_t buflen, request_t *request) if (request->packet->socket.inet.dst_port == 0) tls = " via proxy to virtual server"; snprintf(buf, buflen, "from client %.128s port %u%s%.128s%s", - request->client->shortname, port, + client ? client->shortname : "", port, (cli ? " cli " : ""), (cli ? cli->vp_strvalue : ""), tls);