* are transferred between state entries as the conversation progresses.
*
* @note Called with the mutex free.
+ *
+ * @param[in] state tree to lookup state in.
+ * @param[in] request to restore state for.
+ * @return
+ * - 0 on success (state restored)
+ * - 1 if no state attribute existed.
+ * - -1 if a state entry matching the value couldn't be found.
+ * - -2 if a state entry has already been thawed by a another request.
*/
-void fr_state_to_request(fr_state_tree_t *state, request_t *request)
+int fr_state_to_request(fr_state_tree_t *state, request_t *request)
{
fr_state_entry_t *entry;
TALLOC_CTX *old_ctx = NULL;
*/
vp = fr_pair_find_by_da(&request->request_pairs, state->da);
if (!vp) {
- RDEBUG3("No &request.State attribute, can't restore &session-state");
+ RDEBUG3("No &request.%s attribute, can't restore &session-state", state->da->name);
if (request->seq_start == 0) request->seq_start = request->number; /* Need check for fake requests */
- return;
+ return 1;
}
PTHREAD_MUTEX_LOCK(&state->mutex);
if (entry->thawed) {
REDEBUG("State entry has already been thawed by a request %"PRIu64, entry->thawed->number);
PTHREAD_MUTEX_UNLOCK(&state->mutex);
- return;
+ return -2;
}
if (request->session_state_ctx) old_ctx = request->session_state_ctx; /* Store for later freeing */
entry->ctx = NULL;
entry->thawed = request;
+ PTHREAD_MUTEX_UNLOCK(&state->mutex);
+ } else {
+ PTHREAD_MUTEX_UNLOCK(&state->mutex);
+ REDEBUG("No state entry matching &request.%pP found", vp);
+ return -1;
}
- PTHREAD_MUTEX_UNLOCK(&state->mutex);
if (!fr_pair_list_empty(&request->session_state_pairs)) {
RDEBUG2("Restored &session-state");
RDEBUG3("%s - restored", state->da->name);
REQUEST_VERIFY(request);
- return;
+ return 0;
}
void fr_state_discard(fr_state_tree_t *state, request_t *request);
-void fr_state_to_request(fr_state_tree_t *state, request_t *request);
+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);
talloc_free(msg);
}
-
-#if 0
RECV(access_request)
{
- RETURN_MODULE_FAIL;
+ process_radius_t const *inst = talloc_get_type_abort_const(mctx->instance, process_radius_t);
+
+ /*
+ * Requests with invalid state values
+ * are extremely unlikely to result
+ * in success, so reject them as quickly
+ * as we possible.
+ */
+ if (fr_state_to_request(inst->auth.state_tree, request) < 0) {
+ fr_process_state_t const *state;
+ CONF_SECTION *cs;
+
+ request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
+ UPDATE_STATE_CS(reply);
+ return unlang_module_yield_to_section(p_result, request,
+ cs, state->rcode, state->send,
+ NULL, NULL);
+ }
+
+ return CALL_RECV(generic);
}
-#endif
RESUME(auth_type);
}
/*
- * Set the reply code.
+ * Most cases except handled...
*/
- request->reply->code = auth_type_rcode[rcode];
- if (!request->reply->code) {
+ if (auth_type_rcode[rcode]) request->reply->code = auth_type_rcode[rcode];
+
+ switch (request->reply->code) {
+ case 0:
RDEBUG("No reply code was set. Forcing to Access-Reject");
request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
+ FALL_THROUGH;
- } else switch (request->reply->code) {
/*
* Print complaints before running "send Access-Reject"
*/
[RLM_MODULE_NOTFOUND] = FR_RADIUS_CODE_ACCESS_REJECT
},
.rcode = RLM_MODULE_NOOP,
- .recv = recv_generic,
+ .recv = recv_access_request,
.resume = resume_access_request,
.section_offset = offsetof(process_radius_sections_t, access_request),
},