[krbdev.mit.edu #6016] SAMBA support for SPNEGO
Alexandra Ellwood via RT
rt-comment at krbdev.mit.edu
Mon Jul 7 15:57:08 EDT 2008
diff -u -r Kerberos.orig/KerberosFramework/Kerberos5/Sources/lib/gssapi/spnego/spnego_mech.c Kerberos/KerberosFramework/Kerberos5/Sources/lib/gssapi/spnego/spnego_mech.c
--- Kerberos.orig/KerberosFramework/Kerberos5/Sources/lib/gssapi/spnego/spnego_mech.c 2007-08-09 13:29:15.000000000 -0700
+++ Kerberos/KerberosFramework/Kerberos5/Sources/lib/gssapi/spnego/spnego_mech.c 2008-06-19 14:54:44.000000000 -0700
@@ -151,6 +151,9 @@
get_negTokenResp(OM_uint32 *, unsigned char *, unsigned int,
OM_uint32 *, gss_OID *, gss_buffer_t *, gss_buffer_t *);
+static int
+is_kerb_mech(gss_OID oid);
+
/*
* The Mech OID for SPNEGO:
* { iso(1) org(3) dod(6) internet(1) security(5)
@@ -585,7 +588,16 @@
*minor_status = ERR_SPNEGO_NEGOTIATION_FAILED;
return GSS_S_DEFECTIVE_TOKEN;
}
- if (!g_OID_equal(supportedMech, sc->internal_mech)) {
+
+ /*
+ * If the mechanism we sent is not the mechanism returned from the server
+ * we need to handle the server's counter proposal. There is a bug in SAMBA
+ * servers that always send the old Kerberos mech OID, even though we
+ * sent the new one. So we will treat all the Kerberos mech OIDS as the same.
+ */
+
+ if (!(is_kerb_mech(supportedMech) && is_kerb_mech(sc->internal_mech)) &&
+ !g_OID_equal(supportedMech, sc->internal_mech)) {
ret = init_ctx_reselect(minor_status, sc,
acc_negState, supportedMech,
responseToken, mechListMIC,
@@ -2304,6 +2316,12 @@
gssint_der_length_size(spnego_ctx->DER_mechTypes.length) +
spnego_ctx->DER_mechTypes.length;
dataLen += mechListTokenSize;
+
+/*
+ * Whether the req_flags are set or not we should no longer send them per
+ * RFC 4178. If the old behavior is desired define SEND_REQ_FLAGS.
+ */
+#ifdef SEND_REQ_FLAGS
/*
* 4 bytes for ret_flags:
* ASN.1 token + ASN.1 Length + Padding + Flags
@@ -2311,7 +2329,7 @@
*/
if (req_flags != 0)
dataLen += 6;
-
+#endif
/*
* If a token from gss_init_sec_context exists,
* add the length of the token + the ASN.1 overhead
@@ -2399,12 +2417,13 @@
ptr += spnego_ctx->DER_mechTypes.length;
+#ifdef SEND_REQ_FLAGS
if (req_flags != 0) {
if ((ret = put_req_flags(&ptr, req_flags,
tlen - (int)(ptr-t))))
goto errout;
}
-
+#endif
if (data != NULL) {
*ptr++ = CONTEXT | 0x02;
if ((ret = gssint_put_der_length(rspTokenSize,
@@ -2851,3 +2870,26 @@
return (ret);
}
+
+/*
+ * Return non-zero if the oid is one of the kerberos mech oids,
+ * otherwise return zero.
+ *
+ * N.B. There are 3 oids that represent the kerberos mech:
+ * RFC-specified GSS_MECH_KRB5_OID,
+ * Old pre-RFC GSS_MECH_KRB5_OLD_OID,
+ * Incorrect MS GSS_MECH_KRB5_WRONG_OID
+ */
+
+static int
+is_kerb_mech(gss_OID oid)
+{
+ int answer = 0;
+ OM_uint32 minor;
+ extern const gss_OID_set_desc * const gss_mech_set_krb5_both;
+
+ (void) gss_test_oid_set_member(&minor,
+ oid, (gss_OID_set)gss_mech_set_krb5_both, &answer);
+
+ return (answer);
+}
More information about the krb5-bugs
mailing list