Merge from the 5.3 branch (security fix). Tagged as merge_53_src, merge_53_dst, merge...
[mod_auth_kerb.git] / src / mod_auth_kerb.c
index 9aca9d8..e99f366 100644 (file)
@@ -50,7 +50,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 
-#define MODAUTHKERB_VERSION "5.2"
+#define MODAUTHKERB_VERSION "5.3"
 
 #define MECH_NEGOTIATE "Negotiate"
 #define SERVICE_NAME "HTTP"
@@ -1037,14 +1037,18 @@ end:
  ********************************************************************/
 
 static const char *
-get_gss_error(MK_POOL *p, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
+get_gss_error(request_rec *r, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
 {
    OM_uint32 maj_stat, min_stat; 
    OM_uint32 msg_ctx = 0;
    gss_buffer_desc status_string;
    char *err_msg;
 
-   err_msg = apr_pstrdup(p, prefix);
+   log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+             "GSS-API major_status:%8.8x, minor_status:%8.8x",
+             err_maj, err_min);
+
+   err_msg = apr_pstrdup(r->pool, prefix);
    do {
       maj_stat = gss_display_status (&min_stat,
                                     err_maj,
@@ -1052,11 +1056,16 @@ get_gss_error(MK_POOL *p, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
                                     GSS_C_NO_OID,
                                     &msg_ctx,
                                     &status_string);
-      if (GSS_ERROR(maj_stat))
-        break;
-      err_msg = apr_pstrcat(p, err_msg, ": ", (char*) status_string.value, NULL);
-      gss_release_buffer(&min_stat, &status_string);
-      
+      if (!GSS_ERROR(maj_stat)) {
+         err_msg = apr_pstrcat(r->pool, err_msg, ": ",
+                              (char*) status_string.value, NULL);
+        gss_release_buffer(&min_stat, &status_string);
+      }
+   } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+   msg_ctx = 0;
+   err_msg = apr_pstrcat(r->pool, err_msg, " (", NULL);
+   do {
       maj_stat = gss_display_status (&min_stat,
                                     err_min,
                                     GSS_C_MECH_CODE,
@@ -1064,11 +1073,12 @@ get_gss_error(MK_POOL *p, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
                                     &msg_ctx,
                                     &status_string);
       if (!GSS_ERROR(maj_stat)) {
-        err_msg = apr_pstrcat(p, err_msg,
-                             " (", (char*) status_string.value, ")", NULL);
+        err_msg = apr_pstrcat(r->pool, err_msg, ", ",
+                              (char *) status_string.value, NULL);
         gss_release_buffer(&min_stat, &status_string);
       }
    } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+   err_msg = apr_pstrcat(r->pool, err_msg, ")", NULL);
 
    return err_msg;
 }
@@ -1108,7 +1118,7 @@ store_gss_creds(request_rec *r, kerb_auth_config *conf, char *princ_name,
    if (GSS_ERROR(maj_stat)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
         "Cannot store delegated credential (%s)", 
-        get_gss_error(r->pool, maj_stat, min_stat, "gss_krb5_copy_ccache"));
+        get_gss_error(r, maj_stat, min_stat, "gss_krb5_copy_ccache"));
       goto end;
    }
 
@@ -1154,7 +1164,7 @@ get_gss_creds(request_rec *r,
    memset(&token, 0, sizeof(token));
    if (GSS_ERROR(major_status)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                "%s", get_gss_error(r->pool, major_status, minor_status,
+                "%s", get_gss_error(r, major_status, minor_status,
                 "gss_import_name() failed"));
       return HTTP_INTERNAL_SERVER_ERROR;
    }
@@ -1164,7 +1174,7 @@ get_gss_creds(request_rec *r,
       /* Perhaps we could just ignore this error but it's safer to give up now,
          I think */
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                "%s", get_gss_error(r->pool, major_status, minor_status,
+                "%s", get_gss_error(r, major_status, minor_status,
                                     "gss_display_name() failed"));
       return HTTP_INTERNAL_SERVER_ERROR;
    }
@@ -1179,7 +1189,7 @@ get_gss_creds(request_rec *r,
    gss_release_name(&minor_status2, &server_name);
    if (GSS_ERROR(major_status)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                "%s", get_gss_error(r->pool, major_status, minor_status,
+                "%s", get_gss_error(r, major_status, minor_status,
                                     "gss_acquire_cred() failed"));
       return HTTP_INTERNAL_SERVER_ERROR;
    }
@@ -1258,6 +1268,7 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
   gss_OID_desc spnego_oid;
   gss_ctx_id_t context = GSS_C_NO_CONTEXT;
   gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
+  OM_uint32 ret_flags = 0;
 
   *negotiate_ret_value = "\0";
 
@@ -1326,11 +1337,12 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
                                  &client_name,
                                  NULL,
                                  &output_token,
-                                 NULL,
+                                 &ret_flags,
                                  NULL,
                                  &delegated_cred);
   log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-            "Verification returned code %d", major_status);
+            "Client %s us their credential",
+            (ret_flags & GSS_C_DELEG_FLAG) ? "sent" : "didn't send");
   if (output_token.length) {
      char *token = NULL;
      size_t len;
@@ -1360,7 +1372,7 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
                  "Warning: received token seems to be NTLM, which isn't supported by the Kerberos module. Check your IE configuration.");
 
      log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-               "%s", get_gss_error(r->pool, major_status, minor_status,
+               "%s", get_gss_error(r, major_status, minor_status,
                                    "gss_accept_sec_context() failed"));
      /* Don't offer the Negotiate method again if call to GSS layer failed */
      *negotiate_ret_value = NULL;
@@ -1382,7 +1394,7 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
   gss_release_name(&minor_status, &client_name); 
   if (GSS_ERROR(major_status)) {
     log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-              "%s", get_gss_error(r->pool, major_status, minor_status,
+              "%s", get_gss_error(r, major_status, minor_status,
                                   "gss_display_name() failed"));
     ret = HTTP_INTERNAL_SERVER_ERROR;
     goto end;