]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Discard the child state when processing NAK
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 9 Apr 2021 23:35:09 +0000 (00:35 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 9 Apr 2021 23:35:09 +0000 (00:35 +0100)
src/lib/server/state.c
src/lib/server/state.h
src/modules/rlm_eap/rlm_eap.c

index 50824366e7a290f2e00fef003f5f4d608bee49d4..12aaa1ce37e279d09412cf5ac929eb24d6fcdceb 100644 (file)
@@ -855,6 +855,32 @@ void fr_state_restore_to_child(request_t *child, void const *unique_ptr, int uni
        talloc_free(child_entry);
 }
 
+/** Remove state from a child
+ *
+ * This is useful for modules like EAP, where we keep a persistent eap_session
+ * but may call multiple EAP method modules during negotiation, and need to
+ * discard the state between each module call.
+ *
+ * @param[in] parent           Holding the child's state.
+ * @param[in] unique_ptr       A parent may have multiple subrequests spawned
+ *                             by different modules.  This identifies the module
+ *                             or other facility that spawned the subrequest.
+ * @param[in] unique_int       Further identification.
+ */
+void fr_state_discard_child(request_t *parent, void const *unique_ptr, int unique_int)
+{
+       state_child_entry_t     *child_entry;
+       request_t               *request = parent; /* Stupid logging */
+
+       child_entry = request_data_get(parent, unique_ptr, unique_int);
+       if (!child_entry) {
+               RDEBUG3("No child state found in parent %s", parent->name);
+               return;
+       }
+
+       talloc_free(child_entry);
+}
+
 /** Return number of entries created
  *
  */
index 64bbbddf5f4aade5f5a0bbc3600bb37106a50316..367b70ec104f22fa472d67f4d1e2fd1affcd64fb 100644 (file)
@@ -45,7 +45,9 @@ int   fr_state_to_request(fr_state_tree_t *state, request_t *request);
 int    fr_request_to_state(fr_state_tree_t *state, request_t *request);
 
 void   fr_state_store_in_parent(request_t *request, void const *unique_ptr, int unique_int);
-void   fr_state_restore_to_child(request_t *request, void const *unique_ptr, int unique_int);
+void   fr_state_restore_to_child(request_t *child, void const *unique_ptr, int unique_int);
+void   fr_state_discard_child(request_t *parent, void const *unique_ptr, int unique_int);
+
 /*
  *     Stats
  */
index 944a08453bc96304fece2ea71333f3d63be9155d..75f9db174e0d73c132a0eec8c56807877196866d 100644 (file)
@@ -569,6 +569,7 @@ static unlang_action_t eap_method_select(rlm_rcode_t *p_result, module_ctx_t con
                 *      the memory it alloced.
                 */
                TALLOC_FREE(eap_session->opaque);
+               fr_state_discard_child(eap_session->request, eap_session, 0);
                next = eap_process_nak(mctx, eap_session->request, eap_session->type, type);
                if (!next) RETURN_MODULE_REJECT;