Hi Russ, et al.
We're interested in using linux session keyrings to hold krb5 credentials
acquired through webauth. I'd like to propose one approach.
If acceptable, I'd be happy to submit the required changes to include
documentation and config requirements.
This approach reuses the existing WebAuthCredCacheDir directive by passing it
along unchanged if it begins with "KEYRING:" to webauth_krb5_init_via_cred ->
krb5_cc_resolve.
Thanks for your time,
Ben
diff --git a/modules/webauth/krb5.c b/modules/webauth/krb5.c
index ec2bd4e..87faa17 100644
--- a/modules/webauth/krb5.c
+++ b/modules/webauth/krb5.c
@@ -106,18 +106,14 @@ krb5_validate_sad(MWA_REQ_CTXT *rc, const void *sad,
size_t sad_len)
* called when the request pool gets cleaned up
*/
static apr_status_t
-cred_cache_destroy(void *data)
+krb5_cleanup_context(void *data)
{
- char *path = (char*)data;
+ WEBAUTH_KRB5_CTXT *ctxt = (WEBAUTH_KRB5_CTXT *)data;
/*
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "mod_webauth: cleanup cred: %s", path);
+ "mod_webauth: cleanup ctxt: %p", ctxt);
*/
- if (unlink(path) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "mod_webauth: cleanup cred: unlink(%s) errno(%d)",
- path, errno);
- }
+ webauth_krb5_free(ctxt);
return APR_SUCCESS;
}
@@ -143,43 +139,45 @@ krb5_prepare_creds(MWA_REQ_CTXT *rc, apr_array_header_t
*creds)
return 0;
}
- astatus = apr_filepath_merge(&temp_cred_file,
- rc->sconf->cred_cache_dir,
- "temp.krb5.XXXXXX",
- 0,
- rc->r->pool);
-
- astatus = apr_file_mktemp(&fp, temp_cred_file,
- APR_CREATE|APR_READ|APR_WRITE|APR_EXCL,
- rc->r->pool);
- if (astatus != APR_SUCCESS) {
- mwa_log_apr_error(rc->r->server, astatus, mwa_func,
- "apr_file_mktemp", temp_cred_file, NULL);
- return 0;
- }
+ if (strncmp(rc->sconf->cred_cache_dir, "KEYRING:", 8) == 0) {
+ temp_cred_file = rc->sconf->cred_cache_dir;
+ } else {
+ astatus = apr_filepath_merge(&temp_cred_file,
+ rc->sconf->cred_cache_dir,
+ "temp.krb5.XXXXXX",
+ 0,
+ rc->r->pool);
+
+ astatus = apr_file_mktemp(&fp, temp_cred_file,
+ APR_CREATE|APR_READ|APR_WRITE|APR_EXCL,
+ rc->r->pool);
+ if (astatus != APR_SUCCESS) {
+ mwa_log_apr_error(rc->r->server, astatus, mwa_func,
+ "apr_file_mktemp", temp_cred_file, NULL);
+ return 0;
+ }
- /* we close it here, and register a pool cleanup handler */
- astatus = apr_file_close(fp);
- if (astatus != APR_SUCCESS) {
- mwa_log_apr_error(rc->r->server, astatus, mwa_func,
- "apr_file_close", temp_cred_file, NULL);
- return 0;
+ astatus = apr_file_close(fp);
+ if (astatus != APR_SUCCESS) {
+ mwa_log_apr_error(rc->r->server, astatus, mwa_func,
+ "apr_file_close", temp_cred_file, NULL);
+ return 0;
+ }
}
- apr_pool_cleanup_register(rc->r->pool, temp_cred_file,
- cred_cache_destroy,
- apr_pool_cleanup_null);
-
if (rc->sconf->debug)
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
- "mod_webauth: %s: temp_cred_file mktemp(%s)",
+ "mod_webauth: %s: krb5cc %s)",
mwa_func, temp_cred_file);
ctxt = get_webauth_krb5_ctxt(rc->r->server, mwa_func);
if (ctxt == NULL)
return 0;
- webauth_krb5_keep_cred_cache(ctxt);
+ /* register a pool cleanup handler */
+ apr_pool_cleanup_register(rc->r->pool, ctxt,
+ krb5_cleanup_context,
+ apr_pool_cleanup_null);
for (i = 0; i < (size_t) creds->nelts; i++) {
struct webauth_token_cred *cred;
@@ -207,7 +205,6 @@ krb5_prepare_creds(MWA_REQ_CTXT *rc, apr_array_header_t
*creds)
"webauth_krb5_import_cred", NULL);
}
}
- webauth_krb5_free(ctxt);
/* set environment variable */
apr_table_setn(rc->r->subprocess_env, ENV_KRB5CCNAME, temp_cred_file);
diff --git a/modules/webauth/mod_webauth.c b/modules/webauth/mod_webauth.c
index 47ac648..04e2b28 100644
--- a/modules/webauth/mod_webauth.c
+++ b/modules/webauth/mod_webauth.c
@@ -2601,7 +2601,11 @@ cfg_str(cmd_parms *cmd, void *mconf, const char *arg)
sconf->keyring_path = ap_server_root_relative(cmd->pool, arg);
break;
case E_CredCacheDir:
- sconf->cred_cache_dir = ap_server_root_relative(cmd->pool, arg);
+ if (strncmp(arg, "KEYRING:", 8) == 0) {
+ sconf->cred_cache_dir = apr_pstrdup(cmd->pool, arg);
+ } else {
+ sconf->cred_cache_dir = ap_server_root_relative(cmd->pool,
arg);
+ }
break;
case E_LoginCanceledURL:
dconf->login_canceled_url = apr_pstrdup(cmd->pool, arg);