mit: make it possible to build with MIT kerberos and --picky-developer
[metze/samba/wip.git] / auth / kerberos / gssapi_pac.c
index dadae1afa2680452cac16a3e6293be609f4adfde..253976aecdf2bfeed70b0d108031a063d0695c6d 100644 (file)
@@ -54,7 +54,7 @@ const gss_OID_desc * const gss_mech_krb5_wrong        = krb5_gss_oid_array+2;
 
 gss_OID_desc gse_sesskey_inq_oid = {
        GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH,
-       (void *)GSS_KRB5_INQ_SSPI_SESSION_KEY_OID
+       discard_const(GSS_KRB5_INQ_SSPI_SESSION_KEY_OID)
 };
 
 #ifndef GSS_KRB5_SESSION_KEY_ENCTYPE_OID
@@ -64,7 +64,7 @@ gss_OID_desc gse_sesskey_inq_oid = {
 
 gss_OID_desc gse_sesskeytype_oid = {
        GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,
-       (void *)GSS_KRB5_SESSION_KEY_ENCTYPE_OID
+       discard_const(GSS_KRB5_SESSION_KEY_ENCTYPE_OID)
 };
 
 /* The Heimdal OID for getting the PAC */
@@ -80,8 +80,24 @@ NTSTATUS gssapi_obtain_pac_blob(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        OM_uint32 gss_maj, gss_min;
 #ifdef HAVE_GSS_GET_NAME_ATTRIBUTE
-       gss_buffer_desc pac_buffer;
-       gss_buffer_desc pac_display_buffer;
+/*
+ * gss_get_name_attribute() in MIT krb5 1.10.0 can return unintialized pac_display_buffer
+ * and later gss_release_buffer() will crash on attempting to release it.
+ *
+ * So always initialize the buffer descriptors.
+ *
+ * See following links for more details:
+ * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658514
+ * http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=7087
+ */
+       gss_buffer_desc pac_buffer = {
+               .value = NULL,
+               .length = 0
+       };
+       gss_buffer_desc pac_display_buffer = {
+               .value = NULL,
+               .length = 0
+       };
        gss_buffer_desc pac_name = {
                .value = discard_const("urn:mspac:"),
                .length = sizeof("urn:mspac:")-1
@@ -96,8 +112,11 @@ NTSTATUS gssapi_obtain_pac_blob(TALLOC_CTX *mem_ctx,
                &pac_buffer, &pac_display_buffer, &more);
 
        if (gss_maj != 0) {
-               DEBUG(0, ("obtaining PAC via GSSAPI gss_get_name_attribute failed: %s\n",
-                         gssapi_error_string(mem_ctx, gss_maj, gss_min, gss_mech_krb5)));
+               gss_OID oid = discard_const(gss_mech_krb5);
+               DBG_NOTICE("obtaining PAC via GSSAPI gss_get_name_attribute "
+                          "failed: %s\n", gssapi_error_string(mem_ctx,
+                                                              gss_maj, gss_min,
+                                                              oid));
                return NT_STATUS_ACCESS_DENIED;
        } else if (authenticated && complete) {
                /* The PAC blob is returned directly */
@@ -183,7 +202,11 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
                                &gse_sesskey_inq_oid, &set);
        if (gss_maj) {
                DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n",
-                         gssapi_error_string(mem_ctx, gss_maj, gss_min, gss_mech_krb5)));
+                         gssapi_error_string(mem_ctx,
+                                             gss_maj,
+                                             gss_min,
+                                             discard_const_p(struct gss_OID_desc_struct,
+                                                             gss_mech_krb5))));
                return NT_STATUS_NO_USER_SESSION_KEY;
        }
 
@@ -220,8 +243,9 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
 
        if (keytype) {
                int diflen, i;
-               const char *p;
+               const uint8_t *p;
 
+               *keytype = 0;
                if (set->count < 2) {
 
 #ifdef HAVE_GSSKRB5_GET_SUBKEY
@@ -232,10 +256,6 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
                        if (gss_maj == 0) {
                                *keytype = KRB5_KEY_TYPE(subkey);
                                krb5_free_keyblock(NULL /* should be krb5_context */, subkey);
-                       } else
-#else
-                       {
-                               *keytype = 0;
                        }
 #endif
                        gss_maj = gss_release_buffer_set(&gss_min, &set);
@@ -246,17 +266,15 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
                                  gse_sesskeytype_oid.elements,
                                  gse_sesskeytype_oid.length) != 0) {
                        /* Perhaps a non-krb5 session key */
-                       *keytype = 0;
                        gss_maj = gss_release_buffer_set(&gss_min, &set);
                        return NT_STATUS_OK;
                }
-               p = set->elements[1].value + gse_sesskeytype_oid.length;
+               p = (const uint8_t *)set->elements[1].value + gse_sesskeytype_oid.length;
                diflen = set->elements[1].length - gse_sesskeytype_oid.length;
                if (diflen <= 0) {
                        gss_maj = gss_release_buffer_set(&gss_min, &set);
                        return NT_STATUS_INVALID_PARAMETER;
                }
-               *keytype = 0;
                for (i = 0; i < diflen; i++) {
                        *keytype = (*keytype << 7) | (p[i] & 0x7f);
                        if (i + 1 != diflen && (p[i] & 0x80) == 0) {
@@ -291,9 +309,17 @@ char *gssapi_error_string(TALLOC_CTX *mem_ctx,
        disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat,
                                           GSS_C_GSS_CODE, mech,
                                           &msg_ctx, &maj_error_message);
+       if (disp_maj_stat != 0) {
+               maj_error_message.value = NULL;
+               maj_error_message.length = 0;
+       }
        disp_maj_stat = gss_display_status(&disp_min_stat, min_stat,
                                           GSS_C_MECH_CODE, mech,
                                           &msg_ctx, &min_error_message);
+       if (disp_maj_stat != 0) {
+               min_error_message.value = NULL;
+               min_error_message.length = 0;
+       }
 
        maj_error_string = talloc_strndup(mem_ctx,
                                          (char *)maj_error_message.value,