summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-11-10 02:44:38 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:25:25 -0500
commite5974a1b5f736cf61146e82a33f65540289926a1 (patch)
tree56bf8d549723440a11a0a15745520e4e62d0af72
parentbe5e79323356792d57d5633fa8f1e9f038460130 (diff)
downloadsamba-e5974a1b5f736cf61146e82a33f65540289926a1.tar.gz
samba-e5974a1b5f736cf61146e82a33f65540289926a1.tar.bz2
samba-e5974a1b5f736cf61146e82a33f65540289926a1.zip
r19650: Allow Samba to use Heimdal's SPNEGO code. Currently this can only
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)
-rw-r--r--source4/auth/gensec/gensec_gssapi.c58
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c7
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_mech_switch.c2
-rw-r--r--source4/heimdal_build/config.mk12
4 files changed, 65 insertions, 14 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 8e40973e4a..e17eaa096f 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -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",
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
index 4d634bf20f..d3a21464da 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -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++;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
index b6f261fe29..3d01ba69d4 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
@@ -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) {
diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk
index a39a2ffd05..fd3c60b670 100644
--- a/source4/heimdal_build/config.mk
+++ b/source4/heimdal_build/config.mk
@@ -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 \