r19650: Allow Samba to use Heimdal's SPNEGO code. Currently this can only
authorAndrew Bartlett <abartlet@samba.org>
Fri, 10 Nov 2006 02:44:38 +0000 (02:44 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:25:25 +0000 (14:25 -0500)
negotiate krb5, but if this works, I'll add NTLM as a GSSAPI backend
by some means or other.

Andrew Bartlett
(This used to be commit 476452e143f61a3878a3646864729daaddccdf68)

source4/auth/gensec/gensec_gssapi.c
source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
source4/heimdal_build/config.mk

index 8e40973e4a12d6eb45e5be3dbd2bb42045c94178..e17eaa096fe7448637f773fae3706ec79f7d9b00 100644 (file)
@@ -190,7 +190,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
                gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE;
        }
 
-       gensec_gssapi_state->gss_oid = gss_mech_krb5;
+       gensec_gssapi_state->gss_oid = GSS_C_NULL_OID;
        
        send_to_kdc.func = smb_krb5_send_and_recv_func;
        send_to_kdc.ptr = gensec_security->event_ctx;
@@ -308,6 +308,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
 
        gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
 
+       gensec_gssapi_state->gss_oid = gss_mech_krb5;
+
        principal = gensec_get_target_principal(gensec_security);
        if (principal && lp_client_use_spnego_principal()) {
                name_token.value  = discard_const_p(uint8_t, principal);
@@ -408,7 +410,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
        OM_uint32 maj_stat, min_stat;
        OM_uint32 min_stat2;
        gss_buffer_desc input_token, output_token;
-       gss_OID gss_oid_p;
+       gss_OID gss_oid_p = NULL;
        input_token.length = in.length;
        input_token.value = in.data;
 
@@ -427,10 +429,13 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                                        0, 
                                                        gensec_gssapi_state->input_chan_bindings,
                                                        &input_token, 
-                                                       NULL, 
+                                                       &gss_oid_p,
                                                        &output_token, 
                                                        &gensec_gssapi_state->got_flags, /* ret flags */
                                                        NULL);
+                       if (gss_oid_p) {
+                               gensec_gssapi_state->gss_oid = gss_oid_p;
+                       }
                        break;
                }
                case GENSEC_SERVER:
@@ -446,7 +451,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                                          &gensec_gssapi_state->got_flags, 
                                                          NULL, 
                                                          &gensec_gssapi_state->delegated_cred_handle);
-                       gensec_gssapi_state->gss_oid = gss_oid_p;
+                       if (gss_oid_p) {
+                               gensec_gssapi_state->gss_oid = gss_oid_p;
+                       }
                        break;
                }
                default:
@@ -502,9 +509,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                        gss_release_buffer(&min_stat2, &output_token);
                        
                        return NT_STATUS_MORE_PROCESSING_REQUIRED;
-               } else if ((gensec_gssapi_state->gss_oid->length == gss_mech_krb5->length)
-                          && (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, 
-                                     gensec_gssapi_state->gss_oid->length) == 0)) {
+               } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
                        switch (min_stat) {
                        case KRB5_KDC_UNREACH:
                                DEBUG(3, ("Cannot reach a KDC we require: %s\n",
@@ -1107,8 +1112,7 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security,
        }
        if (feature & GENSEC_FEATURE_SESSION_KEY) {
                /* Only for GSSAPI/Krb5 */
-               if ((gensec_gssapi_state->gss_oid->length == gss_mech_krb5->length)
-                   && (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, gensec_gssapi_state->gss_oid->length) == 0)) {
+               if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
                        return True;
                }
        }
@@ -1354,6 +1358,35 @@ static const char *gensec_gssapi_krb5_oids[] = {
        NULL 
 };
 
+static const char *gensec_gssapi_spnego_oids[] = { 
+       GENSEC_OID_SPNEGO,
+       NULL 
+};
+
+/* As a server, this could in theory accept any GSSAPI mech */
+static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = {
+       .name           = "gssapi_spnego",
+       .sasl_name      = "GSS-SPNEGO",
+       .auth_type      = DCERPC_AUTH_TYPE_SPNEGO,
+       .oid            = gensec_gssapi_spnego_oids,
+       .client_start   = gensec_gssapi_client_start,
+       .server_start   = gensec_gssapi_server_start,
+       .magic          = gensec_gssapi_magic,
+       .update         = gensec_gssapi_update,
+       .session_key    = gensec_gssapi_session_key,
+       .session_info   = gensec_gssapi_session_info,
+       .sign_packet    = gensec_gssapi_sign_packet,
+       .check_packet   = gensec_gssapi_check_packet,
+       .seal_packet    = gensec_gssapi_seal_packet,
+       .unseal_packet  = gensec_gssapi_unseal_packet,
+       .wrap           = gensec_gssapi_wrap,
+       .unwrap         = gensec_gssapi_unwrap,
+       .have_feature   = gensec_gssapi_have_feature,
+       .enabled        = False,
+       .kerberos       = True,
+       .priority       = GENSEC_GSSAPI
+};
+
 /* As a server, this could in theory accept any GSSAPI mech */
 static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = {
        .name           = "gssapi_krb5",
@@ -1400,6 +1433,13 @@ NTSTATUS gensec_gssapi_init(void)
 {
        NTSTATUS ret;
 
+       ret = gensec_register(&gensec_gssapi_spnego_security_ops);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0,("Failed to register '%s' gensec backend!\n",
+                       gensec_gssapi_spnego_security_ops.name));
+               return ret;
+       }
+
        ret = gensec_register(&gensec_gssapi_krb5_security_ops);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("Failed to register '%s' gensec backend!\n",
index 4d634bf20feca067d09449e215d2317463a734bd..d3a21464da9c435761ea8c6ff663c2db3b5643a2 100644 (file)
@@ -72,10 +72,11 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
                /*
                 * Token must start with [APPLICATION 0] SEQUENCE.
                 * But if it doesn't assume its DCE-STYLE Kerberos!
+                * And if it's not there at all, then we are requesting a mech list from SPNEGO
                 */
-               if (len == 0)
-                       return (GSS_S_DEFECTIVE_TOKEN);
-               if  (*p != 0x60) {
+               if (len == 0) {
+                       mech_oid = *GSS_SPNEGO_MECHANISM;
+               } else if  (*p != 0x60) {
                        mech_oid = *GSS_KRB5_MECHANISM;
                } else {
                        p++;
index b6f261fe29a0907d074068823f55a290854fd1a3..3d01ba69d49f2c4d120996be3df721d89f4c87a8 100644 (file)
@@ -213,9 +213,7 @@ _gss_load_mech(void)
        }
 
        add_builtin(__gss_krb5_initialize());
-#ifndef _SAMBA_BUILD_
        add_builtin(__gss_spnego_initialize());
-#endif
 
        fp = fopen(_PATH_GSS_MECH, "r");
        if (!fp) {
index a39a2ffd05a8be7a1c5c7ff5f6e6dca24a09b05f..fd3c60b6701c35f2aa735e8ecc25e92d28f957f4 100644 (file)
@@ -122,6 +122,18 @@ OBJ_FILES = \
        ../heimdal/lib/gssapi/mech/gss_release_name.o \
        ../heimdal/lib/gssapi/mech/gss_set_cred_option.o \
        ../heimdal/lib/gssapi/mech/asn1_GSSAPIContextToken.o \
+       ../heimdal/lib/gssapi/spnego/init_sec_context.o \
+       ../heimdal/lib/gssapi/spnego/external.o \
+       ../heimdal/lib/gssapi/spnego/compat.o \
+       ../heimdal/lib/gssapi/spnego/context_stubs.o \
+       ../heimdal/lib/gssapi/spnego/cred_stubs.o \
+       ../heimdal/lib/gssapi/spnego/accept_sec_context.o \
+       ../heimdal/lib/gssapi/spnego/asn1_ContextFlags.o \
+       ../heimdal/lib/gssapi/spnego/asn1_MechType.o \
+       ../heimdal/lib/gssapi/spnego/asn1_MechTypeList.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegHints.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegTokenInit.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegTokenResp.o \
        ../heimdal/lib/gssapi/krb5/copy_ccache.o \
        ../heimdal/lib/gssapi/krb5/delete_sec_context.o \
        ../heimdal/lib/gssapi/krb5/init_sec_context.o \