freeradiusradius

How to pass arbitrary data between the C module callbacks in FreeRADIUS


What is the proper/recommended method to pass data between the callbacks in a C module in FreeRADIUS?

For example, I want to create a unique request_id for the request and use it for all log entries during that request. If I create this value inside mod_authorize, how do I pass it over to mod_authenticate on the same request thread, and how do I retrieve it?

static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request)
{
    // Generate uuid
    uuid_t uuid;
    uuid_generate_random(uuid);

    // Convert to a string representation
    char *request_id = talloc_array(mem_ctx, char, UUID_STR_LEN);
    uuid_unparse(uuid, request_id);

    // Do stuff and log authorize messages
    radlog(L_INFO, "request_id inside mod_authorize: %s", request_id);

    // How do I pass request_id to mod_authenticate callback
    // ?????????????

    return RLM_MODULE_OK;
}

static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
{
    char *request_id = NULL;

    // How do I retrieve the request_id value
    // ???????????????????

    // Do stuff and log authenticate messages
    radlog(L_INFO, "request_id inside mod_authenticate: %s", request_id);

    return RLM_MODULE_OK;
}

Attaching the value to the request object seems like a logical thing, but I don't see a way of doing it, other than adding a value pair to the request->reply (and I don't want to return this value to NAS).

Thank you.


Solution

  • Apparently, there is a range of "Temporary attributes, for local storage" (defined in the dictionary.freeradius.internal file) that can be used with one of the requests object's collections (request->config, request->reply->vps and request->packet->vps). You can find the start of this range by searching dictionary.freeradius.internal file in the FreeRADIUS repository for

    ATTRIBUTE   Tmp-String-0
    

    In this case I found request->packet->vps to be appropriate, and used Tmp-String-3 to add my request_id to it while inside MOD_AUTHORIZE callback:

    pair_make_request("Tmp-String-3", request_ctx->request_id, T_OP_EQ);
    

    where pair_make_request is a macro defined as

    fr_pair_make(request->packet, &request->packet->vps, _a, _b, _c)
    

    I then retrieved it, while inside MOD_AUTHENTICATE callback:

    VALUE_PAIR *vp = fr_pair_find_by_num(request->packet->vps, PW_TMP_STRING_3, 0, TAG_ANY);
    

    The numerical values of these attributes change between the versions, you must use macro definitions instead

    The macros for these attributes, such as PW_TMP_STRING_3 in the esample above, are located in the file "attributes.h" which is auto-generated during the build. Here is a quote from Arran Cudbard-Bell, that I found here:

    If you really want to know where each one is used, download, configure, build the source. Then see src/include/attributes.h for the macro versions, and grep -r through the code. That'll at least tell you the modules, and if you're familiar with C you should be able to figure out how/when they're added or checked for. – Arran Cudbard-Bell Apr 12 '15 at 20:51

    In my case, the resulting file is located at /usr/include/freeradius/attributes.h

    I must say that it took me unreasonable amount of effort to track this information down. There is no other trace, none whatsoever, of these attribute macros. Not in the code, not in the FreeRADIUS documentation, not in Google search results.