From 7cabdeb7ec84c7c0b3e9b907e19f4e240b7fc4ca Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 Mar 2005 08:24:03 +0000 Subject: r6113: Move GENSEC and the kerberos code out of libcli/auth, and into auth/gensec and auth/kerberos. This also pulls the kerberos configure code out of libads (which is otherwise dead), and into auth/kerberos/kerberos.m4 Andrew Bartlett (This used to be commit e074d63f3dcf4f84239a10879112ebaf1cfa6c4f) --- source4/auth/gensec/gensec_gssapi.c | 376 ++++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 source4/auth/gensec/gensec_gssapi.c (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c new file mode 100644 index 0000000000..c974b93952 --- /dev/null +++ b/source4/auth/gensec/gensec_gssapi.c @@ -0,0 +1,376 @@ +/* + Unix SMB/CIFS implementation. + + Kerberos backend for GENSEC + + Copyright (C) Andrew Bartlett 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/kerberos.h" +#include "auth/auth.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +struct gensec_gssapi_state { + gss_ctx_id_t gssapi_context; + struct gss_channel_bindings_struct *input_chan_bindings; + gss_name_t server_name; + gss_name_t client_name; + OM_uint32 want_flags, got_flags; + const gss_OID_desc *gss_oid; +}; +static int gensec_gssapi_destory(void *ptr) +{ + struct gensec_gssapi_state *gensec_gssapi_state = ptr; + OM_uint32 maj_stat, min_stat; + + if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { + maj_stat = gss_delete_sec_context (&min_stat, + &gensec_gssapi_state->gssapi_context, + GSS_C_NO_BUFFER); + } + + if (gensec_gssapi_state->server_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->server_name); + } + if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); + } + return 0; +} + +static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state; + + gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state); + if (!gensec_gssapi_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_security->private_data = gensec_gssapi_state; + + gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; + gensec_gssapi_state->server_name = GSS_C_NO_NAME; + gensec_gssapi_state->client_name = GSS_C_NO_NAME; + + talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); + + /* TODO: Fill in channel bindings */ + gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; + + gensec_gssapi_state->want_flags = 0; + gensec_gssapi_state->got_flags = 0; + + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + /* GSSAPI won't give us the session keys */ + return NT_STATUS_INVALID_PARAMETER; + } + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { + gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; + } + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { + gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; + } + + if (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) { + static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = + {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; + + gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; + } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { + static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = + {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; + gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_gssapi_state *gensec_gssapi_state; + + nt_status = gensec_gssapi_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_gssapi_state = gensec_security->private_data; + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state; + NTSTATUS nt_status; + gss_buffer_desc name_token; + OM_uint32 maj_stat, min_stat; + + gss_OID_desc hostbased = {10, + (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" + "\x01\x02\x01\x04")}; + + nt_status = gensec_gssapi_start(gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + gensec_gssapi_state = gensec_security->private_data; + + name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), + gensec_get_target_hostname(gensec_security)); + DEBUG(0, ("name: %s\n", (char *)name_token.value)); + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + &hostbased, + &gensec_gssapi_state->server_name); + + + if (maj_stat) { + return NT_STATUS_UNSUCCESSFUL; + } + return NT_STATUS_OK; +} + + + +/** + * Next state function for the GSSAPI GENSEC mechanism + * + * @param gensec_gssapi_state GSSAPI State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + OM_uint32 maj_stat, min_stat; + OM_uint32 min_stat2; + gss_buffer_desc input_token, output_token; + gss_OID gss_oid_p; + input_token.length = in.length; + input_token.value = in.data; + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + { + maj_stat = gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->server_name, + discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), + gensec_gssapi_state->want_flags, + 0, + gensec_gssapi_state->input_chan_bindings, + &input_token, + NULL, + &output_token, + &gensec_gssapi_state->got_flags, /* ret flags */ + NULL); + break; + } + case GENSEC_SERVER: + { + maj_stat = gss_accept_sec_context(&min_stat, + &gensec_gssapi_state->gssapi_context, + GSS_C_NO_CREDENTIAL, + &input_token, + gensec_gssapi_state->input_chan_bindings, + &gensec_gssapi_state->client_name, + &gss_oid_p, + &output_token, + &gensec_gssapi_state->got_flags, + NULL, + NULL); + gensec_gssapi_state->gss_oid = gss_oid_p; + break; + } + default: + return NT_STATUS_INVALID_PARAMETER; + + } + + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat2, &output_token); + + if (maj_stat == GSS_S_COMPLETE) { + return NT_STATUS_OK; + } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gss_buffer_desc msg1, msg2; + OM_uint32 msg_ctx = 0; + + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + DEBUG(1, ("gensec_gssapi_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); + gss_release_buffer(&min_stat2, &msg1); + gss_release_buffer(&min_stat2, &msg2); + + return nt_status; + } + +} + +static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + input_token.length = in->length; + input_token.value = in->data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + if (feature & GENSEC_FEATURE_SIGN) { + return gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG; + } + if (feature & GENSEC_FEATURE_SEAL) { + return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; + } + return False; +} + +/* 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", + .sasl_name = "GSSAPI", + .oid = GENSEC_OID_KERBEROS5, + .client_start = gensec_gssapi_client_start, + .server_start = gensec_gssapi_server_start, + .update = gensec_gssapi_update, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature, + .enabled = False + +}; + +static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { + .name = "gssapi_spnego", + .sasl_name = "GSS-SPNEGO", + .oid = GENSEC_OID_SPNEGO, + .client_start = gensec_gssapi_client_start, + .server_start = gensec_gssapi_server_start, + .update = gensec_gssapi_update, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature, + .enabled = False +}; + +NTSTATUS gensec_gssapi_init(void) +{ + NTSTATUS ret; + + ret = gensec_register(&gensec_gssapi_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gssapi_krb5_security_ops.name)); + return 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; + } + + return ret; +} -- cgit From 8b2eb02d159774168eeb9c2499447ecf13e1b915 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 May 2005 12:03:48 +0000 Subject: r6727: One more step down the long march to the 'Kerberos domain join'. This patch allows a suitably patched Heimdal GSSAPI library (detected in configure) to supply to us the session keys, and further compleats the gensec_gssapi module. This is tested for CIFS, but fails for LDAP at this point (that is what I'll work on next). We currently fill out the 'session info' from the SAM, like gensec_krb5 does, but both will need to use the PAC extraction functions in the near future. Andrew Bartlett (This used to be commit 937ee361615a487af9e0279145e75b6c27720a6b) --- source4/auth/gensec/gensec_gssapi.c | 350 +++++++++++++++++++++++++++++++++++- 1 file changed, 344 insertions(+), 6 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c974b93952..b051e9cb44 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -4,6 +4,7 @@ Kerberos backend for GENSEC Copyright (C) Andrew Bartlett 2004 + Copyright (C) Stefan Metzmacher 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,11 +24,19 @@ #include "includes.h" #include "system/kerberos.h" +#include "auth/kerberos/kerberos.h" +#include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH +static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = + {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; + +static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = + {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; + struct gensec_gssapi_state { gss_ctx_id_t gssapi_context; struct gss_channel_bindings_struct *input_chan_bindings; @@ -35,6 +44,9 @@ struct gensec_gssapi_state { gss_name_t client_name; OM_uint32 want_flags, got_flags; const gss_OID_desc *gss_oid; + + DATA_BLOB session_key; + DATA_BLOB pac; }; static int gensec_gssapi_destory(void *ptr) { @@ -79,9 +91,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->want_flags = 0; gensec_gssapi_state->got_flags = 0; + gensec_gssapi_state->session_key = data_blob(NULL, 0); + gensec_gssapi_state->pac = data_blob(NULL, 0); + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - /* GSSAPI won't give us the session keys */ +#ifndef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY + /* GSSAPI won't give us the session keys, without the right hook */ return NT_STATUS_INVALID_PARAMETER; +#endif } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; @@ -89,17 +106,17 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; } + if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { + gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; + } if (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) { - static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = - {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; - gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { - static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = - {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; } else { + DEBUG(1, ("gensec_gssapi incorrectly configured - cannot determine gss OID from %s\n", + gensec_security->ops->oid)); return NT_STATUS_INVALID_PARAMETER; } @@ -313,6 +330,198 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security) +{ + /* not const but work for DCERPC packets and arcfour */ + return 45; +} + +static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + ssize_t sig_length = 0; + + input_token.length = length; + input_token.value = data; + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length < length) { + return NT_STATUS_INTERNAL_ERROR; + } + + sig_length = 45; + + memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); + +DEBUG(0,("gensec_gssapi_seal_packet: siglen: %d inlen: %d, wrap_len: %d\n", sig->length, length, output_token.length - sig_length)); +dump_data(0,sig->data, sig->length); +dump_data(0,data, length); +dump_data(0,((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + DATA_BLOB in; + +DEBUG(0,("gensec_gssapi_unseal_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + in = data_blob_talloc(mem_ctx, NULL, sig->length + length); + + memcpy(in.data, sig->data, sig->length); + memcpy(in.data + sig->length, data, length); + + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length != length) { + return NT_STATUS_INTERNAL_ERROR; + } + + memcpy(data, output_token.value, length); + + gss_release_buffer(&min_stat, &output_token); + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) + && !conf_state) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + ssize_t sig_length = 0; + + input_token.length = length; + input_token.value = discard_const_p(uint8_t *, data); + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + 0, + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length < length) { + return NT_STATUS_INTERNAL_ERROR; + } + + sig_length = 45; + + /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/ + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); + +DEBUG(0,("gensec_gssapi_sign_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + gss_release_buffer(&min_stat, &output_token); + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + int conf_state; + gss_qop_t qop_state; + DATA_BLOB in; + +DEBUG(0,("gensec_gssapi_check_packet: siglen: %d\n", sig->length)); +dump_data(0,sig->data, sig->length); + + in = data_blob_talloc(mem_ctx, NULL, sig->length + length); + + memcpy(in.data, sig->data, sig->length); + memcpy(in.data + sig->length, data, length); + + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length != length) { + return NT_STATUS_INTERNAL_ERROR; + } + + /*memcpy(data, output_token.value, length);*/ + + gss_release_buffer(&min_stat, &output_token); + + return NT_STATUS_OK; +} + static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, uint32_t feature) { @@ -323,9 +532,125 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_SEAL) { return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; } + if (feature & GENSEC_FEATURE_SESSION_KEY) { +#ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY + if ((gensec_gssapi_state->gss_oid->length == gensec_gss_krb5_mechanism_oid_desc.length) + && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, gensec_gssapi_state->gss_oid->length) == 0)) { + return True; + } + } +#endif return False; } +static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + + if (gensec_gssapi_state->session_key.data) { + *session_key = gensec_gssapi_state->session_key; + return NT_STATUS_OK; + } + +#ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY + if ((gensec_gssapi_state->gss_oid->length == gensec_gss_krb5_mechanism_oid_desc.length) + && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, gensec_gssapi_state->gss_oid->length) == 0)) { + OM_uint32 maj_stat, min_stat; + gss_buffer_desc skey; + + maj_stat = gsskrb5_get_initiator_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &skey); + + if (maj_stat == 0) { + DEBUG(10, ("Got KRB5 session key of length %d\n", skey.length)); + gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, + skey.value, skey.length); + *session_key = gensec_gssapi_state->session_key; + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + gss_release_buffer(&min_stat, &skey); + return NT_STATUS_OK; + } + return NT_STATUS_NO_USER_SESSION_KEY; + } +#endif + + DEBUG(1, ("NO session key for this mech\n")); + return NT_STATUS_NO_USER_SESSION_KEY; +} + +static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security, + struct auth_session_info **_session_info) +{ + NTSTATUS nt_status; + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct auth_serversupplied_info *server_info = NULL; + struct auth_session_info *session_info = NULL; + char *p; + char *principal; + const char *account_name; + const char *realm; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc name_token; + + maj_stat = gss_display_name (&min_stat, + gensec_gssapi_state->client_name, + &name_token, + NULL); + if (maj_stat) { + return NT_STATUS_FOOBAR; + } + + principal = talloc_strndup(gensec_gssapi_state, name_token.value, name_token.length); + + gss_release_buffer(&min_stat, &name_token); + + NT_STATUS_HAVE_NO_MEMORY(principal); + + p = strchr(principal, '@'); + if (p) { + *p = '\0'; + p++; + realm = p; + } else { + realm = lp_realm(); + } + account_name = principal; + + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some + * kind... + * + * when heimdal can generate the PAC, we should fail if there's + * no PAC present + */ + + { + DATA_BLOB user_sess_key = data_blob(NULL, 0); + DATA_BLOB lm_sess_key = data_blob(NULL, 0); + /* TODO: should we pass the krb5 session key in here? */ + nt_status = sam_get_server_info(gensec_gssapi_state, account_name, realm, + user_sess_key, lm_sess_key, + &server_info); + talloc_free(principal); + NT_STATUS_NOT_OK_RETURN(nt_status); + } + + /* references the server_info into the session_info */ + nt_status = auth_generate_session_info(gensec_gssapi_state, server_info, &session_info); + talloc_free(server_info); + NT_STATUS_NOT_OK_RETURN(nt_status); + + nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key); + NT_STATUS_NOT_OK_RETURN(nt_status); + + *_session_info = session_info; + + return NT_STATUS_OK; +} + /* 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", @@ -334,6 +659,13 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, .update = gensec_gssapi_update, + .session_key = gensec_gssapi_session_key, + .session_info = gensec_gssapi_session_info, + .sig_size = gensec_gssapi_sig_size, + .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, @@ -348,6 +680,12 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, .update = gensec_gssapi_update, + .session_key = gensec_gssapi_session_key, + .sig_size = gensec_gssapi_sig_size, + .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, -- cgit From dc3cb69a090647a1f85c5669c9be77b21378474c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 May 2005 12:11:35 +0000 Subject: r6728: Microsoft relies very strongly on getting the OIDs it expects, so we must register the 'MS' OID for the domain join to progress. Andrew Bartlett (This used to be commit c8fbda6bfd96d5d57cd52bc15d8695547effe2e3) --- source4/auth/gensec/gensec_gssapi.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b051e9cb44..0dbcaf5906 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -110,7 +110,8 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; } - if (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) { + if ((strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) + || (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5_OLD) == 0)) { gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; @@ -673,6 +674,27 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { }; +/* As a server, this could in theory accept any GSSAPI mech */ +static const struct gensec_security_ops gensec_gssapi_ms_krb5_security_ops = { + .name = "gssapi_ms_krb5", + .oid = GENSEC_OID_KERBEROS5_OLD, + .client_start = gensec_gssapi_client_start, + .server_start = gensec_gssapi_server_start, + .update = gensec_gssapi_update, + .session_key = gensec_gssapi_session_key, + .session_info = gensec_gssapi_session_info, + .sig_size = gensec_gssapi_sig_size, + .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 + +}; + static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .name = "gssapi_spnego", .sasl_name = "GSS-SPNEGO", @@ -703,6 +725,14 @@ NTSTATUS gensec_gssapi_init(void) return ret; } + + ret = gensec_register(&gensec_gssapi_ms_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gssapi_ms_krb5_security_ops.name)); + return ret; + } + ret = gensec_register(&gensec_gssapi_spnego_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", -- cgit From 15e84f47c55b99f7b75681300f4eae381cd276d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 May 2005 13:09:30 +0000 Subject: r6730: register gensec_krb5 also with the drcrpc auth type metze (This used to be commit 491d7804f5f5bdfb43ae09b81c2cbc34fab2246d) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0dbcaf5906..f04f5abe9a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -656,6 +656,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .name = "gssapi_krb5", .sasl_name = "GSSAPI", + .auth_type = DCERPC_AUTH_TYPE_KRB5, .oid = GENSEC_OID_KERBEROS5, .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, -- cgit From 470f14ece24ebad6d32e60d84699797347ff271e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 May 2005 15:05:21 +0000 Subject: r6733: GSS_C_DCE_STYLE is not available for most builds metze (This used to be commit 3536029e8fb1da1ca689e0b7aa1f3edfb7967790) --- source4/auth/gensec/gensec_gssapi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f04f5abe9a..8ee0c18208 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -107,7 +107,12 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; } if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { +#ifndef GSS_C_DCE_STYLE + /* GSSAPI won't give us the session keys, without the right hook */ + return NT_STATUS_INVALID_PARAMETER; +#else gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; +#endif } if ((strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) -- cgit From 0aef77698e0f927b9d492edc56195217b1b59c07 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 May 2005 19:19:25 +0000 Subject: r6737: Explain these error returns a bit better. Andrew Bartlett (This used to be commit 77d054c65aeecfc0d1156d750f7b8025cb154d3a) --- source4/auth/gensec/gensec_gssapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8ee0c18208..9809a1b408 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -96,7 +96,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { #ifndef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY - /* GSSAPI won't give us the session keys, without the right hook */ + /* GSSAPI won't give us the session keys, without the + * right hooks. This is critical when requested, so + * fail outright. */ return NT_STATUS_INVALID_PARAMETER; #endif } @@ -108,7 +110,8 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { #ifndef GSS_C_DCE_STYLE - /* GSSAPI won't give us the session keys, without the right hook */ + /* GSSAPI DCE_STYLE is critical when requested, so + * fail outright */ return NT_STATUS_INVALID_PARAMETER; #else gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; -- cgit From 3da16200e9582cf676ece75c19be41842282f0a0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 May 2005 02:07:53 +0000 Subject: r6740: make gensec_gssapi.c compile again (This used to be commit 6d15e9511115cc30ee213ec91320a2dccde15b8f) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 9809a1b408..c383c6ac31 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -547,8 +547,8 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, gensec_gssapi_state->gss_oid->length) == 0)) { return True; } - } #endif + } return False; } -- cgit From 8aa0aec431632818ec7524f2644ec3fefe719b88 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 13 May 2005 06:41:42 +0000 Subject: r6767: Fix compiler warning. (This used to be commit 45a0692be10a03032f9a4e26da3de08696c03464) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c383c6ac31..b93d6ee33d 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -24,6 +24,7 @@ #include "includes.h" #include "system/kerberos.h" +#include "system/network.h" #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -- cgit From 5c6dd5e800b879efdce3bbc3a16f32c5e78b4917 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 15 May 2005 23:42:11 +0000 Subject: r6800: A big GENSEC update: Finally remove the distinction between 'krb5' and 'ms_krb5'. We now don't do kerberos stuff twice on failure. The solution to this is slightly more general than perhaps was really required (as this is a special case), but it works, and I'm happy with the cleanup I achived in the process. All modules have been updated to supply a NULL-terminated list of OIDs. In that process, SPNEGO code has been generalised, as I realised that two of the functions should have been identical in behaviour. Over in the actual modules, I have worked to remove the 'kinit' code from gensec_krb5, and placed it in kerberos/kerberos_util.c. The GSSAPI module has been extended to use this, so no longer requires a manual kinit at the command line. It will soon loose the requirement for a on-disk keytab too. The general kerberos code has also been updated to move from error_message() to our routine which gets the Heimdal error string (which may be much more useful) when available. Andrew Bartlett (This used to be commit 0101728d8e2ed9419eb31fe95047944a718ba135) --- source4/auth/gensec/gensec_gssapi.c | 261 +++++++++++++++++++++--------------- 1 file changed, 154 insertions(+), 107 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b93d6ee33d..e57739c85c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -35,9 +35,6 @@ static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; -static const gss_OID_desc gensec_gss_spnego_mechanism_oid_desc = - {6, (void *)discard_const_p(char, "\x2b\x06\x01\x05\x05\x02")}; - struct gensec_gssapi_state { gss_ctx_id_t gssapi_context; struct gss_channel_bindings_struct *input_chan_bindings; @@ -48,11 +45,49 @@ struct gensec_gssapi_state { DATA_BLOB session_key; DATA_BLOB pac; + + krb5_context krb5_context; + krb5_ccache ccache; + const char *ccache_name; + + gss_cred_id_t cred; }; + +static char *gssapi_error_string(TALLOC_CTX *mem_ctx, + OM_uint32 maj_stat, OM_uint32 min_stat) +{ + OM_uint32 disp_min_stat, disp_maj_stat; + gss_buffer_desc maj_error_message; + gss_buffer_desc min_error_message; + OM_uint32 msg_ctx = 0; + + char *ret; + + maj_error_message.value = NULL; + min_error_message.value = NULL; + + disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &maj_error_message); + disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &min_error_message); + ret = talloc_asprintf(mem_ctx, "%s: %s", (char *)maj_error_message.value, (char *)min_error_message.value); + + gss_release_buffer(&disp_min_stat, &maj_error_message); + gss_release_buffer(&disp_min_stat, &min_error_message); + + return ret; +} + + static int gensec_gssapi_destory(void *ptr) { struct gensec_gssapi_state *gensec_gssapi_state = ptr; OM_uint32 maj_stat, min_stat; + + if (gensec_gssapi_state->cred != GSS_C_NO_CREDENTIAL) { + maj_stat = gss_release_cred(&min_stat, + &gensec_gssapi_state->cred); + } if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { maj_stat = gss_delete_sec_context (&min_stat, @@ -66,13 +101,17 @@ static int gensec_gssapi_destory(void *ptr) if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); } + if (gensec_gssapi_state->krb5_context) { + krb5_free_context(gensec_gssapi_state->krb5_context); + } return 0; } static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; - + krb5_error_code ret; + gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state); if (!gensec_gssapi_state) { return NT_STATUS_NO_MEMORY; @@ -84,8 +123,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->server_name = GSS_C_NO_NAME; gensec_gssapi_state->client_name = GSS_C_NO_NAME; - talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); - /* TODO: Fill in channel bindings */ gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; @@ -95,6 +132,12 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->session_key = data_blob(NULL, 0); gensec_gssapi_state->pac = data_blob(NULL, 0); + gensec_gssapi_state->krb5_context = NULL; + + gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL; + + talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { #ifndef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY /* GSSAPI won't give us the session keys, without the @@ -119,15 +162,29 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) #endif } - if ((strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5) == 0) - || (strcmp(gensec_security->ops->oid, GENSEC_OID_KERBEROS5_OLD) == 0)) { - gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; - } else if (strcmp(gensec_security->ops->oid, GENSEC_OID_SPNEGO) == 0) { - gensec_gssapi_state->gss_oid = &gensec_gss_spnego_mechanism_oid_desc; - } else { - DEBUG(1, ("gensec_gssapi incorrectly configured - cannot determine gss OID from %s\n", - gensec_security->ops->oid)); - return NT_STATUS_INVALID_PARAMETER; + gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; + + ret = krb5_init_context(&gensec_gssapi_state->krb5_context); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", + smb_get_krb5_error_message(gensec_gssapi_state->krb5_context, + ret, gensec_gssapi_state))); + return NT_STATUS_INTERNAL_ERROR; + } + + if (lp_realm() && *lp_realm()) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm()); + if (!upper_realm) { + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm())); + return NT_STATUS_NO_MEMORY; + } + ret = krb5_set_default_realm(gensec_gssapi_state->krb5_context, upper_realm); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_set_default_realm failed (%s)\n", + smb_get_krb5_error_message(gensec_gssapi_state->krb5_context, + ret, gensec_gssapi_state))); + return NT_STATUS_INTERNAL_ERROR; + } } return NT_STATUS_OK; @@ -154,10 +211,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi NTSTATUS nt_status; gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; - - gss_OID_desc hostbased = {10, - (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12" - "\x01\x02\x01\x04")}; + const char *ccache_name; nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -168,18 +222,67 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), gensec_get_target_hostname(gensec_security)); - DEBUG(0, ("name: %s\n", (char *)name_token.value)); name_token.length = strlen(name_token.value); maj_stat = gss_import_name (&min_stat, &name_token, - &hostbased, + GSS_C_NT_HOSTBASED_SERVICE, &gensec_gssapi_state->server_name); + if (maj_stat) { + DEBUG(1, ("GSS Import name of %s failed: %s\n", + (char *)name_token.value, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + + name_token.value = cli_credentials_get_principal(gensec_get_credentials(gensec_security), gensec_gssapi_state), + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_USER_NAME, + &gensec_gssapi_state->client_name); + if (maj_stat) { + DEBUG(1, ("GSS Import name of %s failed: %s\n", + (char *)name_token.value, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + initialize_krb5_error_table(); + + nt_status = kinit_to_ccache(gensec_gssapi_state, + gensec_get_credentials(gensec_security), + gensec_gssapi_state->krb5_context, + &gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + maj_stat = gss_krb5_ccache_name(&min_stat, + gensec_gssapi_state->ccache_name, + NULL); + if (maj_stat) { + DEBUG(1, ("GSS krb5 ccache set %s failed: %s\n", + ccache_name, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + maj_stat = gss_acquire_cred(&min_stat, + gensec_gssapi_state->client_name, + GSS_C_INDEFINITE, + GSS_C_NULL_OID_SET, + GSS_C_INITIATE, + &gensec_gssapi_state->cred, + NULL, + NULL); if (maj_stat) { + DEBUG(1, ("Aquiring initiator credentails failed: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_UNSUCCESSFUL; } + return NT_STATUS_OK; } @@ -256,22 +359,10 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { return NT_STATUS_MORE_PROCESSING_REQUIRED; } else { - gss_buffer_desc msg1, msg2; - OM_uint32 msg_ctx = 0; - - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&min_stat2, maj_stat, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&min_stat2, min_stat, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - DEBUG(1, ("gensec_gssapi_update: %s : %s\n", (char *)msg1.value, (char *)msg2.value)); - gss_release_buffer(&min_stat2, &msg1); - gss_release_buffer(&min_stat2, &msg2); - + DEBUG(1, ("GSS Update failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); return nt_status; } - } static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, @@ -294,6 +385,8 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS Wrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); @@ -327,6 +420,8 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS UnWrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); @@ -369,6 +464,8 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS Wrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -381,10 +478,9 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); -DEBUG(0,("gensec_gssapi_seal_packet: siglen: %d inlen: %d, wrap_len: %d\n", sig->length, length, output_token.length - sig_length)); -dump_data(0,sig->data, sig->length); -dump_data(0,data, length); -dump_data(0,((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); + dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); + dump_data_pw("gensec_gssapi_seal_packet: clear\n", data, length); + dump_data_pw("gensec_gssapi_seal_packet: sealed\n", ((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); gss_release_buffer(&min_stat, &output_token); @@ -408,8 +504,7 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur gss_qop_t qop_state; DATA_BLOB in; -DEBUG(0,("gensec_gssapi_unseal_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); + dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); in = data_blob_talloc(mem_ctx, NULL, sig->length + length); @@ -426,6 +521,8 @@ dump_data(0,sig->data, sig->length); &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS UnWrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -467,6 +564,8 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS Wrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -479,8 +578,7 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/ *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); -DEBUG(0,("gensec_gssapi_sign_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); + dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); gss_release_buffer(&min_stat, &output_token); @@ -500,8 +598,7 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi gss_qop_t qop_state; DATA_BLOB in; -DEBUG(0,("gensec_gssapi_check_packet: siglen: %d\n", sig->length)); -dump_data(0,sig->data, sig->length); + dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); in = data_blob_talloc(mem_ctx, NULL, sig->length + length); @@ -518,6 +615,8 @@ dump_data(0,sig->data, sig->length); &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS UnWrap failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -525,8 +624,6 @@ dump_data(0,sig->data, sig->length); return NT_STATUS_INTERNAL_ERROR; } - /*memcpy(data, output_token.value, length);*/ - gss_release_buffer(&min_stat, &output_token); return NT_STATUS_OK; @@ -564,8 +661,10 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit } #ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY + /* Ensure we only call this for GSSAPI/krb5, otherwise things could get very ugly */ if ((gensec_gssapi_state->gss_oid->length == gensec_gss_krb5_mechanism_oid_desc.length) - && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, gensec_gssapi_state->gss_oid->length) == 0)) { + && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, + gensec_gssapi_state->gss_oid->length) == 0)) { OM_uint32 maj_stat, min_stat; gss_buffer_desc skey; @@ -661,33 +760,16 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_OK; } -/* 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", - .sasl_name = "GSSAPI", - .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = GENSEC_OID_KERBEROS5, - .client_start = gensec_gssapi_client_start, - .server_start = gensec_gssapi_server_start, - .update = gensec_gssapi_update, - .session_key = gensec_gssapi_session_key, - .session_info = gensec_gssapi_session_info, - .sig_size = gensec_gssapi_sig_size, - .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 - +static const char *gensec_krb5_oids[] = { + GENSEC_OID_KERBEROS5, + GENSEC_OID_KERBEROS5_OLD, + NULL }; /* As a server, this could in theory accept any GSSAPI mech */ -static const struct gensec_security_ops gensec_gssapi_ms_krb5_security_ops = { - .name = "gssapi_ms_krb5", - .oid = GENSEC_OID_KERBEROS5_OLD, +static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { + .name = "gssapi_krb5", + .oid = gensec_krb5_oids, .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, .update = gensec_gssapi_update, @@ -702,26 +784,6 @@ static const struct gensec_security_ops gensec_gssapi_ms_krb5_security_ops = { .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, .enabled = False - -}; - -static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { - .name = "gssapi_spnego", - .sasl_name = "GSS-SPNEGO", - .oid = GENSEC_OID_SPNEGO, - .client_start = gensec_gssapi_client_start, - .server_start = gensec_gssapi_server_start, - .update = gensec_gssapi_update, - .session_key = gensec_gssapi_session_key, - .sig_size = gensec_gssapi_sig_size, - .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 }; NTSTATUS gensec_gssapi_init(void) @@ -735,20 +797,5 @@ NTSTATUS gensec_gssapi_init(void) return ret; } - - ret = gensec_register(&gensec_gssapi_ms_krb5_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_gssapi_ms_krb5_security_ops.name)); - return 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; - } - return ret; } -- cgit From 1d0e2b9569be6f2e8a5495ead1f92c9855f0e7f9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 16 May 2005 01:31:22 +0000 Subject: r6803: Try to bring in the correct GSSAPI headers for the krb5 mech. This should allow us to ditch the local static storage for OIDs, as well as fix the build on non-heimdal platforms. Andrew Bartlett (This used to be commit a7e2ecfac9aaacd673e3583b62139e4f4e114429) --- source4/auth/gensec/gensec_gssapi.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e57739c85c..d186e3ed1f 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -32,9 +32,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static const gss_OID_desc gensec_gss_krb5_mechanism_oid_desc = - {9, (void *)discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; - struct gensec_gssapi_state { gss_ctx_id_t gssapi_context; struct gss_channel_bindings_struct *input_chan_bindings; @@ -162,7 +159,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) #endif } - gensec_gssapi_state->gss_oid = &gensec_gss_krb5_mechanism_oid_desc; + gensec_gssapi_state->gss_oid = gss_mech_krb5; ret = krb5_init_context(&gensec_gssapi_state->krb5_context); if (ret) { @@ -359,6 +356,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { return NT_STATUS_MORE_PROCESSING_REQUIRED; } else { + if (maj_stat == GSS_S_FAILURE + && (min_stat == KRB5KRB_AP_ERR_BADVERSION || min_stat == KRB5KRB_AP_ERR_MSG_TYPE)) { + /* garbage input, possibly from the auto-mech detection */ + return NT_STATUS_INVALID_PARAMETER; + } DEBUG(1, ("GSS Update failed: %s\n", gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); return nt_status; @@ -641,8 +643,8 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, } if (feature & GENSEC_FEATURE_SESSION_KEY) { #ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY - if ((gensec_gssapi_state->gss_oid->length == gensec_gss_krb5_mechanism_oid_desc.length) - && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, gensec_gssapi_state->gss_oid->length) == 0)) { + 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)) { return True; } #endif @@ -662,8 +664,8 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit #ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY /* Ensure we only call this for GSSAPI/krb5, otherwise things could get very ugly */ - if ((gensec_gssapi_state->gss_oid->length == gensec_gss_krb5_mechanism_oid_desc.length) - && (memcmp(gensec_gssapi_state->gss_oid->elements, gensec_gss_krb5_mechanism_oid_desc.elements, + 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)) { OM_uint32 maj_stat, min_stat; gss_buffer_desc skey; -- cgit From ab92b82d83db4e6a812d048f02fa4ffffeec8691 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 18 May 2005 14:17:53 +0000 Subject: r6882: Put in configure tests and #ifdef to keep Samba building on older Heimdal. Andrew Bartlett (This used to be commit f2e926192595c74bd9cc8a3343e0fcf27a1de38b) --- source4/auth/gensec/gensec_gssapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index d186e3ed1f..71d91a9c96 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -256,6 +256,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return nt_status; } +#ifdef HAVE_GSS_KRB5_CCACHE_NAME /* FIXME, we need an alternate function */ maj_stat = gss_krb5_ccache_name(&min_stat, gensec_gssapi_state->ccache_name, NULL); @@ -265,6 +266,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_UNSUCCESSFUL; } +#endif maj_stat = gss_acquire_cred(&min_stat, gensec_gssapi_state->client_name, -- cgit From b910a7c5e3553113aeda83865276defa59f68691 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jun 2005 11:18:07 +0000 Subject: r7218: Don't use an uninitialised variable in an error message. Andrew Bartlett (This used to be commit 1f68cf7d0eb5de18da7f9d14c729caf314740601) --- source4/auth/gensec/gensec_gssapi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 71d91a9c96..314f76038b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -208,7 +208,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi NTSTATUS nt_status; gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; - const char *ccache_name; nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -262,7 +261,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi NULL); if (maj_stat) { DEBUG(1, ("GSS krb5 ccache set %s failed: %s\n", - ccache_name, + gensec_gssapi_state->ccache_name, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_UNSUCCESSFUL; } -- cgit From d26f46f72c4149cbe404ef23a43a76d7605edc96 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Jun 2005 11:17:05 +0000 Subject: r7270: A big revamp to the way we handle kerberos errors in Samba4. We now fill in the function pointers to handle the logging, and catch all the kerberos warnings. (Currently at level 3). To avoid a memory leak, this requries a new function: krb5_freelog(), which I've added to lorikeet/heimdal. This also required a revamp to how we handle the krb5_context, so as to make it easier to handle with talloc destructors. Andrew Bartlett (This used to be commit 63272794c41231b335b73e7ccf349282f295c4d2) --- source4/auth/gensec/gensec_gssapi.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 314f76038b..c6a16cdf33 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -43,7 +43,7 @@ struct gensec_gssapi_state { DATA_BLOB session_key; DATA_BLOB pac; - krb5_context krb5_context; + struct smb_krb5_context *smb_krb5_context; krb5_ccache ccache; const char *ccache_name; @@ -98,9 +98,6 @@ static int gensec_gssapi_destory(void *ptr) if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); } - if (gensec_gssapi_state->krb5_context) { - krb5_free_context(gensec_gssapi_state->krb5_context); - } return 0; } @@ -129,8 +126,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->session_key = data_blob(NULL, 0); gensec_gssapi_state->pac = data_blob(NULL, 0); - gensec_gssapi_state->krb5_context = NULL; - gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL; talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); @@ -161,29 +156,13 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_oid = gss_mech_krb5; - ret = krb5_init_context(&gensec_gssapi_state->krb5_context); + ret = smb_krb5_init_context(gensec_gssapi_state, + &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", - smb_get_krb5_error_message(gensec_gssapi_state->krb5_context, - ret, gensec_gssapi_state))); + error_message(ret))); return NT_STATUS_INTERNAL_ERROR; } - - if (lp_realm() && *lp_realm()) { - char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm()); - if (!upper_realm) { - DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm())); - return NT_STATUS_NO_MEMORY; - } - ret = krb5_set_default_realm(gensec_gssapi_state->krb5_context, upper_realm); - if (ret) { - DEBUG(1,("gensec_krb5_start: krb5_set_default_realm failed (%s)\n", - smb_get_krb5_error_message(gensec_gssapi_state->krb5_context, - ret, gensec_gssapi_state))); - return NT_STATUS_INTERNAL_ERROR; - } - } - return NT_STATUS_OK; } @@ -216,7 +195,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; - name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), + name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", + gensec_get_target_service(gensec_security), gensec_get_target_hostname(gensec_security)); name_token.length = strlen(name_token.value); @@ -231,7 +211,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_UNSUCCESSFUL; } - name_token.value = cli_credentials_get_principal(gensec_get_credentials(gensec_security), gensec_gssapi_state), + name_token.value = cli_credentials_get_principal(gensec_get_credentials(gensec_security), + gensec_gssapi_state), name_token.length = strlen(name_token.value); maj_stat = gss_import_name (&min_stat, @@ -249,7 +230,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi nt_status = kinit_to_ccache(gensec_gssapi_state, gensec_get_credentials(gensec_security), - gensec_gssapi_state->krb5_context, + gensec_gssapi_state->smb_krb5_context, &gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; -- cgit From 8a68f96f8cea2c53c8babf2ec826dfc6ef1cc199 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Jun 2005 02:12:26 +0000 Subject: r7827: Add in-memory keytab to Samba4, using the new MEMORY_WILDCARD keytab support in Heimdal. This removes the 'ext_keytab' step from my Samba4/WinXP client howto. In doing this work, I realised that the replay cache in Heimdal is currently a no-op, so I have removed the calls to it, and therefore the mutex calls from passdb/secrets.c. This patch also includes a replacement 'magic' mechanism detection, that does not issue extra error messages from deep inside the GSSAPI code. Andrew Bartlett (This used to be commit c19d5706f4fa760415b727b970bc99e7f1abd064) --- source4/auth/gensec/gensec_gssapi.c | 59 +++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c6a16cdf33..1542441e27 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -46,6 +46,7 @@ struct gensec_gssapi_state { struct smb_krb5_context *smb_krb5_context; krb5_ccache ccache; const char *ccache_name; + krb5_keytab keytab; gss_cred_id_t cred; }; @@ -170,6 +171,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi { NTSTATUS nt_status; struct gensec_gssapi_state *gensec_gssapi_state; + struct cli_credentials *machine_account; nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -178,7 +180,30 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; + machine_account = cli_credentials_init(gensec_gssapi_state); + cli_credentials_set_conf(machine_account); + nt_status = cli_credentials_set_machine_account(machine_account); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(3, ("Could not obtain machine account credentials from the local database\n")); + talloc_free(machine_account); + return nt_status; + } else { + nt_status = create_memory_keytab(gensec_gssapi_state, + machine_account, + gensec_gssapi_state->smb_krb5_context, + &gensec_gssapi_state->keytab); + talloc_free(machine_account); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(3, ("Could not create memory keytab!\n")); + talloc_free(machine_account); + return nt_status; + } + } + + gsskrb5_register_acceptor_keytab(gensec_gssapi_state->keytab); return NT_STATUS_OK; + } static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) @@ -236,7 +261,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return nt_status; } -#ifdef HAVE_GSS_KRB5_CCACHE_NAME /* FIXME, we need an alternate function */ maj_stat = gss_krb5_ccache_name(&min_stat, gensec_gssapi_state->ccache_name, NULL); @@ -246,7 +270,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_UNSUCCESSFUL; } -#endif maj_stat = gss_acquire_cred(&min_stat, gensec_gssapi_state->client_name, @@ -266,6 +289,25 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi } +/** + * Check if the packet is one for this mechansim + * + * @param gensec_security GENSEC state + * @param in The request, as a DATA_BLOB + * @return Error, INVALID_PARAMETER if it's not a packet for us + * or NT_STATUS_OK if the packet is ok. + */ + +static NTSTATUS gensec_gssapi_magic(struct gensec_security *gensec_security, + const DATA_BLOB *in) +{ + if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) { + return NT_STATUS_OK; + } else { + return NT_STATUS_INVALID_PARAMETER; + } +} + /** * Next state function for the GSSAPI GENSEC mechanism @@ -294,8 +336,18 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, switch (gensec_security->gensec_role) { case GENSEC_CLIENT: { + maj_stat = gss_krb5_ccache_name(&min_stat, + gensec_gssapi_state->ccache_name, + NULL); + if (maj_stat) { + DEBUG(1, ("GSS krb5 ccache set %s failed: %s\n", + gensec_gssapi_state->ccache_name, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, + gensec_gssapi_state->cred, &gensec_gssapi_state->gssapi_context, gensec_gssapi_state->server_name, discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), @@ -756,6 +808,7 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .oid = gensec_krb5_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, -- cgit From 4432cc73aee188b1aa50b6e1618acd59ebfebd9c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 Jun 2005 01:50:04 +0000 Subject: r7843: Use the new Heimdal gsskrb_acquire_creds API. This has the right lifetime constraints, and works with the in-memory keytab. Move initialize_krb5_error_table() into our kerberos startup code, rather than in the GSSAPI code explitly. (Hmm, we probably don't need this at all..) Andrew Bartlett (This used to be commit bedf92da5c81066405c87c9e588842d3ca5ba945) --- source4/auth/gensec/gensec_gssapi.c | 56 +++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 1542441e27..533448e06f 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -170,6 +170,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security) { NTSTATUS nt_status; + OM_uint32 maj_stat, min_stat; struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *machine_account; @@ -201,7 +202,21 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } } - gsskrb5_register_acceptor_keytab(gensec_gssapi_state->keytab); + maj_stat = gsskrb5_acquire_cred(&min_stat, + gensec_gssapi_state->keytab, NULL, + NULL, + GSS_C_INDEFINITE, + GSS_C_NULL_OID_SET, + GSS_C_ACCEPT, + &gensec_gssapi_state->cred, + NULL, + NULL); + if (maj_stat) { + DEBUG(1, ("Aquiring acceptor credentails failed: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + return NT_STATUS_OK; } @@ -251,8 +266,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_UNSUCCESSFUL; } - initialize_krb5_error_table(); - nt_status = kinit_to_ccache(gensec_gssapi_state, gensec_get_credentials(gensec_security), gensec_gssapi_state->smb_krb5_context, @@ -261,24 +274,15 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return nt_status; } - maj_stat = gss_krb5_ccache_name(&min_stat, - gensec_gssapi_state->ccache_name, + maj_stat = gsskrb5_acquire_cred(&min_stat, + NULL, gensec_gssapi_state->ccache, + gensec_gssapi_state->client_name, + GSS_C_INDEFINITE, + GSS_C_NULL_OID_SET, + GSS_C_INITIATE, + &gensec_gssapi_state->cred, + NULL, NULL); - if (maj_stat) { - DEBUG(1, ("GSS krb5 ccache set %s failed: %s\n", - gensec_gssapi_state->ccache_name, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; - } - - maj_stat = gss_acquire_cred(&min_stat, - gensec_gssapi_state->client_name, - GSS_C_INDEFINITE, - GSS_C_NULL_OID_SET, - GSS_C_INITIATE, - &gensec_gssapi_state->cred, - NULL, - NULL); if (maj_stat) { DEBUG(1, ("Aquiring initiator credentails failed: %s\n", gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); @@ -336,16 +340,6 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, switch (gensec_security->gensec_role) { case GENSEC_CLIENT: { - maj_stat = gss_krb5_ccache_name(&min_stat, - gensec_gssapi_state->ccache_name, - NULL); - if (maj_stat) { - DEBUG(1, ("GSS krb5 ccache set %s failed: %s\n", - gensec_gssapi_state->ccache_name, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; - } - maj_stat = gss_init_sec_context(&min_stat, gensec_gssapi_state->cred, &gensec_gssapi_state->gssapi_context, @@ -365,7 +359,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, { maj_stat = gss_accept_sec_context(&min_stat, &gensec_gssapi_state->gssapi_context, - GSS_C_NO_CREDENTIAL, + gensec_gssapi_state->cred, &input_token, gensec_gssapi_state->input_chan_bindings, &gensec_gssapi_state->client_name, -- cgit From f9861c9c5aee332545a9ea51683da28a87bdb10c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jun 2005 00:55:44 +0000 Subject: r7968: Pull the PAC from within GSSAPI, rather than only when using our own 'mock GSSAPI'. Many thanks to Luke Howard for the work he has done on Heimdal for XAD, to provide the right API hooks in GSSAPI. Next step is to verify the signatures, and to build the PAC for the KDC end. Andrew Bartlett (This used to be commit 2e82743c98e563e97c5a215d09efa0121854d0f7) --- source4/auth/gensec/gensec_gssapi.c | 80 ++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 19 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 533448e06f..a95805f9fa 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -3,8 +3,8 @@ Kerberos backend for GENSEC - Copyright (C) Andrew Bartlett 2004 - Copyright (C) Stefan Metzmacher 2005 + Copyright (C) Andrew Bartlett 2004-2005 + Copyright (C) Stefan Metzmacher 2004-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -224,6 +224,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; + struct cli_credentials *creds = gensec_get_credentials(gensec_security); NTSTATUS nt_status; gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; @@ -251,8 +252,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_UNSUCCESSFUL; } - name_token.value = cli_credentials_get_principal(gensec_get_credentials(gensec_security), - gensec_gssapi_state), + name_token.value = cli_credentials_get_principal(creds, + gensec_gssapi_state); name_token.length = strlen(name_token.value); maj_stat = gss_import_name (&min_stat, @@ -267,7 +268,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi } nt_status = kinit_to_ccache(gensec_gssapi_state, - gensec_get_credentials(gensec_security), + creds, gensec_gssapi_state->smb_krb5_context, &gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name); if (!NT_STATUS_IS_OK(nt_status)) { @@ -724,16 +725,22 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi struct auth_session_info **_session_info) { NTSTATUS nt_status; + TALLOC_CTX *mem_ctx; struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; + struct PAC_LOGON_INFO *logon_info; char *p; char *principal; const char *account_name; const char *realm; OM_uint32 maj_stat, min_stat; gss_buffer_desc name_token; + gss_buffer_desc pac; + mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); + NT_STATUS_HAVE_NO_MEMORY(mem_ctx); + maj_stat = gss_display_name (&min_stat, gensec_gssapi_state->client_name, &name_token, @@ -742,11 +749,14 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_FOOBAR; } - principal = talloc_strndup(gensec_gssapi_state, name_token.value, name_token.length); + principal = talloc_strndup(mem_ctx, name_token.value, name_token.length); gss_release_buffer(&min_stat, &name_token); - NT_STATUS_HAVE_NO_MEMORY(principal); + if (!principal) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } p = strchr(principal, '@'); if (p) { @@ -757,24 +767,56 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi realm = lp_realm(); } account_name = principal; + + maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + 1, + &pac); + + if (maj_stat == 0) { + DATA_BLOB pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); + pac_blob = unwrap_pac(mem_ctx, &pac_blob); + gss_release_buffer(&min_stat, &pac); + + /* decode and verify the pac */ + nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob, + gensec_gssapi_state->smb_krb5_context); + + if (NT_STATUS_IS_OK(nt_status)) { + union netr_Validation validation; + validation.sam3 = &logon_info->info3; + nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, + account_name, + 3, &validation, + &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + } else { + maj_stat = 1; + } + } + + if (maj_stat) { + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some + * kind... + * + * when heimdal can generate the PAC, we should fail if there's + * no PAC present + */ - /* IF we have the PAC - otherwise we need to get this - * data from elsewere - local ldb, or (TODO) lookup of some - * kind... - * - * when heimdal can generate the PAC, we should fail if there's - * no PAC present - */ - - { DATA_BLOB user_sess_key = data_blob(NULL, 0); DATA_BLOB lm_sess_key = data_blob(NULL, 0); /* TODO: should we pass the krb5 session key in here? */ - nt_status = sam_get_server_info(gensec_gssapi_state, account_name, realm, + nt_status = sam_get_server_info(mem_ctx, account_name, realm, user_sess_key, lm_sess_key, &server_info); - talloc_free(principal); - NT_STATUS_NOT_OK_RETURN(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } } /* references the server_info into the session_info */ -- cgit From 99777452f0d191461bf7b92397bb44378cdb4cfb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jun 2005 08:27:50 +0000 Subject: r7978: A start again on PAC verification. I have noticed that the kerberos keys appear at the end of the PAC, which I feel is deliberate (it makes this much easier). I still can't make it work, but I'm sure we are closer. Andrew Bartlett (This used to be commit 6f0e1c80ae7b1e31e7a3fbff84f07442ee5a31cf) --- source4/auth/gensec/gensec_gssapi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a95805f9fa..2b7c4ca2cc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -737,6 +737,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi OM_uint32 maj_stat, min_stat; gss_buffer_desc name_token; gss_buffer_desc pac; + krb5_keyblock *keyblock; mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); @@ -768,9 +769,13 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } account_name = principal; + maj_stat = gss_krb5_copy_service_keyblock(&min_stat, + gensec_gssapi_state->gssapi_context, + &keyblock); + maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, gensec_gssapi_state->gssapi_context, - 1, + KRB5_AUTHDATA_IF_RELEVANT, &pac); if (maj_stat == 0) { @@ -780,7 +785,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* decode and verify the pac */ nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob, - gensec_gssapi_state->smb_krb5_context); + gensec_gssapi_state->smb_krb5_context, + keyblock); if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; -- cgit From c0a78453a77fb0aa42d676635778a75204b6869c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 9 Jul 2005 01:58:38 +0000 Subject: r8250: More PAC work. We now sucessfully verify the KDC signature from my DC (I have included the krbtgt key from my test network). It turns out the krbtgt signature is over the 16 (or whatever, enc-type dependent) bytes of the signature, not the entire structure. Also do not even try to use Kerberos or GSSAPI on an IP address, it will only fail. Andrew Bartlett (This used to be commit 3b9558e82fdebb58f240d43f6a594d676eb04daf) --- source4/auth/gensec/gensec_gssapi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 2b7c4ca2cc..e6049edc58 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -228,6 +228,16 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi NTSTATUS nt_status; gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; + const char *hostname = gensec_get_target_hostname(gensec_security); + + if (!hostname) { + DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (is_ipaddress(hostname)) { + DEBUG(2, ("Cannot do GSSAPI to a IP address")); + return NT_STATUS_INVALID_PARAMETER; + } nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -238,7 +248,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), - gensec_get_target_hostname(gensec_security)); + hostname); name_token.length = strlen(name_token.value); maj_stat = gss_import_name (&min_stat, @@ -786,7 +796,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* decode and verify the pac */ nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context, - keyblock); + NULL, keyblock); if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; -- cgit From e835621799647ee70630b389fb53d15b15d68355 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Jul 2005 09:20:52 +0000 Subject: r8520: fixed a pile of warnings from the build farm gcc -Wall output on S390. This is an attempt to avoid the panic we're seeing in the automatic builds. The main fixes are: - assumptions that sizeof(size_t) == sizeof(int), mostly in printf formats - use of NULL format statements to perform dn searches. - assumption that sizeof() returns an int (This used to be commit a58ea6b3854973b694d2b1e22323ed7eb00e3a3f) --- source4/auth/gensec/gensec_gssapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e6049edc58..a080e75d5c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -714,7 +714,8 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit &skey); if (maj_stat == 0) { - DEBUG(10, ("Got KRB5 session key of length %d\n", skey.length)); + DEBUG(10, ("Got KRB5 session key of length %d\n", + (int)skey.length)); gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, skey.value, skey.length); *session_key = gensec_gssapi_state->session_key; -- cgit From 5bf8d0f51680ba2a44fd954049bd658436f18152 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Jul 2005 10:54:50 +0000 Subject: r8644: This is a more useful error than unsuccesful. Andrew Bartlett (This used to be commit d7136c93fb7ddf27d914329a7c9fd77de22d4356) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a080e75d5c..a803e8649a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -259,7 +259,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi DEBUG(1, ("GSS Import name of %s failed: %s\n", (char *)name_token.value, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_INVALID_PARAMETER; } name_token.value = cli_credentials_get_principal(creds, -- cgit From 176ed87e48134fc998b417242943cfb2e7b4ce6a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Jul 2005 05:07:15 +0000 Subject: r8774: make some gensec errors a bit less verbose (This used to be commit 2134ca475586ed9e062fbf4ef7222fe286c60c57) --- source4/auth/gensec/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a803e8649a..0a98b69f82 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -256,7 +256,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi GSS_C_NT_HOSTBASED_SERVICE, &gensec_gssapi_state->server_name); if (maj_stat) { - DEBUG(1, ("GSS Import name of %s failed: %s\n", + DEBUG(2, ("GSS Import name of %s failed: %s\n", (char *)name_token.value, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_INVALID_PARAMETER; @@ -271,7 +271,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi GSS_C_NT_USER_NAME, &gensec_gssapi_state->client_name); if (maj_stat) { - DEBUG(1, ("GSS Import name of %s failed: %s\n", + DEBUG(2, ("GSS Import name of %s failed: %s\n", (char *)name_token.value, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); return NT_STATUS_UNSUCCESSFUL; -- cgit From 8db8279730c6d4ef6b03b9f96381dee890a8da57 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 5 Aug 2005 00:41:53 +0000 Subject: r9084: 'resign' the sample PAC for the validation of the signature algorithms. If we ever get problems with the kerberos code, it should show up as a different signature in this PAC. This involved returning more data from the pac functions, so changed some callers and split up some functions. Andrew Bartlett (This used to be commit d514a7491208afa0533bf9e99601147eb69e08c9) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0a98b69f82..b6fda0402f 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -795,9 +795,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gss_release_buffer(&min_stat, &pac); /* decode and verify the pac */ - nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob, - gensec_gssapi_state->smb_krb5_context, - NULL, keyblock); + nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, + gensec_gssapi_state->smb_krb5_context, + NULL, keyblock); if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; -- cgit From 878e139f09e6e2f87de35341f4340119959469e5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 17 Aug 2005 12:51:07 +0000 Subject: r9357: Remove DBGC_CLASS cruft copied over from Samba 3. I would like to replace this with something funkier. (This used to be commit 8d376d56c78894b9bbd27ed7fa70da415c0cd038) --- source4/auth/gensec/gensec_gssapi.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b6fda0402f..183e3f201b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -29,9 +29,6 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - struct gensec_gssapi_state { gss_ctx_id_t gssapi_context; struct gss_channel_bindings_struct *input_chan_bindings; -- cgit From 40f56f63bec5a609229033dc4c0854bb4fb16f06 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Aug 2005 06:08:52 +0000 Subject: r9415: Remove old kerberos code (including salt guessing code) that has only caused me pain (and covourty warnings). Simply gensec_gssapi to assume the properties of lorikeet-heimdal, rather than having #ifdef around critical features. This simplifies the code rather a lot. Andrew Bartlett (This used to be commit 11156f556db678c3d325fe5ced5e41a76ed6a3f1) --- source4/auth/gensec/gensec_gssapi.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 183e3f201b..b68bfbdb36 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -128,14 +128,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { -#ifndef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY - /* GSSAPI won't give us the session keys, without the - * right hooks. This is critical when requested, so - * fail outright. */ - return NT_STATUS_INVALID_PARAMETER; -#endif - } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; } @@ -143,13 +135,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; } if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { -#ifndef GSS_C_DCE_STYLE - /* GSSAPI DCE_STYLE is critical when requested, so - * fail outright */ - return NT_STATUS_INVALID_PARAMETER; -#else gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; -#endif } gensec_gssapi_state->gss_oid = gss_mech_krb5; @@ -678,12 +664,16 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; } if (feature & GENSEC_FEATURE_SESSION_KEY) { -#ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY 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)) { return True; } -#endif + } + if (feature & GENSEC_FEATURE_DCE_STYLE) { + return True; + } + if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { + return True; } return False; } @@ -698,7 +688,6 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_OK; } -#ifdef HAVE_GSSKRB5_GET_INITIATOR_SUBKEY /* Ensure we only call this for GSSAPI/krb5, otherwise things could get very ugly */ if ((gensec_gssapi_state->gss_oid->length == gss_mech_krb5->length) && (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, @@ -723,7 +712,6 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit } return NT_STATUS_NO_USER_SESSION_KEY; } -#endif DEBUG(1, ("NO session key for this mech\n")); return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From e85c8561a0fd0f8ea8e072c11554c36e0f6b72eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Aug 2005 16:13:39 +0000 Subject: r9526: provide DCERPC auth type 16 metze (This used to be commit 995b805e046e6e25544487667d928187e13614d6) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b68bfbdb36..2eaad7100c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -843,6 +843,7 @@ static const char *gensec_krb5_oids[] = { /* 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", + .auth_type = DCERPC_AUTH_TYPE_KRB5, .oid = gensec_krb5_oids, .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, -- cgit From c496f58c6fcd8d2c90ddcdf2dc4c3e4c41acd74b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Aug 2005 12:23:37 +0000 Subject: r9681: We don't need the full smb_krb5_context here, so just pass the krb5_context. Andrew Bartlett (This used to be commit 47699019dbb7aa48e7acd6bf8364e40917db8410) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 2eaad7100c..64a6f8be77 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -781,7 +781,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, - gensec_gssapi_state->smb_krb5_context, + gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock); if (NT_STATUS_IS_OK(nt_status)) { -- cgit From 24186a80eb4887b5fb3e72e4b877b456cbe8e35f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Aug 2005 04:30:22 +0000 Subject: r9728: A *major* update to the credentials system, to incorporate the Kerberos CCACHE into the system. This again allows the use of the system ccache when no username is specified, and brings more code in common between gensec_krb5 and gensec_gssapi. It also has a side-effect that may (or may not) be expected: If there is a ccache, even if it is not used (perhaps the remote server didn't want kerberos), it will change the default username. Andrew Bartlett (This used to be commit 6202267f6ec1446d6bd11d1d37d05a977bc8d315) --- source4/auth/gensec/gensec_gssapi.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 64a6f8be77..26494f0222 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -208,6 +208,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi { struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *creds = gensec_get_credentials(gensec_security); + struct ccache_container *ccache; + krb5_error_code ret; NTSTATUS nt_status; gss_buffer_desc name_token; OM_uint32 maj_stat, min_stat; @@ -245,6 +247,13 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } + ret = cli_credentials_get_ccache(creds, + &ccache); + if (ret) { + DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + name_token.value = cli_credentials_get_principal(creds, gensec_gssapi_state); name_token.length = strlen(name_token.value); @@ -260,16 +269,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_UNSUCCESSFUL; } - nt_status = kinit_to_ccache(gensec_gssapi_state, - creds, - gensec_gssapi_state->smb_krb5_context, - &gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - maj_stat = gsskrb5_acquire_cred(&min_stat, - NULL, gensec_gssapi_state->ccache, + NULL, ccache->ccache, gensec_gssapi_state->client_name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, -- cgit From 6b14ffe2713efe2e16a988d920d2dbd7c088601d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Sep 2005 10:53:14 +0000 Subject: r10035: This patch removes the need for the special case hack 'MEMORY_WILDCARD' keytab type. (part of this checking is in effect a merge from lorikeet-heimdal, where I removed this) This is achieved by correctly using the GSSAPI gsskrb5_acquire_cred() function, as this allows us to specify the target principal, regardless of which alias the client may use. This patch also tries to simplify some principal handling and fixes some error cases. Posted to samba-technical, reviewed by metze, and looked over by lha on IRC. Andrew Bartlett (This used to be commit 506a7b67aee949b102d8bf0d6ee9cd12def10d00) --- source4/auth/gensec/gensec_gssapi.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 26494f0222..6316b52bad 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -154,6 +154,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi { NTSTATUS nt_status; OM_uint32 maj_stat, min_stat; + gss_buffer_desc name_token; struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *machine_account; @@ -177,7 +178,6 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi machine_account, gensec_gssapi_state->smb_krb5_context, &gensec_gssapi_state->keytab); - talloc_free(machine_account); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3, ("Could not create memory keytab!\n")); talloc_free(machine_account); @@ -185,9 +185,26 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } } + name_token.value = cli_credentials_get_principal(machine_account, + machine_account); + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_USER_NAME, + &gensec_gssapi_state->server_name); + talloc_free(machine_account); + + if (maj_stat) { + DEBUG(2, ("GSS Import name of %s failed: %s\n", + (char *)name_token.value, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + maj_stat = gsskrb5_acquire_cred(&min_stat, gensec_gssapi_state->keytab, NULL, - NULL, + gensec_gssapi_state->server_name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, -- cgit From 1f2f470889d63a2a81ee3f2d8bdff782ac8d0e28 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 Sep 2005 21:52:50 +0000 Subject: r10066: This is the second in my patches to work on Samba4's kerberos support, with an aim to make the code simpiler and more correct. Gone is the old (since the very early Samba 3.0 krb5 days) 'iterate over all keytypes)' code in gensec_krb5, we now follow the approach used in gensec_gssapi, and use a keytab. I have also done a lot of work in the GSSAPI code, to try and reduce the diff between us and upstream heimdal. It was becoming hard to track patches in this code, and I also want this patch (the DCE_STYLE support) to be in a 'manageable' state for when lha considers it for merging. (metze assures me it still has memory leak problems, but I've started to address some of that). This patch also includes a simple update of other code to current heimdal, as well as changes we need for better PAC verification. On the PAC side of things we now match windows member servers by checking the name and authtime on an incoming PAC. Not generating these right was the cause of the PAC pain, and so now both the main code and torture test validate this behaviour. One thing doesn't work with this patch: - the sealing of RPC pipes with kerberos, Samba -> Samba seems broken. I'm pretty sure this is related to AES, and the need to break apart the gss_wrap interface. Andrew Bartlett (This used to be commit a3aba57c00a9c5318f4706db55d03f64e8bea60c) --- source4/auth/gensec/gensec_gssapi.c | 114 ++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 37 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 6316b52bad..c3f7c52085 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -118,7 +118,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) /* TODO: Fill in channel bindings */ gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; - gensec_gssapi_state->want_flags = 0; + gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG; gensec_gssapi_state->got_flags = 0; gensec_gssapi_state->session_key = data_blob(NULL, 0); @@ -388,12 +388,15 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, } - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - gss_release_buffer(&min_stat2, &output_token); - if (maj_stat == GSS_S_COMPLETE) { + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat2, &output_token); + return NT_STATUS_OK; } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat2, &output_token); + return NT_STATUS_MORE_PROCESSING_REQUIRED; } else { if (maj_stat == GSS_S_FAILURE @@ -427,12 +430,12 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS Wrap failed: %s\n", + DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) @@ -462,12 +465,12 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS UnWrap failed: %s\n", + DEBUG(1, ("gensec_gssapi_unwrap: GSS UnWrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } - *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); + *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) @@ -506,7 +509,7 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS Wrap failed: %s\n", + DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -546,7 +549,7 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur gss_qop_t qop_state; DATA_BLOB in; - dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); + dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length); in = data_blob_talloc(mem_ctx, NULL, sig->length + length); @@ -563,7 +566,7 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS UnWrap failed: %s\n", + DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat))); return NT_STATUS_ACCESS_DENIED; } @@ -688,7 +691,7 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, } } if (feature & GENSEC_FEATURE_DCE_STYLE) { - return True; + return gensec_gssapi_state->got_flags & GSS_C_DCE_STYLE; } if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { return True; @@ -744,15 +747,21 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; - char *p; - char *principal; - const char *account_name; - const char *realm; OM_uint32 maj_stat, min_stat; gss_buffer_desc name_token; gss_buffer_desc pac; krb5_keyblock *keyblock; + time_t authtime; + krb5_principal principal; + char *principal_string; + 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)) { + DEBUG(1, ("NO session info available for this mech\n")); + return NT_STATUS_INVALID_PARAMETER; + } + mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); @@ -764,49 +773,56 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_FOOBAR; } - principal = talloc_strndup(mem_ctx, name_token.value, name_token.length); + principal_string = talloc_strndup(mem_ctx, name_token.value, name_token.length); gss_release_buffer(&min_stat, &name_token); - if (!principal) { + if (!principal_string) { talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } - p = strchr(principal, '@'); - if (p) { - *p = '\0'; - p++; - realm = p; - } else { - realm = lp_realm(); - } - account_name = principal; - maj_stat = gss_krb5_copy_service_keyblock(&min_stat, gensec_gssapi_state->gssapi_context, &keyblock); - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_IF_RELEVANT, - &pac); + if (maj_stat == 0) { + maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + &authtime); + } + + if (maj_stat == 0) { + maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + KRB5_AUTHDATA_IF_RELEVANT, + &pac); + } if (maj_stat == 0) { + krb5_error_code ret; DATA_BLOB pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); pac_blob = unwrap_pac(mem_ctx, &pac_blob); gss_release_buffer(&min_stat, &pac); + + ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context, + principal_string, &principal); + if (ret) { + talloc_free(mem_ctx); + return NT_STATUS_INVALID_PARAMETER; + } /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, - NULL, keyblock); + NULL, keyblock, principal, authtime); + krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; validation.sam3 = &logon_info->info3; nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, - account_name, + NULL, 3, &validation, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { @@ -819,6 +835,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } if (maj_stat) { + krb5_error_code ret; + DATA_BLOB user_sess_key = data_blob(NULL, 0); + DATA_BLOB lm_sess_key = data_blob(NULL, 0); /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... @@ -827,12 +846,32 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi * no PAC present */ - DATA_BLOB user_sess_key = data_blob(NULL, 0); - DATA_BLOB lm_sess_key = data_blob(NULL, 0); - /* TODO: should we pass the krb5 session key in here? */ + char *account_name; + const char *realm; + ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context, + principal_string, &principal); + if (ret) { + talloc_free(mem_ctx); + return NT_STATUS_INVALID_PARAMETER; + } + + realm = krb5_principal_get_realm(gensec_gssapi_state->smb_krb5_context->krb5_context, + principal); + ret = krb5_unparse_name_norealm(gensec_gssapi_state->smb_krb5_context->krb5_context, + principal, &account_name); + if (ret) { + krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(1, ("Unable to use PAC, resorting to local user lookup!\n")); nt_status = sam_get_server_info(mem_ctx, account_name, realm, user_sess_key, lm_sess_key, &server_info); + free(account_name); + krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); + if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; @@ -841,6 +880,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* references the server_info into the session_info */ nt_status = auth_generate_session_info(gensec_gssapi_state, server_info, &session_info); + talloc_free(mem_ctx); talloc_free(server_info); NT_STATUS_NOT_OK_RETURN(nt_status); -- cgit From 5edbeca14108a9b2c3badafce0b0b3447a8280f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Sep 2005 11:19:02 +0000 Subject: r10153: This patch adds a new parameter to gensec_sig_size(), the size of the data to be signed/sealed. We can use this to split the data from the signature portion of the resultant wrapped packet. This required merging the gsskrb5_wrap_size patch from lorikeet-heimdal, and fixes AES encrption issues on DCE/RPC (we no longer use a static 45 byte value). This fixes one of the krb5 issues in my list. Andrew Bartlett (This used to be commit e4f2afc34362953f56a026b66ae1aea81e9db104) --- source4/auth/gensec/gensec_gssapi.c | 55 +++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c3f7c52085..69f219fe07 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -480,10 +480,38 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, return NT_STATUS_OK; } -static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security) +static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size) { - /* not const but work for DCERPC packets and arcfour */ - return 45; + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + OM_uint32 output_size; + 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)) { + DEBUG(1, ("NO sig size available for this mech\n")); + return 0; + } + + maj_stat = gsskrb5_wrap_size(&min_stat, + gensec_gssapi_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + data_size, + &output_size); + if (GSS_ERROR(maj_stat)) { + TALLOC_CTX *mem_ctx = talloc_new(NULL); + DEBUG(1, ("gensec_gssapi_seal_packet: determinaing signature size with gss_wrap_size_limit failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); + talloc_free(mem_ctx); + return 0; + } + + if (output_size < data_size) { + return 0; + } + + /* The difference between the max output and the max input must be the signature */ + return output_size - data_size; } static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security, @@ -496,7 +524,7 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; - ssize_t sig_length = 0; + ssize_t sig_length; input_token.length = length; input_token.value = data; @@ -514,12 +542,15 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit return NT_STATUS_ACCESS_DENIED; } - if (output_token.length < length) { + sig_length = gensec_gssapi_sig_size(gensec_security, length); + + /* Caller must pad to right boundary */ + if (output_token.length != (length + sig_length)) { + DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%d] does not match caller length [%d] plus sig size [%d] = [%d]\n", + output_token.length, length, sig_length, length + sig_length)); return NT_STATUS_INTERNAL_ERROR; } - sig_length = 45; - memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); @@ -618,9 +649,15 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit return NT_STATUS_INTERNAL_ERROR; } - sig_length = 45; + sig_length = gensec_gssapi_sig_size(gensec_security, length); + + /* Caller must pad to right boundary */ + if (output_token.length != (length + sig_length)) { + DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%d] does not match caller length [%d] plus sig size [%d] = [%d]\n", + output_token.length, length, sig_length, length + sig_length)); + return NT_STATUS_INTERNAL_ERROR; + } - /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/ *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); -- cgit From f281d7782451efe4211e6e18435ed367c137ea06 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 Sep 2005 09:46:20 +0000 Subject: r10291: The patch optionally (off by default, not available in all cases) allows Samba to use the target principal name supplied in the mechTokenMIC of an SPNEGO negTokenInit. This isn't a great idea for security reasons, but is how Samba3 behaves, and allows kerberos to function more often in some environments. It is only available for CIFS session setups, due to the ordering of the exchange. Andrew Bartlett (This used to be commit f6a645644127ae695a9f7288e0a469f2eb7f3066) --- source4/auth/gensec/gensec_gssapi.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 69f219fe07..c462cf0ecd 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -229,8 +229,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi krb5_error_code ret; NTSTATUS nt_status; gss_buffer_desc name_token; + gss_OID name_type; OM_uint32 maj_stat, min_stat; const char *hostname = gensec_get_target_hostname(gensec_security); + const char *principal; if (!hostname) { DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); @@ -248,14 +250,22 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; - name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", - gensec_get_target_service(gensec_security), - hostname); - name_token.length = strlen(name_token.value); + principal = gensec_get_target_principal(gensec_security); + if (principal && lp_client_use_spnego_principal()) { + name_token.value = gensec_get_target_principal(gensec_security); + name_token.length = strlen(name_token.value); + name_type = GSS_C_NULL_OID; + } else { + name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", + gensec_get_target_service(gensec_security), + hostname); + name_token.length = strlen(name_token.value); + name_type = GSS_C_NT_HOSTBASED_SERVICE; + } maj_stat = gss_import_name (&min_stat, &name_token, - GSS_C_NT_HOSTBASED_SERVICE, + name_type, &gensec_gssapi_state->server_name); if (maj_stat) { DEBUG(2, ("GSS Import name of %s failed: %s\n", -- cgit From 65d4da0ff330740788c4386a71526b6ed3e10162 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 Sep 2005 21:29:29 +0000 Subject: r10364: Turn gensec:gssapi on by default, except for a login of the form -Udomain\\user. This will probably break in a few configurations, so please let me know. I'll also work to have a way to inhibit kerberos/ntlmssp, as this removes -k. Andrew Bartlett (This used to be commit 3c0dc570b86e79aea5446d7c3bb9750a11bf8ca4) --- source4/auth/gensec/gensec_gssapi.c | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c462cf0ecd..4e1d1e3015 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -250,6 +250,28 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; + ret = cli_credentials_get_ccache(creds, + &ccache); + if (ret) { + DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + name_token.value = cli_credentials_get_principal(creds, + gensec_gssapi_state); + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_USER_NAME, + &gensec_gssapi_state->client_name); + if (maj_stat) { + DEBUG(2, ("GSS Import name of %s failed: %s\n", + (char *)name_token.value, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + principal = gensec_get_target_principal(gensec_security); if (principal && lp_client_use_spnego_principal()) { name_token.value = gensec_get_target_principal(gensec_security); @@ -274,28 +296,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - ret = cli_credentials_get_ccache(creds, - &ccache); - if (ret) { - DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; - } - - name_token.value = cli_credentials_get_principal(creds, - gensec_gssapi_state); - name_token.length = strlen(name_token.value); - - maj_stat = gss_import_name (&min_stat, - &name_token, - GSS_C_NT_USER_NAME, - &gensec_gssapi_state->client_name); - if (maj_stat) { - DEBUG(2, ("GSS Import name of %s failed: %s\n", - (char *)name_token.value, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; - } - maj_stat = gsskrb5_acquire_cred(&min_stat, NULL, ccache->ccache, gensec_gssapi_state->client_name, @@ -964,7 +964,7 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .enabled = False + .enabled = True }; NTSTATUS gensec_gssapi_init(void) -- cgit From 5a770bf72061e6b57f88e28fc585ff3c015ace49 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 24 Sep 2005 03:31:01 +0000 Subject: r10464: Use more consistant names. Andrew Bartlett (This used to be commit 1f726906c488355733dc1a3a89c53e194c192e68) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4e1d1e3015..76458c5f9e 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -239,7 +239,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } if (is_ipaddress(hostname)) { - DEBUG(2, ("Cannot do GSSAPI to a IP address")); + DEBUG(2, ("Cannot do GSSAPI to an IP address")); return NT_STATUS_INVALID_PARAMETER; } @@ -939,7 +939,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_OK; } -static const char *gensec_krb5_oids[] = { +static const char *gensec_gssapi_krb5_oids[] = { GENSEC_OID_KERBEROS5, GENSEC_OID_KERBEROS5_OLD, NULL @@ -949,7 +949,7 @@ static const char *gensec_krb5_oids[] = { static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .name = "gssapi_krb5", .auth_type = DCERPC_AUTH_TYPE_KRB5, - .oid = gensec_krb5_oids, + .oid = gensec_gssapi_krb5_oids, .client_start = gensec_gssapi_client_start, .server_start = gensec_gssapi_server_start, .magic = gensec_gssapi_magic, -- cgit From 718dd6dda6331b27b8f4fc89b891c27124c7821e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 28 Sep 2005 04:50:02 +0000 Subject: r10565: Try to make Kerberos authentication a bit more friendly. This disables it for 'localhost' as well as for any host our KDC does not recognise. Andrew Bartlett (This used to be commit 49c6c36763aae23880a20a8ee50c00e8935d8548) --- source4/auth/gensec/gensec_gssapi.c | 38 +++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 76458c5f9e..8eae8bda71 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -239,7 +239,11 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } if (is_ipaddress(hostname)) { - DEBUG(2, ("Cannot do GSSAPI to an IP address")); + DEBUG(2, ("Cannot do GSSAPI to an IP address\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (strequal(hostname, "localhost")) { + DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -269,7 +273,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi DEBUG(2, ("GSS Import name of %s failed: %s\n", (char *)name_token.value, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_INVALID_PARAMETER; } principal = gensec_get_target_principal(gensec_security); @@ -306,9 +310,16 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi NULL, NULL); if (maj_stat) { - DEBUG(1, ("Aquiring initiator credentails failed: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; + switch (min_stat) { + case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n", + hostname, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ + default: + DEBUG(1, ("Aquiring initiator credentails failed: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } } return NT_STATUS_OK; @@ -408,12 +419,23 @@ 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 (maj_stat == GSS_S_FAILURE - && (min_stat == KRB5KRB_AP_ERR_BADVERSION || min_stat == KRB5KRB_AP_ERR_MSG_TYPE)) { + } 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)) { + switch (min_stat) { + case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + DEBUG(3, ("Server is not registered with our KDC: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ + case KRB5KRB_AP_ERR_MSG_TYPE: /* garbage input, possibly from the auto-mech detection */ return NT_STATUS_INVALID_PARAMETER; + default: + DEBUG(1, ("GSS(krb5) Update failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return nt_status; } + } else { DEBUG(1, ("GSS Update failed: %s\n", gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); return nt_status; -- cgit From 372ca26b2052e267711a45c8bf341f55505f3f8f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 20 Oct 2005 03:47:55 +0000 Subject: r11200: Reposition the creation of the kerberos keytab for GSSAPI and Krb5 authentication. This pulls the creating of the keytab back to the credentials code, and removes the special case of 'use keberos keytab = yes' for now. This allows (and requires) the callers to specify the credentials for the server credentails to GENSEC. This allows kpasswdd (soon to be added) to use a different set of kerberos credentials. The 'use kerberos keytab' code will be moved into the credentials layer, as the layers below now expect a keytab. We also now allow for the old secret to be stored into the credentials, allowing service password changes. Andrew Bartlett (This used to be commit 205f77c579ac8680c85f713a76de5767189c627b) --- source4/auth/gensec/gensec_gssapi.c | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8eae8bda71..97543de445 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -43,7 +43,7 @@ struct gensec_gssapi_state { struct smb_krb5_context *smb_krb5_context; krb5_ccache ccache; const char *ccache_name; - krb5_keytab keytab; + struct keytab_container *keytab; gss_cred_id_t cred; }; @@ -154,6 +154,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi { NTSTATUS nt_status; OM_uint32 maj_stat, min_stat; + int ret; gss_buffer_desc name_token; struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *machine_account; @@ -165,45 +166,43 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; - machine_account = cli_credentials_init(gensec_gssapi_state); - cli_credentials_set_conf(machine_account); - nt_status = cli_credentials_set_machine_account(machine_account); + machine_account = gensec_get_credentials(gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3, ("Could not obtain machine account credentials from the local database\n")); - talloc_free(machine_account); - return nt_status; + if (!machine_account) { + DEBUG(3, ("No machine account credentials specified\n")); + return NT_STATUS_INVALID_PARAMETER; } else { - nt_status = create_memory_keytab(gensec_gssapi_state, - machine_account, - gensec_gssapi_state->smb_krb5_context, - &gensec_gssapi_state->keytab); - if (!NT_STATUS_IS_OK(nt_status)) { + ret = cli_credentials_get_keytab(machine_account, &gensec_gssapi_state->keytab); + if (ret) { DEBUG(3, ("Could not create memory keytab!\n")); - talloc_free(machine_account); - return nt_status; + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } } name_token.value = cli_credentials_get_principal(machine_account, machine_account); - name_token.length = strlen(name_token.value); - - maj_stat = gss_import_name (&min_stat, - &name_token, - GSS_C_NT_USER_NAME, - &gensec_gssapi_state->server_name); - talloc_free(machine_account); - if (maj_stat) { - DEBUG(2, ("GSS Import name of %s failed: %s\n", - (char *)name_token.value, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; + /* This might have been explicity set to NULL, ie use what the client calls us */ + if (name_token.value) { + name_token.length = strlen(name_token.value); + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_USER_NAME, + &gensec_gssapi_state->server_name); + + if (maj_stat) { + DEBUG(2, ("GSS Import name of %s failed: %s\n", + (char *)name_token.value, + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_UNSUCCESSFUL; + } + } else { + gensec_gssapi_state->server_name = GSS_C_NO_NAME; } maj_stat = gsskrb5_acquire_cred(&min_stat, - gensec_gssapi_state->keytab, NULL, + gensec_gssapi_state->keytab->keytab, NULL, gensec_gssapi_state->server_name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, -- cgit From 532b16f3d5b55c91f10ef747b13861be1a969dce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 20 Oct 2005 10:15:31 +0000 Subject: r11216: Upgrade to gd's PAC extraction code from Samba3. While I still want to make some this the kerberos library's problem, we may as well use the best code that is around. Andrew Bartlett (This used to be commit a7fe3078a65f958499779f381731b408f3e6fb1f) --- source4/auth/gensec/gensec_gssapi.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 97543de445..42141e4df2 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -822,6 +822,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi time_t authtime; krb5_principal principal; char *principal_string; + DATA_BLOB pac_blob; + DATA_BLOB unwrapped_pac; if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, @@ -866,12 +868,19 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi KRB5_AUTHDATA_IF_RELEVANT, &pac); } + + if (maj_stat == 0) { + pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); + gss_release_buffer(&min_stat, &pac); + + if (!unwrap_pac(mem_ctx, &pac_blob, &unwrapped_pac)) { + /* No pac actually present */ + maj_stat = 1; + } + } if (maj_stat == 0) { krb5_error_code ret; - DATA_BLOB pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); - pac_blob = unwrap_pac(mem_ctx, &pac_blob); - gss_release_buffer(&min_stat, &pac); ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context, principal_string, &principal); @@ -881,7 +890,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* decode and verify the pac */ - nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, + nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, unwrapped_pac, gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock, principal, authtime); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); -- cgit From db4b95827e4e6d13577513946bff4f956c849756 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Oct 2005 22:20:42 +0000 Subject: r11270: Move the core CrackNames code from rpc_server/drsuapi to dsdb/samdb. I'm sure this will not be the final resting place, but it will do for now. Use the cracknames code in auth/ for creating a server_info given a principal name only (should avoid assumtions about spliting a user@realm principal). Andrew Bartlett (This used to be commit c9d5d8e45dd7b7c99b6cf35b087bc18012f31222) --- source4/auth/gensec/gensec_gssapi.c | 41 ++++++------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 42141e4df2..8fcada2352 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -879,6 +879,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } } + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some + * kind... + */ if (maj_stat == 0) { krb5_error_code ret; @@ -912,42 +916,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } if (maj_stat) { - krb5_error_code ret; - DATA_BLOB user_sess_key = data_blob(NULL, 0); - DATA_BLOB lm_sess_key = data_blob(NULL, 0); - /* IF we have the PAC - otherwise we need to get this - * data from elsewere - local ldb, or (TODO) lookup of some - * kind... - * - * when heimdal can generate the PAC, we should fail if there's - * no PAC present - */ - - char *account_name; - const char *realm; - ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context, - principal_string, &principal); - if (ret) { - talloc_free(mem_ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - realm = krb5_principal_get_realm(gensec_gssapi_state->smb_krb5_context->krb5_context, - principal); - ret = krb5_unparse_name_norealm(gensec_gssapi_state->smb_krb5_context->krb5_context, - principal, &account_name); - if (ret) { - krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - DEBUG(1, ("Unable to use PAC, resorting to local user lookup!\n")); - nt_status = sam_get_server_info(mem_ctx, account_name, realm, - user_sess_key, lm_sess_key, - &server_info); - free(account_name); - krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); + nt_status = sam_get_server_info_principal(mem_ctx, principal_string, + &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); -- cgit From 7751bd939ffb89cfc1dc6fae6b6c6e2a40d338c7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 Oct 2005 15:38:07 +0000 Subject: r11278: fix compiler warnings metze (This used to be commit 716e6b0c883836e50400413cccbeb6fab5cb5744) --- source4/auth/gensec/gensec_gssapi.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8fcada2352..86ecb604ae 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -155,7 +155,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi NTSTATUS nt_status; OM_uint32 maj_stat, min_stat; int ret; - gss_buffer_desc name_token; + const char *principal; struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *machine_account; @@ -179,12 +179,15 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } } - name_token.value = cli_credentials_get_principal(machine_account, - machine_account); + principal = cli_credentials_get_principal(machine_account, + machine_account); /* This might have been explicity set to NULL, ie use what the client calls us */ - if (name_token.value) { - name_token.length = strlen(name_token.value); + if (principal) { + gss_buffer_desc name_token; + + name_token.value = discard_const_p(uint8_t, principal); + name_token.length = strlen(principal); maj_stat = gss_import_name (&min_stat, &name_token, @@ -260,9 +263,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_UNSUCCESSFUL; } - name_token.value = cli_credentials_get_principal(creds, - gensec_gssapi_state); - name_token.length = strlen(name_token.value); + principal = cli_credentials_get_principal(creds, + gensec_gssapi_state); + name_token.value = discard_const_p(uint8_t, principal); + name_token.length = strlen(principal); maj_stat = gss_import_name (&min_stat, &name_token, @@ -277,14 +281,18 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi principal = gensec_get_target_principal(gensec_security); if (principal && lp_client_use_spnego_principal()) { - name_token.value = gensec_get_target_principal(gensec_security); - name_token.length = strlen(name_token.value); + name_token.value = discard_const_p(uint8_t, principal); + name_token.length = strlen(principal); + name_type = GSS_C_NULL_OID; } else { - name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", - gensec_get_target_service(gensec_security), - hostname); - name_token.length = strlen(name_token.value); + principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", + gensec_get_target_service(gensec_security), + hostname); + + name_token.value = discard_const_p(uint8_t, principal); + name_token.length = strlen(principal); + name_type = GSS_C_NT_HOSTBASED_SERVICE; } -- cgit From 14a3abd5591a7c310bdd2638e5c06833dc2c8f92 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Oct 2005 23:41:01 +0000 Subject: r11314: Use a patch from lha to have the kerberos libs extract the PAC, rather than doing ASN.1 parsing in Samba. Also use the API function for getting a client from a ticket, rather than just digging in the structure. Andrew Bartlett (This used to be commit 25d5ea6d724bd2b64a6086ae6e2e1c5148b8ca4a) --- source4/auth/gensec/gensec_gssapi.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 86ecb604ae..37c8333da3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -873,18 +873,13 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi if (maj_stat == 0) { maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_IF_RELEVANT, + KRB5_AUTHDATA_WIN2K_PAC, &pac); } if (maj_stat == 0) { pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); gss_release_buffer(&min_stat, &pac); - - if (!unwrap_pac(mem_ctx, &pac_blob, &unwrapped_pac)) { - /* No pac actually present */ - maj_stat = 1; - } } /* IF we have the PAC - otherwise we need to get this @@ -902,7 +897,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* decode and verify the pac */ - nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, unwrapped_pac, + nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock, principal, authtime); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); -- cgit From c0d1fb491433ca13ff3734ffd8863cfb5f39e298 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Oct 2005 22:37:48 +0000 Subject: r11342: Remove unused variables. Andrew Bartlett (This used to be commit eed8f4a03168a72910c829e490937c696c00b697) --- source4/auth/gensec/gensec_gssapi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 37c8333da3..8c0eb23546 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -831,7 +831,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi krb5_principal principal; char *principal_string; DATA_BLOB pac_blob; - DATA_BLOB unwrapped_pac; if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, -- cgit From 12d4dd28a5de1bafbd982ce0043d73dd5a49c3bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Oct 2005 13:13:52 +0000 Subject: r11394: Allow KDC unreachable as another 'forget about gssapi' error on SPNEGO. Andrew Bartlett (This used to be commit da24074860cb7029ef0ff45105170642174f45c1) --- source4/auth/gensec/gensec_gssapi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8c0eb23546..d59d19c636 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -430,6 +430,10 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, && (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, gensec_gssapi_state->gss_oid->length) == 0)) { switch (min_stat) { + case KRB5_KDC_UNREACH: + DEBUG(3, ("Cannot reach a KDC we require: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: DEBUG(3, ("Server is not registered with our KDC: %s\n", gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); -- cgit From 3b2a6997b43dcfe37adf67c84e564a4fbff5b108 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 00:31:22 +0000 Subject: r11452: Update Heimdal to current lorikeet, including removing the ccache side of the gsskrb5_acquire_cred hack. Add support for delegated credentials into the auth and credentials subsystem, and specifically into gensec_gssapi. Add the CIFS NTVFS handler as a consumer of delegated credentials, when no user/domain/password is specified. Andrew Bartlett (This used to be commit 55b89899adb692d90e63873ccdf80b9f94a6b448) --- source4/auth/gensec/gensec_gssapi.c | 101 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 49 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index d59d19c636..4608b62db5 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -44,8 +44,10 @@ struct gensec_gssapi_state { krb5_ccache ccache; const char *ccache_name; struct keytab_container *keytab; + struct gssapi_creds_container *client_cred; gss_cred_id_t cred; + gss_cred_id_t delegated_cred_handle; }; static char *gssapi_error_string(TALLOC_CTX *mem_ctx, @@ -83,6 +85,10 @@ static int gensec_gssapi_destory(void *ptr) maj_stat = gss_release_cred(&min_stat, &gensec_gssapi_state->cred); } + if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { + maj_stat = gss_release_cred(&min_stat, + &gensec_gssapi_state->delegated_cred_handle); + } if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { maj_stat = gss_delete_sec_context (&min_stat, @@ -118,13 +124,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) /* TODO: Fill in channel bindings */ gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; - gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG; + gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG; gensec_gssapi_state->got_flags = 0; gensec_gssapi_state->session_key = data_blob(NULL, 0); gensec_gssapi_state->pac = data_blob(NULL, 0); gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL; + gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); @@ -205,7 +212,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } maj_stat = gsskrb5_acquire_cred(&min_stat, - gensec_gssapi_state->keytab->keytab, NULL, + gensec_gssapi_state->keytab->keytab, gensec_gssapi_state->server_name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, @@ -227,7 +234,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi { struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *creds = gensec_get_credentials(gensec_security); - struct ccache_container *ccache; krb5_error_code ret; NTSTATUS nt_status; gss_buffer_desc name_token; @@ -235,6 +241,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi OM_uint32 maj_stat, min_stat; const char *hostname = gensec_get_target_hostname(gensec_security); const char *principal; + struct gssapi_creds_container *gcc; if (!hostname) { DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); @@ -256,29 +263,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = gensec_security->private_data; - ret = cli_credentials_get_ccache(creds, - &ccache); - if (ret) { - DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; - } - - principal = cli_credentials_get_principal(creds, - gensec_gssapi_state); - name_token.value = discard_const_p(uint8_t, principal); - name_token.length = strlen(principal); - - maj_stat = gss_import_name (&min_stat, - &name_token, - GSS_C_NT_USER_NAME, - &gensec_gssapi_state->client_name); - if (maj_stat) { - DEBUG(2, ("GSS Import name of %s failed: %s\n", - (char *)name_token.value, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_INVALID_PARAMETER; - } - principal = gensec_get_target_principal(gensec_security); if (principal && lp_client_use_spnego_principal()) { name_token.value = discard_const_p(uint8_t, principal); @@ -307,28 +291,20 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - maj_stat = gsskrb5_acquire_cred(&min_stat, - NULL, ccache->ccache, - gensec_gssapi_state->client_name, - GSS_C_INDEFINITE, - GSS_C_NULL_OID_SET, - GSS_C_INITIATE, - &gensec_gssapi_state->cred, - NULL, - NULL); - if (maj_stat) { - switch (min_stat) { - case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: - DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n", - hostname, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ - default: - DEBUG(1, ("Aquiring initiator credentails failed: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; - } + ret = cli_credentials_get_client_gss_creds(creds, &gcc); + switch (ret) { + case 0: + break; + case KRB5_KDC_UNREACH: + DEBUG(3, ("Cannot reach a KDC we require\n")); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ + default: + DEBUG(1, ("Aquiring initiator credentails failed\n")); + return NT_STATUS_UNSUCCESSFUL; } + gensec_gssapi_state->client_cred = gcc; + return NT_STATUS_OK; } @@ -369,7 +345,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, const DATA_BLOB in, DATA_BLOB *out) { struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; OM_uint32 maj_stat, min_stat; OM_uint32 min_stat2; gss_buffer_desc input_token, output_token; @@ -381,7 +357,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, case GENSEC_CLIENT: { maj_stat = gss_init_sec_context(&min_stat, - gensec_gssapi_state->cred, + gensec_gssapi_state->client_cred->creds, &gensec_gssapi_state->gssapi_context, gensec_gssapi_state->server_name, discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), @@ -407,7 +383,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &output_token, &gensec_gssapi_state->got_flags, NULL, - NULL); + &gensec_gssapi_state->delegated_cred_handle); gensec_gssapi_state->gss_oid = gss_oid_p; break; } @@ -420,6 +396,12 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat2, &output_token); + if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) { + DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); + } else { + DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); + } + return NT_STATUS_OK; } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); @@ -941,6 +923,27 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key); NT_STATUS_NOT_OK_RETURN(nt_status); + if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { + DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client")); + } else { + krb5_error_code ret; + DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); + session_info->credentials = cli_credentials_init(session_info); + if (!session_info->credentials) { + return NT_STATUS_NO_MEMORY; + } + + cli_credentials_set_conf(session_info->credentials); + + ret = cli_credentials_set_client_gss_creds(session_info->credentials, + gensec_gssapi_state->delegated_cred_handle, + CRED_SPECIFIED); + if (ret) { + return NT_STATUS_NO_MEMORY; + } + /* It has been taken from this place... */ + gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; + } *_session_info = session_info; return NT_STATUS_OK; -- cgit From cc0f3779b1de565ed33504d123e41656d6d2aab2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 03:48:49 +0000 Subject: r11468: Merge a bit more of init_sec_context from Heimdal CVS into our DCE_STYLE modified version, and add parametric options to control delegation. It turns out the only remaining issue is sending delegated credentials to a windows server, probably due to the bug lha mentions in his blog (using the wrong key). If I turn delgation on in smbclient, but off in smbd, I can proxy a cifs session. I can't wait till Heimdal 0.8, so I'll see if I can figure out the fix myself :-) Andrew Bartlett (This used to be commit fd5fd03570c13f5644e53ff89ac8eca7c0985740) --- source4/auth/gensec/gensec_gssapi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4608b62db5..a51a30900f 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -124,7 +124,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) /* TODO: Fill in channel bindings */ gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; - gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG; + gensec_gssapi_state->want_flags = 0; + if (lp_parm_bool(-1, "gensec_gssapi", "mutual", True)) { + gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; + } + if (lp_parm_bool(-1, "gensec_gssapi", "delegation", False)) { + gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; + } + gensec_gssapi_state->got_flags = 0; gensec_gssapi_state->session_key = data_blob(NULL, 0); -- cgit From 20debaa289d7f035e74d2044f1fbea18ce85b1db Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 04:12:47 +0000 Subject: r11470: To a server trusted for delegation (checked for in the gss libs), delegate by default. Andrew Bartlett (This used to be commit 49d489c81d5b5c86e032ed6edfda4590d1d1f2be) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a51a30900f..691dc3f064 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -128,7 +128,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (lp_parm_bool(-1, "gensec_gssapi", "mutual", True)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(-1, "gensec_gssapi", "delegation", False)) { + if (lp_parm_bool(-1, "gensec_gssapi", "delegation", True)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } -- cgit From 694a8e7402f446fec848b56e876d031654550175 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 06:38:47 +0000 Subject: r11514: Fixup debug message (This used to be commit b2372cad367a29d7dca596dace703a349b381a09) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 691dc3f064..745191e693 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -931,7 +931,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi NT_STATUS_NOT_OK_RETURN(nt_status); if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { - DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client")); + DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); } else { krb5_error_code ret; DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); -- cgit From 72820aaf9281acc2acec869793a95f3353c1034c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 11:02:37 +0000 Subject: r11521: Add in client support for checking supportedSASLmechanisms, and then determining a mechanism to use. Currently it doesn't to fallbacks like SPNEGO does, but this could be added (to GENSEC, not to here). This also adds a new function to GENSEC, which returns a list of SASL names in our preference order (currently determined by the build system of all things...). Also make the similar function used for OIDs in SPNEGO do the same. This is all a very long-winded way of moving from a hard-coded NTLM to GSS-SPNEGO in our SASL client... Andrew Bartlett (This used to be commit 130eb9bb9a37957614c87e0e6846a812abb51e00) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 745191e693..08e2298c1a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -965,6 +965,7 @@ static const char *gensec_gssapi_krb5_oids[] = { /* 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", + .sasl_name = "GSSAPI", .auth_type = DCERPC_AUTH_TYPE_KRB5, .oid = gensec_gssapi_krb5_oids, .client_start = gensec_gssapi_client_start, -- cgit From 918c7634c21deb0aa89388bb3d9e147bfc8576c8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Nov 2005 02:29:37 +0000 Subject: r11543: A major upgrade to our KDC and PAC handling. We now put the PAC in the AS-REP, so that the client has it in the TGT. We then validate it (and re-sign it) on a TGS-REQ, ie when the client wants a ticket. This should also allow us to interop with windows KDCs. If we get an invalid PAC at the TGS stage, we just drop it. I'm slowly trying to move the application logic out of hdb-ldb.c, and back in with the rest of Samba's auth system, for consistancy. This continues that trend. Andrew Bartlett (This used to be commit 36973b1eef7db5983cce76ba241e54d5f925c69c) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 08e2298c1a..c8a57234e3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -891,7 +891,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, - NULL, keyblock, principal, authtime); + NULL, keyblock, principal, authtime, NULL); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); if (NT_STATUS_IS_OK(nt_status)) { -- cgit From 03d301ead5f702872b8cb948b8cd01b0fa0db5f7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Nov 2005 02:08:15 +0000 Subject: r11967: Fix more 64-bit warnings. (This used to be commit 9c4436a124f874ae240feaf590141d48c33a635f) --- source4/auth/gensec/gensec_gssapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c8a57234e3..b5a2dadd35 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -578,8 +578,8 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit /* Caller must pad to right boundary */ if (output_token.length != (length + sig_length)) { - DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%d] does not match caller length [%d] plus sig size [%d] = [%d]\n", - output_token.length, length, sig_length, length + sig_length)); + DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", + (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length))); return NT_STATUS_INTERNAL_ERROR; } @@ -685,8 +685,8 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit /* Caller must pad to right boundary */ if (output_token.length != (length + sig_length)) { - DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%d] does not match caller length [%d] plus sig size [%d] = [%d]\n", - output_token.length, length, sig_length, length + sig_length)); + DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", + (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length))); return NT_STATUS_INTERNAL_ERROR; } -- cgit From 9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 1 Dec 2005 05:20:39 +0000 Subject: r11995: A big kerberos-related update. This merges Samba4 up to current lorikeet-heimdal, which includes a replacement for some Samba-specific hacks. In particular, the credentials system now supplies GSS client and server credentials. These are imported into GSS with gss_krb5_import_creds(). Unfortunetly this can't take an MEMORY keytab, so we now create a FILE based keytab as provision and join time. Because the keytab is now created in advance, we don't spend .4s at negprot doing sha1 s2k calls. Also, because the keytab is read in real time, any change in the server key will be correctly picked up by the the krb5 code. To mark entries in the secrets which should be exported to a keytab, there is a new kerberosSecret objectClass. The new routine cli_credentials_update_all_keytabs() searches for these, and updates the keytabs. This is called in the provision.js via the ejs wrapper credentials_update_all_keytabs(). We can now (in theory) use a system-provided /etc/krb5.keytab, if krb5Keytab: FILE:/etc/krb5.keytab is added to the secrets.ldb record. By default the attribute privateKeytab: secrets.keytab is set, pointing to allow the whole private directory to be moved without breaking the internal links. (This used to be commit 6b75573df49c6210e1b9d71e108a9490976bd41d) --- source4/auth/gensec/gensec_gssapi.c | 61 +++++-------------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b5a2dadd35..68da2567da 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -41,12 +41,9 @@ struct gensec_gssapi_state { DATA_BLOB pac; struct smb_krb5_context *smb_krb5_context; - krb5_ccache ccache; - const char *ccache_name; - struct keytab_container *keytab; struct gssapi_creds_container *client_cred; + struct gssapi_creds_container *server_cred; - gss_cred_id_t cred; gss_cred_id_t delegated_cred_handle; }; @@ -81,10 +78,6 @@ static int gensec_gssapi_destory(void *ptr) struct gensec_gssapi_state *gensec_gssapi_state = ptr; OM_uint32 maj_stat, min_stat; - if (gensec_gssapi_state->cred != GSS_C_NO_CREDENTIAL) { - maj_stat = gss_release_cred(&min_stat, - &gensec_gssapi_state->cred); - } if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { maj_stat = gss_release_cred(&min_stat, &gensec_gssapi_state->delegated_cred_handle); @@ -137,7 +130,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->session_key = data_blob(NULL, 0); gensec_gssapi_state->pac = data_blob(NULL, 0); - gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL; gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); @@ -167,11 +159,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security) { NTSTATUS nt_status; - OM_uint32 maj_stat, min_stat; int ret; - const char *principal; struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *machine_account; + struct gssapi_creds_container *gcc; nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { @@ -186,53 +177,15 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi DEBUG(3, ("No machine account credentials specified\n")); return NT_STATUS_INVALID_PARAMETER; } else { - ret = cli_credentials_get_keytab(machine_account, &gensec_gssapi_state->keytab); + ret = cli_credentials_get_server_gss_creds(machine_account, &gcc); if (ret) { - DEBUG(3, ("Could not create memory keytab!\n")); + DEBUG(1, ("Aquiring acceptor credentials failed: %s\n", + error_message(ret))); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } } - principal = cli_credentials_get_principal(machine_account, - machine_account); - - /* This might have been explicity set to NULL, ie use what the client calls us */ - if (principal) { - gss_buffer_desc name_token; - - name_token.value = discard_const_p(uint8_t, principal); - name_token.length = strlen(principal); - - maj_stat = gss_import_name (&min_stat, - &name_token, - GSS_C_NT_USER_NAME, - &gensec_gssapi_state->server_name); - - if (maj_stat) { - DEBUG(2, ("GSS Import name of %s failed: %s\n", - (char *)name_token.value, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_UNSUCCESSFUL; - } - } else { - gensec_gssapi_state->server_name = GSS_C_NO_NAME; - } - - maj_stat = gsskrb5_acquire_cred(&min_stat, - gensec_gssapi_state->keytab->keytab, - gensec_gssapi_state->server_name, - GSS_C_INDEFINITE, - GSS_C_NULL_OID_SET, - GSS_C_ACCEPT, - &gensec_gssapi_state->cred, - NULL, - NULL); - if (maj_stat) { - DEBUG(1, ("Aquiring acceptor credentails failed: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - + gensec_gssapi_state->server_cred = gcc; return NT_STATUS_OK; } @@ -382,7 +335,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, { maj_stat = gss_accept_sec_context(&min_stat, &gensec_gssapi_state->gssapi_context, - gensec_gssapi_state->cred, + gensec_gssapi_state->server_cred->creds, &input_token, gensec_gssapi_state->input_chan_bindings, &gensec_gssapi_state->client_name, -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/auth/gensec/gensec_gssapi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 68da2567da..b71bee03ea 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -24,7 +24,6 @@ #include "includes.h" #include "system/kerberos.h" -#include "system/network.h" #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -- cgit From adab8d3968ce2bf18eab6b89375050ebf6630f08 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 07:13:36 +0000 Subject: r12863: As lha suggested to me a while back, it appears that the gsskrb5_get_initiator_subkey() routine is bougs. We can indeed use gss_krb5_get_subkey(). This is fortunate, as there was a segfault bug in 'initiator' version. Andrew Bartlett (This used to be commit ec11870ca1f9231dd3eeae792fc3268b31477e11) --- source4/auth/gensec/gensec_gssapi.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b71bee03ea..4eb7b95d6d 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -734,22 +734,21 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit 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)) { - OM_uint32 maj_stat, min_stat; - gss_buffer_desc skey; + OM_uint32 maj_stat; + krb5_keyblock *skey; - maj_stat = gsskrb5_get_initiator_subkey(&min_stat, - gensec_gssapi_state->gssapi_context, - &skey); + maj_stat = gss_krb5_get_subkey(gensec_gssapi_state->gssapi_context, + &skey); if (maj_stat == 0) { DEBUG(10, ("Got KRB5 session key of length %d\n", - (int)skey.length)); + (int)KRB5_KEY_LENGTH(skey))); gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, - skey.value, skey.length); + KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); *session_key = gensec_gssapi_state->session_key; dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - gss_release_buffer(&min_stat, &skey); + krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, skey); return NT_STATUS_OK; } return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From 44e601b5ad635ba29088fd4c747627dee8d62112 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Jan 2006 12:15:24 +0000 Subject: r13206: This patch finally re-adds a -k option that works reasonably. From here we can add tests to Samba for kerberos, forcing it on and off. In the process, I also remove the dependency of credentials on GENSEC. This also picks up on the idea of bringing 'set_boolean' into general code from jpeach's cifsdd patch. Andrew Bartlett (This used to be commit 1ac7976ea6e3ad6184c911de5df624c44e7c5228) --- source4/auth/gensec/gensec_gssapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4eb7b95d6d..f9650ee6cc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -174,7 +174,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi if (!machine_account) { DEBUG(3, ("No machine account credentials specified\n")); - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } else { ret = cli_credentials_get_server_gss_creds(machine_account, &gcc); if (ret) { @@ -933,7 +933,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .enabled = True + .enabled = True, + .kerberos = True }; NTSTATUS gensec_gssapi_init(void) -- cgit From 7c7125be5dfdbacd702891e16529eb1412966f83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Jan 2006 01:50:54 +0000 Subject: r13247: Try to make better use of talloc in the auth/ and auth/gensec code. We don't want temporary memory hanging around on the long-term contexts. Andrew Bartlett (This used to be commit 85b3f6ebddfb655fdd08d1799752e562a6ff9cb1) --- source4/auth/gensec/gensec_gssapi.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f9650ee6cc..c90faacf02 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -759,7 +759,7 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit } static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security, - struct auth_session_info **_session_info) + struct auth_session_info **_session_info) { NTSTATUS nt_status; TALLOC_CTX *mem_ctx; @@ -873,13 +873,17 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(gensec_gssapi_state, server_info, &session_info); - talloc_free(mem_ctx); - talloc_free(server_info); - NT_STATUS_NOT_OK_RETURN(nt_status); + nt_status = auth_generate_session_info(mem_ctx, server_info, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key); - NT_STATUS_NOT_OK_RETURN(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); @@ -888,6 +892,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); session_info->credentials = cli_credentials_init(session_info); if (!session_info->credentials) { + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -897,11 +902,13 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gensec_gssapi_state->delegated_cred_handle, CRED_SPECIFIED); if (ret) { + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } /* It has been taken from this place... */ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; } + talloc_steal(gensec_gssapi_state, session_info); *_session_info = session_info; return NT_STATUS_OK; -- cgit From 7e9868c74fe5a1f6e7445a64a33a1cb408545bf7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Jan 2006 02:01:52 +0000 Subject: r13250: I missed a couple of talloc_free()'s Andrew Bartlett (This used to be commit 3570a62876dcd656b328bf8c2c1be617ae9a8fd7) --- source4/auth/gensec/gensec_gssapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c90faacf02..e576d8b7c9 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -791,6 +791,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi &name_token, NULL); if (maj_stat) { + talloc_free(mem_ctx); return NT_STATUS_FOOBAR; } @@ -909,6 +910,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; } talloc_steal(gensec_gssapi_state, session_info); + talloc_free(mem_ctx); *_session_info = session_info; return NT_STATUS_OK; -- cgit From f256a9c55e4785e4383a0546e75bba355a51fa04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 09:53:50 +0000 Subject: r13342: Make the GSSAPI SASL mech actually work, by (shock horror) reading the spec. GSSAPI differs from GSS-SPNEGO in an additional 3 packets, negotiating a buffer size and what integrity protection/privacy should be used. I worked off draft-ietf-sasl-gssapi-03, and this works against Win2k3. I'm doing this in the hope that Apple clients as well as SASL-based LDAP tools may get a bit further. I still can't get ldapsearch to work, it fails with the ever-helpful 'Local error'. Andrew Bartlett (This used to be commit 3e462897754b30306c1983af2d137329dd937ad6) --- source4/auth/gensec/gensec_gssapi.c | 476 ++++++++++++++++++++++++++++++------ 1 file changed, 406 insertions(+), 70 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e576d8b7c9..0b48a010eb 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -28,6 +28,18 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" +enum gensec_gssapi_sasl_state +{ + STAGE_GSS_NEG, + STAGE_SASL_SSF_NEG, + STAGE_SASL_SSF_ACCEPT, + STAGE_DONE +}; + +#define NEG_SEAL 0x4 +#define NEG_SIGN 0x2 +#define NEG_NONE 0x1 + struct gensec_gssapi_state { gss_ctx_id_t gssapi_context; struct gss_channel_bindings_struct *input_chan_bindings; @@ -44,6 +56,14 @@ struct gensec_gssapi_state { struct gssapi_creds_container *server_cred; gss_cred_id_t delegated_cred_handle; + + BOOL sasl; /* We have two different mechs in this file: One + * for SASL wrapped GSSAPI and another for normal + * GSSAPI */ + enum gensec_gssapi_sasl_state sasl_state; + uint8_t sasl_protection; /* What was negotiated at the SASL + * layer, independent of the GSSAPI + * layer... */ }; static char *gssapi_error_string(TALLOC_CTX *mem_ctx, @@ -106,6 +126,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (!gensec_gssapi_state) { return NT_STATUS_NO_MEMORY; } + + gensec_gssapi_state->sasl = False; + gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; gensec_security->private_data = gensec_gssapi_state; @@ -123,6 +146,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (lp_parm_bool(-1, "gensec_gssapi", "delegation", True)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } + if (lp_parm_bool(-1, "gensec_gssapi", "sequence", True)) { + gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; + } gensec_gssapi_state->got_flags = 0; @@ -168,7 +194,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi return nt_status; } - gensec_gssapi_state = gensec_security->private_data; + gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); machine_account = gensec_get_credentials(gensec_security); @@ -189,6 +215,19 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } +static NTSTATUS gensec_gssapi_sasl_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_gssapi_state *gensec_gssapi_state; + nt_status = gensec_gssapi_server_start(gensec_security); + + if (NT_STATUS_IS_OK(nt_status)) { + gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + gensec_gssapi_state->sasl = True; + } + return nt_status; +} + static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; @@ -220,7 +259,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return nt_status; } - gensec_gssapi_state = gensec_security->private_data; + gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); principal = gensec_get_target_principal(gensec_security); if (principal && lp_client_use_spnego_principal()) { @@ -267,6 +306,19 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_OK; } +static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_gssapi_state *gensec_gssapi_state; + nt_status = gensec_gssapi_client_start(gensec_security); + + if (NT_STATUS_IS_OK(nt_status)) { + gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + gensec_gssapi_state->sasl = True; + } + return nt_status; +} + /** * Check if the packet is one for this mechansim @@ -312,85 +364,315 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, input_token.length = in.length; input_token.value = in.data; - switch (gensec_security->gensec_role) { - case GENSEC_CLIENT: - { - maj_stat = gss_init_sec_context(&min_stat, - gensec_gssapi_state->client_cred->creds, - &gensec_gssapi_state->gssapi_context, - gensec_gssapi_state->server_name, - discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), - gensec_gssapi_state->want_flags, - 0, - gensec_gssapi_state->input_chan_bindings, - &input_token, - NULL, - &output_token, - &gensec_gssapi_state->got_flags, /* ret flags */ - NULL); - break; - } - case GENSEC_SERVER: + switch (gensec_gssapi_state->sasl_state) { + case STAGE_GSS_NEG: { - maj_stat = gss_accept_sec_context(&min_stat, - &gensec_gssapi_state->gssapi_context, - gensec_gssapi_state->server_cred->creds, - &input_token, - gensec_gssapi_state->input_chan_bindings, - &gensec_gssapi_state->client_name, - &gss_oid_p, + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + { + maj_stat = gss_init_sec_context(&min_stat, + gensec_gssapi_state->client_cred->creds, + &gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->server_name, + discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), + gensec_gssapi_state->want_flags, + 0, + gensec_gssapi_state->input_chan_bindings, + &input_token, + NULL, + &output_token, + &gensec_gssapi_state->got_flags, /* ret flags */ + NULL); + break; + } + case GENSEC_SERVER: + { + maj_stat = gss_accept_sec_context(&min_stat, + &gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->server_cred->creds, + &input_token, + gensec_gssapi_state->input_chan_bindings, + &gensec_gssapi_state->client_name, + &gss_oid_p, &output_token, &gensec_gssapi_state->got_flags, NULL, - &gensec_gssapi_state->delegated_cred_handle); - gensec_gssapi_state->gss_oid = gss_oid_p; - break; - } - default: - return NT_STATUS_INVALID_PARAMETER; - - } + &gensec_gssapi_state->delegated_cred_handle); + gensec_gssapi_state->gss_oid = gss_oid_p; + break; + } + default: + return NT_STATUS_INVALID_PARAMETER; + + } - if (maj_stat == GSS_S_COMPLETE) { - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - gss_release_buffer(&min_stat2, &output_token); + if (maj_stat == GSS_S_COMPLETE) { + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat2, &output_token); + + if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) { + DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); + } else { + DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); + } - if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) { - DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); + /* We may have been invoked as SASL, so there is more work to do */ + if (gensec_gssapi_state->sasl) { + gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gensec_gssapi_state->sasl_state = STAGE_DONE; + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(3, ("GSSAPI Connection will be cryptographicly sealed\n")); + } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(3, ("GSSAPI Connection will be cryptographicly signed\n")); + } else { + DEBUG(3, ("GSSAPI Connection will have no cryptographicly protection\n")); + } + + return NT_STATUS_OK; + } + } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + 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)) { + switch (min_stat) { + case KRB5_KDC_UNREACH: + DEBUG(3, ("Cannot reach a KDC we require: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ + case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: + DEBUG(3, ("Server is not registered with our KDC: %s\n", + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ + case KRB5KRB_AP_ERR_MSG_TYPE: + /* garbage input, possibly from the auto-mech detection */ + return NT_STATUS_INVALID_PARAMETER; + default: + DEBUG(1, ("GSS(krb5) Update failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return nt_status; + } } else { - DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); + DEBUG(1, ("GSS Update failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return nt_status; } + break; + } + /* These last two stages are only done if we were invoked as SASL */ + case STAGE_SASL_SSF_NEG: + { + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + { + uint8_t maxlength_proposed[4]; + uint8_t security_supported; + int conf_state; + gss_qop_t qop_state; + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return NT_STATUS_ACCESS_DENIED; + } + + if (output_token.length < 4) { + return NT_STATUS_INVALID_PARAMETER; + } - return NT_STATUS_OK; - } else if (maj_stat == GSS_S_CONTINUE_NEEDED) { - *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); - gss_release_buffer(&min_stat2, &output_token); + memcpy(maxlength_proposed, output_token.value, 4); + gss_release_buffer(&min_stat, &output_token); + + /* first byte is the proposed security */ + security_supported = maxlength_proposed[0]; + maxlength_proposed[0] = '\0'; + gensec_gssapi_state->sasl_protection = 0; + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + if (security_supported & NEG_SEAL) { + gensec_gssapi_state->sasl_protection |= NEG_SEAL; + } + } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + if (security_supported & NEG_SIGN) { + gensec_gssapi_state->sasl_protection |= NEG_SIGN; + } + } else if (security_supported & NEG_NONE) { + gensec_gssapi_state->sasl_protection |= NEG_NONE; + } else { + DEBUG(1, ("Remote server does not support unprotected connections")); + return NT_STATUS_ACCESS_DENIED; + } + + /* We just accept their max length, and send + * it back with the SASL flags */ + maxlength_proposed[0] = gensec_gssapi_state->sasl_protection; + + input_token.value = maxlength_proposed; + input_token.length = sizeof(maxlength_proposed); + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + False, + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return NT_STATUS_ACCESS_DENIED; + } + + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat, &output_token); + + /* quirk: This changes the value that gensec_have_feature returns, to be that after SASL negotiation */ + gensec_gssapi_state->sasl_state = STAGE_DONE; + + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(3, ("GSSAPI Connection to server will be cryptographicly sealed\n")); + } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(3, ("GSSAPI Connection to server will be cryptographicly signed\n")); + } else { + DEBUG(3, ("GSSAPI Connection to server will have no cryptographicly protection\n")); + } - 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)) { - switch (min_stat) { - case KRB5_KDC_UNREACH: - DEBUG(3, ("Cannot reach a KDC we require: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ - case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: - DEBUG(3, ("Server is not registered with our KDC: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); - return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ - case KRB5KRB_AP_ERR_MSG_TYPE: - /* garbage input, possibly from the auto-mech detection */ - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; + } + case GENSEC_SERVER: + { + uint8_t maxlength_proposed[4]; + uint8_t security_supported = 0x0; + int conf_state; + + /* TODO: Need some better ideas for this */ + RSIVAL(maxlength_proposed, 0, 0xFFFFFF); + /* first byte is the proposed security */ + maxlength_proposed[0] = '\0'; + + gensec_gssapi_state->sasl_protection = 0; + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + security_supported |= NEG_SEAL; + } + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + security_supported |= NEG_SIGN; + } + if (security_supported == 0) { + /* If we don't support anything, this must be 0 */ + RSIVAL(maxlength_proposed, 0, 0x0); + } + + /* TODO: We may not wish to support this */ + security_supported |= NEG_NONE; + + /* Ignore 'in' */ + maxlength_proposed[0] = security_supported; + + input_token.value = maxlength_proposed; + input_token.length = sizeof(maxlength_proposed); + + maj_stat = gss_wrap(&min_stat, + gensec_gssapi_state->gssapi_context, + False, + GSS_C_QOP_DEFAULT, + &input_token, + &conf_state, + &output_token); + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + return NT_STATUS_ACCESS_DENIED; + } + + *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); + gss_release_buffer(&min_stat, &output_token); + + gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_ACCEPT; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } default: - DEBUG(1, ("GSS(krb5) Update failed: %s\n", + return NT_STATUS_INVALID_PARAMETER; + + } + } + /* This is s server-only stage */ + case STAGE_SASL_SSF_ACCEPT: + { + uint8_t maxlength_proposed[4]; + uint8_t security_proposed; + int conf_state; + gss_qop_t qop_state; + input_token.length = in.length; + input_token.value = in.data; + + maj_stat = gss_unwrap(&min_stat, + gensec_gssapi_state->gssapi_context, + &input_token, + &output_token, + &conf_state, + &qop_state); + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); - return nt_status; + return NT_STATUS_ACCESS_DENIED; } - } else { - DEBUG(1, ("GSS Update failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); - return nt_status; + + if (output_token.length < 4) { + return NT_STATUS_INVALID_PARAMETER; + } + + memcpy(maxlength_proposed, output_token.value, 4); + gss_release_buffer(&min_stat, &output_token); + + /* first byte is the proposed security */ + /* TODO: We should do something with the rest, but for now... */ + security_proposed = maxlength_proposed[0]; + + maxlength_proposed[0] = 0x0; + gensec_gssapi_state->sasl_protection = 0; + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + if (security_proposed & NEG_SEAL) { + gensec_gssapi_state->sasl_protection |= NEG_SEAL; + } + } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + if (security_proposed & NEG_SIGN) { + gensec_gssapi_state->sasl_protection |= NEG_SIGN; + } + } else if (security_proposed & NEG_NONE) { + gensec_gssapi_state->sasl_protection |= NEG_NONE; + } else { + DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better")); + return NT_STATUS_ACCESS_DENIED; + } + + /* quirk: This changes the value that gensec_have_feature returns, to be that after SASL negotiation */ + gensec_gssapi_state->sasl_state = STAGE_DONE; + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(3, ("GSSAPI Connection from client will be cryptographicly sealed\n")); + } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(3, ("GSSAPI Connection from client will be cryptographicly signed\n")); + } else { + DEBUG(3, ("GSSAPI Connection from client will have no cryptographicly protection\n")); + } + + *out = data_blob(NULL, 0); + return NT_STATUS_OK; + } + default: + return NT_STATUS_INVALID_PARAMETER; } } @@ -464,6 +746,12 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, return NT_STATUS_OK; } +/* Find out the size of the signature, assuming (incorrectly) that it + * GSSAPI provides any guarantees as to it's size. + * + * This is needed by the DCE/RPC code, which uses AEAD + * (signed headers, including signature legnth and a sealed body) + */ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size) { struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; @@ -695,17 +983,31 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi return NT_STATUS_OK; } +/* Try to figure out what features we actually got on the connection */ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, uint32_t feature) { struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; if (feature & GENSEC_FEATURE_SIGN) { + /* If we are going GSSAPI SASL, then we honour the second negotiation */ + if (gensec_gssapi_state->sasl + && gensec_gssapi_state->sasl_state == STAGE_DONE) { + return ((gensec_gssapi_state->sasl_protection & NEG_SIGN) + && (gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG)); + } return gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG; } if (feature & GENSEC_FEATURE_SEAL) { + /* If we are going GSSAPI SASL, then we honour the second negotiation */ + if (gensec_gssapi_state->sasl + && gensec_gssapi_state->sasl_state == STAGE_DONE) { + return ((gensec_gssapi_state->sasl_protection & NEG_SEAL) + && (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG)); + } return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG; } 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)) { return True; @@ -714,12 +1016,19 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_DCE_STYLE) { return gensec_gssapi_state->got_flags & GSS_C_DCE_STYLE; } + /* We can always do async (rather than strict request/reply) packets. */ if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { return True; } return False; } +/* + * Extract the 'sesssion key' needed by SMB signing and ncacn_np + * (for encrypting some passwords). + * + * This breaks all the abstractions, but what do you expect... + */ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { @@ -730,7 +1039,8 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_OK; } - /* Ensure we only call this for GSSAPI/krb5, otherwise things could get very ugly */ + /* Ensure we only call this for GSSAPI/krb5, otherwise things + * could get very ugly */ 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)) { @@ -758,6 +1068,10 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_NO_USER_SESSION_KEY; } + +/* Get some basic (and authorization) information about the user on + * this session. This uses either the PAC (if present) or a local + * database lookup */ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security, struct auth_session_info **_session_info) { @@ -925,7 +1239,6 @@ static const char *gensec_gssapi_krb5_oids[] = { /* 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", - .sasl_name = "GSSAPI", .auth_type = DCERPC_AUTH_TYPE_KRB5, .oid = gensec_gssapi_krb5_oids, .client_start = gensec_gssapi_client_start, @@ -946,6 +1259,22 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .kerberos = True }; +/* As a server, this could in theory accept any GSSAPI mech */ +static const struct gensec_security_ops gensec_gssapi_sasl_krb5_security_ops = { + .name = "gssapi_krb5_sasl", + .sasl_name = "GSSAPI", + .client_start = gensec_gssapi_sasl_client_start, + .server_start = gensec_gssapi_sasl_server_start, + .update = gensec_gssapi_update, + .session_key = gensec_gssapi_session_key, + .session_info = gensec_gssapi_session_info, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature, + .enabled = True, + .kerberos = True +}; + NTSTATUS gensec_gssapi_init(void) { NTSTATUS ret; @@ -957,5 +1286,12 @@ NTSTATUS gensec_gssapi_init(void) return ret; } + ret = gensec_register(&gensec_gssapi_sasl_krb5_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_gssapi_sasl_krb5_security_ops.name)); + return ret; + } + return ret; } -- cgit From 2e7f35f88faedb5b6e2302c5dacf62709dee12a9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 11:19:09 +0000 Subject: r13344: Trust SASL to have subtle distinctions between NULL and zero-length responses... Also trust OpenLDAP to be pedantic about it, breaking connections to AD. In any case, we now get this 'right' (by nasty overloading hacks, but hey), and we can now use system-supplied OpenLDAP libs and SASL/GSSAPI to talk to Samba4. Andrew Bartlett (This used to be commit 0cbe18211a95f811b51865bc0e8729e9a302ad25) --- source4/auth/gensec/gensec_gssapi.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0b48a010eb..aaa79aa407 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -394,9 +394,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gensec_gssapi_state->input_chan_bindings, &gensec_gssapi_state->client_name, &gss_oid_p, - &output_token, - &gensec_gssapi_state->got_flags, - NULL, + &output_token, + &gensec_gssapi_state->got_flags, + NULL, &gensec_gssapi_state->delegated_cred_handle); gensec_gssapi_state->gss_oid = gss_oid_p; break; @@ -416,8 +416,22 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); } - /* We may have been invoked as SASL, so there is more work to do */ + /* We may have been invoked as SASL, so there + * is more work to do */ if (gensec_gssapi_state->sasl) { + /* Due to a very subtle interaction + * with SASL and the LDAP libs, we + * must ensure the data pointer is + * != NULL, but the length is 0. + * + * This ensures we send a 'zero + * length' (rather than NULL) response + */ + + if (!out->data) { + out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0"); + } + gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG; return NT_STATUS_MORE_PROCESSING_REQUIRED; } else { @@ -543,11 +557,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gensec_gssapi_state->sasl_state = STAGE_DONE; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(3, ("GSSAPI Connection to server will be cryptographicly sealed\n")); + DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n")); } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(3, ("GSSAPI Connection to server will be cryptographicly signed\n")); + DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n")); } else { - DEBUG(3, ("GSSAPI Connection to server will have no cryptographicly protection\n")); + DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n")); } return NT_STATUS_OK; @@ -661,11 +675,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* quirk: This changes the value that gensec_have_feature returns, to be that after SASL negotiation */ gensec_gssapi_state->sasl_state = STAGE_DONE; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(3, ("GSSAPI Connection from client will be cryptographicly sealed\n")); + DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n")); } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(3, ("GSSAPI Connection from client will be cryptographicly signed\n")); + DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n")); } else { - DEBUG(3, ("GSSAPI Connection from client will have no cryptographicly protection\n")); + DEBUG(3, ("SASL/GSSAPI Connection from client will have no cryptographicly protection\n")); } *out = data_blob(NULL, 0); -- cgit From 26421fb2dc995c4fc10195f451c4d7dce07034bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 13 Feb 2006 00:08:16 +0000 Subject: r13481: As far as I can tell, my changes in -r 12863 were dangerously untested. We do need the gsskrb5_get_initiator_subkey() routine. But we should ensure that we do always get a valid key, to prevent any segfaults. Without this code, we get a different session key compared with Win2k3, and so kerberised smb signing fails. Andrew Bartlett (This used to be commit cfd0df16b74b0432670b33c7bf26316b741b1bde) --- source4/auth/gensec/gensec_gssapi.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index aaa79aa407..eab8211525 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1058,21 +1058,22 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit 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)) { - OM_uint32 maj_stat; - krb5_keyblock *skey; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc skey; - maj_stat = gss_krb5_get_subkey(gensec_gssapi_state->gssapi_context, - &skey); + maj_stat = gsskrb5_get_initiator_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &skey); if (maj_stat == 0) { DEBUG(10, ("Got KRB5 session key of length %d\n", - (int)KRB5_KEY_LENGTH(skey))); + (int)skey.length)); gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, - KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + skey.value, skey.length); *session_key = gensec_gssapi_state->session_key; dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, skey); + gss_release_buffer(&min_stat, &skey); return NT_STATUS_OK; } return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index eab8211525..580b7a7be1 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -27,6 +27,7 @@ #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" +#include "auth/auth_sam.h" enum gensec_gssapi_sasl_state { -- cgit From e3f2414cf9e582a4e4deecc662b64a7bb2679a34 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 15:03:25 +0000 Subject: r14380: Reduce the size of structs.h (This used to be commit 1a16a6f1dfa66499af43a6b88b3ea69a6a75f1fe) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 580b7a7be1..a1f5dc118a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -27,6 +27,7 @@ #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" +#include "ldb.h" #include "auth/auth_sam.h" enum gensec_gssapi_sasl_state -- cgit From 7651d097b44bd5743e58ce67333e00133df11eda Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 15:44:40 +0000 Subject: r14383: Fix non-developer build. (This used to be commit f4de155c94b89e586640d11992953a0d5fc0716d) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a1f5dc118a..f3b5f8c119 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -27,7 +27,7 @@ #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -#include "ldb.h" +#include "lib/ldb/include/ldb.h" #include "auth/auth_sam.h" enum gensec_gssapi_sasl_state -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f3b5f8c119..8d1cef1cbd 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -25,7 +25,7 @@ #include "includes.h" #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" -#include "librpc/gen_ndr/ndr_krb5pac.h" +#include "librpc/gen_ndr/krb5pac.h" #include "auth/auth.h" #include "lib/ldb/include/ldb.h" #include "auth/auth_sam.h" -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8d1cef1cbd..c08b96083c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -29,6 +29,7 @@ #include "auth/auth.h" #include "lib/ldb/include/ldb.h" #include "auth/auth_sam.h" +#include "librpc/rpc/dcerpc.h" enum gensec_gssapi_sasl_state { -- cgit From 3fdc3cf0c224fd4ce923bb0df7e8f175356cecf2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 Mar 2006 00:50:26 +0000 Subject: r14700: Fix spelling, and change these informational messages to debug level 5. Andrew Bartlett (This used to be commit 8f96f524bfde99667410ec98087831b9c14c66e5) --- source4/auth/gensec/gensec_gssapi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c08b96083c..8f487571f3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -441,11 +441,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gensec_gssapi_state->sasl_state = STAGE_DONE; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(3, ("GSSAPI Connection will be cryptographicly sealed\n")); + DEBUG(5, ("GSSAPI Connection will be cryptographicly sealed\n")); } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(3, ("GSSAPI Connection will be cryptographicly signed\n")); + DEBUG(5, ("GSSAPI Connection will be cryptographicly signed\n")); } else { - DEBUG(3, ("GSSAPI Connection will have no cryptographicly protection\n")); + DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n")); } return NT_STATUS_OK; @@ -678,11 +678,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* quirk: This changes the value that gensec_have_feature returns, to be that after SASL negotiation */ gensec_gssapi_state->sasl_state = STAGE_DONE; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n")); + DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n")); } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n")); + DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n")); } else { - DEBUG(3, ("SASL/GSSAPI Connection from client will have no cryptographicly protection\n")); + DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n")); } *out = data_blob(NULL, 0); -- cgit From 710ea949886dd57c66dc6d397e0ea41c89736107 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 16:09:17 +0000 Subject: r15297: Move create_security_token() to samdb as it requires SAMDB (and the rest of LIBSECURITY doesn't) Make the ldb password_hash module only depend on some keys manipulation code, not full heimdal Some other dependency fixes (This used to be commit 5b3ab728edfc9cdd9eee16ad0fe6dfd4b5ced630) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8f487571f3..4cc067ffde 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -252,7 +252,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi DEBUG(2, ("Cannot do GSSAPI to an IP address\n")); return NT_STATUS_INVALID_PARAMETER; } - if (strequal(hostname, "localhost")) { + if (strcmp(hostname, "localhost") == 0) { DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 5f4d86f955d939e96ec9b81c8a9d080aab4354b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 4 May 2006 10:03:41 +0000 Subject: r15426: Implement SPNEGO as the default RPC authentication mechanism. Where this isn't supported, fallback to NTLM. Also, where we get a failure as 'logon failure', try and do a '3 tries' for the password, like we already do for CIFS. (Incomplete: needs a mapping between RPC errors and the logon failure NTSTATUS). Because we don't yet support Kerberos sign/seal to win2k3 SP1 for DCE/RPC, disable this (causing SPNEGO to negotiate NTLM) when kerberos isn't demanded. Andrew Bartlett (This used to be commit b3212d1fb91b26c1d326a289560106dffe1d2e80) --- source4/auth/gensec/gensec_gssapi.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4cc067ffde..070e83e97c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -257,6 +257,15 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } + if (((gensec_security->want_features & GENSEC_FEATURE_SIGN) + || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) + && (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) + && !lp_parm_bool(-1, "gensec_gssapi", "dce_signseal", + cli_credentials_get_kerberos_state(creds) == CRED_MUST_USE_KERBEROS)) { + DEBUG(2, ("GSSAPI sign/seal disabled for DCE/RPC. ")); + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; -- cgit From cdc64c448df49676c96f87d106af8de0c467651f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:32:17 +0000 Subject: r15853: started the process of removing the warnings now that talloc_set_destructor() is type safe. The end result will be lots less use of void*, and less calls to talloc_get_type() (This used to be commit 6b4c085b862c0932b80b93e316396a53b993544c) --- source4/auth/gensec/gensec_gssapi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 070e83e97c..270ae37703 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -95,9 +95,8 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx, } -static int gensec_gssapi_destory(void *ptr) +static int gensec_gssapi_destory(struct gensec_gssapi_state *gensec_gssapi_state) { - struct gensec_gssapi_state *gensec_gssapi_state = ptr; OM_uint32 maj_stat, min_stat; if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { -- cgit From 048d0c64f9505ad236b9bf138d10ee3e2bb08cec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Jul 2006 01:44:24 +0000 Subject: r17171: Add a gensec function to determine the maximum negotiated buffer size, and the maximum amount of user data that may be fitted into that. This is used in the new SASL code, to correctly honour SASL buffer sizes. Andrew Bartlett (This used to be commit cbbe99d9c1f0262e67a495fb098cacc09fd78e05) --- source4/auth/gensec/gensec_gssapi.c | 148 +++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 34 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 270ae37703..e8597dc73b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -67,8 +67,13 @@ struct gensec_gssapi_state { uint8_t sasl_protection; /* What was negotiated at the SASL * layer, independent of the GSSAPI * layer... */ + + size_t max_wrap_buf_size; }; +static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); +static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); + static char *gssapi_error_string(TALLOC_CTX *mem_ctx, OM_uint32 maj_stat, OM_uint32 min_stat) { @@ -129,6 +134,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) return NT_STATUS_NO_MEMORY; } + gensec_gssapi_state->max_wrap_buf_size + = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65535); + gensec_gssapi_state->sasl = False; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -490,6 +498,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, } break; } + /* These last two stages are only done if we were invoked as SASL */ case STAGE_SASL_SSF_NEG: { @@ -497,11 +506,17 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, case GENSEC_CLIENT: { uint8_t maxlength_proposed[4]; + uint8_t maxlength_accepted[4]; uint8_t security_supported; int conf_state; gss_qop_t qop_state; input_token.length = in.length; input_token.value = in.data; + + /* As a client, we have just send a + * zero-length blob to the server (after the + * normal GSSAPI exchange), and it has replied + * with it's SASL negotiation */ maj_stat = gss_unwrap(&min_stat, gensec_gssapi_state->gssapi_context, @@ -521,10 +536,14 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, memcpy(maxlength_proposed, output_token.value, 4); gss_release_buffer(&min_stat, &output_token); - + /* first byte is the proposed security */ security_supported = maxlength_proposed[0]; maxlength_proposed[0] = '\0'; + + /* Rest is the proposed max wrap length */ + gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_proposed, 0), + gensec_gssapi_state->max_wrap_buf_size); gensec_gssapi_state->sasl_protection = 0; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { if (security_supported & NEG_SEAL) { @@ -540,13 +559,15 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, DEBUG(1, ("Remote server does not support unprotected connections")); return NT_STATUS_ACCESS_DENIED; } + + /* Send back the negotiated max length */ + + RSIVAL(maxlength_accepted, 0, gensec_gssapi_state->max_wrap_buf_size); + + maxlength_accepted[0] = gensec_gssapi_state->sasl_protection; - /* We just accept their max length, and send - * it back with the SASL flags */ - maxlength_proposed[0] = gensec_gssapi_state->sasl_protection; - - input_token.value = maxlength_proposed; - input_token.length = sizeof(maxlength_proposed); + input_token.value = maxlength_accepted; + input_token.length = sizeof(maxlength_accepted); maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, @@ -583,8 +604,14 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, uint8_t security_supported = 0x0; int conf_state; - /* TODO: Need some better ideas for this */ - RSIVAL(maxlength_proposed, 0, 0xFFFFFF); + /* As a server, we have just been sent a zero-length blob (note this, but it isn't fatal) */ + if (in.length != 0) { + DEBUG(1, ("SASL/GSSAPI: client sent non-zero length starting SASL negotiation!\n")); + } + + /* Give the client some idea what we will support */ + + RSIVAL(maxlength_proposed, 0, gensec_gssapi_state->max_wrap_buf_size); /* first byte is the proposed security */ maxlength_proposed[0] = '\0'; @@ -599,11 +626,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* If we don't support anything, this must be 0 */ RSIVAL(maxlength_proposed, 0, 0x0); } - + /* TODO: We may not wish to support this */ security_supported |= NEG_NONE; - - /* Ignore 'in' */ maxlength_proposed[0] = security_supported; input_token.value = maxlength_proposed; @@ -636,8 +661,8 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* This is s server-only stage */ case STAGE_SASL_SSF_ACCEPT: { - uint8_t maxlength_proposed[4]; - uint8_t security_proposed; + uint8_t maxlength_accepted[4]; + uint8_t security_accepted; int conf_state; gss_qop_t qop_state; input_token.length = in.length; @@ -659,24 +684,27 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - memcpy(maxlength_proposed, output_token.value, 4); + memcpy(maxlength_accepted, output_token.value, 4); gss_release_buffer(&min_stat, &output_token); /* first byte is the proposed security */ - /* TODO: We should do something with the rest, but for now... */ - security_proposed = maxlength_proposed[0]; + security_accepted = maxlength_accepted[0]; + maxlength_accepted[0] = '\0'; + + /* Rest is the proposed max wrap length */ + gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0), + gensec_gssapi_state->max_wrap_buf_size); - maxlength_proposed[0] = 0x0; gensec_gssapi_state->sasl_protection = 0; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - if (security_proposed & NEG_SEAL) { + if (security_accepted & NEG_SEAL) { gensec_gssapi_state->sasl_protection |= NEG_SEAL; } } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - if (security_proposed & NEG_SIGN) { + if (security_accepted & NEG_SIGN) { gensec_gssapi_state->sasl_protection |= NEG_SIGN; } - } else if (security_proposed & NEG_NONE) { + } else if (security_accepted & NEG_NONE) { gensec_gssapi_state->sasl_protection |= NEG_NONE; } else { DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better")); @@ -712,6 +740,16 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, int conf_state; input_token.length = in->length; input_token.value = in->data; + + if (gensec_gssapi_state->sasl) { + size_t max_input_size = gensec_gssapi_max_input_size(gensec_security); + if (max_input_size < in->length) { + DEBUG(1, ("gensec_gssapi_wrap: INPUT data (%u) is larger than SASL negotiated maximum size (%u)\n", + in->length, + (unsigned int)max_input_size)); + } + return NT_STATUS_INVALID_PARAMETER; + } maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, @@ -749,6 +787,14 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, input_token.length = in->length; input_token.value = in->data; + if (gensec_gssapi_state->sasl) { + size_t max_wrapped_size = gensec_gssapi_max_wrapped_size(gensec_security); + if (max_wrapped_size < in->length) { + DEBUG(1, ("gensec_gssapi_unwrap: WRAPPED data is larger than SASL negotiated maximum size\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + maj_stat = gss_unwrap(&min_stat, gensec_gssapi_state->gssapi_context, &input_token, @@ -797,7 +843,7 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si &output_size); if (GSS_ERROR(maj_stat)) { TALLOC_CTX *mem_ctx = talloc_new(NULL); - DEBUG(1, ("gensec_gssapi_seal_packet: determinaing signature size with gss_wrap_size_limit failed: %s\n", + DEBUG(1, ("gensec_gssapi_sig_size: determinaing signature size with gsskrb5_wrap_size failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat))); talloc_free(mem_ctx); return 0; @@ -811,6 +857,38 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si return output_size - data_size; } +/* Find out the maximum input size negotiated on this connection */ + +static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + OM_uint32 maj_stat, min_stat; + OM_uint32 max_input_size; + + maj_stat = gss_wrap_size_limit(&min_stat, + gensec_gssapi_state->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + gensec_gssapi_state->max_wrap_buf_size, + &max_input_size); + if (GSS_ERROR(maj_stat)) { + TALLOC_CTX *mem_ctx = talloc_new(NULL); + DEBUG(1, ("gensec_gssapi_max_input_size: determinaing signature size with gss_wrap_size_limit failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat))); + talloc_free(mem_ctx); + return 0; + } + + return max_input_size; +} + +/* Find out the maximum output size negotiated on this connection */ +static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security) +{ + struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + return gensec_gssapi_state->max_wrap_buf_size; +} + static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, @@ -1287,18 +1365,20 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { /* As a server, this could in theory accept any GSSAPI mech */ static const struct gensec_security_ops gensec_gssapi_sasl_krb5_security_ops = { - .name = "gssapi_krb5_sasl", - .sasl_name = "GSSAPI", - .client_start = gensec_gssapi_sasl_client_start, - .server_start = gensec_gssapi_sasl_server_start, - .update = gensec_gssapi_update, - .session_key = gensec_gssapi_session_key, - .session_info = gensec_gssapi_session_info, - .wrap = gensec_gssapi_wrap, - .unwrap = gensec_gssapi_unwrap, - .have_feature = gensec_gssapi_have_feature, - .enabled = True, - .kerberos = True + .name = "gssapi_krb5_sasl", + .sasl_name = "GSSAPI", + .client_start = gensec_gssapi_sasl_client_start, + .server_start = gensec_gssapi_sasl_server_start, + .update = gensec_gssapi_update, + .session_key = gensec_gssapi_session_key, + .session_info = gensec_gssapi_session_info, + .max_input_size = gensec_gssapi_max_input_size, + .max_wrapped_size = gensec_gssapi_max_wrapped_size, + .wrap = gensec_gssapi_wrap, + .unwrap = gensec_gssapi_unwrap, + .have_feature = gensec_gssapi_have_feature, + .enabled = True, + .kerberos = True }; NTSTATUS gensec_gssapi_init(void) -- cgit From b718193b6bbf67b7677b07c0eb41364672bc69a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Jul 2006 02:05:45 +0000 Subject: r17173: Check for oversize output, not oversize input, and fix the GSSAPI mech to work (it broke it in the previous commit). Andrew Bartlett (This used to be commit e96638bc74f0752ce8af6626a04c92d48b917ffe) --- source4/auth/gensec/gensec_gssapi.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e8597dc73b..2ff52311c3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -741,16 +741,6 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, input_token.length = in->length; input_token.value = in->data; - if (gensec_gssapi_state->sasl) { - size_t max_input_size = gensec_gssapi_max_input_size(gensec_security); - if (max_input_size < in->length) { - DEBUG(1, ("gensec_gssapi_wrap: INPUT data (%u) is larger than SASL negotiated maximum size (%u)\n", - in->length, - (unsigned int)max_input_size)); - } - return NT_STATUS_INVALID_PARAMETER; - } - maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), @@ -767,6 +757,17 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); + if (gensec_gssapi_state->sasl) { + size_t max_wrapped_size = gensec_gssapi_max_wrapped_size(gensec_security); + if (max_wrapped_size < out->length) { + DEBUG(1, ("gensec_gssapi_wrap: when wrapped, INPUT data (%u) is grew to be larger than SASL negotiated maximum output size (%u > %u)\n", + in->length, + out->length, + (unsigned int)max_wrapped_size)); + return NT_STATUS_INVALID_PARAMETER; + } + } + if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) && !conf_state) { return NT_STATUS_ACCESS_DENIED; -- cgit From 582cf8c1c01e5f933c31ce82bf4504e7537da2d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Jul 2006 01:20:05 +0000 Subject: r17332: May as well make this a round number (This used to be commit a2d614147663c4f9b80d6e383819e92ca45e013b) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 2ff52311c3..f241a646cc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -135,7 +135,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65535); + = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = False; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; -- cgit From c1ec0da99cf5ee0633a43c13a39df3803c8483f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Sep 2006 06:21:02 +0000 Subject: r18257: Order the GENSEC modules, with unknown modules last. Andrew Bartlett (This used to be commit 8ae880b5019ab275fe0eca48120ab9e0fcca6293) --- source4/auth/gensec/gensec_gssapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f241a646cc..3bf14505f5 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1361,7 +1361,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, .enabled = True, - .kerberos = True + .kerberos = True, + .priority = GENSEC_GSSAPI }; /* As a server, this could in theory accept any GSSAPI mech */ @@ -1379,7 +1380,8 @@ static const struct gensec_security_ops gensec_gssapi_sasl_krb5_security_ops = { .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, .enabled = True, - .kerberos = True + .kerberos = True, + .priority = GENSEC_GSSAPI }; NTSTATUS gensec_gssapi_init(void) -- cgit From 30ee8beb9316a99e8a49993306252591106cb349 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 10:05:58 +0000 Subject: r18301: I discovered how to load the warnings from a build farm build into emacs compile mode (hint, paste to a file, and compile as "cat filename"). This allowed me to fix nearly all the warnings for a IA_64 SuSE build very quickly. (This used to be commit eba6c84efff735bb0ca941ac4b755ce2b0591667) --- source4/auth/gensec/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 3bf14505f5..d9f6edc7d7 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -761,8 +761,8 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, size_t max_wrapped_size = gensec_gssapi_max_wrapped_size(gensec_security); if (max_wrapped_size < out->length) { DEBUG(1, ("gensec_gssapi_wrap: when wrapped, INPUT data (%u) is grew to be larger than SASL negotiated maximum output size (%u > %u)\n", - in->length, - out->length, + (unsigned)in->length, + (unsigned)out->length, (unsigned int)max_wrapped_size)); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 3c203ab927b0ec793ec431199526bb218cc6e2bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 23 Oct 2006 06:08:25 +0000 Subject: r19465: Rather than use the non-standard API for determining the signature length, use the amount the wapped message expanded by. This works, because GSSAPI doesn't do AEAD (signing of headers), and so changing the signature length after the fact is valid. Andrew Bartlett (This used to be commit bd1e0f679c8f2b9755051b8d34114fa127a7cf26) --- source4/auth/gensec/gensec_gssapi.c | 63 +++++-------------------------------- 1 file changed, 8 insertions(+), 55 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index d9f6edc7d7..364c0c3499 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -818,46 +818,6 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, return NT_STATUS_OK; } -/* Find out the size of the signature, assuming (incorrectly) that it - * GSSAPI provides any guarantees as to it's size. - * - * This is needed by the DCE/RPC code, which uses AEAD - * (signed headers, including signature legnth and a sealed body) - */ -static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size) -{ - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - OM_uint32 maj_stat, min_stat; - OM_uint32 output_size; - 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)) { - DEBUG(1, ("NO sig size available for this mech\n")); - return 0; - } - - maj_stat = gsskrb5_wrap_size(&min_stat, - gensec_gssapi_state->gssapi_context, - gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), - GSS_C_QOP_DEFAULT, - data_size, - &output_size); - if (GSS_ERROR(maj_stat)) { - TALLOC_CTX *mem_ctx = talloc_new(NULL); - DEBUG(1, ("gensec_gssapi_sig_size: determinaing signature size with gsskrb5_wrap_size failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); - talloc_free(mem_ctx); - return 0; - } - - if (output_size < data_size) { - return 0; - } - - /* The difference between the max output and the max input must be the signature */ - return output_size - data_size; -} - /* Find out the maximum input size negotiated on this connection */ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security) @@ -918,14 +878,12 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit return NT_STATUS_ACCESS_DENIED; } - sig_length = gensec_gssapi_sig_size(gensec_security, length); - - /* Caller must pad to right boundary */ - if (output_token.length != (length + sig_length)) { - DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", - (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length))); + if (output_token.length < input_token.length) { + DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", + (long)output_token.length, (long)length)); return NT_STATUS_INTERNAL_ERROR; } + sig_length = output_token.length - input_token.length; memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); @@ -1021,18 +979,14 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit return NT_STATUS_ACCESS_DENIED; } - if (output_token.length < length) { + if (output_token.length < input_token.length) { + DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", + (long)output_token.length, (long)length)); return NT_STATUS_INTERNAL_ERROR; } - sig_length = gensec_gssapi_sig_size(gensec_security, length); - /* Caller must pad to right boundary */ - if (output_token.length != (length + sig_length)) { - DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", - (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length))); - return NT_STATUS_INTERNAL_ERROR; - } + sig_length = output_token.length - input_token.length; *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); @@ -1352,7 +1306,6 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .update = gensec_gssapi_update, .session_key = gensec_gssapi_session_key, .session_info = gensec_gssapi_session_info, - .sig_size = gensec_gssapi_sig_size, .sign_packet = gensec_gssapi_sign_packet, .check_packet = gensec_gssapi_check_packet, .seal_packet = gensec_gssapi_seal_packet, -- cgit From c755bb5025ee60ae41de9cc32d3fa54e3671941d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:47:36 +0000 Subject: r19597: Ahead of the merge to current lorikeet-heimdal: Supply the correct OID to the error display functions. Rework the session key functions. Andrew Bartlett (This used to be commit 363628c13f4e4a8904802dcf4d80e296ed2f9e02) --- source4/auth/gensec/gensec_gssapi.c | 126 +++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 59 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 364c0c3499..ed407b623b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -24,12 +24,16 @@ #include "includes.h" #include "system/kerberos.h" +#include "heimdal/lib/gssapi/gssapi.h" #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/krb5pac.h" #include "auth/auth.h" #include "lib/ldb/include/ldb.h" #include "auth/auth_sam.h" #include "librpc/rpc/dcerpc.h" +#include "auth/credentials/credentials.h" +#include "auth/credentials/credentials_krb5.h" +#include "auth/gensec/gensec.h" enum gensec_gssapi_sasl_state { @@ -75,7 +79,8 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); static char *gssapi_error_string(TALLOC_CTX *mem_ctx, - OM_uint32 maj_stat, OM_uint32 min_stat) + OM_uint32 maj_stat, OM_uint32 min_stat, + const gss_OID_desc *mech) { OM_uint32 disp_min_stat, disp_maj_stat; gss_buffer_desc maj_error_message; @@ -88,9 +93,9 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx, min_error_message.value = NULL; disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &maj_error_message); + mech, &msg_ctx, &maj_error_message); disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &min_error_message); + mech, &msg_ctx, &min_error_message); ret = talloc_asprintf(mem_ctx, "%s: %s", (char *)maj_error_message.value, (char *)min_error_message.value); gss_release_buffer(&disp_min_stat, &maj_error_message); @@ -304,7 +309,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi if (maj_stat) { DEBUG(2, ("GSS Import name of %s failed: %s\n", (char *)name_token.value, - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_INVALID_PARAMETER; } @@ -374,7 +379,8 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; OM_uint32 maj_stat, min_stat; OM_uint32 min_stat2; @@ -477,23 +483,23 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, switch (min_stat) { case KRB5_KDC_UNREACH: DEBUG(3, ("Cannot reach a KDC we require: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: DEBUG(3, ("Server is not registered with our KDC: %s\n", - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat))); + gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ case KRB5KRB_AP_ERR_MSG_TYPE: /* garbage input, possibly from the auto-mech detection */ return NT_STATUS_INVALID_PARAMETER; default: DEBUG(1, ("GSS(krb5) Update failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return nt_status; } } else { DEBUG(1, ("GSS Update failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return nt_status; } break; @@ -526,7 +532,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -578,7 +584,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -643,7 +649,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -676,7 +682,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", - gssapi_error_string(out_mem_ctx, maj_stat, min_stat))); + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -734,7 +740,8 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, const DATA_BLOB *in, DATA_BLOB *out) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -750,7 +757,7 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -780,7 +787,8 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, const DATA_BLOB *in, DATA_BLOB *out) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -804,7 +812,7 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_unwrap: GSS UnWrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -822,7 +830,8 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; OM_uint32 max_input_size; @@ -835,7 +844,7 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi if (GSS_ERROR(maj_stat)) { TALLOC_CTX *mem_ctx = talloc_new(NULL); DEBUG(1, ("gensec_gssapi_max_input_size: determinaing signature size with gss_wrap_size_limit failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); talloc_free(mem_ctx); return 0; } @@ -846,7 +855,7 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi /* Find out the maximum output size negotiated on this connection */ static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);; return gensec_gssapi_state->max_wrap_buf_size; } @@ -856,7 +865,8 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -874,7 +884,7 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -907,7 +917,8 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -932,7 +943,7 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -957,7 +968,8 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -975,7 +987,7 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("GSS Wrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -1003,7 +1015,8 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; int conf_state; @@ -1028,7 +1041,7 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("GSS UnWrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat))); + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -1045,7 +1058,8 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, uint32_t feature) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); if (feature & GENSEC_FEATURE_SIGN) { /* If we are going GSSAPI SASL, then we honour the second negotiation */ if (gensec_gssapi_state->sasl @@ -1090,43 +1104,34 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; - + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + OM_uint32 maj_stat, min_stat; + krb5_keyblock *subkey; + if (gensec_gssapi_state->session_key.data) { *session_key = gensec_gssapi_state->session_key; return NT_STATUS_OK; } - /* Ensure we only call this for GSSAPI/krb5, otherwise things - * could get very ugly */ - 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)) { - OM_uint32 maj_stat, min_stat; - gss_buffer_desc skey; - - maj_stat = gsskrb5_get_initiator_subkey(&min_stat, - gensec_gssapi_state->gssapi_context, - &skey); - - if (maj_stat == 0) { - DEBUG(10, ("Got KRB5 session key of length %d\n", - (int)skey.length)); - gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, - skey.value, skey.length); - *session_key = gensec_gssapi_state->session_key; - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); - - gss_release_buffer(&min_stat, &skey); - return NT_STATUS_OK; - } + maj_stat = gsskrb5_get_initiator_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &subkey); + if (maj_stat != 0) { + DEBUG(1, ("NO session key for this mech\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - DEBUG(1, ("NO session key for this mech\n")); - return NT_STATUS_NO_USER_SESSION_KEY; -} + DEBUG(10, ("Got KRB5 session key of length %d\n", + (int)KRB5_KEY_LENGTH(subkey))); + gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, + KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey)); + krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey); + *session_key = gensec_gssapi_state->session_key; + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + return NT_STATUS_OK; +} /* Get some basic (and authorization) information about the user on * this session. This uses either the PAC (if present) or a local @@ -1136,7 +1141,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi { NTSTATUS nt_status; TALLOC_CTX *mem_ctx; - struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data; + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; @@ -1163,7 +1169,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gensec_gssapi_state->client_name, &name_token, NULL); - if (maj_stat) { + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("GSS display_name failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); talloc_free(mem_ctx); return NT_STATUS_FOOBAR; } -- cgit From 3c1e780ec7e16dc6667402bbc65708bf9a5c062f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 06:59:56 +0000 Subject: r19604: This is a massive commit, and I appologise in advance for it's size. This merges Samba4 with lorikeet-heimdal, which itself has been tracking Heimdal CVS for the past couple of weeks. This is such a big change because Heimdal reorganised it's internal structures, with the mechglue merge, and because many of our 'wishes' have been granted: we now have DCE_STYLE GSSAPI, send_to_kdc hooks and many other features merged into the mainline code. We have adapted to upstream's choice of API in these cases. In gensec_gssapi and gensec_krb5, we either expect a valid PAC, or NO PAC. This matches windows behavour. We also have an option to require the PAC to be present (which allows us to automate the testing of this code). This also includes a restructure of how the kerberos dependencies are handled, due to the fallout of the merge. Andrew Bartlett (This used to be commit 4826f1735197c2a471d771495e6d4c1051b4c471) --- source4/auth/gensec/gensec_gssapi.c | 127 +++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 44 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index ed407b623b..136962d892 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -24,7 +24,7 @@ #include "includes.h" #include "system/kerberos.h" -#include "heimdal/lib/gssapi/gssapi.h" +#include "heimdal/lib/gssapi/gssapi/gssapi.h" #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/krb5pac.h" #include "auth/auth.h" @@ -73,6 +73,7 @@ struct gensec_gssapi_state { * layer... */ size_t max_wrap_buf_size; + int gss_exchange_count; }; static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); @@ -133,12 +134,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; krb5_error_code ret; - + struct gsskrb5_send_to_kdc send_to_kdc; + gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state); if (!gensec_gssapi_state) { return NT_STATUS_NO_MEMORY; } + gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65536); @@ -186,10 +189,18 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_oid = gss_mech_krb5; + send_to_kdc.func = smb_krb5_send_and_recv_func; + send_to_kdc.ptr = gensec_security->event_ctx; + + ret = gsskrb5_set_send_to_kdc(&send_to_kdc); + if (ret) { + DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); + return NT_STATUS_INTERNAL_ERROR; + } ret = smb_krb5_init_context(gensec_gssapi_state, &gensec_gssapi_state->smb_krb5_context); if (ret) { - DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", + DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); return NT_STATUS_INTERNAL_ERROR; } @@ -431,6 +442,8 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, } + gensec_gssapi_state->gss_exchange_count++; + if (maj_stat == GSS_S_COMPLETE) { *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat2, &output_token); @@ -493,12 +506,14 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* garbage input, possibly from the auto-mech detection */ return NT_STATUS_INVALID_PARAMETER; default: - DEBUG(1, ("GSS(krb5) Update failed: %s\n", + DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n", + gensec_gssapi_state->gss_exchange_count, gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return nt_status; } } else { - DEBUG(1, ("GSS Update failed: %s\n", + DEBUG(1, ("GSS Update(%d) failed: %s\n", + gensec_gssapi_state->gss_exchange_count, gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return nt_status; } @@ -583,7 +598,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", + DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -648,7 +663,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", + DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } @@ -1185,38 +1200,57 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } - maj_stat = gss_krb5_copy_service_keyblock(&min_stat, - gensec_gssapi_state->gssapi_context, - &keyblock); - - if (maj_stat == 0) { - maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - &authtime); - } - - if (maj_stat == 0) { - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_WIN2K_PAC, - &pac); - } - + maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + KRB5_AUTHDATA_WIN2K_PAC, + &pac); + + if (maj_stat == 0) { pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); gss_release_buffer(&min_stat, &pac); + + } else { + pac_blob = data_blob(NULL, 0); } /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ - if (maj_stat == 0) { + if (pac_blob.length) { krb5_error_code ret; + union netr_Validation validation; - ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context, - principal_string, &principal); + maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, + gensec_gssapi_state->gssapi_context, + &authtime); + + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gsskrb5_extract_authtime_from_sec_context: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + talloc_free(mem_ctx); + return NT_STATUS_FOOBAR; + } + + maj_stat = gsskrb5_extract_service_keyblock(&min_stat, + gensec_gssapi_state->gssapi_context, + &keyblock); + + if (GSS_ERROR(maj_stat)) { + DEBUG(1, ("gsskrb5_copy_service_keyblock failed: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + talloc_free(mem_ctx); + return NT_STATUS_FOOBAR; + } + + ret = krb5_parse_name_flags(gensec_gssapi_state->smb_krb5_context->krb5_context, + principal_string, + KRB5_PRINCIPAL_PARSE_MUST_REALM, + &principal); if (ret) { + krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, + keyblock); talloc_free(mem_ctx); return NT_STATUS_INVALID_PARAMETER; } @@ -1226,25 +1260,25 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock, principal, authtime, NULL); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); + krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, + keyblock); - if (NT_STATUS_IS_OK(nt_status)) { - union netr_Validation validation; - validation.sam3 = &logon_info->info3; - nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, - NULL, - 3, &validation, - &server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - } else { - maj_stat = 1; + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; } - } - - if (maj_stat) { - DEBUG(1, ("Unable to use PAC, resorting to local user lookup!\n")); + validation.sam3 = &logon_info->info3; + nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, + NULL, + 3, &validation, + &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + } else if (!lp_parm_bool(-1, "gensec", "require_pac", False)) { + DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); nt_status = sam_get_server_info_principal(mem_ctx, principal_string, &server_info); @@ -1252,6 +1286,11 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi talloc_free(mem_ctx); return nt_status; } + } else { + DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n", + principal_string, + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + return NT_STATUS_ACCESS_DENIED; } /* references the server_info into the session_info */ -- cgit From a77b25cea7f95584a05f3f6e81564fcbd8e1e3a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 21:05:45 +0000 Subject: r19628: This hint via Love at the IETF meeting: Larry told me that most context flags needed to be set to, otherwise it wouldn't work. This fixes DCE_STYLE against Win2k3 SP1. It seems they just tightened up their end of the GSSAPI code, as DCE_STYLE is explicity rejected in the session setup too (being the wrong layer). Andrew Bartlett (This used to be commit b2b77f34a4d0cebb828cac7bf9a73826fecab5b6) --- source4/auth/gensec/gensec_gssapi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 136962d892..39d90546f6 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -164,6 +164,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) if (lp_parm_bool(-1, "gensec_gssapi", "delegation", True)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } + if (lp_parm_bool(-1, "gensec_gssapi", "replay", True)) { + gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; + } if (lp_parm_bool(-1, "gensec_gssapi", "sequence", True)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } -- cgit From daa463070c12332938677136fa0f8ccf82853f71 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 21:08:33 +0000 Subject: r19629: No need to special case use of DCE_STYLE sign and seal away any more... Andrew Bartlett (This used to be commit 247b9f1ca907cf921087e6840400ddf68289b8f2) --- source4/auth/gensec/gensec_gssapi.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 39d90546f6..9f796dc9d1 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -283,15 +283,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - if (((gensec_security->want_features & GENSEC_FEATURE_SIGN) - || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) - && (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) - && !lp_parm_bool(-1, "gensec_gssapi", "dce_signseal", - cli_credentials_get_kerberos_state(creds) == CRED_MUST_USE_KERBEROS)) { - DEBUG(2, ("GSSAPI sign/seal disabled for DCE/RPC. ")); - return NT_STATUS_INVALID_PARAMETER; - } - nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; -- cgit From f722b0743811a4a5caf5288fa901cc8f683b9ffd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Nov 2006 01:48:35 +0000 Subject: r19633: Merge to lorikeet-heimdal, removing krb5_rd_req_return_keyblock in favour of a more tasteful replacement. Remove kerberos_verify.c, as we don't need that code any more. Replace with code for using the new krb5_rd_req_ctx() borrowed from Heimdal's accecpt_sec_context.c Andrew Bartlett (This used to be commit 13c9df1d4f0517468c80040d3756310d4dcbdd50) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 9f796dc9d1..7094692fb2 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1123,9 +1123,9 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_OK; } - maj_stat = gsskrb5_get_initiator_subkey(&min_stat, - gensec_gssapi_state->gssapi_context, - &subkey); + maj_stat = gsskrb5_get_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &subkey); if (maj_stat != 0) { DEBUG(1, ("NO session key for this mech\n")); return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From cb3a884048f7ae5e3c25a4b2abe7ff57283cc0e6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Nov 2006 04:54:56 +0000 Subject: r19635: It appears that under CFX, different keys are used in each direction (or something like that). In any case, we need to stick with the initiator subkey for now, until we figure out what Vista uses for the CIFS session key. Andrew Bartlett (This used to be commit b91a921e1393581ca0102ad1f49a1075acb91b4e) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 7094692fb2..9f796dc9d1 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1123,9 +1123,9 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_OK; } - maj_stat = gsskrb5_get_subkey(&min_stat, - gensec_gssapi_state->gssapi_context, - &subkey); + maj_stat = gsskrb5_get_initiator_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &subkey); if (maj_stat != 0) { DEBUG(1, ("NO session key for this mech\n")); return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From ed77e4e57beee0c9c8b0c4c75626c41ebfc5b0c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 9 Nov 2006 00:33:43 +0000 Subject: r19644: Merge up to current lorikeet-heimdal, incling adding gsskrb5_set_default_realm(), which should fix mimir's issues. Andrew Bartlett (This used to be commit 8117e76d2adee163925a29df872015ff5021a1d3) --- source4/auth/gensec/gensec_gssapi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 9f796dc9d1..8e40973e4a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -198,13 +198,31 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) ret = gsskrb5_set_send_to_kdc(&send_to_kdc); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); + talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } + if (lp_realm() && *lp_realm()) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm()); + if (!upper_realm) { + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm())); + talloc_free(gensec_gssapi_state); + return NT_STATUS_NO_MEMORY; + } + ret = gsskrb5_set_default_realm(upper_realm); + talloc_free(upper_realm); + if (ret) { + DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n")); + talloc_free(gensec_gssapi_state); + return NT_STATUS_INTERNAL_ERROR; + } + } + ret = smb_krb5_init_context(gensec_gssapi_state, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", error_message(ret))); + talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } return NT_STATUS_OK; -- cgit From e5974a1b5f736cf61146e82a33f65540289926a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 10 Nov 2006 02:44:38 +0000 Subject: 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) --- source4/auth/gensec/gensec_gssapi.c | 58 +++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 9 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') 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", -- cgit From 47b7419fa7b040764209353af45af868ff75a211 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Nov 2006 03:41:50 +0000 Subject: r19660: Forgot to tell gsskrb5 not to canonicalize hostnames. Shoudl fix valrind issues on fort, because we won't hit NSS any more. Andrew Bartlett (This used to be commit 6f67fa01ab4f946c9a9aae0d4e8d028153873e04) --- source4/auth/gensec/gensec_gssapi.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e17eaa096f..8140cfa44b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -217,6 +217,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } } + /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ + ret = gsskrb5_set_dns_canonicalize(FALSE); + if (ret) { + DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); + talloc_free(gensec_gssapi_state); + return NT_STATUS_INTERNAL_ERROR; + } + ret = smb_krb5_init_context(gensec_gssapi_state, &gensec_gssapi_state->smb_krb5_context); if (ret) { -- cgit From 78ea6370bffbd31b198e17cfcc826a54eb82387e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Dec 2006 16:45:31 +0000 Subject: r20108: match w2k3 and send 1.2.840.48018.1.2.2 before 1.2.840.113554.1.2.2 to work better against w2k, so we don't get redirected from 1.2.840.113554.1.2.2 to 1.2.840.48018.1.2.2 by a w2k server, causing 2 additional auth roundtrips. metze (This used to be commit fa5c942ee99d3b5779598aa75f71d0317ba3f622) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8140cfa44b..3ce64be564 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1361,8 +1361,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } static const char *gensec_gssapi_krb5_oids[] = { - GENSEC_OID_KERBEROS5, GENSEC_OID_KERBEROS5_OLD, + GENSEC_OID_KERBEROS5, NULL }; -- cgit From a88ac66d989b5a852fa73a1848a3f17de31e83cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Apr 2007 13:36:49 +0000 Subject: r22199: fix typo metze (This used to be commit 4e8f844be939a6e11a3bece4e7e66534fce00cc0) --- source4/auth/gensec/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 3ce64be564..a59aa8a07c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -106,7 +106,7 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx, } -static int gensec_gssapi_destory(struct gensec_gssapi_state *gensec_gssapi_state) +static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { OM_uint32 maj_stat, min_stat; @@ -178,7 +178,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; - talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); + talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; -- cgit From 2bedec23eeeed0ef7559fad927be9d70df71538a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Apr 2007 05:37:08 +0000 Subject: r22208: Print the target principal name, to help with kdc unreachable errors. Andrew Bartlett (This used to be commit bbde5b6a2f85f22110d6840857eaceb6b923c1b4) --- source4/auth/gensec/gensec_gssapi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a59aa8a07c..11f94b7708 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -320,20 +320,17 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi principal = gensec_get_target_principal(gensec_security); if (principal && lp_client_use_spnego_principal()) { - name_token.value = discard_const_p(uint8_t, principal); - name_token.length = strlen(principal); - name_type = GSS_C_NULL_OID; } else { principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", gensec_get_target_service(gensec_security), hostname); - name_token.value = discard_const_p(uint8_t, principal); - name_token.length = strlen(principal); - name_type = GSS_C_NT_HOSTBASED_SERVICE; } + name_token.value = discard_const_p(uint8_t, principal); + name_token.length = strlen(principal); + maj_stat = gss_import_name (&min_stat, &name_token, @@ -351,7 +348,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi case 0: break; case KRB5_KDC_UNREACH: - DEBUG(3, ("Cannot reach a KDC we require\n")); + DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ default: DEBUG(1, ("Aquiring initiator credentails failed\n")); -- cgit From d7fe1f182b042696c39df6a36d5e0af72be4e48f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 17 Apr 2007 03:49:46 +0000 Subject: r22294: Lock the delegated credentials to being kerberos only, we just don't have the data for anything else. Andrew Bartlett (This used to be commit 9e0c0cd0ff678388436430bb1ba4eb7595cbefbd) --- source4/auth/gensec/gensec_gssapi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 11f94b7708..82a79e1945 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1339,6 +1339,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } cli_credentials_set_conf(session_info->credentials); + /* Just so we don't segfault trying to get at a username */ + cli_credentials_set_anonymous(session_info->credentials); ret = cli_credentials_set_client_gss_creds(session_info->credentials, gensec_gssapi_state->delegated_cred_handle, @@ -1347,6 +1349,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } + + /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */ + cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS); + /* It has been taken from this place... */ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; } -- cgit From 798398950864fd780b7b70f80cce2b2e73aa0349 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 May 2007 09:54:06 +0000 Subject: r22635: make it possible to not turn off dns canonicalization of hostnames with krb5:set_dns_canonicalize=yes needed for the drsuapi replication, but we should fix this with a kdc locator plugin ... metze (This used to be commit f0a12355bcfab47663e62f3d8ae820815210cdc5) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 82a79e1945..86e988e4cb 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -218,7 +218,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(FALSE); + ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(-1, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); -- cgit From 1a7b2513191fc1b29ccdbf23fca693b41a0d446a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 May 2007 05:44:51 +0000 Subject: r22966: Make sure to return LOGON_FAILURE if the user's kerberos password is incorrect. Andrew Bartlett (This used to be commit 9dc6f36e43170bc5bf4f94d893b5a3689460d237) --- source4/auth/gensec/gensec_gssapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 86e988e4cb..4dd5905480 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -347,6 +347,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi switch (ret) { case 0: break; + case KRB5KDC_ERR_PREAUTH_FAILED: + return NT_STATUS_LOGON_FAILURE; case KRB5_KDC_UNREACH: DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ -- cgit From c42219d7352bd2e7a6413f7ae1cd0fd5cded1d95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 May 2007 08:47:04 +0000 Subject: r22969: fix some more places where we could end up with more than one event context. We now have an event context on the torture_context, and we can also get one from the cli_credentials structure (This used to be commit c0f65eb6562e13530337c23e3447a6aa6eb8fc17) --- source4/auth/gensec/gensec_gssapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4dd5905480..b8040df7eb 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "lib/events/events.h" #include "system/kerberos.h" #include "heimdal/lib/gssapi/gssapi/gssapi.h" #include "auth/kerberos/kerberos.h" @@ -226,6 +227,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } ret = smb_krb5_init_context(gensec_gssapi_state, + gensec_security->event_ctx, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", -- cgit From 6d52f4a63f89f771707cd617a19b4162dabbd88a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 May 2007 08:44:33 +0000 Subject: r23136: Set the event context onto the credentials in more places. This helps ensure that the kerberos code uses the right event context. Andrew Bartlett (This used to be commit cbdce358ae8f86c9b76a50537b931e56b07ee213) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b8040df7eb..5596949eda 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1342,6 +1342,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } + cli_credentials_set_event_context(session_info->credentials, gensec_security->event_ctx); cli_credentials_set_conf(session_info->credentials); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); -- cgit From f7110d928afd61cee203d07fd85968af993a327f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Jun 2007 05:14:00 +0000 Subject: r23455: These buffers may not be null terminated. Ensure we don't run past the end of teh buffer printing the error strings. Andrew Bartlett (This used to be commit 37e7070ca92e2f48fa02f7fd6736e5b26520f559) --- source4/auth/gensec/gensec_gssapi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 5596949eda..8a629405da 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -87,18 +87,29 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx, OM_uint32 disp_min_stat, disp_maj_stat; gss_buffer_desc maj_error_message; gss_buffer_desc min_error_message; + char *maj_error_string, *min_error_string; OM_uint32 msg_ctx = 0; char *ret; maj_error_message.value = NULL; min_error_message.value = NULL; + maj_error_message.length = 0; + min_error_message.length = 0; disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, mech, &msg_ctx, &maj_error_message); disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, mech, &msg_ctx, &min_error_message); - ret = talloc_asprintf(mem_ctx, "%s: %s", (char *)maj_error_message.value, (char *)min_error_message.value); + + maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length); + + min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length); + + ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string); + + talloc_free(maj_error_string); + talloc_free(min_error_string); gss_release_buffer(&disp_min_stat, &maj_error_message); gss_release_buffer(&disp_min_stat, &min_error_message); -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/auth/gensec/gensec_gssapi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8a629405da..a9076845ba 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 233e4f72d63e074692662ac4f6a523ad8a893c57 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 9 Aug 2007 06:26:19 +0000 Subject: r24282: Try to fix the occasional Samba4 crash in BASE-BENCH-READWRITE, as seen in particular on opi. This looked like a Heimdal problem, but I think it was simply that we didn't do a talloc_reference() to keep tabs on the memory we were using, and in between obtaining the pointer and using it, it was assigned to unrelated memory. Andrew Bartlett (This used to be commit a650ad8b37d58ba64458a33313714d1abfc4850b) --- source4/auth/gensec/gensec_gssapi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a9076845ba..3c66a032d5 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -370,7 +370,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi } gensec_gssapi_state->client_cred = gcc; - + if (!talloc_reference(gensec_gssapi_state, gcc)) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; } -- cgit From 959915a8cbea0c598ef1f29ce666329a521ef2f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:35:18 +0000 Subject: r25001: Fix more C++ and other warnings, fix some of the indentation with ts=4 lines that I accidently added earlier. (This used to be commit 0bcb21ed740fcec0f48ad36bbc2deee2948e8fc7) --- source4/auth/gensec/gensec_gssapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 3c66a032d5..dd9f19ac43 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1229,7 +1229,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_FOOBAR; } - principal_string = talloc_strndup(mem_ctx, name_token.value, name_token.length); + principal_string = talloc_strndup(mem_ctx, + (const char *)name_token.value, + name_token.length); gss_release_buffer(&min_stat, &name_token); -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index dd9f19ac43..a3351f75a8 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -34,6 +34,7 @@ #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" #include "auth/gensec/gensec.h" +#include "param/param.h" enum gensec_gssapi_sasl_state { -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/auth/gensec/gensec_gssapi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a3351f75a8..8a7e8090eb 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -155,7 +155,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65536); + = lp_parm_int(NULL, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = False; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -170,16 +170,16 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; gensec_gssapi_state->want_flags = 0; - if (lp_parm_bool(-1, "gensec_gssapi", "mutual", True)) { + if (lp_parm_bool(NULL, "gensec_gssapi", "mutual", true)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(-1, "gensec_gssapi", "delegation", True)) { + if (lp_parm_bool(NULL, "gensec_gssapi", "delegation", true)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } - if (lp_parm_bool(-1, "gensec_gssapi", "replay", True)) { + if (lp_parm_bool(NULL, "gensec_gssapi", "replay", true)) { gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; } - if (lp_parm_bool(-1, "gensec_gssapi", "sequence", True)) { + if (lp_parm_bool(NULL, "gensec_gssapi", "sequence", true)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } @@ -230,7 +230,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(-1, "krb5", "set_dns_canonicalize", false)); + ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(NULL, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); @@ -1317,7 +1317,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi talloc_free(mem_ctx); return nt_status; } - } else if (!lp_parm_bool(-1, "gensec", "require_pac", False)) { + } else if (!lp_parm_bool(NULL, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); nt_status = sam_get_server_info_principal(mem_ctx, principal_string, -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/auth/gensec/gensec_gssapi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8a7e8090eb..69e87cf555 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -213,10 +213,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } - if (lp_realm() && *lp_realm()) { - char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm()); + if (lp_realm(global_loadparm) && *lp_realm(global_loadparm)) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(global_loadparm)); if (!upper_realm) { - DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm())); + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(global_loadparm))); talloc_free(gensec_gssapi_state); return NT_STATUS_NO_MEMORY; } @@ -332,7 +332,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state->gss_oid = gss_mech_krb5; principal = gensec_get_target_principal(gensec_security); - if (principal && lp_client_use_spnego_principal()) { + if (principal && lp_client_use_spnego_principal(global_loadparm)) { name_type = GSS_C_NULL_OID; } else { principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", @@ -1359,7 +1359,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } cli_credentials_set_event_context(session_info->credentials, gensec_security->event_ctx); - cli_credentials_set_conf(session_info->credentials); + cli_credentials_set_conf(session_info->credentials, global_loadparm); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); -- cgit From 60a1046c5c5783799bd64fe18e03534670f83d82 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Sep 2007 18:00:19 +0000 Subject: r25430: Add the loadparm context to all parametric options. (This used to be commit fd697d77c9fe67a00939a1f04b35c451316fff58) --- source4/auth/gensec/gensec_gssapi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 69e87cf555..f83da1db63 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -155,7 +155,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(NULL, "gensec_gssapi", "max wrap buf size", 65536); + = lp_parm_int(global_loadparm, NULL, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = False; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -170,16 +170,16 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; gensec_gssapi_state->want_flags = 0; - if (lp_parm_bool(NULL, "gensec_gssapi", "mutual", true)) { + if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "mutual", true)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(NULL, "gensec_gssapi", "delegation", true)) { + if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "delegation", true)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } - if (lp_parm_bool(NULL, "gensec_gssapi", "replay", true)) { + if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "replay", true)) { gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; } - if (lp_parm_bool(NULL, "gensec_gssapi", "sequence", true)) { + if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "sequence", true)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } @@ -230,7 +230,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(NULL, "krb5", "set_dns_canonicalize", false)); + ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(global_loadparm, NULL, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); @@ -1317,7 +1317,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi talloc_free(mem_ctx); return nt_status; } - } else if (!lp_parm_bool(NULL, "gensec", "require_pac", false)) { + } else if (!lp_parm_bool(global_loadparm, NULL, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); nt_status = sam_get_server_info_principal(mem_ctx, principal_string, -- cgit From 3642f3b40d755209a843745f160a9d7962a6deca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:16:19 +0000 Subject: r25552: Convert to standard bool type. (This used to be commit b8d6b82f1248d36a0aa91a1c58d06b4f7c66d245) --- source4/auth/gensec/gensec_gssapi.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f83da1db63..dceb10e7b6 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -65,7 +65,7 @@ struct gensec_gssapi_state { gss_cred_id_t delegated_cred_handle; - BOOL sasl; /* We have two different mechs in this file: One + bool sasl; /* We have two different mechs in this file: One * for SASL wrapped GSSAPI and another for normal * GSSAPI */ enum gensec_gssapi_sasl_state sasl_state; @@ -157,7 +157,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->max_wrap_buf_size = lp_parm_int(global_loadparm, NULL, "gensec_gssapi", "max wrap buf size", 65536); - gensec_gssapi_state->sasl = False; + gensec_gssapi_state->sasl = false; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; gensec_security->private_data = gensec_gssapi_state; @@ -291,7 +291,7 @@ static NTSTATUS gensec_gssapi_sasl_server_start(struct gensec_security *gensec_s if (NT_STATUS_IS_OK(nt_status)) { gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - gensec_gssapi_state->sasl = True; + gensec_gssapi_state->sasl = true; } return nt_status; } @@ -386,7 +386,7 @@ static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_s if (NT_STATUS_IS_OK(nt_status)) { gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - gensec_gssapi_state->sasl = True; + gensec_gssapi_state->sasl = true; } return nt_status; } @@ -632,7 +632,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, - False, + false, GSS_C_QOP_DEFAULT, &input_token, &conf_state, @@ -697,7 +697,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, - False, + false, GSS_C_QOP_DEFAULT, &input_token, &conf_state, @@ -1110,7 +1110,7 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi } /* Try to figure out what features we actually got on the connection */ -static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, +static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, uint32_t feature) { struct gensec_gssapi_state *gensec_gssapi_state @@ -1136,7 +1136,7 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_SESSION_KEY) { /* Only for GSSAPI/Krb5 */ if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { - return True; + return true; } } if (feature & GENSEC_FEATURE_DCE_STYLE) { @@ -1144,9 +1144,9 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security, } /* We can always do async (rather than strict request/reply) packets. */ if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { - return True; + return true; } - return False; + return false; } /* @@ -1414,8 +1414,8 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .enabled = False, - .kerberos = True, + .enabled = false, + .kerberos = true, .priority = GENSEC_GSSAPI }; @@ -1437,8 +1437,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .enabled = True, - .kerberos = True, + .enabled = true, + .kerberos = true, .priority = GENSEC_GSSAPI }; @@ -1456,8 +1456,8 @@ static const struct gensec_security_ops gensec_gssapi_sasl_krb5_security_ops = { .wrap = gensec_gssapi_wrap, .unwrap = gensec_gssapi_unwrap, .have_feature = gensec_gssapi_have_feature, - .enabled = True, - .kerberos = True, + .enabled = true, + .kerberos = true, .priority = GENSEC_GSSAPI }; -- cgit From fface33dd731a711688b56593bb703c38090e782 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 19:31:14 +0100 Subject: r26231: Spell check: credentails -> credentials. (This used to be commit 4b46888bd0195ab12190f76868719fc018baafd6) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index dceb10e7b6..98d8a40672 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -366,7 +366,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ default: - DEBUG(1, ("Aquiring initiator credentails failed\n")); + DEBUG(1, ("Aquiring initiator credentials failed\n")); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 120ecdb5cb7dbd7c650f3e9fbcefb925f695e0f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 20:56:26 +0100 Subject: r26233: Pass loadparm context when creating krb5 contexts. (This used to be commit 7780bf285fdfc30f89409d0436bad0d4b6de5cd4) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 98d8a40672..fabdfb4308 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -239,6 +239,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) ret = smb_krb5_init_context(gensec_gssapi_state, gensec_security->event_ctx, + global_loadparm, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", -- cgit From 7e298580e06a5b9a0c1210937af47f277849080e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 21:14:16 +0100 Subject: r26234: More global_loadparm fixes. (This used to be commit 84892d030de6266fc0f3a699cade960dd5dc37bc) --- source4/auth/gensec/gensec_gssapi.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index fabdfb4308..fd6ca1a336 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -142,7 +142,8 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st return 0; } -static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, + struct loadparm_context *lp_ctx) { struct gensec_gssapi_state *gensec_gssapi_state; krb5_error_code ret; @@ -155,7 +156,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(global_loadparm, NULL, "gensec_gssapi", "max wrap buf size", 65536); + = lp_parm_int(lp_ctx, NULL, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = false; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -170,16 +171,16 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; gensec_gssapi_state->want_flags = 0; - if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "mutual", true)) { + if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "mutual", true)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "delegation", true)) { + if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "delegation", true)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } - if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "replay", true)) { + if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "replay", true)) { gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; } - if (lp_parm_bool(global_loadparm, NULL, "gensec_gssapi", "sequence", true)) { + if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "sequence", true)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } @@ -213,10 +214,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } - if (lp_realm(global_loadparm) && *lp_realm(global_loadparm)) { - char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(global_loadparm)); + if (lp_realm(lp_ctx) && *lp_realm(lp_ctx)) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(lp_ctx)); if (!upper_realm) { - DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(global_loadparm))); + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(lp_ctx))); talloc_free(gensec_gssapi_state); return NT_STATUS_NO_MEMORY; } @@ -230,7 +231,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(global_loadparm, NULL, "krb5", "set_dns_canonicalize", false)); + ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); @@ -239,7 +240,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) ret = smb_krb5_init_context(gensec_gssapi_state, gensec_security->event_ctx, - global_loadparm, + lp_ctx, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", @@ -258,7 +259,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi struct cli_credentials *machine_account; struct gssapi_creds_container *gcc; - nt_status = gensec_gssapi_start(gensec_security); + nt_status = gensec_gssapi_start(gensec_security, global_loadparm); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -323,7 +324,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_gssapi_start(gensec_security); + nt_status = gensec_gssapi_start(gensec_security, global_loadparm); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- cgit From 43696d2752e2faad34fb3ed2a7dbf01d40ffdc46 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 15:53:28 +0100 Subject: r26252: Specify loadparm_context explicitly when creating sessions. (This used to be commit 7280c1e9415daabb2712db1372e23f9846272ede) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index fd6ca1a336..b3e5352410 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1322,7 +1322,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } else if (!lp_parm_bool(global_loadparm, NULL, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - nt_status = sam_get_server_info_principal(mem_ctx, principal_string, + nt_status = sam_get_server_info_principal(mem_ctx, global_loadparm, principal_string, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 78416aff6c96a9db9df4f5d4a2907e5afe762748 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:41:37 +0100 Subject: r26258: Use loadparm context in client_start function of gensec. (This used to be commit bad1891cae2c688b17a6a2b932e754f51291035c) --- source4/auth/gensec/gensec_gssapi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index b3e5352410..1d8d5f057a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -298,7 +298,7 @@ static NTSTATUS gensec_gssapi_sasl_server_start(struct gensec_security *gensec_s return nt_status; } -static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security, struct loadparm_context *lp_ctx) { struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *creds = gensec_get_credentials(gensec_security); @@ -324,7 +324,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_gssapi_start(gensec_security, global_loadparm); + nt_status = gensec_gssapi_start(gensec_security, lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -334,7 +334,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state->gss_oid = gss_mech_krb5; principal = gensec_get_target_principal(gensec_security); - if (principal && lp_client_use_spnego_principal(global_loadparm)) { + if (principal && lp_client_use_spnego_principal(lp_ctx)) { name_type = GSS_C_NULL_OID; } else { principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", @@ -380,11 +380,11 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_OK; } -static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security, struct loadparm_context *lp_ctx) { NTSTATUS nt_status; struct gensec_gssapi_state *gensec_gssapi_state; - nt_status = gensec_gssapi_client_start(gensec_security); + nt_status = gensec_gssapi_client_start(gensec_security, lp_ctx); if (NT_STATUS_IS_OK(nt_status)) { gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); -- cgit From ecea5ce24553989103d4a06296b24f4d29f30a36 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:41:50 +0100 Subject: r26260: Store loadparm context in gensec context. (This used to be commit b9e3a4862e267be39d603fed8207a237c3d72081) --- source4/auth/gensec/gensec_gssapi.c | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 1d8d5f057a..c91da6d1a0 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -142,8 +142,7 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st return 0; } -static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, - struct loadparm_context *lp_ctx) +static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; krb5_error_code ret; @@ -156,7 +155,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(lp_ctx, NULL, "gensec_gssapi", "max wrap buf size", 65536); + = lp_parm_int(gensec_security->lp_ctx, NULL, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = false; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -171,16 +170,16 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; gensec_gssapi_state->want_flags = 0; - if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "mutual", true)) { + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "mutual", true)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "delegation", true)) { + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "delegation", true)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } - if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "replay", true)) { + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "replay", true)) { gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; } - if (lp_parm_bool(lp_ctx, NULL, "gensec_gssapi", "sequence", true)) { + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "sequence", true)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } @@ -214,10 +213,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } - if (lp_realm(lp_ctx) && *lp_realm(lp_ctx)) { - char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(lp_ctx)); + if (lp_realm(gensec_security->lp_ctx) && *lp_realm(gensec_security->lp_ctx)) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->lp_ctx)); if (!upper_realm) { - DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(lp_ctx))); + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->lp_ctx))); talloc_free(gensec_gssapi_state); return NT_STATUS_NO_MEMORY; } @@ -231,7 +230,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false)); + ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(gensec_security->lp_ctx, NULL, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); @@ -240,7 +239,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security, ret = smb_krb5_init_context(gensec_gssapi_state, gensec_security->event_ctx, - lp_ctx, + gensec_security->lp_ctx, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", @@ -259,7 +258,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi struct cli_credentials *machine_account; struct gssapi_creds_container *gcc; - nt_status = gensec_gssapi_start(gensec_security, global_loadparm); + nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -298,7 +297,7 @@ static NTSTATUS gensec_gssapi_sasl_server_start(struct gensec_security *gensec_s return nt_status; } -static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security, struct loadparm_context *lp_ctx) +static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; struct cli_credentials *creds = gensec_get_credentials(gensec_security); @@ -324,7 +323,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_gssapi_start(gensec_security, lp_ctx); + nt_status = gensec_gssapi_start(gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -334,7 +333,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state->gss_oid = gss_mech_krb5; principal = gensec_get_target_principal(gensec_security); - if (principal && lp_client_use_spnego_principal(lp_ctx)) { + if (principal && lp_client_use_spnego_principal(gensec_security->lp_ctx)) { name_type = GSS_C_NULL_OID; } else { principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", @@ -380,11 +379,11 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_OK; } -static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security, struct loadparm_context *lp_ctx) +static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security) { NTSTATUS nt_status; struct gensec_gssapi_state *gensec_gssapi_state; - nt_status = gensec_gssapi_client_start(gensec_security, lp_ctx); + nt_status = gensec_gssapi_client_start(gensec_security); if (NT_STATUS_IS_OK(nt_status)) { gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); @@ -1319,10 +1318,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi talloc_free(mem_ctx); return nt_status; } - } else if (!lp_parm_bool(global_loadparm, NULL, "gensec", "require_pac", false)) { + } else if (!lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - nt_status = sam_get_server_info_principal(mem_ctx, global_loadparm, principal_string, + nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->lp_ctx, principal_string, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1361,7 +1360,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } cli_credentials_set_event_context(session_info->credentials, gensec_security->event_ctx); - cli_credentials_set_conf(session_info->credentials, global_loadparm); + cli_credentials_set_conf(session_info->credentials, gensec_security->lp_ctx); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); -- cgit From 1fbdd6ef1dfb8704de0524fc6f5c33e1418858cd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 18:47:35 +0100 Subject: r26264: pass name resolve order explicitly, use torture context for settings in dssync tests. (This used to be commit c7eae1c7842f9ff8b70cce9e5d6f3ebbbe78e83b) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c91da6d1a0..a0b42db141 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1336,7 +1336,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(mem_ctx, server_info, &session_info); + nt_status = auth_generate_session_info(mem_ctx, gensec_security->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; -- cgit From 5db23bce227b909b9577501f733e733023a2daa8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 12 Dec 2007 11:08:32 +0100 Subject: r26416: Janitorial: Fix warnings in auth/gensec/ As per metze's suggestion, the "unused variables" warning is left in to remind us to fix the #else part of the #if 1 (This used to be commit e9ef98b06466486d3b8a68a76a29728b9bffbe29) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a0b42db141..bb71a55073 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -54,7 +54,7 @@ struct gensec_gssapi_state { gss_name_t server_name; gss_name_t client_name; OM_uint32 want_flags, got_flags; - const gss_OID_desc *gss_oid; + gss_OID gss_oid; DATA_BLOB session_key; DATA_BLOB pac; @@ -82,7 +82,7 @@ static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_secu static char *gssapi_error_string(TALLOC_CTX *mem_ctx, OM_uint32 maj_stat, OM_uint32 min_stat, - const gss_OID_desc *mech) + const gss_OID mech) { OM_uint32 disp_min_stat, disp_maj_stat; gss_buffer_desc maj_error_message; @@ -448,7 +448,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gensec_gssapi_state->client_cred->creds, &gensec_gssapi_state->gssapi_context, gensec_gssapi_state->server_name, - discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid), + gensec_gssapi_state->gss_oid, gensec_gssapi_state->want_flags, 0, gensec_gssapi_state->input_chan_bindings, -- cgit From a2cea02584256e2cf59da5420e8e080e70c66939 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:17 +0100 Subject: r26430: require explicit specification of loadparm context. (This used to be commit 1b947fe0e6e16318e5a8127bb4932d6b5d20bcf6) --- source4/auth/gensec/gensec_gssapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index bb71a55073..87fa47646b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -271,7 +271,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi DEBUG(3, ("No machine account credentials specified\n")); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } else { - ret = cli_credentials_get_server_gss_creds(machine_account, &gcc); + ret = cli_credentials_get_server_gss_creds(machine_account, gensec_security->lp_ctx, &gcc); if (ret) { DEBUG(1, ("Aquiring acceptor credentials failed: %s\n", error_message(ret))); @@ -357,7 +357,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - ret = cli_credentials_get_client_gss_creds(creds, &gcc); + ret = cli_credentials_get_client_gss_creds(creds, gensec_security->lp_ctx, &gcc); switch (ret) { case 0: break; @@ -1365,6 +1365,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi cli_credentials_set_anonymous(session_info->credentials); ret = cli_credentials_set_client_gss_creds(session_info->credentials, + gensec_security->lp_ctx, gensec_gssapi_state->delegated_cred_handle, CRED_SPECIFIED); if (ret) { -- cgit From 39a6495c86679d5e970012a0d1f5cd375e56450c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Feb 2008 19:40:20 +0100 Subject: Make more module init functions public, since they are compiled with -fvisibility=hidden. Not doing this causes failures on Mac OS X. (This used to be commit da1a9438bd89569077ef1eaa9dc977b5f9d62836) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 87fa47646b..8361b115d7 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1463,7 +1463,7 @@ static const struct gensec_security_ops gensec_gssapi_sasl_krb5_security_ops = { .priority = GENSEC_GSSAPI }; -NTSTATUS gensec_gssapi_init(void) +_PUBLIC_ NTSTATUS gensec_gssapi_init(void) { NTSTATUS ret; -- cgit From 37deca2d41d74faa7abe060a21340263bd6d66f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 14:16:02 +0100 Subject: Avoid use of global_loadparm. (This used to be commit c5a95bbe0ce55c29e135a9c6058bf192ec3bb546) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 8361b115d7..d8cdb90197 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1298,7 +1298,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* decode and verify the pac */ - nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, + nt_status = kerberos_pac_logon_info(mem_ctx, lp_iconv_convenience(gensec_security->lp_ctx), &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock, principal, authtime, NULL); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/auth/gensec/gensec_gssapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index d8cdb90197..e7dcb4ea68 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -34,7 +34,9 @@ #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" #include "auth/gensec/gensec.h" +#include "auth/gensec/gensec_proto.h" #include "param/param.h" +#include "auth/session_proto.h" enum gensec_gssapi_sasl_state { -- cgit From 1efbd5fbf6b0f606ed29a763e2adfa6f99c6beac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:03:18 +0200 Subject: Remove event context tracking from the credentials struct. (This used to be commit 4d7fc946b2ec50e774689c9036423b6feef99b8e) --- source4/auth/gensec/gensec_gssapi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e7dcb4ea68..cbee557d5a 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -273,7 +273,9 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi DEBUG(3, ("No machine account credentials specified\n")); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } else { - ret = cli_credentials_get_server_gss_creds(machine_account, gensec_security->lp_ctx, &gcc); + ret = cli_credentials_get_server_gss_creds(machine_account, + gensec_security->event_ctx, + gensec_security->lp_ctx, &gcc); if (ret) { DEBUG(1, ("Aquiring acceptor credentials failed: %s\n", error_message(ret))); @@ -359,7 +361,9 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; } - ret = cli_credentials_get_client_gss_creds(creds, gensec_security->lp_ctx, &gcc); + ret = cli_credentials_get_client_gss_creds(creds, + gensec_security->event_ctx, + gensec_security->lp_ctx, &gcc); switch (ret) { case 0: break; @@ -1361,12 +1365,12 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } - cli_credentials_set_event_context(session_info->credentials, gensec_security->event_ctx); cli_credentials_set_conf(session_info->credentials, gensec_security->lp_ctx); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); ret = cli_credentials_set_client_gss_creds(session_info->credentials, + gensec_security->event_ctx, gensec_security->lp_ctx, gensec_gssapi_state->delegated_cred_handle, CRED_SPECIFIED); -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/auth/gensec/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index cbee557d5a..cc0d40469e 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1327,7 +1327,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } else if (!lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->lp_ctx, principal_string, + nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, principal_string, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1342,7 +1342,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(mem_ctx, gensec_security->lp_ctx, server_info, &session_info); + nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; -- cgit From 55ea54ec640e4a76df397becc211a81aaec6f09d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jul 2008 18:26:31 +0200 Subject: gensec_gssapi: add support for signing RPC messages metze (This used to be commit dc2847c0acb0adaede4db72a7517046b93221162) --- source4/auth/gensec/gensec_gssapi.c | 47 ++++++++++--------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index cc0d40469e..205d8a0f9b 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1034,35 +1034,22 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; - int conf_state; - ssize_t sig_length = 0; input_token.length = length; input_token.value = discard_const_p(uint8_t *, data); - maj_stat = gss_wrap(&min_stat, + maj_stat = gss_get_mic(&min_stat, gensec_gssapi_state->gssapi_context, - 0, GSS_C_QOP_DEFAULT, &input_token, - &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS Wrap failed: %s\n", + DEBUG(1, ("GSS GetMic failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } - if (output_token.length < input_token.length) { - DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", - (long)output_token.length, (long)length)); - return NT_STATUS_INTERNAL_ERROR; - } - - /* Caller must pad to right boundary */ - sig_length = output_token.length - input_token.length; - - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length); dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); @@ -1080,39 +1067,29 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; + gss_buffer_desc input_token; + gss_buffer_desc input_message; gss_qop_t qop_state; - DATA_BLOB in; dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); - in = data_blob_talloc(mem_ctx, NULL, sig->length + length); + input_message.length = length; + input_message.value = data; - memcpy(in.data, sig->data, sig->length); - memcpy(in.data + sig->length, data, length); + input_token.length = sig->length; + input_token.value = sig->data; - input_token.length = in.length; - input_token.value = in.data; - - maj_stat = gss_unwrap(&min_stat, + maj_stat = gss_verify_mic(&min_stat, gensec_gssapi_state->gssapi_context, + &input_message, &input_token, - &output_token, - &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS UnWrap failed: %s\n", + DEBUG(1, ("GSS VerifyMic failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } - if (output_token.length != length) { - return NT_STATUS_INTERNAL_ERROR; - } - - gss_release_buffer(&min_stat, &output_token); - return NT_STATUS_OK; } -- cgit From c251443e733d44347160fc158d5c83a3417fcc95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Aug 2008 16:58:01 +0200 Subject: gensec_gssapi: include metze (This used to be commit 49e01d00bded74190c8e3049ac5883fe211e86fd) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 205d8a0f9b..bb44c75901 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -24,7 +24,6 @@ #include "includes.h" #include "lib/events/events.h" #include "system/kerberos.h" -#include "heimdal/lib/gssapi/gssapi/gssapi.h" #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/krb5pac.h" #include "auth/auth.h" @@ -37,6 +36,7 @@ #include "auth/gensec/gensec_proto.h" #include "param/param.h" #include "auth/session_proto.h" +#include enum gensec_gssapi_sasl_state { -- cgit From fd84beb19454963b4ded2b5aed2ed04a511cb397 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Aug 2008 21:30:17 +0200 Subject: gensec_gssapi: add support for GENSEC_FEATURE_SIGN_PKT_HEADER This only works for sign/verify_packet() yet, seal/unseal_packet() doesn't work yet... metze (This used to be commit c62e5d23a69789d23516a6d150fd3b756e270998) --- source4/auth/gensec/gensec_gssapi.c | 86 +++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index bb44c75901..1541c88e07 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -37,6 +37,7 @@ #include "param/param.h" #include "auth/session_proto.h" #include +#include enum gensec_gssapi_sasl_state { @@ -77,6 +78,7 @@ struct gensec_gssapi_state { size_t max_wrap_buf_size; int gss_exchange_count; + size_t sig_size; }; static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); @@ -191,6 +193,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->pac = data_blob(NULL, 0); gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; + gensec_gssapi_state->sig_size = 0; talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); @@ -1035,8 +1038,13 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; - input_token.length = length; - input_token.value = discard_const_p(uint8_t *, data); + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + input_token.length = pdu_length; + input_token.value = discard_const_p(uint8_t *, whole_pdu); + } else { + input_token.length = length; + input_token.value = discard_const_p(uint8_t *, data); + } maj_stat = gss_get_mic(&min_stat, gensec_gssapi_state->gssapi_context, @@ -1073,8 +1081,13 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); - input_message.length = length; - input_message.value = data; + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + input_message.length = pdu_length; + input_message.value = whole_pdu; + } else { + input_message.length = length; + input_message.value = data; + } input_token.length = sig->length; input_token.value = sig->data; @@ -1369,6 +1382,70 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_OK; } +size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size) +{ + struct gensec_gssapi_state *gensec_gssapi_state + = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + OM_uint32 maj_stat, min_stat; + gss_krb5_lucid_context_v1_t *lucid = NULL; + + if (gensec_gssapi_state->sig_size) { + return gensec_gssapi_state->sig_size; + } + + if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { + gensec_gssapi_state->sig_size = 45; + } else { + gensec_gssapi_state->sig_size = 37; + } + + maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, + &gensec_gssapi_state->gssapi_context, + 1, (void **)&lucid); + if (maj_stat != GSS_S_COMPLETE) { + return gensec_gssapi_state->sig_size; + } + + if (lucid->version != 1) { + return gensec_gssapi_state->sig_size; + } + + if (lucid->protocol == 1) { + if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { + /* + * TODO: windows uses 76 here, but we don't know + * gss_wrap works with aes keys yet + */ + gensec_gssapi_state->sig_size = 60; + } else { + gensec_gssapi_state->sig_size = 28; + } + } else if (lucid->protocol == 0) { + switch (lucid->rfc1964_kd.ctx_key.type) { + case KEYTYPE_DES: + case KEYTYPE_ARCFOUR: + case KEYTYPE_ARCFOUR_56: + if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { + gensec_gssapi_state->sig_size = 45; + } else { + gensec_gssapi_state->sig_size = 37; + } + break; + case KEYTYPE_DES3: + if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { + gensec_gssapi_state->sig_size = 57; + } else { + gensec_gssapi_state->sig_size = 49; + } + break; + } + } + + gss_krb5_free_lucid_sec_context(&min_stat, lucid); + + return gensec_gssapi_state->sig_size; +} + static const char *gensec_gssapi_krb5_oids[] = { GENSEC_OID_KERBEROS5_OLD, GENSEC_OID_KERBEROS5, @@ -1415,6 +1492,7 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .update = gensec_gssapi_update, .session_key = gensec_gssapi_session_key, .session_info = gensec_gssapi_session_info, + .sig_size = gensec_gssapi_sig_size, .sign_packet = gensec_gssapi_sign_packet, .check_packet = gensec_gssapi_check_packet, .seal_packet = gensec_gssapi_seal_packet, -- cgit From dd35840d9be4acff6fe2ff4f268039adf828d871 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Aug 2008 15:27:40 +0200 Subject: gensec_gssapi: use gsskrb5_get_subkey() to get the session key This is needed to get the correct key, when aes keys are used. metze (This used to be commit 7587a7d8b65f27a5865d6873f63a450488da02c9) --- source4/auth/gensec/gensec_gssapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 1541c88e07..0b1b9d851c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1165,9 +1165,9 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_OK; } - maj_stat = gsskrb5_get_initiator_subkey(&min_stat, - gensec_gssapi_state->gssapi_context, - &subkey); + maj_stat = gsskrb5_get_subkey(&min_stat, + gensec_gssapi_state->gssapi_context, + &subkey); if (maj_stat != 0) { DEBUG(1, ("NO session key for this mech\n")); return NT_STATUS_NO_USER_SESSION_KEY; -- cgit From 50fb2059c023600259e21051a29d1613ef19459f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Aug 2008 12:39:11 +0200 Subject: gensec_gssapi: use the correct signature size for cfx/rfc4121 style signatures metze (This used to be commit fcabe24f96c9677146ca754a502f336c23050339) --- source4/auth/gensec/gensec_gssapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0b1b9d851c..ff4a23e7fc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1416,7 +1416,7 @@ size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t da * TODO: windows uses 76 here, but we don't know * gss_wrap works with aes keys yet */ - gensec_gssapi_state->sig_size = 60; + gensec_gssapi_state->sig_size = 76; } else { gensec_gssapi_state->sig_size = 28; } -- cgit From b686328039f117d1fa097085996d0c8c0d747d67 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Aug 2008 14:56:36 +0200 Subject: gensec_gssapi: add a function to load the lucid structure once metze (This used to be commit daa986d1d04e59550bb5d33b5075daa414d087ba) --- source4/auth/gensec/gensec_gssapi.c | 59 +++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index ff4a23e7fc..6910a6ecbe 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -65,6 +65,7 @@ struct gensec_gssapi_state { struct smb_krb5_context *smb_krb5_context; struct gssapi_creds_container *client_cred; struct gssapi_creds_container *server_cred; + gss_krb5_lucid_context_v1_t *lucid; gss_cred_id_t delegated_cred_handle; @@ -143,9 +144,45 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); } + + if (gensec_gssapi_state->lucid) { + gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid); + } + return 0; } +static NTSTATUS gensec_gssapi_init_lucid(struct gensec_gssapi_state *gensec_gssapi_state) +{ + OM_uint32 maj_stat, min_stat; + + if (gensec_gssapi_state->lucid) { + return NT_STATUS_OK; + } + + maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, + &gensec_gssapi_state->gssapi_context, + 1, + (void **)&gensec_gssapi_state->lucid); + if (maj_stat != GSS_S_COMPLETE) { + DEBUG(0,("gensec_gssapi_init_lucid: %s\n", + gssapi_error_string(gensec_gssapi_state, + maj_stat, min_stat, + gensec_gssapi_state->gss_oid))); + return NT_STATUS_INTERNAL_ERROR; + } + + if (gensec_gssapi_state->lucid->version != 1) { + DEBUG(0,("gensec_gssapi_init_lucid: lucid version[%d] != 1\n", + gensec_gssapi_state->lucid->version)); + gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid); + gensec_gssapi_state->lucid = NULL; + return NT_STATUS_INTERNAL_ERROR; + } + + return NT_STATUS_OK; +} + static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; @@ -169,6 +206,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; gensec_gssapi_state->server_name = GSS_C_NO_NAME; gensec_gssapi_state->client_name = GSS_C_NO_NAME; + gensec_gssapi_state->lucid = NULL; /* TODO: Fill in channel bindings */ gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; @@ -1386,8 +1424,7 @@ size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t da { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - OM_uint32 maj_stat, min_stat; - gss_krb5_lucid_context_v1_t *lucid = NULL; + NTSTATUS status; if (gensec_gssapi_state->sig_size) { return gensec_gssapi_state->sig_size; @@ -1399,18 +1436,12 @@ size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t da gensec_gssapi_state->sig_size = 37; } - maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, - &gensec_gssapi_state->gssapi_context, - 1, (void **)&lucid); - if (maj_stat != GSS_S_COMPLETE) { + status = gensec_gssapi_init_lucid(gensec_gssapi_state); + if (!NT_STATUS_IS_OK(status)) { return gensec_gssapi_state->sig_size; } - if (lucid->version != 1) { - return gensec_gssapi_state->sig_size; - } - - if (lucid->protocol == 1) { + if (gensec_gssapi_state->lucid->protocol == 1) { if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { /* * TODO: windows uses 76 here, but we don't know @@ -1420,8 +1451,8 @@ size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t da } else { gensec_gssapi_state->sig_size = 28; } - } else if (lucid->protocol == 0) { - switch (lucid->rfc1964_kd.ctx_key.type) { + } else if (gensec_gssapi_state->lucid->protocol == 0) { + switch (gensec_gssapi_state->lucid->rfc1964_kd.ctx_key.type) { case KEYTYPE_DES: case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: @@ -1441,8 +1472,6 @@ size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t da } } - gss_krb5_free_lucid_sec_context(&min_stat, lucid); - return gensec_gssapi_state->sig_size; } -- cgit From 588cc81760b5bac201afd039855f93b1592d16d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Aug 2008 14:57:14 +0200 Subject: gensec_gssapi: fix compiler warnings metze (This used to be commit f4f4bb7fe977301e468ab164ba750b69d9a92306) --- source4/auth/gensec/gensec_gssapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 6910a6ecbe..7ded764095 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1121,10 +1121,10 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { input_message.length = pdu_length; - input_message.value = whole_pdu; + input_message.value = discard_const(whole_pdu); } else { input_message.length = length; - input_message.value = data; + input_message.value = discard_const(data); } input_token.length = sig->length; -- cgit From 8c0fbbf6e927db9fdbffc28fcde0bea97c5e60e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Aug 2008 15:02:02 +0200 Subject: gensec_gssapi: add support for GENSEC_FEATURE_NEW_SPNEGO metze (This used to be commit 9246924effd4d0b08ca1ef87e45ad510020df93e) --- source4/auth/gensec/gensec_gssapi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 7ded764095..0df40dc82f 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1177,6 +1177,31 @@ static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_DCE_STYLE) { return gensec_gssapi_state->got_flags & GSS_C_DCE_STYLE; } + if (feature & GENSEC_FEATURE_NEW_SPNEGO) { + NTSTATUS status; + + if (!(gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG)) { + return false; + } + + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "force_new_spnego", false)) { + return true; + } + if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "disable_new_spnego", false)) { + return false; + } + + status = gensec_gssapi_init_lucid(gensec_gssapi_state); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + if (gensec_gssapi_state->lucid->protocol == 1) { + return true; + } + + return false; + } /* We can always do async (rather than strict request/reply) packets. */ if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { return true; -- cgit From 26853e4607573ec849aa663eb2dd7bcea9acca24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 13 Aug 2008 07:18:35 +0200 Subject: gensec_gssapi: only cache the session key in STAGE_DONE The key may change because we switch from initiator to acceptor subkey. metze (This used to be commit 66244092a457b2cde6339cb31dcfa73b122ba9b5) --- source4/auth/gensec/gensec_gssapi.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0df40dc82f..20d08078be 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1236,12 +1236,16 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit return NT_STATUS_NO_USER_SESSION_KEY; } - DEBUG(10, ("Got KRB5 session key of length %d\n", - (int)KRB5_KEY_LENGTH(subkey))); - gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state, - KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey)); + DEBUG(10, ("Got KRB5 session key of length %d%s\n", + (int)KRB5_KEY_LENGTH(subkey), + (gensec_gssapi_state->sasl_state == STAGE_DONE)?" (done)":"")); + *session_key = data_blob_talloc(gensec_gssapi_state, + KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey)); krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey); - *session_key = gensec_gssapi_state->session_key; + if (gensec_gssapi_state->sasl_state == STAGE_DONE) { + /* only cache in the done stage */ + gensec_gssapi_state->session_key = *session_key; + } dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); return NT_STATUS_OK; -- cgit From 031d145e382fd545f43fa1cd72c10e1469034659 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 27 Aug 2008 16:24:05 +1000 Subject: Put the internal gensec_gssapi state into a header. This will allow a torture suite to inspect some otherwise internal details. Andrew Bartlett (This used to be commit 9701149ef75f9771f42000e2b6f44963abfee938) --- source4/auth/gensec/gensec_gssapi.c | 44 +------------------------------------ 1 file changed, 1 insertion(+), 43 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 20d08078be..20576256c2 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -38,49 +38,7 @@ #include "auth/session_proto.h" #include #include - -enum gensec_gssapi_sasl_state -{ - STAGE_GSS_NEG, - STAGE_SASL_SSF_NEG, - STAGE_SASL_SSF_ACCEPT, - STAGE_DONE -}; - -#define NEG_SEAL 0x4 -#define NEG_SIGN 0x2 -#define NEG_NONE 0x1 - -struct gensec_gssapi_state { - gss_ctx_id_t gssapi_context; - struct gss_channel_bindings_struct *input_chan_bindings; - gss_name_t server_name; - gss_name_t client_name; - OM_uint32 want_flags, got_flags; - gss_OID gss_oid; - - DATA_BLOB session_key; - DATA_BLOB pac; - - struct smb_krb5_context *smb_krb5_context; - struct gssapi_creds_container *client_cred; - struct gssapi_creds_container *server_cred; - gss_krb5_lucid_context_v1_t *lucid; - - gss_cred_id_t delegated_cred_handle; - - bool sasl; /* We have two different mechs in this file: One - * for SASL wrapped GSSAPI and another for normal - * GSSAPI */ - enum gensec_gssapi_sasl_state sasl_state; - uint8_t sasl_protection; /* What was negotiated at the SASL - * layer, independent of the GSSAPI - * layer... */ - - size_t max_wrap_buf_size; - int gss_exchange_count; - size_t sig_size; -}; +#include "auth/gensec/gensec_gssapi.h" static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); -- cgit From c79dff2e9b7c0c07ae5845ddc3b2c06f7996dfd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Aug 2008 16:28:47 +1000 Subject: Heimdal provides Kerberos PAC parsing routines. Use them. This uses Heimdal's PAC parsing code in the: - LOCAL-PAC test - gensec_gssapi server - KDC (where is was already used, the support code refactored from here) In addition, the service and KDC checksums are recorded in the struct auth_serversupplied_info, allowing them to be extracted for validation across NETLOGON. Andrew Bartlett (This used to be commit 418b440a7b8cdb53035045f3981d47b078be6c1e) --- source4/auth/gensec/gensec_gssapi.c | 129 ++++++++++++------------------------ 1 file changed, 41 insertions(+), 88 deletions(-) (limited to 'source4/auth/gensec/gensec_gssapi.c') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 20576256c2..1334e799ae 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1221,14 +1221,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; - struct PAC_LOGON_INFO *logon_info; OM_uint32 maj_stat, min_stat; - gss_buffer_desc name_token; gss_buffer_desc pac; - krb5_keyblock *keyblock; - time_t authtime; - krb5_principal principal; - char *principal_string; DATA_BLOB pac_blob; if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) @@ -1241,28 +1235,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); - maj_stat = gss_display_name (&min_stat, - gensec_gssapi_state->client_name, - &name_token, - NULL); - if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS display_name failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - talloc_free(mem_ctx); - return NT_STATUS_FOOBAR; - } - - principal_string = talloc_strndup(mem_ctx, - (const char *)name_token.value, - name_token.length); - - gss_release_buffer(&min_stat, &name_token); - - if (!principal_string) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, gensec_gssapi_state->gssapi_context, KRB5_AUTHDATA_WIN2K_PAC, @@ -1282,82 +1254,63 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi * kind... */ if (pac_blob.length) { - krb5_error_code ret; - union netr_Validation validation; - - maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - &authtime); - - if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("gsskrb5_extract_authtime_from_sec_context: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + nt_status = kerberos_pac_blob_to_server_info(mem_ctx, + lp_iconv_convenience(gensec_security->lp_ctx), + pac_blob, + gensec_gssapi_state->smb_krb5_context->krb5_context, + &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); - return NT_STATUS_FOOBAR; + return nt_status; } + } else { + gss_buffer_desc name_token; + char *principal_string; - maj_stat = gsskrb5_extract_service_keyblock(&min_stat, - gensec_gssapi_state->gssapi_context, - &keyblock); - + maj_stat = gss_display_name (&min_stat, + gensec_gssapi_state->client_name, + &name_token, + NULL); if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("gsskrb5_copy_service_keyblock failed: %s\n", + DEBUG(1, ("GSS display_name failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); talloc_free(mem_ctx); return NT_STATUS_FOOBAR; - } - - ret = krb5_parse_name_flags(gensec_gssapi_state->smb_krb5_context->krb5_context, - principal_string, - KRB5_PRINCIPAL_PARSE_MUST_REALM, - &principal); - if (ret) { - krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, - keyblock); - talloc_free(mem_ctx); - return NT_STATUS_INVALID_PARAMETER; } - /* decode and verify the pac */ - nt_status = kerberos_pac_logon_info(mem_ctx, lp_iconv_convenience(gensec_security->lp_ctx), &logon_info, pac_blob, - gensec_gssapi_state->smb_krb5_context->krb5_context, - NULL, keyblock, principal, authtime, NULL); - krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); - krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, - keyblock); - - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - validation.sam3 = &logon_info->info3; - nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, - NULL, - 3, &validation, - &server_info); - if (!NT_STATUS_IS_OK(nt_status)) { + principal_string = talloc_strndup(mem_ctx, + (const char *)name_token.value, + name_token.length); + + gss_release_buffer(&min_stat, &name_token); + + if (!principal_string) { talloc_free(mem_ctx); - return nt_status; + return NT_STATUS_NO_MEMORY; } - } else if (!lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { - DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, principal_string, - &server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; + if (!lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { + DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, + gensec_security->lp_ctx, principal_string, + &server_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + } else { + DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n", + principal_string, + gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + return NT_STATUS_ACCESS_DENIED; } - } else { - DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n", - principal_string, - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - return NT_STATUS_ACCESS_DENIED; } /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, server_info, &session_info); + nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, + gensec_security->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; -- cgit