Hi,
I'm proceeding with my action items, unfortunately much more slowly than
I expected. For the moment, I've put together a short description how
Apache modules can pass information, with an example handing a GSS
context.
Daniel
Modules define hooks that are invoked by the Apache core at particular
stages of the request handling. Apache provides several "pools" for
easier memory management, which can also be used as a memory space
shared across the modules. These pools are linked from within a context
structure which flows among the modules throughout the handling of a
request (the context is passed as a parameter to the hooks).
There're several types of hooks categorized according to their lifetime.
The shortest-lived one (request pool) is assigned to a request once it
comes in, and is destroyed once the request has been handled. Other
pools can live over a connection (consisting of multiple keep-alive'd
requests) or a lifetime of the Apache slaves, etc. A cleanup call is
given for each item that is placed to a pool, so it could be propely
free'd when on the pool removal.
In order to pass a value between modules processing a single request, it
is possible to store a "named" value into the pool assigning it a
well-known key and let the other modules read it later on using the same
key. The keys must be carefully crafted to avoid possible clashes.
The code snippets below demonstrate how a GSS context can be passed from
one module to another via the request pool.
mod_auth_gssapi (the provider)
------------------------------
{
char key[1024];
snprintf(key, sizeof(key), "mod_auth_gssapi:gss_ctx");
apr_pool_userdata_set(context, key, cleanup_req_ctx, r->pool);
}
another subsuqent module (consumer)
-----------------------------------
{
char key[1024];
apr_status_t ret;
gss_ctx_id_t gss_ctx = GSS_C_NO_CONTEXT;
snprintf(key, sizeof(key), "mod_auth_gssapi:gss_ctx");
ret = apr_pool_userdata_get((void**)&gss_ctx, key, r->pool);
if (ret)
goto end;
OM_uint32 min, maj;
gss_name_t name;
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
maj = gss_inquire_context(&min, gss_ctx, &name, NULL, NULL,
NULL, NULL, NULL, NULL);
if GSS_ERROR(maj)
goto end;
maj = gss_display_name(&min, name, &token, NULL);
if GSS_ERROR(maj)
goto end;
log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
"Passed GSS id %s", token.value);
gss_release_buffer(&min, &token);
end:
;
}
|