]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add variant of functions which do not produce a result
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 2 Jun 2025 02:30:30 +0000 (20:30 -0600)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 18 Jun 2025 12:53:15 +0000 (13:53 +0100)
27 files changed:
src/lib/eap/base.c
src/lib/eap/tls.c
src/lib/ldap/base.c
src/lib/ldap/bind.c
src/lib/ldap/edir.c
src/lib/ldap/sasl.c
src/lib/server/trigger.c
src/lib/server/virtual_servers.c
src/lib/tls/base-h
src/lib/tls/cache.c
src/lib/tls/session.c
src/lib/tls/verify.c
src/lib/tls/virtual_server.c
src/lib/unlang/call_env.c
src/lib/unlang/function.c
src/lib/unlang/function.h
src/lib/unlang/interpret.c
src/modules/rlm_eap/types/rlm_eap_peap/peap.c
src/modules/rlm_ldap/groups.c
src/modules/rlm_ldap/profile.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_ldap/rlm_ldap.h
src/modules/rlm_ldap/user.c
src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sql/rlm_sql.h
src/modules/rlm_sql/sql.c
src/modules/rlm_sqlippool/rlm_sqlippool.c

index 907740b4bf12c2014d5f684a48c21414a345ff34..dad15a17678c7f343cf2b65deb8efd97ff912ea0 100644 (file)
@@ -441,13 +441,13 @@ unlang_action_t eap_virtual_server(request_t *request, eap_session_t *eap_sessio
                                  attr_packet_type) < 0) return UNLANG_ACTION_FAIL;
        vp->vp_uint32 = FR_RADIUS_CODE_ACCESS_REQUEST;
 
-       if (unlang_function_push(/* transparent */ unlang_interpret_result(request),
-                                request,
-                                NULL,
-                                eap_virtual_server_resume,
-                                NULL, 0,
-                                UNLANG_SUB_FRAME,
-                                eap_session) < 0) return UNLANG_ACTION_FAIL;
+       if (unlang_function_push_with_result(/* transparent */ unlang_interpret_result(request),
+                                            request,
+                                            NULL,
+                                            eap_virtual_server_resume,
+                                            NULL, 0,
+                                            UNLANG_SUB_FRAME,
+                                            eap_session) < 0) return UNLANG_ACTION_FAIL;
 
        if (unlang_call_push(NULL, request, server_cs, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
 
index 2af9995b0fddafd347ec9b5fe79c7f94af185ceb..c4699d1fe1ba62789a6c2101557bc6fcdc71d8d8 100644 (file)
@@ -803,8 +803,7 @@ ignore_length:
  *     - eap_tls_session->state = EAP_TLS_ESTABLISHED if the handshake
  *       completed successfully, and there's no more data to send.
  */
-static unlang_action_t eap_tls_handshake_resume(UNUSED unlang_result_t *p_result,
-                                               request_t *request, void *uctx)
+static unlang_action_t eap_tls_handshake_resume(request_t *request, void *uctx)
 {
        eap_session_t           *eap_session = talloc_get_type_abort(uctx, eap_session_t);
        eap_tls_session_t       *eap_tls_session = talloc_get_type_abort(eap_session->opaque, eap_tls_session_t);
@@ -927,11 +926,12 @@ static inline CC_HINT(always_inline) unlang_action_t eap_tls_handshake_push(requ
        /*
         *      Will run after the handshake round completes
         */
-       if (unlang_function_push(/* discard, sets eap_tls_session->state */ NULL,
-                                request,
+       if (unlang_function_push(request,
                                 NULL,
                                 eap_tls_handshake_resume,
-                                NULL, 0, UNLANG_SUB_FRAME, eap_session) < 0) return UNLANG_ACTION_FAIL;
+                                NULL,
+                                0, UNLANG_SUB_FRAME,
+                                eap_session) < 0) return UNLANG_ACTION_FAIL;
 
        if (fr_tls_session_async_handshake_push(request, tls_session) < 0) return UNLANG_ACTION_FAIL;
 
index 3967710765b466f2956dc2dc07a160a636f31825..7dc89c147e87a255ec7ee9a081e2deac75b1d714 100644 (file)
@@ -615,7 +615,7 @@ static void ldap_trunk_search_results_debug(request_t *request, fr_ldap_query_t
  *
  * @note This function sets no rcode, the result of query is available in query->ret.
  */
-static unlang_action_t ldap_trunk_query_results(UNUSED unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t ldap_trunk_query_results(request_t *request, void *uctx)
 {
        fr_ldap_query_t         *query = talloc_get_type_abort(uctx, fr_ldap_query_t);
 
@@ -726,12 +726,12 @@ unlang_action_t fr_ldap_trunk_search(TALLOC_CTX *ctx,
                return UNLANG_ACTION_FAIL;
        }
 
-       action = unlang_function_push(/* discard, result is written to query->ret */NULL,
-                                     request,
+       action = unlang_function_push(request,
                                      NULL,
                                      ldap_trunk_query_results,
                                      ldap_trunk_query_cancel, ~FR_SIGNAL_CANCEL,
-                                     UNLANG_SUB_FRAME, query);
+                                     UNLANG_SUB_FRAME,
+                                     query);
 
        if (action == UNLANG_ACTION_FAIL) goto error;
 
@@ -777,12 +777,12 @@ unlang_action_t fr_ldap_trunk_modify(TALLOC_CTX *ctx,
                return UNLANG_ACTION_FAIL;
        }
 
-       action = unlang_function_push(/* discard, result is written to query->ret */ NULL,
-                                     request,
+       action = unlang_function_push(request,
                                      NULL,
                                      ldap_trunk_query_results,
                                      ldap_trunk_query_cancel, ~FR_SIGNAL_CANCEL,
-                                     UNLANG_SUB_FRAME, query);
+                                     UNLANG_SUB_FRAME,
+                                     query);
 
        if (action == UNLANG_ACTION_FAIL) goto error;
 
@@ -909,12 +909,12 @@ unlang_action_t fr_ldap_trunk_extended(TALLOC_CTX *ctx,
                return UNLANG_ACTION_FAIL;
        }
 
-       action = unlang_function_push(/* discard, result is written to query->ret */ NULL,
-                                     request,
+       action = unlang_function_push(request,
                                      NULL,
                                      ldap_trunk_query_results,
                                      ldap_trunk_query_cancel, ~FR_SIGNAL_CANCEL,
-                                     UNLANG_SUB_FRAME, query);
+                                     UNLANG_SUB_FRAME,
+                                     query);
 
        if (action == UNLANG_ACTION_FAIL) goto error;
 
index 8985a15de3be1277ef1003fbbc7f1f79b50081f2..b8047434be04b4df5d961b63a10e55f212efa1cf 100644 (file)
@@ -368,11 +368,11 @@ unlang_action_t fr_ldap_bind_auth_async(unlang_result_t *p_result, request_t *re
                RETURN_UNLANG_FAIL;
        }
 
-       return unlang_function_push(p_result,
-                                   request,
-                                   ldap_async_auth_bind_start,
-                                   ldap_async_auth_bind_results,
-                                   ldap_async_auth_bind_cancel,
-                                   ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
-                                   bind_auth_ctx);
+       return unlang_function_push_with_result(p_result,
+                                               request,
+                                               ldap_async_auth_bind_start,
+                                               ldap_async_auth_bind_results,
+                                               ldap_async_auth_bind_cancel,
+                                               ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
+                                               bind_auth_ctx);
 }
index b650bc2c0247aab3f44bb63cc5c2c130195f2903..190832cadf77462637abc94691e19a01ec8782f3 100644 (file)
@@ -316,12 +316,12 @@ unlang_action_t fr_ldap_edir_get_password(unlang_result_t *p_result,
                RETURN_UNLANG_FAIL;
        }
 
-       return unlang_function_push(p_result,
-                                   request,
-                                   ldap_edir_get_password_start,
-                                   ldap_edir_get_password_resume,
-                                   ldap_edir_get_password_cancel, ~FR_SIGNAL_CANCEL,
-                                   UNLANG_SUB_FRAME, edir_ctx);
+       return unlang_function_push_with_result(p_result,
+                                               request,
+                                               ldap_edir_get_password_start,
+                                               ldap_edir_get_password_resume,
+                                               ldap_edir_get_password_cancel, ~FR_SIGNAL_CANCEL,
+                                               UNLANG_SUB_FRAME, edir_ctx);
 }
 
 char const *fr_ldap_edir_errstr(int code)
index d8b5399f3ce30d739e4f4885e95562ff9322da37..af6a20e033e982214a89350cfe908f5c47474cab 100644 (file)
@@ -553,11 +553,11 @@ unlang_action_t fr_ldap_sasl_bind_auth_async(unlang_result_t *p_result,
                RETURN_UNLANG_FAIL;
        }
 
-       return unlang_function_push(p_result,
-                                   request,
-                                   ldap_async_sasl_bind_auth_start,
-                                   ldap_async_sasl_bind_auth_results,
-                                   ldap_async_sasl_bind_auth_cancel,
-                                   ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
-                                   bind_auth_ctx);
+       return unlang_function_push_with_result(p_result,
+                                               request,
+                                               ldap_async_sasl_bind_auth_start,
+                                               ldap_async_sasl_bind_auth_results,
+                                               ldap_async_sasl_bind_auth_cancel,
+                                               ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
+                                               bind_auth_ctx);
 }
index 85e993c73c6d79ff35eacea43df9117e40c12851..334aefec11fd215cabb74c2ecc620818d7c7b368 100644 (file)
@@ -141,23 +141,21 @@ typedef struct {
        fr_time_delta_t         timeout;        //!< How long the trigger has to run.
 } fr_trigger_t;
 
-static unlang_action_t trigger_done(unlang_result_t *p_result,
-                                   request_t *request, void *rctx)
+static unlang_action_t trigger_done(request_t *request, void *rctx)
 {
        fr_trigger_t    *trigger = talloc_get_type_abort(rctx, fr_trigger_t);
 
        if (trigger->exec.status == 0) {
                RDEBUG2("Trigger \"%s\" done", trigger->command);
-               RETURN_UNLANG_OK;
+               return UNLANG_ACTION_CALCULATE_RESULT;
        }
 
        RERROR("Trigger \"%s\" failed", trigger->command);
 
-       RETURN_UNLANG_FAIL;
+       return UNLANG_ACTION_CALCULATE_RESULT;
 }
 
-static unlang_action_t trigger_resume(UNUSED unlang_result_t *p_result,
-                                     request_t *request, void *rctx)
+static unlang_action_t trigger_resume(request_t *request, void *rctx)
 {
        fr_trigger_t    *trigger = talloc_get_type_abort(rctx, fr_trigger_t);
 
@@ -194,7 +192,7 @@ static unlang_action_t trigger_resume(UNUSED unlang_result_t *p_result,
        return UNLANG_ACTION_YIELD;
 }
 
-static unlang_action_t trigger_run(unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t trigger_run(request_t *request, void *uctx)
 {
        fr_trigger_t    *trigger = talloc_get_type_abort(uctx, fr_trigger_t);
 
@@ -202,7 +200,7 @@ static unlang_action_t trigger_run(unlang_result_t *p_result, request_t *request
 
        if (unlang_xlat_push(request, NULL, &trigger->args, request,
                             trigger->xlat, UNLANG_SUB_FRAME) < 0) {
-               RETURN_UNLANG_FAIL;
+               return UNLANG_ACTION_CALCULATE_RESULT;
        }
 
        return UNLANG_ACTION_PUSHED_CHILD;
@@ -423,11 +421,12 @@ int trigger_exec(unlang_interpret_t *intp,
                return -1;
        }
 
-       if (unlang_function_push(/* discarded */ NULL,
-                                request,
-                                trigger_run, trigger_resume,
+       if (unlang_function_push(request,
+                                trigger_run,
+                                trigger_resume,
                                 NULL, 0,
-                                UNLANG_TOP_FRAME, trigger) < 0) goto error;
+                                UNLANG_TOP_FRAME,
+                                trigger) < 0) goto error;
 
        if (!intp) {
                /*
index f037f133bcebed857e8a0d9b41fe180d3ff29527..4f341df3228205a827529f322d1df40ef948aa5c 100644 (file)
@@ -781,12 +781,13 @@ unlang_action_t virtual_server_push(unlang_result_t *p_result, request_t *reques
                if (unlang_interpret_stack_depth(request) > 1) {
                        unlang_action_t action;
 
-                       action = unlang_function_push(unlang_interpret_result(request), /* transparent */
-                                                     request,
-                                                     NULL,                             /* don't call it immediately */
-                                                     server_remove_log_destination,    /* but when we pop the frame */
-                                                     server_signal_remove_log_destination, ~(FR_SIGNAL_CANCEL),
-                                                     top_frame, vs);
+                       action = unlang_function_push_with_result(unlang_interpret_result(request),     /* transparent */
+                                                                 request,
+                                                                 NULL,                                 /* don't call it immediately */
+                                                                 server_remove_log_destination,        /* but when we pop the frame */
+                                                                 server_signal_remove_log_destination, ~(FR_SIGNAL_CANCEL),
+                                                                 top_frame,
+                                                                 vs);
                        if (action != UNLANG_ACTION_PUSHED_CHILD) return action;
 
                        top_frame = UNLANG_SUB_FRAME;   /* switch to SUB_FRAME after the first instruction */
index 2113fe38341a8122f7f1ccdef941fa7085e1bc55..6540b52d009f25c94fd946e37ee5799b0dc71820 100644 (file)
@@ -171,7 +171,7 @@ void                fr_tls_dict_free(void);
 /*
  *     tls/virtual_server.c
  */
-unlang_action_t fr_tls_call_push(request_t *child, unlang_function_t resume,
+unlang_action_t fr_tls_call_push(request_t *child, unlang_function_no_result_t resume,
                                 fr_tls_conf_t *conf, fr_tls_session_t *tls_session, bool cache_required);
 
 #ifdef __cplusplus
index f6e0869720d7984b86ed3759f7af961d706a276d..ac3fb6e2b246cc39096843b104014f663adcaa8b 100644 (file)
@@ -348,7 +348,7 @@ static void tls_cache_delete_request(SSL_SESSION *sess)
 
 /** Process the result of `load session { ... }`
  */
-static unlang_action_t tls_cache_load_result(UNUSED unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t tls_cache_load_result(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        fr_tls_cache_t          *tls_cache = tls_session->cache;
@@ -457,8 +457,7 @@ static unlang_action_t tls_cache_load_push(request_t *request, fr_tls_session_t
 
 /** Process the result of `store session { ... }`
  */
-static unlang_action_t tls_cache_store_result(UNUSED unlang_result_t *p_result,
-                                             request_t *request, void *uctx)
+static unlang_action_t tls_cache_store_result(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        fr_tls_cache_t          *tls_cache = tls_session->cache;
@@ -593,8 +592,7 @@ unlang_action_t tls_cache_store_push(request_t *request, fr_tls_conf_t *conf, fr
 
 /** Process the result of `clear session { ... }`
  */
-static unlang_action_t tls_cache_clear_result(UNUSED unlang_result_t *p_result,
-                                             request_t *request, void *uctx)
+static unlang_action_t tls_cache_clear_result(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        fr_tls_cache_t          *tls_cache = tls_session->cache;
index 914fcb334bb66b58e57536ab15b3d30caac255b2..f2a0476027162d26638083d9648a2d6d663a5a22 100644 (file)
@@ -1147,8 +1147,7 @@ static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *sess
  *
  * As this is just a logging session, it's result doesn't affect the parent.
  */
-static unlang_action_t tls_establish_session_result(UNUSED unlang_result_t *p_result,
-                                                   UNUSED request_t *request, UNUSED void *uctx)
+static unlang_action_t tls_establish_session_result(UNUSED request_t *request, UNUSED void *uctx)
 {
        return UNLANG_ACTION_CALCULATE_RESULT;
 }
@@ -1202,8 +1201,7 @@ unlang_action_t tls_establish_session_push(request_t *request, fr_tls_conf_t *co
 /** Finish off a handshake round, possibly adding attributes to the request
  *
  */
-static unlang_action_t tls_session_async_handshake_done_round(UNUSED unlang_result_t *p_result,
-                                                             request_t *request, void *uctx)
+static unlang_action_t tls_session_async_handshake_done_round(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        int                     ret;
@@ -1391,15 +1389,13 @@ static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED
  *
  * This function may be called multiple times, once after every asynchronous request.
  *
- * @param[in,out] p_result     UNUSED.
  * @param[in] request          The current request.
  * @param[in] uctx             #fr_tls_session_t to continue.
  * @return
  *     - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
  *     - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
  */
-static unlang_action_t tls_session_async_handshake_cont(unlang_result_t *p_result,
-                                                       request_t *request, void *uctx)
+static unlang_action_t tls_session_async_handshake_cont(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        int                     err;
@@ -1567,7 +1563,7 @@ DIAG_ON(DIAG_UNKNOWN_PRAGMAS)
                 */
                if (fr_tls_log_io_error(request,
                                        err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
-               return tls_session_async_handshake_done_round(p_result, request, uctx);
+               return tls_session_async_handshake_done_round(request, uctx);
        }
 }
 
@@ -1580,15 +1576,13 @@ DIAG_ON(DIAG_UNKNOWN_PRAGMAS)
  * #tls_session_async_handshake_read is split out because we may need to call
  * it multiple times, once after every async action.
  *
- * @param[in,out] p_result     UNUSED.
  * @param[in] request          The current request.
  * @param[in] uctx             #fr_tls_session_t to continue.
  * @return
  *     - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
  *     - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
  */
-static unlang_action_t tls_session_async_handshake(unlang_result_t *p_result,
-                                                  request_t *request, void *uctx)
+static unlang_action_t tls_session_async_handshake(request_t *request, void *uctx)
 {
        fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        int ret;
@@ -1633,7 +1627,7 @@ static unlang_action_t tls_session_async_handshake(unlang_result_t *p_result,
                record_init(&tls_session->dirty_in);
        }
 
-       return tls_session_async_handshake_cont(p_result, request, uctx);       /* Must unbind request, possibly asynchronously */
+       return tls_session_async_handshake_cont(request, uctx); /* Must unbind request, possibly asynchronously */
 }
 
 /** Push a handshake call onto the stack
@@ -1653,8 +1647,7 @@ static unlang_action_t tls_session_async_handshake(unlang_result_t *p_result,
  */
 unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
 {
-       return unlang_function_push(/* discard, result is written to tls_session->result */ NULL,
-                                   request,
+       return unlang_function_push(request,
                                    tls_session_async_handshake,
                                    NULL,
                                    tls_session_async_handshake_signal,
@@ -1986,7 +1979,7 @@ fr_tls_session_t *fr_tls_session_alloc_server(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx,
        return tls_session;
 }
 
-static unlang_action_t tls_new_session_result(UNUSED unlang_result_t *p_result, request_t *request, UNUSED void *uctx)
+static unlang_action_t tls_new_session_result(request_t *request, UNUSED void *uctx)
 {
        request_t       *parent = request->parent;
 
@@ -2013,8 +2006,7 @@ unlang_action_t fr_tls_new_session_push(request_t *request, fr_tls_conf_t const
        if (unlang_subrequest_child_push(NULL, child, child->parent, true, UNLANG_SUB_FRAME) < 0) {
                return UNLANG_ACTION_FAIL;
        }
-       if (unlang_function_push(/* discard, eap_tls_session->state holds result */ NULL,
-                                child,
+       if (unlang_function_push(child,
                                 NULL,
                                 tls_new_session_result,
                                 NULL, 0,
index c04fa676935bb0aa2617bc3cb9327c64456e13cf..e026e8974f0bad7ec051e2603432cc41854ec462 100644 (file)
@@ -411,8 +411,7 @@ int fr_tls_verify_cert_chain(request_t *request, SSL *ssl)
 /** Process the result of `verify certificate { ... }`
  *
  */
-static unlang_action_t tls_verify_client_cert_result(UNUSED unlang_result_t *p_result,
-                                                    request_t *request, void *uctx)
+static unlang_action_t tls_verify_client_cert_result(request_t *request, void *uctx)
 {
        fr_tls_session_t        *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
        fr_pair_t               *vp, *next;
index 42e3e370a3a87dea73d85e550c9e353377ddba70..60f34b4f4495bec384ba14bf12d1a24c9b18df99 100644 (file)
@@ -51,7 +51,7 @@
  *      - 0 on success.
  *     - -1 on failure.
  */
-unlang_action_t fr_tls_call_push(request_t *child, unlang_function_t resume,
+unlang_action_t fr_tls_call_push(request_t *child, unlang_function_no_result_t resume,
                                 fr_tls_conf_t *conf, fr_tls_session_t *tls_session,
 #ifdef NDEBUG
                                 UNUSED
@@ -74,8 +74,7 @@ unlang_action_t fr_tls_call_push(request_t *child, unlang_function_t resume,
         *      Setup a function to execute after the
         *      subrequest completes.
         */
-       if (unlang_function_push(/* discard, the failure of these callbacks does not affect the handshake */NULL,
-                                child,
+       if (unlang_function_push(child,
                                 NULL,
                                 resume,
                                 NULL,
index 7f7cb3d1f27b9126fc20b67c560ed6c271f51d3f..8b4e984f188b8d3cffb6237200a40d8d9afe0473 100644 (file)
@@ -128,12 +128,12 @@ typedef struct {
        void                                    **data;                 //!< Final destination structure for value boxes.
 } call_env_rctx_t;
 
-static unlang_action_t call_env_expand_repeat(unlang_result_t *p_result, request_t *request, void *uctx);
+static unlang_action_t call_env_expand_repeat(request_t *request, void *uctx);
 
 /** Start the expansion of a call environment tmpl.
  *
  */
-static unlang_action_t call_env_expand_start(UNUSED unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t call_env_expand_start(request_t *request, void *uctx)
 {
        call_env_rctx_t *call_env_rctx = talloc_get_type_abort(uctx, call_env_rctx_t);
        TALLOC_CTX      *ctx;
@@ -239,8 +239,7 @@ static unlang_action_t call_env_expand_start(UNUSED unlang_result_t *p_result, r
  *
  * If there are more tmpls to expand, push the next expansion.
  */
-static unlang_action_t call_env_expand_repeat(UNUSED unlang_result_t *p_result,
-                                             request_t *request, void *uctx)
+static unlang_action_t call_env_expand_repeat(request_t *request, void *uctx)
 {
        void                    *out = NULL, *tmpl_out = NULL;
        call_env_rctx_t         *call_env_rctx = talloc_get_type_abort(uctx, call_env_rctx_t);
@@ -280,12 +279,11 @@ parse_only:
                return UNLANG_ACTION_CALCULATE_RESULT;
        }
 
-       return unlang_function_push(/* discard, result is provided in env_result */ NULL,
-                                   request,
+       return unlang_function_push(request,
                                    call_env_expand_start,
                                    call_env_expand_repeat,
-                                   NULL, 0,
-                                   UNLANG_SUB_FRAME,
+                                   NULL,
+                                   0, UNLANG_SUB_FRAME,
                                    call_env_rctx);
 }
 
@@ -311,8 +309,7 @@ unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_re
        call_env_rctx->call_env = call_env;
        fr_value_box_list_init(&call_env_rctx->tmpl_expanded);
 
-       return unlang_function_push(/* discard, result is provided in env_result */NULL,
-                                   request,
+       return unlang_function_push(request,
                                    call_env_expand_start,
                                    call_env_expand_repeat,
                                    NULL,
index a8083375452efea18c1844d0c788aceb3a6591a9..36090ba219ac1e91eee01c7b0bad0d20754e2dd7 100644 (file)
  */
 RCSID("$Id$")
 
+#include "action.h"
 #include "unlang_priv.h"
 #include "function.h"
 
+#define FUNC(_state) *((void **)&state->func)
+#define REPEAT(_state) *((void **)&state->repeat)
+
 /*
  *     Some functions differ mainly in their parsing
  */
 typedef struct {
-       unlang_function_t               func;                   //!< To call when going down the stack.
+       union {
+               unlang_function_no_result_t     nres;           //!< To call when going down the stack.
+               unlang_function_with_result_t   wres;           //!< To call when going down the stack.
+       } func;
        char const                      *func_name;             //!< Debug name for the function.
-       unlang_function_t               repeat;                 //!< To call when going back up the stack.
+
+       union {
+               unlang_function_no_result_t     nres;           //!< To call when going back up the stack.
+               unlang_function_with_result_t   wres;           //!< To call when going back up the stack.
+       } repeat;
+       unlang_function_type_t          type;                   //!< Record whether we need to call the
        char const                      *repeat_name;           //!< Debug name for the repeat function.
+
        unlang_function_signal_t        signal;                 //!< Signal function to call.
        fr_signal_t                     sigmask;                //!< Signals to block.
        char const                      *signal_name;           //!< Debug name for the signal function.
@@ -89,74 +102,98 @@ static void unlang_function_signal(request_t *request,
        state->signal(request, action, state->uctx);
 }
 
-static unlang_action_t unlang_function_call_repeat(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
+
+/*
+ *     Don't let the callback mess with the current
+ *     module permanently.
+ */
+#define STORE_CALLER \
+       char const *caller; \
+       caller = request->module; \
+       request->module = NULL
+
+#define RESTORE_CALLER \
+       request->module = caller;
+
+/** Call a generic function that produces a result
+ *
+ * @param[out] p_result                The frame result.
+ * @param[in] request          The current request.
+ * @param[in] frame            The current frame.
+ */
+static unlang_action_t call_with_result(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_action_t                 ua;
        unlang_frame_state_func_t       *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t);
-       char const                      *caller;
-
-       /*
-        *      Don't let the callback mess with the current
-        *      module permanently.
-        */
-       caller = request->module;
-       request->module = NULL;
-       RDEBUG4("Calling repeat function %p (%s)", state->repeat, state->repeat_name);
 
-       /*
-        *      FIXME: The full scratch rcode/priority should be passed in
-        *      and then passed to this function.
-        */
-       ua = state->repeat(p_result, request, state->uctx);
-       request->module = caller;
+       STORE_CALLER;
+
+again:
+       RDEBUG4("Calling function %p (%s)", state->func.wres, state->func_name);
+       ua = state->func.wres(p_result, request, state->uctx);
+       state->func.wres = state->repeat.wres;
+       state->repeat.wres = NULL;
+       state->repeat_name = NULL;
+       if (state->func.wres) {
+               switch (ua) {
+               case UNLANG_ACTION_STOP_PROCESSING:
+                       break;
+
+               case UNLANG_ACTION_CALCULATE_RESULT:
+                       goto again;
+
+               default:
+                       frame_repeat(frame, call_with_result);
+               }
+       }
+       RESTORE_CALLER;
 
        return ua;
 }
 
-/** Call a generic function
+/** Call a generic function that produces no result
+ *
+ * These functions report results by modifying the rctx passed into the function.
+ * They are not allowed to return UNLANG_ACTION_FAIL.  In non-debug builds this
+ * is rewritten to UNLANG_ACTION_CALCULATE_RESULT, and in debug builds it triggers
+ * an assert.
  *
  * @param[out] p_result                The frame result.
  * @param[in] request          The current request.
  * @param[in] frame            The current frame.
  */
-static unlang_action_t unlang_function_call(UNUSED unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
+static unlang_action_t call_no_result(UNUSED unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_action_t                 ua;
        unlang_frame_state_func_t       *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t);
-       char const                      *caller;
-
-       /*
-        *      Don't let the callback mess with the current
-        *      module permanently.
-        */
-       caller = request->module;
-       request->module = NULL;
-
-       RDEBUG4("Calling function %p (%s)", state->func, state->func_name);
-       ua = state->func(p_result, request, state->uctx);
-       switch (ua) {
-       case UNLANG_ACTION_STOP_PROCESSING:
-               break;
-
-       /*
-        *      Similar functionality to the modcall code.
-        *      If we have a repeat function set and the
-        *      initial function is done, call the repeat
-        *      function using the C stack.
-        */
-       case UNLANG_ACTION_CALCULATE_RESULT:
-               if (state->repeat) unlang_function_call_repeat(p_result, request, frame);
-               break;
 
-       /*
-        *      Function pushed more children or yielded
-        *      setup our repeat function for when we
-        *      eventually start heading back up the stack.
-        */
-       default:
-               if (state->repeat) frame_repeat(frame, unlang_function_call_repeat);
+       STORE_CALLER;
+
+again:
+       RDEBUG4("Calling function %p (%s)", state->func.nres, state->func_name);
+       ua = state->func.nres(request, state->uctx);
+       state->func.nres = state->repeat.nres;
+       state->func_name = state->repeat_name;
+       state->repeat.nres = NULL;
+       state->repeat_name = NULL;
+       if (state->func.nres) {
+               switch (ua) {
+               case UNLANG_ACTION_STOP_PROCESSING:
+                       break;
+
+               case UNLANG_ACTION_CALCULATE_RESULT:
+                       goto again;
+
+               default:
+                       frame_repeat(frame, call_no_result);
+               }
        }
-       request->module = caller;
+       if (ua == UNLANG_ACTION_FAIL) {
+               fr_assert_msg(0, "Function %s (%p) is not allowed to indicate failure via UNLANG_ACTION_FAIL",
+                             state->func_name, state->func.nres);
+               ua = UNLANG_ACTION_CALCULATE_RESULT;
+       }
+       RESTORE_CALLER;
 
        return ua;
 }
@@ -182,7 +219,7 @@ int unlang_function_clear(request_t *request)
        }
 
        state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t);
-       state->repeat = NULL;
+       REPEAT(state) = NULL;
        state->signal = NULL;
 
        repeatable_clear(frame);
@@ -238,11 +275,12 @@ int _unlang_function_signal_set(request_t *request, unlang_function_signal_t sig
  * @param[in] request          The current request.
  * @param[in] repeat           the repeat function to set.
  * @param[in] repeat_name      Name of the repeat function call (for debugging).
+ * @param[in] type             Type of repeat function (with or without result).
  * @return
  *     - 0 on success.
  *      - -1 on failure.
  */
-int _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, char const *repeat_name)
+int _unlang_function_repeat_set(request_t *request, void *repeat, char const *repeat_name, unlang_function_type_t type)
 {
        unlang_stack_t                  *stack = request->stack;
        unlang_stack_frame_t            *frame = &stack->frame[stack->depth];
@@ -255,19 +293,84 @@ int _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, ch
 
        state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t);
 
+       if (unlikely(state->type != type)) {
+               fr_assert_msg(0, "Function type mismatch \"%s\"", repeat_name);
+               return -1;
+       }
+
        /*
         *      If we're inside unlang_function_call,
         *      it'll pickup state->repeat and do the right thing
         *      once the current function returns.
         */
-       state->repeat = repeat;
+       REPEAT(state) = repeat;
        state->repeat_name = repeat_name;
        repeatable_set(frame);
 
        return 0;
 }
 
-/** Push a generic function onto the unlang stack
+static inline CC_HINT(always_inline)
+unlang_action_t unlang_function_push_common(unlang_result_t *p_result,
+                                           request_t *request,
+                                           void *func,
+                                           char const *func_name,
+                                           void *repeat,
+                                           char const *repeat_name,
+                                           unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
+                                           unlang_function_type_t type,
+                                           bool top_frame,
+                                           void *uctx)
+{
+       unlang_stack_t                  *stack = request->stack;
+       unlang_stack_frame_t            *frame;
+       unlang_frame_state_func_t       *state;
+
+       /*
+        *      Push module's function
+        */
+       if (unlang_interpret_push(p_result, request, &function_instruction,
+                                 FRAME_CONF(RLM_MODULE_NOOP, top_frame), UNLANG_NEXT_STOP) < 0) {
+               RETURN_UNLANG_FAIL;
+       }
+
+       frame = &stack->frame[stack->depth];
+
+       /*
+        *      Initialize state
+        */
+       state = frame->state;
+       state->signal = signal;
+       state->sigmask = sigmask;
+       state->signal_name = signal_name;
+       state->type = type;
+       state->uctx = uctx;
+
+       /*
+        *      Just skip to the repeat state directly
+        */
+       if (!func && repeat) {
+               FUNC(state) = repeat;
+               state->func_name = repeat_name;
+               repeatable_set(frame);  /* execute on the way back up */
+       /*
+        *      If we have both a function and a repeat,
+        *      then record them both, and execute
+        *      'func' first.  This will set the repeat
+        *      function to call 'repeat' on the way
+        *      back up the stack.
+        */
+       } else {
+               FUNC(state) = func;
+               state->func_name = func_name;
+               REPEAT(state) = repeat;
+               state->repeat_name = repeat_name;
+       }
+
+       return UNLANG_ACTION_PUSHED_CHILD;
+}
+
+/** Push a generic function onto the unlang stack with a result
  *
  * @private
  *
@@ -291,52 +394,73 @@ int _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, ch
  *     - UNLANG_ACTION_PUSHED_CHILD on success.
  *     - UNLANG_ACTION_FAIL on failure.
  */
-unlang_action_t _unlang_function_push(unlang_result_t *p_result,
-                                     request_t *request,
-                                     unlang_function_t func, char const *func_name,
-                                     unlang_function_t repeat, char const *repeat_name,
-                                     unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
-                                     bool top_frame, void *uctx)
+unlang_action_t _unlang_function_push_with_result(unlang_result_t *p_result,
+                                                 request_t *request,
+                                                 unlang_function_with_result_t func, char const *func_name,
+                                                 unlang_function_with_result_t repeat, char const *repeat_name,
+                                                 unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
+                                                 bool top_frame, void *uctx)
 {
-       unlang_stack_t                  *stack = request->stack;
-       unlang_stack_frame_t            *frame;
-       unlang_frame_state_func_t       *state;
+       unlang_action_t ua;
+       unlang_stack_frame_t *frame;
 
-       /*
-        *      Push module's function
-        */
-       if (unlang_interpret_push(p_result, request, &function_instruction,
-                                 FRAME_CONF(RLM_MODULE_NOOP, top_frame), UNLANG_NEXT_STOP) < 0) {
-               RETURN_UNLANG_FAIL;
-       }
+       ua = unlang_function_push_common(p_result,
+                                        request,
+                                        func, func_name,
+                                        repeat, repeat_name,
+                                        signal, sigmask, signal_name,
+                                        UNLANG_FUNCTION_TYPE_WITH_RESULT, top_frame, uctx);
 
-       frame = &stack->frame[stack->depth];
+       if (unlikely(ua == UNLANG_ACTION_FAIL)) return UNLANG_ACTION_FAIL;
 
-       /*
-        *      Tell the interpreter to call unlang_function_call
-        *      again when going back up the stack.
-        */
-       if (repeat) repeatable_set(frame);
+       frame = frame_current(request);
+       frame->process = call_with_result;
 
-       /*
-        *      Initialize state
-        */
-       state = frame->state;
-       state->func = func;
-       state->func_name = func_name;
-       state->repeat = repeat;
-       state->repeat_name = repeat_name;
-       state->signal = signal;
-       state->sigmask = sigmask;
-       state->signal_name = signal_name;
-       state->uctx = uctx;
+       return ua;
+}
 
-       /*
-        *      Just skip to the repeat state directly
-        */
-       if (!func && repeat) frame->process = unlang_function_call_repeat;
+/** Push a generic function onto the unlang stack
+ *
+ * @private
+ *
+ * These can be pushed by any other type of unlang op to allow a submodule or function
+ * deeper in the C call stack to establish a new resumption point.
+ *
+ * @param[in] request          The current request.
+ * @param[in] func             to call going up the stack.
+ * @param[in] func_name                Name of the function call (for debugging).
+ * @param[in] repeat           function to call going back down the stack (may be NULL).
+ *                             This may be the same as func.
+ * @param[in] repeat_name      Name of the repeat function call (for debugging).
+ * @param[in] signal           function to call if the request is signalled.
+ * @param[in] sigmask          Signals to block.
+ * @param[in] signal_name      Name of the signal function call (for debugging).
+ * @param[in] top_frame                Return out of the unlang interpreter when popping this frame.
+ * @param[in] uctx             to pass to func(s).
+ * @return
+ *     - UNLANG_ACTION_PUSHED_CHILD on success.
+ *     - UNLANG_ACTION_FAIL on failure.
+ */
+unlang_action_t _unlang_function_push_no_result(request_t *request,
+                                               unlang_function_no_result_t func, char const *func_name,
+                                               unlang_function_no_result_t repeat, char const *repeat_name,
+                                               unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
+                                               bool top_frame, void *uctx)
+{
+       unlang_action_t ua;
 
-       return UNLANG_ACTION_PUSHED_CHILD;
+       ua = unlang_function_push_common(NULL,
+                                        request,
+                                        func, func_name,
+                                        repeat, repeat_name,
+                                        signal, sigmask, signal_name,
+                                        UNLANG_FUNCTION_TYPE_NO_RESULT, top_frame, uctx);
+
+       if (unlikely(ua == UNLANG_ACTION_FAIL)) return UNLANG_ACTION_FAIL;
+
+       /* frame->process = call_no_result - This is the default, we don't need to set it again */
+
+       return ua;
 }
 
 /** Custom frame state dumper
@@ -347,22 +471,22 @@ static void unlang_function_dump(request_t *request, unlang_stack_frame_t *frame
        unlang_frame_state_func_t       *state = talloc_get_type_abort(frame->state, unlang_frame_state_func_t);
 
        RDEBUG2("frame state");
-       if (state->func)   RDEBUG2("function       %p (%s)", state->func, state->func_name);
-       if (state->repeat) RDEBUG2("repeat         %p (%s)", state->repeat, state->repeat_name);
+       if (FUNC(state))   RDEBUG2("function       %p (%s)", FUNC(state), state->func_name);
+       if (REPEAT(state)) RDEBUG2("repeat         %p (%s)", REPEAT(state), state->repeat_name);
        if (state->signal) RDEBUG2("signal         %p (%s)", state->signal, state->signal_name);
 }
 
 void unlang_function_init(void)
 {
        unlang_register(UNLANG_TYPE_FUNCTION,
-                          &(unlang_op_t){
+                       &(unlang_op_t){
                                .name = "function",
-                               .interpret = unlang_function_call,
+                               .interpret = call_no_result,
                                .signal = unlang_function_signal,
                                .dump = unlang_function_dump,
                                .flag = UNLANG_OP_FLAG_RETURN_POINT,
-                               .frame_state_size = sizeof(unlang_frame_state_func_t),
+                               .frame_state_size = sizeof(unlang_frame_state_func_t),
                                .frame_state_type = "unlang_frame_state_func_t",
-                          });
+                       });
 
 }
index 542ee339ebeb3ab6c9905cdfd05dd3c03a6f90e9..767841b615062ab5e2821f1fd4f7d33b97f43f69 100644 (file)
@@ -37,6 +37,12 @@ extern "C" {
 #include <freeradius-devel/server/request.h>
 #include <freeradius-devel/server/signal.h>
 
+
+typedef enum {
+       UNLANG_FUNCTION_TYPE_WITH_RESULT,       //!< Function with a result.
+       UNLANG_FUNCTION_TYPE_NO_RESULT,         //!< Function without a result.
+} unlang_function_type_t;
+
 /** A generic function pushed by a module or xlat to functions deeper in the C call stack to create resumption points
  *
  * @param[in] p_result         The module return code and priority.
@@ -46,7 +52,20 @@ extern "C" {
  *                             All input (args) and output will be done using this structure.
  * @return an #unlang_action_t.
  */
-typedef unlang_action_t (*unlang_function_t)(unlang_result_t *p_result, request_t *request, void *uctx);
+typedef unlang_action_t (*unlang_function_with_result_t)(unlang_result_t *p_result, request_t *request, void *uctx);
+
+/** A generic function pushed by a module or xlat to functions deeper in the C call stack to create resumption points
+ *
+ * @note Returning UNLANG_ACTION_FAIL has an identical effect to returning UNLANG_ACTION_CALCULATE_RESULT
+ *      and will not be visible to the caller.
+ *
+ * @param[in] request          The current request.
+ * @param[in,out] uctx         Provided by whatever pushed the function.  Is opaque to the
+ *                             interpreter, but should be usable by the function.
+ *                             All input (args) and output will be done using this structure.
+ * @return an #unlang_action_t.
+ */
+typedef unlang_action_t (*unlang_function_no_result_t)(request_t *request, void *uctx);
 
 /** Function to call if the request was signalled
  *
@@ -87,11 +106,20 @@ int                _unlang_function_signal_set(request_t *request, unlang_function_signal_t si
  *      - -1 on failure.
  */
 #define                unlang_function_repeat_set(_request, _repeat) \
-               _unlang_function_repeat_set(_request, _repeat, STRINGIFY(_repeat))
-int            _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, char const *name)
+               _Generic((&(_repeat)), \
+                       unlang_function_with_result_t: _unlang_function_repeat_set(_request,\
+                                                                                  (void *)(_repeat), \
+                                                                                  STRINGIFY(_repeat), \
+                                                                                  UNLANG_FUNCTION_TYPE_WITH_RESULT), \
+                       unlang_function_no_result_t: _unlang_function_repeat_set(_request,\
+                                                                                (void *)(_repeat), \
+                                                                                STRINGIFY(_repeat), \
+                                                                                UNLANG_FUNCTION_TYPE_NO_RESULT) \
+               )
+int            _unlang_function_repeat_set(request_t *request, void *repeat, char const *name, unlang_function_type_t type)
                CC_HINT(warn_unused_result);
 
-/** Push a generic function onto the unlang stack
+/** Push a generic function onto the unlang stack that produces a result
  *
  * These can be pushed by any other type of unlang op to allow a submodule or function
  * deeper in the C call stack to establish a new resumption point.
@@ -100,12 +128,6 @@ int                _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, c
  *      doing it wrong.  Use unlang_module_yield() instead, and change the process function for the
  *      module.
  *
- * @note By default the rcodes from functions will be discarded.  This can be altered on a per-function
- *       basis by the func or repeat functions setting result_p->priority to a non-zero value.
- *      Results can also be collected by passing in a non-NULL _result_p pointer.
- *      You can also pass the result of unlang_interpret_result(request) to make the function frame
- *      transparent, and evaluate the rcodes with the priorities of the current frame.
- *
  * @param[in] _result_p                Where to write the result.
  * @param[in] _request         The current request.
  * @param[in] _func            to call going up the stack.
@@ -119,19 +141,53 @@ int               _unlang_function_repeat_set(request_t *request, unlang_function_t repeat, c
  *     - UNLANG_ACTION_PUSHED_CHILD on success.
  *     - UNLANG_ACTION_FAIL on failure.
  */
-#define                unlang_function_push(_result_p, _request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx) \
-               _unlang_function_push(_result_p, _request, \
-                                     _func, STRINGIFY(_func), \
-                                     _repeat, STRINGIFY(_repeat), \
-                                     _signal, _sigmask, STRINGIFY(_signal), \
-                                     _top_frame, _uctx)
-unlang_action_t        _unlang_function_push(unlang_result_t *p_result, request_t *request,
-                                     unlang_function_t func, char const *func_name,
-                                     unlang_function_t repeat, char const *repeat_name,
-                                     unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
-                                     bool top_frame, void *uctx)
-                                     CC_HINT(warn_unused_result);
+#define        unlang_function_push_with_result(_result_p, _request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx) \
+               _unlang_function_push_with_result(_result_p, _request, \
+                                                 _func, STRINGIFY(_func), \
+                                                 _repeat, STRINGIFY(_repeat), \
+                                                 _signal, _sigmask, STRINGIFY(_signal), \
+                                                 _top_frame, _uctx)
+
+unlang_action_t _unlang_function_push_with_result(unlang_result_t *p_result,
+                                                 request_t *request,
+                                                 unlang_function_with_result_t func, char const *func_name,
+                                                 unlang_function_with_result_t repeat, char const *repeat_name,
+                                                 unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
+                                                 bool top_frame, void *uctx) CC_HINT(warn_unused_result);
+
+/** Push a generic function onto the unlang stack
+ *
+ * These can be pushed by any other type of unlang op to allow a submodule or function
+ * deeper in the C call stack to establish a new resumption point.
+ *
+ * @note If you're pushing a function onto the stack to resume execution in a module, you're probably
+ *      doing it wrong.  Use unlang_module_yield() instead, and change the process function for the
+ *      module.
+ *
+ * @param[in] _request         The current request.
+ * @param[in] _func            to call going up the stack.
+ * @param[in] _repeat          function to call going back down the stack (may be NULL).
+ *                             This may be the same as func.
+ * @param[in] _signal          function to call if the request is signalled.
+ * @param[in] _sigmask         Signals to block.
+ * @param[in] _top_frame       Return out of the unlang interpreter when popping this frame.
+ * @param[in] _uctx            to pass to func(s).
+ * @return
+ *     - UNLANG_ACTION_PUSHED_CHILD on success.
+ *     - UNLANG_ACTION_FAIL on failure.
+ */
+#define        unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx) \
+               _unlang_function_push_no_result(_request, \
+                                               _func, STRINGIFY(_func), \
+                                               _repeat, STRINGIFY(_repeat), \
+                                               _signal, _sigmask, STRINGIFY(_signal), \
+                                                _top_frame, _uctx)
 
+unlang_action_t _unlang_function_push_no_result(request_t *request,
+                                               unlang_function_no_result_t func, char const *func_name,
+                                               unlang_function_no_result_t repeat, char const *repeat_name,
+                                               unlang_function_signal_t signal, fr_signal_t sigmask, char const *signal_name,
+                                               bool top_frame, void *uctx) CC_HINT(warn_unused_result);
 #ifdef __cplusplus
 }
 #endif
index 9a1d3795f691a6bfb3ac082f0af491c6ff60390f..92fa174341824677f89dec5b1acb9be8ac3eb699 100644 (file)
@@ -162,9 +162,10 @@ static void frame_dump(request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_op_t     *op = NULL;
 
-       op = &unlang_ops[frame->instruction->type];
-
-       instruction_dump(request, frame->instruction);
+       if (frame->instruction) {
+               op = &unlang_ops[frame->instruction->type];
+               instruction_dump(request, frame->instruction);
+       }
 
        RINDENT();
        if (frame->state) RDEBUG2("state          %s (%p)", talloc_get_name(frame->state), frame->state);
@@ -197,11 +198,13 @@ static void frame_dump(request_t *request, unlang_stack_frame_t *frame)
        RDEBUG2("yielded        %s", is_yielded(frame) ? "yes" : "no");
        RDEBUG2("unwind         %s", is_unwinding(frame) ? "yes" : "no");
 
-       RDEBUG2("control        %s%s%s",
-               is_break_point(frame) ? "b" : "-",
-               is_return_point(frame) ? "r" : "-",
-               is_continue_point(frame) ? "c" : "-"
-               );
+       if (frame->instruction) {
+               RDEBUG2("control        %s%s%s",
+                       is_break_point(frame) ? "b" : "-",
+                       is_return_point(frame) ? "r" : "-",
+                       is_continue_point(frame) ? "c" : "-"
+                       );
+       }
 
        /*
         *      Call the custom frame dump function
index 07df095ae61479fb89dfae48d339c8a6aaec75d2..71be8b3aeb6992e1a3c78ce7608db99c38610128 100644 (file)
@@ -283,9 +283,6 @@ static unlang_action_t process_reply(unlang_result_t *p_result, request_t *reque
        request_t               *parent = request->parent;
        fr_packet_t             *reply = request->reply;
 
-       /*
-        *      Bubble this rcode up to become the result of the subrequest
-        */
        p_result->priority = MOD_PRIORITY_MAX;
 
        if (RDEBUG_ENABLED2) {
@@ -595,17 +592,17 @@ unlang_action_t eap_peap_process(unlang_result_t *p_result, request_t *request,
         *      Setup a function in thie child to process the
         *      result of the subrequest.
         */
-       if (unlang_function_push(/* sets priority */ NULL,
-                                child,
-                                NULL,
-                                /*
-                                 *     Run in the child after the virtual sever executes.
-                                 *     This sets the rcode for the subrequest, which is
-                                 *     written to eap_session->submodule_result.
-                                 */
-                                process_reply,
-                                NULL, 0,
-                                UNLANG_SUB_FRAME, eap_session) != UNLANG_ACTION_PUSHED_CHILD) goto finish;
+       if (unlang_function_push_with_result(NULL,
+                                            child,
+                                            NULL,
+                                            /*
+                                             * Run in the child after the virtual sever executes.
+                                             * This sets the rcode for the subrequest, which is
+                                             * written to eap_session->submodule_result.
+                                             */
+                                            process_reply,
+                                            NULL, 0,
+                                            UNLANG_SUB_FRAME, eap_session) != UNLANG_ACTION_PUSHED_CHILD) goto finish;
 
        /*
         *      Run inner tunnel in the context of the child
index f7ccfefdf08d95c0fee223daeb3ed0c1596b76e6..1f007894a11852926bd9238458f56638f75e848f 100644 (file)
@@ -396,11 +396,12 @@ static unlang_action_t ldap_cacheable_userobj_resolve(unlang_result_t *p_result,
         */
        if (*group_ctx->dn) {
                if (unlang_function_repeat_set(request, ldap_cacheable_userobj_resolve) < 0) RETURN_UNLANG_FAIL;
-               if (unlang_function_push(/* both start and resume provide an rcode */p_result, request,
-                                        ldap_group_dn2name_start,
-                                        ldap_group_dn2name_resume,
-                                        ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
-                                        UNLANG_SUB_FRAME, group_ctx) < 0) RETURN_UNLANG_FAIL;
+               if (unlang_function_push_with_result(/* both start and resume provide an rcode */p_result, request,
+                                                    ldap_group_dn2name_start,
+                                                    ldap_group_dn2name_resume,
+                                                    ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
+                                                    UNLANG_SUB_FRAME,
+                                                    group_ctx) < 0) RETURN_UNLANG_FAIL;
                return UNLANG_ACTION_PUSHED_CHILD;
        }
 
@@ -409,11 +410,12 @@ static unlang_action_t ldap_cacheable_userobj_resolve(unlang_result_t *p_result,
         */
        if (*group_ctx->group_name) {
                if (unlang_function_repeat_set(request, ldap_cacheable_userobj_resolve) < 0) RETURN_UNLANG_FAIL;
-               if (unlang_function_push(/* both start and resume provide an rcode */p_result, request,
-                                        ldap_group_name2dn_start,
-                                        ldap_group_name2dn_resume,
-                                        ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
-                                        UNLANG_SUB_FRAME, group_ctx) < 0) RETURN_UNLANG_FAIL;
+               if (unlang_function_push_with_result(/* both start and resume provide an rcode */p_result, request,
+                                                    ldap_group_name2dn_start,
+                                                    ldap_group_name2dn_resume,
+                                                    ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
+                                                    UNLANG_SUB_FRAME,
+                                                    group_ctx) < 0) RETURN_UNLANG_FAIL;
                return UNLANG_ACTION_PUSHED_CHILD;
        }
 
@@ -544,12 +546,12 @@ unlang_action_t rlm_ldap_cacheable_userobj(unlang_result_t *p_result, request_t
         */
        if ((name_p != group_ctx->group_name) || (dn_p != group_ctx->group_dn)) {
                group_ctx->attrs[0] = inst->group.obj_name_attr;
-               if (unlang_function_push(p_result, request,
-                                        ldap_cacheable_userobj_resolve,
-                                        NULL,
-                                        ldap_group_userobj_cancel,
-                                        ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
-                                        group_ctx) < 0) {
+               if (unlang_function_push_with_result(p_result, request,
+                                                    ldap_cacheable_userobj_resolve,
+                                                    NULL,
+                                                    ldap_group_userobj_cancel,
+                                                    ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME,
+                                                    group_ctx) < 0) {
                        talloc_free(group_ctx);
                        RETURN_UNLANG_FAIL;
                }
@@ -714,13 +716,13 @@ unlang_action_t rlm_ldap_cacheable_groupobj(unlang_result_t *p_result, request_t
        group_ctx->base_dn = &autz_ctx->call_env->group_base;
        fr_value_box_list_init(&group_ctx->expanded_filter);
 
-       if (unlang_function_push(p_result,
-                                request,
-                                ldap_cacheable_groupobj_start,
-                                ldap_cacheable_groupobj_resume,
-                                ldap_group_groupobj_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME,
-                                group_ctx) < 0) {
+       if (unlang_function_push_with_result(p_result,
+                                            request,
+                                            ldap_cacheable_groupobj_start,
+                                            ldap_cacheable_groupobj_resume,
+                                            ldap_group_groupobj_cancel, ~FR_SIGNAL_CANCEL,
+                                            UNLANG_SUB_FRAME,
+                                            group_ctx) < 0) {
        error:
                talloc_free(group_ctx);
                RETURN_UNLANG_FAIL;
@@ -841,13 +843,13 @@ unlang_action_t rlm_ldap_check_groupobj_dynamic(unlang_result_t *p_result, reque
                group_ctx->base_dn = &xlat_ctx->env_data->group_base;
        }
 
-       if (unlang_function_push(p_result,
-                                request,
-                                ldap_cacheable_groupobj_start,
-                                ldap_check_groupobj_resume,
-                                ldap_group_groupobj_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME,
-                                group_ctx) < 0) {
+       if (unlang_function_push_with_result(p_result,
+                                            request,
+                                            ldap_cacheable_groupobj_start,
+                                            ldap_check_groupobj_resume,
+                                            ldap_group_groupobj_cancel, ~FR_SIGNAL_CANCEL,
+                                            UNLANG_SUB_FRAME,
+                                            group_ctx) < 0) {
        error:
                talloc_free(group_ctx);
                RETURN_UNLANG_FAIL;
@@ -861,10 +863,10 @@ unlang_action_t rlm_ldap_check_groupobj_dynamic(unlang_result_t *p_result, reque
 /** Initiate resolving a group DN to its name
  *
  */
-static unlang_action_t ldap_dn2name_start (unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t ldap_dn2name_start(unlang_result_t *p_result, request_t *request, void *uctx)
 {
        ldap_group_userobj_dyn_ctx_t    *group_ctx = talloc_get_type_abort(uctx, ldap_group_userobj_dyn_ctx_t);
-       ldap_group_xlat_ctx_t   *xlat_ctx = group_ctx->xlat_ctx;
+       ldap_group_xlat_ctx_t           *xlat_ctx = group_ctx->xlat_ctx;
        rlm_ldap_t const                *inst = xlat_ctx->inst;
 
        if (!inst->group.obj_name_attr) {
@@ -909,8 +911,7 @@ static unlang_action_t ldap_check_userobj_start(UNUSED unlang_result_t *p_result
 /** Process the results of evaluating a user object when checking group membership
  *
  */
-static unlang_action_t ldap_check_userobj_resume(UNUSED unlang_result_t *p_result,
-                                                request_t *request, void *uctx)
+static unlang_action_t ldap_check_userobj_resume(unlang_result_t *p_result, request_t *request, void *uctx)
 {
        ldap_group_userobj_dyn_ctx_t    *group_ctx = talloc_get_type_abort(uctx, ldap_group_userobj_dyn_ctx_t);
        ldap_group_xlat_ctx_t           *xlat_ctx = talloc_get_type_abort(group_ctx->xlat_ctx, ldap_group_xlat_ctx_t);
@@ -922,6 +923,17 @@ static unlang_action_t ldap_check_userobj_resume(UNUSED unlang_result_t *p_resul
        fr_value_box_t                  *group = xlat_ctx->group;
        char                            *value_name = NULL;
 
+       /*
+        *      Something we pushed failed early
+        */
+       switch (p_result->rcode) {
+       case RLM_MODULE_USER_SECTION_REJECT:
+               return UNLANG_ACTION_CALCULATE_RESULT;
+
+       default:
+               break;
+       }
+
        /*
         *      If group_ctx->values is not populated, this is the first call
         *      - extract the returned values if any.
@@ -1067,12 +1079,14 @@ static unlang_action_t ldap_check_userobj_resume(UNUSED unlang_result_t *p_resul
 
                                if (unlang_function_repeat_set(request, ldap_check_userobj_resume) < 0) RETURN_UNLANG_FAIL;
 
-                               return unlang_function_push(/* discard, ldap_check_userobj_resume looks at the query result */ NULL,
-                                                           request,
-                                                           ldap_dn2name_start,
-                                                           NULL,
-                                                           ldap_dn2name_cancel, ~FR_SIGNAL_CANCEL,
-                                                           UNLANG_SUB_FRAME, group_ctx);
+                               /* Need to push this for the custom cancellation function */
+                               return unlang_function_push_with_result(p_result,
+                                                                       request,
+                                                                       ldap_dn2name_start,
+                                                                       NULL,
+                                                                       ldap_dn2name_cancel, ~FR_SIGNAL_CANCEL,
+                                                                       UNLANG_SUB_FRAME,
+                                                                       group_ctx);
                        }
 
                        if (((talloc_array_length(group_ctx->group_name) - 1) == value->bv_len) &&
@@ -1096,12 +1110,13 @@ static unlang_action_t ldap_check_userobj_resume(UNUSED unlang_result_t *p_resul
 
                        if (unlang_function_repeat_set(request, ldap_check_userobj_resume) < 0) RETURN_UNLANG_FAIL;
 
-                       return unlang_function_push(/* discard, ldap_check_userobj_resume gets result from group_ctx */ NULL,
-                                                   request,
-                                                   ldap_dn2name_start,
-                                                   NULL,
-                                                   ldap_dn2name_cancel, ~FR_SIGNAL_CANCEL,
-                                                   UNLANG_SUB_FRAME, group_ctx);
+                       /* Need to push this for the custom cancellation function */
+                       return unlang_function_push_with_result(p_result,
+                                                               request,
+                                                               ldap_dn2name_start,
+                                                               NULL,
+                                                               ldap_dn2name_cancel, ~FR_SIGNAL_CANCEL,
+                                                               UNLANG_SUB_FRAME, group_ctx);
                }
 
                fr_assert(0);
@@ -1150,12 +1165,13 @@ unlang_action_t rlm_ldap_check_userobj_dynamic(unlang_result_t *p_result, reques
         *      can be checked.
         *      If not then a query is needed to retrieve the user object.
         */
-       if (unlang_function_push(/* ldap_check_userobj_resume provides an rcode result */p_result,
-                                request,
-                                xlat_ctx->query ? NULL : ldap_check_userobj_start,
-                                ldap_check_userobj_resume,
-                                ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME, group_ctx) < 0) {
+       if (unlang_function_push_with_result(p_result,
+                                            request,
+                                            xlat_ctx->query ? NULL : ldap_check_userobj_start,
+                                            ldap_check_userobj_resume,
+                                            ldap_group_userobj_cancel, ~FR_SIGNAL_CANCEL,
+                                            UNLANG_SUB_FRAME,
+                                            group_ctx) < 0) {
                talloc_free(group_ctx);
                RETURN_UNLANG_FAIL;
        }
index 558565540caf637b8958bdc72991e320b71be871..a0aa62a9d9ff4df8f234f01affe51e6602dff675 100644 (file)
@@ -52,7 +52,7 @@ typedef struct {
 /** Process the results of a profile lookup
  *
  */
-static unlang_action_t ldap_map_profile_resume(UNUSED unlang_result_t *p_result, request_t *request, void *uctx)
+static unlang_action_t ldap_map_profile_resume(request_t *request, void *uctx)
 {
        ldap_profile_ctx_t      *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
        fr_ldap_query_t         *query = profile_ctx->query;
@@ -228,12 +228,12 @@ unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret, int *applied,
        };
        if (ret) *ret = LDAP_RESULT_ERROR;
 
-       if (unlang_function_push(/* discard, ldap_map_profile_resume doesn't appear to return an rcode */ NULL,
-                                request,
+       if (unlang_function_push(request,
                                 NULL,
                                 ldap_map_profile_resume,
                                 ldap_map_profile_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME, profile_ctx) < 0) {
+                                UNLANG_SUB_FRAME,
+                                profile_ctx) < 0) {
                talloc_free(profile_ctx);
                return UNLANG_ACTION_FAIL;
        }
index 1d0077591dce715602cd98183cff400e646bcaeb..e16e381985d114cf4b522a483daefe5a7f706ed2 100644 (file)
@@ -942,7 +942,7 @@ static unlang_action_t ldap_group_xlat_user_find(UNUSED unlang_result_t *p_resul
        xlat_ctx->basedn = &xlat_ctx->env_data->user_base;
 
        return rlm_ldap_find_user_async(xlat_ctx,
-                                       /* discard, only used by xlats */NULL,
+                                       /* discard, this function is only used by xlats */NULL,
                                        xlat_ctx->inst, request,
                                        xlat_ctx->basedn, xlat_ctx->filter,
                                        xlat_ctx->ttrunk, xlat_ctx->attrs, &xlat_ctx->query);
@@ -962,19 +962,24 @@ static void ldap_group_xlat_cancel(UNUSED request_t *request, UNUSED fr_signal_t
 
 #define REPEAT_LDAP_MEMBEROF_XLAT_RESULTS \
        if (unlang_function_repeat_set(request, ldap_group_xlat_results) < 0) do { \
-               result.rcode = RLM_MODULE_FAIL; \
-               goto finish; \
+               RETURN_UNLANG_FAIL; \
        } while (0)
 
 /** Run the state machine for the LDAP membership xlat
  *
  * This is called after each async lookup is completed
+ *
+ * Will stop early, and set p_result to unlang_result
  */
 static unlang_action_t ldap_group_xlat_results(unlang_result_t *p_result, request_t *request, void *uctx)
 {
        ldap_group_xlat_ctx_t           *xlat_ctx = talloc_get_type_abort(uctx, ldap_group_xlat_ctx_t);
        rlm_ldap_t const                *inst = xlat_ctx->inst;
-       unlang_result_t                 result = { .rcode = RLM_MODULE_NOTFOUND };
+
+       /*
+        *      Check to see if rlm_ldap_check_groupobj_dynamic or rlm_ldap_check_userobj_dynamic failed
+        */
+       if (p_result->rcode == RLM_MODULE_FAIL) return UNLANG_ACTION_CALCULATE_RESULT;
 
        switch (xlat_ctx->status) {
        case GROUP_XLAT_FIND_USER:
@@ -983,7 +988,7 @@ static unlang_action_t ldap_group_xlat_results(unlang_result_t *p_result, reques
 
                if (inst->group.obj_membership_filter) {
                        REPEAT_LDAP_MEMBEROF_XLAT_RESULTS;
-                       if (rlm_ldap_check_groupobj_dynamic(&result, request, xlat_ctx) == UNLANG_ACTION_PUSHED_CHILD) {
+                       if (rlm_ldap_check_groupobj_dynamic(p_result, request, xlat_ctx) == UNLANG_ACTION_PUSHED_CHILD) {
                                xlat_ctx->status = GROUP_XLAT_MEMB_FILTER;
                                return UNLANG_ACTION_PUSHED_CHILD;
                        }
@@ -991,14 +996,11 @@ static unlang_action_t ldap_group_xlat_results(unlang_result_t *p_result, reques
                FALL_THROUGH;
 
        case GROUP_XLAT_MEMB_FILTER:
-               if (xlat_ctx->found) {
-                       result.rcode = RLM_MODULE_OK;
-                       goto finish;
-               }
+               if (xlat_ctx->found) RETURN_UNLANG_OK;
 
                if (inst->group.userobj_membership_attr) {
                        REPEAT_LDAP_MEMBEROF_XLAT_RESULTS;
-                       if (rlm_ldap_check_userobj_dynamic(&result, request, xlat_ctx) == UNLANG_ACTION_PUSHED_CHILD) {
+                       if (rlm_ldap_check_userobj_dynamic(p_result, request, xlat_ctx) == UNLANG_ACTION_PUSHED_CHILD) {
                                xlat_ctx->status = GROUP_XLAT_MEMB_ATTR;
                                return UNLANG_ACTION_PUSHED_CHILD;
                        }
@@ -1006,12 +1008,11 @@ static unlang_action_t ldap_group_xlat_results(unlang_result_t *p_result, reques
                FALL_THROUGH;
 
        case GROUP_XLAT_MEMB_ATTR:
-               if (xlat_ctx->found) result.rcode = RLM_MODULE_OK;
+               if (xlat_ctx->found) RETURN_UNLANG_OK;
                break;
        }
 
-finish:
-       RETURN_UNLANG_RCODE(result.rcode);
+       RETURN_UNLANG_NOTFOUND;
 }
 
 /** Process the results of evaluating LDAP group membership
@@ -1021,7 +1022,7 @@ static xlat_action_t ldap_group_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
                                            UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
 {
        ldap_group_xlat_ctx_t   *xlat_ctx = talloc_get_type_abort(xctx->rctx, ldap_group_xlat_ctx_t);
-       fr_value_box_t                  *vb;
+       fr_value_box_t          *vb;
 
        MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, attr_expr_bool_enum));
        vb->vb_bool = xlat_ctx->found;
@@ -1121,13 +1122,13 @@ static xlat_action_t ldap_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ct
 
        if (unlang_xlat_yield(request, ldap_group_xlat_resume, NULL, 0, xlat_ctx) != XLAT_ACTION_YIELD) goto error;
 
-       if (unlang_function_push(/* discard, ldap_group_xlat_resume just looks at xlat_ctx to see if things succeeded */ NULL,
-                                request,
-                                xlat_ctx->dn ? NULL : ldap_group_xlat_user_find,
-                                ldap_group_xlat_results,
-                                ldap_group_xlat_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME,
-                                xlat_ctx) < 0) goto error;
+       if (unlang_function_push_with_result(NULL,
+                                            request,
+                                            xlat_ctx->dn ? NULL : ldap_group_xlat_user_find,
+                                            ldap_group_xlat_results,
+                                            ldap_group_xlat_cancel, ~FR_SIGNAL_CANCEL,
+                                            UNLANG_SUB_FRAME,
+                                            xlat_ctx) < 0) goto error;
 
        return XLAT_ACTION_PUSH_UNLANG;
 }
index b0f7f318f14edd35c8fdf366f3c3d50ba6f85990..ff3ce6ee8b21a966aab15bcf08778d0f736f1886 100644 (file)
@@ -227,6 +227,7 @@ typedef struct {
        fr_ldap_thread_trunk_t          *ttrunk;
        fr_ldap_query_t                 *query;
        ldap_group_xlat_status_t        status;
+       unlang_result_t                 result;
        bool                            found;
 } ldap_group_xlat_ctx_t;
 
index b4f53300092e3f86d59d7a037b87c4eeba2ab131..e5c6227cfeb931b67f727c6d5f0182f5d5328322 100644 (file)
@@ -178,12 +178,12 @@ unlang_action_t rlm_ldap_find_user_async(TALLOC_CTX *ctx,
        };
 
        if (filter) user_ctx->filter = filter->vb_strvalue;
-       if (unlang_function_push(/* ldap_find_user_async_result sets an rcode based on the search result */ p_result,
-                                request,
-                                NULL,
-                                ldap_find_user_async_result,
-                                ldap_find_user_async_cancel, ~FR_SIGNAL_CANCEL,
-                                UNLANG_SUB_FRAME, user_ctx) < 0) {
+       if (unlang_function_push_with_result(/* ldap_find_user_async_result sets an rcode based on the search result */ p_result,
+                                            request,
+                                            NULL,
+                                            ldap_find_user_async_result,
+                                            ldap_find_user_async_cancel, ~FR_SIGNAL_CANCEL,
+                                            UNLANG_SUB_FRAME, user_ctx) < 0) {
                talloc_free(user_ctx);
                return UNLANG_ACTION_FAIL;
        }
index 3a69e88847b893c9067d2a5e8595427d320ba53c..37d8cec3537bcfaccf44ec97eab64815474aaeb7 100644 (file)
@@ -594,12 +594,12 @@ static xlat_action_t sql_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
 
        unlang_xlat_yield(request, sql_xlat_select_resume, NULL, 0, query_ctx);
 
-       if (unlang_function_push(/* discard, sql_xlat_select_resume just uses query_ctx->rcode */ NULL,
-                                request,
-                                inst->select,
-                                NULL,
-                                NULL, 0,
-                                UNLANG_SUB_FRAME, query_ctx) == UNLANG_ACTION_FAIL) return XLAT_ACTION_FAIL;
+       if (unlang_function_push_with_result(/* discard, sql_xlat_select_resume just uses query_ctx->rcode */ NULL,
+                                            request,
+                                            inst->select,
+                                            NULL,
+                                            NULL, 0,
+                                            UNLANG_SUB_FRAME, query_ctx) == UNLANG_ACTION_FAIL) return XLAT_ACTION_FAIL;
        return XLAT_ACTION_PUSH_UNLANG;
 }
 
@@ -628,12 +628,12 @@ static xlat_action_t sql_fetch_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t
                                           thread->trunk, arg->vb_strvalue, SQL_QUERY_SELECT));
 
        unlang_xlat_yield(request, sql_xlat_select_resume, NULL, 0, query_ctx);
-       if (unlang_function_push(/* discard, sql_xlat_select_resume just uses query_ctx->rcode */NULL,
-                                request,
-                                inst->select,
-                                NULL,
-                                NULL, 0,
-                                UNLANG_SUB_FRAME, query_ctx) != UNLANG_ACTION_PUSHED_CHILD) return XLAT_ACTION_FAIL;
+       if (unlang_function_push_with_result(/* discard, sql_xlat_select_resume just uses query_ctx->rcode */NULL,
+                                            request,
+                                            inst->select,
+                                            NULL,
+                                            NULL, 0,
+                                            UNLANG_SUB_FRAME, query_ctx) != UNLANG_ACTION_PUSHED_CHILD) return XLAT_ACTION_FAIL;
        return XLAT_ACTION_PUSH_UNLANG;
 }
 
@@ -904,13 +904,13 @@ static unlang_action_t mod_map_proc(unlang_result_t *p_result, map_ctx_t const *
                                       thread->trunk, query_head->vb_strvalue, SQL_QUERY_SELECT);
 
        if (unlang_map_yield(request, mod_map_resume, NULL, 0, query_ctx) != UNLANG_ACTION_YIELD) RETURN_UNLANG_FAIL;
-       return unlang_function_push(/* discard, mod_map_resume just uses query_ctx->rcode */ NULL,
-                                   request,
-                                   inst->select,
-                                   NULL,
-                                   NULL,
-                                   0, UNLANG_SUB_FRAME,
-                                   query_ctx);
+       return unlang_function_push_with_result(/* discard, mod_map_resume just uses query_ctx->rcode */ NULL,
+                                               request,
+                                               inst->select,
+                                               NULL,
+                                               NULL,
+                                               0, UNLANG_SUB_FRAME,
+                                               query_ctx);
 }
 
 /** xlat escape function for drivers which do not provide their own
@@ -1109,20 +1109,20 @@ static unlang_action_t sql_get_grouplist(unlang_result_t *p_result, sql_group_ct
        MEM(group_ctx->query_ctx = fr_sql_query_alloc(group_ctx, inst, request, trunk,
                                                      group_ctx->query->vb_strvalue, SQL_QUERY_SELECT));
 
-       if (unlang_function_push(/* sql_get_grouplist_resume translates the query_ctx->rocde into a module rcode */p_result,
-                                request,
+       if (unlang_function_push_with_result(/* sql_get_grouplist_resume translates the query_ctx->rocde into a module rcode */p_result,
+                                            request,
                                 NULL,
                                 sql_get_grouplist_resume,
                                 NULL,
                                 0, UNLANG_SUB_FRAME,
                                 group_ctx) < 0) return UNLANG_ACTION_FAIL;
 
-       return unlang_function_push(/* discard, sql_get_grouplist_resume translates rcodes */NULL,
-                                   request,
-                                   inst->select,
-                                   NULL,
-                                   NULL, 0,
-                                   UNLANG_SUB_FRAME, group_ctx->query_ctx);
+       return unlang_function_push_with_result(/* discard, sql_get_grouplist_resume translates rcodes */NULL,
+                                               request,
+                                               inst->select,
+                                               NULL,
+                                               NULL, 0,
+                                               UNLANG_SUB_FRAME, group_ctx->query_ctx);
 }
 
 typedef struct {
@@ -1877,13 +1877,13 @@ static unlang_action_t mod_sql_redundant_resume(unlang_result_t *p_result, modul
                                                          redundant_ctx->query_vb->vb_strvalue, SQL_QUERY_OTHER));
 
        unlang_module_yield(request, mod_sql_redundant_query_resume, NULL, 0, redundant_ctx);
-       return unlang_function_push(/* discard, mod_sql_redundant_query_resume uses query_ctx->rcode*/ NULL,
-                                   request,
-                                   inst->query,
-                                   NULL,
-                                   NULL,
-                                   0, UNLANG_SUB_FRAME,
-                                   redundant_ctx->query_ctx);
+       return unlang_function_push_with_result(/* discard, mod_sql_redundant_query_resume uses query_ctx->rcode*/ NULL,
+                                               request,
+                                               inst->query,
+                                               NULL,
+                                               NULL,
+                                               0, UNLANG_SUB_FRAME,
+                                               redundant_ctx->query_ctx);
 }
 
 /**  Generic module call for failing between a bunch of queries.
index b830779d689f977d1016a2a1200d9017ff0ab37b..f8214adc366ee82e5ca8365feb92c9a2b35268ad 100644 (file)
@@ -202,13 +202,13 @@ typedef struct {
 
        int             flags;
 
-       unlang_function_t       sql_query_resume;               //!< Callback run after an SQL trunk query is run.
-       unlang_function_t       sql_select_query_resume;        //!< Callback run after an SQL select trunk query is run.
+       unlang_function_with_result_t   sql_query_resume;               //!< Callback run after an SQL trunk query is run.
+       unlang_function_with_result_t   sql_select_query_resume;        //!< Callback run after an SQL select trunk query is run.
 
        int             (*sql_num_rows)(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config);
        int             (*sql_affected_rows)(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config);
 
-       unlang_function_t       sql_fetch_row;
+       unlang_function_with_result_t   sql_fetch_row;
        sql_rcode_t     (*sql_fields)(char const **out[], fr_sql_query_t *query_ctx, rlm_sql_config_t const *config);
        sql_rcode_t     (*sql_free_result)(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config);
 
@@ -225,27 +225,29 @@ typedef struct {
 } rlm_sql_driver_t;
 
 struct sql_inst {
-       rlm_sql_config_t        config; /* HACK */
+       rlm_sql_config_t                config; /* HACK */
 
-       fr_dict_attr_t const    *sql_user;              //!< Cached pointer to SQL-User-Name
+       fr_dict_attr_t const            *sql_user;              //!< Cached pointer to SQL-User-Name
                                                        //!< dictionary attribute.
-       exfile_t                *ef;
+       exfile_t                        *ef;
 
-       module_instance_t       *driver_submodule;      //!< Driver's submodule.
-       rlm_sql_driver_t const  *driver;                //!< Driver's exported interface.
+       module_instance_t               *driver_submodule;      //!< Driver's submodule.
+       rlm_sql_driver_t const          *driver;                //!< Driver's exported interface.
 
-       xlat_escape_legacy_t    sql_escape_func;
-       fr_value_box_escape_t   box_escape;
-       void                    *sql_escape_arg;        //!< Instance specific argument to be passed to escape function.
-       unlang_function_t       query;
-       unlang_function_t       select;
-       unlang_function_t       fetch_row;
-       fr_sql_query_t          *(*query_alloc)(TALLOC_CTX *ctx, rlm_sql_t const *inst, request_t *request, trunk_t *trunk, char const *query_str, fr_sql_query_type_t type);
-
-       char const              *name;                  //!< Module instance name.
-       fr_dict_attr_t const    *group_da;              //!< Group dictionary attribute.
-       fr_dict_attr_t const    *query_number_da;       //!< Query number attribute.
-       module_instance_t const *mi;                    //!< Module instance data for thread lookups.
+       xlat_escape_legacy_t            sql_escape_func;
+       fr_value_box_escape_t           box_escape;
+       void                            *sql_escape_arg;        //!< Instance specific argument to be passed to escape function.
+
+       unlang_function_with_result_t   query;
+       unlang_function_with_result_t   select;
+       unlang_function_with_result_t   fetch_row;
+
+       fr_sql_query_t                  *(*query_alloc)(TALLOC_CTX *ctx, rlm_sql_t const *inst, request_t *request, trunk_t *trunk, char const *query_str, fr_sql_query_type_t type);
+
+       char const                      *name;                  //!< Module instance name.
+       fr_dict_attr_t const            *group_da;              //!< Group dictionary attribute.
+       fr_dict_attr_t const            *query_number_da;       //!< Query number attribute.
+       module_instance_t const         *mi;                    //!< Module instance data for thread lookups.
 };
 
 unlang_action_t        sql_get_map_list(unlang_result_t *p_result, request_t *request, fr_sql_map_ctx_t *map_ctx, trunk_t *trunk);
index b883b80ba8264eec1524d373fbe1c0d7a1d56b1b..1366368d92eae53c8dfe895d4d73388f3dfe14be 100644 (file)
@@ -268,15 +268,15 @@ unlang_action_t rlm_sql_trunk_query(unlang_result_t *p_result, request_t *reques
                 *      state of the trunk request to reapable - so in that case don't
                 *      yield (in sql_trunk_query_start)
                 */
-               if (unlang_function_push(/* allow the caller of rlm_sql_trunk_query to get at the rcode */p_result,
-                                        request,
-                                        query_ctx->treq->state == TRUNK_REQUEST_STATE_REAPABLE ?
-                                               NULL : sql_trunk_query_start,
-                                        query_ctx->type == SQL_QUERY_SELECT ?
-                                               query_ctx->inst->driver->sql_select_query_resume :
-                                               query_ctx->inst->driver->sql_query_resume,
-                                        sql_trunk_query_cancel, ~FR_SIGNAL_CANCEL,
-                                        UNLANG_SUB_FRAME, query_ctx) < 0) RETURN_UNLANG_FAIL;
+               if (unlang_function_push_with_result(/* allow the caller of rlm_sql_trunk_query to get at the rcode */p_result,
+                                                    request,
+                                                    query_ctx->treq->state == TRUNK_REQUEST_STATE_REAPABLE ?
+                                                       NULL : sql_trunk_query_start,
+                                                    query_ctx->type == SQL_QUERY_SELECT ?
+                                                       query_ctx->inst->driver->sql_select_query_resume :
+                                                       query_ctx->inst->driver->sql_query_resume,
+                                                    sql_trunk_query_cancel, ~FR_SIGNAL_CANCEL,
+                                                    UNLANG_SUB_FRAME, query_ctx) < 0) RETURN_UNLANG_FAIL;
                p_result->rcode = RLM_MODULE_OK;
                return UNLANG_ACTION_PUSHED_CHILD;
 
@@ -350,21 +350,21 @@ unlang_action_t sql_get_map_list(unlang_result_t *p_result, request_t *request,
        MEM(map_ctx->query_ctx = fr_sql_query_alloc(map_ctx->ctx, inst, request, trunk,
                                                    map_ctx->query->vb_strvalue, SQL_QUERY_SELECT));
 
-       if (unlang_function_push(p_result,
-                                request,
-                                NULL,
-                                sql_get_map_list_resume,
-                                NULL, 0,
-                                UNLANG_SUB_FRAME,
-                                map_ctx) < 0) return UNLANG_ACTION_FAIL;
-
-       return unlang_function_push(/* discard, sql_get_map_list_resume uses query_ctx->rcode */ NULL,
-                                   request,
-                                   inst->select,
-                                   NULL,
-                                   NULL, 0,
-                                   UNLANG_SUB_FRAME,
-                                   map_ctx->query_ctx);
+       if (unlang_function_push_with_result(p_result,
+                                            request,
+                                            NULL,
+                                            sql_get_map_list_resume,
+                                            NULL, 0,
+                                            UNLANG_SUB_FRAME,
+                                           map_ctx) < 0) return UNLANG_ACTION_FAIL;
+
+       return unlang_function_push_with_result(/* discard, sql_get_map_list_resume uses query_ctx->rcode */ NULL,
+                                               request,
+                                               inst->select,
+                                               NULL,
+                                               NULL, 0,
+                                               UNLANG_SUB_FRAME,
+                                               map_ctx->query_ctx);
 }
 
 /*
index 37880e1c3d9f91699b988a25badab851941a3676..c84f8ed4aeefdd4fa57f95d56a284ad2acebe72a 100644 (file)
@@ -233,7 +233,7 @@ static int sqlippool_alloc_ctx_free(ippool_alloc_ctx_t *to_free)
        query_ctx->type = _type; \
        query_ctx->status = SQL_QUERY_PREPARED; \
        alloc_ctx->query = query; \
-       return unlang_function_push(p_result, request, sql->_function, NULL, NULL, 0, UNLANG_SUB_FRAME, query_ctx); \
+       return unlang_function_push_with_result(p_result, request, sql->_function, NULL, NULL, 0, UNLANG_SUB_FRAME, query_ctx); \
 } while (0)
 
 /** Resume function called after each IP allocation query is expanded
@@ -532,13 +532,13 @@ static unlang_action_t CC_HINT(nonnull) mod_alloc(unlang_result_t *p_result, mod
 
        if ((env->begin.type == FR_TYPE_STRING) && env->begin.vb_length) {
                alloc_ctx->query_ctx->query_str = env->begin.vb_strvalue;
-               return unlang_function_push(/* mod_alloc_resume looks at frame result */ p_result,
-                                           request,
-                                           sql->query,
-                                           NULL,
-                                           NULL, 0,
-                                           UNLANG_SUB_FRAME,
-                                           alloc_ctx->query_ctx);
+               return unlang_function_push_with_result(/* mod_alloc_resume looks at frame result */ p_result,
+                                                       request,
+                                                       sql->query,
+                                                       NULL,
+                                                       NULL, 0,
+                                                       UNLANG_SUB_FRAME,
+                                                       alloc_ctx->query_ctx);
        }
 
        return UNLANG_ACTION_PUSHED_CHILD;
@@ -595,13 +595,13 @@ static unlang_action_t mod_common_free_resume(unlang_result_t *p_result, module_
 
        common_ctx->query_ctx->query_str = common_ctx->env->update.vb_strvalue;
        query_ctx->status = SQL_QUERY_PREPARED;
-       return unlang_function_push(/* mod_common_update_resume uses frame rcode */p_result,
-                                   request,
-                                   sql->query,
-                                   NULL,
-                                   NULL, 0,
-                                   UNLANG_SUB_FRAME,
-                                   query_ctx);
+       return unlang_function_push_with_result(/* mod_common_update_resume uses frame rcode */p_result,
+                                               request,
+                                               sql->query,
+                                               NULL,
+                                               NULL, 0,
+                                               UNLANG_SUB_FRAME,
+                                               query_ctx);
 }
 
 /** Common function used by module methods which perform an optional "free" then "update"
@@ -640,13 +640,13 @@ static unlang_action_t CC_HINT(nonnull) mod_common(unlang_result_t *p_result, mo
                        talloc_free(common_ctx);
                        RETURN_UNLANG_FAIL;
                }
-               return unlang_function_push(/* mod_common_free_resume looks at frame result */ NULL,
-                                           request,
-                                           sql->query,
-                                           NULL,
-                                           NULL, 0,
-                                           UNLANG_SUB_FRAME,
-                                           common_ctx->query_ctx);
+               return unlang_function_push_with_result(/* mod_common_free_resume looks at frame result */ NULL,
+                                                       request,
+                                                       sql->query,
+                                                       NULL,
+                                                       NULL, 0,
+                                                       UNLANG_SUB_FRAME,
+                                                       common_ctx->query_ctx);
        }
 
        common_ctx->query_ctx->query_str = env->update.vb_strvalue;
@@ -655,13 +655,13 @@ static unlang_action_t CC_HINT(nonnull) mod_common(unlang_result_t *p_result, mo
                talloc_free(common_ctx);
                RETURN_UNLANG_FAIL;
        }
-       return unlang_function_push(/* mod_common_update_resume looks at frame result */ p_result,
-                                   request,
-                                   sql->query,
-                                   NULL,
-                                   NULL, 0,
-                                   UNLANG_SUB_FRAME,
-                                   common_ctx->query_ctx);
+       return unlang_function_push_with_result(/* mod_common_update_resume looks at frame result */ p_result,
+                                               request,
+                                               sql->query,
+                                               NULL,
+                                               NULL, 0,
+                                               UNLANG_SUB_FRAME,
+                                               common_ctx->query_ctx);
 }
 
 /** Call SQL module box_escape_func to escape tainted values