]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Not all requests have clients
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Apr 2021 23:01:51 +0000 (00:01 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Apr 2021 23:01:51 +0000 (00:01 +0100)
20 files changed:
src/bin/unit_test_module.c
src/lib/server/client.c
src/lib/server/client.h
src/lib/server/request.c
src/lib/server/request.h
src/lib/unlang/interpret.c
src/lib/unlang/parallel.c
src/lib/unlang/subrequest_child.c
src/lib/unlang/xlat_eval.c
src/listen/dhcpv4/proto_dhcpv4.c
src/listen/dhcpv6/proto_dhcpv6.c
src/listen/radius/proto_radius.c
src/listen/tacacs/proto_tacacs.c
src/listen/vmps/proto_vmps.c
src/modules/rlm_client/rlm_client.c
src/modules/rlm_opendirectory/rlm_opendirectory.c
src/modules/rlm_radius/rlm_radius.c
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_unix/rlm_unix.c
src/process/radius/base.c

index 0fbc6fabee428a361a7dff18f45e1acad4ccd541..38a9ed591c559eae7f8f2eca08bb8737862233e4 100644 (file)
@@ -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;
index 8e13f2b5dfefc6605f44a3dddd58f9153908ceda..94287f2b5dcf839b7be1834ae5794c01f615d69b 100644 (file)
@@ -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;
+}
index fc1c1941fa815c20c3bc38e45245c6427853437d..5dfc5f11178d96035d23cf7e73d0c343f8184e4d 100644 (file)
@@ -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
index 28ac9140b4e32f17c5407d5c82b28fa9a0ef93b5..94eeb36ae8fba525a5c5b8e9149a1550a351d5b4 100644 (file)
@@ -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;
        }
 
index c963248164a69e526b187133b05b6f5715e396cb..5ec78c62660eac26aefe2db4f5817266729e745f 100644 (file)
@@ -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
index 3c38b060b217b385ce56ac1d4b87ffef9b7a547b..8af40cc90c39ff39cee3f7458711f606d4783765 100644 (file)
@@ -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:
index 216c2df741d837224e09dd0488ce07918ceb19de..e7793775f1965c68ca23af589056d694dc9d68c8 100644 (file)
@@ -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;
index 0dcc707f781ffc76a1bec55c280ae6f89cc57d06..e220e6ccda5257d20ef30cc342fb3673485ab084 100644 (file)
@@ -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;
 }
index f6b96fae181acb6ca3b8744f8212b77b7bc48378..ae631ffdac51f731e0c10fe5e087d1c9a7d5db6f 100644 (file)
@@ -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;
index b4d1585e78c1bf07cb093333a7d839215d6e0dfe..aa69c2c8f4c73ab6407117231b4634239673e80f 100644 (file)
@@ -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);
index b2a516575f312b0a5eb30d558b87ea7d1d0d544f..18becba2dab446dc3f0ef6b098d6b97e9d9d3947 100644 (file)
@@ -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);
index 321bcfc89083d931d8d7ea7018478d8fab73fe10..37405d55f88e7c96d25e1de95f510d86a4b6ff9b 100644 (file)
@@ -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);
index e4356e8bb83e79db7ee869745430c90e3f03889c..a619ce5a4d3d10df7213d770e220ba7378fa1fb3 100644 (file)
@@ -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);
index e2af2f40e46092143282833e6383c0ff17818c2d..7a16f6244038e867ba08c5ab2c906dbfd4d1f2e6 100644 (file)
@@ -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);
index 8649a069b3801ffe02a5790e7359489efa414f81..df48833eb75b48fb1034791d3a352288858a9cdf 100644 (file)
@@ -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;
 }
index 44530c8764afcb0a697f2da84945445d644d2667..21bde248af6b572eff4b8df88c1df5a22abefc83 100644 (file)
@@ -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 {
index 745956de0e52ed4e99d891d0d172e0fac0d3aa3b..19057faae09dbe16d1e85f2363cba8dc42d459dd 100644 (file)
@@ -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;
        }
index ef17561f33a4ab9cce90e13a3d8cace781edbda7..4ae03ecb8b63b0d0c4fe26bcd831d351328596ab 100644 (file)
@@ -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));
        }
 
index d001bffab0394aa37a4a97eee15bcadbb2ab5022..1d393c3f9d7bef1ed68dc53fdcabe8022baf2e35 100644 (file)
@@ -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__
index 1f84b7363b033604e52590deb48640f12853e244..523f2c7a1c18de1aae1f0a2f2e3594c0648820af 100644 (file)
@@ -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);