Find the right server name when using basic auth
authorSimo Sorce <simo@redhat.com>
Mon, 25 May 2015 13:53:44 +0000 (15:53 +0200)
committerSimo Sorce <simo@redhat.com>
Tue, 26 May 2015 17:09:25 +0000 (13:09 -0400)
When S4U2Proxy is used in combination with Basic Auth, the gss_inquire_cred()
call will return the client name instead of the server name we need.
Detect this case and aquire a separate set of credentials in that case.

Fixes #28

src/mod_auth_gssapi.c

index edb5d0a..c1cb068 100644 (file)
@@ -206,6 +206,7 @@ static int mag_auth(request_rec *req)
     gss_name_t client = GSS_C_NO_NAME;
     gss_cred_id_t user_cred = GSS_C_NO_CREDENTIAL;
     gss_cred_id_t acquired_cred = GSS_C_NO_CREDENTIAL;
+    gss_cred_id_t server_cred = GSS_C_NO_CREDENTIAL;
     gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
     gss_cred_usage_t cred_usage = GSS_C_ACCEPT;
     uint32_t flags;
@@ -427,7 +428,33 @@ static int mag_auth(request_rec *req)
                 goto done;
             }
         }
-        maj = gss_inquire_cred(&min, acquired_cred, &server,
+        if (cred_usage == GSS_C_BOTH) {
+            /* If GSS_C_BOTH is used then inquire_cred will return the client
+             * name instead of the SPN of the server credentials. Therefore we
+             * need to acquire a different set of credential setting
+             * GSS_C_ACCEPT explicitly */
+            if (cfg->cred_store) {
+                maj = gss_acquire_cred_from(&min, GSS_C_NO_NAME,
+                                            GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
+                                            GSS_C_ACCEPT, cfg->cred_store,
+                                            &server_cred, NULL, NULL);
+            } else {
+                /* Try to acquire default creds */
+                maj = gss_acquire_cred(&min, GSS_C_NO_NAME, GSS_C_INDEFINITE,
+                                       GSS_C_NO_OID_SET, GSS_C_ACCEPT,
+                                       &server_cred, NULL, NULL);
+            }
+            if (GSS_ERROR(maj)) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s",
+                              mag_error(req, "gss_acquire_cred[_from]() "
+                                        "failed to get server creds",
+                                        maj, min));
+                goto done;
+            }
+        } else {
+            server_cred = acquired_cred;
+        }
+        maj = gss_inquire_cred(&min, server_cred, &server,
                                NULL, NULL, NULL);
         if (GSS_ERROR(maj)) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
@@ -435,6 +462,9 @@ static int mag_auth(request_rec *req)
                                           "failed", maj, min));
             goto done;
         }
+        if (server_cred != acquired_cred) {
+            gss_release_cred(&min, &server_cred);
+        }
 
         if (cfg->deleg_ccache_dir) {
             /* delegate ourselves credentials so we store them as requested */