diff options
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/mod_auth_gssapi.c | 40 | ||||
-rw-r--r-- | src/mod_auth_gssapi.h | 1 |
3 files changed, 44 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 78f31a2..7be2b7e 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,8 @@ PKG_CHECK_MODULES([OPENSSL], [openssl]) AC_SUBST([OPENSSL_CFLAGS]) AC_SUBST([OPENSSL_LIBS]) -AC_CHECK_HEADERS([gssapi/gssapi.h],,[AC_MSG_ERROR([Could not find GSSAPI headers])]) +AC_CHECK_HEADERS([gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h], + ,[AC_MSG_ERROR([Could not find GSSAPI headers])]) AC_PATH_PROG(KRB5_CONFIG, krb5-config, failed) if test x$KRB5_CONFIG = xfailed; then AC_MSG_ERROR([Could not find GSSAPI development libraries]) @@ -66,6 +67,7 @@ AC_CHECK_LIB([gssapi_krb5], [gss_accept_sec_context], [], AC_CHECK_FUNCS(gss_acquire_cred_from) AC_CHECK_FUNCS(gss_store_cred_into) AC_CHECK_FUNCS(gss_acquire_cred_with_password) +AC_CHECK_FUNCS(gss_krb5_ccache_name) AC_SUBST([GSSAPI_CFLAGS]) AC_SUBST([GSSAPI_LIBS]) diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index aed0c3b..db87c10 100644 --- a/src/mod_auth_gssapi.c +++ b/src/mod_auth_gssapi.c @@ -183,6 +183,10 @@ static int mag_auth(request_rec *req) bool is_basic = false; gss_ctx_id_t user_ctx = GSS_C_NO_CONTEXT; gss_name_t server = GSS_C_NO_NAME; +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + const char *user_ccache = NULL; + char *orig_ccache = NULL; +#endif type = ap_auth_type(req); if ((type == NULL) || (strcasecmp(type, "GSSAPI") != 0)) { @@ -284,6 +288,29 @@ static int mag_auth(request_rec *req) maj, min)); goto done; } +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + /* Set a per-thread ccache in case we are using kerberos, + * it is not elegant but avoids interference between threads */ + long long unsigned int rndname; + apr_status_t rs; + rs = apr_generate_random_bytes((unsigned char *)(&rndname), + sizeof(long long unsigned int)); + if (rs != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req, + "Failed to generate random ccache name"); + goto done; + } + user_ccache = apr_psprintf(req->pool, "MEMORY:user_%qu", rndname); + maj = gss_krb5_ccache_name(&min, user_ccache, + (const char **)&orig_ccache); + if (GSS_ERROR(maj)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req, + "In Basic Auth, %s", + mag_error(req, "gss_krb5_ccache_name() " + "failed", maj, min)); + goto done; + } +#endif maj = gss_acquire_cred_with_password(&min, client, &ba_pwd, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, @@ -479,6 +506,19 @@ done: } } } +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + if (user_ccache != NULL) { + maj = gss_krb5_ccache_name(&min, orig_ccache, NULL); + if (maj != GSS_S_COMPLETE) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req, + "Failed to restore per-thread ccache, %s", + mag_error(req, "gss_krb5_ccache_name() " + "failed", maj, min)); + } + } + free(orig_ccache); + orig_ccache = NULL; +#endif gss_delete_sec_context(&min, &user_ctx, &output); gss_release_cred(&min, &user_cred); gss_release_cred(&min, &acquired_cred); diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h index efe230d..4cf7d39 100644 --- a/src/mod_auth_gssapi.h +++ b/src/mod_auth_gssapi.h @@ -5,6 +5,7 @@ #include <time.h> #include <gssapi/gssapi.h> #include <gssapi/gssapi_ext.h> +#include <gssapi/gssapi_krb5.h> #define APR_WANT_STRFUNC #include "apr_want.h" |