From a1cdaa8b44449afe21371d756e98a5550a0f2dfd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:52:12 +0100 Subject: [PATCH 001/440] s4:auth/gensec_gssapi: remove compiler warnings BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 2bf79c419ddef693e74bcf33375ba56533b4774b) --- source4/auth/gensec/gensec_gssapi.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 514d423..44319dc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -56,24 +56,26 @@ static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_secu static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { - OM_uint32 maj_stat, min_stat; - + OM_uint32 min_stat; + if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { - maj_stat = gss_release_cred(&min_stat, - &gensec_gssapi_state->delegated_cred_handle); + 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, - &gensec_gssapi_state->gssapi_context, - GSS_C_NO_BUFFER); + 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); + 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); + gss_release_name(&min_stat, + &gensec_gssapi_state->client_name); } if (gensec_gssapi_state->lucid) { -- 1.9.1 From 50f920ae44c5a281cd33d1bb1542ba984d4a1f94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:42:19 +0100 Subject: [PATCH 002/440] s4:lib/tls: add tls_cert_generate() prototype to tls.h This avoids compiler warnings... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit f074e271a15215fe5e30f83bb170bd99a6e0ae92) --- source4/lib/tls/tls.h | 5 +++++ source4/lib/tls/tls_tstream.c | 2 -- source4/lib/tls/tlscert.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index ed3c81e..64ab7c2 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -45,6 +45,11 @@ struct socket_context *tls_init_server(struct tls_params *parms, struct tevent_fd *fde, const char *plain_chars); +void tls_cert_generate(TALLOC_CTX *mem_ctx, + const char *hostname, + const char *keyfile, const char *certfile, + const char *cafile); + /* call tls_init_client() on each new client connection */ diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index b907d0a..5b2329b 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -1061,8 +1061,6 @@ int tstream_tls_connect_recv(struct tevent_req *req, return 0; } -extern void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *); - /* initialise global tls state */ diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c index b44d46b..8eab04a 100644 --- a/source4/lib/tls/tlscert.c +++ b/source4/lib/tls/tlscert.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "lib/tls/tls.h" #if ENABLE_GNUTLS #include -- 1.9.1 From e627253da9ce2443a165adb280989d2945091c39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:43:00 +0100 Subject: [PATCH 003/440] s4:lib/tls: remove allow_warnings=True BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 0a4adb6730d0ec0e681ca9606b5a06934cf5ee7a) --- source4/lib/tls/wscript | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript index cbba87d..7985c6f 100644 --- a/source4/lib/tls/wscript +++ b/source4/lib/tls/wscript @@ -64,6 +64,5 @@ def configure(conf): def build(bld): bld.SAMBA_SUBSYSTEM('LIBTLS', source='tls.c tlscert.c tls_tstream.c', - allow_warnings=True, public_deps='talloc gnutls gcrypt samba-hostconfig samba_socket LIBTSOCKET tevent tevent-util' ) -- 1.9.1 From 89411abbb9d797ac31059f28769915ef2f124465 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:49:05 +0100 Subject: [PATCH 004/440] auth/kerberos: avoid compiler warnings BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 21ed0efac0b8371a7d56320875b88fbde161990e) --- auth/kerberos/gssapi_pac.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/auth/kerberos/gssapi_pac.c b/auth/kerberos/gssapi_pac.c index 99181a1..c6fa909 100644 --- a/auth/kerberos/gssapi_pac.c +++ b/auth/kerberos/gssapi_pac.c @@ -54,7 +54,7 @@ const gss_OID_desc * const gss_mech_krb5_wrong = krb5_gss_oid_array+2; gss_OID_desc gse_sesskey_inq_oid = { GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, - (void *)GSS_KRB5_INQ_SSPI_SESSION_KEY_OID + discard_const(GSS_KRB5_INQ_SSPI_SESSION_KEY_OID) }; #ifndef GSS_KRB5_SESSION_KEY_ENCTYPE_OID @@ -64,7 +64,7 @@ gss_OID_desc gse_sesskey_inq_oid = { gss_OID_desc gse_sesskeytype_oid = { GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH, - (void *)GSS_KRB5_SESSION_KEY_ENCTYPE_OID + discard_const(GSS_KRB5_SESSION_KEY_ENCTYPE_OID) }; /* The Heimdal OID for getting the PAC */ @@ -236,7 +236,7 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx, if (keytype) { int diflen, i; - const char *p; + const uint8_t *p; if (set->count < 2) { @@ -266,7 +266,7 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx, gss_maj = gss_release_buffer_set(&gss_min, &set); return NT_STATUS_OK; } - p = (uint8_t *)set->elements[1].value + gse_sesskeytype_oid.length; + p = (const uint8_t *)set->elements[1].value + gse_sesskeytype_oid.length; diflen = set->elements[1].length - gse_sesskeytype_oid.length; if (diflen <= 0) { gss_maj = gss_release_buffer_set(&gss_min, &set); @@ -307,9 +307,17 @@ char *gssapi_error_string(TALLOC_CTX *mem_ctx, disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, mech, &msg_ctx, &maj_error_message); + if (disp_maj_stat != 0) { + maj_error_message.value = NULL; + maj_error_message.length = 0; + } disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, mech, &msg_ctx, &min_error_message); + if (disp_maj_stat != 0) { + min_error_message.value = NULL; + min_error_message.length = 0; + } maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, -- 1.9.1 From 0cdf7d9c258139c2fffedce2b8d8513b32adb64f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:49:32 +0100 Subject: [PATCH 005/440] auth/kerberos: remove allow_warnings=True BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit bf77d78fd8ff442e6cefdaec1d9ee0f344c075d7) --- auth/kerberos/wscript_build | 1 - 1 file changed, 1 deletion(-) diff --git a/auth/kerberos/wscript_build b/auth/kerberos/wscript_build index 15b4889..97b8879 100755 --- a/auth/kerberos/wscript_build +++ b/auth/kerberos/wscript_build @@ -1,5 +1,4 @@ #!/usr/bin/env python bld.SAMBA_SUBSYSTEM('KRB5_PAC', source='gssapi_pac.c kerberos_pac.c', - allow_warnings=True, deps='gssapi_krb5 ndr-krb5pac krb5samba') -- 1.9.1 From dec0c1df6c9e734bb733763006511c9ffcd90959 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Mar 2015 21:52:12 +0100 Subject: [PATCH 006/440] s4:auth/gensec_gssapi: remove allow_warnings=True BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit f99d9548fd77496e848283bb8f2fd5c42ee9e884) --- source4/auth/gensec/wscript_build | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build index 1a44a90..cdf1789 100755 --- a/source4/auth/gensec/wscript_build +++ b/source4/auth/gensec/wscript_build @@ -19,7 +19,6 @@ bld.SAMBA_MODULE('gensec_gssapi', source='gensec_gssapi.c', subsystem='gensec', init_function='gensec_gssapi_init', - allow_warnings=True, deps='gssapi samba-credentials authkrb5 com_err gensec_util' ) -- 1.9.1 From 8294f11291638e0ffa98c5942dbbacf40d9eb220 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 29 Jul 2014 12:33:49 +0200 Subject: [PATCH 007/440] s4-gensec: Check if we have delegated credentials. With MIT Kerberos it is possible that the GSS_C_DELEG_FLAG is set, but the delegated_cred_handle is NULL which results in a NULL-pointer dereference. This way we fix it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit f05fbc14105096da9c9ecd75a6913d57e58c218f) --- source4/auth/gensec/gensec_gssapi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 44319dc..32337c0 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -526,7 +526,8 @@ 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->gss_got_flags & GSS_C_DELEG_FLAG) { + if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG && + gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); } else { DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); @@ -1404,9 +1405,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return nt_status; } - if (!(gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG)) { - DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); - } else { + if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG && + gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { krb5_error_code ret; const char *error_string; @@ -1436,7 +1436,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* It has been taken from this place... */ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; + } else { + DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); } + *_session_info = talloc_steal(mem_ctx, session_info); talloc_free(tmp_ctx); -- 1.9.1 From 3c56171b4b9e4f4c31f2246ebc41c19a24063996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 7 Feb 2015 10:48:30 +0100 Subject: [PATCH 008/440] gensec: map KRB5KRB_AP_ERR_BAD_INTEGRITY to logon failure. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When requesting initiator credentials fails, we need to map the error code KRB5KRB_AP_ERR_BAD_INTEGRITY to NT_STATUS_LOGON_FAILURE as well. This is what current MIT kerberos returns. Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Stefan Metzmacher (cherry picked from commit de6021127d2d666280d11ebcf41dd2a64f6591f3) --- source4/auth/gensec/gensec_gssapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 32337c0..053bd91 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -305,6 +305,7 @@ static NTSTATUS gensec_gssapi_client_creds(struct gensec_security *gensec_securi return NT_STATUS_INVALID_PARAMETER; case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: + case KRB5KRB_AP_ERR_BAD_INTEGRITY: DEBUG(1, ("Wrong username or password: %s\n", error_string)); return NT_STATUS_LOGON_FAILURE; case KRB5KDC_ERR_CLIENT_REVOKED: -- 1.9.1 From 5b0e24ffced3b0ac53beb8f034d7a0cff9fb414a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:17:10 +0200 Subject: [PATCH 009/440] s4:heimdal_build: define HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 01499617bdd7f7b202ddd1e1c35e21b5c042ac65) --- source4/heimdal_build/wscript_configure | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/heimdal_build/wscript_configure b/source4/heimdal_build/wscript_configure index 90df14c..e49c9c9 100755 --- a/source4/heimdal_build/wscript_configure +++ b/source4/heimdal_build/wscript_configure @@ -94,6 +94,7 @@ conf.define('HAVE_GSSKRB5_GET_SUBKEY', 1) conf.define('HAVE_GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT', 1) conf.define('HAVE_GSS_IMPORT_CRED', 1) conf.define('HAVE_GSS_EXPORT_CRED', 1) +conf.define('HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X', 1) conf.define('HAVE_GSSAPI', 1) conf.define('HAVE_ADDR_TYPE_IN_KRB5_ADDRESS', 1) conf.define('HAVE_CHECKSUM_IN_KRB5_CHECKSUM', 1) -- 1.9.1 From cdc86804a8a2f71b3690a1328f8aee2d6924b699 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:17:33 +0200 Subject: [PATCH 010/440] auth/credentials: use HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X instead of SAMBA4_USES_HEIMDAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer MIT versions also have this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 57579453d12429adba08b80c1eb6936cc422a2fd) --- auth/credentials/credentials_krb5.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index d968e20..a340ed9 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -516,7 +516,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct ccache_container *ccache; -#ifdef SAMBA4_USES_HEIMDAL +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; #endif krb5_enctype *etypes = NULL; @@ -632,8 +632,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } } -#ifdef SAMBA4_USES_HEIMDAL /* MIT lacks GSS_KRB5_CRED_NO_CI_FLAGS_X */ - +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X /* don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG */ maj_stat = gss_set_cred_option(&min_stat, &gcc->creds, GSS_KRB5_CRED_NO_CI_FLAGS_X, -- 1.9.1 From ab830b03292c8dedc5de44b258226e2c50ad5430 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 23:18:58 +0200 Subject: [PATCH 011/440] s4:gensec/gssapi: use gensec_gssapi_max_{input,wrapped}_size() for all backends This avoids calls to gensec_gssapi_sig_size() as fallback in gensec_max_input_size(). gensec_gssapi_sig_size() needs to report the sig size gensec_{sign,seal}_packet(), which could be different to the overhead produced by gensec_wrap(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit ac5283f7888d3b0bbc4d3a53102cc47d32366d06) --- source4/auth/gensec/gensec_gssapi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 053bd91..5f0f6e3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1531,6 +1531,8 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = { .check_packet = gensec_gssapi_check_packet, .seal_packet = gensec_gssapi_seal_packet, .unseal_packet = gensec_gssapi_unseal_packet, + .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, @@ -1556,6 +1558,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = { .check_packet = gensec_gssapi_check_packet, .seal_packet = gensec_gssapi_seal_packet, .unseal_packet = gensec_gssapi_unseal_packet, + .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, -- 1.9.1 From 76a6885b6d1f4b57b8d2ac3da0e7e9c889b58a03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 21:07:58 +0200 Subject: [PATCH 012/440] s4:gensec/gssapi: make calculation of gensec_gssapi_sig_size() for aes keys more clear This way the result matches what gss_wrap_iov_length() would return. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 7b916b5f9a3db5b268639d2d68cfa85e20a83266) --- source4/auth/gensec/gensec_gssapi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 5f0f6e3..f02f2ab 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1470,11 +1470,10 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si if (gensec_gssapi_state->lucid->protocol == 1) { if (gensec_gssapi_state->gss_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 = 76; + gensec_gssapi_state->sig_size = 60; + if (gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE) { + gensec_gssapi_state->sig_size += 16; + } } else { gensec_gssapi_state->sig_size = 28; } -- 1.9.1 From 254d3d1d099a37f2721b0b5db5c40d9c4282ce96 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 01:07:49 +0200 Subject: [PATCH 013/440] s3:libads/sasl: use gensec_max_{input,wrapped}_size() in ads_sasl_spnego_ntlmssp_bind gensec_sig_size() is for gensec_{sign,seal}_packet() instead of gensec_wrap(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 8dbe9d785bd3b3d7bdca1e9854dc0516047d5e5a) --- source3/libads/sasl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index ea0b821..b1896f8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -250,11 +250,12 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32_t sig_size = gensec_sig_size(auth_generic_state->gensec_security, 0); - ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - sig_size; - ads->ldap.out.sig_size = sig_size; + size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security); + ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); + + ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped; ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; - ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED; + ads->ldap.in.max_wrapped = max_wrapped; status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, auth_generic_state->gensec_security); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", -- 1.9.1 From 4d62e81d966e7889c0fa49b52e335afddb43dc82 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 12:26:55 +0200 Subject: [PATCH 014/440] s4:lib/tls: fix tstream_tls_connect_send() define BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 3d298b994d949786c0eda47ece4a2d7b1c6f3104) --- source4/lib/tls/tls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index 64ab7c2..3ff009d 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -90,7 +90,7 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx, struct tstream_context *plain_stream, struct tstream_tls_params *tls_params, const char *location); -#define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params); \ +#define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params) \ _tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params, __location__) int tstream_tls_connect_recv(struct tevent_req *req, -- 1.9.1 From 2a4da5e00cf3e542f911500cc1d469ae8da8c049 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 13:30:10 +0200 Subject: [PATCH 015/440] s4:lib/tls: ignore non-existing ca and crl files in tstream_tls_params_client() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 6f2c29a13cfee0e816499f8aea4076aaee9e2f85) --- source4/lib/tls/tls_tstream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 5b2329b..113e03a 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -919,7 +919,7 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (ca_file && *ca_file) { + if (ca_file && *ca_file && file_exist(ca_file)) { ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred, ca_file, GNUTLS_X509_FMT_PEM); @@ -931,7 +931,7 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, } } - if (crl_file && *crl_file) { + if (crl_file && *crl_file && file_exist(crl_file)) { ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred, crl_file, GNUTLS_X509_FMT_PEM); -- 1.9.1 From 30b287c2213d212ff566e48c53f59f491a62b939 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 12:26:06 +0200 Subject: [PATCH 016/440] s4:libcli/ldap: conversion to tstream BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 67c5d5849efb6dc9ff04088e0599056bcfad1aee) --- source4/libcli/ldap/ldap_bind.c | 65 ++++-- source4/libcli/ldap/ldap_client.c | 443 +++++++++++++++++++++++++------------- source4/libcli/ldap/ldap_client.h | 17 +- source4/libcli/ldap/wscript_build | 4 +- 4 files changed, 357 insertions(+), 172 deletions(-) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index a96ea9f..daa7662 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -28,7 +28,7 @@ #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "auth/gensec/gensec_internal.h" /* TODO: remove this */ -#include "auth/gensec/gensec_socket.h" +#include "source4/auth/gensec/gensec_tstream.h" #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" #include "param/param.h" @@ -224,6 +224,27 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; unsigned int logon_retries = 0; + size_t queue_length; + + if (conn->sockets.active == NULL) { + status = NT_STATUS_CONNECTION_DISCONNECTED; + goto failed; + } + + queue_length = tevent_queue_length(conn->sockets.send_queue); + if (queue_length != 0) { + status = NT_STATUS_INVALID_PARAMETER_MIX; + DEBUG(1, ("SASL bind triggered with non empty send_queue[%ju]: %s\n", + queue_length, nt_errstr(status))); + goto failed; + } + + if (conn->pending != NULL) { + status = NT_STATUS_INVALID_PARAMETER_MIX; + DEBUG(1, ("SASL bind triggered with pending requests: %s\n", + nt_errstr(status))); + goto failed; + } status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, false, NULL, NULL, &sasl_mechs_msgs); @@ -281,7 +302,7 @@ try_logon_again: /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ old_gensec_features = cli_credentials_get_gensec_features(creds); - if (tls_enabled(conn->sock)) { + if (conn->sockets.active == conn->sockets.tls) { cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); } @@ -436,27 +457,31 @@ try_logon_again: } } - talloc_free(tmp_ctx); + TALLOC_FREE(tmp_ctx); - if (NT_STATUS_IS_OK(status)) { - struct socket_context *sasl_socket; - status = gensec_socket_init(conn->gensec, - conn, - conn->sock, - conn->event.event_ctx, - ldap_read_io_handler, - conn, - &sasl_socket); - if (!NT_STATUS_IS_OK(status)) goto failed; - - conn->sock = sasl_socket; - packet_set_socket(conn->packet, conn->sock); - - conn->bind.type = LDAP_BIND_SASL; - conn->bind.creds = creds; + if (!NT_STATUS_IS_OK(status)) { + goto failed; } - return status; + conn->bind.type = LDAP_BIND_SASL; + conn->bind.creds = creds; + + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) && + !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { + return NT_STATUS_OK; + } + + status = gensec_create_tstream(conn->sockets.raw, + conn->gensec, + conn->sockets.raw, + &conn->sockets.sasl); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + conn->sockets.active = conn->sockets.sasl; + + return NT_STATUS_OK; failed: talloc_free(tmp_ctx); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7c8bb03..e49df9e 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -25,22 +25,36 @@ #include "includes.h" #include #include "lib/socket/socket.h" +#include "lib/tsocket/tsocket.h" +#include "libcli/util/tstream.h" #include "../lib/util/asn1.h" #include "../lib/util/dlinklist.h" #include "libcli/ldap/libcli_ldap.h" #include "libcli/ldap/ldap_proto.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" -#include "lib/stream/packet.h" #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" #include "param/param.h" #include "libcli/resolve/resolve.h" +static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status); + +static int ldap_connection_destructor(struct ldap_connection *conn) +{ + /* + * NT_STATUS_OK means that callbacks of pending requests are not + * triggered + */ + ldap_connection_dead(conn, NT_STATUS_OK); + return 0; +} + /** create a new ldap_connection stucture. The event context is optional */ + _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct tevent_context *ev) @@ -59,6 +73,13 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, conn->next_messageid = 1; conn->event.event_ctx = ev; + conn->sockets.send_queue = tevent_queue_create(conn, + "ldap_connection send_queue"); + if (conn->sockets.send_queue == NULL) { + TALLOC_FREE(conn); + return NULL; + } + conn->lp_ctx = lp_ctx; /* set a reasonable request timeout */ @@ -66,29 +87,35 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, /* explicitly avoid reconnections by default */ conn->reconnect.max_retries = 0; - + + talloc_set_destructor(conn, ldap_connection_destructor); return conn; } /* the connection is dead */ -static void ldap_connection_dead(struct ldap_connection *conn) +static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status) { struct ldap_request *req; - talloc_free(conn->sock); /* this will also free event.fde */ - talloc_free(conn->packet); - conn->sock = NULL; - conn->event.fde = NULL; - conn->packet = NULL; + tevent_queue_stop(conn->sockets.send_queue); + TALLOC_FREE(conn->sockets.recv_subreq); + conn->sockets.active = NULL; + TALLOC_FREE(conn->sockets.sasl); + TALLOC_FREE(conn->sockets.tls); + TALLOC_FREE(conn->sockets.raw); /* return an error for any pending request ... */ while (conn->pending) { req = conn->pending; DLIST_REMOVE(req->conn->pending, req); + req->conn = NULL; req->state = LDAP_REQUEST_DONE; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (NT_STATUS_IS_OK(status)) { + continue; + } + req->status = status; if (req->async.fn) { req->async.fn(req); } @@ -100,11 +127,9 @@ static void ldap_reconnect(struct ldap_connection *conn); /* handle packet errors */ -static void ldap_error_handler(void *private_data, NTSTATUS status) +static void ldap_error_handler(struct ldap_connection *conn, NTSTATUS status) { - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - ldap_connection_dead(conn); + ldap_connection_dead(conn, status); /* but try to reconnect so that the ldb client can go on */ ldap_reconnect(conn); @@ -130,7 +155,7 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message if (req == NULL) { DEBUG(0,("ldap: no matching message id for %u\n", msg->messageid)); - talloc_free(msg); + TALLOC_FREE(msg); return; } @@ -138,6 +163,7 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message for (i=0; msg->controls && msg->controls[i]; i++) { if (!msg->controls_decoded[i] && msg->controls[i]->critical) { + TALLOC_FREE(msg); req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); req->state = LDAP_REQUEST_DONE; DLIST_REMOVE(conn->pending, req); @@ -149,10 +175,10 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message } /* add to the list of replies received */ - talloc_steal(req, msg); req->replies = talloc_realloc(req, req->replies, struct ldap_message *, req->num_replies+1); if (req->replies == NULL) { + TALLOC_FREE(msg); req->status = NT_STATUS_NO_MEMORY; req->state = LDAP_REQUEST_DONE; DLIST_REMOVE(conn->pending, req); @@ -178,64 +204,120 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message } } +static void ldap_connection_recv_done(struct tevent_req *subreq); + +static void ldap_connection_recv_next(struct ldap_connection *conn) +{ + struct tevent_req *subreq = NULL; + + if (conn->sockets.recv_subreq != NULL) { + return; + } + + if (conn->sockets.active == NULL) { + return; + } + + if (conn->pending == NULL) { + return; + } + + /* + * The minimun size of a LDAP pdu is 7 bytes + * + * dumpasn1 -hh ldap-unbind-min.dat + * + * <30 05 02 01 09 42 00> + * 0 5: SEQUENCE { + * <02 01 09> + * 2 1: INTEGER 9 + * <42 00> + * 5 0: [APPLICATION 2] + * : Error: Object has zero length. + * : } + * + * dumpasn1 -hh ldap-unbind-windows.dat + * + * <30 84 00 00 00 05 02 01 09 42 00> + * 0 5: SEQUENCE { + * <02 01 09> + * 6 1: INTEGER 9 + * <42 00> + * 9 0: [APPLICATION 2] + * : Error: Object has zero length. + * : } + * + * This means using an initial read size + * of 7 is ok. + */ + subreq = tstream_read_pdu_blob_send(conn, + conn->event.event_ctx, + conn->sockets.active, + 7, /* initial_read_size */ + ldap_full_packet, + conn); + if (subreq == NULL) { + ldap_error_handler(conn, NT_STATUS_NO_MEMORY); + return; + } + tevent_req_set_callback(subreq, ldap_connection_recv_done, conn); + conn->sockets.recv_subreq = subreq; + return; +} /* decode/process LDAP data */ -static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) +static void ldap_connection_recv_done(struct tevent_req *subreq) { NTSTATUS status; - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - struct ldap_message *msg = talloc(conn, struct ldap_message); - struct asn1_data *asn1 = asn1_init(conn); - - if (asn1 == NULL || msg == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + struct ldap_connection *conn = + tevent_req_callback_data(subreq, + struct ldap_connection); + struct ldap_message *msg; + struct asn1_data *asn1; + DATA_BLOB blob; + + msg = talloc_zero(conn, struct ldap_message); + if (msg == NULL) { + ldap_error_handler(conn, NT_STATUS_NO_MEMORY); + return; } - if (!asn1_load(asn1, blob)) { - talloc_free(msg); - talloc_free(asn1); - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + asn1 = asn1_init(conn); + if (asn1 == NULL) { + TALLOC_FREE(msg); + ldap_error_handler(conn, NT_STATUS_NO_MEMORY); + return; } - - status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); + + conn->sockets.recv_subreq = NULL; + + status = tstream_read_pdu_blob_recv(subreq, + asn1, + &blob); + TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(msg); asn1_free(asn1); - return status; + ldap_error_handler(conn, status); + return; } - ldap_match_message(conn, msg); + asn1_load_nocopy(asn1, blob.data, blob.length); - data_blob_free(&blob); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); asn1_free(asn1); - return NT_STATUS_OK; -} + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(msg); + ldap_error_handler(conn, status); + return; + } -/* Handle read events, from the GENSEC socket callback, or real events */ -void ldap_read_io_handler(void *private_data, uint16_t flags) -{ - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - packet_recv(conn->packet); -} + ldap_match_message(conn, msg); + ldap_connection_recv_next(conn); -/* - handle ldap socket events -*/ -static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data) -{ - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - if (flags & TEVENT_FD_WRITE) { - packet_queue_run(conn->packet); - if (!tls_enabled(conn->sock)) return; - } - if (flags & TEVENT_FD_READ) { - ldap_read_io_handler(private_data, flags); - } + return; } /* @@ -284,6 +366,10 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, struct ldap_connect_state { struct composite_context *ctx; struct ldap_connection *conn; + struct socket_context *sock; + struct tstream_context *raw; + struct tstream_tls_params *tls_params; + struct tstream_context *tls; }; static void ldap_connect_recv_unix_conn(struct composite_context *ctx); @@ -327,11 +413,11 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con struct socket_address *unix_addr; char path[1025]; - NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0); + NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &state->sock, 0); if (!NT_STATUS_IS_OK(status)) { return NULL; } - talloc_steal(conn, conn->sock); + talloc_steal(state, state->sock); SMB_ASSERT(sizeof(protocol)>10); SMB_ASSERT(sizeof(path)>1024); @@ -354,29 +440,53 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con } rfc1738_unescape(path); - - unix_addr = socket_address_from_strings(conn, conn->sock->backend_name, + + unix_addr = socket_address_from_strings(state, state->sock->backend_name, path, 0); - if (!unix_addr) { - return NULL; + if (composite_nomem(unix_addr, result)) { + return result; } - ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, conn->event.event_ctx); + + ctx = socket_connect_send(state->sock, NULL, unix_addr, + 0, result->event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; } else { NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); - if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_error(state->ctx, status); + if (!NT_STATUS_IS_OK(status)) { + composite_error(result, status); return result; } - + + if (conn->ldaps) { + char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx); + char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx); + + if (!ca_file || !*ca_file) { + composite_error(result, + NT_STATUS_INVALID_PARAMETER_MIX); + return result; + } + + status = tstream_tls_params_client(state, + ca_file, + crl_file, + &state->tls_params); + if (!NT_STATUS_IS_OK(status)) { + composite_error(result, status); + return result; + } + } + ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - lpcfg_resolve_context(conn->lp_ctx), conn->event.event_ctx); - if (ctx == NULL) goto failed; + lpcfg_resolve_context(conn->lp_ctx), + result->event_ctx); + if (composite_nomem(ctx, result)) { + return result; + } ctx->async.fn = ldap_connect_recv_tcp_conn; ctx->async.private_data = state; @@ -387,72 +497,80 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con return NULL; } +static void ldap_connect_got_tls(struct tevent_req *subreq); + static void ldap_connect_got_sock(struct composite_context *ctx, - struct ldap_connection *conn) + struct ldap_connection *conn) { - /* setup a handler for events on this socket */ - conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock, - socket_get_fd(conn->sock), - TEVENT_FD_READ, ldap_io_handler, conn); - if (conn->event.fde == NULL) { - composite_error(ctx, NT_STATUS_INTERNAL_ERROR); - return; - } + struct ldap_connect_state *state = + talloc_get_type_abort(ctx->private_data, + struct ldap_connect_state); + struct tevent_req *subreq = NULL; + int fd; + int ret; - tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn); - socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE); + socket_set_flags(state->sock, SOCKET_FLAG_NOCLOSE); + fd = socket_get_fd(state->sock); + TALLOC_FREE(state->sock); - talloc_steal(conn, conn->sock); - if (conn->ldaps) { - struct socket_context *tls_socket; - char *cafile = lpcfg_tls_cafile(conn->sock, conn->lp_ctx); + smb_set_close_on_exec(fd); + set_blocking(fd, false); - if (!cafile || !*cafile) { - talloc_free(conn->sock); - return; - } - - tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile); - talloc_free(cafile); - - if (tls_socket == NULL) { - talloc_free(conn->sock); - return; - } + ret = tstream_bsd_existing_socket(state, fd, &state->raw); + if (ret == -1) { + NTSTATUS status = map_nt_error_from_unix_common(errno); + composite_error(state->ctx, status); + return; + } - conn->sock = talloc_steal(conn, tls_socket); + if (!conn->ldaps) { + conn->sockets.raw = talloc_move(conn, &state->raw); + conn->sockets.active = conn->sockets.raw; + composite_done(state->ctx); + return; } - conn->packet = packet_init(conn); - if (conn->packet == NULL) { - talloc_free(conn->sock); + subreq = tstream_tls_connect_send(state, state->ctx->event_ctx, + state->raw, state->tls_params); + if (composite_nomem(subreq, state->ctx)) { return; } + tevent_req_set_callback(subreq, ldap_connect_got_tls, state); +} - packet_set_private(conn->packet, conn); - packet_set_socket(conn->packet, conn->sock); - packet_set_callback(conn->packet, ldap_recv_handler); - packet_set_full_request(conn->packet, ldap_full_packet); - packet_set_error_handler(conn->packet, ldap_error_handler); - packet_set_event_context(conn->packet, conn->event.event_ctx); - packet_set_fde(conn->packet, conn->event.fde); -/* packet_set_serialise(conn->packet); */ +static void ldap_connect_got_tls(struct tevent_req *subreq) +{ + struct ldap_connect_state *state = + tevent_req_callback_data(subreq, + struct ldap_connect_state); + int err; + int ret; - if (conn->ldaps) { - packet_set_unreliable_select(conn->packet); + ret = tstream_tls_connect_recv(subreq, &err, state, &state->tls); + TALLOC_FREE(subreq); + if (ret == -1) { + NTSTATUS status = map_nt_error_from_unix_common(err); + composite_error(state->ctx, status); + return; } - composite_done(ctx); + talloc_steal(state->tls, state->tls_params); + + state->conn->sockets.raw = talloc_move(state->conn, &state->raw); + state->conn->sockets.tls = talloc_move(state->conn->sockets.raw, + &state->tls); + state->conn->sockets.active = state->conn->sockets.tls; + composite_done(state->ctx); } static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) { struct ldap_connect_state *state = - talloc_get_type(ctx->async.private_data, - struct ldap_connect_state); + talloc_get_type_abort(ctx->async.private_data, + struct ldap_connect_state); struct ldap_connection *conn = state->conn; uint16_t port; - NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock, + NTSTATUS status = socket_connect_multi_recv(ctx, state, &state->sock, &port); if (!NT_STATUS_IS_OK(status)) { composite_error(state->ctx, status); @@ -465,8 +583,8 @@ static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) static void ldap_connect_recv_unix_conn(struct composite_context *ctx) { struct ldap_connect_state *state = - talloc_get_type(ctx->async.private_data, - struct ldap_connect_state); + talloc_get_type_abort(ctx->async.private_data, + struct ldap_connect_state); struct ldap_connection *conn = state->conn; NTSTATUS status = socket_connect_recv(ctx); @@ -533,7 +651,7 @@ static void ldap_reconnect(struct ldap_connection *conn) /* rebind */ status = ldap_rebind(conn); if ( ! NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); + ldap_connection_dead(conn, status); } } @@ -552,7 +670,10 @@ static int ldap_request_destructor(struct ldap_request *req) static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); + struct ldap_request *req = + talloc_get_type_abort(private_data, + struct ldap_request); + req->status = NT_STATUS_IO_TIMEOUT; if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); @@ -570,26 +691,17 @@ static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); - if (req->async.fn) { - req->async.fn(req); - } -} + struct ldap_request *req = + talloc_get_type_abort(private_data, + struct ldap_request); -/* - called on completion of a one-way ldap request -*/ -static void ldap_request_oneway_complete(void *private_data) -{ - struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); - if (req->state == LDAP_REQUEST_PENDING) { - DLIST_REMOVE(req->conn->pending, req); - } - req->state = LDAP_REQUEST_DONE; if (req->async.fn) { req->async.fn(req); } } + +static void ldap_request_written(struct tevent_req *subreq); + /* send a ldap message - async interface */ @@ -598,12 +710,12 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, { struct ldap_request *req; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - packet_send_callback_fn_t send_callback = NULL; + struct tevent_req *subreq = NULL; req = talloc_zero(conn, struct ldap_request); if (req == NULL) return NULL; - if (conn->sock == NULL) { + if (conn->sockets.active == NULL) { status = NT_STATUS_INVALID_CONNECTION; goto failed; } @@ -628,25 +740,31 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, goto failed; } - if (req->type == LDAP_TAG_AbandonRequest || - req->type == LDAP_TAG_UnbindRequest) { - send_callback = ldap_request_oneway_complete; + /* put a timeout on the request */ + req->time_event = tevent_add_timer(conn->event.event_ctx, req, + timeval_current_ofs(conn->timeout, 0), + ldap_request_timeout, req); + if (req->time_event == NULL) { + status = NT_STATUS_NO_MEMORY; + goto failed; } - status = packet_send_callback(conn->packet, req->data, - send_callback, req); - if (!NT_STATUS_IS_OK(status)) { + req->write_iov.iov_base = req->data.data; + req->write_iov.iov_len = req->data.length; + + subreq = tstream_writev_queue_send(req, conn->event.event_ctx, + conn->sockets.active, + conn->sockets.send_queue, + &req->write_iov, 1); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; goto failed; } + tevent_req_set_callback(subreq, ldap_request_written, req); req->state = LDAP_REQUEST_PENDING; DLIST_ADD(conn->pending, req); - /* put a timeout on the request */ - req->time_event = tevent_add_timer(conn->event.event_ctx, req, - timeval_current_ofs(conn->timeout, 0), - ldap_request_timeout, req); - return req; failed: @@ -658,6 +776,38 @@ failed: return req; } +static void ldap_request_written(struct tevent_req *subreq) +{ + struct ldap_request *req = + tevent_req_callback_data(subreq, + struct ldap_request); + int err; + ssize_t ret; + + ret = tstream_writev_queue_recv(subreq, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + NTSTATUS error = map_nt_error_from_unix_common(err); + ldap_error_handler(req->conn, error); + return; + } + + if (req->type == LDAP_TAG_AbandonRequest || + req->type == LDAP_TAG_UnbindRequest) + { + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); + } + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + return; + } + + ldap_connection_recv_next(req->conn); +} + /* wait for a request to complete @@ -667,6 +817,7 @@ _PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req) { while (req->state < LDAP_REQUEST_DONE) { if (tevent_loop_once(req->conn->event.event_ctx) != 0) { + req->state = LDAP_REQUEST_ERROR; req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 3b4da6b..e2b1b30 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -20,6 +20,7 @@ */ +#include "system/network.h" /* for struct iovec */ #include "libcli/ldap/libcli_ldap.h" enum ldap_request_state { LDAP_REQUEST_SEND=1, LDAP_REQUEST_PENDING=2, LDAP_REQUEST_DONE=3, LDAP_REQUEST_ERROR=4 }; @@ -39,6 +40,8 @@ struct ldap_request { NTSTATUS status; DATA_BLOB data; + struct iovec write_iov; + struct { void (*fn)(struct ldap_request *); void *private_data; @@ -50,7 +53,16 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { - struct socket_context *sock; + struct { + struct tstream_context *raw; + struct tstream_context *tls; + struct tstream_context *sasl; + struct tstream_context *active; + + struct tevent_queue *send_queue; + struct tevent_req *recv_subreq; + } sockets; + struct loadparm_context *lp_ctx; char *host; @@ -89,10 +101,7 @@ struct ldap_connection { struct { struct tevent_context *event_ctx; - struct tevent_fd *fde; } event; - - struct packet_context *packet; }; struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, diff --git a/source4/libcli/ldap/wscript_build b/source4/libcli/ldap/wscript_build index f7afec7..f79cc2b 100644 --- a/source4/libcli/ldap/wscript_build +++ b/source4/libcli/ldap/wscript_build @@ -3,9 +3,9 @@ bld.SAMBA_LIBRARY('cli-ldap', source='ldap_client.c ldap_bind.c ldap_ildap.c ldap_controls.c', autoproto='ldap_proto.h', - public_deps='errors tevent LIBPACKET', + public_deps='errors tevent', public_headers='libcli_ldap.h:ldap-util.h', - deps='cli_composite samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common', + deps='cli_composite LIBSAMBA_TSOCKET samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common', private_library=True ) -- 1.9.1 From 1a6df101cb94510ecba2fba72dad16943dadca3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 13:30:54 +0200 Subject: [PATCH 017/440] s4:auth/gensec: remove unused and untested cyrus_sasl module There's not a high chance that this module worked at all. Requesting SASL_SSF in order to get the max input length is completely broken. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (similar to commit beb84d0c26305b80c8c56711782d62212e7abf86) --- source4/auth/gensec/cyrus_sasl.c | 452 -------------------------------------- source4/auth/gensec/wscript_build | 11 - source4/auth/wscript_configure | 4 - 3 files changed, 467 deletions(-) delete mode 100644 source4/auth/gensec/cyrus_sasl.c diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c deleted file mode 100644 index 08dccd6..0000000 --- a/source4/auth/gensec/cyrus_sasl.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Connect GENSEC to an external SASL lib - - Copyright (C) Andrew Bartlett 2006 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "lib/tsocket/tsocket.h" -#include "auth/credentials/credentials.h" -#include "auth/gensec/gensec.h" -#include "auth/gensec/gensec_internal.h" -#include "auth/gensec/gensec_proto.h" -#include "auth/gensec/gensec_toplevel_proto.h" -#include - -NTSTATUS gensec_sasl_init(void); - -struct gensec_sasl_state { - sasl_conn_t *conn; - int step; - bool wrap; -}; - -static NTSTATUS sasl_nt_status(int sasl_ret) -{ - switch (sasl_ret) { - case SASL_CONTINUE: - return NT_STATUS_MORE_PROCESSING_REQUIRED; - case SASL_NOMEM: - return NT_STATUS_NO_MEMORY; - case SASL_BADPARAM: - case SASL_NOMECH: - return NT_STATUS_INVALID_PARAMETER; - case SASL_BADMAC: - return NT_STATUS_ACCESS_DENIED; - case SASL_OK: - return NT_STATUS_OK; - default: - return NT_STATUS_UNSUCCESSFUL; - } -} - -static int gensec_sasl_get_user(void *context, int id, - const char **result, unsigned *len) -{ - struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security); - const char *username = cli_credentials_get_username(gensec_get_credentials(gensec_security)); - if (id != SASL_CB_USER && id != SASL_CB_AUTHNAME) { - return SASL_FAIL; - } - - *result = username; - return SASL_OK; -} - -static int gensec_sasl_get_realm(void *context, int id, - const char **availrealms, - const char **result) -{ - struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security); - const char *realm = cli_credentials_get_realm(gensec_get_credentials(gensec_security)); - int i; - if (id != SASL_CB_GETREALM) { - return SASL_FAIL; - } - - for (i=0; availrealms && availrealms[i]; i++) { - if (strcasecmp_m(realm, availrealms[i]) == 0) { - result[i] = availrealms[i]; - return SASL_OK; - } - } - /* None of the realms match, so lets not specify one */ - *result = ""; - return SASL_OK; -} - -static int gensec_sasl_get_password(sasl_conn_t *conn, void *context, int id, - sasl_secret_t **psecret) -{ - struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security); - const char *password = cli_credentials_get_password(gensec_get_credentials(gensec_security)); - - sasl_secret_t *secret; - if (!password) { - *psecret = NULL; - return SASL_OK; - } - secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)+1); - if (!secret) { - return SASL_NOMEM; - } - secret->len = strlen(password); - strlcpy((char*)secret->data, password, secret->len+1); - *psecret = secret; - return SASL_OK; -} - -static int gensec_sasl_dispose(struct gensec_sasl_state *gensec_sasl_state) -{ - sasl_dispose(&gensec_sasl_state->conn); - return SASL_OK; -} - -static NTSTATUS gensec_sasl_client_start(struct gensec_security *gensec_security) -{ - struct gensec_sasl_state *gensec_sasl_state; - const char *service = gensec_get_target_service(gensec_security); - const char *target_name = gensec_get_target_hostname(gensec_security); - const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security); - const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security); - char *local_addr = NULL; - char *remote_addr = NULL; - int sasl_ret; - - sasl_callback_t *callbacks; - - gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state); - if (!gensec_sasl_state) { - return NT_STATUS_NO_MEMORY; - } - - callbacks = talloc_array(gensec_sasl_state, sasl_callback_t, 5); - callbacks[0].id = SASL_CB_USER; - callbacks[0].proc = gensec_sasl_get_user; - callbacks[0].context = gensec_security; - - callbacks[1].id = SASL_CB_AUTHNAME; - callbacks[1].proc = gensec_sasl_get_user; - callbacks[1].context = gensec_security; - - callbacks[2].id = SASL_CB_GETREALM; - callbacks[2].proc = gensec_sasl_get_realm; - callbacks[2].context = gensec_security; - - callbacks[3].id = SASL_CB_PASS; - callbacks[3].proc = gensec_sasl_get_password; - callbacks[3].context = gensec_security; - - callbacks[4].id = SASL_CB_LIST_END; - callbacks[4].proc = NULL; - callbacks[4].context = NULL; - - gensec_security->private_data = gensec_sasl_state; - - if (tlocal_addr) { - local_addr = talloc_asprintf(gensec_sasl_state, - "%s;%d", - tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state), - tsocket_address_inet_port(tlocal_addr)); - } - - if (tremote_addr) { - remote_addr = talloc_asprintf(gensec_sasl_state, - "%s;%d", - tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state), - tsocket_address_inet_port(tremote_addr)); - } - gensec_sasl_state->step = 0; - - sasl_ret = sasl_client_new(service, - target_name, - local_addr, remote_addr, callbacks, 0, - &gensec_sasl_state->conn); - - if (sasl_ret == SASL_OK) { - sasl_security_properties_t props; - talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose); - - ZERO_STRUCT(props); - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - props.min_ssf = 1; - props.max_ssf = 1; - props.maxbufsize = 65536; - gensec_sasl_state->wrap = true; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - props.min_ssf = 40; - props.max_ssf = UINT_MAX; - props.maxbufsize = 65536; - gensec_sasl_state->wrap = true; - } - - sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props); - } - if (sasl_ret != SASL_OK) { - DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); - } - return sasl_nt_status(sasl_ret); -} - -static NTSTATUS gensec_sasl_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - struct tevent_context *ev, - const DATA_BLOB in, DATA_BLOB *out) -{ - struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data, - struct gensec_sasl_state); - int sasl_ret; - const char *out_data; - unsigned int out_len; - - if (gensec_sasl_state->step == 0) { - const char *mech; - sasl_ret = sasl_client_start(gensec_sasl_state->conn, gensec_security->ops->sasl_name, - NULL, &out_data, &out_len, &mech); - } else { - sasl_ret = sasl_client_step(gensec_sasl_state->conn, - (char*)in.data, in.length, NULL, - &out_data, &out_len); - } - if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) { - *out = data_blob_talloc(out_mem_ctx, out_data, out_len); - } else { - DEBUG(1, ("GENSEC SASL: step %d update failed: %s\n", gensec_sasl_state->step, - sasl_errdetail(gensec_sasl_state->conn))); - } - gensec_sasl_state->step++; - return sasl_nt_status(sasl_ret); -} - -static NTSTATUS gensec_sasl_unwrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data, - struct gensec_sasl_state); - const char *out_data; - unsigned int out_len; - - int sasl_ret = sasl_decode(gensec_sasl_state->conn, - (char*)in->data, in->length, &out_data, - &out_len); - if (sasl_ret == SASL_OK) { - *out = data_blob_talloc(out_mem_ctx, out_data, out_len); - *len_processed = in->length; - } else { - DEBUG(1, ("GENSEC SASL: unwrap failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); - } - return sasl_nt_status(sasl_ret); - -} - -static NTSTATUS gensec_sasl_wrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data, - struct gensec_sasl_state); - const char *out_data; - unsigned int out_len; - unsigned len_permitted; - int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, - (const void**)&len_permitted); - if (sasl_ret != SASL_OK) { - return sasl_nt_status(sasl_ret); - } - len_permitted = MIN(len_permitted, in->length); - - sasl_ret = sasl_encode(gensec_sasl_state->conn, - (char*)in->data, len_permitted, &out_data, - &out_len); - if (sasl_ret == SASL_OK) { - *out = data_blob_talloc(out_mem_ctx, out_data, out_len); - *len_processed = in->length; - } else { - DEBUG(1, ("GENSEC SASL: wrap failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); - } - return sasl_nt_status(sasl_ret); -} - -/* Try to figure out what features we actually got on the connection */ -static bool gensec_sasl_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data, - struct gensec_sasl_state); - sasl_ssf_t ssf; - int sasl_ret; - - /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */ - if (!gensec_sasl_state->wrap) { - return false; - } - - sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, - (const void**)&ssf); - if (sasl_ret != SASL_OK) { - return false; - } - if (feature & GENSEC_FEATURE_SIGN) { - if (ssf == 0) { - return false; - } - if (ssf >= 1) { - return true; - } - } - if (feature & GENSEC_FEATURE_SEAL) { - if (ssf <= 1) { - return false; - } - if (ssf > 1) { - return true; - } - } - return false; -} - -/* This could in theory work with any SASL mech */ -static const struct gensec_security_ops gensec_sasl_security_ops = { - .name = "sasl-DIGEST-MD5", - .sasl_name = "DIGEST-MD5", - .client_start = gensec_sasl_client_start, - .update = gensec_sasl_update, - .wrap_packets = gensec_sasl_wrap_packets, - .unwrap_packets = gensec_sasl_unwrap_packets, - .have_feature = gensec_sasl_have_feature, - .enabled = true, - .priority = GENSEC_SASL -}; - -static int gensec_sasl_log(void *context, - int sasl_log_level, - const char *message) -{ - int dl; - switch (sasl_log_level) { - case SASL_LOG_NONE: - dl = 0; - break; - case SASL_LOG_ERR: - dl = 1; - break; - case SASL_LOG_FAIL: - dl = 2; - break; - case SASL_LOG_WARN: - dl = 3; - break; - case SASL_LOG_NOTE: - dl = 5; - break; - case SASL_LOG_DEBUG: - dl = 10; - break; - case SASL_LOG_TRACE: - dl = 11; - break; -#if DEBUG_PASSWORD - case SASL_LOG_PASS: - dl = 100; - break; -#endif - default: - dl = 0; - break; - } - DEBUG(dl, ("gensec_sasl: %s\n", message)); - - return SASL_OK; -} - -NTSTATUS gensec_sasl_init(void) -{ - NTSTATUS ret; - int sasl_ret; -#if 0 - int i; - const char **sasl_mechs; -#endif - - static const sasl_callback_t callbacks[] = { - { - .id = SASL_CB_LOG, - .proc = gensec_sasl_log, - .context = NULL, - }, - { - .id = SASL_CB_LIST_END, - .proc = gensec_sasl_log, - .context = NULL, - } - }; - sasl_ret = sasl_client_init(callbacks); - - if (sasl_ret == SASL_NOMECH) { - /* Nothing to do here */ - return NT_STATUS_OK; - } - - if (sasl_ret != SASL_OK) { - return sasl_nt_status(sasl_ret); - } - - /* For now, we just register DIGEST-MD5 */ -#if 1 - ret = gensec_register(&gensec_sasl_security_ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_sasl_security_ops.name)); - return ret; - } -#else - sasl_mechs = sasl_global_listmech(); - for (i = 0; sasl_mechs && sasl_mechs[i]; i++) { - const struct gensec_security_ops *oldmech; - struct gensec_security_ops *newmech; - oldmech = gensec_security_by_sasl_name(NULL, sasl_mechs[i]); - if (oldmech) { - continue; - } - newmech = talloc(talloc_autofree_context(), struct gensec_security_ops); - if (!newmech) { - return NT_STATUS_NO_MEMORY; - } - *newmech = gensec_sasl_security_ops; - newmech->sasl_name = talloc_strdup(newmech, sasl_mechs[i]); - newmech->name = talloc_asprintf(newmech, "sasl-%s", sasl_mechs[i]); - if (!newmech->sasl_name || !newmech->name) { - return NT_STATUS_NO_MEMORY; - } - - ret = gensec_register(newmech); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' gensec backend!\n", - gensec_sasl_security_ops.name)); - return ret; - } - } -#endif - return NT_STATUS_OK; -} diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build index cdf1789..46915f0 100755 --- a/source4/auth/gensec/wscript_build +++ b/source4/auth/gensec/wscript_build @@ -22,17 +22,6 @@ bld.SAMBA_MODULE('gensec_gssapi', deps='gssapi samba-credentials authkrb5 com_err gensec_util' ) - -bld.SAMBA_MODULE('cyrus_sasl', - source='cyrus_sasl.c', - subsystem='gensec', - init_function='gensec_sasl_init', - deps='samba-credentials sasl2', - allow_warnings=True, - enabled=bld.CONFIG_SET('HAVE_SASL') - ) - - bld.SAMBA_PYTHON('pygensec', source='pygensec.c', deps='gensec pytalloc-util pyparam_util', diff --git a/source4/auth/wscript_configure b/source4/auth/wscript_configure index 1d26cde..d25cc0b 100644 --- a/source4/auth/wscript_configure +++ b/source4/auth/wscript_configure @@ -2,7 +2,3 @@ conf.CHECK_HEADERS('security/pam_appl.h') conf.CHECK_FUNCS_IN('pam_start', 'pam', checklibc=True) - -if (conf.CHECK_HEADERS('sasl/sasl.h') and - conf.CHECK_FUNCS_IN('sasl_client_init', 'sasl2')): - conf.DEFINE('HAVE_SASL', 1) -- 1.9.1 From c1ba22ec8c82d628e47fab018dc84d49a47b7176 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 13:47:29 +0200 Subject: [PATCH 018/440] s4:auth/gensec: remove unused include of lib/socket/socket.h BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 7943ffbb77bd3ee3a47d20ccdcbbcfe0e2b74b1e) --- source4/auth/gensec/gensec_krb5.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index c34c434..7b9ecfe 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -27,7 +27,6 @@ #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" #include "auth/auth.h" -#include "lib/socket/socket.h" #include "lib/tsocket/tsocket.h" #include "librpc/gen_ndr/dcerpc.h" #include "auth/credentials/credentials.h" -- 1.9.1 From b828c80864d4e5b2f8a3477e1f27c409175c8940 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 12:46:27 +0200 Subject: [PATCH 019/440] s4:auth/gensec: remove unused gensec_socket_init() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 37041e41589d529aedfeb0d39de2d542cd9c8798) --- source4/auth/gensec/gensec_socket.h | 28 --- source4/auth/gensec/socket.c | 435 ------------------------------------ source4/auth/gensec/wscript_build | 2 +- 3 files changed, 1 insertion(+), 464 deletions(-) delete mode 100644 source4/auth/gensec/gensec_socket.h delete mode 100644 source4/auth/gensec/socket.c diff --git a/source4/auth/gensec/gensec_socket.h b/source4/auth/gensec/gensec_socket.h deleted file mode 100644 index bb12cc0..0000000 --- a/source4/auth/gensec/gensec_socket.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - GENSEC socket interface - - Copyright (C) Andrew Bartlett 2006 - - 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 3 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, see . -*/ - -NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - struct socket_context *current_socket, - struct tevent_context *ev, - void (*recv_handler)(void *, uint16_t), - void *recv_private, - struct socket_context **new_socket); diff --git a/source4/auth/gensec/socket.c b/source4/auth/gensec/socket.c deleted file mode 100644 index c89e080..0000000 --- a/source4/auth/gensec/socket.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - GENSEC socket interface - - Copyright (C) Andrew Bartlett 2006 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include "lib/socket/socket.h" -#include "lib/stream/packet.h" -#include "auth/gensec/gensec.h" -#include "auth/gensec/gensec_proto.h" -#include "auth/gensec/gensec_socket.h" - -static const struct socket_ops gensec_socket_ops; - -struct gensec_socket { - struct gensec_security *gensec_security; - struct socket_context *socket; - struct tevent_context *ev; - struct packet_context *packet; - DATA_BLOB read_buffer; /* SASL packets are turned into liniarlised data here, for reading */ - size_t orig_send_len; - bool eof; - NTSTATUS error; - bool interrupted; - void (*recv_handler)(void *, uint16_t); - void *recv_private; - int in_extra_read; - bool wrap; /* Should we be wrapping on this socket at all? */ -}; - -static NTSTATUS gensec_socket_init_fn(struct socket_context *sock) -{ - switch (sock->type) { - case SOCKET_TYPE_STREAM: - break; - default: - return NT_STATUS_INVALID_PARAMETER; - } - - sock->backend_name = "gensec"; - - return NT_STATUS_OK; -} - -static NTSTATUS gensec_socket_full_request(void *private_data, DATA_BLOB blob, size_t *size) -{ - struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket); - struct gensec_security *gensec_security = gensec_socket->gensec_security; - return gensec_packet_full_request(gensec_security, blob, size); -} - -/* Try to figure out how much data is waiting to be read */ -static NTSTATUS gensec_socket_pending(struct socket_context *sock, size_t *npending) -{ - struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket); - if (!gensec_socket->wrap) { - return socket_pending(gensec_socket->socket, npending); - } - - if (gensec_socket->read_buffer.length > 0) { - *npending = gensec_socket->read_buffer.length; - return NT_STATUS_OK; - } - - /* This is a lie. We hope the decrypted data will always be - * less than this value, so the application just gets a short - * read. Without reading and decrypting it, we can't tell. - * If the SASL mech does compression, then we just need to - * manually trigger read events */ - return socket_pending(gensec_socket->socket, npending); -} - -/* Note if an error occours, so we can return it up the stack */ -static void gensec_socket_error_handler(void *private_data, NTSTATUS status) -{ - struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket); - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - gensec_socket->eof = true; - } else { - gensec_socket->error = status; - } -} - -static void gensec_socket_trigger_read(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, void *private_data) -{ - struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket); - - gensec_socket->in_extra_read++; - gensec_socket->recv_handler(gensec_socket->recv_private, TEVENT_FD_READ); - gensec_socket->in_extra_read--; - - /* It may well be that, having run the recv handler, we still - * have even more data waiting for us! - */ - if (gensec_socket->read_buffer.length > 0) { - /* Schedule this funcion to run again */ - tevent_add_timer(gensec_socket->ev, gensec_socket, timeval_zero(), - gensec_socket_trigger_read, gensec_socket); - } -} - -/* These two routines could be changed to use a circular buffer of - * some kind, or linked lists, or ... */ -static NTSTATUS gensec_socket_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread) -{ - struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket); - - if (!gensec_socket->wrap) { - return socket_recv(gensec_socket->socket, buf, wantlen, nread); - } - - gensec_socket->error = NT_STATUS_OK; - - if (gensec_socket->read_buffer.length == 0) { - /* Process any data on the socket, into the read buffer. At - * this point, the socket is not available for read any - * longer */ - packet_recv(gensec_socket->packet); - - if (gensec_socket->eof) { - *nread = 0; - return NT_STATUS_OK; - } - - if (!NT_STATUS_IS_OK(gensec_socket->error)) { - return gensec_socket->error; - } - - if (gensec_socket->read_buffer.length == 0) { - /* Clearly we don't have the entire SASL packet yet, - * so it has not been written into the buffer */ - *nread = 0; - return STATUS_MORE_ENTRIES; - } - } - - - *nread = MIN(wantlen, gensec_socket->read_buffer.length); - memcpy(buf, gensec_socket->read_buffer.data, *nread); - - if (gensec_socket->read_buffer.length > *nread) { - memmove(gensec_socket->read_buffer.data, - gensec_socket->read_buffer.data + *nread, - gensec_socket->read_buffer.length - *nread); - } - - gensec_socket->read_buffer.length -= *nread; - gensec_socket->read_buffer.data = talloc_realloc(gensec_socket, - gensec_socket->read_buffer.data, - uint8_t, - gensec_socket->read_buffer.length); - - if (gensec_socket->read_buffer.length && - gensec_socket->in_extra_read == 0 && - gensec_socket->recv_handler) { - /* Manually call a read event, to get this moving - * again (as the socket should be dry, so the normal - * event handler won't trigger) */ - tevent_add_timer(gensec_socket->ev, gensec_socket, timeval_zero(), - gensec_socket_trigger_read, gensec_socket); - } - - return NT_STATUS_OK; -} - -/* Completed SASL packet callback. When we have a 'whole' SASL - * packet, decrypt it, and add it to the read buffer - * - * This function (and anything under it) MUST NOT call the event system - */ -static NTSTATUS gensec_socket_unwrap(void *private_data, DATA_BLOB blob) -{ - struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket); - DATA_BLOB unwrapped; - NTSTATUS nt_status; - TALLOC_CTX *mem_ctx; - size_t packet_size; - - mem_ctx = talloc_new(gensec_socket); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - nt_status = gensec_unwrap_packets(gensec_socket->gensec_security, - mem_ctx, - &blob, &unwrapped, - &packet_size); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - - if (packet_size != blob.length) { - DEBUG(0, ("gensec_socket_unwrap: Did not consume entire packet!\n")); - talloc_free(mem_ctx); - return NT_STATUS_INTERNAL_ERROR; - } - - /* We could change this into a linked list, and have - * gensec_socket_recv() and gensec_socket_pending() walk the - * linked list */ - - if (!data_blob_append(gensec_socket, &gensec_socket->read_buffer, - unwrapped.data, unwrapped.length)) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - talloc_free(mem_ctx); - return NT_STATUS_OK; -} - -/* when the data is sent, we know we have not been interrupted */ -static void send_callback(void *private_data) -{ - struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket); - gensec_socket->interrupted = false; -} - -/* - send data, but only as much as we allow in one packet. - - If this returns STATUS_MORE_ENTRIES, the caller must retry with - exactly the same data, or a NULL blob. -*/ -static NTSTATUS gensec_socket_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen) -{ - NTSTATUS nt_status; - struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket); - DATA_BLOB wrapped; - TALLOC_CTX *mem_ctx; - - if (!gensec_socket->wrap) { - return socket_send(gensec_socket->socket, blob, sendlen); - } - - *sendlen = 0; - - /* We have have been interupted, so the caller should be - * giving us the same data again. */ - if (gensec_socket->interrupted) { - packet_queue_run(gensec_socket->packet); - - if (!NT_STATUS_IS_OK(gensec_socket->error)) { - return gensec_socket->error; - } else if (gensec_socket->interrupted) { - return STATUS_MORE_ENTRIES; - } else { - *sendlen = gensec_socket->orig_send_len; - gensec_socket->orig_send_len = 0; - return NT_STATUS_OK; - } - } - - mem_ctx = talloc_new(gensec_socket); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = gensec_wrap_packets(gensec_socket->gensec_security, - mem_ctx, - blob, &wrapped, - &gensec_socket->orig_send_len); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - - gensec_socket->interrupted = true; - gensec_socket->error = NT_STATUS_OK; - - nt_status = packet_send_callback(gensec_socket->packet, - wrapped, - send_callback, gensec_socket); - - talloc_free(mem_ctx); - - packet_queue_run(gensec_socket->packet); - - if (!NT_STATUS_IS_OK(gensec_socket->error)) { - return gensec_socket->error; - } else if (gensec_socket->interrupted) { - return STATUS_MORE_ENTRIES; - } else { - *sendlen = gensec_socket->orig_send_len; - gensec_socket->orig_send_len = 0; - return NT_STATUS_OK; - } -} - -/* Turn a normal socket into a potentially GENSEC wrapped socket */ -/* CAREFUL: this function will steal 'current_socket' */ - -NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - struct socket_context *current_socket, - struct tevent_context *ev, - void (*recv_handler)(void *, uint16_t), - void *recv_private, - struct socket_context **new_socket) -{ - struct gensec_socket *gensec_socket; - struct socket_context *new_sock; - NTSTATUS nt_status; - - nt_status = socket_create_with_ops(mem_ctx, &gensec_socket_ops, &new_sock, - SOCKET_TYPE_STREAM, current_socket->flags | SOCKET_FLAG_ENCRYPT); - if (!NT_STATUS_IS_OK(nt_status)) { - *new_socket = NULL; - return nt_status; - } - - new_sock->state = current_socket->state; - - gensec_socket = talloc(new_sock, struct gensec_socket); - if (gensec_socket == NULL) { - *new_socket = NULL; - talloc_free(new_sock); - return NT_STATUS_NO_MEMORY; - } - - new_sock->private_data = gensec_socket; - gensec_socket->socket = current_socket; - - /* Nothing to do here, if we are not actually wrapping on this socket */ - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) && - !gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - - gensec_socket->wrap = false; - talloc_steal(gensec_socket, current_socket); - *new_socket = new_sock; - return NT_STATUS_OK; - } - - gensec_socket->gensec_security = gensec_security; - - gensec_socket->wrap = true; - gensec_socket->eof = false; - gensec_socket->error = NT_STATUS_OK; - gensec_socket->interrupted = false; - gensec_socket->in_extra_read = 0; - - gensec_socket->read_buffer = data_blob(NULL, 0); - - gensec_socket->recv_handler = recv_handler; - gensec_socket->recv_private = recv_private; - gensec_socket->ev = ev; - - gensec_socket->packet = packet_init(gensec_socket); - if (gensec_socket->packet == NULL) { - *new_socket = NULL; - talloc_free(new_sock); - return NT_STATUS_NO_MEMORY; - } - - packet_set_private(gensec_socket->packet, gensec_socket); - packet_set_socket(gensec_socket->packet, gensec_socket->socket); - packet_set_callback(gensec_socket->packet, gensec_socket_unwrap); - packet_set_full_request(gensec_socket->packet, gensec_socket_full_request); - packet_set_error_handler(gensec_socket->packet, gensec_socket_error_handler); - packet_set_serialise(gensec_socket->packet); - - /* TODO: full-request that knows about maximum packet size */ - - talloc_steal(gensec_socket, current_socket); - *new_socket = new_sock; - return NT_STATUS_OK; -} - - -static NTSTATUS gensec_socket_set_option(struct socket_context *sock, const char *option, const char *val) -{ - set_socket_options(socket_get_fd(sock), option); - return NT_STATUS_OK; -} - -static char *gensec_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket); - return socket_get_peer_name(gensec->socket, mem_ctx); -} - -static struct socket_address *gensec_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket); - return socket_get_peer_addr(gensec->socket, mem_ctx); -} - -static struct socket_address *gensec_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket); - return socket_get_my_addr(gensec->socket, mem_ctx); -} - -static int gensec_socket_get_fd(struct socket_context *sock) -{ - struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket); - return socket_get_fd(gensec->socket); -} - -static const struct socket_ops gensec_socket_ops = { - .name = "gensec", - .fn_init = gensec_socket_init_fn, - .fn_recv = gensec_socket_recv, - .fn_send = gensec_socket_send, - .fn_pending = gensec_socket_pending, - - .fn_set_option = gensec_socket_set_option, - - .fn_get_peer_name = gensec_socket_get_peer_name, - .fn_get_peer_addr = gensec_socket_get_peer_addr, - .fn_get_my_addr = gensec_socket_get_my_addr, - .fn_get_fd = gensec_socket_get_fd -}; - diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build index 46915f0..3c7cc2e 100755 --- a/source4/auth/gensec/wscript_build +++ b/source4/auth/gensec/wscript_build @@ -1,7 +1,7 @@ #!/usr/bin/env python bld.SAMBA_SUBSYSTEM('gensec_util', - source='socket.c gensec_tstream.c', + source='gensec_tstream.c', deps='tevent-util tevent samba-util LIBTSOCKET', autoproto='gensec_proto.h') -- 1.9.1 From a0dc93073c4ea1736047f18c674c74ff7d4dc722 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jun 2015 12:47:10 +0200 Subject: [PATCH 020/440] auth/gensec: remove unused gensec_[un]wrap_packets() hooks BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 2cd3e51e19c0ae851ea2f294125c387f72d4432c) --- auth/gensec/gensec.h | 21 -------- auth/gensec/gensec_internal.h | 12 ----- auth/gensec/gensec_util.c | 116 ------------------------------------------ auth/gensec/spnego.c | 56 -------------------- auth/gensec/wscript_build | 2 +- 5 files changed, 1 insertion(+), 206 deletions(-) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index 0d3a29c..d09813e 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -107,30 +107,9 @@ const struct gensec_critical_sizes *gensec_interface_version(void); /* Socket wrapper */ struct gensec_security; -struct socket_context; struct auth4_context; struct auth_user_info_dc; -/* These functions are for use here only (public because SPNEGO must - * use them for recursion) */ -NTSTATUS gensec_wrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed); -/* These functions are for use here only (public because SPNEGO must - * use them for recursion) */ -NTSTATUS gensec_unwrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed); - -/* These functions are for use here only (public because SPNEGO must - * use them for recursion) */ -NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security, - DATA_BLOB blob, size_t *size); - struct loadparm_context; NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index c04164a..45a66f8 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -74,18 +74,6 @@ struct gensec_security_ops { TALLOC_CTX *mem_ctx, const DATA_BLOB *in, DATA_BLOB *out); - NTSTATUS (*wrap_packets)(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed); - NTSTATUS (*unwrap_packets)(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed); - NTSTATUS (*packet_full_request)(struct gensec_security *gensec_security, - DATA_BLOB blob, size_t *size); NTSTATUS (*session_key)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c index b8e38b7..8ef4b25 100644 --- a/auth/gensec/gensec_util.c +++ b/auth/gensec/gensec_util.c @@ -68,122 +68,6 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, } /* - * These functions are for use in the deprecated - * gensec_socket code (public because SPNEGO must - * use them for recursion) - */ -_PUBLIC_ NTSTATUS gensec_wrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - if (!gensec_security->ops->wrap_packets) { - NTSTATUS nt_status; - size_t max_input_size; - DATA_BLOB unwrapped, wrapped; - max_input_size = gensec_max_input_size(gensec_security); - unwrapped = data_blob_const(in->data, MIN(max_input_size, (size_t)in->length)); - - nt_status = gensec_wrap(gensec_security, - mem_ctx, - &unwrapped, &wrapped); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - *out = data_blob_talloc(mem_ctx, NULL, 4); - if (!out->data) { - return NT_STATUS_NO_MEMORY; - } - RSIVAL(out->data, 0, wrapped.length); - - if (!data_blob_append(mem_ctx, out, wrapped.data, wrapped.length)) { - return NT_STATUS_NO_MEMORY; - } - *len_processed = unwrapped.length; - return NT_STATUS_OK; - } - return gensec_security->ops->wrap_packets(gensec_security, mem_ctx, in, out, - len_processed); -} - -/* - * These functions are for use in the deprecated - * gensec_socket code (public because SPNEGO must - * use them for recursion) - */ -NTSTATUS gensec_unwrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - if (!gensec_security->ops->unwrap_packets) { - DATA_BLOB wrapped; - NTSTATUS nt_status; - size_t packet_size; - if (in->length < 4) { - /* Missing the header we already had! */ - DEBUG(0, ("Asked to unwrap packet of bogus length! How did we get the short packet?!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - packet_size = RIVAL(in->data, 0); - - wrapped = data_blob_const(in->data + 4, packet_size); - - if (wrapped.length > (in->length - 4)) { - DEBUG(0, ("Asked to unwrap packed of bogus length %d > %d! How did we get this?!\n", - (int)wrapped.length, (int)(in->length - 4))); - return NT_STATUS_INTERNAL_ERROR; - } - - nt_status = gensec_unwrap(gensec_security, - mem_ctx, - &wrapped, out); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - *len_processed = packet_size + 4; - return nt_status; - } - return gensec_security->ops->unwrap_packets(gensec_security, mem_ctx, in, out, - len_processed); -} - -/* - * These functions are for use in the deprecated - * gensec_socket code (public because SPNEGO must - * use them for recursion) - */ -NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security, - DATA_BLOB blob, size_t *size) -{ - if (gensec_security->ops->packet_full_request) { - return gensec_security->ops->packet_full_request(gensec_security, - blob, size); - } - if (gensec_security->ops->unwrap_packets) { - if (blob.length) { - *size = blob.length; - return NT_STATUS_OK; - } - return STATUS_MORE_ENTRIES; - } - - if (blob.length < 4) { - return STATUS_MORE_ENTRIES; - } - *size = 4 + RIVAL(blob.data, 0); - if (*size > blob.length) { - return STATUS_MORE_ENTRIES; - } - return NT_STATUS_OK; -} - -/* magic check a GSS-API wrapper packet for an Kerberos OID */ static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 8fd11e9..fe2ec43 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -221,59 +221,6 @@ static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security, mem_ctx, in, out); } -static NTSTATUS gensec_spnego_wrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_wrap: wrong state for wrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_wrap_packets(spnego_state->sub_sec_security, - mem_ctx, in, out, - len_processed); -} - -static NTSTATUS gensec_spnego_packet_full_request(struct gensec_security *gensec_security, - DATA_BLOB blob, size_t *size) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_packet_full_request(spnego_state->sub_sec_security, - blob, size); -} - -static NTSTATUS gensec_spnego_unwrap_packets(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out, - size_t *len_processed) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_unwrap_packets(spnego_state->sub_sec_security, - mem_ctx, in, out, - len_processed); -} - static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security, size_t data_size) { struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; @@ -1384,11 +1331,8 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .max_input_size = gensec_spnego_max_input_size, .check_packet = gensec_spnego_check_packet, .unseal_packet = gensec_spnego_unseal_packet, - .packet_full_request = gensec_spnego_packet_full_request, .wrap = gensec_spnego_wrap, .unwrap = gensec_spnego_unwrap, - .wrap_packets = gensec_spnego_wrap_packets, - .unwrap_packets = gensec_spnego_unwrap_packets, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, .want_feature = gensec_spnego_want_feature, diff --git a/auth/gensec/wscript_build b/auth/gensec/wscript_build index b2f6033..413c606 100755 --- a/auth/gensec/wscript_build +++ b/auth/gensec/wscript_build @@ -3,7 +3,7 @@ bld.SAMBA_LIBRARY('gensec', source='gensec.c gensec_start.c gensec_util.c', pc_files='gensec.pc', autoproto='gensec_toplevel_proto.h', - public_deps='tevent-util samba-util errors LIBPACKET auth_system_session samba-modules gensec_util asn1util', + public_deps='tevent-util samba-util errors auth_system_session samba-modules gensec_util asn1util', public_headers='gensec.h', deps='com_err', vnum='0.0.1' -- 1.9.1 From 610ad1ed8d2a50e24065edfc825caf4303ca185d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Jun 2015 16:54:33 +0200 Subject: [PATCH 021/440] s3:ntlm_auth: don't start gensec backend twice ntlm_auth_start_ntlmssp_server() was used in two cases and both call gensec_start_mech_by_oid() again. So we remove gensec_start_mech_by_oid() and rename the function to ntlm_auth_prepare_gensec_server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 965d9ce5559f01bc8f2e0d5fc95547a9ea7d5078) --- source3/utils/ntlm_auth.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 3906f38..1fe7d56 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1027,9 +1027,9 @@ static struct auth4_context *make_auth4_context_ntlm_auth(TALLOC_CTX *mem_ctx, b return auth4_context; } -static NTSTATUS ntlm_auth_start_ntlmssp_server(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx, - struct gensec_security **gensec_security_out) +static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct gensec_security **gensec_security_out) { struct gensec_security *gensec_security; NTSTATUS nt_status; @@ -1135,12 +1135,6 @@ static NTSTATUS ntlm_auth_start_ntlmssp_server(TALLOC_CTX *mem_ctx, talloc_unlink(tmp_ctx, gensec_settings); talloc_unlink(tmp_ctx, auth4_context); - nt_status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_NTLMSSP); - if (!NT_STATUS_IS_OK(nt_status)) { - TALLOC_FREE(tmp_ctx); - return nt_status; - } - *gensec_security_out = talloc_steal(mem_ctx, gensec_security); TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; @@ -1541,8 +1535,8 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, case GSS_SPNEGO_SERVER: case SQUID_2_5_NTLMSSP: { - nt_status = ntlm_auth_start_ntlmssp_server(state, lp_ctx, - &state->gensec_state); + nt_status = ntlm_auth_prepare_gensec_server(state, lp_ctx, + &state->gensec_state); if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH GENSEC mech failed to start: %s\n", nt_errstr(nt_status)); talloc_free(mem_ctx); -- 1.9.1 From 6956379a93cb43df33af7acd0cc50b103c3de817 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Jun 2015 20:30:43 +0200 Subject: [PATCH 022/440] auth/credentials: anonymous should not try to use kerberos BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit f3f1c3892596e438c716172c053a016ee4ba464a) --- auth/credentials/credentials.c | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index e988d2d3..7c7e4d5 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -900,6 +900,7 @@ _PUBLIC_ void cli_credentials_set_anonymous(struct cli_credentials *cred) cli_credentials_set_password(cred, NULL, CRED_SPECIFIED); cli_credentials_set_realm(cred, NULL, CRED_SPECIFIED); cli_credentials_set_workstation(cred, "", CRED_UNINITIALISED); + cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS); } /** -- 1.9.1 From d9441f5adb450b41a7e319076345e3f83b5b1434 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Sep 2014 21:53:46 +0200 Subject: [PATCH 023/440] midltests: add valid/midltests_DRS_EXTENSIONS.* BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit cb8c156671530296b746d8b71fd62e677fa88cd0) --- .../midltests/valid/midltests_DRS_EXTENSIONS.idl | 64 ++++++++++++++++++++++ .../midltests/valid/midltests_DRS_EXTENSIONS.out | 43 +++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl create mode 100644 testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out diff --git a/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl new file mode 100644 index 0000000..73aeb16 --- /dev/null +++ b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl @@ -0,0 +1,64 @@ +#ifndef MIDLTESTS_C_CODE + +/* + * For midltests_tcp.exe you may want to + * redirect the traffic via rinetd + * with a /etc/rinetd.conf like this: + * + * 172.31.9.1 5032 172.31.9.8 5032 + * 172.31.9.1 5064 172.31.9.8 5064 + * + * This is useful to watch the traffic with + * a network sniffer. + */ +/* +cpp_quote("#define LISTEN_IP \"0.0.0.0\"") +cpp_quote("#define FORWARD_IP \"127.0.0.1\"") +cpp_quote("#define CONNECT_IP \"172.31.9.1\"") +*/ + +/* + * With midltests_tcp.exe NDR64 is enforced by default. + * For testing it might be needed to allow downgrades + * to NDR32. This is needed when you use 'pipe'. + */ +//cpp_quote("#define DONOT_FORCE_NDR64 1") + +[ + uuid("225b9fcb-eb3d-497b-8b0b-591f049a2507"), + pointer_default(unique) +] +interface midltests +{ + + typedef struct { + [range(1,10000)] long cb; + [size_is(cb)] char rcg[]; + } DRS_EXTENSIONS; + + long midltests_fn( + [out] DRS_EXTENSIONS **e + ); +} + +#elif MIDLTESTS_C_CODE + +static void midltests(void) +{ + DRS_EXTENSIONS *e = NULL; + cli_midltests_fn(&e); +} + +long srv_midltests_fn(DRS_EXTENSIONS **_e) +{ + DRS_EXTENSIONS *e; + printf("srv_midltests_fn: Start\n"); + e = (DRS_EXTENSIONS *)malloc(sizeof(DRS_EXTENSIONS) + 0x34); + e->cb = 0x34; + memset(e->rcg, 0xcd, e->cb); + *_e = e; + printf("srv_midltests_fn: End\n"); + return 0x65757254; +} + +#endif diff --git a/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out new file mode 100644 index 0000000..e0b3a0e --- /dev/null +++ b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out @@ -0,0 +1,43 @@ +Wait for setup of server threads + +Test NDR32 + +ndr32: disable NDR64 + +ndr32:in => out: ptype[request] flen[24] plen[0] ahint[0] + + +srv_midltests_fn: Start +srv_midltests_fn: End + +ndr32:out => in: ptype[response] flen[92] plen[68] ahint[68] + +[000] 00 00 02 00 34 00 00 00 34 00 00 00 CD CD CD CD ....4... 4....... +[010] CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........ +[020] CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........ +[030] CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........ +[040] 54 72 75 65 True + +NDRTcpThread[ndr32] stop + +Test NDR64 + +ndr64: got NDR64 + +ndr64:in => out: ptype[request] flen[24] plen[0] ahint[0] + + +srv_midltests_fn: Start +srv_midltests_fn: End + +ndr64:out => in: ptype[response] flen[100] plen[76] ahint[76] + +[000] 00 00 02 00 00 00 00 00 34 00 00 00 00 00 00 00 ........ 4....... +[010] 34 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD 4....... ........ +[020] CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........ +[030] CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........ +[040] CD CD CD CD CD CD CD CD 54 72 75 65 ........ True + +NDRTcpThread[ndr64] stop + +Test OK -- 1.9.1 From c30fb1a1cf209b824fd738f5073e160339278f41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Mar 2014 22:17:11 +0100 Subject: [PATCH 024/440] librpc/rpc: add faultcode to nt_status mappings BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 1eef70872930fa4f9d3dedd23476b34cae638428) --- librpc/rpc/dcerpc_error.c | 143 ++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 68 deletions(-) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index 4f0ed6e..3366f63 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -26,58 +26,72 @@ struct dcerpc_fault_table { const char *errstr; uint32_t faultcode; + NTSTATUS nt_status; }; static const struct dcerpc_fault_table dcerpc_faults[] = { -#define _FAULT_STR(x) { #x , x } - _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE), - _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR), - _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF), - _FAULT_STR(DCERPC_NCA_S_WRONG_BOOT_TIME), - _FAULT_STR(DCERPC_NCA_S_YOU_CRASHED), - _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR), - _FAULT_STR(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), - _FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY), - _FAULT_STR(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), - _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_TYPE), - _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO), - _FAULT_STR(DCERPC_NCA_S_FAULT_ADDR_ERROR), - _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO), - _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW), - _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW), - _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG), - _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND), - _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH), - _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC_REJECT), - _FAULT_STR(DCERPC_NCA_S_FAULT_BAD_ACTID), - _FAULT_STR(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED), - _FAULT_STR(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED), - _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL), - _FAULT_STR(DCERPC_NCA_S_FAULT_ILL_INST), - _FAULT_STR(DCERPC_NCA_S_FAULT_FP_ERROR), - _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW), - _FAULT_STR(DCERPC_NCA_S_UNUSED_1C000011), - _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC), - _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_EMPTY), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_ORDER), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR), - _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_MEMORY), - _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH), - _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY), - _FAULT_STR(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID), - _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL), - _FAULT_STR(DCERPC_NCA_S_UNUSED_1C00001E), - _FAULT_STR(DCERPC_NCA_S_INVALID_CHECKSUM), - _FAULT_STR(DCERPC_NCA_S_INVALID_CRC), - _FAULT_STR(DCERPC_NCA_S_FAULT_USER_DEFINED), - _FAULT_STR(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED), - _FAULT_STR(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR), - _FAULT_STR(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), - _FAULT_STR(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), +#define _FAULT_STR(x, s) { .errstr = #x , .faultcode = x, .nt_status = s } +#define _FAULT_STR_NO_NT_MAPPING(x) _FAULT_STR(x, NT_STATUS_RPC_NOT_RPC_ERROR) + _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE, NT_STATUS_RPC_COMM_FAILURE), + _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE), + _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF, NT_STATUS_RPC_UNKNOWN_IF), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_WRONG_BOOT_TIME), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_YOU_CRASHED), + _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR, NT_STATUS_RPC_PROTOCOL_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_SERVER_TOO_BUSY), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR), + _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO), + _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW, NT_STATUS_RPC_FP_UNDERFLOW), + _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW, NT_STATUS_RPC_FP_OVERFLOW), + _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO), + _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW, NT_STATUS_RPC_FP_OVERFLOW), + /* + * What's the difference between NT_STATUS_RPC_INVALID_TAG + * and NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ??? + * + * Our callers expect NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE. + */ + _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE), + _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_INVALID_TAG), + _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND, NT_STATUS_RPC_INVALID_BOUND), + _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH, NT_STATUS_RPC_PROTOCOL_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC_REJECT), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_BAD_ACTID), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED), + _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL, NT_STATUS_RPC_CALL_CANCELLED), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ILL_INST), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_FP_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C000011), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_EMPTY), + _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED, NT_STATUS_RPC_PIPE_CLOSED), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_ORDER), + _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE, NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_MEMORY), + _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH, NT_STATUS_RPC_SS_CONTEXT_MISMATCH), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID), + _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL, NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C00001E), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CHECKSUM), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CRC), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_USER_DEFINED), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), + _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), + _FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED), + _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), + _FAULT_STR(DCERPC_FAULT_NDR, NT_STATUS_RPC_BAD_STUB_DATA), + _FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED), + _FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR), { NULL, 0 } #undef _FAULT_STR }; @@ -99,26 +113,19 @@ _PUBLIC_ const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code) _PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code) { - /* TODO: add more mappings */ - switch (fault_code) { - case DCERPC_NCA_S_OP_RNG_ERROR: - return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE; - case DCERPC_NCA_S_UNKNOWN_IF: - return NT_STATUS_RPC_UNKNOWN_IF; - case DCERPC_FAULT_NDR: - return NT_STATUS_RPC_BAD_STUB_DATA; - case DCERPC_NCA_S_FAULT_INVALID_TAG: - return NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE; - case DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH: - return NT_STATUS_RPC_SS_CONTEXT_MISMATCH; - case DCERPC_FAULT_OTHER: - return NT_STATUS_RPC_CALL_FAILED; - case DCERPC_FAULT_ACCESS_DENIED: - return NT_STATUS_ACCESS_DENIED; - case DCERPC_FAULT_SEC_PKG_ERROR: - return NT_STATUS_RPC_SEC_PKG_ERROR; + int idx = 0; + WERROR werr = W_ERROR(fault_code); + + if (fault_code == 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; } - return NT_STATUS_RPC_PROTOCOL_ERROR; -} + while (dcerpc_faults[idx].errstr != NULL) { + if (dcerpc_faults[idx].faultcode == fault_code) { + return dcerpc_faults[idx].nt_status; + } + idx++; + } + return werror_to_ntstatus(werr); +} -- 1.9.1 From cae06c2e74dcab2c611c496548522ae7cb5d186f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Mar 2014 22:22:58 +0100 Subject: [PATCH 025/440] librpc/rpc: add dcerpc_fault_from_nt_status() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 18dce19ef988d5398ba3f3ae59931b121dd85e3d) --- librpc/rpc/dcerpc_error.c | 21 +++++++++++++++++++++ librpc/rpc/rpc_common.h | 1 + 2 files changed, 22 insertions(+) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index 3366f63..2b90334 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -129,3 +129,24 @@ _PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code) return werror_to_ntstatus(werr); } + +_PUBLIC_ uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status) +{ + int idx = 0; + WERROR werr; + + if (NT_STATUS_IS_OK(nt_status)) { + return DCERPC_NCA_S_PROTO_ERROR; + } + + while (dcerpc_faults[idx].errstr != NULL) { + if (NT_STATUS_EQUAL(dcerpc_faults[idx].nt_status, nt_status)) { + return dcerpc_faults[idx].faultcode; + } + idx++; + } + + werr = ntstatus_to_werror(nt_status); + + return W_ERROR_V(werr); +} diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 45d3691..aa28bd2 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -106,6 +106,7 @@ struct dcerpc_binding; const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code); NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code); +uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status); /* The following definitions come from ../librpc/rpc/binding.c */ -- 1.9.1 From f4e9b95efee3f99a5739d6507ae5d102d37856dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jan 2014 12:35:58 +0100 Subject: [PATCH 026/440] librpc/rpc: add dcerpc_[extract|construct]_bind_time_features() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit e1498ac674ed099394777e10065b34805bd24054) --- librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ librpc/rpc/rpc_common.h | 30 +++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index a4dd569..696bcda 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -652,3 +652,66 @@ bool dcerpc_sec_verification_trailer_check( return true; } + +static const struct ndr_syntax_id dcerpc_bind_time_features_prefix = { + .uuid = { + .time_low = 0x6cb71c2c, + .time_mid = 0x9812, + .time_hi_and_version = 0x4540, + .clock_seq = {0x00, 0x00}, + .node = {0x00,0x00,0x00,0x00,0x00,0x00} + }, + .if_version = 1, +}; + +bool dcerpc_extract_bind_time_features(struct ndr_syntax_id s, uint64_t *_features) +{ + uint8_t values[8]; + uint64_t features = 0; + + values[0] = s.uuid.clock_seq[0]; + values[1] = s.uuid.clock_seq[1]; + values[2] = s.uuid.node[0]; + values[3] = s.uuid.node[1]; + values[4] = s.uuid.node[2]; + values[5] = s.uuid.node[3]; + values[6] = s.uuid.node[4]; + values[7] = s.uuid.node[5]; + + ZERO_STRUCT(s.uuid.clock_seq); + ZERO_STRUCT(s.uuid.node); + + if (!ndr_syntax_id_equal(&s, &dcerpc_bind_time_features_prefix)) { + if (_features != NULL) { + *_features = 0; + } + return false; + } + + features = BVAL(values, 0); + + if (_features != NULL) { + *_features = features; + } + + return true; +} + +struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features) +{ + struct ndr_syntax_id s = dcerpc_bind_time_features_prefix; + uint8_t values[8]; + + SBVAL(values, 0, features); + + s.uuid.clock_seq[0] = values[0]; + s.uuid.clock_seq[1] = values[1]; + s.uuid.node[0] = values[2]; + s.uuid.node[1] = values[3]; + s.uuid.node[2] = values[4]; + s.uuid.node[3] = values[5]; + s.uuid.node[4] = values[6]; + s.uuid.node[5] = values[7]; + + return s; +} diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index aa28bd2..a515ddd 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -371,6 +371,36 @@ bool dcerpc_sec_verification_trailer_check( const struct dcerpc_sec_vt_pcontext *pcontext, const struct dcerpc_sec_vt_header2 *header2); +/** + * @brief check and optionally extract the Bind Time Features from + * the given ndr_syntax_id. + * + * MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation. + * + * @param[in] s the syntax that should be checked. + * + * @param[out] features This is optional, it will be filled with the extracted + * features the on success, otherwise it's filled with 0. + * + * @return true if the syntax matches the 6CB71C2C-9812-4540 prefix with version 1, false otherwise. + * + * @see dcerpc_construct_bind_time_features + */ +bool dcerpc_extract_bind_time_features(struct ndr_syntax_id syntax, uint64_t *features); + +/** + * @brief Construct a ndr_syntax_id used for Bind Time Features Negotiation. + * + * MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation. + * + * @param[in] features The supported features. + * + * @return The ndr_syntax_id with the given features. + * + * @see dcerpc_extract_bind_time_features + */ +struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features); + #define DCERPC_AUTH_PAD_LENGTH(stub_length) (\ (((stub_length) % DCERPC_AUTH_PAD_ALIGNMENT) > 0)?\ (DCERPC_AUTH_PAD_ALIGNMENT - (stub_length) % DCERPC_AUTH_PAD_ALIGNMENT):\ -- 1.9.1 From 6fbc937a7f911827b25ea73dbc5aa602ed27bb6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Apr 2014 19:53:18 +0200 Subject: [PATCH 027/440] s4:pyrpc: add base.bind_time_features_syntax(features) BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 8c9612e1144e33aafd94f28fb7fa4b6b8444b05c) --- source4/librpc/rpc/pyrpc.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 09f6632..12199d4 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -398,6 +398,45 @@ static PyTypeObject py_transfer_syntax_ndr64_SyntaxType = { .tp_new = py_transfer_syntax_ndr64_new, }; +static PyObject *py_bind_time_features_syntax_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + const char *kwnames[] = { + "features", NULL + }; + unsigned long long features = 0; + struct ndr_syntax_id syntax; + PyObject *args2 = Py_None; + PyObject *kwargs2 = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "K:features", discard_const_p(char *, kwnames), &features)) { + return NULL; + } + + args2 = Py_BuildValue("()"); + if (args2 == NULL) { + return NULL; + } + + kwargs2 = Py_BuildValue("{}"); + if (kwargs2 == NULL) { + Py_DECREF(args2); + return NULL; + } + + syntax = dcerpc_construct_bind_time_features(features); + + return py_dcerpc_syntax_init_helper(type, args2, kwargs2, &syntax); +} + +static PyTypeObject py_bind_time_features_syntax_SyntaxType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "base.bind_time_features_syntax", + .tp_basicsize = sizeof(pytalloc_Object), + .tp_doc = "bind_time_features_syntax(features)\n", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_new = py_bind_time_features_syntax_new, +}; + void initbase(void) { PyObject *m; @@ -413,6 +452,7 @@ void initbase(void) py_transfer_syntax_ndr_SyntaxType.tp_base = ndr_syntax_id_Type; py_transfer_syntax_ndr64_SyntaxType.tp_base = ndr_syntax_id_Type; + py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type; if (PyType_Ready(&dcerpc_InterfaceType) < 0) return; @@ -421,6 +461,8 @@ void initbase(void) return; if (PyType_Ready(&py_transfer_syntax_ndr64_SyntaxType) < 0) return; + if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0) + return; m = Py_InitModule3("base", NULL, "DCE/RPC protocol implementation"); if (m == NULL) @@ -433,4 +475,6 @@ void initbase(void) PyModule_AddObject(m, "transfer_syntax_ndr", (PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType); Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType); PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType); + Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType); + PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType); } -- 1.9.1 From 5895a8b30f5c339adba413bc71872985746b805f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Jun 2015 13:53:41 +0200 Subject: [PATCH 028/440] lib/util: fix output format in dump_data*() This changes: [0000] 4E 54 4C 4D 53 53 50 00 01 00 00 00 05 82 08 60 NTLMSSP. .......` [0010] 09 00 09 00 20 00 00 00 00 00 00 00 29 00 00 00 .... ... ....)... [0020] 57 4F 52 4B 47 52 4F 55 50 WORKGROU P into: [0000] 4E 54 4C 4D 53 53 50 00 01 00 00 00 05 82 08 60 NTLMSSP. .......` [0010] 09 00 09 00 20 00 00 00 00 00 00 00 29 00 00 00 .... ... ....)... [0020] 57 4F 52 4B 47 52 4F 55 50 WORKGROU P Note the alignment of 'WORKGROU P'. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 4a0370bdfdb599aa1798855a6074210583dd7cc4) --- lib/util/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/util.c b/lib/util/util.c index 21d55c6..e21c364 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -530,7 +530,7 @@ void dump_data_cb(const uint8_t *buf, int len, if (i%16) { int n; n = 16 - (i%16); - cb(" ", private_data); + cb(" ", private_data); if (n>8) { cb(" ", private_data); } -- 1.9.1 From 0330ad211f620446d8449b29c430527dbf45f527 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Jun 2015 14:05:37 +0200 Subject: [PATCH 029/440] librpc/ndr: make use of dump_data_cb() in ndr_dump_data() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 2b163012aa243e682c5ba7bb23f1af265783a940) --- librpc/ndr/ndr_basic.c | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c index a6cf607..ea3a2d4 100644 --- a/librpc/ndr/ndr_basic.c +++ b/librpc/ndr/ndr_basic.c @@ -1204,11 +1204,11 @@ _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, #undef _ONELINE_LIMIT } -static void ndr_print_asc(struct ndr_print *ndr, const uint8_t *buf, int len) +static void ndr_print_dump_data_cb(const char *buf, void *private_data) { - int i; - for (i=0;iprint(ndr, "%c", isprint(buf[i])?buf[i]:'.'); + struct ndr_print *ndr = (struct ndr_print *)private_data; + + ndr->print(ndr, "%s", buf); } /* @@ -1216,37 +1216,8 @@ static void ndr_print_asc(struct ndr_print *ndr, const uint8_t *buf, int len) */ static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len) { - int i=0; - ndr->no_newline = true; - - for (i=0;iprint(ndr, "[%04X] ",i); - } - - ndr->print(ndr, "%02X ",(int)buf[i]); - i++; - if (i%8 == 0) ndr->print(ndr," "); - if (i%16 == 0) { - ndr_print_asc(ndr,&buf[i-16],8); ndr->print(ndr," "); - ndr_print_asc(ndr,&buf[i-8],8); ndr->print(ndr, "\n"); - } - } - - if (i%16) { - int n; - n = 16 - (i%16); - ndr->print(ndr, " "); - if (n>8) ndr->print(ndr," "); - while (n--) ndr->print(ndr," "); - n = MIN(8,i%16); - ndr_print_asc(ndr,&buf[i-(i%16)],n); ndr->print(ndr, " "); - n = (i%16) - n; - if (n>0) ndr_print_asc(ndr,&buf[i-n],n); - ndr->print(ndr,"\n"); - } - + dump_data_cb(buf, len, true, ndr_print_dump_data_cb, ndr); ndr->no_newline = false; } -- 1.9.1 From 9e8cd40479e5b7c421ae12b50ee0ffb77bb89f1f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Nov 2014 20:37:41 +0000 Subject: [PATCH 030/440] Reduce number of places where sys.path is (possibly) updated for external module paths. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I69d060f27ea090d14405e884d1ce271975358c56 Signed-Off-By: Jelmer Vernooij Reviewed-by: Andrew Bartlett Autobuild-User(master): Jelmer Vernooij Autobuild-Date(master): Sun Nov 30 20:54:04 CET 2014 on sn-devel-104 (cherry picked from commit 7dbc58f524fbde517966d671da138b69566929d7) --- python/samba/tests/__init__.py | 2 ++ python/samba/tests/subunitrun.py | 4 +--- selftest/filter-subunit | 11 ++++++----- selftest/format-subunit | 10 ++++++---- source4/dsdb/tests/python/dsdb_schema_info.py | 3 +-- source4/torture/drs/python/drs_base.py | 6 +----- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 8d3b4dd..8e662ed 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -26,6 +26,8 @@ from samba.samdb import SamDB import subprocess import tempfile +samba.ensure_external_module("mimeparse", "mimeparse") +samba.ensure_external_module("extras", "extras") samba.ensure_external_module("testtools", "testtools") # Other modules import these two classes from here, for convenience: diff --git a/python/samba/tests/subunitrun.py b/python/samba/tests/subunitrun.py index d454676..291e7ab 100755 --- a/python/samba/tests/subunitrun.py +++ b/python/samba/tests/subunitrun.py @@ -37,9 +37,7 @@ signal.signal(signal.SIGINT, signal.SIG_DFL) import optparse import samba import sys -samba.ensure_external_module("mimeparse", "mimeparse") -samba.ensure_external_module("extras", "extras") -samba.ensure_external_module("testtools", "testtools") +import samba.tests samba.ensure_external_module("subunit", "subunit/python") import subunit.run diff --git a/selftest/filter-subunit b/selftest/filter-subunit index 2ce9584..4f95546 100755 --- a/selftest/filter-subunit +++ b/selftest/filter-subunit @@ -19,14 +19,15 @@ # to upstream subunit's filtering tools. import optparse -import os import sys import signal -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/subunit/python")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/testtools")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/mimeparse")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/extras")) +sys.path.insert(0, "bin/python") +import samba +samba.ensure_external_module("mimeparse", "mimeparse") +samba.ensure_external_module("extras", "extras") +samba.ensure_external_module("testtools", "testtools") +samba.ensure_external_module("subunit", "subunit/python") import subunithelper diff --git a/selftest/format-subunit b/selftest/format-subunit index 5da56be..dc44842 100755 --- a/selftest/format-subunit +++ b/selftest/format-subunit @@ -9,10 +9,12 @@ import os import signal import sys -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/subunit/python")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/testtools")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/mimeparse")) -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/extras")) +sys.path.insert(0, "bin/python") +import samba +samba.ensure_external_module("mimeparse", "mimeparse") +samba.ensure_external_module("extras", "extras") +samba.ensure_external_module("testtools", "testtools") +samba.ensure_external_module("subunit", "subunit/python") import subunithelper diff --git a/source4/dsdb/tests/python/dsdb_schema_info.py b/source4/dsdb/tests/python/dsdb_schema_info.py index 28fce1b..8f64f10 100755 --- a/source4/dsdb/tests/python/dsdb_schema_info.py +++ b/source4/dsdb/tests/python/dsdb_schema_info.py @@ -30,8 +30,7 @@ import time import random sys.path.insert(0, "bin/python") -import samba -samba.ensure_external_module("testtools", "testtools") +import samba.tests from ldb import SCOPE_BASE, LdbError diff --git a/source4/torture/drs/python/drs_base.py b/source4/torture/drs/python/drs_base.py index f692edc..683987f 100644 --- a/source4/torture/drs/python/drs_base.py +++ b/source4/torture/drs/python/drs_base.py @@ -24,10 +24,8 @@ import time import os sys.path.insert(0, "bin/python") -import samba +import samba.tests from samba import dsdb -samba.ensure_external_module("testtools", "testtools") -samba.ensure_external_module("subunit", "subunit/python") from ldb import ( SCOPE_BASE, @@ -35,8 +33,6 @@ from ldb import ( FLAG_MOD_REPLACE, ) -import samba.tests - class DrsBaseTestCase(samba.tests.BlackboxTestCase): """Base class implementation for all DRS python tests. -- 1.9.1 From a9582095eca9979bcfd649344254a24877217372 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Tue, 2 Dec 2014 05:04:40 +0100 Subject: [PATCH 031/440] s4-tests/env_loadparm: Throw KeyError in case SMB_CONF_PATH A bit more specific for the caller to "know" that env key is missing BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I4d4c2121af868d79f46f865f420336222bc67347 Signed-off-by: Kamen Mazdrashki Reviewed-by: Jelmer Vernooij Autobuild-User(master): Kamen Mazdrashki Autobuild-Date(master): Mon Dec 8 05:27:34 CET 2014 on sn-devel-104 (cherry picked from commit 29732b0d427472041bf3a586f3eeb281ccd408d5) --- python/samba/tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 8e662ed..cca82bb 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -91,7 +91,7 @@ def env_loadparm(): try: lp.load(os.environ["SMB_CONF_PATH"]) except KeyError: - raise Exception("SMB_CONF_PATH not set") + raise KeyError("SMB_CONF_PATH not set") return lp -- 1.9.1 From e5a10c35ac0c78aeae15cc29ff1bef8cab26ac70 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Jan 2015 08:31:10 +0100 Subject: [PATCH 032/440] python/samba/tests: don't lower case path names in connect_samdb() We should not lower case file names, because we may get a path to sam.ldb. Now we only lower case ldap urls. For a long time I got failing private autobuild like this: [1623(9233)/1718 at 1h28m9s] samba4.urgent_replication.python(dc)(dc:local) Failed to connect to ldap URL 'ldap:///memdisk/metze/w/b12985/samba/bin/ab/dc/private/sam.ldb' - LDAP client internal error: NT_STATUS_NO_MEMORY Failed to connect to 'ldap:///memdisk/metze/w/b12985/samba/bin/ab/dc/private/sam.ldb' with backend 'ldap': (null) UNEXPECTED(error): samba4.urgent_replication.python(dc).__main__.UrgentReplicationTests.test_attributeSchema_object(dc:local) REASON: _StringException: _StringException: Content-Type: text/x-traceback;charset=utf8,language=python traceback 322 The problem is that /memdisk/metze/W/ is my test directory instead of /memdisk/metze/w/. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Jelmer Vernooij (cherry picked from commit 0e37189dab01a80c10143a54b80859229e181e9b) --- python/samba/tests/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index cca82bb..bda4adf 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -185,7 +185,6 @@ def connect_samdb(samdb_url, lp=None, session_info=None, credentials=None, to make proper URL for ldb.connect() while using default parameters for connection based on test environment """ - samdb_url = samdb_url.lower() if not "://" in samdb_url: if not ldap_only and os.path.isfile(samdb_url): samdb_url = "tdb://%s" % samdb_url -- 1.9.1 From bbb5963e3b5c9ce990bc54bd7528a5597dc907fe Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Sun, 2 Nov 2014 17:11:20 +0100 Subject: [PATCH 033/440] s4-tests: Print out what the error is in delete_force() Change-Id: Iaa631179dc79fa756416be8eaf8c55e3b0c1a29f BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Kamen Mazdrashki Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit e33c54914306ae0fc726d8e066456346aac6ca6c) --- python/samba/tests/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index bda4adf..952b6ee 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -237,5 +237,5 @@ def connect_samdb_ex(samdb_url, lp=None, session_info=None, credentials=None, def delete_force(samdb, dn): try: samdb.delete(dn) - except ldb.LdbError, (num, _): - assert(num == ldb.ERR_NO_SUCH_OBJECT) + except ldb.LdbError, (num, errstr): + assert num == ldb.ERR_NO_SUCH_OBJECT, "ldb.delete() failed: %s" % errstr -- 1.9.1 From c39527b30659b647f427c2a14476562e2aa57323 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Wed, 5 Nov 2014 06:26:25 +0100 Subject: [PATCH 034/440] s4-dsdb-test: Implement samdb_connect_env() to rely solely on environment this is to help me port Python tests to be more Unit test alike and remove all global handling Starting from a new test suite - tombstone_reanimation.py Andrew Bartlett rose his concerns that passing parameters through environment may make tests hard to trace for failures. However, passing parameters on command line is not Unit test alike either. After discussing this with him offline, we agreed to continue this approach, but prefix environment variables with "TEST_". So that an env var should not be used by coincidence. Change-Id: I29445c42cdcafede3897c8dd1f1529222a74afc9 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Kamen Mazdrashki Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 599187ead61340d8d3bd3e9db7eab034175bfd7b) --- python/samba/tests/__init__.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 952b6ee..5b45865 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -23,6 +23,7 @@ import samba import samba.auth from samba import param from samba.samdb import SamDB +from samba import credentials import subprocess import tempfile @@ -234,6 +235,26 @@ def connect_samdb_ex(samdb_url, lp=None, session_info=None, credentials=None, return (sam_db, res[0]) +def connect_samdb_env(env_url, env_username, env_password, lp=None): + """Connect to SamDB by getting URL and Credentials from environment + + :param env_url: Environment variable name to get lsb url from + :param env_username: Username environment variable + :param env_password: Password environment variable + :return: sam_db_connection + """ + samdb_url = env_get_var_value(env_url) + creds = credentials.Credentials() + if lp is None: + # guess Credentials parameters here. Otherwise workstation + # and domain fields are NULL and gencache code segfalts + lp = param.LoadParm() + creds.guess(lp) + creds.set_username(env_get_var_value(env_username)) + creds.set_password(env_get_var_value(env_password)) + return connect_samdb(samdb_url, credentials=creds, lp=lp) + + def delete_force(samdb, dn): try: samdb.delete(dn) -- 1.9.1 From 4e64abc02dd5862eb040a3cbdd88a15a4395830d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Dec 2014 19:59:13 +0000 Subject: [PATCH 035/440] Avoid importing TestCase and TestSkipped from testtools. Change-Id: I34488ddf253decd336a67a8634e7039096bdd160 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 7cb7d4b53eec0bea355a94388bfcce320b36ddfc) --- python/samba/tests/__init__.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 5b45865..dc6a247 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -26,19 +26,16 @@ from samba.samdb import SamDB from samba import credentials import subprocess import tempfile +import unittest -samba.ensure_external_module("mimeparse", "mimeparse") -samba.ensure_external_module("extras", "extras") -samba.ensure_external_module("testtools", "testtools") +try: + from unittest import SkipTest as TestSkipped +except ImportError: + class TestSkipped(Exception): + """Test skipped.""" -# Other modules import these two classes from here, for convenience: -from testtools.testcase import ( - TestCase as TesttoolsTestCase, - TestSkipped, - ) - -class TestCase(TesttoolsTestCase): +class TestCase(unittest.TestCase): """A Samba test case.""" def setUp(self): @@ -57,7 +54,7 @@ class TestCase(TesttoolsTestCase): return cmdline_credentials -class LdbTestCase(TesttoolsTestCase): +class LdbTestCase(unittest.TestCase): """Trivial test case for running tests against a LDB.""" def setUp(self): -- 1.9.1 From ad79a0f503f4659384ad64b4cf318be807c26630 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Dec 2014 20:03:28 +0000 Subject: [PATCH 036/440] Rename TestSkipped to Skiptest, consistent with Python 2.7. Change-Id: I023df54363328333f1cb6c3ae3c1a406befa8f7b BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 940c277d83737367617a7b06e49f71b6a2ab4fde) --- python/samba/tests/__init__.py | 4 ++-- python/samba/tests/docs.py | 3 +-- python/samba/tests/ntacls.py | 7 +++---- python/samba/tests/xattr.py | 10 +++++----- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index dc6a247..25de135 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -29,9 +29,9 @@ import tempfile import unittest try: - from unittest import SkipTest as TestSkipped + from unittest import SkipTest except ImportError: - class TestSkipped(Exception): + class SkipTest(Exception): """Test skipped.""" diff --git a/python/samba/tests/docs.py b/python/samba/tests/docs.py index 0d71e68..561628f 100644 --- a/python/samba/tests/docs.py +++ b/python/samba/tests/docs.py @@ -21,9 +21,7 @@ import samba import samba.tests -from samba.tests import TestSkipped, TestCaseInTempDir -import errno import os import re import subprocess @@ -36,6 +34,7 @@ class TestCase(samba.tests.TestCaseInTempDir): parameters.sort() return message + '\n\n %s' % ('\n '.join(parameters)) + def get_documented_parameters(sourcedir): path = os.path.join(sourcedir, "bin", "default", "docs-xml", "smbdotconf") if not os.path.exists(os.path.join(path, "parameters.all.xml")): diff --git a/python/samba/tests/ntacls.py b/python/samba/tests/ntacls.py index aa9ef68..8cd09fb 100644 --- a/python/samba/tests/ntacls.py +++ b/python/samba/tests/ntacls.py @@ -19,10 +19,9 @@ """Tests for samba.ntacls.""" from samba.ntacls import setntacl, getntacl, XattrBackendError -from samba.dcerpc import xattr, security from samba.param import LoadParm -from samba.tests import TestCaseInTempDir, TestSkipped -import random +from samba.dcerpc import security +from samba.tests import TestCaseInTempDir, SkipTest import os class NtaclsTests(TestCaseInTempDir): @@ -64,7 +63,7 @@ class NtaclsTests(TestCaseInTempDir): def test_setntacl_forcenative(self): if os.getuid() == 0: - raise TestSkipped("Running test as root, test skipped") + raise SkipTest("Running test as root, test skipped") lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" open(self.tempf, 'w').write("empty") diff --git a/python/samba/tests/xattr.py b/python/samba/tests/xattr.py index 89add28..6387452 100644 --- a/python/samba/tests/xattr.py +++ b/python/samba/tests/xattr.py @@ -22,9 +22,9 @@ from samba.xattr import copytree_with_xattrs from samba.dcerpc import xattr from samba.ndr import ndr_pack from samba.tests import ( + SkipTest, TestCase, TestCaseInTempDir, - TestSkipped, ) import random import shutil @@ -42,7 +42,7 @@ class XattrTests(TestCase): def test_set_xattr_native(self): if not samba.xattr_native.is_xattr_supported(): - raise TestSkipped() + raise SkipTest() ntacl = xattr.NTACL() ntacl.version = 1 tempf = self._tmpfilename() @@ -51,12 +51,12 @@ class XattrTests(TestCase): samba.xattr_native.wrap_setxattr(tempf, "user.unittests", ndr_pack(ntacl)) except IOError: - raise TestSkipped("the filesystem where the tests are runned do not support XATTR") + raise SkipTest("the filesystem where the tests are runned do not support XATTR") os.unlink(tempf) def test_set_and_get_native(self): if not samba.xattr_native.is_xattr_supported(): - raise TestSkipped() + raise SkipTest() tempf = self._tmpfilename() reftxt = "this is a test" open(tempf, 'w').write("empty") @@ -65,7 +65,7 @@ class XattrTests(TestCase): text = samba.xattr_native.wrap_getxattr(tempf, "user.unittests") self.assertEquals(text, reftxt) except IOError: - raise TestSkipped("the filesystem where the tests are runned do not support XATTR") + raise SkipTest("the filesystem where the tests are runned do not support XATTR") os.unlink(tempf) def test_set_xattr_tdb(self): -- 1.9.1 From 499469eeed765b72a5b27283980e1c1ad21ec959 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 11 Dec 2014 01:11:41 +0000 Subject: [PATCH 037/440] selftest/tests/*.py: remove use of testtools. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Ia692c6b3037b7d867310c3793980f9f953d31680 Signed-Off-By: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 3f1ecfd2d04b919cd488692ff4bcf02dcac60205) --- selftest/tests/__init__.py | 2 -- selftest/tests/test_run.py | 2 +- selftest/tests/test_samba.py | 2 +- selftest/tests/test_socket_wrapper.py | 2 +- selftest/tests/test_target.py | 2 +- selftest/tests/test_testlist.py | 2 +- 6 files changed, 5 insertions(+), 7 deletions(-) diff --git a/selftest/tests/__init__.py b/selftest/tests/__init__.py index 85d0316..ee53663 100644 --- a/selftest/tests/__init__.py +++ b/selftest/tests/__init__.py @@ -19,8 +19,6 @@ """Tests for selftest.""" -from testtools import TestCase - import unittest def test_suite(): diff --git a/selftest/tests/test_run.py b/selftest/tests/test_run.py index de5f4b1..35f99e8 100644 --- a/selftest/tests/test_run.py +++ b/selftest/tests/test_run.py @@ -33,7 +33,7 @@ from selftest.run import ( run_testsuite_command, ) -from selftest.tests import TestCase +from unittest import TestCase class ExpandEnvironmentStringsTests(TestCase): diff --git a/selftest/tests/test_samba.py b/selftest/tests/test_samba.py index b49463e..4528213 100644 --- a/selftest/tests/test_samba.py +++ b/selftest/tests/test_samba.py @@ -21,7 +21,7 @@ from cStringIO import StringIO -from selftest.tests import TestCase +from unittest import TestCase from selftest.target.samba import ( bindir_path, diff --git a/selftest/tests/test_socket_wrapper.py b/selftest/tests/test_socket_wrapper.py index 81fe5b6..5862f1e 100644 --- a/selftest/tests/test_socket_wrapper.py +++ b/selftest/tests/test_socket_wrapper.py @@ -19,7 +19,7 @@ """Tests for selftest/socket_wrapper.""" -from selftest.tests import TestCase +from unittest import TestCase from selftest import socket_wrapper diff --git a/selftest/tests/test_target.py b/selftest/tests/test_target.py index 00b7126..0d081ce 100644 --- a/selftest/tests/test_target.py +++ b/selftest/tests/test_target.py @@ -29,7 +29,7 @@ from selftest.target import ( UnsupportedEnvironment, ) -from selftest.tests import TestCase +from unittest import TestCase class DummyEnvironment(Environment): diff --git a/selftest/tests/test_testlist.py b/selftest/tests/test_testlist.py index 7007d6d..c0bbebf 100644 --- a/selftest/tests/test_testlist.py +++ b/selftest/tests/test_testlist.py @@ -22,7 +22,7 @@ import os import tempfile -from selftest.tests import TestCase +from unittest import TestCase from selftest.testlist import ( RestrictedTestManager, -- 1.9.1 From a80722b4358fd0bebf1a71f82ff98d76c1d6f5a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 15 Dec 2014 17:35:24 +0000 Subject: [PATCH 038/440] Fix use of TestCase.skipTest on python2.6 now that we no longer use testtools. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I630e4073bf1553dfc77e9fe7e843ee8b71907683 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 85c1dc99083598339050ab5326ba9e0766eacdc8) --- python/samba/tests/__init__.py | 4 ++++ python/samba/tests/dcerpc/srvsvc.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 25de135..d85260c 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -53,6 +53,10 @@ class TestCase(unittest.TestCase): def get_credentials(self): return cmdline_credentials + if not getattr(unittest.TestCase, "skipTest", None): + def skipTest(self, reason): + raise SkipTest(reason) + class LdbTestCase(unittest.TestCase): """Trivial test case for running tests against a LDB.""" diff --git a/python/samba/tests/dcerpc/srvsvc.py b/python/samba/tests/dcerpc/srvsvc.py index 3206a27..407a9d5 100644 --- a/python/samba/tests/dcerpc/srvsvc.py +++ b/python/samba/tests/dcerpc/srvsvc.py @@ -45,12 +45,12 @@ class SrvsvcTests(RpcInterfaceTestCase): return share def test_NetShareAdd(self): - self.skip("Dangerous test") + self.skipTest("Dangerous test") share = self.getDummyShareObject() self.conn.NetShareAdd(self.server_unc, 2, share, None) def test_NetShareSetInfo(self): - self.skip("Dangerous test") + self.skipTest("Dangerous test") share = self.getDummyShareObject() parm_error = 0x00000000 self.conn.NetShareAdd(self.server_unc, 502, share, parm_error) @@ -60,7 +60,7 @@ class SrvsvcTests(RpcInterfaceTestCase): 502, share, parm_error) def test_NetShareDel(self): - self.skip("Dangerous test") + self.skipTest("Dangerous test") share = self.getDummyShareObject() parm_error = 0x00000000 self.expectFailure("NetShareAdd doesn't work properly from Python", -- 1.9.1 From 4b6233b7d48d1d0459c4eb4d4cc530aa9d585503 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Jan 2015 03:40:34 +0100 Subject: [PATCH 039/440] Add custom implementations of TestCase.assertIs and TestCase.assertIsNot, for Python2.6. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I3b806abdaf9540b7c39c961c179c2d2b15d327fe Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit e3a9feb6984136172616260293130095e19051e2) --- python/samba/tests/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index d85260c..86ec3df 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -57,6 +57,14 @@ class TestCase(unittest.TestCase): def skipTest(self, reason): raise SkipTest(reason) + if not getattr(unittest.TestCase, "assertIs", None): + def assertIs(self, a, b): + self.assertTrue(a is b) + + if not getattr(unittest.TestCase, "assertIsNot", None): + def assertIsNot(self, a, b): + self.assertTrue(a is not b) + class LdbTestCase(unittest.TestCase): """Trivial test case for running tests against a LDB.""" -- 1.9.1 From ac04e8811d618827be84182d45cb96b2ed307d49 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Jan 2015 03:44:10 +0100 Subject: [PATCH 040/440] Add replacement addCleanup. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Ie85756effde344fc4cc9b693c4a28611ea091677 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 9a4a7b9d3e91439145e8a54c37da4a84754fe152) --- python/samba/tests/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 86ec3df..65a727a 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -53,6 +53,7 @@ class TestCase(unittest.TestCase): def get_credentials(self): return cmdline_credentials + # These functions didn't exist before Python2.7: if not getattr(unittest.TestCase, "skipTest", None): def skipTest(self, reason): raise SkipTest(reason) @@ -65,6 +66,16 @@ class TestCase(unittest.TestCase): def assertIsNot(self, a, b): self.assertTrue(a is not b) + if not getattr(unittest.TestCase, "addCleanup", None): + def addCleanup(self, fn, *args, **kwargs): + self._cleanups = getattr(self, "_cleanups", []) + [ + (fn, args, kwargs)] + + def tearDown(self): + super(TestCase, self).tearDown() + for (fn, args, kwargs) in reversed(getattr(self, "_cleanups", [])): + fn(*args, **kwargs) + class LdbTestCase(unittest.TestCase): """Trivial test case for running tests against a LDB.""" -- 1.9.1 From 578f69e489edca086ab48446def942f6b2a25be9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Jan 2015 22:17:41 +0100 Subject: [PATCH 041/440] Use Samba TestCase class, as the python 2.6 one doesn't have assertIs, assertIsInstance or addCleanup. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I3daeffade0dac9795f61f91ee0da35fee0143a38 Signed-Off-By: Jelmer Vernooij Reviewed-by: Andrew Bartlett (similar to commit to cef4861906633be00cfb91a2d5e38f9870f749f4) --- selftest/tests/test_run.py | 2 +- selftest/tests/test_testlist.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/selftest/tests/test_run.py b/selftest/tests/test_run.py index 35f99e8..9b77516 100644 --- a/selftest/tests/test_run.py +++ b/selftest/tests/test_run.py @@ -22,6 +22,7 @@ import datetime import os import subunit +from samba.tests import TestCase import tempfile from selftest.run import ( @@ -33,7 +34,6 @@ from selftest.run import ( run_testsuite_command, ) -from unittest import TestCase class ExpandEnvironmentStringsTests(TestCase): diff --git a/selftest/tests/test_testlist.py b/selftest/tests/test_testlist.py index c0bbebf..d82b00c 100644 --- a/selftest/tests/test_testlist.py +++ b/selftest/tests/test_testlist.py @@ -22,7 +22,7 @@ import os import tempfile -from unittest import TestCase +from samba.tests import TestCase from selftest.testlist import ( RestrictedTestManager, -- 1.9.1 From 107e9fde061c6d2e4a7c97d0deeba69dacfe292b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Jan 2015 23:17:13 +0100 Subject: [PATCH 042/440] Provide TestCase.assertIsInstance for python < 2.7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Id6d3c8a7dc56cb560eccc3db897a83c638dec7a6 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit fe231bedecace7e97da22add0cf48f1fd3772544) --- python/samba/tests/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 65a727a..480b2c8 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -66,6 +66,10 @@ class TestCase(unittest.TestCase): def assertIsNot(self, a, b): self.assertTrue(a is not b) + if not getattr(unittest.TestCase, "assertIsInstance", None): + def assertIsInstance(self, a, b): + self.assertTrue(isinstance(a, b)) + if not getattr(unittest.TestCase, "addCleanup", None): def addCleanup(self, fn, *args, **kwargs): self._cleanups = getattr(self, "_cleanups", []) + [ -- 1.9.1 From 4cc434bdb3fc4b692779fd9e62da863f08b50195 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Jan 2015 02:06:33 +0100 Subject: [PATCH 043/440] Use samba TestCase so we get all compatibility functions on Python < 2.7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Iba87e3c8fa9331c4d5438ab60a8385379da634d7 Signed-Off-By: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 0acb1d49a78d6d63013ee9b7352e70cb8dd9b2c6) --- python/samba/tests/__init__.py | 2 +- selftest/tests/test_samba.py | 2 +- selftest/tests/test_socket_wrapper.py | 2 +- selftest/tests/test_target.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 480b2c8..b73308e 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -81,7 +81,7 @@ class TestCase(unittest.TestCase): fn(*args, **kwargs) -class LdbTestCase(unittest.TestCase): +class LdbTestCase(TestCase): """Trivial test case for running tests against a LDB.""" def setUp(self): diff --git a/selftest/tests/test_samba.py b/selftest/tests/test_samba.py index 4528213..23de0d3 100644 --- a/selftest/tests/test_samba.py +++ b/selftest/tests/test_samba.py @@ -21,7 +21,7 @@ from cStringIO import StringIO -from unittest import TestCase +from samba.tests import TestCase from selftest.target.samba import ( bindir_path, diff --git a/selftest/tests/test_socket_wrapper.py b/selftest/tests/test_socket_wrapper.py index 5862f1e..e278fdd 100644 --- a/selftest/tests/test_socket_wrapper.py +++ b/selftest/tests/test_socket_wrapper.py @@ -19,7 +19,7 @@ """Tests for selftest/socket_wrapper.""" -from unittest import TestCase +from samba.tests import TestCase from selftest import socket_wrapper diff --git a/selftest/tests/test_target.py b/selftest/tests/test_target.py index 0d081ce..ed9b064 100644 --- a/selftest/tests/test_target.py +++ b/selftest/tests/test_target.py @@ -29,7 +29,7 @@ from selftest.target import ( UnsupportedEnvironment, ) -from unittest import TestCase +from samba.tests import TestCase class DummyEnvironment(Environment): -- 1.9.1 From b319da0a3c4f2c3433b54642cfe3d54675e736f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Jan 2015 02:16:05 +0100 Subject: [PATCH 044/440] Run cleanup after tearDown, for consistency with Python >= 2.7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Ic3ce975e3b2e4b30e07643efb4496ebf36a93284 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit b53a6df3d0587b7f865b425f66cee8361117b99f) --- python/samba/tests/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index b73308e..99cea49 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -75,10 +75,11 @@ class TestCase(unittest.TestCase): self._cleanups = getattr(self, "_cleanups", []) + [ (fn, args, kwargs)] - def tearDown(self): - super(TestCase, self).tearDown() + def run(self, result=None): + ret = super(TestCase, self).run(result=result) for (fn, args, kwargs) in reversed(getattr(self, "_cleanups", [])): fn(*args, **kwargs) + return ret class LdbTestCase(TestCase): -- 1.9.1 From c5d04527a981d22e7994bd976d921fec9f1dd81d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 4 Feb 2015 16:40:29 +0100 Subject: [PATCH 045/440] Handle skips when running on python2.6. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I8b0a15760a72f41800d23150232c2b0e59e32c32 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit 1988e11585f8e928b2c52d2d97bf1269253b18d0) --- python/samba/tests/__init__.py | 66 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 99cea49..9c82abd 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -25,6 +25,7 @@ from samba import param from samba.samdb import SamDB from samba import credentials import subprocess +import sys import tempfile import unittest @@ -54,32 +55,79 @@ class TestCase(unittest.TestCase): return cmdline_credentials # These functions didn't exist before Python2.7: - if not getattr(unittest.TestCase, "skipTest", None): + if sys.version_info < (2, 7): + import warnings + def skipTest(self, reason): raise SkipTest(reason) - if not getattr(unittest.TestCase, "assertIs", None): def assertIs(self, a, b): self.assertTrue(a is b) - if not getattr(unittest.TestCase, "assertIsNot", None): def assertIsNot(self, a, b): self.assertTrue(a is not b) - if not getattr(unittest.TestCase, "assertIsInstance", None): def assertIsInstance(self, a, b): self.assertTrue(isinstance(a, b)) - if not getattr(unittest.TestCase, "addCleanup", None): def addCleanup(self, fn, *args, **kwargs): self._cleanups = getattr(self, "_cleanups", []) + [ (fn, args, kwargs)] + def _addSkip(self, result, reason): + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None: + addSkip(self, reason) + else: + warnings.warn("TestResult has no addSkip method, skips not reported", + RuntimeWarning, 2) + result.addSuccess(self) + def run(self, result=None): - ret = super(TestCase, self).run(result=result) - for (fn, args, kwargs) in reversed(getattr(self, "_cleanups", [])): - fn(*args, **kwargs) - return ret + if result is None: result = self.defaultTestResult() + result.startTest(self) + testMethod = getattr(self, self._testMethodName) + try: + try: + self.setUp() + except SkipTest, e: + self._addSkip(result, str(e)) + return + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + return + + ok = False + try: + testMethod() + ok = True + except SkipTest, e: + self._addSkip(result, str(e)) + return + except self.failureException: + result.addFailure(self, self._exc_info()) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + + try: + self.tearDown() + except SkipTest, e: + self._addSkip(result, str(e)) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + ok = False + + for (fn, args, kwargs) in reversed(getattr(self, "_cleanups", [])): + fn(*args, **kwargs) + if ok: result.addSuccess(self) + finally: + result.stopTest(self) class LdbTestCase(TestCase): -- 1.9.1 From 9791a7b0c3aa405f88c256ef06ab48dffba167f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 5 Feb 2015 10:25:53 +0100 Subject: [PATCH 046/440] Implement assertIsNone for Python < 2.7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I3937acb16ca0c5430b70f0af305997878da53c37 Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit d459096e7c35f7bc7a83fd69cf0f70fc5ae4e15f) --- python/samba/tests/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 9c82abd..413ac69 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -70,6 +70,9 @@ class TestCase(unittest.TestCase): def assertIsInstance(self, a, b): self.assertTrue(isinstance(a, b)) + def assertIsNone(self, a, msg=None): + self.assertTrue(a is None, msg) + def addCleanup(self, fn, *args, **kwargs): self._cleanups = getattr(self, "_cleanups", []) + [ (fn, args, kwargs)] -- 1.9.1 From dc315cfa437f92c4908b4dc95ad086f14216d62b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 5 Feb 2015 19:57:26 +0100 Subject: [PATCH 047/440] Implement TestCase.assertIn for older versions of Python. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I17d855166b439c0bd9344a17a454ea5bc6e057aa Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett (cherry picked from commit a6b2110abd061b0e03d8b684e5a2edd12fbc1c64) --- python/samba/tests/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 413ac69..840e5c3 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -61,6 +61,9 @@ class TestCase(unittest.TestCase): def skipTest(self, reason): raise SkipTest(reason) + def assertIn(self, member, container, msg=None): + self.assertTrue(member in container, msg) + def assertIs(self, a, b): self.assertTrue(a is b) -- 1.9.1 From d69a2338ed34c4322bbdbe1a4f9b563f7b3e3160 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 5 Feb 2015 22:04:44 +0100 Subject: [PATCH 048/440] Implement TestCase.assertIsNotNone for python < 2.7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: Ieaefdc77495e27bad791075d985a70908e9be1ad Signed-off-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Mar 6 07:11:43 CET 2015 on sn-devel-104 (cherry picked from commit 7004ccc441f700692b95dba89f8d3c4f30f2ca18) --- python/samba/tests/__init__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 840e5c3..3e7094f 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -64,14 +64,17 @@ class TestCase(unittest.TestCase): def assertIn(self, member, container, msg=None): self.assertTrue(member in container, msg) - def assertIs(self, a, b): - self.assertTrue(a is b) + def assertIs(self, a, b, msg=None): + self.assertTrue(a is b, msg) - def assertIsNot(self, a, b): - self.assertTrue(a is not b) + def assertIsNot(self, a, b, msg=None): + self.assertTrue(a is not b, msg) - def assertIsInstance(self, a, b): - self.assertTrue(isinstance(a, b)) + def assertIsNotNone(self, a, msg=None): + self.assertTrue(a is not None) + + def assertIsInstance(self, a, b, msg=None): + self.assertTrue(isinstance(a, b), msg) def assertIsNone(self, a, msg=None): self.assertTrue(a is None, msg) -- 1.9.1 From d1a03298dacd90c3654e2e8aa32e6345e265614b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 08:41:22 +0200 Subject: [PATCH 049/440] python/samba/tests: add fallbacks for assert{Less,Greater}[Equal]() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 24ea9175f41e391ce48d21dedf0e79fb16f7352e) --- python/samba/tests/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 3e7094f..82aa72d 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -79,6 +79,18 @@ class TestCase(unittest.TestCase): def assertIsNone(self, a, msg=None): self.assertTrue(a is None, msg) + def assertGreater(self, a, b, msg=None): + self.assertTrue(a > b, msg) + + def assertGreaterEqual(self, a, b, msg=None): + self.assertTrue(a >= b, msg) + + def assertLess(self, a, b, msg=None): + self.assertTrue(a < b, msg) + + def assertLessEqual(self, a, b, msg=None): + self.assertTrue(a <= b, msg) + def addCleanup(self, fn, *args, **kwargs): self._cleanups = getattr(self, "_cleanups", []) + [ (fn, args, kwargs)] -- 1.9.1 From dbc5126ac2ecfebab4c68dfa8299ccf77f23ea61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Jun 2015 10:28:31 +0200 Subject: [PATCH 050/440] python/samba/tests: move hexdump() from DNSTest to TestCase This is useful in a lot of test cases. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (similar to commit 7a07f6a7647b63eab560a0e75b46b047f46d1f7e) --- python/samba/tests/__init__.py | 12 ++++++++++++ python/samba/tests/dns.py | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 82aa72d..2c3b9b0 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -35,6 +35,7 @@ except ImportError: class SkipTest(Exception): """Test skipped.""" +HEXDUMP_FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) class TestCase(unittest.TestCase): """A Samba test case.""" @@ -54,6 +55,17 @@ class TestCase(unittest.TestCase): def get_credentials(self): return cmdline_credentials + def hexdump(self, src, length=8): + N = 0 + result = '' + while src: + s, src = src[:length], src[length:] + hexa = ' '.join(["%02X" % ord(x) for x in s]) + s = s.translate(HEXDUMP_FILTER) + result += "%04X %-*s %s\n" % (N, length*3, hexa, s) + N += length + return result + # These functions didn't exist before Python2.7: if sys.version_info < (2, 7): import warnings diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index f7f56a3..a0d93ab 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -33,8 +33,6 @@ parser = optparse.OptionParser("dns.py [options]") sambaopts = options.SambaOptions(parser) parser.add_option_group(sambaopts) -FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) - # This timeout only has relevance when testing against Windows # Format errors tend to return patchy responses, so a timeout is needed. parser.add_option("--timeout", type="int", dest="timeout", @@ -178,16 +176,6 @@ class DNSTest(TestCase): if s is not None: s.close() - def hexdump(self, src, length=8): - N=0; result='' - while src: - s,src = src[:length],src[length:] - hexa = ' '.join(["%02X"%ord(x) for x in s]) - s = s.translate(FILTER) - result += "%04X %-*s %s\n" % (N, length*3, hexa, s) - N+=length - return result - def make_txt_update(self, prefix, txt_array): p = self.make_name_packet(dns.DNS_OPCODE_UPDATE) updates = [] -- 1.9.1 From fc4bfa786565622a01430dc38d6153413f386920 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Jun 2015 14:06:40 +0200 Subject: [PATCH 051/440] python/samba/tests: let the output of hexdump() match our C code in dump_data_cb() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit c7e9968cf830d567d44d2a0bd3ca5d1217d8847c) --- python/samba/tests/__init__.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 2c3b9b0..b53c4ea 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -55,15 +55,19 @@ class TestCase(unittest.TestCase): def get_credentials(self): return cmdline_credentials - def hexdump(self, src, length=8): + def hexdump(self, src): N = 0 result = '' while src: - s, src = src[:length], src[length:] - hexa = ' '.join(["%02X" % ord(x) for x in s]) - s = s.translate(HEXDUMP_FILTER) - result += "%04X %-*s %s\n" % (N, length*3, hexa, s) - N += length + ll = src[:8] + lr = src[8:16] + src = src[16:] + hl = ' '.join(["%02X" % ord(x) for x in ll]) + hr = ' '.join(["%02X" % ord(x) for x in lr]) + ll = ll.translate(HEXDUMP_FILTER) + lr = lr.translate(HEXDUMP_FILTER) + result += "[%04X] %-*s %-*s %s %s\n" % (N, 8*3, hl, 8*3, hr, ll, lr) + N += 16 return result # These functions didn't exist before Python2.7: -- 1.9.1 From e1ce0e9ccc3076dddd5565b1bb9c1b4e0a53128c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 09:52:45 +0200 Subject: [PATCH 052/440] s3:winbindd: use check dcerpc_binding_handle_is_connected() instead of a specific status BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 793af3f2aeb036727981e00b709b88b9996fc25d) --- source3/winbindd/winbindd_dual_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index bff310a..cb85560 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -711,7 +711,7 @@ reconnect: logon_server, NETLOGON_CONTROL_QUERY, 2, &info, &werr); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) { + if (!dcerpc_binding_handle_is_connected(b) && !retry) { DEBUG(10, ("Session might have expired. " "Reconnect and retry once.\n")); invalidate_cm_connection(&domain->conn); -- 1.9.1 From 72fa7c94a909a3b80631ecd9e76b451ad27029d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 22:55:22 +0200 Subject: [PATCH 053/440] libcli/smb: let tstream_smbXcli_np report connection errors as EPIPE instead of EIO This maps to NT_STATUS_CONNECTION_DISCONNECTED instead of NT_STATUS_IO_DEVICE_ERROR. EPIPE, NT_STATUS_CONNECTION_DISCONNECTED matches what other tstream backends e.g. tcp and unix report. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 7e095eb334068a9c25064a52fd3e9c995ddf220e) --- libcli/smb/tstream_smbXcli_np.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c index 77a326b..9cd6302 100644 --- a/libcli/smb/tstream_smbXcli_np.c +++ b/libcli/smb/tstream_smbXcli_np.c @@ -632,7 +632,7 @@ static void tstream_smbXcli_np_writev_write_done(struct tevent_req *subreq) } TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - tstream_smbXcli_np_writev_disconnect_now(req, EIO, __location__); + tstream_smbXcli_np_writev_disconnect_now(req, EPIPE, __location__); return; } @@ -980,7 +980,7 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq) status = NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { - tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__); + tstream_smbXcli_np_readv_disconnect_now(req, EPIPE, __location__); return; } @@ -1064,7 +1064,7 @@ static void tstream_smbXcli_np_readv_read_done(struct tevent_req *subreq) } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); - tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__); + tstream_smbXcli_np_readv_disconnect_now(req, EPIPE, __location__); return; } @@ -1290,7 +1290,7 @@ static void tstream_smbXcli_np_disconnect_done(struct tevent_req *subreq) } TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - tevent_req_error(req, EIO); + tevent_req_error(req, EPIPE); return; } -- 1.9.1 From ab1b9ad111140181f941c783bd3319952982bb1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 09:46:57 +0200 Subject: [PATCH 054/440] s4:torture/rpc: expect NT_STATUS_CONNECTION_DISCONNECTED when a dcerpc connection is not connected We still also allow NT_STATUS_INVALID_HANDLE and NT_STATUS_IO_DEVICE_ERROR for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 58a874111b0534ecda3f5036b188ff4bd046ad2b) --- source4/torture/rpc/samba3rpc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index ff1a53c..6f5477f 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -192,13 +192,19 @@ bool torture_bind_authcontext(struct torture_context *torture) if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, " - "expected NT_STATUS_IO_DEVICE_ERROR\n", + "expected NT_STATUS_CONNECTION_DISCONNECTED\n", nt_errstr(status)); - status = NT_STATUS_IO_DEVICE_ERROR; + status = NT_STATUS_CONNECTION_DISCONNECTED; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) { + torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, " + "expected NT_STATUS_CONNECTION_DISCONNECTED\n", + nt_errstr(status)); + status = NT_STATUS_CONNECTION_DISCONNECTED; } - torture_assert_ntstatus_equal(torture, status, NT_STATUS_IO_DEVICE_ERROR, - "lsa io device error"); + torture_assert_ntstatus_equal(torture, status, NT_STATUS_CONNECTION_DISCONNECTED, + "lsa connection disconnected"); smb1cli_session_set_id(tmp->smbXcli, tmp_vuid); cli->tree->session = tmp; -- 1.9.1 From 8189a94567a63f6418062cd43fd8a9c4d83b95de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 09:49:05 +0200 Subject: [PATCH 055/440] s4:torture/rpc: expect NT_STATUS_CONNECTION_DISCONNECTED in torture_rpc_alter_context() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 828e1d3f831fd8e44d5b859d8ad9b05bf9e6d9e4) --- source4/torture/rpc/alter_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/rpc/alter_context.c b/source4/torture/rpc/alter_context.c index d14cabc..60e03db 100644 --- a/source4/torture/rpc/alter_context.c +++ b/source4/torture/rpc/alter_context.c @@ -85,7 +85,7 @@ bool torture_rpc_alter_context(struct torture_context *torture) if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { ret &= test_lsa_OpenPolicy2_ex(p->binding_handle, torture, &handle, - NT_STATUS_IO_DEVICE_ERROR); + NT_STATUS_CONNECTION_DISCONNECTED); torture_assert(torture, !dcerpc_binding_handle_is_connected(p->binding_handle), "dcerpc disonnected"); -- 1.9.1 From 4a81283609087902b8e5609aae8c04e2dc408283 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 10:03:40 +0200 Subject: [PATCH 056/440] python:samba/tests: don't use the x.alter_context() method in dcerpc/bare.py Establishing a new context on a given connection using alter_context is supposed to be done by using y = ClientConnection(..., basis_connection=x) The current x.alter_context() can work as it's not allowed to change the abstract or transfer syntax of an existing presentation context. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 84993440aa9dadd89d8739102c3b7771774064fa) --- python/samba/tests/dcerpc/bare.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/python/samba/tests/dcerpc/bare.py b/python/samba/tests/dcerpc/bare.py index 3efbf9d..e101c5b 100644 --- a/python/samba/tests/dcerpc/bare.py +++ b/python/samba/tests/dcerpc/bare.py @@ -31,21 +31,12 @@ class BareTestCase(samba.tests.TestCase): lp_ctx=samba.tests.env_loadparm()) self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) - def test_alter_context(self): + def test_two_contexts(self): x = ClientConnection("ncalrpc:localhost[DEFAULT]", ("12345778-1234-abcd-ef00-0123456789ac", 1), lp_ctx=samba.tests.env_loadparm()) y = ClientConnection("ncalrpc:localhost", ("60a15ec5-4de8-11d7-a637-005056a20182", 1), basis_connection=x, lp_ctx=samba.tests.env_loadparm()) - x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1)) - # FIXME: self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) - - def test_two_connections(self): - x = ClientConnection("ncalrpc:localhost[DEFAULT]", - ("60a15ec5-4de8-11d7-a637-005056a20182", 1), - lp_ctx=samba.tests.env_loadparm()) - y = ClientConnection("ncalrpc:localhost", - ("60a15ec5-4de8-11d7-a637-005056a20182", 1), - basis_connection=x, lp_ctx=samba.tests.env_loadparm()) + self.assertEquals(24, len(x.request(0, chr(0) * 8))) self.assertEquals("\x01\x00\x00\x00", y.request(0, chr(0) * 4)) -- 1.9.1 From 1f0345d633256a47e1480dd7e572f7ff12bb3d92 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 10:07:17 +0200 Subject: [PATCH 057/440] s4:pyrpc: remove pointless alter_context() method This will always result in a rpc protocol error. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 3cdac4a85521974e3c71488ad4078c09245e3b7d) --- source4/librpc/rpc/pyrpc.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 12199d4..243e96b 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -246,44 +246,8 @@ static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwar return ret; } -static PyObject *py_iface_alter_context(PyObject *self, PyObject *args, PyObject *kwargs) -{ - dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self; - NTSTATUS status; - const char *kwnames[] = { "abstract_syntax", "transfer_syntax", NULL }; - PyObject *py_abstract_syntax = Py_None, *py_transfer_syntax = Py_None; - struct ndr_syntax_id abstract_syntax, transfer_syntax; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:alter_context", - discard_const_p(char *, kwnames), &py_abstract_syntax, - &py_transfer_syntax)) { - return NULL; - } - - if (!ndr_syntax_from_py_object(py_abstract_syntax, &abstract_syntax)) - return NULL; - - if (py_transfer_syntax == Py_None) { - transfer_syntax = ndr_transfer_syntax_ndr; - } else { - if (!ndr_syntax_from_py_object(py_transfer_syntax, &transfer_syntax)) - return NULL; - } - - status = dcerpc_alter_context(iface->pipe, iface->pipe, &abstract_syntax, - &transfer_syntax); - - if (!NT_STATUS_IS_OK(status)) { - PyErr_SetDCERPCStatus(iface->pipe, status); - return NULL; - } - - Py_RETURN_NONE; -} - static PyMethodDef dcerpc_interface_methods[] = { { "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" }, - { "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" }, { NULL, NULL, 0, NULL }, }; -- 1.9.1 From 1dc804e1df0e6adbea3b5a5982536ffbecc03676 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 22:12:49 +0200 Subject: [PATCH 058/440] dcerpc.idl: fix calculatin of uint16 secondary_address_size; This should be 0 for secondary_address = "". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 9c165e550491339fbea1222b26b78e75658ec876) --- librpc/idl/dcerpc.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index cb7f5b8..1036693 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -106,7 +106,7 @@ interface dcerpc uint16 max_xmit_frag; uint16 max_recv_frag; uint32 assoc_group_id; - [value(strlen(secondary_address)+1)] uint16 secondary_address_size; + [value(strlen_m_term_null(secondary_address))] uint16 secondary_address_size; [charset(DOS)] uint8 secondary_address[secondary_address_size]; [flag(NDR_ALIGN4)] DATA_BLOB _pad1; uint8 num_results; -- 1.9.1 From b0020c4514d00056fa38f01baac3ee9dc5a5992d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 15:43:32 +0200 Subject: [PATCH 059/440] heimdal:lib/gssapi/krb5: make _gssapi_verify_pad() more robust BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 9414d9867c51c0db3d7166b4afcf5ff5b39d64a1) --- source4/heimdal/lib/gssapi/krb5/decapsulate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c index 640c064..86085f5 100644 --- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c @@ -190,6 +190,9 @@ _gssapi_verify_pad(gss_buffer_t wrapped_token, size_t padlength; int i; + if (wrapped_token->length < 1) + return GSS_S_BAD_MECH; + pad = (u_char *)wrapped_token->value + wrapped_token->length - 1; padlength = *pad; -- 1.9.1 From 14c98a11ab7ca324bd75a602d3f82acf0c1b0953 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 12:20:26 +0200 Subject: [PATCH 060/440] heimdal:lib/gssapi/krb5: fix indentation in _gk_wrap_iov() Now it matches _gk_unwrap_iov() and _gk_wrap_iov_length(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 01350c76ade6962f7974513afd81632494a8efaa) --- source4/heimdal/lib/gssapi/krb5/aeap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c index 47913e4..87ca06d 100644 --- a/source4/heimdal/lib/gssapi/krb5/aeap.c +++ b/source4/heimdal/lib/gssapi/krb5/aeap.c @@ -44,15 +44,15 @@ _gk_wrap_iov(OM_uint32 * minor_status, gss_iov_buffer_desc *iov, int iov_count) { - const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; - krb5_context context; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + krb5_context context; - GSSAPI_KRB5_INIT (&context); + GSSAPI_KRB5_INIT (&context); - if (ctx->more_flags & IS_CFX) - return _gssapi_wrap_cfx_iov(minor_status, ctx, context, - conf_req_flag, conf_state, - iov, iov_count); + if (ctx->more_flags & IS_CFX) + return _gssapi_wrap_cfx_iov(minor_status, ctx, context, + conf_req_flag, conf_state, + iov, iov_count); return GSS_S_FAILURE; } -- 1.9.1 From 71e34ae30f7565a36701212b930d338aa4f7508a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 14:06:57 +0200 Subject: [PATCH 061/440] heimdal:lib/gssapi/krb5: clear temporary buffer with cleartext data. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 3269ebfcbfefb2bf41c92eca270ea5feefdb9d05) --- source4/heimdal/lib/gssapi/krb5/arcfour.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index f5e41e4..5cd1fe3 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -149,6 +149,7 @@ arcfour_mic_cksum(krb5_context context, 0, ptr, len, &CKSUM); + memset(ptr, 0, len); free(ptr); if (ret == 0) { memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz); -- 1.9.1 From 1c40fe303cf3048c3dfe660de741854ccd1db63d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 15:42:03 +0200 Subject: [PATCH 062/440] heimdal:lib/gssapi/krb5: add const to arcfour_mic_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 688c537ab1fb9690e58a448f8a06d5cc65eafbb4) --- source4/heimdal/lib/gssapi/krb5/arcfour.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 5cd1fe3..0836cf5 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -69,7 +69,7 @@ static krb5_error_code arcfour_mic_key(krb5_context context, krb5_keyblock *key, - void *cksum_data, size_t cksum_size, + const void *cksum_data, size_t cksum_size, void *key6_data, size_t key6_size) { krb5_error_code ret; -- 1.9.1 From 1720701f2d82621d8680eeaeb9c68e067e3d82c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 Jun 2015 14:07:43 +0200 Subject: [PATCH 063/440] heimdal:lib/gssapi/krb5: split out a arcfour_mic_cksum_iov() function BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 571a05c64951f28c41c73541f5824458a3bba909) --- source4/heimdal/lib/gssapi/krb5/arcfour.c | 83 +++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 0836cf5..13bf1d3 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -112,30 +112,73 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key, static krb5_error_code -arcfour_mic_cksum(krb5_context context, - krb5_keyblock *key, unsigned usage, - u_char *sgn_cksum, size_t sgn_cksum_sz, - const u_char *v1, size_t l1, - const void *v2, size_t l2, - const void *v3, size_t l3) +arcfour_mic_cksum_iov(krb5_context context, + krb5_keyblock *key, unsigned usage, + u_char *sgn_cksum, size_t sgn_cksum_sz, + const u_char *v1, size_t l1, + const void *v2, size_t l2, + const gss_iov_buffer_desc *iov, + int iov_count, + const gss_iov_buffer_desc *padding) { Checksum CKSUM; u_char *ptr; size_t len; + size_t ofs = 0; + int i; krb5_crypto crypto; krb5_error_code ret; assert(sgn_cksum_sz == 8); - len = l1 + l2 + l3; + len = l1 + l2; + + for (i=0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + continue; + } + + len += iov[i].buffer.length; + } + + if (padding) { + len += padding->buffer.length; + } ptr = malloc(len); if (ptr == NULL) return ENOMEM; - memcpy(ptr, v1, l1); - memcpy(ptr + l1, v2, l2); - memcpy(ptr + l1 + l2, v3, l3); + memcpy(ptr + ofs, v1, l1); + ofs += l1; + memcpy(ptr + ofs, v2, l2); + ofs += l2; + + for (i=0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + continue; + } + + memcpy(ptr + ofs, + iov[i].buffer.value, + iov[i].buffer.length); + ofs += iov[i].buffer.length; + } + + if (padding) { + memcpy(ptr + ofs, + padding->buffer.value, + padding->buffer.length); + ofs += padding->buffer.length; + } ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) { @@ -160,6 +203,26 @@ arcfour_mic_cksum(krb5_context context, return ret; } +static krb5_error_code +arcfour_mic_cksum(krb5_context context, + krb5_keyblock *key, unsigned usage, + u_char *sgn_cksum, size_t sgn_cksum_sz, + const u_char *v1, size_t l1, + const void *v2, size_t l2, + const void *v3, size_t l3) +{ + gss_iov_buffer_desc iov; + + iov.type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov.buffer.value = rk_UNCONST(v3); + iov.buffer.length = l3; + + return arcfour_mic_cksum_iov(context, key, usage, + sgn_cksum, sgn_cksum_sz, + v1, l1, v2, l2, + &iov, 1, NULL); +} + OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 * minor_status, -- 1.9.1 From 1b698df6d7ead0b35c537c26142257c819a1834e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Aug 2009 19:48:50 +0200 Subject: [PATCH 064/440] heimdal:lib/gssapi/krb5: implement gss_[un]wrap_iov[_length] with arcfour-hmac-md5 Pair-Programmed-With: Andreas Schneider Signed-off-by: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett (cherry picked from commit c245d4f33e233f16aafb29a1737f8f1fa96724d7) --- source4/heimdal/lib/gssapi/krb5/aeap.c | 84 ++++- source4/heimdal/lib/gssapi/krb5/arcfour.c | 559 ++++++++++++++++++++++++++++++ 2 files changed, 640 insertions(+), 3 deletions(-) diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c index 87ca06d..fe95ecf 100644 --- a/source4/heimdal/lib/gssapi/krb5/aeap.c +++ b/source4/heimdal/lib/gssapi/krb5/aeap.c @@ -46,6 +46,9 @@ _gk_wrap_iov(OM_uint32 * minor_status, { const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; + OM_uint32 ret; + krb5_keyblock *key; + krb5_keytype keytype; GSSAPI_KRB5_INIT (&context); @@ -54,7 +57,30 @@ _gk_wrap_iov(OM_uint32 * minor_status, conf_req_flag, conf_state, iov, iov_count); - return GSS_S_FAILURE; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, context, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + krb5_enctype_to_keytype(context, key->keytype, &keytype); + + switch (keytype) { + case KEYTYPE_ARCFOUR: + case KEYTYPE_ARCFOUR_56: + ret = _gssapi_wrap_iov_arcfour(minor_status, ctx, context, + conf_req_flag, conf_state, + iov, iov_count, key); + break; + + default: + ret = GSS_S_FAILURE; + break; + } + + krb5_free_keyblock(context, key); + return ret; } OM_uint32 GSSAPI_CALLCONV @@ -67,6 +93,9 @@ _gk_unwrap_iov(OM_uint32 *minor_status, { const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; + OM_uint32 ret; + krb5_keytype keytype; + krb5_keyblock *key; GSSAPI_KRB5_INIT (&context); @@ -74,7 +103,30 @@ _gk_unwrap_iov(OM_uint32 *minor_status, return _gssapi_unwrap_cfx_iov(minor_status, ctx, context, conf_state, qop_state, iov, iov_count); - return GSS_S_FAILURE; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, context, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + krb5_enctype_to_keytype(context, key->keytype, &keytype); + + switch (keytype) { + case KEYTYPE_ARCFOUR: + case KEYTYPE_ARCFOUR_56: + ret = _gssapi_unwrap_iov_arcfour(minor_status, ctx, context, + conf_state, qop_state, + iov, iov_count, key); + break; + + default: + ret = GSS_S_FAILURE; + break; + } + + krb5_free_keyblock(context, key); + return ret; } OM_uint32 GSSAPI_CALLCONV @@ -88,6 +140,9 @@ _gk_wrap_iov_length(OM_uint32 * minor_status, { const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; + OM_uint32 ret; + krb5_keytype keytype; + krb5_keyblock *key; GSSAPI_KRB5_INIT (&context); @@ -96,5 +151,28 @@ _gk_wrap_iov_length(OM_uint32 * minor_status, conf_req_flag, qop_req, conf_state, iov, iov_count); - return GSS_S_FAILURE; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, context, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + krb5_enctype_to_keytype(context, key->keytype, &keytype); + + switch (keytype) { + case KEYTYPE_ARCFOUR: + case KEYTYPE_ARCFOUR_56: + ret = _gssapi_wrap_iov_length_arcfour(minor_status, ctx, context, + conf_req_flag, qop_req, conf_state, + iov, iov_count); + break; + + default: + ret = GSS_S_FAILURE; + break; + } + + krb5_free_keyblock(context, key); + return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 13bf1d3..a61f768 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -824,3 +824,562 @@ _gssapi_wrap_size_arcfour(OM_uint32 *minor_status, return GSS_S_COMPLETE; } + +OM_uint32 +_gssapi_wrap_iov_length_arcfour(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 major_status; + size_t data_len = 0; + int i; + gss_iov_buffer_desc *header = NULL; + gss_iov_buffer_desc *padding = NULL; + gss_iov_buffer_desc *trailer = NULL; + + *minor_status = 0; + + for (i = 0; i < iov_count; i++) { + switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_EMPTY: + break; + case GSS_IOV_BUFFER_TYPE_DATA: + data_len += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_HEADER: + if (header != NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + header = &iov[i]; + break; + case GSS_IOV_BUFFER_TYPE_TRAILER: + if (trailer != NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + trailer = &iov[i]; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + if (padding != NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + padding = &iov[i]; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } + + major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer); + if (major_status != GSS_S_COMPLETE) { + return major_status; + } + + if (IS_DCE_STYLE(ctx)) { + size_t len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; + size_t total_len; + _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + header->buffer.length = total_len; + } else { + size_t len; + size_t total_len; + if (padding) { + data_len += 1; /* padding */ + } + len = data_len + GSS_ARCFOUR_WRAP_TOKEN_SIZE; + _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + header->buffer.length = total_len - data_len; + } + + if (trailer) { + trailer->buffer.length = 0; + } + + if (padding) { + padding->buffer.length = 1; + } + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gssapi_wrap_iov_arcfour(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count, + krb5_keyblock *key) +{ + OM_uint32 major_status, junk; + gss_iov_buffer_desc *header, *padding, *trailer; + krb5_error_code kret; + int32_t seq_number; + u_char Klocaldata[16], k6_data[16], *p, *p0; + size_t make_len = 0; + size_t header_len = 0; + size_t data_len = 0; + krb5_keyblock Klocal; + int i; + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer); + if (major_status != GSS_S_COMPLETE) { + return major_status; + } + + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + break; + default: + continue; + } + + data_len += iov[i].buffer.length; + } + + if (padding) { + data_len += 1; + } + + if (IS_DCE_STYLE(ctx)) { + size_t unwrapped_len; + unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; + _gssapi_encap_length(unwrapped_len, + &make_len, + &header_len, + GSS_KRB5_MECHANISM); + } else { + size_t unwrapped_len; + unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + data_len; + _gssapi_encap_length(unwrapped_len, + &make_len, + &header_len, + GSS_KRB5_MECHANISM); + header_len -= data_len; + } + + if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = _gk_allocate_buffer(minor_status, header, + header_len); + if (major_status != GSS_S_COMPLETE) + goto failure; + } else if (header->buffer.length < header_len) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else { + header->buffer.length = header_len; + } + + if (padding) { + if (GSS_IOV_BUFFER_FLAGS(padding->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = _gk_allocate_buffer(minor_status, padding, 1); + if (major_status != GSS_S_COMPLETE) + goto failure; + } else if (padding->buffer.length < 1) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else { + padding->buffer.length = 1; + } + memset(padding->buffer.value, 1, 1); + } + + if (trailer) { + trailer->buffer.length = 0; + trailer->buffer.value = NULL; + } + + p0 = _gssapi_make_mech_header(header->buffer.value, + make_len, + GSS_KRB5_MECHANISM); + p = p0; + + *p++ = 0x02; /* TOK_ID */ + *p++ = 0x01; + *p++ = 0x11; /* SGN_ALG */ + *p++ = 0x00; + if (conf_req_flag) { + *p++ = 0x10; /* SEAL_ALG */ + *p++ = 0x00; + } else { + *p++ = 0xff; /* SEAL_ALG */ + *p++ = 0xff; + } + *p++ = 0xff; /* Filler */ + *p++ = 0xff; + + p = NULL; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + krb5_auth_con_getlocalseqnumber(context, + ctx->auth_context, + &seq_number); + _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); + + krb5_auth_con_setlocalseqnumber(context, + ctx->auth_context, + ++seq_number); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + memset(p0 + 8 + 4, + (ctx->more_flags & LOCAL) ? 0 : 0xff, + 4); + + krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ + + /* Sign Data */ + kret = arcfour_mic_cksum_iov(context, + key, KRB5_KU_USAGE_SEAL, + p0 + 16, 8, /* SGN_CKSUM */ + p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ + p0 + 24, 8, /* Confounder */ + iov, iov_count, /* Data + SignOnly */ + padding); /* padding */ + if (kret) { + *minor_status = kret; + major_status = GSS_S_FAILURE; + goto failure; + } + + Klocal.keytype = key->keytype; + Klocal.keyvalue.data = Klocaldata; + Klocal.keyvalue.length = sizeof(Klocaldata); + + for (i = 0; i < 16; i++) { + Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; + } + kret = arcfour_mic_key(context, &Klocal, + p0 + 8, 4, /* SND_SEQ */ + k6_data, sizeof(k6_data)); + memset(Klocaldata, 0, sizeof(Klocaldata)); + if (kret) { + *minor_status = kret; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (conf_req_flag) { + EVP_CIPHER_CTX rc4_key; + + EVP_CIPHER_CTX_init(&rc4_key); + EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); + + /* Confounder */ + EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8); + + /* Seal Data */ + for (i=0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + break; + default: + continue; + } + + EVP_Cipher(&rc4_key, iov[i].buffer.value, + iov[i].buffer.value, iov[i].buffer.length); + } + + /* Padding */ + if (padding) { + EVP_Cipher(&rc4_key, padding->buffer.value, + padding->buffer.value, padding->buffer.length); + } + + EVP_CIPHER_CTX_cleanup(&rc4_key); + } + memset(k6_data, 0, sizeof(k6_data)); + + kret = arcfour_mic_key(context, key, + p0 + 16, 8, /* SGN_CKSUM */ + k6_data, sizeof(k6_data)); + if (kret) { + *minor_status = kret; + major_status = GSS_S_FAILURE; + } + + { + EVP_CIPHER_CTX rc4_key; + + EVP_CIPHER_CTX_init(&rc4_key); + EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); + EVP_Cipher(&rc4_key, p0 + 8, p0 + 8, 8); /* SND_SEQ */ + EVP_CIPHER_CTX_cleanup(&rc4_key); + + memset(k6_data, 0, sizeof(k6_data)); + } + + if (conf_state) + *conf_state = conf_req_flag; + + *minor_status = 0; + return GSS_S_COMPLETE; + +failure: + + gss_release_iov_buffer(&junk, iov, iov_count); + + return major_status; +} + +OM_uint32 +_gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int *pconf_state, + gss_qop_t *pqop_state, + gss_iov_buffer_desc *iov, + int iov_count, + krb5_keyblock *key) +{ + OM_uint32 major_status; + gss_iov_buffer_desc *header, *padding, *trailer; + krb5_keyblock Klocal; + uint8_t Klocaldata[16]; + uint8_t k6_data[16], snd_seq[8], Confounder[8]; + uint8_t cksum_data[8]; + uint8_t *_p = NULL; + const uint8_t *p, *p0; + size_t verify_len = 0; + uint32_t seq_number; + size_t hlen = 0; + int conf_state; + int cmp; + size_t i; + krb5_error_code kret; + OM_uint32 ret; + + if (pconf_state != NULL) { + *pconf_state = 0; + } + if (pqop_state != NULL) { + *pqop_state = 0; + } + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + /* Check if the packet is correct */ + major_status = _gk_verify_buffers(minor_status, + ctx, + header, + padding, + trailer); + if (major_status != GSS_S_COMPLETE) { + return major_status; + } + + if (padding != NULL && padding->buffer.length != 1) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (IS_DCE_STYLE(context)) { + verify_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + + GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE; + if (header->buffer.length > verify_len) { + return GSS_S_BAD_MECH; + } + } else { + verify_len = header->buffer.length; + } + _p = header->buffer.value; + + ret = _gssapi_verify_mech_header(&_p, + verify_len, + GSS_KRB5_MECHANISM); + if (ret) { + return ret; + } + p0 = _p; + + /* length of mech header */ + hlen = (p0 - (uint8_t *)header->buffer.value); + hlen += GSS_ARCFOUR_WRAP_TOKEN_SIZE; + + if (hlen > header->buffer.length) { + return GSS_S_BAD_MECH; + } + + p = p0; + + if (memcmp(p, "\x02\x01", 2) != 0) + return GSS_S_BAD_SIG; + p += 2; + if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ + return GSS_S_BAD_SIG; + p += 2; + + if (memcmp (p, "\x10\x00", 2) == 0) + conf_state = 1; + else if (memcmp (p, "\xff\xff", 2) == 0) + conf_state = 0; + else + return GSS_S_BAD_SIG; + + p += 2; + if (memcmp (p, "\xff\xff", 2) != 0) + return GSS_S_BAD_MIC; + p = NULL; + + kret = arcfour_mic_key(context, + key, + p0 + 16, /* SGN_CKSUM */ + 8, /* SGN_CKSUM_LEN */ + k6_data, + sizeof(k6_data)); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } + + { + EVP_CIPHER_CTX rc4_key; + + EVP_CIPHER_CTX_init(&rc4_key); + EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); + EVP_Cipher(&rc4_key, snd_seq, p0 + 8, 8); /* SND_SEQ */ + EVP_CIPHER_CTX_cleanup(&rc4_key); + + memset(k6_data, 0, sizeof(k6_data)); + } + + _gsskrb5_decode_be_om_uint32(snd_seq, &seq_number); + + if (ctx->more_flags & LOCAL) { + cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); + } else { + cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); + } + if (cmp != 0) { + *minor_status = 0; + return GSS_S_BAD_MIC; + } + + if (ctx->more_flags & LOCAL) { + cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); + } else { + cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); + } + if (cmp != 0) { + *minor_status = 0; + return GSS_S_BAD_MIC; + } + + /* keyblock */ + Klocal.keytype = key->keytype; + Klocal.keyvalue.data = Klocaldata; + Klocal.keyvalue.length = sizeof(Klocaldata); + + for (i = 0; i < 16; i++) { + Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; + } + + kret = arcfour_mic_key(context, + &Klocal, + snd_seq, + 4, + k6_data, sizeof(k6_data)); + memset(Klocaldata, 0, sizeof(Klocaldata)); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } + + if (conf_state == 1) { + EVP_CIPHER_CTX rc4_key; + + EVP_CIPHER_CTX_init(&rc4_key); + EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); + + /* Confounder */ + EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8); + + /* Data */ + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + break; + default: + continue; + } + + EVP_Cipher(&rc4_key, iov[i].buffer.value, + iov[i].buffer.value, iov[i].buffer.length); + } + + /* Padding */ + if (padding) { + EVP_Cipher(&rc4_key, padding->buffer.value, + padding->buffer.value, padding->buffer.length); + } + + EVP_CIPHER_CTX_cleanup(&rc4_key); + } else { + /* Confounder */ + memcpy(Confounder, p0 + 24, 8); + } + memset(k6_data, 0, sizeof(k6_data)); + + /* Prepare the buffer for signing */ + kret = arcfour_mic_cksum_iov(context, + key, KRB5_KU_USAGE_SEAL, + cksum_data, sizeof(cksum_data), + p0, 8, + Confounder, sizeof(Confounder), + iov, iov_count, + padding); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } + + cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ + if (cmp != 0) { + *minor_status = 0; + return GSS_S_BAD_MIC; + } + + if (padding) { + size_t plen; + + ret = _gssapi_verify_pad(&padding->buffer, 1, &plen); + if (ret) { + *minor_status = 0; + return ret; + } + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gssapi_msg_order_check(ctx->order, seq_number); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + if (ret != 0) { + return ret; + } + + if (pconf_state) { + *pconf_state = conf_state; + } + + *minor_status = 0; + return GSS_S_COMPLETE; +} -- 1.9.1 From 9e65f344db188a447a65b042b11ad5f1cd22576b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Sep 2008 08:34:48 +0200 Subject: [PATCH 065/440] auth/kerberos: add gssapi_get_sig_size() and gssapi_{seal,unseal,sign,check}_packet() helper functions These make use of gss_[un]wrap_iov[_length]() where required and support header signing. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 8a4c0abb3eaf1ae80d1ce476cc123c5a195cd15d) --- auth/kerberos/gssapi_helper.c | 395 ++++++++++++++++++++++++++++++++++++++++++ auth/kerberos/gssapi_helper.h | 55 ++++++ auth/kerberos/wscript_build | 2 +- 3 files changed, 451 insertions(+), 1 deletion(-) create mode 100644 auth/kerberos/gssapi_helper.c create mode 100644 auth/kerberos/gssapi_helper.h diff --git a/auth/kerberos/gssapi_helper.c b/auth/kerberos/gssapi_helper.c new file mode 100644 index 0000000..b7ffb6c --- /dev/null +++ b/auth/kerberos/gssapi_helper.c @@ -0,0 +1,395 @@ +/* + Unix SMB/CIFS implementation. + GSSAPI helper functions + + Copyright (C) Stefan Metzmacher 2008,2015 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "system/gssapi.h" +#include "auth/kerberos/pac_utils.h" +#include "auth/kerberos/gssapi_helper.h" + +size_t gssapi_get_sig_size(gss_ctx_id_t gssapi_context, + const gss_OID mech, + uint32_t gss_want_flags, + size_t data_size) +{ + TALLOC_CTX *frame = talloc_stackframe(); + size_t sig_size = 0; + + if (gss_want_flags & GSS_C_CONF_FLAG) { + OM_uint32 min_stat, maj_stat; + bool want_sealing = true; + int sealed = 0; + gss_iov_buffer_desc iov[2]; + + if (!(gss_want_flags & GSS_C_DCE_STYLE)) { + TALLOC_FREE(frame); + return 0; + } + + /* + * gss_wrap_iov_length() only needs the type and length + */ + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[0].buffer.value = NULL; + iov[0].buffer.length = 0; + iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[1].buffer.value = NULL; + iov[1].buffer.length = data_size; + + maj_stat = gss_wrap_iov_length(&min_stat, + gssapi_context, + want_sealing, + GSS_C_QOP_DEFAULT, + &sealed, + iov, ARRAY_SIZE(iov)); + if (maj_stat) { + DEBUG(0, ("gss_wrap_iov_length failed with [%s]\n", + gssapi_error_string(frame, + maj_stat, + min_stat, + mech))); + TALLOC_FREE(frame); + return 0; + } + + sig_size = iov[0].buffer.length; + } else if (gss_want_flags & GSS_C_INTEG_FLAG) { + NTSTATUS status; + uint32_t keytype; + + status = gssapi_get_session_key(frame, + gssapi_context, + NULL, &keytype); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return 0; + } + + switch (keytype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_ARCFOUR_HMAC: + case ENCTYPE_ARCFOUR_HMAC_EXP: + sig_size = 37; + break; + default: + sig_size = 28; + break; + } + } + + TALLOC_FREE(frame); + return sig_size; +} + +NTSTATUS gssapi_seal_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, size_t sig_size, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + TALLOC_CTX *mem_ctx, + DATA_BLOB *sig) +{ + OM_uint32 maj_stat, min_stat; + gss_iov_buffer_desc iov[4]; + int req_seal = 1; + int sealed = 0; + const uint8_t *pre_sign_ptr = NULL; + size_t pre_sign_len = 0; + const uint8_t *post_sign_ptr = NULL; + size_t post_sign_len = 0; + + if (hdr_signing) { + const uint8_t *de = data + length; + const uint8_t *we = whole_pdu + pdu_length; + + if (data < whole_pdu) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (de > we) { + return NT_STATUS_INVALID_PARAMETER; + } + + pre_sign_len = data - whole_pdu; + if (pre_sign_len > 0) { + pre_sign_ptr = whole_pdu; + } + post_sign_len = we - de; + if (post_sign_len > 0) { + post_sign_ptr = de; + } + } + + sig->length = sig_size; + if (sig->length == 0) { + return NT_STATUS_ACCESS_DENIED; + } + + sig->data = talloc_zero_array(mem_ctx, uint8_t, sig->length); + if (sig->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[0].buffer.length = sig->length; + iov[0].buffer.value = sig->data; + + if (pre_sign_ptr != NULL) { + iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[1].buffer.length = pre_sign_len; + iov[1].buffer.value = discard_const(pre_sign_ptr); + } else { + iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY; + iov[1].buffer.length = 0; + iov[1].buffer.value = NULL; + } + + /* data is encrypted in place, which is ok */ + iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[2].buffer.length = length; + iov[2].buffer.value = data; + + if (post_sign_ptr != NULL) { + iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[3].buffer.length = post_sign_len; + iov[3].buffer.value = discard_const(post_sign_ptr); + } else { + iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY; + iov[3].buffer.length = 0; + iov[3].buffer.value = NULL; + } + + maj_stat = gss_wrap_iov(&min_stat, + gssapi_context, + req_seal, + GSS_C_QOP_DEFAULT, + &sealed, + iov, ARRAY_SIZE(iov)); + if (GSS_ERROR(maj_stat)) { + char *error_string = gssapi_error_string(mem_ctx, + maj_stat, + min_stat, + mech); + DEBUG(1, ("gss_wrap_iov failed: %s\n", error_string)); + talloc_free(error_string); + data_blob_free(sig); + return NT_STATUS_ACCESS_DENIED; + } + + if (req_seal == 1 && sealed == 0) { + DEBUG(0, ("gss_wrap_iov says data was not sealed!\n")); + data_blob_free(sig); + return NT_STATUS_ACCESS_DENIED; + } + + dump_data_pw("gssapi_seal_packet: sig\n", sig->data, sig->length); + dump_data_pw("gssapi_seal_packet: sealed\n", data, length); + + DEBUG(10, ("Sealed %d bytes, and got %d bytes header/signature.\n", + (int)iov[2].buffer.length, (int)iov[0].buffer.length)); + + return NT_STATUS_OK; +} + +NTSTATUS gssapi_unseal_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) +{ + OM_uint32 maj_stat, min_stat; + gss_iov_buffer_desc iov[4]; + gss_qop_t qop_state; + int sealed = 0; + const uint8_t *pre_sign_ptr = NULL; + size_t pre_sign_len = 0; + const uint8_t *post_sign_ptr = NULL; + size_t post_sign_len = 0; + + if (hdr_signing) { + const uint8_t *de = data + length; + const uint8_t *we = whole_pdu + pdu_length; + + if (data < whole_pdu) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (de > we) { + return NT_STATUS_INVALID_PARAMETER; + } + + pre_sign_len = data - whole_pdu; + if (pre_sign_len > 0) { + pre_sign_ptr = whole_pdu; + } + post_sign_len = we - de; + if (post_sign_len > 0) { + post_sign_ptr = de; + } + } + + dump_data_pw("gssapi_unseal_packet: sig\n", sig->data, sig->length); + dump_data_pw("gssapi_unseal_packet: sealed\n", data, length); + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[0].buffer.length = sig->length; + iov[0].buffer.value = sig->data; + + if (pre_sign_ptr != NULL) { + iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[1].buffer.length = pre_sign_len; + iov[1].buffer.value = discard_const(pre_sign_ptr); + } else { + iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY; + iov[1].buffer.length = 0; + iov[1].buffer.value = NULL; + } + + /* data is encrypted in place, which is ok */ + iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[2].buffer.length = length; + iov[2].buffer.value = data; + + if (post_sign_ptr != NULL) { + iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + iov[3].buffer.length = post_sign_len; + iov[3].buffer.value = discard_const(post_sign_ptr); + } else { + iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY; + iov[3].buffer.length = 0; + iov[3].buffer.value = NULL; + } + + maj_stat = gss_unwrap_iov(&min_stat, + gssapi_context, + &sealed, + &qop_state, + iov, ARRAY_SIZE(iov)); + if (GSS_ERROR(maj_stat)) { + char *error_string = gssapi_error_string(NULL, + maj_stat, + min_stat, + mech); + DEBUG(1, ("gss_unwrap_iov failed: %s\n", error_string)); + talloc_free(error_string); + + return NT_STATUS_ACCESS_DENIED; + } + + if (sealed == 0) { + DEBUG(0, ("gss_unwrap_iov says data was not sealed!\n")); + return NT_STATUS_ACCESS_DENIED; + } + + DEBUG(10, ("Unsealed %d bytes, with %d bytes header/signature.\n", + (int)iov[2].buffer.length, (int)iov[0].buffer.length)); + + return NT_STATUS_OK; +} + +NTSTATUS gssapi_sign_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + TALLOC_CTX *mem_ctx, + DATA_BLOB *sig) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + + if (hdr_signing) { + 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, + gssapi_context, + GSS_C_QOP_DEFAULT, + &input_token, + &output_token); + if (GSS_ERROR(maj_stat)) { + char *error_string = gssapi_error_string(mem_ctx, + maj_stat, + min_stat, + mech); + DEBUG(1, ("GSS GetMic failed: %s\n", error_string)); + talloc_free(error_string); + return NT_STATUS_ACCESS_DENIED; + } + + *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length); + gss_release_buffer(&min_stat, &output_token); + if (sig->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + dump_data_pw("gssapi_sign_packet: sig\n", sig->data, sig->length); + + return NT_STATUS_OK; +} + +NTSTATUS gssapi_check_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token; + gss_buffer_desc input_message; + gss_qop_t qop_state; + + dump_data_pw("gssapi_check_packet: sig\n", sig->data, sig->length); + + if (hdr_signing) { + input_message.length = pdu_length; + input_message.value = discard_const(whole_pdu); + } else { + input_message.length = length; + input_message.value = discard_const(data); + } + + input_token.length = sig->length; + input_token.value = sig->data; + + maj_stat = gss_verify_mic(&min_stat, + gssapi_context, + &input_message, + &input_token, + &qop_state); + if (GSS_ERROR(maj_stat)) { + char *error_string = gssapi_error_string(NULL, + maj_stat, + min_stat, + mech); + DEBUG(1, ("GSS VerifyMic failed: %s\n", error_string)); + talloc_free(error_string); + + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} diff --git a/auth/kerberos/gssapi_helper.h b/auth/kerberos/gssapi_helper.h new file mode 100644 index 0000000..f40adf1 --- /dev/null +++ b/auth/kerberos/gssapi_helper.h @@ -0,0 +1,55 @@ +/* + Unix SMB/CIFS implementation. + GSSAPI helper functions + + Copyright (C) Stefan Metzmacher 2008,2015 + + 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 3 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, see . +*/ + +#ifndef AUTH_KERBEROS_GSSAPI_HELPER_H +#define AUTH_KERBEROS_GSSAPI_HELPER_H 1 + +size_t gssapi_get_sig_size(gss_ctx_id_t gssapi_context, + const gss_OID mech, + uint32_t gss_want_flags, + size_t data_size); +NTSTATUS gssapi_seal_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, size_t sig_size, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + TALLOC_CTX *mem_ctx, + DATA_BLOB *sig); +NTSTATUS gssapi_unseal_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig); +NTSTATUS gssapi_sign_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + TALLOC_CTX *mem_ctx, + DATA_BLOB *sig); +NTSTATUS gssapi_check_packet(gss_ctx_id_t gssapi_context, + const gss_OID mech, + bool hdr_signing, + const uint8_t *data, size_t length, + const uint8_t *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig); + +#endif /* AUTH_KERBEROS_GSSAPI_HELPER_H */ diff --git a/auth/kerberos/wscript_build b/auth/kerberos/wscript_build index 97b8879..1fa1b51 100755 --- a/auth/kerberos/wscript_build +++ b/auth/kerberos/wscript_build @@ -1,4 +1,4 @@ #!/usr/bin/env python bld.SAMBA_SUBSYSTEM('KRB5_PAC', - source='gssapi_pac.c kerberos_pac.c', + source='gssapi_pac.c kerberos_pac.c gssapi_helper.c', deps='gssapi_krb5 ndr-krb5pac krb5samba') -- 1.9.1 From 44e4c66e68da291144a36ba9a2fa94ae271e3794 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 01:23:16 +0200 Subject: [PATCH 066/440] s3:librpc/gse: make use of add gssapi_get_sig_size() and gssapi_{seal,unseal,sign,check}_packet() helper functions This way are able to support GENSEC_FEATURE_SIGN_PKT_HEADER. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit f643677d3fe62978b6ca7f1da9ec8b1e450b7bcb) --- source3/librpc/crypto/gse.c | 312 +++++++++++++----------------------- source4/auth/gensec/gensec_gssapi.c | 1 + 2 files changed, 115 insertions(+), 198 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 8db3cdd..beebd14 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -36,12 +36,15 @@ #include "gse_krb5.h" static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min); +static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, + size_t data_size); struct gse_context { gss_ctx_id_t gssapi_context; gss_name_t server_name; gss_name_t client_name; OM_uint32 gss_want_flags, gss_got_flags; + size_t sig_size; gss_cred_id_t delegated_cred_handle; @@ -541,193 +544,6 @@ done: return errstr; } -static size_t gse_get_signature_length(struct gse_context *gse_ctx, - bool seal, size_t payload_size) -{ - OM_uint32 gss_min, gss_maj; - gss_iov_buffer_desc iov[2]; - int sealed; - - /* - * gss_wrap_iov_length() only needs the type and length - */ - iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; - iov[0].buffer.value = NULL; - iov[0].buffer.length = 0; - iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; - iov[1].buffer.value = NULL; - iov[1].buffer.length = payload_size; - - gss_maj = gss_wrap_iov_length(&gss_min, gse_ctx->gssapi_context, - seal, GSS_C_QOP_DEFAULT, - &sealed, iov, 2); - if (gss_maj) { - DEBUG(0, ("gss_wrap_iov_length failed with [%s]\n", - gse_errstr(talloc_tos(), gss_maj, gss_min))); - return 0; - } - - return iov[0].buffer.length; -} - -static NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, - DATA_BLOB *data, DATA_BLOB *signature) -{ - OM_uint32 gss_min, gss_maj; - gss_iov_buffer_desc iov[2]; - int req_seal = 1; /* setting to 1 means we request sign+seal */ - int sealed = 1; - NTSTATUS status; - - /* allocate the memory ourselves so we do not need to talloc_memdup */ - signature->length = gse_get_signature_length(gse_ctx, true, data->length); - if (!signature->length) { - return NT_STATUS_INTERNAL_ERROR; - } - signature->data = (uint8_t *)talloc_size(mem_ctx, signature->length); - if (!signature->data) { - return NT_STATUS_NO_MEMORY; - } - iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; - iov[0].buffer.value = signature->data; - iov[0].buffer.length = signature->length; - - /* data is encrypted in place, which is ok */ - iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; - iov[1].buffer.value = data->data; - iov[1].buffer.length = data->length; - - gss_maj = gss_wrap_iov(&gss_min, gse_ctx->gssapi_context, - req_seal, GSS_C_QOP_DEFAULT, - &sealed, iov, 2); - if (gss_maj) { - DEBUG(0, ("gss_wrap_iov failed with [%s]\n", - gse_errstr(talloc_tos(), gss_maj, gss_min))); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - if (!sealed) { - DEBUG(0, ("gss_wrap_iov says data was not sealed!\n")); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - status = NT_STATUS_OK; - - DEBUG(10, ("Sealed %d bytes, and got %d bytes header/signature.\n", - (int)iov[1].buffer.length, (int)iov[0].buffer.length)); - -done: - return status; -} - -static NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, - DATA_BLOB *data, const DATA_BLOB *signature) -{ - OM_uint32 gss_min, gss_maj; - gss_iov_buffer_desc iov[2]; - int sealed; - NTSTATUS status; - - iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; - iov[0].buffer.value = signature->data; - iov[0].buffer.length = signature->length; - - /* data is decrypted in place, which is ok */ - iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; - iov[1].buffer.value = data->data; - iov[1].buffer.length = data->length; - - gss_maj = gss_unwrap_iov(&gss_min, gse_ctx->gssapi_context, - &sealed, NULL, iov, 2); - if (gss_maj) { - DEBUG(0, ("gss_unwrap_iov failed with [%s]\n", - gse_errstr(talloc_tos(), gss_maj, gss_min))); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - if (!sealed) { - DEBUG(0, ("gss_unwrap_iov says data is not sealed!\n")); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - status = NT_STATUS_OK; - - DEBUG(10, ("Unsealed %d bytes, with %d bytes header/signature.\n", - (int)iov[1].buffer.length, (int)iov[0].buffer.length)); - -done: - return status; -} - -static NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, - DATA_BLOB *data, DATA_BLOB *signature) -{ - OM_uint32 gss_min, gss_maj; - gss_buffer_desc in_data = { 0, NULL }; - gss_buffer_desc out_data = { 0, NULL}; - NTSTATUS status; - - in_data.value = data->data; - in_data.length = data->length; - - gss_maj = gss_get_mic(&gss_min, gse_ctx->gssapi_context, - GSS_C_QOP_DEFAULT, - &in_data, &out_data); - if (gss_maj) { - DEBUG(0, ("gss_get_mic failed with [%s]\n", - gse_errstr(talloc_tos(), gss_maj, gss_min))); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - *signature = data_blob_talloc(mem_ctx, - out_data.value, out_data.length); - if (!signature->data) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - status = NT_STATUS_OK; - -done: - if (out_data.value) { - gss_maj = gss_release_buffer(&gss_min, &out_data); - } - return status; -} - -static NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, - const DATA_BLOB *data, const DATA_BLOB *signature) -{ - OM_uint32 gss_min, gss_maj; - gss_buffer_desc in_data = { 0, NULL }; - gss_buffer_desc in_token = { 0, NULL}; - NTSTATUS status; - - in_data.value = data->data; - in_data.length = data->length; - in_token.value = signature->data; - in_token.length = signature->length; - - gss_maj = gss_verify_mic(&gss_min, gse_ctx->gssapi_context, - &in_data, &in_token, NULL); - if (gss_maj) { - DEBUG(0, ("gss_verify_mic failed with [%s]\n", - gse_errstr(talloc_tos(), gss_maj, gss_min))); - status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - status = NT_STATUS_OK; - -done: - return status; -} - static NTSTATUS gensec_gse_client_start(struct gensec_security *gensec_security) { struct gse_context *gse_ctx; @@ -921,8 +737,31 @@ static NTSTATUS gensec_gse_seal_packet(struct gensec_security *gensec_security, struct gse_context *gse_ctx = talloc_get_type_abort(gensec_security->private_data, struct gse_context); - DATA_BLOB payload = data_blob_const(data, length); - return gse_seal(mem_ctx, gse_ctx, &payload, sig); + bool hdr_signing = false; + size_t sig_size = 0; + NTSTATUS status; + + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + hdr_signing = true; + } + + sig_size = gensec_gse_sig_size(gensec_security, length); + + status = gssapi_seal_packet(gse_ctx->gssapi_context, + &gse_ctx->gss_mech, + hdr_signing, sig_size, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig_size, length, pdu_length, + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; } static NTSTATUS gensec_gse_unseal_packet(struct gensec_security *gensec_security, @@ -933,8 +772,28 @@ static NTSTATUS gensec_gse_unseal_packet(struct gensec_security *gensec_security struct gse_context *gse_ctx = talloc_get_type_abort(gensec_security->private_data, struct gse_context); - DATA_BLOB payload = data_blob_const(data, length); - return gse_unseal(talloc_tos() /* unused */, gse_ctx, &payload, sig); + bool hdr_signing = false; + NTSTATUS status; + + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + hdr_signing = true; + } + + status = gssapi_unseal_packet(gse_ctx->gssapi_context, + &gse_ctx->gss_mech, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; } static NTSTATUS gensec_gse_sign_packet(struct gensec_security *gensec_security, @@ -946,8 +805,28 @@ static NTSTATUS gensec_gse_sign_packet(struct gensec_security *gensec_security, struct gse_context *gse_ctx = talloc_get_type_abort(gensec_security->private_data, struct gse_context); - DATA_BLOB payload = data_blob_const(data, length); - return gse_sign(mem_ctx, gse_ctx, &payload, sig); + bool hdr_signing = false; + NTSTATUS status; + + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + hdr_signing = true; + } + + status = gssapi_sign_packet(gse_ctx->gssapi_context, + &gse_ctx->gss_mech, + hdr_signing, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, length, pdu_length, + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; } static NTSTATUS gensec_gse_check_packet(struct gensec_security *gensec_security, @@ -958,8 +837,28 @@ static NTSTATUS gensec_gse_check_packet(struct gensec_security *gensec_security, struct gse_context *gse_ctx = talloc_get_type_abort(gensec_security->private_data, struct gse_context); - DATA_BLOB payload = data_blob_const(data, length); - return gse_sigcheck(NULL, gse_ctx, &payload, sig); + bool hdr_signing = false; + NTSTATUS status; + + if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { + hdr_signing = true; + } + + status = gssapi_check_packet(gse_ctx->gssapi_context, + &gse_ctx->gss_mech, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%ju" + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; } /* Try to figure out what features we actually got on the connection */ @@ -1019,6 +918,17 @@ static bool gensec_gse_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { return true; } + if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { + if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { + return true; + } + + if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { + return true; + } + + return false; + } return false; } @@ -1133,9 +1043,15 @@ static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, talloc_get_type_abort(gensec_security->private_data, struct gse_context); - return gse_get_signature_length(gse_ctx, - gensec_security->want_features & GENSEC_FEATURE_SEAL, - data_size); + if (gse_ctx->sig_size > 0) { + return gse_ctx->sig_size; + } + + gse_ctx->sig_size = gssapi_get_sig_size(gse_ctx->gssapi_context, + &gse_ctx->gss_mech, + gse_ctx->gss_want_flags, + data_size); + return gse_ctx->sig_size; } static const char *gensec_gse_krb5_oids[] = { diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index f02f2ab..a0c58c9 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -42,6 +42,7 @@ #include "gensec_gssapi.h" #include "lib/util/util_net.h" #include "auth/kerberos/pac_utils.h" +#include "auth/kerberos/gssapi_helper.h" #ifndef gss_mech_spnego gss_OID_desc spnego_mech_oid_desc = -- 1.9.1 From 188dae3353ac37b8d81dc06c45b22eed3b3f39f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jun 2015 12:32:34 +0200 Subject: [PATCH 067/440] s4:gensec/gssapi: make use of add gssapi_get_sig_size() and gssapi_{seal,unseal,sign,check}_packet() helper functions This way are able to support GENSEC_FEATURE_SIGN_PKT_HEADER also together with GENSEC_FEATURE_SEAL. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Wed Jun 24 04:00:43 CEST 2015 on sn-devel-104 (cherry picked from commit fa4f4fed2ea20166f48fc40b895ef57aa608ace9) --- source3/librpc/crypto/gse.c | 1 + source4/auth/gensec/gensec_gssapi.c | 284 +++++++++--------------------------- source4/auth/gensec/gensec_gssapi.h | 1 - 3 files changed, 72 insertions(+), 214 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index beebd14..46b5c6d 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -33,6 +33,7 @@ #if defined(HAVE_KRB5) #include "auth/kerberos/pac_utils.h" +#include "auth/kerberos/gssapi_helper.h" #include "gse_krb5.h" static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min); diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index a0c58c9..15685a8 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -54,6 +54,7 @@ _PUBLIC_ NTSTATUS gensec_gssapi_init(void); 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 size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size); static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { @@ -79,44 +80,9 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st &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; @@ -194,8 +160,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->client_cred = NULL; gensec_gssapi_state->server_cred = NULL; - gensec_gssapi_state->lucid = NULL; - gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; gensec_gssapi_state->sasl = false; @@ -1033,53 +997,30 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit { 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; - ssize_t sig_length; + bool hdr_signing = false; + size_t sig_size = 0; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - DEBUG(1, ("gensec_gssapi_seal_packet: " - "GENSEC_FEATURE_SIGN_PKT_HEADER not supported\n")); - return NT_STATUS_ACCESS_DENIED; + hdr_signing = true; } - 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)) { - DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - return NT_STATUS_ACCESS_DENIED; - } + sig_size = gensec_gssapi_sig_size(gensec_security, 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; + status = gssapi_seal_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, sig_size, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig_size, length, pdu_length, + nt_errstr(status))); + return status; } - 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); - - 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); - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } return NT_STATUS_OK; } @@ -1090,55 +1031,27 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur { 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_qop_t qop_state; - DATA_BLOB in; - - dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length); + bool hdr_signing = false; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - DEBUG(1, ("gensec_gssapi_unseal_packet: " - "GENSEC_FEATURE_SIGN_PKT_HEADER not supported\n")); - return NT_STATUS_ACCESS_DENIED; - } - - in = data_blob_talloc(gensec_security, 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); - talloc_free(in.data); - if (GSS_ERROR(maj_stat)) { - char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid); - DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", - error_string)); - talloc_free(error_string); - return NT_STATUS_ACCESS_DENIED; + hdr_signing = true; } - if (output_token.length != length) { - return NT_STATUS_INTERNAL_ERROR; + status = gssapi_unseal_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; } - 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; } @@ -1150,34 +1063,27 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit { 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; + bool hdr_signing = false; + NTSTATUS status; 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); + hdr_signing = true; } - maj_stat = gss_get_mic(&min_stat, - gensec_gssapi_state->gssapi_context, - GSS_C_QOP_DEFAULT, - &input_token, - &output_token); - if (GSS_ERROR(maj_stat)) { - 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; + status = gssapi_sign_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, length, pdu_length, + nt_errstr(status))); + return status; } - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length); - - dump_data_pw("gensec_gssapi_sign_packet: sig\n", sig->data, sig->length); - - gss_release_buffer(&min_stat, &output_token); - return NT_STATUS_OK; } @@ -1188,35 +1094,25 @@ 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; - gss_buffer_desc input_message; - gss_qop_t qop_state; - - dump_data_pw("gensec_gssapi_check_packet: sig\n", sig->data, sig->length); + bool hdr_signing = false; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - input_message.length = pdu_length; - input_message.value = discard_const(whole_pdu); - } else { - input_message.length = length; - input_message.value = discard_const(data); + hdr_signing = true; } - input_token.length = sig->length; - input_token.value = sig->data; - - maj_stat = gss_verify_mic(&min_stat, - gensec_gssapi_state->gssapi_context, - &input_message, - &input_token, - &qop_state); - if (GSS_ERROR(maj_stat)) { - char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid); - DEBUG(1, ("GSS VerifyMic failed: %s\n", error_string)); - talloc_free(error_string); - - return NT_STATUS_ACCESS_DENIED; + status = gssapi_check_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; } return NT_STATUS_OK; @@ -1299,8 +1195,7 @@ static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, } if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - /* TODO: implement this using gss_wrap_iov() */ - return false; + return true; } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { @@ -1452,55 +1347,18 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - NTSTATUS status; + size_t sig_size; - if (gensec_gssapi_state->sig_size) { + if (gensec_gssapi_state->sig_size > 0) { return gensec_gssapi_state->sig_size; } - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 45; - } else { - gensec_gssapi_state->sig_size = 37; - } - - status = gensec_gssapi_init_lucid(gensec_gssapi_state); - if (!NT_STATUS_IS_OK(status)) { - return gensec_gssapi_state->sig_size; - } - - if (gensec_gssapi_state->lucid->protocol == 1) { - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 60; - if (gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE) { - gensec_gssapi_state->sig_size += 16; - } - } else { - gensec_gssapi_state->sig_size = 28; - } - } else if (gensec_gssapi_state->lucid->protocol == 0) { - switch (gensec_gssapi_state->lucid->rfc1964_kd.ctx_key.type) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_ARCFOUR_HMAC: - case ENCTYPE_ARCFOUR_HMAC_EXP: - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 45; - } else { - gensec_gssapi_state->sig_size = 37; - } - break; -#ifdef SAMBA4_USES_HEIMDAL - case ENCTYPE_OLD_DES3_CBC_SHA1: - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 57; - } else { - gensec_gssapi_state->sig_size = 49; - } - break; -#endif - } - } + sig_size = gssapi_get_sig_size(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + gensec_gssapi_state->gss_want_flags, + data_size); + gensec_gssapi_state->sig_size = sig_size; return gensec_gssapi_state->sig_size; } diff --git a/source4/auth/gensec/gensec_gssapi.h b/source4/auth/gensec/gensec_gssapi.h index b7429b5..cf0e3a8 100644 --- a/source4/auth/gensec/gensec_gssapi.h +++ b/source4/auth/gensec/gensec_gssapi.h @@ -46,7 +46,6 @@ struct gensec_gssapi_state { NTTIME expire_time; /* gensec_gssapi only */ - gss_krb5_lucid_context_v1_t *lucid; gss_OID gss_oid; struct gss_channel_bindings_struct *input_chan_bindings; -- 1.9.1 From d54c823dc1a1c385dd14cfa62740b261ab5b124e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Feb 2015 23:14:38 +0100 Subject: [PATCH 068/440] security.idl: add KERB_ENCTYPE_{FAST_SUPPORTED,COMPOUND_IDENTITY_SUPPORTED,CLAIMS_SUPPORTED,RESOURCE_SID_COMPRESSION_DISABLED} These are not encryption types, but flags for specific kerberos features. See [MS-KILE] 2.2.6 Supported Encryption Types Bit Flags. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 1d299f1d7b0544c5e1ea5a8a89c96554fc619fb7) --- librpc/idl/security.idl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 78c13c9..bf7c955 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -648,12 +648,19 @@ interface security SECINFO_BACKUP | 0); + /* + * See [MS-KILE] 2.2.6 Supported Encryption Types Bit Flags + */ typedef [public,bitmap32bit] bitmap { KERB_ENCTYPE_DES_CBC_CRC = 0x00000001, KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002, KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004, KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008, - KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010 + KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010, + KERB_ENCTYPE_FAST_SUPPORTED = 0x00010000, + KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED = 0x00020000, + KERB_ENCTYPE_CLAIMS_SUPPORTED = 0x00040000, + KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED = 0x00080000 } kerb_EncTypes; typedef [public,bitmap32bit] bitmap { -- 1.9.1 From f14212beae081e6a5bbfd80e990b904e74a50506 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 18 Apr 2015 08:40:14 -0700 Subject: [PATCH 069/440] Convert all uses of uint8/16/32 to uint8/16/32_t in the libads code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Richard Sharpe Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Wed Apr 22 06:22:29 CEST 2015 on sn-devel-104 (cherry picked from commit 5074cf825d046c0523de501e00cbfb4fbb814149) --- source3/include/ads.h | 30 +++++++++++++++--------------- source3/libads/ads_ldap_protos.h | 6 +++--- source3/libads/ads_proto.h | 10 +++++----- source3/libads/ads_status.c | 6 +++--- source3/libads/ads_status.h | 2 +- source3/libads/disp_sec.c | 4 ++-- source3/libads/ldap.c | 30 +++++++++++++++--------------- source3/libads/ldap_printer.c | 4 ++-- source3/libads/ldap_utils.c | 10 +++++----- source3/libads/sasl.c | 36 ++++++++++++++++++------------------ source3/libads/sasl_wrapping.c | 2 +- 11 files changed, 70 insertions(+), 70 deletions(-) diff --git a/source3/include/ads.h b/source3/include/ads.h index 3de1d8b..daea56d 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -13,7 +13,7 @@ struct ads_struct; struct ads_saslwrap_ops { const char *name; - ADS_STATUS (*wrap)(struct ads_struct *, uint8 *buf, uint32 len); + ADS_STATUS (*wrap)(struct ads_struct *, uint8_t *buf, uint32_t len); ADS_STATUS (*unwrap)(struct ads_struct *); void (*disconnect)(struct ads_struct *); }; @@ -53,7 +53,7 @@ typedef struct ads_struct { /* info derived from the servers config */ struct { - uint32 flags; /* cldap flags identifying the services. */ + uint32_t flags; /* cldap flags identifying the services. */ char *realm; char *bind_path; char *ldap_server_name; @@ -82,23 +82,23 @@ typedef struct ads_struct { const struct ads_saslwrap_ops *wrap_ops; void *wrap_private_data; struct { - uint32 ofs; - uint32 needed; - uint32 left; + uint32_t ofs; + uint32_t needed; + uint32_t left; #define ADS_SASL_WRAPPING_IN_MAX_WRAPPED 0x0FFFFFFF - uint32 max_wrapped; - uint32 min_wrapped; - uint32 size; - uint8 *buf; + uint32_t max_wrapped; + uint32_t min_wrapped; + uint32_t size; + uint8_t *buf; } in; struct { - uint32 ofs; - uint32 left; + uint32_t ofs; + uint32_t left; #define ADS_SASL_WRAPPING_OUT_MAX_WRAPPED 0x00A00000 - uint32 max_unwrapped; - uint32 sig_size; - uint32 size; - uint8 *buf; + uint32_t max_unwrapped; + uint32_t sig_size; + uint32_t size; + uint8_t *buf; } out; } ldap; #endif /* HAVE_LDAP */ diff --git a/source3/libads/ads_ldap_protos.h b/source3/libads/ads_ldap_protos.h index 3024ae2..b063815 100644 --- a/source3/libads/ads_ldap_protos.h +++ b/source3/libads/ads_ldap_protos.h @@ -51,7 +51,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, size_t *num_strings, bool *more_strings); bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, - uint32 *v); + uint32_t *v); bool ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid); bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, struct dom_sid *sid); @@ -120,12 +120,12 @@ ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, const char *gpo_dn, struct GROUP_POLICY_OBJECT *gpo); ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, - uint32 sd_flags, + uint32_t sd_flags, const char *dn, const char **attrs); ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, - const char **attrs, uint32 sd_flags, + const char **attrs, uint32_t sd_flags, LDAPMessage **res); ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index 1e34247..224d992 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -85,7 +85,7 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit); char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid); ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char **vals); -uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name); +uint32_t ads_get_kvno(ADS_STRUCT *ads, const char *account_name); uint32_t ads_get_machine_kvno(ADS_STRUCT *ads, const char *machine_name); bool ads_element_in_array(const char **el_array, size_t num_el, const char *el); @@ -103,9 +103,9 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, const char *org_unit, bool *moved); int ads_count_replies(ADS_STRUCT *ads, void *res); -ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn); +ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32_t *usn); ADS_STATUS ads_current_time(ADS_STRUCT *ads); -ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val); +ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32_t *val); ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, struct dom_sid *sid); ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name); ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn); @@ -122,12 +122,12 @@ char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ); char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ); ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, const char *org_unit); + uint32_t account_type, const char *org_unit); ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname); ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *samaccountname, - uint32 *uac_ret, + uint32_t *uac_ret, const char **dn_ret); ADS_STATUS ads_config_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 7465531..7056994 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -119,8 +119,8 @@ const char *ads_errstr(ADS_STATUS status) case ENUM_ADS_ERROR_GSS: { char *ret; - uint32 msg_ctx; - uint32 minor; + uint32_t msg_ctx; + uint32_t minor; gss_buffer_desc msg1, msg2; msg_ctx = 0; @@ -147,7 +147,7 @@ const char *ads_errstr(ADS_STATUS status) } #ifdef HAVE_KRB5 -NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min) +NTSTATUS gss_err_to_ntstatus(uint32_t maj, uint32_t min) { ADS_STATUS adss = ADS_ERROR_GSS(maj, min); DEBUG(10,("gss_err_to_ntstatus: Error %s\n", diff --git a/source3/libads/ads_status.h b/source3/libads/ads_status.h index ff7c103..2ff4ef0 100644 --- a/source3/libads/ads_status.h +++ b/source3/libads/ads_status.h @@ -63,6 +63,6 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, NTSTATUS nt_status); NTSTATUS ads_ntstatus(ADS_STATUS status); const char *ads_errstr(ADS_STATUS status); -NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min); +NTSTATUS gss_err_to_ntstatus(uint32_t maj, uint32_t min); #endif /* _LIBADS_ADS_STATUS_H_ */ diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 7dcdc95..472741f 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -29,7 +29,7 @@ #ifdef HAVE_LDAP static struct perm_mask_str { - uint32 mask; + uint32_t mask; const char *str; } perms[] = { {SEC_RIGHTS_FULL_CTRL, "[Full Control]"}, @@ -59,7 +59,7 @@ static struct perm_mask_str { }; /* convert a security permissions into a string */ -static void ads_disp_perms(uint32 type) +static void ads_disp_perms(uint32_t type) { int i = 0; int j = 0; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6031b42..3fb9e78 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1174,7 +1174,7 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, - const char **attrs, uint32 sd_flags, + const char **attrs, uint32_t sd_flags, LDAPMessage **res) { ads_control args; @@ -1783,10 +1783,10 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, * @return the kvno for the account, or -1 in case of a failure. **/ -uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name) +uint32_t ads_get_kvno(ADS_STRUCT *ads, const char *account_name) { LDAPMessage *res = NULL; - uint32 kvno = (uint32)-1; /* -1 indicates a failure */ + uint32_t kvno = (uint32)-1; /* -1 indicates a failure */ char *filter; const char *attrs[] = {"msDS-KeyVersionNumber", NULL}; char *dn_string = NULL; @@ -2136,7 +2136,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; LDAPMessage *res = NULL; - uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ + uint32_t acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ UF_DONT_EXPIRE_PASSWD |\ UF_ACCOUNTDISABLE ); @@ -2312,7 +2312,7 @@ static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) struct security_descriptor *psd; NTSTATUS status; - status = unmarshall_sec_desc(talloc_tos(), (uint8 *)values[0]->bv_val, + status = unmarshall_sec_desc(talloc_tos(), (uint8_t *)values[0]->bv_val, values[0]->bv_len, &psd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("unmarshall_sec_desc failed: %s\n", @@ -2725,7 +2725,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) } /** - * pull a single uint32 from a ADS result + * pull a single uint32_t from a ADS result * @param ads connection to ads server * @param msg Results of search * @param field Attribute to retrieve @@ -2733,7 +2733,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @return boolean inidicating success */ bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, - uint32 *v) + uint32_t *v) { char **values; @@ -2858,7 +2858,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) if (values[0]) { NTSTATUS status; status = unmarshall_sec_desc(mem_ctx, - (uint8 *)values[0]->bv_val, + (uint8_t *)values[0]->bv_val, values[0]->bv_len, sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("unmarshall_sec_desc failed: %s\n", @@ -2908,7 +2908,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param usn Pointer to retrieved update serial number * @return status of search **/ -ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) +ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32_t *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; ADS_STATUS status; @@ -3020,7 +3020,7 @@ done: /******************************************************************** ********************************************************************/ -ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) +ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32_t *val) { const char *attrs[] = {"domainFunctionality", NULL}; ADS_STATUS status; @@ -3512,7 +3512,7 @@ out: * @return status of join **/ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, const char *org_unit) + uint32_t account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res = NULL; @@ -3708,7 +3708,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) struct dom_sid *tmp_sids; struct dom_sid tmp_user_sid; struct dom_sid tmp_primary_group_sid; - uint32 pgid; + uint32_t pgid; const char *attrs[] = { "objectSid", "tokenGroups", @@ -3790,14 +3790,14 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) * @param ads connection to ads server * @param mem_ctx TALLOC_CTX for allocating sid array * @param samaccountname to search - * @param uac_ret uint32 pointer userAccountControl attribute value + * @param uac_ret uint32_t pointer userAccountControl attribute value * @param dn_ret pointer to dn * @return status of token query **/ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *samaccountname, - uint32 *uac_ret, + uint32_t *uac_ret, const char **dn_ret) { ADS_STATUS status; @@ -3805,7 +3805,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, const char *filter; LDAPMessage *res = NULL; char *dn = NULL; - uint32 uac = 0; + uint32_t uac = 0; filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", samaccountname); diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index e9eb419..82c1311 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -146,7 +146,7 @@ static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (value->type != REG_DWORD) { return false; } - if (value->data.length != sizeof(uint32)) { + if (value->data.length != sizeof(uint32_t)) { return false; } str_value = talloc_asprintf(ctx, "%d", IVAL(value->data.data, 0)); @@ -292,7 +292,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, char *printername; struct spoolss_PrinterEnumValues *info; uint32_t count; - uint32 i; + uint32_t i; struct policy_handle pol; WERROR werr; diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 88db3a3..117dc55 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -36,7 +36,7 @@ static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, const char *range_attr, char ***strings, size_t *num_strings, - uint32 *first_usn, + uint32_t *first_usn, int *num_retries, bool *more_values); @@ -169,7 +169,7 @@ static ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_pat } ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, - uint32 sd_flags, + uint32_t sd_flags, const char *dn, const char **attrs) { @@ -242,7 +242,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads, size_t *num_strings) { ADS_STATUS status; - uint32 first_usn; + uint32_t first_usn; int num_retries = 0; const char **attrs; bool more_values = False; @@ -296,14 +296,14 @@ static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, const char *range_attr, char ***strings, size_t *num_strings, - uint32 *first_usn, + uint32_t *first_usn, int *num_retries, bool *more_values) { LDAPMessage *res = NULL; ADS_STATUS status; int count; - uint32 current_usn; + uint32_t current_usn; DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1])); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b1896f8..720ee78 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,7 +28,7 @@ #ifdef HAVE_LDAP -static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -340,12 +340,12 @@ done: return status; } -static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) { gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; - uint32 minor_status; + uint32_t minor_status; gss_buffer_desc unwrapped, wrapped; int conf_req_flag, conf_state; @@ -386,7 +386,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; - uint32 minor_status; + uint32_t minor_status; gss_buffer_desc unwrapped, wrapped; int conf_state; @@ -422,7 +422,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads) { gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; - uint32 minor_status; + uint32_t minor_status; gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); @@ -444,7 +444,7 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t { ADS_STATUS status; bool ok; - uint32 minor_status; + uint32_t minor_status; int gss_rc, rc; gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; gss_OID_desc krb5_mech_type = @@ -454,8 +454,8 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_buffer_desc input_token, output_token; - uint32 req_flags, ret_flags; - uint32 req_tmp, ret_tmp; + uint32_t req_flags, ret_flags; + uint32_t req_tmp, ret_tmp; DATA_BLOB unwrapped; DATA_BLOB wrapped; struct berval cred, *scred = NULL; @@ -676,7 +676,7 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t } if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; + uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; gss_rc = gss_wrap_size_limit(&minor_status, context_handle, (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), @@ -727,7 +727,7 @@ static void ads_free_service_principal(struct ads_service_principal *p) #ifdef HAVE_KRB5 if (p->name) { - uint32 minor_status; + uint32_t minor_status; gss_release_name(&minor_status, &p->name); } #endif @@ -840,7 +840,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, /* GSS_KRB5_NT_PRINCIPAL_NAME */ gss_OID_desc nt_principal = {10, discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; - uint32 minor_status; + uint32_t minor_status; int gss_rc; #endif @@ -1060,20 +1060,20 @@ failed: */ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { - uint32 minor_status; + uint32_t minor_status; gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; - uint32 req_flags, ret_flags; + uint32_t req_flags, ret_flags; int conf_state; struct berval cred; struct berval *scred = NULL; int i=0; int gss_rc, rc; - uint8 *p; - uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; - uint8 wrap_type = ADS_SASLWRAP_TYPE_PLAIN; + uint8_t *p; + uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; + uint8_t wrap_type = ADS_SASLWRAP_TYPE_PLAIN; ADS_STATUS status; input_token.value = NULL; @@ -1150,7 +1150,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv goto failed; } - p = (uint8 *)output_token.value; + p = (uint8_t *)output_token.value; #if 0 file_save("sasl_gssapi.dat", output_token.value, output_token.length); @@ -1188,7 +1188,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto failed; } - p = (uint8 *)output_token.value; + p = (uint8_t *)output_token.value; RSIVAL(p,0,max_msg_size); SCVAL(p,0,ads->ldap.wrap_type); diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index d7353ac..9296d60 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -171,7 +171,7 @@ eagain: return -1; } -static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32 len) +static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32_t len) { ads->ldap.out.ofs = 0; ads->ldap.out.left = 0; -- 1.9.1 From 6bc78f0e644ba6c9444b43529b48a870cd0acc29 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 9 May 2015 16:59:45 -0700 Subject: [PATCH 070/440] Convert all uint32/16/8 to _t in source3/libsmb. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Richard Sharpe Reviewed-by: Jeremy Allison (cherry picked from commit 5c1f8adc331a33c8fdd8e3995284d5833dc29f38) --- source3/libsmb/cliconnect.c | 8 +++---- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clierror.c | 6 ++--- source3/libsmb/clifsinfo.c | 22 +++++++++--------- source3/libsmb/clilist.c | 6 ++--- source3/libsmb/clirap.c | 26 +++++++++++----------- source3/libsmb/clirap.h | 48 ++++++++++++++++++++-------------------- source3/libsmb/clirap2.c | 30 ++++++++++++------------- source3/libsmb/clisecdesc.c | 4 ++-- source3/libsmb/libsmb_dir.c | 18 +++++++-------- source3/libsmb/libsmb_file.c | 6 ++--- source3/libsmb/libsmb_misc.c | 4 ++-- source3/libsmb/libsmb_server.c | 2 +- source3/libsmb/libsmb_stat.c | 10 ++++----- source3/libsmb/libsmb_xattr.c | 14 ++++++------ source3/libsmb/namequery.c | 4 ++-- source3/libsmb/nmblib.c | 2 +- source3/libsmb/proto.h | 26 +++++++++++----------- source3/libsmb/samlogon_cache.c | 2 +- source3/libsmb/smb_share_modes.c | 18 +++++++-------- source3/libsmb/smbsock_connect.c | 2 +- 22 files changed, 131 insertions(+), 131 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 46d3da3..1549194 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2410,7 +2410,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, * Non-encrypted passwords - convert to DOS codepage * before using. */ - tmp_pass = talloc_array(talloc_tos(), uint8, 0); + tmp_pass = talloc_array(talloc_tos(), uint8_t, 0); if (tevent_req_nomem(tmp_pass, req)) { return tevent_req_post(req, ev); } @@ -2637,7 +2637,7 @@ static struct tevent_req *cli_raw_tcon_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, const char *service, const char *pass, const char *dev); static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req, - uint16 *max_xmit, uint16 *tid); + uint16_t *max_xmit, uint16_t *tid); static void cli_tree_connect_smb2_done(struct tevent_req *subreq); static void cli_tree_connect_andx_done(struct tevent_req *subreq); @@ -3543,7 +3543,7 @@ static void cli_raw_tcon_done(struct tevent_req *subreq) } static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req, - uint16 *max_xmit, uint16 *tid) + uint16_t *max_xmit, uint16_t *tid) { struct cli_raw_tcon_state *state = tevent_req_data( req, struct cli_raw_tcon_state); @@ -3559,7 +3559,7 @@ static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req, NTSTATUS cli_raw_tcon(struct cli_state *cli, const char *service, const char *pass, const char *dev, - uint16 *max_xmit, uint16 *tid) + uint16_t *max_xmit, uint16_t *tid) { struct tevent_context *ev; struct tevent_req *req; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index be23754..d8fa1c6 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -33,7 +33,7 @@ */ static bool cli_prep_mailslot(bool unique, const char *mailslot, - uint16 priority, + uint16_t priority, char *buf, int len, const char *srcname, int src_type, const char *dstname, int dest_type, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 71ec1dc..6bed510 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -379,7 +379,7 @@ uint16_t cli_state_get_vc_num(struct cli_state *cli) Set the PID to use for smb messages. Return the old pid. ****************************************************************************/ -uint16 cli_setpid(struct cli_state *cli, uint16 pid) +uint16_t cli_setpid(struct cli_state *cli, uint16 pid) { uint16_t ret = cli->smb1.pid; cli->smb1.pid = pid; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index a53c9c4..f209802 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -84,7 +84,7 @@ NTSTATUS cli_nt_error(struct cli_state *cli) code. ****************************************************************************/ -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) +void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode) { if (!cli_state_is_connected(cli)) { *eclass = ERRDOS; @@ -115,8 +115,8 @@ int cli_errno(struct cli_state *cli) } if (cli_is_dos_error(cli)) { - uint8 eclass; - uint32 ecode; + uint8_t eclass; + uint32_t ecode; cli_dos_error(cli, &eclass, &ecode); status = dos_to_ntstatus(eclass, ecode); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 376c4f5..3fbfbbe 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -120,9 +120,9 @@ NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req, return NT_STATUS_OK; } -NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, - uint16 *pminor, uint32 *pcaplow, - uint32 *pcaphigh) +NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16_t *pmajor, + uint16_t *pminor, uint32_t *pcaplow, + uint32_t *pcaphigh) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; @@ -235,8 +235,8 @@ NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req) } NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, - uint16 major, uint16 minor, - uint32 caplow, uint32 caphigh) + uint16_t major, uint16 minor, + uint32_t caplow, uint32 caphigh) { struct tevent_context *ev; struct tevent_req *req; @@ -432,7 +432,7 @@ NTSTATUS cli_get_fs_full_size_info(struct cli_state *cli, uint64_t *sectors_per_allocation_unit, uint64_t *bytes_per_sector) { - uint16 setup[1]; + uint16_t setup[1]; uint8_t param[2]; uint8_t *rdata = NULL; uint32_t rdata_count; @@ -476,8 +476,8 @@ fail: } NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, - uint32 *optimal_transfer_size, - uint32 *block_size, + uint32_t *optimal_transfer_size, + uint32_t *block_size, uint64_t *total_blocks, uint64_t *blocks_available, uint64_t *user_blocks_available, @@ -485,7 +485,7 @@ NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, uint64_t *free_file_nodes, uint64_t *fs_identifier) { - uint16 setup[1]; + uint16_t setup[1]; uint8_t param[2]; uint8_t *rdata = NULL; uint32_t rdata_count; @@ -748,8 +748,8 @@ NTSTATUS cli_force_encryption(struct cli_state *c, const char *password, const char *domain) { - uint16 major, minor; - uint32 caplow, caphigh; + uint16_t major, minor; + uint32_t caplow, caphigh; NTSTATUS status; if (!SERVER_HAS_UNIX_CIFS(c)) { diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3080fb8..2e50239 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -56,7 +56,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, const char *p, const char *pdata_end, struct file_info *finfo, - uint32 *p_resume_key, + uint32_t *p_resume_key, DATA_BLOB *p_last_name_raw) { int len; @@ -479,7 +479,7 @@ static NTSTATUS cli_list_old_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, } NTSTATUS cli_list_old(struct cli_state *cli, const char *mask, - uint16 attribute, + uint16_t attribute, NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state) { @@ -929,7 +929,7 @@ NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute, +NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16_t attribute, NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state) { diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 64e3767..c176fd6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -165,7 +165,7 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) Call a NetShareEnum - try and browse available connections on a host. ****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32_t, const char *, void *), void *state) { char *rparam = NULL; char *rdata = NULL; @@ -272,8 +272,8 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co the comment and a state pointer. ****************************************************************************/ -bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, void *), +bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype, + void (*fn)(const char *, uint32_t, const char *, void *), void *state) { char *rparam = NULL; @@ -284,7 +284,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, char param[1024]; int uLevel = 1; size_t len; - uint32 func = RAP_NetServerEnum2; + uint32_t func = RAP_NetServerEnum2; char *last_entry = NULL; int total_cnt = 0; int return_cnt = 0; @@ -626,7 +626,7 @@ NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req, time_t *access_time, time_t *write_time, off_t *size, - uint16 *mode) + uint16_t *mode) { struct cli_qpathinfo1_state *state = tevent_req_data( req, struct cli_qpathinfo1_state); @@ -668,7 +668,7 @@ NTSTATUS cli_qpathinfo1(struct cli_state *cli, time_t *access_time, time_t *write_time, off_t *size, - uint16 *mode) + uint16_t *mode) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; @@ -709,7 +709,7 @@ NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname, time_t access_time, time_t write_time, time_t change_time, - uint16 mode) + uint16_t mode) { unsigned int data_len = 0; char data[40]; @@ -802,7 +802,7 @@ NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino) { struct cli_qpathinfo2_state *state = tevent_req_data( @@ -842,7 +842,7 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino) { TALLOC_CTX *frame = NULL; @@ -1138,7 +1138,7 @@ NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum, ****************************************************************************/ NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum, - uint16 *mode, off_t *size, + uint16_t *mode, off_t *size, struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, @@ -1255,7 +1255,7 @@ static void cli_qpathinfo_basic_done(struct tevent_req *subreq) } NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req, - SMB_STRUCT_STAT *sbuf, uint32 *attributes) + SMB_STRUCT_STAT *sbuf, uint32_t *attributes) { struct cli_qpathinfo_basic_state *state = tevent_req_data( req, struct cli_qpathinfo_basic_state); @@ -1274,7 +1274,7 @@ NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req, } NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name, - SMB_STRUCT_STAT *sbuf, uint32 *attributes) + SMB_STRUCT_STAT *sbuf, uint32_t *attributes) { TALLOC_CTX *frame = NULL; struct tevent_context *ev; @@ -1420,7 +1420,7 @@ NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino) { NTSTATUS status = NT_STATUS_OK; diff --git a/source3/libsmb/clirap.h b/source3/libsmb/clirap.h index 54f06b4..a0d4d06 100644 --- a/source3/libsmb/clirap.h +++ b/source3/libsmb/clirap.h @@ -35,9 +35,9 @@ bool cli_api(struct cli_state *cli, char **rparam, unsigned int *rprcnt, char **rdata, unsigned int *rdrcnt); bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state); -bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, void *), +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32_t, const char *, void *), void *state); +bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype, + void (*fn)(const char *, uint32_t, const char *, void *), void *state); bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password); @@ -50,20 +50,20 @@ NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req, time_t *access_time, time_t *write_time, off_t *size, - uint16 *mode); + uint16_t *mode); NTSTATUS cli_qpathinfo1(struct cli_state *cli, const char *fname, time_t *change_time, time_t *access_time, time_t *write_time, off_t *size, - uint16 *mode); + uint16_t *mode); NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname, time_t create_time, time_t access_time, time_t write_time, time_t change_time, - uint16 mode); + uint16_t mode); struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, @@ -73,21 +73,21 @@ NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino); NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino); NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname, struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, struct timespec *change_time, - off_t *size, uint16 *mode, + off_t *size, uint16_t *mode, SMB_INO_T *ino); struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -108,7 +108,7 @@ bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata, NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum, TALLOC_CTX *mem_ctx, char **name); NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum, - uint16 *mode, off_t *size, + uint16_t *mode, off_t *size, struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, @@ -119,9 +119,9 @@ struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, const char *fname); NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req, - SMB_STRUCT_STAT *sbuf, uint32 *attributes); + SMB_STRUCT_STAT *sbuf, uint32_t *attributes); NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name, - SMB_STRUCT_STAT *sbuf, uint32 *attributes); + SMB_STRUCT_STAT *sbuf, uint32_t *attributes); NTSTATUS cli_qpathinfo_standard(struct cli_state *cli, const char *fname, uint64_t *allocated, uint64_t *size, uint32_t *nlinks, @@ -191,31 +191,31 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char int cli_RNetUserEnum0(struct cli_state *cli, void (*fn)(const char *, void *), void *state); -int cli_NetFileClose(struct cli_state *cli, uint32 file_id ); -int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const char *, const char *, uint16, uint16, uint32)); +int cli_NetFileClose(struct cli_state *cli, uint32_t file_id ); +int cli_NetFileGetInfo(struct cli_state *cli, uint32_t file_id, void (*fn)(const char *, const char *, uint16_t, uint16_t, uint32_t)); int cli_NetFileEnum(struct cli_state *cli, const char * user, const char * base_path, - void (*fn)(const char *, const char *, uint16, uint16, - uint32)); + void (*fn)(const char *, const char *, uint16_t, uint16_t, + uint32_t)); int cli_NetShareAdd(struct cli_state *cli, struct rap_share_info_2 * sinfo ); int cli_NetShareDelete(struct cli_state *cli, const char * share_name ); bool cli_get_pdc_name(struct cli_state *cli, const char *workgroup, char **pdc_name); bool cli_get_server_domain(struct cli_state *cli); -bool cli_get_server_type(struct cli_state *cli, uint32 *pstype); +bool cli_get_server_type(struct cli_state *cli, uint32_t *pstype); bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, char **servername); -bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype); +bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32_t stype); bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char *workstation); int cli_NetPrintQEnum(struct cli_state *cli, - void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), - void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,unsigned int,unsigned int,const char*)); + void (*qfn)(const char*,uint16_t,uint16_t,uint16_t,const char*,const char*,const char*,const char*,const char*,uint16_t,uint16_t), + void (*jfn)(uint16_t,const char*,const char*,const char*,const char*,uint16_t,uint16_t,const char*,unsigned int,unsigned int,const char*)); int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, - void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), - void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,unsigned int,unsigned int,const char*)); + void (*qfn)(const char*,uint16_t,uint16_t,uint16_t,const char*,const char*,const char*,const char*,const char*,uint16_t,uint16_t), + void (*jfn)(uint16_t,const char*,const char*,const char*,const char*,uint16_t,uint16_t,const char*,unsigned int,unsigned int,const char*)); int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state); -int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, unsigned int, unsigned int, unsigned int, char *)); +int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16_t, uint16_t, uint16_t, unsigned int, unsigned int, unsigned int, char *)); int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, - void (*fn)(const char *, const char *, uint16, uint16, uint16, unsigned int, unsigned int, unsigned int, const char *)); + void (*fn)(const char *, const char *, uint16_t, uint16_t, uint16_t, unsigned int, unsigned int, unsigned int, const char *)); int cli_NetSessionDel(struct cli_state *cli, const char *workstation); int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16_t conid, uint16_t contype, diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 457a82e..931bc23 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -218,7 +218,7 @@ static size_t rap_getstringp(TALLOC_CTX *ctx, char *p, char **dest, char *r, uin return 4; } -static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt) +static char *make_header(char *param, uint16_t apinum, const char *reqfmt, const char *datafmt) { PUTWORD(param,apinum); if (reqfmt) @@ -1097,7 +1097,7 @@ int cli_RNetUserEnum0(struct cli_state *cli, Call a NetFileClose2 - close open file on another session to server. ****************************************************************************/ -int cli_NetFileClose(struct cli_state *cli, uint32 file_id ) +int cli_NetFileClose(struct cli_state *cli, uint32_t file_id ) { char *rparam = NULL; char *rdata = NULL; @@ -1145,7 +1145,7 @@ int cli_NetFileClose(struct cli_state *cli, uint32 file_id ) workstation. ****************************************************************************/ -int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const char *, const char *, uint16, uint16, uint32)) +int cli_NetFileGetInfo(struct cli_state *cli, uint32_t file_id, void (*fn)(const char *, const char *, uint16_t, uint16_t, uint32_t)) { char *rparam = NULL; char *rdata = NULL; @@ -1245,8 +1245,8 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c int cli_NetFileEnum(struct cli_state *cli, const char * user, const char * base_path, - void (*fn)(const char *, const char *, uint16, uint16, - uint32)) + void (*fn)(const char *, const char *, uint16_t, uint16_t, + uint32_t)) { char *rparam = NULL; char *rdata = NULL; @@ -1636,7 +1636,7 @@ bool cli_get_server_domain(struct cli_state *cli) * * Parameters: * cli - pointer to cli_state structure -* pstype - pointer to uint32 to contain returned server type +* pstype - pointer to uint32_t to contain returned server type * * Returns: * True - success @@ -1646,7 +1646,7 @@ bool cli_get_server_domain(struct cli_state *cli) * ************************************************************************/ -bool cli_get_server_type(struct cli_state *cli, uint32 *pstype) +bool cli_get_server_type(struct cli_state *cli, uint32_t *pstype) { char *rparam = NULL; char *rdata = NULL; @@ -1775,7 +1775,7 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, * ************************************************************************/ -bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype) +bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32_t stype) { char *rparam = NULL; char *rdata = NULL; @@ -1910,8 +1910,8 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char } int cli_NetPrintQEnum(struct cli_state *cli, - void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), - void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,unsigned int,unsigned int,const char*)) + void (*qfn)(const char*,uint16_t,uint16_t,uint16_t,const char*,const char*,const char*,const char*,const char*,uint16_t,uint16_t), + void (*jfn)(uint16_t,const char*,const char*,const char*,const char*,uint16_t,uint16_t,const char*,unsigned int,unsigned int,const char*)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetPrintQEnum_REQ) /* req string */ @@ -2018,7 +2018,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, if (jobcount) { int j; for (j=0;jcli, path, mode, 0)); } diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c index 98739c6..1d874c7 100644 --- a/source3/libsmb/libsmb_misc.c +++ b/source3/libsmb/libsmb_misc.c @@ -53,8 +53,8 @@ SMBC_errno(SMBCCTX *context, int ret = cli_errno(c); if (cli_is_dos_error(c)) { - uint8 eclass; - uint32 ecode; + uint8_t eclass; + uint32_t ecode; cli_dos_error(c, &eclass, &ecode); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 6e8e3c3..39a0b47 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -267,7 +267,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, struct cli_state *c = NULL; const char *server_n = server; int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0); - uint32 fs_attrs = 0; + uint32_t fs_attrs = 0; const char *username_used; NTSTATUS status; char *newserver, *newshare; diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 3c895ce..4191ad6 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -119,7 +119,7 @@ SMBC_stat_ctx(SMBCCTX *context, struct timespec access_time_ts; struct timespec change_time_ts; off_t size = 0; - uint16 mode = 0; + uint16_t mode = 0; uint16_t port = 0; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); @@ -207,7 +207,7 @@ SMBC_fstat_ctx(SMBCCTX *context, struct timespec access_time_ts; struct timespec write_time_ts; off_t size; - uint16 mode; + uint16_t mode; char *server = NULL; char *share = NULL; char *user = NULL; @@ -368,7 +368,7 @@ SMBC_fstatvfs_ctx(SMBCCTX *context, struct statvfs *st) { unsigned long flags = 0; - uint32 fs_attrs = 0; + uint32_t fs_attrs = 0; struct cli_state *cli = file->srv->cli; struct smbXcli_tcon *tcon; TALLOC_CTX *frame = talloc_stackframe(); @@ -424,8 +424,8 @@ SMBC_fstatvfs_ctx(SMBCCTX *context, flags |= SMBC_VFS_FEATURE_NO_UNIXCIFS; } else { - uint32 optimal_transfer_size; - uint32 block_size; + uint32_t optimal_transfer_size; + uint32_t block_size; uint64_t total_blocks; uint64_t blocks_available; uint64_t user_blocks_available; diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 9f7bea8..8c23a8f 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -146,7 +146,7 @@ ace_compare(struct security_ace *ace1, static void sort_acl(struct security_acl *the_acl) { - uint32 i; + uint32_t i; if (!the_acl) return; TYPESAFE_QSORT(the_acl->aces, the_acl->num_aces, ace_compare); @@ -272,7 +272,7 @@ parse_ace(struct cli_state *ipc_cli, const struct perm_value *v; struct perm_value { const char perm[7]; - uint32 mask; + uint32_t mask; }; TALLOC_CTX *frame = talloc_stackframe(); @@ -558,7 +558,7 @@ dos_attr_query(SMBCCTX *context, struct timespec access_time_ts; struct timespec change_time_ts; off_t size = 0; - uint16 mode = 0; + uint16_t mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; @@ -708,7 +708,7 @@ cacl_get(SMBCCTX *context, char *buf, int bufsize) { - uint32 i; + uint32_t i; int n = 0; int n_used; bool all; @@ -746,7 +746,7 @@ cacl_get(SMBCCTX *context, time_t access_time = (time_t)0; time_t change_time = (time_t)0; off_t size = 0; - uint16 mode = 0; + uint16_t mode = 0; SMB_INO_T ino = 0; struct cli_state *cli = srv->cli; struct { @@ -1515,7 +1515,7 @@ cacl_set(SMBCCTX *context, struct security_acl *dacl = NULL; struct dom_sid *owner_sid = NULL; struct dom_sid *group_sid = NULL; - uint32 i, j; + uint32_t i, j; size_t sd_size; int ret = 0; char *p; @@ -1595,7 +1595,7 @@ cacl_set(SMBCCTX *context, for (j=0;old->dacl && jdacl->num_aces;j++) { if (security_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) { - uint32 k; + uint32_t k; for (k=j; kdacl->num_aces-1;k++) { old->dacl->aces[k] = old->dacl->aces[k+1]; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6f056be..544c508 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -241,9 +241,9 @@ static struct in_addr my_socket_addr_v4(void) static int generate_trn_id(void) { - uint16 id; + uint16_t id; - generate_random_buffer((uint8 *)&id, sizeof(id)); + generate_random_buffer((uint8_t *)&id, sizeof(id)); return id % (unsigned)0x7FFF; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4adc3da..8feb029 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1334,7 +1334,7 @@ static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int c = *(unsigned char *)(buf+ofs); if ((c & 0xC0) == 0xC0) { - uint16 l = 0; + uint16_t l = 0; if (ofs > buf_len - 1) { return NULL; diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 08dda96..a4b3c74 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -99,7 +99,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, int signing_state); NTSTATUS cli_raw_tcon(struct cli_state *cli, const char *service, const char *pass, const char *dev, - uint16 *max_xmit, uint16 *tid); + uint16_t *max_xmit, uint16_t *tid); struct cli_state *get_ipc_connect(char *server, struct sockaddr_storage *server_ss, const struct user_auth_info *user_info); @@ -176,7 +176,7 @@ void cli_nt_pipes_close(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); const char *cli_state_remote_realm(struct cli_state *cli); uint16_t cli_state_get_vc_num(struct cli_state *cli); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); +uint16_t cli_setpid(struct cli_state *cli, uint16_t pid); uint16_t cli_getpid(struct cli_state *cli); bool cli_state_has_tcon(struct cli_state *cli); uint16_t cli_state_get_tid(struct cli_state *cli); @@ -204,7 +204,7 @@ NTSTATUS cli_smb(TALLOC_CTX *mem_ctx, struct cli_state *cli, const char *cli_errstr(struct cli_state *cli); NTSTATUS cli_nt_error(struct cli_state *cli); -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode); +void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode); int cli_errno(struct cli_state *cli); bool cli_is_error(struct cli_state *cli); bool cli_is_nt_error(struct cli_state *cli); @@ -643,16 +643,16 @@ NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req, uint16_t *pmajor, uint16_t *pminor, uint32_t *pcaplow, uint32_t *pcaphigh); -NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, - uint16 *pminor, uint32 *pcaplow, - uint32 *pcaphigh); +NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16_t *pmajor, + uint16_t *pminor, uint32_t *pcaplow, + uint32_t *pcaphigh); struct tevent_req *cli_set_unix_extensions_capabilities_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, uint16_t major, uint16_t minor, uint32_t caplow, uint32_t caphigh); NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req); NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, - uint16 major, uint16 minor, - uint32 caplow, uint32 caphigh); + uint16_t major, uint16_t minor, + uint32_t caplow, uint32 caphigh); struct tevent_req *cli_get_fs_attr_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli); @@ -660,7 +660,7 @@ NTSTATUS cli_get_fs_attr_info_recv(struct tevent_req *req, uint32_t *fs_attr); NTSTATUS cli_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr); NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **volume_name, - uint32 *pserial_number, time_t *pdate); + uint32_t *pserial_number, time_t *pdate); NTSTATUS cli_get_fs_full_size_info(struct cli_state *cli, uint64_t *total_allocation_units, uint64_t *caller_allocation_units, @@ -668,8 +668,8 @@ NTSTATUS cli_get_fs_full_size_info(struct cli_state *cli, uint64_t *sectors_per_allocation_unit, uint64_t *bytes_per_sector); NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, - uint32 *optimal_transfer_size, - uint32 *block_size, + uint32_t *optimal_transfer_size, + uint32_t *block_size, uint64_t *total_blocks, uint64_t *blocks_available, uint64_t *user_blocks_available, @@ -688,7 +688,7 @@ NTSTATUS cli_force_encryption(struct cli_state *c, /* The following definitions come from libsmb/clilist.c */ -NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, +NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16_t attribute, NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state); NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, @@ -704,7 +704,7 @@ struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx, uint16_t info_level); NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct file_info **finfo, size_t *num_finfo); -NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, +NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint16_t attribute, NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state); diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 0a157d4..a91ef6e 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -261,7 +261,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct do --jerry */ { time_t now = time(NULL); - uint32 time_diff; + uint32_t time_diff; /* is the entry expired? */ time_diff = now - t; diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index bf21bf5..325078d 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -60,7 +60,7 @@ struct locking_data { int num_share_mode_entries; struct timespec old_write_time; struct timespec changed_write_time; - uint32 num_delete_token_entries; + uint32_t num_delete_token_entries; } s; struct share_mode_entry dummy; /* Needed for alignment. */ } u; @@ -146,7 +146,7 @@ static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev, lk->dev = (SMB_DEV_T)dev; lk->inode = (SMB_INO_T)ino; lk->extid = extid; - ld.dptr = (uint8 *)lk; + ld.dptr = (uint8_t *)lk; ld.dsize = sizeof(*lk); return ld; } @@ -213,7 +213,7 @@ static void create_share_mode_entry(struct share_mode_entry *out, out->id.devid = in->dev; out->id.inode = in->ino; out->id.extid = in->extid; - out->uid = (uint32)geteuid(); + out->uid = (uint32_t)geteuid(); out->flags = 0; out->name_hash = name_hash; } @@ -342,7 +342,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; - uint8 *new_data_p = NULL; + uint8_t *new_data_p = NULL; size_t new_data_size = 0; int err = 0; uint32_t name_hash = smb_name_hash(sharepath, filename, &err); @@ -354,7 +354,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, db_data = tdb_fetch_compat(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = (uint8 *)malloc( + db_data.dptr = (uint8_t *)malloc( sizeof(struct locking_data) + sizeof(struct share_mode_entry) + strlen(sharepath) + 1 + @@ -389,7 +389,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, } /* Entry exists, we must add a new entry. */ - new_data_p = (uint8 *)malloc( + new_data_p = (uint8_t *)malloc( db_data.dsize + sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); @@ -463,10 +463,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; - uint8 *new_data_p = NULL; + uint8_t *new_data_p = NULL; size_t remaining_size = 0; size_t i, num_share_modes; - const uint8 *remaining_ptr = NULL; + const uint8_t *remaining_ptr = NULL; db_data = tdb_fetch_compat(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { @@ -490,7 +490,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* More than one - allocate a new record minus the one we'll delete. */ - new_data_p = (uint8 *)malloc( + new_data_p = (uint8_t *)malloc( db_data.dsize - sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c index dc04b6a..9f915e1 100644 --- a/source3/libsmb/smbsock_connect.c +++ b/source3/libsmb/smbsock_connect.c @@ -29,7 +29,7 @@ struct cli_session_request_state { struct tevent_context *ev; int sock; - uint32 len_hdr; + uint32_t len_hdr; struct iovec iov[3]; uint8_t nb_session_response; }; -- 1.9.1 From cbae5869807acd62ba11e5e5f3a94eda3dc87ca4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Oct 2014 07:06:35 +1300 Subject: [PATCH 071/440] libsmb: Print the principal name that we failed to kinit for. This should aid debugging when this is called from an automated process. Andrew Bartlett BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Change-Id: I2c7291ab3f67f9f7462d7c52c8c9a4b042f7ec5a Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit e9472f8e821acd988fee9a1a288986282a138fc6) --- source3/libsmb/cliconnect.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1549194..8d5721f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1826,6 +1826,12 @@ static struct tevent_req *cli_session_setup_spnego_send( const char *remote_name = smbXcli_conn_remote_name(cli->conn); char *tmp; + + tmp = cli_session_setup_get_principal( + talloc_tos(), principal, remote_name, dest_realm); + TALLOC_FREE(principal); + principal = tmp; + if (pass && *pass) { int ret; @@ -1833,8 +1839,8 @@ static struct tevent_req *cli_session_setup_spnego_send( ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); if (ret){ + DEBUG(0, ("Kinit for %s to access %s failed: %s\n", user, principal, error_message(ret))); TALLOC_FREE(principal); - DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); if (cli->fallback_after_kerberos) goto ntlmssp; state->result = ADS_ERROR_KRB5(ret); @@ -1843,11 +1849,6 @@ static struct tevent_req *cli_session_setup_spnego_send( } } - tmp = cli_session_setup_get_principal( - talloc_tos(), principal, remote_name, dest_realm); - TALLOC_FREE(principal); - principal = tmp; - if (principal) { subreq = cli_session_setup_kerberos_send( state, ev, cli, principal); -- 1.9.1 From e3360f44ca81bd0335774fdbee969940486ae8eb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Mar 2015 10:47:03 +0100 Subject: [PATCH 072/440] rpc_server: Fix CID 1035534 Uninitialized scalar variable I believe this can't happen, but better be safe than sorry BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: David Disseldorp (cherry picked from commit 8f7bdc8194a6e666c795da0d27feb316b0a8dd37) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 77200f8..1bd9b1e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -936,7 +936,7 @@ err: static bool api_pipe_alter_context(struct pipes_struct *p, struct ncacn_packet *pkt) { - struct dcerpc_auth auth_info; + struct dcerpc_auth auth_info = {0}; uint16 assoc_gid; NTSTATUS status; union dcerpc_payload u; -- 1.9.1 From 085f3666f3e38f56f8f9719960f007913eef8b9c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Mar 2015 10:47:03 +0100 Subject: [PATCH 073/440] rpc_server: Fix CID 1035535 Uninitialized scalar variable I believe this can't happen, but better be safe than sorry BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: David Disseldorp Autobuild-User(master): David Disseldorp Autobuild-Date(master): Wed Mar 4 17:14:53 CET 2015 on sn-devel-104 (cherry picked from commit 40a317f092829aa78a35cc0421f524a4b0233f10) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1bd9b1e..5ad56b1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -573,7 +573,7 @@ static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p) static bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt) { - struct dcerpc_auth auth_info; + struct dcerpc_auth auth_info = {0}; uint16 assoc_gid; unsigned int auth_type = DCERPC_AUTH_TYPE_NONE; NTSTATUS status; -- 1.9.1 From 793a67ab8c28f3625c926094060b672000caa1ee Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 9 May 2015 10:02:05 -0700 Subject: [PATCH 074/440] Convert all uses of uint32/16/8 to _t in source3/rpc_server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Richard Sharpe Reviewed-by: Jeremy Allison (cherry picked from commit a685404dce06d0f227f24b745629b0d0b46b925a) --- source3/rpc_server/rpc_handles.c | 6 +++--- source3/rpc_server/srv_access_check.c | 6 +++--- source3/rpc_server/srv_access_check.h | 4 ++-- source3/rpc_server/srv_pipe.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c index 3542acc..4e2edc6 100644 --- a/source3/rpc_server/rpc_handles.c +++ b/source3/rpc_server/rpc_handles.c @@ -253,8 +253,8 @@ static struct dcesrv_handle *create_rpc_handle_internal(struct pipes_struct *p, struct policy_handle *hnd, void *data_ptr) { struct dcesrv_handle *rpc_hnd; - static uint32 pol_hnd_low = 0; - static uint32 pol_hnd_high = 0; + static uint32_t pol_hnd_low = 0; + static uint32_t pol_hnd_high = 0; time_t t = time(NULL); if (p->pipe_handles->count > MAX_OPEN_POLS) { @@ -336,7 +336,7 @@ static struct dcesrv_handle *find_policy_by_hnd_internal(struct pipes_struct *p, for (h = p->pipe_handles->handles; h != NULL; h = h->next) { if (memcmp(&h->wire_handle, hnd, sizeof(*hnd)) == 0) { DEBUG(6,("Found policy hnd[%u] ", count)); - dump_data(6, (const uint8 *)hnd, sizeof(*hnd)); + dump_data(6, (const uint8_t *)hnd, sizeof(*hnd)); if (data_p) { *data_p = h->data; } diff --git a/source3/rpc_server/srv_access_check.c b/source3/rpc_server/srv_access_check.c index 878e38b..bb638251 100644 --- a/source3/rpc_server/srv_access_check.c +++ b/source3/rpc_server/srv_access_check.c @@ -47,12 +47,12 @@ NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token, enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2, - uint32 rights_mask, - uint32 des_access, uint32 *acc_granted, + uint32_t rights_mask, + uint32_t des_access, uint32 *acc_granted, const char *debug ) { NTSTATUS status = NT_STATUS_ACCESS_DENIED; - uint32 saved_mask = 0; + uint32_t saved_mask = 0; bool priv_granted = false; bool is_system = false; bool is_root = false; diff --git a/source3/rpc_server/srv_access_check.h b/source3/rpc_server/srv_access_check.h index 72ce539..0e16168 100644 --- a/source3/rpc_server/srv_access_check.h +++ b/source3/rpc_server/srv_access_check.h @@ -34,8 +34,8 @@ NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token, enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2, - uint32 rights_mask, - uint32 des_access, uint32 *acc_granted, + uint32_t rights_mask, + uint32_t des_access, uint32 *acc_granted, const char *debug ); void map_max_allowed_access(const struct security_token *nt_token, const struct security_unix_token *unix_token, diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5ad56b1..4ffaa0d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -574,7 +574,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt) { struct dcerpc_auth auth_info = {0}; - uint16 assoc_gid; + uint16_t assoc_gid; unsigned int auth_type = DCERPC_AUTH_TYPE_NONE; NTSTATUS status; struct ndr_syntax_id id; @@ -937,7 +937,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, struct ncacn_packet *pkt) { struct dcerpc_auth auth_info = {0}; - uint16 assoc_gid; + uint16_t assoc_gid; NTSTATUS status; union dcerpc_payload u; struct dcerpc_ack_ctx bind_ack_ctx; -- 1.9.1 From 26121d92eafbf67af572a6a2ad2339ec524685d0 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 9 May 2015 09:49:04 -0700 Subject: [PATCH 075/440] Convert all uses of uint32/16/8 to _t in source3/rpc_client. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Richard Sharpe Reviewed-by: Jeremy Allison (cherry picked from commit 8bcdd677ce616c636c81c0fa6f077c56dc269707) --- source3/rpc_client/cli_lsarpc.c | 4 ++-- source3/rpc_client/cli_lsarpc.h | 4 ++-- source3/rpc_client/cli_netlogon.c | 4 ++-- source3/rpc_client/cli_netlogon.h | 2 +- source3/rpc_client/cli_pipe.c | 14 +++++++------- source3/rpc_client/rpc_client.h | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 974538b..f50a5e9 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -81,7 +81,7 @@ NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h, NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - bool sec_qos, uint32 des_access, + bool sec_qos, uint32_t des_access, struct policy_handle *pol) { NTSTATUS status; @@ -140,7 +140,7 @@ NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h, NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, - uint32 des_access, struct policy_handle *pol) + uint32_t des_access, struct policy_handle *pol) { NTSTATUS status; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/rpc_client/cli_lsarpc.h b/source3/rpc_client/cli_lsarpc.h index 36afe0b..4f9464d 100644 --- a/source3/rpc_client/cli_lsarpc.h +++ b/source3/rpc_client/cli_lsarpc.h @@ -54,7 +54,7 @@ NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h, NTSTATUS *result); NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - bool sec_qos, uint32 des_access, + bool sec_qos, uint32_t des_access, struct policy_handle *pol); /** @@ -83,7 +83,7 @@ NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h, NTSTATUS *result); NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, - uint32 des_access, struct policy_handle *pol); + uint32_t des_access, struct policy_handle *pol); /** * @brief Look up the names that correspond to an array of sids. diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 7063351..9c727f7 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -312,7 +312,7 @@ NTSTATUS rpccli_netlogon_password_logon(struct netlogon_creds_cli_context *creds } case NetlogonNetworkInformation: { struct netr_NetworkInfo *network_info; - uint8 chal[8]; + uint8_t chal[8]; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; struct netr_ChallengeResponse lm; @@ -400,7 +400,7 @@ NTSTATUS rpccli_netlogon_network_logon(struct netlogon_creds_cli_context *creds, const char *username, const char *domain, const char *workstation, - const uint8 chal[8], + const uint8_t chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, uint8_t *authoritative, diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h index fee0801..0765dfa 100644 --- a/source3/rpc_client/cli_netlogon.h +++ b/source3/rpc_client/cli_netlogon.h @@ -60,7 +60,7 @@ NTSTATUS rpccli_netlogon_network_logon(struct netlogon_creds_cli_context *creds, const char *username, const char *domain, const char *workstation, - const uint8 chal[8], + const uint8_t chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, uint8_t *authoritative, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 652a773..fd81bf3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -56,9 +56,9 @@ static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, Rpc pipe call id. ********************************************************************/ -static uint32 get_rpc_call_id(void) +static uint32_t get_rpc_call_id(void) { - static uint32 call_id = 0; + static uint32_t call_id = 0; return ++call_id; } @@ -1039,14 +1039,14 @@ static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli, static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, enum dcerpc_pkt_type ptype, - uint32 rpc_call_id, + uint32_t rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, const DATA_BLOB *auth_info, bool client_hdr_signing, DATA_BLOB *blob) { - uint16 auth_len = auth_info->length; + uint16_t auth_len = auth_info->length; NTSTATUS status; union dcerpc_payload u; struct dcerpc_ctx_list ctx_list; @@ -1093,7 +1093,7 @@ static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, struct pipe_auth_data *auth, - uint32 rpc_call_id, + uint32_t rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, DATA_BLOB *rpc_out) @@ -1628,7 +1628,7 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, - uint32 rpc_call_id, + uint32_t rpc_call_id, enum dcerpc_AuthType auth_type, enum dcerpc_AuthLevel auth_level, DATA_BLOB *pauth_blob, @@ -1675,7 +1675,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, enum dcerpc_AuthType auth_type, enum dcerpc_AuthLevel auth_level, - uint32 rpc_call_id, + uint32_t rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index 7c5ff0e..b033da6 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -44,8 +44,8 @@ struct rpc_pipe_client { char *desthost; char *srv_name_slash; - uint16 max_xmit_frag; - uint16 max_recv_frag; + uint16_t max_xmit_frag; + uint16_t max_recv_frag; struct pipe_auth_data *auth; }; -- 1.9.1 From ee702a93bb55e06b7ca387e61c970507ec26d488 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 26 Feb 2015 17:03:44 +0100 Subject: [PATCH 076/440] torture: Fix the usage of the MEMORY credential cache. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Pair-Programmed-With: Guenther Deschner Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Andreas Schneider Signed-off-by: Guenther Deschner Signed-off-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Sat Mar 21 02:03:34 CET 2015 on sn-devel-104 (cherry picked from commit c07a54b2941c0d5dc69eb435405daddac1b994bf) --- source4/torture/rpc/remote_pac.c | 84 +++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 7ea123b..07b6c01 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -139,6 +139,8 @@ static bool test_PACVerify(struct torture_context *tctx, struct netlogon_creds_CredentialState *creds; struct gensec_security *gensec_client_context; struct gensec_security *gensec_server_context; + struct cli_credentials *client_creds; + struct cli_credentials *server_creds; DATA_BLOB client_to_server, server_to_client, pac_wrapped, payload; struct PAC_Validate pac_wrapped_struct; @@ -157,8 +159,22 @@ static bool test_PACVerify(struct torture_context *tctx, "Testing PAC Verify (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n", secure_channel_type, test_machine_name, negotiate_flags); + /* + * Copy the credentials in order to use a different MEMORY krb5 ccache + * for each client/server setup. The MEMORY cache identifier is a + * pointer to the creds container. If we copy it the pointer changes and + * we will get a new clean memory cache. + */ + client_creds = cli_credentials_shallow_copy(tmp_ctx, + cmdline_credentials); + torture_assert(tctx, client_creds, "Failed to copy of credentials"); + + server_creds = cli_credentials_shallow_copy(tmp_ctx, + credentials); + torture_assert(tctx, server_creds, "Failed to copy of credentials"); + if (!test_SetupCredentials2(p, tctx, negotiate_flags, - credentials, secure_channel_type, + server_creds, secure_channel_type, &creds)) { return false; } @@ -174,7 +190,7 @@ static bool test_PACVerify(struct torture_context *tctx, status = gensec_set_target_hostname(gensec_client_context, test_machine_name); - status = gensec_set_credentials(gensec_client_context, cmdline_credentials); + status = gensec_set_credentials(gensec_client_context, client_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI"); @@ -185,7 +201,7 @@ static bool test_PACVerify(struct torture_context *tctx, auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); - status = gensec_set_credentials(gensec_server_context, credentials); + status = gensec_set_credentials(gensec_server_context, server_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed"); status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI"); @@ -269,7 +285,7 @@ static bool test_PACVerify(struct torture_context *tctx, r.in.logon = &logon; r.in.logon_level = NetlogonGenericInformation; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.validation_level = NetlogonValidationGenericInfo2; r.out.validation = &validation; r.out.authoritative = &authoritative; @@ -292,7 +308,7 @@ static bool test_PACVerify(struct torture_context *tctx, r.in.logon_level = NetlogonGenericInformation; r.in.logon = &logon; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.validation_level = NetlogonValidationGenericInfo2; torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), @@ -315,7 +331,7 @@ static bool test_PACVerify(struct torture_context *tctx, r.in.logon_level = NetlogonGenericInformation; r.in.logon = &logon; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.validation_level = NetlogonValidationGenericInfo2; torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), @@ -368,7 +384,7 @@ static bool test_PACVerify(struct torture_context *tctx, r.in.logon_level = NetlogonGenericInformation; r.in.logon = &logon; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.validation_level = NetlogonValidationGenericInfo2; torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), @@ -420,7 +436,7 @@ static bool test_PACVerify(struct torture_context *tctx, r.in.logon_level = NetlogonGenericInformation; r.in.logon = &logon; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.validation_level = NetlogonValidationGenericInfo2; torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), @@ -527,6 +543,8 @@ static bool test_S2U4Self(struct torture_context *tctx, struct netlogon_creds_CredentialState *creds; struct gensec_security *gensec_client_context; struct gensec_security *gensec_server_context; + struct cli_credentials *client_creds; + struct cli_credentials *server_creds; struct auth4_context *auth_context; struct auth_session_info *kinit_session_info; @@ -548,6 +566,20 @@ static bool test_S2U4Self(struct torture_context *tctx, "Testing S4U2SELF (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n", secure_channel_type, test_machine_name, negotiate_flags); + /* + * Copy the credentials in order to use a different MEMORY krb5 ccache + * for each client/server setup. The MEMORY cache identifier is a + * pointer to the creds container. If we copy it the pointer changes and + * we will get a new clean memory cache. + */ + client_creds = cli_credentials_shallow_copy(tmp_ctx, + cmdline_credentials); + torture_assert(tctx, client_creds, "Failed to copy of credentials"); + + server_creds = cli_credentials_shallow_copy(tmp_ctx, + credentials); + torture_assert(tctx, server_creds, "Failed to copy of credentials"); + auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -561,7 +593,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = gensec_set_target_hostname(gensec_client_context, test_machine_name); - status = gensec_set_credentials(gensec_client_context, cmdline_credentials); + status = gensec_set_credentials(gensec_client_context, client_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI"); @@ -572,7 +604,7 @@ static bool test_S2U4Self(struct torture_context *tctx, auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); - status = gensec_set_credentials(gensec_server_context, credentials); + status = gensec_set_credentials(gensec_server_context, server_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed"); status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI"); @@ -606,9 +638,10 @@ static bool test_S2U4Self(struct torture_context *tctx, /* Now do the dance with S2U4Self */ /* Wipe out any existing ccache */ - cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); - cli_credentials_set_impersonate_principal(credentials, - cli_credentials_get_principal(cmdline_credentials, tmp_ctx), + cli_credentials_invalidate_ccache(client_creds, CRED_SPECIFIED); + cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED); + cli_credentials_set_impersonate_principal(server_creds, + cli_credentials_get_principal(client_creds, tmp_ctx), talloc_asprintf(tmp_ctx, "host/%s", test_machine_name)); status = gensec_client_start(tctx, &gensec_client_context, @@ -618,7 +651,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = gensec_set_target_hostname(gensec_client_context, test_machine_name); /* We now set the same credentials on both client and server contexts */ - status = gensec_set_credentials(gensec_client_context, credentials); + status = gensec_set_credentials(gensec_client_context, server_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI"); @@ -629,7 +662,7 @@ static bool test_S2U4Self(struct torture_context *tctx, auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); - status = gensec_set_credentials(gensec_server_context, credentials); + status = gensec_set_credentials(gensec_server_context, server_creds); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed"); status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI"); @@ -655,16 +688,16 @@ static bool test_S2U4Self(struct torture_context *tctx, } while (1); /* Don't pollute the remaining tests with the changed credentials */ - cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); - cli_credentials_set_target_service(credentials, NULL); - cli_credentials_set_impersonate_principal(credentials, NULL, NULL); + cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED); + cli_credentials_set_target_service(server_creds, NULL); + cli_credentials_set_impersonate_principal(server_creds, NULL, NULL); /* Extract the PAC using Samba's code */ status = gensec_session_info(gensec_server_context, gensec_server_context, &s2u4self_session_info); torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed"); - cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, + cli_credentials_get_ntlm_username_domain(client_creds, tctx, &ninfo.identity_info.account_name.string, &ninfo.identity_info.domain_name.string); @@ -674,10 +707,10 @@ static bool test_S2U4Self(struct torture_context *tctx, chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); - names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), - cli_credentials_get_domain(credentials)); + names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(client_creds), + cli_credentials_get_domain(client_creds)); - status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, + status = cli_credentials_get_ntlm_response(client_creds, tctx, &flags, chal, names_blob, @@ -694,12 +727,12 @@ static bool test_S2U4Self(struct torture_context *tctx, ninfo.identity_info.parameter_control = 0; ninfo.identity_info.logon_id_low = 0; ninfo.identity_info.logon_id_high = 0; - ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials); + ninfo.identity_info.workstation.string = cli_credentials_get_workstation(server_creds); logon.network = &ninfo; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon_level = NetlogonNetworkInformation; @@ -708,7 +741,7 @@ static bool test_S2U4Self(struct torture_context *tctx, r.out.authoritative = &authoritative; if (!test_SetupCredentials2(p, tctx, negotiate_flags, - credentials, secure_channel_type, + server_creds, secure_channel_type, &creds)) { return false; } @@ -797,7 +830,6 @@ struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "pac"); struct torture_rpc_tcase *tcase; - /* It is important to use different names, so that old entries in our credential cache are not used */ tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-arcfour", &ndr_table_netlogon, TEST_MACHINE_NAME_BDC); torture_rpc_tcase_add_test_creds(tcase, "verify-sig-arcfour", test_PACVerify_bdc_arcfour); -- 1.9.1 From 4969fa99a4fac68ef320e44eb7bc03f311d25f5a Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 13 Apr 2015 15:37:58 +0200 Subject: [PATCH 077/440] torture: Correctly invalidate the memory ccache. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andreas Schneider Reviewed-by: Michael Adam (cherry picked from commit ba6ffdbbcc954b9c58547eb9505fce75234d593d) --- source4/torture/rpc/remote_pac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 07b6c01..e7e24c1 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -168,6 +168,8 @@ static bool test_PACVerify(struct torture_context *tctx, client_creds = cli_credentials_shallow_copy(tmp_ctx, cmdline_credentials); torture_assert(tctx, client_creds, "Failed to copy of credentials"); + /* Invalidate the gss creds container to allocate a new MEMORY ccache */ + cli_credentials_invalidate_ccache(client_creds, CRED_SPECIFIED); server_creds = cli_credentials_shallow_copy(tmp_ctx, credentials); -- 1.9.1 From 24c3e5991510fca2b1fe81921e9fbfe3ff211bdd Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 14 Apr 2015 10:56:53 +0200 Subject: [PATCH 078/440] torture: Free the temporary memory context BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andreas Schneider Reviewed-by: Michael Adam Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Wed Apr 15 11:20:22 CEST 2015 on sn-devel-104 (cherry picked from commit e8951eb9b837c05bd3c53de9368702c5de644ada) --- source4/torture/rpc/remote_pac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index e7e24c1..a6d49fc 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -449,6 +449,8 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); + talloc_free(tmp_ctx); + return true; } -- 1.9.1 From 1f1ea90048d24cd8742d19919e56e06d79b70108 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2014 20:49:23 +1300 Subject: [PATCH 079/440] docs: Explain that winbindd enforces smb signing by default. Change-Id: I9341fa3bd7480836ac5e0c18e28458175b42d44a BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 0f6ad5370e0ed5201a63e047b7e3fef5b27b3149) --- docs-xml/smbdotconf/security/clientsigning.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs-xml/smbdotconf/security/clientsigning.xml b/docs-xml/smbdotconf/security/clientsigning.xml index 34fce3e..3b5687f 100644 --- a/docs-xml/smbdotconf/security/clientsigning.xml +++ b/docs-xml/smbdotconf/security/clientsigning.xml @@ -9,8 +9,11 @@ and disabled. - When set to auto or default, SMB signing is offered, but not enforced. - When set to mandatory, SMB signing is required and if set + When set to auto or default, SMB signing is offered, but not + enforced, except in winbindd, where it is enforced to Active + Directory Domain Controllers. + + When set to mandatory, SMB signing is required and if set to disabled, SMB signing is not offered either. -- 1.9.1 From d70180daa074da35cea22a4b3092c8b767781ce1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jul 2015 11:22:46 +1200 Subject: [PATCH 080/440] lib/tls: Add new 'tls priority' option This adds a new option to the smb.conf to allow administrators to disable TLS protocols in GnuTLS without changing the code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11076 Pair-programmed-with: Garming Sam BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Garming Sam Signed-off-by: Andrew Bartlett (similar to commit 374d73617d71abf594cc92d335cd8bc60c10a1b7) --- docs-xml/smbdotconf/security/tlspriority.xml | 18 ++++++++++++++++ lib/param/loadparm.c | 1 + lib/param/param_table.c | 8 +++++++ source3/param/loadparm.c | 1 + source4/ldap_server/ldap_server.c | 1 + source4/lib/tls/tls.h | 2 ++ source4/lib/tls/tls_tstream.c | 31 ++++++++++++++++++++++++---- source4/libcli/ldap/ldap_client.c | 3 ++- source4/librpc/rpc/dcerpc_roh.c | 2 ++ 9 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 docs-xml/smbdotconf/security/tlspriority.xml diff --git a/docs-xml/smbdotconf/security/tlspriority.xml b/docs-xml/smbdotconf/security/tlspriority.xml new file mode 100644 index 0000000..345f030 --- /dev/null +++ b/docs-xml/smbdotconf/security/tlspriority.xml @@ -0,0 +1,18 @@ + + + This option can be set to a string describing the TLS protocols + to be supported in the parts of Samba that use GnuTLS, specifically + the AD DC. + + The valid options are described in the + GNUTLS + Priority-Strings documentation at http://gnutls.org/manual/html_node/Priority-Strings.html + + + + NORMAL + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 2cc145d..99fe1aa 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2556,6 +2556,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); + lpcfg_do_global_parameter(lp_ctx, "tls priority", "NORMAL"); lpcfg_do_global_parameter(lp_ctx, "prefork children:smb", "4"); lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc"); diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 530d858..57cb382 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4433,6 +4433,14 @@ struct parm_struct parm_table[] = { .special = NULL, .enum_list = NULL }, + { + .label = "tls priority", + .type = P_STRING, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(tls_priority), + .special = NULL, + .enum_list = NULL + }, {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0} }; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 94de252..e6a34d4 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -833,6 +833,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem"); + lpcfg_string_set(Globals.ctx, &Globals.tls_priority, "NORMAL"); lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic"); diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 691266c..d849ed3 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -934,6 +934,7 @@ static void ldapsrv_task_init(struct task_server *task) lpcfg_tls_cafile(ldap_service, task->lp_ctx), lpcfg_tls_crlfile(ldap_service, task->lp_ctx), lpcfg_tls_dhpfile(ldap_service, task->lp_ctx), + lpcfg_tls_priority(task->lp_ctx), &ldap_service->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed tstream_tls_params_server - %s\n", diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index 3ff009d..e6c27f3 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -71,6 +71,7 @@ struct tstream_tls_params; NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, + const char *tls_priority, struct tstream_tls_params **_tlsp); NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, @@ -81,6 +82,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *dhp_file, + const char *tls_priority, struct tstream_tls_params **_params); bool tstream_tls_params_enabled(struct tstream_tls_params *params); diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 113e03a..4352c24 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -868,6 +868,7 @@ struct tstream_tls_params { #if ENABLE_GNUTLS gnutls_certificate_credentials x509_cred; gnutls_dh_params dh_params; + const char *tls_priority; #endif /* ENABLE_GNUTLS */ bool tls_enabled; }; @@ -895,6 +896,7 @@ bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp) NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, + const char *tls_priority, struct tstream_tls_params **_tlsp) { #if ENABLE_GNUTLS @@ -943,6 +945,12 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, } } + tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); + if (tlsp->tls_priority == NULL) { + talloc_free(tlsp); + return NT_STATUS_NO_MEMORY; + } + tlsp->tls_enabled = true; *_tlsp = tlsp; @@ -964,6 +972,7 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req; struct tstream_tls_connect_state *state; + const char *error_pos; #if ENABLE_GNUTLS struct tstream_tls *tlss; int ret; @@ -1002,9 +1011,12 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = gnutls_set_default_priority(tlss->tls_session); + ret = gnutls_priority_set_direct(tlss->tls_session, + tls_params->tls_priority, + &error_pos); if (ret != GNUTLS_E_SUCCESS) { - DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", + __location__, gnutls_strerror(ret), error_pos)); tevent_req_error(req, EINVAL); return tevent_req_post(req, ev); } @@ -1072,6 +1084,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *dhp_file, + const char *tls_priority, struct tstream_tls_params **_tlsp) { struct tstream_tls_params *tlsp; @@ -1202,6 +1215,12 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params); + tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); + if (tlsp->tls_priority == NULL) { + talloc_free(tlsp); + return NT_STATUS_NO_MEMORY; + } + tlsp->tls_enabled = true; #else /* ENABLE_GNUTLS */ @@ -1228,6 +1247,7 @@ struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx, struct tevent_req *req; struct tstream_tls_accept_state *state; struct tstream_tls *tlss; + const char *error_pos; #if ENABLE_GNUTLS int ret; #endif /* ENABLE_GNUTLS */ @@ -1265,9 +1285,12 @@ struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = gnutls_set_default_priority(tlss->tls_session); + ret = gnutls_priority_set_direct(tlss->tls_session, + tlsp->tls_priority, + &error_pos); if (ret != GNUTLS_E_SUCCESS) { - DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", + __location__, gnutls_strerror(ret), error_pos)); tevent_req_error(req, EINVAL); return tevent_req_post(req, ev); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index e49df9e..b11490f 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -464,7 +464,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con if (conn->ldaps) { char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx); char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx); - + const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx); if (!ca_file || !*ca_file) { composite_error(result, NT_STATUS_INVALID_PARAMETER_MIX); @@ -474,6 +474,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con status = tstream_tls_params_client(state, ca_file, crl_file, + tls_priority, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { composite_error(result, status); diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index 0907294..61a22a7 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -31,6 +31,7 @@ #include "librpc/rpc/dcerpc.h" #include "librpc/rpc/dcerpc_roh.h" #include "librpc/rpc/dcerpc_proto.h" +#include "lib/param/param.h" static ssize_t tstream_roh_pending_bytes(struct tstream_context *stream); static struct tevent_req * tstream_roh_readv_send( @@ -185,6 +186,7 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn, /* Initialize TLS */ if (use_tls) { status = tstream_tls_params_client(state->roh, NULL, NULL, + lpcfg_tls_priority(lp_ctx), &state->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n", -- 1.9.1 From 80502d3e691ea1ed0354918f4e9fb809af38066d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jul 2015 11:46:36 +1200 Subject: [PATCH 081/440] lib/tls: Change default supported TLS versions. The new default is to disable SSLv3, as this is no longer considered secure after CVE-2014-3566. Newer GnuTLS versions already disable SSLv3. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Andrew Bartlett Pair-programmed-with: Garming Sam Signed-off-by: Garming Sam (similar to commit 06f378fa652e0ff3cb5aae1b30eee4f73b570664) --- docs-xml/smbdotconf/security/tlspriority.xml | 6 +++++- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- testprogs/blackbox/test_ldb.sh | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs-xml/smbdotconf/security/tlspriority.xml b/docs-xml/smbdotconf/security/tlspriority.xml index 345f030..d399eef 100644 --- a/docs-xml/smbdotconf/security/tlspriority.xml +++ b/docs-xml/smbdotconf/security/tlspriority.xml @@ -8,11 +8,15 @@ to be supported in the parts of Samba that use GnuTLS, specifically the AD DC. + The default turns off SSLv3, as this protocol is no longer considered + secure after CVE-2014-3566 (otherwise known as POODLE) impacted SSLv3 use + in HTTPS applications. + The valid options are described in the GNUTLS Priority-Strings documentation at http://gnutls.org/manual/html_node/Priority-Strings.html - NORMAL + NORMAL:-VERS-SSL3.0 diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 99fe1aa..0de9793 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2556,7 +2556,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); - lpcfg_do_global_parameter(lp_ctx, "tls priority", "NORMAL"); + lpcfg_do_global_parameter(lp_ctx, "tls priority", "NORMAL:-VERS-SSL3.0"); lpcfg_do_global_parameter(lp_ctx, "prefork children:smb", "4"); lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e6a34d4..360d997 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -833,7 +833,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem"); - lpcfg_string_set(Globals.ctx, &Globals.tls_priority, "NORMAL"); + lpcfg_string_set(Globals.ctx, &Globals.tls_priority, "NORMAL:-VERS-SSL3.0"); lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic"); diff --git a/testprogs/blackbox/test_ldb.sh b/testprogs/blackbox/test_ldb.sh index 60bad44..394a7e8 100755 --- a/testprogs/blackbox/test_ldb.sh +++ b/testprogs/blackbox/test_ldb.sh @@ -39,6 +39,9 @@ ldbsearch="$VALGRIND ldbsearch" check "RootDSE" $ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base DUMMY=x dnsHostName highestCommittedUSN || failed=`expr $failed + 1` check "RootDSE (full)" $ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base '(objectClass=*)' || failed=`expr $failed + 1` check "RootDSE (extended)" $ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base '(objectClass=*)' --extended-dn || failed=`expr $failed + 1` +if [ x$p = x"ldaps" ]; then + testit_expect_failure "RootDSE over SSLv3 should fail" $ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base DUMMY=x dnsHostName highestCommittedUSN --option='tlspriority=NONE:+VERS-SSL3.0:+MAC-ALL:+CIPHER-ALL:+RSA:+SIGN-ALL:+COMP-NULL' && failed=`expr $failed + 1` +fi echo "Getting defaultNamingContext" BASEDN=`$ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base DUMMY=x defaultNamingContext | grep defaultNamingContext | awk '{print $2}'` -- 1.9.1 From e230335febe078f948f997b56e0557a62eefe9a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 23 Mar 2015 20:37:23 +0100 Subject: [PATCH 082/440] s4:selftest: run rpc.netlogon.admin against also ad_dc BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit c9f68df7987ad17c83217c7fad46cd7ee59ecde2) --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index e044c80..c20fc67 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -82,7 +82,7 @@ else: # add tests to this list as they start passing, so we test # that they stay passing -ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] +ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests -- 1.9.1 From 31e5b53fa7342ede6f0f38b66f8e624ea5f64615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 7 Apr 2014 15:46:32 +0200 Subject: [PATCH 083/440] lib/util: globally include herrors in error.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Stefan Metzmacher (cherry picked from commit 5b68527f2b2b5be0cd27bfbbdd87921ac4373e48) --- libcli/util/error.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcli/util/error.h b/libcli/util/error.h index 0972601..1461445 100644 --- a/libcli/util/error.h +++ b/libcli/util/error.h @@ -22,6 +22,7 @@ #include "libcli/util/werror.h" #include "libcli/util/doserr.h" #include "libcli/util/ntstatus.h" +#include "libcli/util/hresult.h" /***************************************************************************** convert a NT status code to a dos class/code -- 1.9.1 From b5171747a855c76ed42ce560e7020bce4c679523 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jan 2015 13:05:15 +0000 Subject: [PATCH 084/440] s4:rpc_server: pass the remote address to gensec_set_remote_address() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider Reviewed-by: Günther Deschner (cherry picked from commit efebf3c80c9d89d012942d99ce955225c218790a) --- source4/rpc_server/dcesrv_auth.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 51f2995..374c2e0 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -80,10 +80,24 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) server_credentials, NULL, &auth->gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to call samba_server_gensec_start %s\n", + nt_errstr(status))); + return false; + } + + if (call->conn->remote_address != NULL) { + status = gensec_set_remote_address(auth->gensec_security, + call->conn->remote_address); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to call gensec_set_remote_address() %s\n", + nt_errstr(status))); + return false; + } + } status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, auth->auth_info->auth_level); - if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", (int)auth->auth_info->auth_type, -- 1.9.1 From 3d6763584831e2ce82b1c8bbed229848d7d7f32f Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 24 Aug 2015 20:26:42 -0700 Subject: [PATCH 085/440] Prevent a crash in Python modules that try to authenticate by ensuring we reject cases where credendials fields are not intialized. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Richard Sharpe Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Aug 25 21:45:18 CEST 2015 on sn-devel-104 (cherry picked from commit dba9e631bd1e1c7e00430b72f0c60b32ee4eeb33) --- auth/ntlmssp/ntlmssp_client.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index d8531e4c..b22619b 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -147,7 +147,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; int flags = 0; - const char *user, *domain; + const char *user = NULL, *domain = NULL, *workstation = NULL; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -256,6 +256,23 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx, &user, &domain); + workstation = cli_credentials_get_workstation(gensec_security->credentials); + + if (user == NULL) { + DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (domain == NULL) { + DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (workstation == NULL) { + DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { flags |= CLI_CRED_NTLM2; } @@ -337,7 +354,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, nt_response.data, nt_response.length, domain, user, - cli_credentials_get_workstation(gensec_security->credentials), + workstation, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags); if (!NT_STATUS_IS_OK(nt_status)) { -- 1.9.1 From 3ee67d808de3e057980b00f0eec4f2ae26090989 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Dec 2015 21:49:26 +0100 Subject: [PATCH 086/440] asn1: Remove an unused asn1 function BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 45800223fd5fb8d35770d101882cfb2b19465944) --- lib/util/asn1.c | 28 ---------------------------- lib/util/asn1.h | 1 - 2 files changed, 29 deletions(-) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 90f950a..26473d1 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -994,34 +994,6 @@ void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len) data->length = len; } -/* - check if a ASN.1 blob is a full tag -*/ -NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) -{ - struct asn1_data *asn1 = asn1_init(NULL); - int size; - - NT_STATUS_HAVE_NO_MEMORY(asn1); - - asn1->data = blob.data; - asn1->length = blob.length; - if (!asn1_start_tag(asn1, tag)) { - talloc_free(asn1); - return STATUS_MORE_ENTRIES; - } - size = asn1_tag_remaining(asn1) + asn1->ofs; - - talloc_free(asn1); - - if (size > blob.length) { - return STATUS_MORE_ENTRIES; - } - - *packet_size = size; - return NT_STATUS_OK; -} - NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) { struct asn1_data asn1; diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 568b4e4..d15787e 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -100,7 +100,6 @@ bool asn1_check_enumerated(struct asn1_data *data, int v); bool asn1_write_enumerated(struct asn1_data *data, uint8_t v); bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob); void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len); -NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); #endif /* _ASN_1_H */ -- 1.9.1 From 4af68c411c9500f41a46feb30e2862c2bccaf4ef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Dec 2015 10:41:39 +0100 Subject: [PATCH 087/440] asn1: Make asn1_peek_full_tag return 0/errno We don't need the full power of NTSTATUS here. This was the only NTSTATUS in asn1.h, so I think it's worth removing it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit ad630a681e345cc7765f2a2f2dc1ba25ee0200c2) --- auth/gensec/spnego.c | 12 +++++------- lib/util/asn1.c | 8 ++++---- lib/util/asn1.h | 2 +- libcli/ldap/ldap_message.c | 9 ++++++++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index fe2ec43..85b13e9 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1095,26 +1095,24 @@ static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security, { struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; size_t expected; - NTSTATUS status; bool ok; *full_in = data_blob_null; if (spnego_state->in_needed == 0) { size_t size = 0; + int ret; /* * try to work out the size of the full * input token, it might be fragmented */ - status = asn1_peek_full_tag(in, ASN1_APPLICATION(0), &size); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - status = asn1_peek_full_tag(in, ASN1_CONTEXT(1), &size); + ret = asn1_peek_full_tag(in, ASN1_APPLICATION(0), &size); + if ((ret != 0) && (ret != EAGAIN)) { + ret = asn1_peek_full_tag(in, ASN1_CONTEXT(1), &size); } - if (NT_STATUS_IS_OK(status) || - NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + if ((ret == 0) || (ret == EAGAIN)) { spnego_state->in_needed = size; } else { /* diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 26473d1..eb47a1a 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -994,7 +994,7 @@ void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len) data->length = len; } -NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) +int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) { struct asn1_data asn1; size_t size; @@ -1006,14 +1006,14 @@ NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) ok = asn1_peek_tag_needed_size(&asn1, tag, &size); if (!ok) { - return NT_STATUS_INVALID_BUFFER_SIZE; + return EMSGSIZE; } if (size > blob.length) { *packet_size = size; - return STATUS_MORE_ENTRIES; + return EAGAIN; } *packet_size = size; - return NT_STATUS_OK; + return 0; } diff --git a/lib/util/asn1.h b/lib/util/asn1.h index d15787e..0cf5fbc 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -100,6 +100,6 @@ bool asn1_check_enumerated(struct asn1_data *data, int v); bool asn1_write_enumerated(struct asn1_data *data, uint8_t v); bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob); void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len); -NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); +int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); #endif /* _ASN_1_H */ diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index ba94f4c..9d7c62a 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -1626,6 +1626,8 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, */ NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) { + int ret; + if (blob.length < 6) { /* * We need at least 6 bytes to workout the length @@ -1633,5 +1635,10 @@ NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_siz */ return STATUS_MORE_ENTRIES; } - return asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size); + + ret = asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size); + if (ret != 0) { + return map_nt_error_from_unix_common(ret); + } + return NT_STATUS_OK; } -- 1.9.1 From e4418cd863c65a32d2d005391c1e631f8a7ea2f1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Dec 2015 13:50:54 +0100 Subject: [PATCH 088/440] asn1: Add overflow check to asn1_write Found by pure code reading :-) BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 249202d8c04fae245ee373e7926484e33822c905) --- lib/util/asn1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index eb47a1a..ab6bbcd0 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -40,6 +40,12 @@ void asn1_free(struct asn1_data *data) bool asn1_write(struct asn1_data *data, const void *p, int len) { if (data->has_error) return false; + + if ((len < 0) || (data->ofs + (size_t)len < data->ofs)) { + data->has_error = true; + return false; + } + if (data->length < data->ofs+len) { uint8_t *newp; newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); -- 1.9.1 From 1911ca520d99d5c3edd44a978bc5663ec1a1ed02 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Dec 2015 10:57:07 +0100 Subject: [PATCH 089/440] asn1: Add some early returns BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit f908e6560bcb06938bee9019d43b622eb31fb2c3) --- lib/util/asn1.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index ab6bbcd0..037465b 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -72,7 +72,9 @@ bool asn1_push_tag(struct asn1_data *data, uint8_t tag) { struct nesting *nesting; - asn1_write_uint8(data, tag); + if (!asn1_write_uint8(data, tag)) { + return false; + } nesting = talloc(data, struct nesting); if (!nesting) { data->has_error = true; @@ -91,6 +93,10 @@ bool asn1_pop_tag(struct asn1_data *data) struct nesting *nesting; size_t len; + if (data->has_error) { + return false; + } + nesting = data->nesting; if (!nesting) { @@ -190,6 +196,10 @@ static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool nega bool asn1_write_implicit_Integer(struct asn1_data *data, int i) { + if (data->has_error) { + return false; + } + if (i == -1) { /* -1 is special as it consists of all-0xff bytes. In push_int_bigendian this is the only case that is not -- 1.9.1 From 61a48c0afaee3cea5ed77f706c22fe8fd6c8ce29 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Dec 2015 11:18:47 +0100 Subject: [PATCH 090/440] asn1: Make "struct nesting" private BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit ef8049b24353ea657d6fba989a294939c58895cb) --- lib/util/asn1.c | 6 ++++++ lib/util/asn1.h | 6 +----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 037465b..602d4b5 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -20,6 +20,12 @@ #include "includes.h" #include "../lib/util/asn1.h" +struct nesting { + off_t start; + size_t taglen; /* for parsing */ + struct nesting *next; +}; + /* allocate an asn1 structure */ struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 0cf5fbc..f77036f 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -20,11 +20,7 @@ #ifndef _ASN_1_H #define _ASN_1_H -struct nesting { - off_t start; - size_t taglen; /* for parsing */ - struct nesting *next; -}; +struct nesting; struct asn1_data { uint8_t *data; -- 1.9.1 From c4f9751f503adc1e6890b551dc64ba03100eb746 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 17:58:21 +0100 Subject: [PATCH 091/440] asn1: Add asn1_has_error() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit fa207fe9d17d27060e5e2989c19980103fd4778d) --- lib/util/asn1.c | 5 +++++ lib/util/asn1.h | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 602d4b5..925a2a1 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -42,6 +42,11 @@ void asn1_free(struct asn1_data *data) talloc_free(data); } +bool asn1_has_error(const struct asn1_data *data) +{ + return data->has_error; +} + /* write to the ASN1 buffer, advancing the buffer pointer */ bool asn1_write(struct asn1_data *data, const void *p, int len) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index f77036f..c2f0283 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -50,6 +50,7 @@ typedef struct asn1_data ASN1_DATA; struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx); void asn1_free(struct asn1_data *data); +bool asn1_has_error(const struct asn1_data *data); bool asn1_write(struct asn1_data *data, const void *p, int len); bool asn1_write_uint8(struct asn1_data *data, uint8_t v); bool asn1_push_tag(struct asn1_data *data, uint8_t tag); -- 1.9.1 From 84f4e1088af3503887fd8326263bb322d6aa18e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 18:11:00 +0100 Subject: [PATCH 092/440] lib: Use asn1_has_error() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 57a0bc9a9f3a02f809153dc19537110c4c796338) --- auth/gensec/gensec_util.c | 2 +- libcli/auth/spnego_parse.c | 20 ++++++++++---------- libcli/ldap/ldap_message.c | 18 +++++++++++------- source3/lib/tldap.c | 6 +++--- source3/libsmb/clispnego.c | 18 +++++++++--------- source4/auth/gensec/gensec_krb5.c | 2 +- 6 files changed, 35 insertions(+), 31 deletions(-) diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c index 8ef4b25..64fffb1 100644 --- a/auth/gensec/gensec_util.c +++ b/auth/gensec/gensec_util.c @@ -81,7 +81,7 @@ static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid) if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err; if (!asn1_check_OID(data, oid)) goto err; - ret = !data->has_error; + ret = !asn1_has_error(data); err: diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index d4c5bdc..ba67273 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -32,7 +32,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false; if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false; - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + while (!asn1_has_error(asn1) && 0 < asn1_tag_remaining(asn1)) { int i; uint8_t context; @@ -54,7 +54,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, asn1->has_error = true; return false; } - for (i = 0; !asn1->has_error && + for (i = 0; !asn1_has_error(asn1) && 0 < asn1_tag_remaining(asn1); i++) { char *oid; const char **p; @@ -127,7 +127,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, if (!asn1_end_tag(asn1)) return false; if (!asn1_end_tag(asn1)) return false; - return !asn1->has_error; + return !asn1_has_error(asn1); } static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token) @@ -190,7 +190,7 @@ static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni if (!asn1_pop_tag(asn1)) return false; if (!asn1_pop_tag(asn1)) return false; - return !asn1->has_error; + return !asn1_has_error(asn1); } static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, @@ -201,7 +201,7 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, if (!asn1_start_tag(asn1, ASN1_CONTEXT(1))) return false; if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false; - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + while (!asn1_has_error(asn1) && 0 < asn1_tag_remaining(asn1)) { uint8_t context; char *oid; if (!asn1_peek_uint8(asn1, &context)) { @@ -242,7 +242,7 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, if (!asn1_end_tag(asn1)) return false; if (!asn1_end_tag(asn1)) return false; - return !asn1->has_error; + return !asn1_has_error(asn1); } static bool write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token) @@ -279,7 +279,7 @@ static bool write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTar if (!asn1_pop_tag(asn1)) return false; if (!asn1_pop_tag(asn1)) return false; - return !asn1->has_error; + return !asn1_has_error(asn1); } ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data *token) @@ -324,7 +324,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data } } - if (!asn1->has_error) ret = asn1->ofs; + if (!asn1_has_error(asn1)) ret = asn1->ofs; err: @@ -357,7 +357,7 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da break; } - if (!asn1->has_error) { + if (!asn1_has_error(asn1)) { *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length); ret = asn1->ofs; } @@ -423,7 +423,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx, if (!asn1_pop_tag(asn1)) goto err; } - if (asn1->has_error) { + if (asn1_has_error(asn1)) { goto err; } diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 9d7c62a..62e7fcc 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -322,7 +322,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7))) return false; if (!asn1_write_LDAPString(data, tree->u.present.attr)) return false; if (!asn1_pop_tag(data)) return false; - return !data->has_error; + return !asn1_has_error(data); case LDB_OP_APPROX: /* approx test */ @@ -366,7 +366,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree default: return false; } - return !data->has_error; + return !asn1_has_error(data); } static bool ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) @@ -842,7 +842,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed; if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed; if (!asn1_end_tag(data)) goto failed; - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + if (asn1_has_error(data) || (attrib == NULL) || + (value.data == NULL)) { goto failed; } @@ -954,7 +955,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed; if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed; if (!asn1_end_tag(data)) goto failed; - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + if (asn1_has_error(data) || (attrib == NULL) || + (value.data == NULL)) { goto failed; } @@ -973,7 +975,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed; if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed; if (!asn1_end_tag(data)) goto failed; - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + if (asn1_has_error(data) || (attrib == NULL) || + (value.data == NULL)) { goto failed; } @@ -1011,7 +1014,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed; if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed; if (!asn1_end_tag(data)) goto failed; - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + if (asn1_has_error(data) || (attrib == NULL) || + (value.data == NULL)) { goto failed; } @@ -1609,7 +1613,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, } if (!asn1_end_tag(data)) goto prot_err; - if ((data->has_error) || (data->nesting != NULL)) { + if (asn1_has_error(data) || (data->nesting != NULL)) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } return NT_STATUS_OK; diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c index 5d3773e4..17238a5 100644 --- a/source3/lib/tldap.c +++ b/source3/lib/tldap.c @@ -1315,7 +1315,7 @@ done: } s++; - if (data->has_error) { + if (asn1_has_error(data)) { return false; } @@ -1529,7 +1529,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld, if (!asn1_write_OctetString(data, uval, uval_len)) return false; } - if (data->has_error) { + if (asn1_has_error(data)) { return false; } return asn1_pop_tag(data); @@ -2019,7 +2019,7 @@ static bool tldap_decode_controls(struct tldap_req_state *state) if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto out; if (!asn1_read_OctetString_talloc(msg, data, &oid)) goto out; - if ((data->has_error) || (oid == NULL)) { + if (asn1_has_error(data) || (oid == NULL)) { goto out; } c->oid = oid; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index ec8d1ee..68c3309 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -83,7 +83,7 @@ DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, err: - if (data->has_error) { + if (asn1_has_error(data)) { DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs)); } @@ -143,7 +143,7 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, if (!asn1_read_OID(data,ctx, &OIDs[i])) { goto err; } - if (data->has_error) { + if (asn1_has_error(data)) { goto err; } } @@ -209,11 +209,11 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, if (!asn1_end_tag(data)) goto err; - ret = !data->has_error; + ret = !asn1_has_error(data); err: - if (data->has_error) { + if (asn1_has_error(data)) { int j; if (principal) { TALLOC_FREE(*principal); @@ -254,7 +254,7 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui err: - if (data->has_error) { + if (asn1_has_error(data)) { DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs)); } @@ -342,11 +342,11 @@ bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, if (!asn1_end_tag(data)) goto err; if (!asn1_end_tag(data)) goto err; - ret = !data->has_error; + ret = !asn1_has_error(data); err: - if (data->has_error) { + if (asn1_has_error(data)) { data_blob_free(chal1); data_blob_free(chal2); } @@ -452,11 +452,11 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, if (!asn1_end_tag(data)) goto err; if (!asn1_end_tag(data)) goto err; - ret = !data->has_error; + ret = !asn1_has_error(data); err: - if (data->has_error) { + if (asn1_has_error(data)) { DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data->ofs)); asn1_free(data); data_blob_free(auth); diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 7b9ecfe..0b37c45 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -459,7 +459,7 @@ static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB * if (!asn1_end_tag(data)) goto err; - ret = !data->has_error; + ret = !asn1_has_error(data); err: -- 1.9.1 From 4d933f10c9279e966aae35f1249a0241206c5554 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:50:49 +0100 Subject: [PATCH 093/440] asn1: Add asn1_set_error() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 94b44598a581539958d8f537742fcab44d21de4c) --- lib/util/asn1.c | 5 +++++ lib/util/asn1.h | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 925a2a1..f147e21 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -47,6 +47,11 @@ bool asn1_has_error(const struct asn1_data *data) return data->has_error; } +void asn1_set_error(struct asn1_data *data) +{ + data->has_error = true; +} + /* write to the ASN1 buffer, advancing the buffer pointer */ bool asn1_write(struct asn1_data *data, const void *p, int len) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index c2f0283..94f14f8 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -51,6 +51,7 @@ typedef struct asn1_data ASN1_DATA; struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx); void asn1_free(struct asn1_data *data); bool asn1_has_error(const struct asn1_data *data); +void asn1_set_error(struct asn1_data *data); bool asn1_write(struct asn1_data *data, const void *p, int len); bool asn1_write_uint8(struct asn1_data *data, uint8_t v); bool asn1_push_tag(struct asn1_data *data, uint8_t tag); -- 1.9.1 From f5dc890970af16363522071ddbaab296415fbc30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:51:07 +0100 Subject: [PATCH 094/440] lib: Use asn1_set_error() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 8cfb6a313937964902940a7ebada7bacab7dbbb8) --- libcli/auth/spnego_parse.c | 20 ++++++++++---------- source3/libsmb/clispnego.c | 2 +- source4/auth/gensec/gensec_krb5.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index ba67273..5418189 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -37,7 +37,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, uint8_t context; if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = true; + asn1_set_error(asn1); break; } @@ -51,7 +51,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, mechTypes = talloc(mem_ctx, const char *); if (mechTypes == NULL) { - asn1->has_error = true; + asn1_set_error(asn1); return false; } for (i = 0; !asn1_has_error(asn1) && @@ -63,7 +63,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, const char *, i+2); if (p == NULL) { talloc_free(mechTypes); - asn1->has_error = true; + asn1_set_error(asn1); return false; } mechTypes = p; @@ -97,7 +97,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, uint8_t type_peek; if (!asn1_start_tag(asn1, ASN1_CONTEXT(3))) return false; if (!asn1_peek_uint8(asn1, &type_peek)) { - asn1->has_error = true; + asn1_set_error(asn1); break; } if (type_peek == ASN1_OCTET_STRING) { @@ -119,7 +119,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, break; } default: - asn1->has_error = true; + asn1_set_error(asn1); break; } } @@ -205,7 +205,7 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, uint8_t context; char *oid; if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = true; + asn1_set_error(asn1); break; } @@ -234,7 +234,7 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, if (!asn1_end_tag(asn1)) return false; break; default: - asn1->has_error = true; + asn1_set_error(asn1); break; } } @@ -302,7 +302,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data if (!asn1_load(asn1, data)) goto err; if (!asn1_peek_uint8(asn1, &context)) { - asn1->has_error = true; + asn1_set_error(asn1); } else { switch (context) { case ASN1_APPLICATION(0): @@ -319,7 +319,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data } break; default: - asn1->has_error = true; + asn1_set_error(asn1); break; } } @@ -353,7 +353,7 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da write_negTokenTarg(asn1, &spnego->negTokenTarg); break; default: - asn1->has_error = true; + asn1_set_error(asn1); break; } diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 68c3309..195aedc 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -431,7 +431,7 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, if (!asn1_end_tag(data)) goto err; } } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) { - data->has_error = 1; + asn1_set_error(data); goto err; } diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 0b37c45..60b175a 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -449,7 +449,7 @@ static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB * data_remaining = asn1_tag_remaining(data); if (data_remaining < 3) { - data->has_error = true; + asn1_set_error(data); } else { if (!asn1_read(data, tok_id, 2)) goto err; data_remaining -= 2; -- 1.9.1 From 374a4d3c3af1944742973bbbe0ffad76b8a16745 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:53:23 +0100 Subject: [PATCH 095/440] asn1: Add asn1_extract_blob() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 7b7aa016df35ed7f8388a9df08d66a816adc1bf7) --- lib/util/asn1.c | 20 ++++++++++++++++++++ lib/util/asn1.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index f147e21..134c550 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -1016,6 +1016,26 @@ bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob) return true; } +bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, + DATA_BLOB *pblob) +{ + DATA_BLOB blob; + + if (!asn1_blob(asn1, &blob)) { + return false; + } + + *pblob = (DATA_BLOB) { .length = blob.length }; + pblob->data = talloc_move(mem_ctx, &blob.data); + + /* + * Stop access from here on + */ + asn1->has_error = true; + + return true; +} + /* Fill in an asn1 struct without making a copy */ diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 94f14f8..5c2daad 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -97,6 +97,8 @@ bool asn1_read_enumerated(struct asn1_data *data, int *v); bool asn1_check_enumerated(struct asn1_data *data, int v); bool asn1_write_enumerated(struct asn1_data *data, uint8_t v); bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob); +bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, + DATA_BLOB *pblob); void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len); int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); -- 1.9.1 From 60043656fc9cf8863adcb412dba101abc25badea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 20:10:53 +0100 Subject: [PATCH 096/440] lib: Use asn1_extract_blob() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit a93946b2fee6d6fedb9830d1dec593fca15fefc8) --- libcli/auth/spnego_parse.c | 10 ++++---- libcli/ldap/ldap_message.c | 5 +++- source3/libsmb/clispnego.c | 12 +++++++--- source4/auth/gensec/gensec_krb5.c | 4 +++- source4/libcli/ldap/ldap_controls.c | 48 ++++++++++++++++++------------------- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index 5418189..b5e4b1c 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -357,11 +357,12 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da break; } - if (!asn1_has_error(asn1)) { - *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length); - ret = asn1->ofs; + if (!asn1_extract_blob(asn1, mem_ctx, blob)) { + goto err; } + ret = asn1->ofs; + err: asn1_free(asn1); @@ -427,8 +428,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx, goto err; } - *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length); - if (blob->length != asn1->length) { + if (!asn1_extract_blob(asn1, mem_ctx, blob)) { goto err; } diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 62e7fcc..927202c 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -691,7 +691,10 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg, if (!asn1_pop_tag(data)) goto err; - *result = data_blob_talloc(mem_ctx, data->data, data->length); + if (!asn1_extract_blob(data, mem_ctx, result)) { + goto err; + } + asn1_free(data); return true; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 195aedc..3be508b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -79,7 +79,9 @@ DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, if (!asn1_pop_tag(data)) goto err; - ret = data_blob_talloc(ctx, data->data, data->length); + if (!asn1_extract_blob(data, ctx, &ret)) { + goto err; + } err: @@ -250,7 +252,9 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui if (!asn1_write(data, ticket.data, ticket.length)) goto err; if (!asn1_pop_tag(data)) goto err; - ret = data_blob_talloc(ctx, data->data, data->length); + if (!asn1_extract_blob(data, ctx, &ret)) { + goto err; + } err: @@ -377,7 +381,9 @@ DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob) if (!asn1_pop_tag(data)) goto err; if (!asn1_pop_tag(data)) goto err; - ret = data_blob_talloc(ctx, data->data, data->length); + if (!asn1_extract_blob(data, ctx, &ret)) { + goto err; + } err: diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 60b175a..31cf990 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -417,7 +417,9 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO if (!asn1_pop_tag(data)) goto err; - ret = data_blob_talloc(mem_ctx, data->data, data->length); + if (!asn1_extract_blob(data, mem_ctx, &ret)) { + goto err; + } asn1_free(data); return ret; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index f910acb..448a263 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -512,10 +512,10 @@ static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -716,10 +716,10 @@ static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -774,10 +774,10 @@ static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -809,10 +809,10 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -837,10 +837,10 @@ static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -865,10 +865,10 @@ static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -897,10 +897,10 @@ static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -935,10 +935,10 @@ static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -971,10 +971,10 @@ static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -1047,10 +1047,10 @@ static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -1089,10 +1089,10 @@ static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; @@ -1140,10 +1140,10 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) return false; } - *out = data_blob_talloc(mem_ctx, data->data, data->length); - if (out->data == NULL) { + if (!asn1_extract_blob(data, mem_ctx, out)) { return false; } + talloc_free(data); return true; } -- 1.9.1 From bb262a263f995b3dee04fb3290d7a64947d30941 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:23:20 +0100 Subject: [PATCH 097/440] asn1: Add asn1_has_nesting BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 2a5141a772f531ca113b9c2649ad79400c283749) --- lib/util/asn1.c | 5 +++++ lib/util/asn1.h | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 134c550..6f4a510 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -52,6 +52,11 @@ void asn1_set_error(struct asn1_data *data) data->has_error = true; } +bool asn1_has_nesting(const struct asn1_data *data) +{ + return data->nesting != NULL; +} + /* write to the ASN1 buffer, advancing the buffer pointer */ bool asn1_write(struct asn1_data *data, const void *p, int len) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 5c2daad..38dff34 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -52,6 +52,7 @@ struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx); void asn1_free(struct asn1_data *data); bool asn1_has_error(const struct asn1_data *data); void asn1_set_error(struct asn1_data *data); +bool asn1_has_nesting(const struct asn1_data *data); bool asn1_write(struct asn1_data *data, const void *p, int len); bool asn1_write_uint8(struct asn1_data *data, uint8_t v); bool asn1_push_tag(struct asn1_data *data, uint8_t tag); -- 1.9.1 From 0d2e4e5047fb7f8cb53e408879d1c32c2bb3a8d2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:24:01 +0100 Subject: [PATCH 098/440] lib: Use asn1_has_nesting BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 1282f6063d53b2b86c91cf80c9b0d6a2cdb4ad7b) --- libcli/ldap/ldap_message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 927202c..a4e702a 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -1616,7 +1616,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, } if (!asn1_end_tag(data)) goto prot_err; - if (asn1_has_error(data) || (data->nesting != NULL)) { + if (asn1_has_error(data) || asn1_has_nesting(data)) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } return NT_STATUS_OK; -- 1.9.1 From d4bcce1aea2d79eb02611d08f6e48d3333663a62 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:25:41 +0100 Subject: [PATCH 099/440] asn1: Add asn1_current_ofs() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 927bbed6aaed9d454e8750aa053c5fa9fb1f1005) --- lib/util/asn1.c | 5 +++++ lib/util/asn1.h | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 6f4a510..81b7cf8 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -57,6 +57,11 @@ bool asn1_has_nesting(const struct asn1_data *data) return data->nesting != NULL; } +off_t asn1_current_ofs(const struct asn1_data *data) +{ + return data->ofs; +} + /* write to the ASN1 buffer, advancing the buffer pointer */ bool asn1_write(struct asn1_data *data, const void *p, int len) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 38dff34..92ad8ae 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -53,6 +53,7 @@ void asn1_free(struct asn1_data *data); bool asn1_has_error(const struct asn1_data *data); void asn1_set_error(struct asn1_data *data); bool asn1_has_nesting(const struct asn1_data *data); +off_t asn1_current_ofs(const struct asn1_data *data); bool asn1_write(struct asn1_data *data, const void *p, int len); bool asn1_write_uint8(struct asn1_data *data, uint8_t v); bool asn1_push_tag(struct asn1_data *data, uint8_t tag); -- 1.9.1 From 3ea7ca938d984dbf1f348dd1a2c8729450c539cd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 5 Jan 2016 10:55:44 +0100 Subject: [PATCH 100/440] lib: Use asn1_current_ofs() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit b7f0e29fd2c30024d5a7da7aa6a1f0084612f9d2) --- libcli/auth/spnego_parse.c | 6 ++++-- source3/libsmb/clispnego.c | 9 ++++++--- source4/auth/gensec/gensec_krb5.c | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index b5e4b1c..1b294df 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -324,7 +324,9 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data } } - if (!asn1_has_error(asn1)) ret = asn1->ofs; + if (!asn1_has_error(asn1)) { + ret = asn1_current_ofs(asn1); + } err: @@ -361,7 +363,7 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da goto err; } - ret = asn1->ofs; + ret = asn1_current_ofs(asn1); err: diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3be508b..6fc59b5 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -86,7 +86,8 @@ DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, err: if (asn1_has_error(data)) { - DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs)); + DEBUG(1, ("Failed to build negTokenInit at offset %d\n", + (int)asn1_current_ofs(data))); } asn1_free(data); @@ -259,7 +260,8 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui err: if (asn1_has_error(data)) { - DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs)); + DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n", + (int)asn1_current_ofs(data))); } asn1_free(data); @@ -463,7 +465,8 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, err: if (asn1_has_error(data)) { - DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data->ofs)); + DEBUG(3, ("spnego_parse_auth_response failed at %d\n", + (int)asn1_current_ofs(data))); asn1_free(data); data_blob_free(auth); return false; diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 31cf990..5d2f8b8 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -426,7 +426,8 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO err: - DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs)); + DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n", + (int)asn1_current_ofs(data))); asn1_free(data); return ret; } -- 1.9.1 From 3df74a0f999753f042be853252bb274cb0189fcd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:30:35 +0100 Subject: [PATCH 101/440] libcli: Remove a reference to asn1->ofs BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 3c340d81d8bf2e7b8488b150452bbcc4e3b521b6) --- libcli/cldap/cldap.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c index df81767..2d34337 100644 --- a/libcli/cldap/cldap.c +++ b/libcli/cldap/cldap.c @@ -220,7 +220,6 @@ nomem: static bool cldap_socket_recv_dgram(struct cldap_socket *c, struct cldap_incoming *in) { - DATA_BLOB blob; struct asn1_data *asn1; void *p; struct cldap_search_state *search; @@ -230,16 +229,12 @@ static bool cldap_socket_recv_dgram(struct cldap_socket *c, goto error; } - blob = data_blob_const(in->buf, in->len); - asn1 = asn1_init(in); if (!asn1) { goto nomem; } - if (!asn1_load(asn1, blob)) { - goto nomem; - } + asn1_load_nocopy(asn1, in->buf, in->len); in->ldap_msg = talloc(in, struct ldap_message); if (in->ldap_msg == NULL) { @@ -267,8 +262,11 @@ static bool cldap_socket_recv_dgram(struct cldap_socket *c, search = talloc_get_type_abort(p, struct cldap_search_state); search->response.in = talloc_move(search, &in); + search->response.asn1 = asn1; - search->response.asn1->ofs = 0; + + asn1_load_nocopy(search->response.asn1, + search->response.in->buf, search->response.in->len); DLIST_REMOVE(c->searches.list, search); -- 1.9.1 From 8e1530dcb6efe923f42743546ab958ee84d7e265 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:42:11 +0100 Subject: [PATCH 102/440] asn1: Remove a reference to asn1_data internals BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 44c56fc66788adf7b58f1d77a1e7d79d840ea9f6) --- lib/util/tests/asn1_tests.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c index 2c68cb4..a91d7a7 100644 --- a/lib/util/tests/asn1_tests.c +++ b/lib/util/tests/asn1_tests.c @@ -337,8 +337,10 @@ static bool test_asn1_Integer(struct torture_context *tctx) if (!asn1_write_Integer(data, integer_tests[i].value)) goto err; - blob.data = data->data; - blob.length = data->length; + if (!asn1_blob(data, &blob)) { + goto err; + } + torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result"); if (!asn1_load(data, blob)) goto err; -- 1.9.1 From 28a7195696b092ec305e610f621e316c62276732 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Jan 2016 21:26:50 +0100 Subject: [PATCH 103/440] asn1: Make 'struct asn1_data' private BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit d865ed20062cc5fc62313c25e7a6cb90763d0158) --- lib/util/asn1.c | 9 +++++++++ lib/util/asn1.h | 10 +--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/util/asn1.c b/lib/util/asn1.c index 81b7cf8..4778da4 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -26,6 +26,15 @@ struct nesting { struct nesting *next; }; + +struct asn1_data { + uint8_t *data; + size_t length; + off_t ofs; + struct nesting *nesting; + bool has_error; +}; + /* allocate an asn1 structure */ struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) { diff --git a/lib/util/asn1.h b/lib/util/asn1.h index 92ad8ae..4eb8506 100644 --- a/lib/util/asn1.h +++ b/lib/util/asn1.h @@ -21,15 +21,7 @@ #define _ASN_1_H struct nesting; - -struct asn1_data { - uint8_t *data; - size_t length; - off_t ofs; - struct nesting *nesting; - bool has_error; -}; - +struct asn1_data; typedef struct asn1_data ASN1_DATA; #define ASN1_APPLICATION(x) ((x)+0x60) -- 1.9.1 From f5988a258bc12616a74c2b6bdc9085a85b91edfd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Jan 2016 15:03:47 -0800 Subject: [PATCH 104/440] s3: smbclient: asn1_extract_blob() stops further asn1 processing by setting has_error. Don't call asn1_has_error() after asn1_extract_blob() has been successful otherwise we get an "Failed to build negTokenInit at offset" message on success. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Thu Jan 7 16:00:02 CET 2016 on sn-devel-144 (cherry picked from commit 8108f0d320013c560339723d8d70ab601350d0c4) --- source3/libsmb/clispnego.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6fc59b5..6551858 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -83,14 +83,19 @@ DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, goto err; } + asn1_free(data); + data = NULL; + err: - if (asn1_has_error(data)) { - DEBUG(1, ("Failed to build negTokenInit at offset %d\n", - (int)asn1_current_ofs(data))); - } + if (data != NULL) { + if (asn1_has_error(data)) { + DEBUG(1, ("Failed to build negTokenInit at offset %d\n", + (int)asn1_current_ofs(data))); + } - asn1_free(data); + asn1_free(data); + } return ret; } -- 1.9.1 From fe3d00fd4b4c64b2f04153649e3196a5e02d18be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 15:50:06 +0100 Subject: [PATCH 105/440] s3:clispnego: fix confusing warning in spnego_gen_krb5_wrap() asn1_extract_blob() stops further asn1 processing by setting has_error. Don't call asn1_has_error() after asn1_extract_blob() has been successful otherwise we get an "Failed to build krb5 wrapper at" message on success. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11702 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit 14f1a94b6fb3a55be1e60fe0d28740f04fd94b3f) (cherry picked from commit c17b1f697c388bd2e0190c4a3574d951b8be483e) --- source3/libsmb/clispnego.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6551858..af52e4e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -262,14 +262,19 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui goto err; } + asn1_free(data); + data = NULL; + err: - if (asn1_has_error(data)) { - DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n", - (int)asn1_current_ofs(data))); - } + if (data != NULL) { + if (asn1_has_error(data)) { + DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n", + (int)asn1_current_ofs(data))); + } - asn1_free(data); + asn1_free(data); + } return ret; } -- 1.9.1 From a102a427611d33d931ac5f4887710f68df7dee6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 14:48:20 +0100 Subject: [PATCH 106/440] s3:pam_smbpass: remove unused dependency to LIBNTLMSSP BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher --- source3/pam_smbpass/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/pam_smbpass/wscript_build b/source3/pam_smbpass/wscript_build index a4eaa6c..fb760b4 100644 --- a/source3/pam_smbpass/wscript_build +++ b/source3/pam_smbpass/wscript_build @@ -8,7 +8,7 @@ if bld.CONFIG_SET('WITH_PAM_MODULES'): support.c''', allow_warnings=True, deps='''tdb talloc pam PAM_ERRORS wbclient cap asn1util param pdb - LIBNTLMSSP LIBTSOCKET''', + LIBTSOCKET''', cflags='-DLOCALEDIR=\"%s/locale\"' % bld.env.DATADIR, realname='pam_smbpass.so', install_path='${PAMMODULESDIR}', -- 1.9.1 From 931a5414c7599a6dc0c7e8723db7f4a894edac3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Wed, 2 Sep 2015 12:37:12 +0200 Subject: [PATCH 107/440] tls: increase Diffie-Hellman group size to 2048 bits 1024 bits is already the minimum accepted size of current TLS libraries. 2048 is recommended for servers, see https://weakdh.org/ BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Bjoern Jacke Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Sep 3 03:47:48 CEST 2015 on sn-devel-104 (cherry picked from commit 22a37c453d83c39634fbae72de592024d9b8ba4a) --- source4/lib/tls/tls.c | 2 +- source4/lib/tls/tls_tstream.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index 2fe4ff7..f2197e6 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -31,7 +31,7 @@ #if ENABLE_GNUTLS #include -#define DH_BITS 1024 +#define DH_BITS 2048 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T) typedef gnutls_datum gnutls_datum_t; diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 4352c24..255e2ce 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -28,7 +28,7 @@ #if ENABLE_GNUTLS #include -#define DH_BITS 1024 +#define DH_BITS 2048 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T) typedef gnutls_datum gnutls_datum_t; -- 1.9.1 From 1bb8eee5c6d9a7275a79080454780cc99d1a46a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 16 Nov 2015 16:31:27 +0100 Subject: [PATCH 108/440] ntlmssp: add some missing defines from MS-NLMP to our IDL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit feb4ee62c5271b45877c1d3bc1d8b327439e5fd4) --- librpc/idl/ntlmssp.idl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 7c3b8fe..de1a085 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -59,7 +59,8 @@ interface ntlmssp typedef [enum8bit] enum { NTLMSSP_WINDOWS_MAJOR_VERSION_5 = 0x05, - NTLMSSP_WINDOWS_MAJOR_VERSION_6 = 0x06 + NTLMSSP_WINDOWS_MAJOR_VERSION_6 = 0x06, + NTLMSSP_WINDOWS_MAJOR_VERSION_10 = 0x0A } ntlmssp_WindowsMajorVersion; /* @@ -140,7 +141,8 @@ interface ntlmssp typedef [bitmap32bit] bitmap { NTLMSSP_AVFLAG_CONSTRAINTED_ACCOUNT = 0x00000001, - NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE = 0x00000002 + NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE = 0x00000002, + NTLMSSP_AVFLAG_TARGET_SPN_FROM_UNTRUSTED_SOURCE = 0x00000004 } ntlmssp_AvFlags; typedef [gensize,nodiscriminant,flag(NDR_NOALIGN)] union { -- 1.9.1 From 11eb167ae4c85f06ec998af5c37038427e98cba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 16:42:08 +0100 Subject: [PATCH 109/440] ntlmssp: fix copy/paste typo in CHALLENGE_MESSAGE in IDL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 4be7451d9a7ed122c61a08bcf977bebeef4749dd) --- librpc/idl/ntlmssp.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index de1a085..42a1554 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -185,7 +185,7 @@ interface ntlmssp uint8 ServerChallenge[8]; uint8 Reserved[8]; [value(ndr_size_AV_PAIR_LIST(TargetInfo, ndr->flags))] uint16 TargetInfoLen; - [value(TargetInfoLen)] uint16 TargetNameInfoMaxLen; + [value(TargetInfoLen)] uint16 TargetInfoMaxLen; [relative] [subcontext(0),subcontext_size(TargetInfoLen)] AV_PAIR_LIST *TargetInfo; [switch_is(NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)] ntlmssp_Version Version; } CHALLENGE_MESSAGE; -- 1.9.1 From 63fc49a5187e054e7041f447ba77b99e0053ff85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 15:34:47 +0100 Subject: [PATCH 110/440] ntlmssp: properly document version defines in IDL (from MS-NLMP). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit ded0f3c8b7b4132d250907022ba59e88b45a6ed0) --- librpc/idl/ntlmssp.idl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 42a1554..ed2f02c 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -54,7 +54,8 @@ interface ntlmssp /* NTLMSSP_WINDOWS_MAJOR_VERSION_5: Windows XP SP2 and Server 2003 - NTLMSSP_WINDOWS_MAJOR_VERSION_6: Windows Vista, Server 2008, 7 and Server 2008 R2 + NTLMSSP_WINDOWS_MAJOR_VERSION_6: Windows Vista, Server 2008, 7, Server 2008 R2, 8, Server 2012, 8.1, Server 2012 R2 + NTLMSSP_WINDOWS_MAJOR_VERSION_10: Windows 10, Windows Server 2016 Technical Preview */ typedef [enum8bit] enum { @@ -64,9 +65,10 @@ interface ntlmssp } ntlmssp_WindowsMajorVersion; /* - NTLMSSP_WINDOWS_MINOR_VERSION_0: Windows Vista, Server 2008, 7, Server 2008 R2 - NTLMSSP_WINDOWS_MINOR_VERSION_1: Windows XP SP2 - NTLMSSP_WINDOWS_MINOR_VERSION_2: Windows Server 2003 + NTLMSSP_WINDOWS_MINOR_VERSION_0: Windows Vista, 10, Server 2016 Technical Preview + NTLMSSP_WINDOWS_MINOR_VERSION_1: Windows XP SP2, 7, Server 2008 R2 + NTLMSSP_WINDOWS_MINOR_VERSION_2: Windows Server 2003, 8, Server 2012 + NTLMSSP_WINDOWS_MINOR_VERSION_3: Windows 8.1, Server 2012 R2 */ typedef [enum8bit] enum { -- 1.9.1 From cd28f995f93febbdda7b884c989e2f537a76f155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 15:35:29 +0100 Subject: [PATCH 111/440] ntlmssp: when pulling messages it is important to clear memory first. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 30386c23ae0a6afd2060e626c73df9a3691a71fb) --- auth/ntlmssp/ntlmssp_ndr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/ntlmssp/ntlmssp_ndr.c b/auth/ntlmssp/ntlmssp_ndr.c index af24be9..c8b16cc 100644 --- a/auth/ntlmssp/ntlmssp_ndr.c +++ b/auth/ntlmssp/ntlmssp_ndr.c @@ -25,6 +25,7 @@ #define NTLMSSP_PULL_MESSAGE(type, blob, mem_ctx, r) \ do { \ enum ndr_err_code __ndr_err; \ + ZERO_STRUCTP(r); /* in order to deal with unset neg flags */\ __ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r, \ (ndr_pull_flags_fn_t)ndr_pull_ ##type); \ if (!NDR_ERR_CODE_IS_SUCCESS(__ndr_err)) { \ -- 1.9.1 From 28ed4abbbb304ac7ab55274e1a9105e94b1e3cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:27:29 +0100 Subject: [PATCH 112/440] s4-torture: fill in ntlmssp_NEGOTIATE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 68d043faa0aa9e5e0d289806e1aa2acba3f07af5) --- source4/torture/ndr/ntlmssp.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index a3cf7b8..d5c309a 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. test suite for ntlmssp ndr operations - Copyright (C) Guenther Deschner 2010 + Copyright (C) Guenther Deschner 2010,2015 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 @@ -33,6 +33,24 @@ static const uint8_t ntlmssp_NEGOTIATE_MESSAGE_data[] = { static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, struct NEGOTIATE_MESSAGE *r) { + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmNegotiate, "MessageType"); + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2088297, "NegotiateFlags"); + torture_assert_int_equal(tctx, r->DomainNameLen, 0, "DomainNameLen"); + torture_assert_int_equal(tctx, r->DomainNameMaxLen, 0, "DomainNameMaxLen"); + torture_assert(tctx, r->DomainName == NULL, "DomainName"); + torture_assert_int_equal(tctx, r->WorkstationLen, 0, "WorkstationLen"); + torture_assert_int_equal(tctx, r->WorkstationMaxLen, 0, "WorkstationMaxLen"); + torture_assert(tctx, r->Workstation == NULL, "Workstation"); + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0x1db0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From 8947780ad0a19785af76f559c32593426b17c705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:29:16 +0100 Subject: [PATCH 113/440] s4-torture: activate testing of CHALLENGE and AUTHENTICATE ntlmssp messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 4ac7a6572149ec5b43a91a303c2008e73e467a56) --- source4/torture/ndr/ntlmssp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index d5c309a..0a593ba 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -131,9 +131,8 @@ struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx) struct torture_suite *suite = torture_suite_create(ctx, "ntlmssp"); torture_suite_add_ndr_pull_test(suite, NEGOTIATE_MESSAGE, ntlmssp_NEGOTIATE_MESSAGE_data, ntlmssp_NEGOTIATE_MESSAGE_check); -#if 0 torture_suite_add_ndr_pull_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, ntlmssp_CHALLENGE_MESSAGE_check); torture_suite_add_ndr_pull_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, ntlmssp_AUTHENTICATE_MESSAGE_check); -#endif + return suite; } -- 1.9.1 From d645142c30ac639af5a267656da1a537c4db8d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:30:16 +0100 Subject: [PATCH 114/440] s4-torture: flesh out ntlmssp_CHALLENGE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit fe1be37c71a816458173082fa9213a3f279a0b79) --- source4/torture/ndr/ntlmssp.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 0a593ba..cd4a67f 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -76,6 +76,49 @@ static const uint8_t ntlmssp_CHALLENGE_MESSAGE_data[] = { static bool ntlmssp_CHALLENGE_MESSAGE_check(struct torture_context *tctx, struct CHALLENGE_MESSAGE *r) { + uint8_t chal[8] = { 0xed, 0xc8, 0x2b, 0x7d, 0x2e, 0xd7, 0xd0, 0xd9 }; + uint8_t data[8] = { 0 }; + + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmChallenge, "MessageType"); + torture_assert_int_equal(tctx, r->TargetNameLen, 10, "TargetNameLen"); + torture_assert_int_equal(tctx, r->TargetNameMaxLen, 10, "TargetNameMaxLen"); + torture_assert_str_equal(tctx, r->TargetName, "SAMBA", "TargetName"); + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2898295, "NegotiateFlags"); + torture_assert_mem_equal(tctx, r->ServerChallenge, chal, 8, "ServerChallenge"); + torture_assert_mem_equal(tctx, r->Reserved, data, 8, "Reserved"); + torture_assert_int_equal(tctx, r->TargetInfoLen, 120, "TargetInfoLen"); + torture_assert_int_equal(tctx, r->TargetInfoMaxLen, 120, "TargetInfoMaxLen"); + torture_assert_int_equal(tctx, r->TargetInfo->count, 5, "TargetInfo->count"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[0].AvId, MsvAvNbDomainName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[0].AvLen, 10, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[0].Value.AvNbDomainName, "SAMBA", "AvNbDomainName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[1].AvId, MsvAvNbComputerName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[1].AvLen, 16, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[1].Value.AvNbComputerName, "MTHELENA", "AvNbComputerName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[2].AvId, MsvAvDnsDomainName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[2].AvLen, 28, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[2].Value.AvDnsDomainName, "ber.redhat.com", "AvDnsDomainName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[3].AvId, MsvAvDnsComputerName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[3].AvLen, 46, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "AvDnsComputerName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[4].AvId, MsvAvEOL, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[4].AvLen, 0, "AvLen"); + + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From 6e5757b009d43ba6f38213aa195e4ec46adbb962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:32:28 +0100 Subject: [PATCH 115/440] s4-torture: add ndr pullpush validation for NTLMSSP CHALLENGE and AUTHENTICATE messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 68b9b18e6cd346e2aa32418642b0746cee593be3) --- source4/torture/ndr/ntlmssp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index cd4a67f..f00c26e 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -177,5 +177,15 @@ struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx) torture_suite_add_ndr_pull_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, ntlmssp_CHALLENGE_MESSAGE_check); torture_suite_add_ndr_pull_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, ntlmssp_AUTHENTICATE_MESSAGE_check); + torture_suite_add_ndr_pullpush_test(suite, + NEGOTIATE_MESSAGE, + data_blob_const(ntlmssp_NEGOTIATE_MESSAGE_data, sizeof(ntlmssp_NEGOTIATE_MESSAGE_data)), + ntlmssp_NEGOTIATE_MESSAGE_check); + + torture_suite_add_ndr_pullpush_test(suite, + CHALLENGE_MESSAGE, + data_blob_const(ntlmssp_CHALLENGE_MESSAGE_data, sizeof(ntlmssp_CHALLENGE_MESSAGE_data)), + ntlmssp_CHALLENGE_MESSAGE_check); + return suite; } -- 1.9.1 From fcf5e319f0cbd9ee6526a053b4c32f97d684b106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:35:29 +0100 Subject: [PATCH 116/440] s4-torture: flesh out ntlmssp_AUTHENTICATE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit e073f3c0b622f49ffad7082b9b4fbc429c48d530) --- source4/torture/ndr/ntlmssp.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index f00c26e..5b879c6 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -166,6 +166,113 @@ static const uint8_t ntlmssp_AUTHENTICATE_MESSAGE_data[] = { static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, struct AUTHENTICATE_MESSAGE *r) { + uint8_t lm_challenge_response[24] = { 0 }; + struct NTLMv2_RESPONSE v2; + struct AV_PAIR_LIST AvPairs; + uint8_t Response[16] = { + 0x38, 0xcf, 0xfb, 0x39, 0x5a, 0xb3, 0x4c, 0x58, + 0x86, 0x35, 0xa3, 0xe7, 0x1e, 0x00, 0x98, 0x43 + }; + uint8_t ChallengeFromClient[8] = { + 0x3c, 0x21, 0x0a, 0xe9, 0xde, 0x61, 0xc0, 0x7e + }; + uint8_t MachineId[32] = { + 0x0a, 0xfd, 0x3b, 0x2c, 0xad, 0x43, 0x46, 0x8b, + 0x49, 0x01, 0x6c, 0xa5, 0xf3, 0xbc, 0xd2, 0x13, + 0xbb, 0x70, 0xe2, 0x65, 0x96, 0xba, 0x0d, 0x8d, + 0x5d, 0x31, 0xe6, 0x47, 0x94, 0x61, 0xed, 0x28 + }; + uint8_t EncryptedRandomSessionKey[16] = { + 0xA4, 0x23, 0xD4, 0x5C, 0x16, 0x52, 0x8D, 0x56, + 0x34, 0x2D, 0x1C, 0xFF, 0x86, 0x17, 0xC9, 0x4F + }; + + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmAuthenticate, "MessageType"); + torture_assert_int_equal(tctx, r->LmChallengeResponseLen, 24, "LmChallengeResponseLen"); + torture_assert_int_equal(tctx, r->LmChallengeResponseMaxLen, 24, "LmChallengeResponseMaxLen"); + torture_assert_mem_equal(tctx, r->LmChallengeResponse->v1.Response, lm_challenge_response, 24, "LmChallengeResponse"); + + torture_assert_int_equal(tctx, r->NtChallengeResponseLen, 270, "NtChallengeResponseLen"); + torture_assert_int_equal(tctx, r->NtChallengeResponseMaxLen, 270, "NtChallengeResponseMaxLen"); + + v2 = r->NtChallengeResponse->v2; + + torture_assert_mem_equal(tctx, v2.Response, Response, 16, "v2.Response"); + torture_assert_int_equal(tctx, v2.Challenge.RespType, 1, "RespType"); + torture_assert_int_equal(tctx, v2.Challenge.HiRespType, 1, "HiRespType"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved1, 0, "Reserved1"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved2, 0, "Reserved2"); + /* TimeStamp : Tue Sep 14 17:06:53 2010 CEST */ + torture_assert_mem_equal(tctx, v2.Challenge.ChallengeFromClient, ChallengeFromClient, 8, "v2.Challenge.ChallengeFromClient"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved3, 0, "Reserved3"); + + AvPairs = v2.Challenge.AvPairs; + + torture_assert_int_equal(tctx, AvPairs.count, 8, "AvPairs.count"); + + torture_assert_int_equal(tctx, AvPairs.pair[0].AvId, MsvAvNbDomainName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[0].AvLen, 10, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[0].Value.AvNbDomainName, "SAMBA", "Value.AvNbDomainName"); + + torture_assert_int_equal(tctx, AvPairs.pair[1].AvId, MsvAvNbComputerName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[1].AvLen, 16, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[1].Value.AvNbComputerName, "MTHELENA", "Value.AvNbComputerName"); + + torture_assert_int_equal(tctx, AvPairs.pair[2].AvId, MsvAvDnsDomainName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[2].AvLen, 28, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[2].Value.AvDnsDomainName, "ber.redhat.com", "Value.AvDnsDomainName"); + + torture_assert_int_equal(tctx, AvPairs.pair[3].AvId, MsvAvDnsComputerName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[3].AvLen, 46, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "Value.AvDnsComputerName"); + + torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsAvRestrictions, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].AvLen, 48, "AvLen"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Size, 48, "Value.AvRestrictions.Size"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Z4, 0, "Value.AvRestrictions.Z4"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.IntegrityLevel, 0, "Value.AvRestrictions.IntegrityLevel"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.SubjectIntegrityLevel, 0x00003000, "Value.AvRestrictions.SubjectIntegrityLevel"); + torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.MachineId, MachineId, 32, "Value.AvRestrictions.MachineId"); + + torture_assert_int_equal(tctx, AvPairs.pair[5].AvId, MsvChannelBindings, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[5].AvLen, 16, "AvLen"); + torture_assert_mem_equal(tctx, AvPairs.pair[5].Value.ChannelBindings, lm_challenge_response, 16, "Value.ChannelBindings"); + + torture_assert_int_equal(tctx, AvPairs.pair[6].AvId, MsvAvTargetName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[6].AvLen, 26, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[6].Value.AvTargetName, "cifs/mthelena", "Value.AvTargetName"); + + torture_assert_int_equal(tctx, AvPairs.pair[7].AvId, MsvAvEOL, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[7].AvLen, 0, "AvLen"); + + torture_assert_int_equal(tctx, r->DomainNameLen, 14, "DomainNameLen"); + torture_assert_int_equal(tctx, r->DomainNameMaxLen, 14, "DomainNameMaxLen"); + torture_assert_str_equal(tctx, r->DomainName, "W2K8DOM", "DomainName"); + + torture_assert_int_equal(tctx, r->UserNameLen, 26, "UserNameLen"); + torture_assert_int_equal(tctx, r->UserNameMaxLen, 26, "UserNameMaxLen"); + torture_assert_str_equal(tctx, r->UserName, "Administrator", "UserName"); + + torture_assert_int_equal(tctx, r->WorkstationLen, 12, "WorkstationLen"); + torture_assert_int_equal(tctx, r->WorkstationMaxLen, 12, "WorkstationMaxLen"); + torture_assert_str_equal(tctx, r->Workstation, "W2K8R2", "Workstation"); + + torture_assert_int_equal(tctx, r->EncryptedRandomSessionKeyLen, 16, "EncryptedRandomSessionKeyLen"); + torture_assert_int_equal(tctx, r->EncryptedRandomSessionKeyMaxLen, 16, "EncryptedRandomSessionKeyMaxLen"); + torture_assert_mem_equal(tctx, r->EncryptedRandomSessionKey->data, EncryptedRandomSessionKey, 16, "EncryptedRandomSessionKeyMaxLen"); + + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2888215, "NegotiateFlags"); + + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0x1db0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From abddf9441f6f6a9eda0a4fb06c6a353094deaab5 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Mon, 8 Feb 2016 23:20:19 +0100 Subject: [PATCH 117/440] s4:torture/ntlmssp fix a compiler warning about invalid array subscript BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Christian Ambach Reviewed-by: Andreas Schneider (cherry picked from commit 8ca0f14b5c4ac85e40c9c96f8f5ebb569335f031) --- source4/torture/ndr/ntlmssp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 5b879c6..ae56192 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -48,7 +48,6 @@ static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; @@ -116,7 +115,6 @@ static bool ntlmssp_CHALLENGE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; @@ -270,7 +268,6 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; -- 1.9.1 From 40a32b7e48e2422d70978d01a5e8f452b4632fd2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Jan 2016 21:49:21 +0100 Subject: [PATCH 118/440] spnego: Correctly check asn1_tag_remaining retval BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Guenther Deschner (cherry picked from commit 024c619fa82960ae4f8af029b6872102202ffd07) --- source3/libsmb/clispnego.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index af52e4e..320da41 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -349,7 +349,7 @@ bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, if (!asn1_end_tag(data)) goto err; /* the second challenge is optional (XP doesn't send it) */ - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err; if (!asn1_read_OctetString(data, ctx, chal2)) goto err; if (!asn1_end_tag(data)) goto err; @@ -438,12 +438,12 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, if (!asn1_check_enumerated(data, negResult)) goto err; if (!asn1_end_tag(data)) goto err; - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; if (!asn1_check_OID(data, mechOID)) goto err; if (!asn1_end_tag(data)) goto err; - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; if (!asn1_read_OctetString(data, ctx, auth)) goto err; if (!asn1_end_tag(data)) goto err; @@ -457,7 +457,7 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, * the optional mechListMIC field. This is a bug in Win2K. We ignore * this field if it exists. Win2K8 may return a proper mechListMIC at * which point we need to implement the integrity checking. */ - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { DATA_BLOB mechList = data_blob_null; if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err; if (!asn1_read_OctetString(data, ctx, &mechList)) goto err; -- 1.9.1 From 9ebea64f5478b173ac1626cb3e2ba53540b6eba6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 119/440] lib/util_net: move ipv6 linklocal handling into interpret_string_addr_internal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 771042a2387b596fff2ab59a1a68d75c6c27b2cc) --- lib/util/util_net.c | 95 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/lib/util/util_net.c b/lib/util/util_net.c index d58855d..f5fe323 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -49,6 +49,10 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, { int ret; struct addrinfo hints; +#if defined(HAVE_IPV6) + char addr[INET6_ADDRSTRLEN] = { 0, }; + unsigned int scope_id = 0; +#endif ZERO_STRUCT(hints); @@ -58,8 +62,60 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, /* always try as a numeric host first. This prevents unnecessary name * lookups, and also ensures we accept IPv6 addresses */ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + +#if defined(HAVE_IPV6) + if (strchr_m(str, ':')) { + char *p = strchr_m(str, '%'); + + /* + * Cope with link-local. + * This is IP:v6:addr%ifname. + */ + + if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) { + /* Length of string we want to copy. + This is IP:v6:addr (removing the %ifname). + */ + size_t len = PTR_DIFF(p,str); + + if (len+1 > sizeof(addr)) { + /* string+nul too long for array. */ + return false; + } + memcpy(addr, str, len); + addr[len] = '\0'; + + str = addr; + } + } +#endif + ret = getaddrinfo(str, NULL, &hints, ppres); if (ret == 0) { +#if defined(HAVE_IPV6) + struct sockaddr_in6 *ps6 = NULL; + + if (scope_id == 0) { + return true; + } + if (ppres == NULL) { + return true; + } + if ((*ppres) == NULL) { + return true; + } + if ((*ppres)->ai_addr->sa_family != AF_INET6) { + return true; + } + + ps6 = (struct sockaddr_in6 *)(*ppres)->ai_addr; + + if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) && + ps6->sin6_scope_id == 0) { + ps6->sin6_scope_id = scope_id; + } +#endif + return true; } @@ -94,35 +150,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss, { struct addrinfo *res = NULL; int int_flags; -#if defined(HAVE_IPV6) - char addr[INET6_ADDRSTRLEN]; - unsigned int scope_id = 0; - - if (strchr_m(str, ':')) { - char *p = strchr_m(str, '%'); - - /* - * Cope with link-local. - * This is IP:v6:addr%ifname. - */ - - if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) { - /* Length of string we want to copy. - This is IP:v6:addr (removing the %ifname). - */ - size_t len = PTR_DIFF(p,str); - - if (len+1 > sizeof(addr)) { - /* string+nul too long for array. */ - return false; - } - memcpy(addr, str, len); - addr[len] = '\0'; - - str = addr; - } - } -#endif zero_sockaddr(pss); @@ -157,16 +184,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss, memcpy(pss, res->ai_addr, res->ai_addrlen); } -#if defined(HAVE_IPV6) - if (pss->ss_family == AF_INET6 && scope_id) { - struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss; - if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) && - ps6->sin6_scope_id == 0) { - ps6->sin6_scope_id = scope_id; - } - } -#endif - freeaddrinfo(res); return true; } -- 1.9.1 From a661c4bf6cd1859ddd89da1876f5f97684b6ee9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 120/440] lib/util_net: add support for .ipv6-literal.net MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 6400bbb5eee958babbdd578c2f80b0c65d6f6e7a) --- lib/util/util_net.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/util/util_net.h | 1 + 2 files changed, 154 insertions(+), 5 deletions(-) diff --git a/lib/util/util_net.c b/lib/util/util_net.c index f5fe323..e5b33aa 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -41,6 +41,115 @@ void zero_sockaddr(struct sockaddr_storage *pss) pss->ss_family = AF_INET; } +static char *normalize_ipv6_literal(const char *str, char *buf, size_t *_len) +{ +#define IPv6_LITERAL_NET ".ipv6-literal.net" + static const size_t llen = sizeof(IPv6_LITERAL_NET) - 1; + size_t len = *_len; + int cmp; + size_t i; + size_t idx_chars = 0; + size_t cnt_delimiter = 0; + size_t cnt_chars = 0; + + if (len <= llen) { + return false; + } + + /* ignore a trailing '.' */ + if (str[len - 1] == '.') { + len -= 1; + } + + len -= llen; + if (len >= INET6_ADDRSTRLEN) { + return NULL; + } + if (len < 2) { + return NULL; + } + + cmp = strncasecmp(&str[len], IPv6_LITERAL_NET, llen); + if (cmp != 0) { + return NULL; + } + + for (i = 0; i < len; i++) { + if (idx_chars != 0) { + break; + } + + switch (str[i]) { + case '-': + buf[i] = ':'; + cnt_chars = 0; + cnt_delimiter += 1; + break; + case 's': + buf[i] = '%'; + idx_chars += 1; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + buf[i] = str[i]; + cnt_chars += 1; + break; + default: + return NULL; + } + if (cnt_chars > 4) { + return NULL; + } + if (cnt_delimiter > 7) { + return NULL; + } + } + + if (cnt_delimiter < 2) { + return NULL; + } + + for (; idx_chars != 0 && i < len; i++) { + switch (str[i]) { + case '%': + case ':': + return NULL; + default: + buf[i] = str[i]; + idx_chars += 1; + break; + } + } + + if (idx_chars == 1) { + return NULL; + } + + buf[i] = '\0'; + *_len = len; + return buf; +} + /** * Wrap getaddrinfo... */ @@ -50,8 +159,9 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, int ret; struct addrinfo hints; #if defined(HAVE_IPV6) - char addr[INET6_ADDRSTRLEN] = { 0, }; + char addr[INET6_ADDRSTRLEN*2] = { 0, }; unsigned int scope_id = 0; + size_t len = strlen(str); #endif ZERO_STRUCT(hints); @@ -64,6 +174,16 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; #if defined(HAVE_IPV6) + if (len < sizeof(addr)) { + char *p = NULL; + + p = normalize_ipv6_literal(str, addr, &len); + if (p != NULL) { + hints.ai_family = AF_INET6; + str = p; + } + } + if (strchr_m(str, ':')) { char *p = strchr_m(str, '%'); @@ -76,13 +196,15 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, /* Length of string we want to copy. This is IP:v6:addr (removing the %ifname). */ - size_t len = PTR_DIFF(p,str); + len = PTR_DIFF(p,str); if (len+1 > sizeof(addr)) { /* string+nul too long for array. */ return false; } - memcpy(addr, str, len); + if (str != addr) { + memcpy(addr, str, len); + } addr[len] = '\0'; str = addr; @@ -337,6 +459,28 @@ bool is_ipaddress_v4(const char *str) return false; } +bool is_ipv6_literal(const char *str) +{ +#if defined(HAVE_IPV6) + char buf[INET6_ADDRSTRLEN*2] = { 0, }; + size_t len = strlen(str); + char *p = NULL; + + if (len >= sizeof(buf)) { + return false; + } + + p = normalize_ipv6_literal(str, buf, &len); + if (p == NULL) { + return false; + } + + return true; +#else + return false; +#endif +} + /** * Return true if a string could be a IPv6 address. */ @@ -345,16 +489,20 @@ bool is_ipaddress_v6(const char *str) { #if defined(HAVE_IPV6) int ret = -1; + char *p = NULL; - if (strchr_m(str, ':')) { + p = strchr_m(str, ':'); + if (p == NULL) { + return is_ipv6_literal(str); + } else { char buf[INET6_ADDRSTRLEN] = { 0, }; size_t len; const char *addr = str; const char *idxs = NULL; unsigned int idx = 0; struct in6_addr ip6; - char *p = strchr_m(str, '%'); + p = strchr_m(str, '%'); if (p && (p > str)) { len = PTR_DIFF(p, str); idxs = p + 1; diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 2f1beff..29468b4 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -86,6 +86,7 @@ _PUBLIC_ uint32_t interpret_addr(const char *str); _PUBLIC_ struct in_addr interpret_addr2(const char *str); _PUBLIC_ bool is_ipaddress_v4(const char *str); +_PUBLIC_ bool is_ipv6_literal(const char *str); _PUBLIC_ bool is_ipaddress_v6(const char *str); bool is_address_any(const struct sockaddr *psa); -- 1.9.1 From c7b599799189d77b68ed0a8b98f9f69986288b68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:47:59 +0100 Subject: [PATCH 121/440] s3:test_smbclient_auth.sh: test using the ip address in the unc path (incl. ipv6-literal.net) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit e906739553ee6112426af0cf29e33ef1920a316c) --- source3/script/tests/test_smbclient_auth.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/script/tests/test_smbclient_auth.sh b/source3/script/tests/test_smbclient_auth.sh index 24e98b1..2402f73 100755 --- a/source3/script/tests/test_smbclient_auth.sh +++ b/source3/script/tests/test_smbclient_auth.sh @@ -21,6 +21,17 @@ ADDARGS="$*" incdir=`dirname $0`/../../../testprogs/blackbox . $incdir/subunit.sh +echo "${SERVER_IP}" | grep -q ':.*:' && { + # If we have an ipv6 address e.g. + # fd00:0000:0000:0000:0000:0000:5357:5f03 + # we also try + # fd00-0000-0000-0000-0000-0000-5357-5f03.ipv6-literal.net + IPV6LITERAL=$(echo "${SERVER_IP}.ipv6-literal.net" | sed -e 's!:!-!g' -e 's!%!s!') + testit "smbclient //${IPV6LITERAL}/tmpguest" $SMBCLIENT //${IPV6LITERAL}/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -c quit $ADDARGS + testit "smbclient //${IPV6LITERAL}./tmpguest" $SMBCLIENT //${IPV6LITERAL}./tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -c quit $ADDARGS +} +testit "smbclient //${SERVER_IP}/tmpguest" $SMBCLIENT //${SERVER_IP}/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -p 139 -c quit $ADDARGS + testit "smbclient //$SERVER/guestonly" $SMBCLIENT //$SERVER/guestonly $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS testit "smbclient //$SERVER/guestonly as anon" $SMBCLIENT //$SERVER/guestonly $CONFIGURATION -U% -I $SERVER_IP -p 139 -c quit $ADDARGS testit "smbclient //$SERVER/tmpguest" $SMBCLIENT //$SERVER/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS -- 1.9.1 From 7524088ad58820339ef340e71ba4f60658b1ca9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:53:21 +0100 Subject: [PATCH 122/440] s3:selftest: run samba3.blackbox.smbclient_auth.plain also with $SERVER_IPV6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit 2c9f9557e4d7e02b4f588aa0a6551a6881ac57af) --- source3/selftest/tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 830753c..a4ff473 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -135,6 +135,9 @@ for env in ["s3dc", "member", "s3member"]: plantestsuite("samba3.blackbox.smbclient_auth.plain (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$DC_USERNAME', '$DC_PASSWORD', smbclient3, configuration]) plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) member creds" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration]) +env="s3dc" +plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) ipv6" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IPV6', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration]) + for env in ["member", "s3member"]: plantestsuite("samba3.blackbox.net_cred_change.(%s:local)" % env, "%s:local" % env, [os.path.join(samba3srcdir, "script/tests/test_net_cred_change.sh"), configuration]) -- 1.9.1 From c27e013d08e9ac3fc29c8a4a83c2a44c846fbd69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 17:15:24 +0200 Subject: [PATCH 123/440] epmapper.idl: make epm_twr_t available in python bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 2e71f5d9351b9660a5ef94309674e09fdeb7ab48) --- librpc/idl/epmapper.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/epmapper.idl b/librpc/idl/epmapper.idl index 5f3d653..fd8eeb4 100644 --- a/librpc/idl/epmapper.idl +++ b/librpc/idl/epmapper.idl @@ -214,7 +214,7 @@ interface epmapper epm_floor floors[num_floors]; } epm_tower; - typedef struct { + typedef [public] struct { [value(ndr_size_epm_tower(&tower, ndr->flags))] uint32 tower_length; [subcontext(4)] epm_tower tower; } epm_twr_t; -- 1.9.1 From 3c59027e2e03b3dd1b0e5ffb9c78ebb8119af33a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:35:19 +0200 Subject: [PATCH 124/440] dcerpc.idl: make WERROR RPC faults available in ndr_print output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 5afc2d85b3d17b32ca9bd2856958114af146f80e) --- librpc/idl/dcerpc.idl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 1036693..f7bf595 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -197,18 +197,21 @@ interface dcerpc DCERPC_NCA_S_FAULT_TX_OPEN_FAILED = 0x1C000022, DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR = 0x1C000023, DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND = 0x1C000024, - DCERPC_NCA_S_FAULT_NO_CLIENT_STUB = 0x1C000025 + DCERPC_NCA_S_FAULT_NO_CLIENT_STUB = 0x1C000025, + DCERPC_FAULT_ACCESS_DENIED = 0x00000005, + DCERPC_FAULT_NO_CALL_ACTIVE = 0x000006bd, + DCERPC_FAULT_CANT_PERFORM = 0x000006d8, + DCERPC_FAULT_OUT_OF_RESOURCES = 0x000006d9, + DCERPC_FAULT_BAD_STUB_DATA = 0x000006f7, + DCERPC_FAULT_SEC_PKG_ERROR = 0x00000721 } dcerpc_nca_status; const int DCERPC_FAULT_OP_RNG_ERROR = DCERPC_NCA_S_OP_RNG_ERROR; const int DCERPC_FAULT_UNK_IF = DCERPC_NCA_S_UNKNOWN_IF; - const int DCERPC_FAULT_NDR = 0x000006f7; + const int DCERPC_FAULT_NDR = DCERPC_FAULT_BAD_STUB_DATA; const int DCERPC_FAULT_INVALID_TAG = DCERPC_NCA_S_FAULT_INVALID_TAG; const int DCERPC_FAULT_CONTEXT_MISMATCH = DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH; const int DCERPC_FAULT_OTHER = 0x00000001; - const int DCERPC_FAULT_ACCESS_DENIED = 0x00000005; - const int DCERPC_FAULT_CANT_PERFORM = 0x000006d8; - const int DCERPC_FAULT_SEC_PKG_ERROR = 0x00000721; /* we return this fault when we haven't yet run the test to see what fault w2k3 returns in this case */ -- 1.9.1 From ee45c082b34e0f39cfd1888a92463e412134b765 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:36:36 +0200 Subject: [PATCH 125/440] librpc/rpc: add error mappings for NO_CALL_ACTIVE, OUT_OF_RESOURCES and BAD_STUB_DATA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit e9e9ba7eaecf2b6d95e79fbe424e1479e9468d63) --- librpc/rpc/dcerpc_error.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index 2b90334..f386025 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -88,9 +88,11 @@ static const struct dcerpc_fault_table dcerpc_faults[] = _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), _FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED), - _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), - _FAULT_STR(DCERPC_FAULT_NDR, NT_STATUS_RPC_BAD_STUB_DATA), _FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED), + _FAULT_STR(DCERPC_FAULT_NO_CALL_ACTIVE, NT_STATUS_RPC_NO_CALL_ACTIVE), + _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), + _FAULT_STR(DCERPC_FAULT_OUT_OF_RESOURCES, NT_STATUS_RPC_OUT_OF_RESOURCES), + _FAULT_STR(DCERPC_FAULT_BAD_STUB_DATA, NT_STATUS_RPC_BAD_STUB_DATA), _FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR), { NULL, 0 } #undef _FAULT_STR -- 1.9.1 From 72b1ba5fa87fa30a047d38fe287d2e0a47d80c62 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:06:47 +0100 Subject: [PATCH 126/440] s4:librpc/rpc: map alter context SEC_PKG_ERROR to NT_STATUS_LOGON_FAILURE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 960b0adfb398eeabd48213393bc560654baeed5b) --- source4/librpc/rpc/dcerpc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 6e3410b..31b14f1 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2230,6 +2230,9 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, if (pkt->u.fault.status == DCERPC_FAULT_ACCESS_DENIED) { state->p->last_fault_code = pkt->u.fault.status; tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); + } else if (pkt->u.fault.status == DCERPC_FAULT_SEC_PKG_ERROR) { + state->p->last_fault_code = pkt->u.fault.status; + tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); } else { state->p->last_fault_code = pkt->u.fault.status; status = dcerpc_fault_to_nt_status(pkt->u.fault.status); -- 1.9.1 From 1c77eda5fddc2070e86b9427a25ca640e0aff61c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:36:14 +0100 Subject: [PATCH 127/440] s3:libads: remove unused ads_connect_gc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit cd8af25d4bf87a9156cb2afb3dd206c68b1bedd7) --- source3/libads/ads_proto.h | 1 - source3/libads/ldap.c | 133 --------------------------------------------- 2 files changed, 134 deletions(-) diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index 224d992..1399f41 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -66,7 +66,6 @@ bool ads_sitename_match(ADS_STRUCT *ads); bool ads_closest_dc(ADS_STRUCT *ads); ADS_STATUS ads_connect(ADS_STRUCT *ads); ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads); -ADS_STATUS ads_connect_gc(ADS_STRUCT *ads); void ads_disconnect(ADS_STRUCT *ads); ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3fb9e78..121ba08 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -476,139 +476,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) return NT_STATUS_NO_LOGON_SERVERS; } -/********************************************************************* - *********************************************************************/ - -static NTSTATUS ads_lookup_site(void) -{ - ADS_STRUCT *ads = NULL; - ADS_STATUS ads_status; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - ads = ads_init(lp_realm(), NULL, NULL); - if (!ads) { - return NT_STATUS_NO_MEMORY; - } - - /* The NO_BIND here will find a DC and set the client site - but not establish the TCP connection */ - - ads->auth.flags = ADS_AUTH_NO_BIND; - ads_status = ads_connect(ads); - if (!ADS_ERR_OK(ads_status)) { - DEBUG(4, ("ads_lookup_site: ads_connect to our realm failed! (%s)\n", - ads_errstr(ads_status))); - } - nt_status = ads_ntstatus(ads_status); - - if (ads) { - ads_destroy(&ads); - } - - return nt_status; -} - -/********************************************************************* - *********************************************************************/ - -static const char* host_dns_domain(const char *fqdn) -{ - const char *p = fqdn; - - /* go to next char following '.' */ - - if ((p = strchr_m(fqdn, '.')) != NULL) { - p++; - } - - return p; -} - - -/** - * Connect to the Global Catalog server - * @param ads Pointer to an existing ADS_STRUCT - * @return status of connection - * - * Simple wrapper around ads_connect() that fills in the - * GC ldap server information - **/ - -ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct dns_rr_srv *gcs_list; - int num_gcs; - const char *realm = ads->server.realm; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - int i; - bool done = false; - char *sitename = NULL; - const char *dns_hosts_file; - - if (!realm) - realm = lp_realm(); - - if ((sitename = sitename_fetch(frame, realm)) == NULL) { - ads_lookup_site(); - sitename = sitename_fetch(frame, realm); - } - - dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL); - do { - /* We try once with a sitename and once without - (unless we don't have a sitename and then we're - done */ - - if (sitename == NULL) - done = true; - - nt_status = ads_dns_query_gcs(frame, dns_hosts_file, - realm, sitename, - &gcs_list, &num_gcs); - - if (!NT_STATUS_IS_OK(nt_status)) { - ads_status = ADS_ERROR_NT(nt_status); - goto done; - } - - /* Loop until we get a successful connection or have gone - through them all. When connecting a GC server, make sure that - the realm is the server's DNS name and not the forest root */ - - for (i=0; iserver.gc = true; - ads->server.ldap_server = SMB_STRDUP(gcs_list[i].hostname); - ads->server.realm = SMB_STRDUP(host_dns_domain(ads->server.ldap_server)); - ads_status = ads_connect(ads); - if (ADS_ERR_OK(ads_status)) { - /* Reset the bind_dn to "". A Global Catalog server - may host multiple domain trees in a forest. - Windows 2003 GC server will accept "" as the search - path to imply search all domain trees in the forest */ - - SAFE_FREE(ads->config.bind_path); - ads->config.bind_path = SMB_STRDUP(""); - - - goto done; - } - SAFE_FREE(ads->server.ldap_server); - SAFE_FREE(ads->server.realm); - } - - TALLOC_FREE(gcs_list); - num_gcs = 0; - } while (!done); - -done: - talloc_destroy(frame); - - return ads_status; -} - - /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT -- 1.9.1 From cf58c384dd14ba05b28f73521faca11ff688cc4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:18:22 +0200 Subject: [PATCH 128/440] wscript_configure_system_mitkrb5: add configure checks for GSS_KRB5_CRED_NO_CI_FLAGS_X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer MIT versions (maybe krb5-1.14) will also support this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 1fd5bdafbddfd0ad2926ef50a0cb7d07956ddd44) --- wscript_configure_system_mitkrb5 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5 index 0db55ce..4b50d60 100644 --- a/wscript_configure_system_mitkrb5 +++ b/wscript_configure_system_mitkrb5 @@ -55,7 +55,8 @@ conf.CHECK_FUNCS_IN('_et_list', 'com_err') conf.CHECK_HEADERS('com_err.h', lib='com_err') conf.CHECK_HEADERS('krb5.h krb5/locate_plugin.h', lib='krb5') -conf.CHECK_HEADERS('gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h', lib='gssapi') +possible_gssapi_headers="gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h gssapi/gssapi_oid.h" +conf.CHECK_HEADERS(possible_gssapi_headers, lib='gssapi') conf.CHECK_FUNCS_IN('krb5_encrypt_data', 'k5crypto') conf.CHECK_FUNCS_IN('des_set_key','crypto') @@ -83,6 +84,7 @@ conf.CHECK_FUNCS_IN(''' gss_krb5_export_lucid_sec_context gss_import_cred gss_export_cred ''', 'gssapi gssapi_krb5') +conf.CHECK_VARIABLE('GSS_KRB5_CRED_NO_CI_FLAGS_X', headers=possible_gssapi_headers) conf.CHECK_FUNCS_IN('krb5_mk_req_extended krb5_kt_compare', 'krb5') conf.CHECK_FUNCS(''' krb5_set_default_in_tkt_etypes krb5_set_default_tgs_enctypes -- 1.9.1 From ff25a8a2d2346fb0e190dca6e7be0fcbb6892bdc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:05 +0200 Subject: [PATCH 129/440] s3:librpc/gse: make use of GSS_C_EMPTY_BUFFER in gse_init_client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 46b92525181fa32c5797c914e8de92f3c226e3c7) --- source3/librpc/crypto/gse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 46b5c6d..45b9c3b 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -201,7 +201,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, { struct gse_context *gse_ctx; OM_uint32 gss_maj, gss_min; - gss_buffer_desc name_buffer = {0, NULL}; + gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_OID_set_desc mech_set; NTSTATUS status; -- 1.9.1 From 97d082469158439b220586dea2ce395cbbedf867 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:53 +0200 Subject: [PATCH 130/440] s3:librpc/gse: fix debug message in gse_init_client() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 84c66f1a388c8b5105f3740a3cd5d4d5a27f6ee8) --- source3/librpc/crypto/gse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 45b9c3b..8568de0 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -255,8 +255,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, &gse_ctx->creds, NULL, NULL); if (gss_maj) { - DEBUG(0, ("gss_acquire_creds failed for %s, with [%s]\n", - (char *)name_buffer.value, + DEBUG(0, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s]\n", gse_errstr(gse_ctx, gss_maj, gss_min))); status = NT_STATUS_INTERNAL_ERROR; goto err_out; -- 1.9.1 From a448efc703406bfa1eaf9fe299f486f1e0ec381b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:22:44 +0200 Subject: [PATCH 131/440] s3:librpc/gse: set GSS_KRB5_CRED_NO_CI_FLAGS_X in gse_init_client() if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit a8fa078f1acbd9fb1a1681033922731dce855aad) --- source3/librpc/crypto/gse.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 8568de0..40e691e 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -203,6 +203,9 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, OM_uint32 gss_maj, gss_min; gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_OID_set_desc mech_set; +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; +#endif NTSTATUS status; if (!server || !service) { @@ -261,6 +264,28 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, goto err_out; } +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + /* + * Don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG. + * + * This allows us to disable SIGN and SEAL for + * AUTH_LEVEL_CONNECT and AUTH_LEVEL_INTEGRITY. + * + * https://groups.yahoo.com/neo/groups/cat-ietf/conversations/topics/575 + * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 + */ + gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, + GSS_KRB5_CRED_NO_CI_FLAGS_X, + &empty_buffer); + if (gss_maj) { + DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), " + "failed with [%s]\n", + gse_errstr(gse_ctx, gss_maj, gss_min))); + status = NT_STATUS_INTERNAL_ERROR; + goto err_out; + } +#endif + *_gse_ctx = gse_ctx; TALLOC_FREE(name_buffer.value); return NT_STATUS_OK; -- 1.9.1 From ffbd89b1673ab789ef6417f7a72580ed06b1f086 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 17:37:38 +0100 Subject: [PATCH 132/440] s3:librpc/gse: correctly support GENSEC_FEATURE_SESSION_KEY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit e4aebd7e28e7b00a13246b367eb2e7de5ae7b57b) --- source3/librpc/crypto/gse.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 40e691e..a2364d3 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -594,6 +594,9 @@ static NTSTATUS gensec_gse_client_start(struct gensec_security *gensec_security) return NT_STATUS_INVALID_PARAMETER; } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + do_sign = true; + } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { do_sign = true; } @@ -894,18 +897,15 @@ static bool gensec_gse_have_feature(struct gensec_security *gensec_security, talloc_get_type_abort(gensec_security->private_data, struct gse_context); + if (feature & GENSEC_FEATURE_SESSION_KEY) { + return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; + } if (feature & GENSEC_FEATURE_SIGN) { return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; } if (feature & GENSEC_FEATURE_SEAL) { return gse_ctx->gss_got_flags & GSS_C_CONF_FLAG; } - if (feature & GENSEC_FEATURE_SESSION_KEY) { - /* Only for GSE/Krb5 */ - if (smb_gss_oid_equal(gse_ctx->ret_mech, gss_mech_krb5)) { - return true; - } - } if (feature & GENSEC_FEATURE_DCE_STYLE) { return gse_ctx->gss_got_flags & GSS_C_DCE_STYLE; } -- 1.9.1 From 9bb32e77ecfb7c7a178a1586cedf7df836a3e19c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:42:41 +0100 Subject: [PATCH 133/440] s3:librpc/gse: don't log gss_acquire_creds failed at level 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some callers just retry after a kinit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 79bf88353488b5912435e0c7f8e77f2d075ce134) --- source3/librpc/crypto/gse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index a2364d3..e6d4221 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -258,7 +258,8 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, &gse_ctx->creds, NULL, NULL); if (gss_maj) { - DEBUG(0, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s]\n", + DEBUG(5, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s] -" + "the caller may retry after a kinit.\n", gse_errstr(gse_ctx, gss_maj, gss_min))); status = NT_STATUS_INTERNAL_ERROR; goto err_out; -- 1.9.1 From 4d08cf54db40a53eb1d3aeb1af0192e119f061d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:52:29 +0100 Subject: [PATCH 134/440] s3:librpc/gse: implement gensec_gse_max_{input,wrapped}_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is important in order to support gensec_[un]wrap() with GENSEC_SEAL. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit dec9d085f3eea8d49fa129c05c030bdd779cba54) --- source3/librpc/crypto/gse.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index e6d4221..fc31064 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -45,6 +45,7 @@ struct gse_context { gss_name_t server_name; gss_name_t client_name; OM_uint32 gss_want_flags, gss_got_flags; + size_t max_wrap_buf_size; size_t sig_size; gss_cred_id_t delegated_cred_handle; @@ -136,6 +137,7 @@ static NTSTATUS gse_context_init(TALLOC_CTX *mem_ctx, talloc_set_destructor((TALLOC_CTX *)gse_ctx, gse_context_destructor); gse_ctx->expire_time = GENSEC_EXPIRE_TIME_INFINITY; + gse_ctx->max_wrap_buf_size = UINT16_MAX; memcpy(&gse_ctx->gss_mech, gss_mech_krb5, sizeof(gss_OID_desc)); @@ -1062,6 +1064,40 @@ static NTSTATUS gensec_gse_session_info(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static size_t gensec_gse_max_input_size(struct gensec_security *gensec_security) +{ + struct gse_context *gse_ctx = + talloc_get_type_abort(gensec_security->private_data, + struct gse_context); + OM_uint32 maj_stat, min_stat; + OM_uint32 max_input_size; + + maj_stat = gss_wrap_size_limit(&min_stat, + gse_ctx->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + gse_ctx->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: determining signature size with gss_wrap_size_limit failed: %s\n", + gse_errstr(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_gse_max_wrapped_size(struct gensec_security *gensec_security) +{ + struct gse_context *gse_ctx = + talloc_get_type_abort(gensec_security->private_data, + struct gse_context); + return gse_ctx->max_wrap_buf_size; +} + static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, size_t data_size) { @@ -1101,6 +1137,8 @@ const struct gensec_security_ops gensec_gse_krb5_security_ops = { .check_packet = gensec_gse_check_packet, .seal_packet = gensec_gse_seal_packet, .unseal_packet = gensec_gse_unseal_packet, + .max_input_size = gensec_gse_max_input_size, + .max_wrapped_size = gensec_gse_max_wrapped_size, .wrap = gensec_gse_wrap, .unwrap = gensec_gse_unwrap, .have_feature = gensec_gse_have_feature, -- 1.9.1 From 21745a09358539bd7be8cc0a6bc038cb9f253da0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Aug 2015 10:53:34 +0200 Subject: [PATCH 135/440] s4:pygensec: make sig_size() and sign/check_packet() available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0f6713826dfe73b7f338b8110c53ce52d42efbda) --- source4/auth/gensec/pygensec.c | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index 83864e6..a6be0cb 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -504,6 +504,83 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) return ret; } +static PyObject *py_gensec_sig_size(PyObject *self, PyObject *args) +{ + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + Py_ssize_t data_size = 0; + size_t sig_size = 0; + + if (!PyArg_ParseTuple(args, "n", &data_size)) { + return NULL; + } + + sig_size = gensec_sig_size(security, data_size); + + return PyLong_FromSize_t(sig_size); +} + +static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + Py_ssize_t data_length = 0; + Py_ssize_t pdu_length = 0; + DATA_BLOB data, pdu, sig; + PyObject *py_sig; + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + + if (!PyArg_ParseTuple(args, "z#z#", &data.data, &data_length, &pdu.data, &pdu_length)) { + return NULL; + } + data.length = data_length; + pdu.length = pdu_length; + + mem_ctx = talloc_new(NULL); + + status = gensec_sign_packet(security, mem_ctx, + data.data, data.length, + pdu.data, pdu.length, &sig); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + talloc_free(mem_ctx); + return NULL; + } + + py_sig = PyBytes_FromStringAndSize((const char *)sig.data, sig.length); + talloc_free(mem_ctx); + return py_sig; +} + +static PyObject *py_gensec_check_packet(PyObject *self, PyObject *args) +{ + NTSTATUS status; + Py_ssize_t data_length = 0; + Py_ssize_t pdu_length = 0; + Py_ssize_t sig_length = 0; + DATA_BLOB data, pdu, sig; + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + + if (!PyArg_ParseTuple(args, "z#z#z#", + &data.data, &data_length, + &pdu.data, &pdu_length, + &sig.data, &sig_length)) { + return NULL; + } + data.length = data_length; + pdu.length = pdu_length; + sig.length = sig_length; + + status = gensec_check_packet(security, + data.data, data.length, + pdu.data, pdu.length, &sig); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + Py_RETURN_NONE; +} + static PyMethodDef py_gensec_security_methods[] = { { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS, "S.start_client(settings) -> gensec" }, @@ -537,6 +614,12 @@ static PyMethodDef py_gensec_security_methods[] = { "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." }, { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." }, + { "sig_size", (PyCFunction)py_gensec_sig_size, METH_VARARGS, + "S.sig_size(data_size) -> sig_size\nSize of the DCERPC packet signature" }, + { "sign_packet", (PyCFunction)py_gensec_sign_packet, METH_VARARGS, + "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." }, + { "check_packet", (PyCFunction)py_gensec_check_packet, METH_VARARGS, + "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." }, { NULL } }; -- 1.9.1 From 1ff660a284b7487d973c1b24c024861c3614cf1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 136/440] auth/gensec: keep a pointer to a possible child/sub gensec_security context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a hack in order to temporary implement something like: gensec_ntlmssp_server_domain(), which may be used within spnego. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 5e913af833721733c4f79f2636fc3ae19d5f42f0) --- auth/gensec/gensec_internal.h | 2 ++ auth/gensec/spnego.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 45a66f8..2751196 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -110,6 +110,8 @@ struct gensec_security { * NTLM authentication backend, and user lookup (such as if no * PAC is found) */ struct auth4_context *auth_context; + + struct gensec_security *child_security; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 85b13e9..74ed234 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1260,6 +1260,9 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu &spnego_state->out_frag); data_blob_free(&spnego_state->in_frag); spnego_state->in_needed = 0; + if (NT_STATUS_IS_OK(status)) { + gensec_security->child_security = spnego_state->sub_sec_security; + } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { return status; -- 1.9.1 From 8c0c58bd5e7bfb90ee1653047a05e044dd58ea0d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:29:40 +0100 Subject: [PATCH 137/440] auth/gensec: handle gensec_security_by_sasl_name(NULL, ...) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do that for all other gensec_security_by_*() functions already. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 64364e365c56c93e86305a536c5c68450d154d2a) --- auth/gensec/gensec_start.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index b1bc1b9..dc0cb0a 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -203,8 +203,10 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_sasl_name( } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { - if (!gensec_security_ops_enabled(backends[i], gensec_security)) - continue; + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], gensec_security)) { + continue; + } if (backends[i]->sasl_name && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) { backend = backends[i]; -- 1.9.1 From f0c127709f33ca52fca8d812a68f709d856f7a93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:43:02 +0100 Subject: [PATCH 138/440] auth/gensec: make gensec_security_by_name() public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8efcb4943585f015c9956118d8f42be89d5c7677) --- auth/gensec/gensec.h | 2 ++ auth/gensec/gensec_start.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index d09813e..fae44df 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -163,6 +163,8 @@ const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_sec const struct gensec_security_ops *gensec_security_by_auth_type( struct gensec_security *gensec_security, uint32_t auth_type); +const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, + const char *name); const struct gensec_security_ops **gensec_security_mechs(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx); const struct gensec_security_ops_wrapper *gensec_security_by_oid_list( diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index dc0cb0a..c7356d2 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -247,8 +247,8 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_auth_type( return NULL; } -static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, - const char *name) +const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, + const char *name) { int i; const struct gensec_security_ops **backends; -- 1.9.1 From 320b146f87bf2806f51ce0145f44a7d9b873b533 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:44:02 +0100 Subject: [PATCH 139/440] s3:auth_generic: add auth_generic_client_start_by_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit ccfd2647c7e65c3e2ad92dbc27c21570da0706d4) --- source3/include/auth_generic.h | 3 ++- source3/libsmb/auth_generic.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index 96b07cd..75babdc 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -40,7 +40,8 @@ NTSTATUS auth_generic_set_password(struct auth_generic_state *ans, NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_state **_ans); NTSTATUS auth_generic_client_start(struct auth_generic_state *ans, const char *oid); - +NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, + const char *name); NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level); diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 1f6c681..6b203f1 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -143,6 +143,29 @@ NTSTATUS auth_generic_client_start(struct auth_generic_state *ans, const char *o return NT_STATUS_OK; } +NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, + const char *name) +{ + NTSTATUS status; + + /* Transfer the credentials to gensec */ + status = gensec_set_credentials(ans->gensec_security, ans->credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC credentials: %s\n", + nt_errstr(status))); + return status; + } + talloc_unlink(ans, ans->credentials); + ans->credentials = NULL; + + status = gensec_start_mech_by_name(ans->gensec_security, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level) -- 1.9.1 From b6e6da66fa97cd1c61c7afd72ac84fc080df710b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:39:04 +0100 Subject: [PATCH 140/440] s3:auth_generic: add auth_generic_client_start_by_sasl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 79a6fc0532936558421eb4321f795655b5280763) --- source3/include/auth_generic.h | 2 ++ source3/libsmb/auth_generic.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index 75babdc..f88ffef 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -45,6 +45,8 @@ NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level); +NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, + const char **sasl_list); extern const struct gensec_security_ops gensec_ntlmssp3_client_ops; diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 6b203f1..806c785 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -190,3 +190,26 @@ NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, return NT_STATUS_OK; } + +NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, + const char **sasl_list) +{ + NTSTATUS status; + + /* Transfer the credentials to gensec */ + status = gensec_set_credentials(ans->gensec_security, ans->credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC credentials: %s\n", + nt_errstr(status))); + return status; + } + talloc_unlink(ans, ans->credentials); + ans->credentials = NULL; + + status = gensec_start_mech_by_sasl_list(ans->gensec_security, sasl_list); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} -- 1.9.1 From 8112435d4fae0ba6effc36255393fac046bb62e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 22:15:50 +0100 Subject: [PATCH 141/440] auth/ntlmssp: keep ntlmssp_state->server.netbios_domain on the correct talloc context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0a9e37a0db86815d2baf7ab791721b6a7e04a717) --- auth/ntlmssp/ntlmssp_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index b22619b..1ac0996 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -244,7 +244,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } /* TODO: parse struct_blob and fill in the rest */ ntlmssp_state->server.netbios_name = ""; - ntlmssp_state->server.netbios_domain = server_domain; + ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain); ntlmssp_state->server.dns_name = ""; ntlmssp_state->server.dns_domain = ""; -- 1.9.1 From 73ea0e166fda24cb4d0a2906d4449352c76a1215 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 142/440] auth/ntlmssp: add gensec_ntlmssp_server_domain() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a hack in order to temporary export the server domain from NTLMSSP through the gensec stack. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit a85a02b631609cd9c16e1048c62dbe9661128279) --- auth/ntlmssp/ntlmssp.c | 37 ++++++++++++++++++++++++++++++++++++- auth/ntlmssp/ntlmssp.h | 1 + 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 916b376..0b7667c 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -209,13 +209,48 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) return ret; } +static struct gensec_security *gensec_find_child_by_ops(struct gensec_security *gensec_security, + const struct gensec_security_ops *ops) +{ + struct gensec_security *current = gensec_security; + + while (current != NULL) { + if (current->ops == ops) { + return current; + } + + current = current->child_security; + } + + return NULL; +} + uint32_t gensec_ntlmssp_neg_flags(struct gensec_security *gensec_security) { struct gensec_ntlmssp_context *gensec_ntlmssp; - if (gensec_security->ops != &gensec_ntlmssp_security_ops) { + + gensec_security = gensec_find_child_by_ops(gensec_security, + &gensec_ntlmssp_security_ops); + if (gensec_security == NULL) { return 0; } + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); return gensec_ntlmssp->ntlmssp_state->neg_flags; } + +const char *gensec_ntlmssp_server_domain(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp; + + gensec_security = gensec_find_child_by_ops(gensec_security, + &gensec_ntlmssp_security_ops); + if (gensec_security == NULL) { + return NULL; + } + + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + return gensec_ntlmssp->ntlmssp_state->server.netbios_domain; +} diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 6061cd0..b357e42 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -132,3 +132,4 @@ bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob); NTSTATUS gensec_ntlmssp_init(void); uint32_t gensec_ntlmssp_neg_flags(struct gensec_security *gensec_security); +const char *gensec_ntlmssp_server_domain(struct gensec_security *gensec_security); -- 1.9.1 From 4f4b90b9f0eb277a4c4cdac639b9255e7fc944fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 21:23:33 +0100 Subject: [PATCH 143/440] s3:ntlm_auth: fix --use-cached-creds with ntlmssp-client-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 69a7ec794213e8adec5dcbd9ca45172df13292c1) --- source3/utils/ntlm_auth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 1fe7d56..ddc54b2 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1207,7 +1207,7 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m } winbindd_free_response(&wb_response); - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return NT_STATUS_OK; } static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, @@ -1266,7 +1266,7 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo DATA_BLOB empty_blob = data_blob_null; nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_IS_OK(nt_status)) { /* failed to use cached creds */ use_cached_creds = False; } -- 1.9.1 From be24b9a1055b82f034d85d6065387dc7c4f7849a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:11:05 +0100 Subject: [PATCH 144/440] s3:torture/test_ntlm_auth.py: replace tabs with whitespaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit cf2ea04135774853d1cebca82c60bed890135163) --- source3/torture/test_ntlm_auth.py | 548 +++++++++++++++++++------------------- 1 file changed, 274 insertions(+), 274 deletions(-) diff --git a/source3/torture/test_ntlm_auth.py b/source3/torture/test_ntlm_auth.py index d17af9b..ae868f1 100755 --- a/source3/torture/test_ntlm_auth.py +++ b/source3/torture/test_ntlm_auth.py @@ -27,300 +27,300 @@ import sys from optparse import OptionParser class ReadChildError(Exception): - pass + pass class WriteChildError(Exception): - pass + pass def readLine(pipe): - """readLine(pipe) -> str - Read a line from the child's pipe, returns the string read. - Throws ReadChildError if the read fails. - """ - buf = os.read(pipe, 2047) - newline = buf.find('\n') - if newline == -1: - raise ReadChildError() - return buf[:newline] + """readLine(pipe) -> str + Read a line from the child's pipe, returns the string read. + Throws ReadChildError if the read fails. + """ + buf = os.read(pipe, 2047) + newline = buf.find('\n') + if newline == -1: + raise ReadChildError() + return buf[:newline] def writeLine(pipe, buf): - """writeLine(pipe, buf) -> nul - Write a line to the child's pipe. - Raises WriteChildError if the write fails. - """ - written = os.write(pipe, buf) - if written != len(buf): - raise WriteChildError() - os.write(pipe, "\n") + """writeLine(pipe, buf) -> nul + Write a line to the child's pipe. + Raises WriteChildError if the write fails. + """ + written = os.write(pipe, buf) + if written != len(buf): + raise WriteChildError() + os.write(pipe, "\n") def parseCommandLine(): - """parseCommandLine() -> (opts, ntlm_auth_path) - Parse the command line. - Return a tuple consisting of the options and the path to ntlm_auth. - """ - usage = "usage: %prog [options] path/to/ntlm_auth" - parser = OptionParser(usage) - - parser.set_defaults(client_username="foo") - parser.set_defaults(client_password="secret") - parser.set_defaults(client_domain="FOO") - parser.set_defaults(client_helper="ntlmssp-client-1") - - parser.set_defaults(server_username="foo") - parser.set_defaults(server_password="secret") - parser.set_defaults(server_domain="FOO") - parser.set_defaults(server_helper="squid-2.5-ntlmssp") - parser.set_defaults(config_file="/etc/samba/smb.conf") - - parser.add_option("--client-username", dest="client_username",\ - help="User name for the client. [default: foo]") - parser.add_option("--client-password", dest="client_password",\ - help="Password the client will send. [default: secret]") - parser.add_option("--client-domain", dest="client_domain",\ - help="Domain the client authenticates for. [default: FOO]") - parser.add_option("--client-helper", dest="client_helper",\ - help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") - - parser.add_option("--target-hostname", dest="target_hostname",\ - help="Target hostname for kerberos") - parser.add_option("--target-service", dest="target_service",\ - help="Target service for kerberos") - - - parser.add_option("--server-username", dest="server_username",\ - help="User name server uses for local auth. [default: foo]") - parser.add_option("--server-password", dest="server_password",\ - help="Password server uses for local auth. [default: secret]") - parser.add_option("--server-domain", dest="server_domain",\ - help="Domain server uses for local auth. [default: FOO]") - parser.add_option("--server-helper", dest="server_helper",\ - help="Helper mode for the ntlm_auth server. [default: squid-2.5-server]") - parser.add_option("--server-use-winbindd", dest="server_use_winbindd",\ - help="Use winbindd to check the password (rather than default username/pw)", action="store_true") - parser.add_option("--require-membership-of", dest="sid",\ - help="Require that the user is a member of this group to authenticate.") - - - parser.add_option("-s", "--configfile", dest="config_file",\ - help="Path to smb.conf file. [default:/etc/samba/smb.conf") - - (opts, args) = parser.parse_args() - if len(args) != 1: - parser.error("Invalid number of arguments.") - - if not os.access(args[0], os.X_OK): - parser.error("%s is not executable." % args[0]) - - return (opts, args[0]) + """parseCommandLine() -> (opts, ntlm_auth_path) + Parse the command line. + Return a tuple consisting of the options and the path to ntlm_auth. + """ + usage = "usage: %prog [options] path/to/ntlm_auth" + parser = OptionParser(usage) + + parser.set_defaults(client_username="foo") + parser.set_defaults(client_password="secret") + parser.set_defaults(client_domain="FOO") + parser.set_defaults(client_helper="ntlmssp-client-1") + + parser.set_defaults(server_username="foo") + parser.set_defaults(server_password="secret") + parser.set_defaults(server_domain="FOO") + parser.set_defaults(server_helper="squid-2.5-ntlmssp") + parser.set_defaults(config_file="/etc/samba/smb.conf") + + parser.add_option("--client-username", dest="client_username",\ + help="User name for the client. [default: foo]") + parser.add_option("--client-password", dest="client_password",\ + help="Password the client will send. [default: secret]") + parser.add_option("--client-domain", dest="client_domain",\ + help="Domain the client authenticates for. [default: FOO]") + parser.add_option("--client-helper", dest="client_helper",\ + help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") + + parser.add_option("--target-hostname", dest="target_hostname",\ + help="Target hostname for kerberos") + parser.add_option("--target-service", dest="target_service",\ + help="Target service for kerberos") + + + parser.add_option("--server-username", dest="server_username",\ + help="User name server uses for local auth. [default: foo]") + parser.add_option("--server-password", dest="server_password",\ + help="Password server uses for local auth. [default: secret]") + parser.add_option("--server-domain", dest="server_domain",\ + help="Domain server uses for local auth. [default: FOO]") + parser.add_option("--server-helper", dest="server_helper",\ + help="Helper mode for the ntlm_auth server. [default: squid-2.5-server]") + parser.add_option("--server-use-winbindd", dest="server_use_winbindd",\ + help="Use winbindd to check the password (rather than default username/pw)", action="store_true") + parser.add_option("--require-membership-of", dest="sid",\ + help="Require that the user is a member of this group to authenticate.") + + + parser.add_option("-s", "--configfile", dest="config_file",\ + help="Path to smb.conf file. [default:/etc/samba/smb.conf") + + (opts, args) = parser.parse_args() + if len(args) != 1: + parser.error("Invalid number of arguments.") + + if not os.access(args[0], os.X_OK): + parser.error("%s is not executable." % args[0]) + + return (opts, args[0]) def main(): - """main() -> int - Run the test. - Returns 0 if test succeeded, <>0 otherwise. - """ - (opts, ntlm_auth_path) = parseCommandLine() + """main() -> int + Run the test. + Returns 0 if test succeeded, <>0 otherwise. + """ + (opts, ntlm_auth_path) = parseCommandLine() - (client_in_r, client_in_w) = os.pipe() - (client_out_r, client_out_w) = os.pipe() - - client_pid = os.fork() - - if not client_pid: - # We're in the client child - os.close(0) - os.close(1) - - os.dup2(client_out_r, 0) - os.close(client_out_r) - os.close(client_out_w) - - os.dup2(client_in_w, 1) - os.close(client_in_r) - os.close(client_in_w) - - client_args = [] - client_args.append("--helper-protocol=%s" % opts.client_helper) - client_args.append("--username=%s" % opts.client_username) - client_args.append("--password=%s" % opts.client_password) - client_args.append("--domain=%s" % opts.client_domain) - client_args.append("--configfile=%s" % opts.config_file) - if opts.target_service: - client_args.append("--target-service=%s" % opts.target_service) - if opts.target_hostname: - client_args.append("--target-hostname=%s" % opts.target_hostname) - - os.execv(ntlm_auth_path, client_args) - - client_in = client_in_r - os.close(client_in_w) - - client_out = client_out_w - os.close(client_out_r) - - (server_in_r, server_in_w) = os.pipe() - (server_out_r, server_out_w) = os.pipe() - - server_pid = os.fork() - - if not server_pid: - # We're in the server child - os.close(0) - os.close(1) - - os.dup2(server_out_r, 0) - os.close(server_out_r) - os.close(server_out_w) - - os.dup2(server_in_w, 1) - os.close(server_in_r) - os.close(server_in_w) - - server_args = [] - server_args.append("--helper-protocol=%s" % opts.server_helper) - if not opts.server_use_winbindd: - server_args.append("--username=%s" % opts.server_username) - server_args.append("--password=%s" % opts.server_password) - server_args.append("--domain=%s" % opts.server_domain) - if opts.sid: - raise Exception("Server must be using winbindd for require-membership-of.") - else: - if opts.sid: - server_args.append("--require-membership-of=%s" % opts.sid) - - server_args.append("--configfile=%s" % opts.config_file) - - os.execv(ntlm_auth_path, server_args) - - server_in = server_in_r - os.close(server_in_w) - - server_out = server_out_w - os.close(server_out_r) - - if opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "squid-2.5-ntlmssp": - - # We're in the parent - writeLine(client_out, "YR") - buf = readLine(client_in) - - if buf.count("YR ", 0, 3) != 1: - sys.exit(1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(client_out, buf) - buf = readLine(client_in) - - if buf.count("AF ", 0, 3) != 1: - sys.exit(3) - - # Client sends 'AF ' but server expects 'KK ' - buf = buf.replace("AF", "KK", 1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF ", 0, 3) != 1: - sys.exit(4) - - - elif opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "gss-spnego": - # We're in the parent - writeLine(client_out, "YR") - buf = readLine(client_in) - - if buf.count("YR ", 0, 3) != 1: - sys.exit(1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(client_out, buf) - buf = readLine(client_in) + (client_in_r, client_in_w) = os.pipe() + (client_out_r, client_out_w) = os.pipe() - if buf.count("AF ", 0, 3) != 1: - sys.exit(3) + client_pid = os.fork() - # Client sends 'AF ' but server expects 'KK ' - buf = buf.replace("AF", "KK", 1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF * ", 0, 5) != 1: - sys.exit(4) + if not client_pid: + # We're in the client child + os.close(0) + os.close(1) + os.dup2(client_out_r, 0) + os.close(client_out_r) + os.close(client_out_w) - elif opts.client_helper == "gss-spnego-client" and opts.server_helper == "gss-spnego": - # We're in the parent - writeLine(server_out, "YR") - buf = readLine(server_in) - - while True: - if buf.count("AF ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: - sys.exit(1) - - writeLine(client_out, buf) - buf = readLine(client_in) - - if buf.count("AF", 0, 2) == 1: - break - - if buf.count("AF ", 0, 5) != 1 and buf.count("KK ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF * ", 0, 5) == 1: - break - - else: - sys.exit(5) + os.dup2(client_in_w, 1) + os.close(client_in_r) + os.close(client_in_w) - if opts.client_helper == "ntlmssp-client-1": - writeLine(client_out, "GK") - buf = readLine(client_in) + client_args = [] + client_args.append("--helper-protocol=%s" % opts.client_helper) + client_args.append("--username=%s" % opts.client_username) + client_args.append("--password=%s" % opts.client_password) + client_args.append("--domain=%s" % opts.client_domain) + client_args.append("--configfile=%s" % opts.config_file) + if opts.target_service: + client_args.append("--target-service=%s" % opts.target_service) + if opts.target_hostname: + client_args.append("--target-hostname=%s" % opts.target_hostname) - if buf.count("GK ", 0, 3) != 1: - sys.exit(4) - - writeLine(client_out, "GF") - buf = readLine(client_in) - - if buf.count("GF ", 0, 3) != 1: - sys.exit(4) - - if opts.server_helper == "squid-2.5-ntlmssp": - writeLine(server_out, "GK") - buf = readLine(server_in) - - if buf.count("GK ", 0, 3) != 1: - sys.exit(4) + os.execv(ntlm_auth_path, client_args) - writeLine(server_out, "GF") - buf = readLine(server_in) - - if buf.count("GF ", 0, 3) != 1: - sys.exit(4) - - os.close(server_in) - os.close(server_out) - os.close(client_in) - os.close(client_out) - os.waitpid(server_pid, 0) - os.waitpid(client_pid, 0) - sys.exit(0) + client_in = client_in_r + os.close(client_in_w) + + client_out = client_out_w + os.close(client_out_r) + + (server_in_r, server_in_w) = os.pipe() + (server_out_r, server_out_w) = os.pipe() + + server_pid = os.fork() + + if not server_pid: + # We're in the server child + os.close(0) + os.close(1) + + os.dup2(server_out_r, 0) + os.close(server_out_r) + os.close(server_out_w) + + os.dup2(server_in_w, 1) + os.close(server_in_r) + os.close(server_in_w) + + server_args = [] + server_args.append("--helper-protocol=%s" % opts.server_helper) + if not opts.server_use_winbindd: + server_args.append("--username=%s" % opts.server_username) + server_args.append("--password=%s" % opts.server_password) + server_args.append("--domain=%s" % opts.server_domain) + if opts.sid: + raise Exception("Server must be using winbindd for require-membership-of.") + else: + if opts.sid: + server_args.append("--require-membership-of=%s" % opts.sid) + + server_args.append("--configfile=%s" % opts.config_file) + + os.execv(ntlm_auth_path, server_args) + + server_in = server_in_r + os.close(server_in_w) + + server_out = server_out_w + os.close(server_out_r) + + if opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "squid-2.5-ntlmssp": + + # We're in the parent + writeLine(client_out, "YR") + buf = readLine(client_in) + + if buf.count("YR ", 0, 3) != 1: + sys.exit(1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(3) + + # Client sends 'AF ' but server expects 'KK ' + buf = buf.replace("AF", "KK", 1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(4) + + + elif opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "gss-spnego": + # We're in the parent + writeLine(client_out, "YR") + buf = readLine(client_in) + + if buf.count("YR ", 0, 3) != 1: + sys.exit(1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(3) + + # Client sends 'AF ' but server expects 'KK ' + buf = buf.replace("AF", "KK", 1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF * ", 0, 5) != 1: + sys.exit(4) + + + elif opts.client_helper == "gss-spnego-client" and opts.server_helper == "gss-spnego": + # We're in the parent + writeLine(server_out, "YR") + buf = readLine(server_in) + + while True: + if buf.count("AF ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: + sys.exit(1) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF", 0, 2) == 1: + break + + if buf.count("AF ", 0, 5) != 1 and buf.count("KK ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF * ", 0, 5) == 1: + break + + else: + sys.exit(5) + + if opts.client_helper == "ntlmssp-client-1": + writeLine(client_out, "GK") + buf = readLine(client_in) + + if buf.count("GK ", 0, 3) != 1: + sys.exit(4) + + writeLine(client_out, "GF") + buf = readLine(client_in) + + if buf.count("GF ", 0, 3) != 1: + sys.exit(4) + + if opts.server_helper == "squid-2.5-ntlmssp": + writeLine(server_out, "GK") + buf = readLine(server_in) + + if buf.count("GK ", 0, 3) != 1: + sys.exit(4) + + writeLine(server_out, "GF") + buf = readLine(server_in) + + if buf.count("GF ", 0, 3) != 1: + sys.exit(4) + + os.close(server_in) + os.close(server_out) + os.close(client_in) + os.close(client_out) + os.waitpid(server_pid, 0) + os.waitpid(client_pid, 0) + sys.exit(0) if __name__ == "__main__": - main() + main() -- 1.9.1 From bd5a8f48020bb8731e1bc7317e26d029c942f5b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 145/440] s3:torture/test_ntlm_auth.py: add --client-use-cached-creds option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 1289130ad2aeded63990bf1bde6f169505c62280) --- source3/torture/test_ntlm_auth.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/torture/test_ntlm_auth.py b/source3/torture/test_ntlm_auth.py index ae868f1..fffeb26 100755 --- a/source3/torture/test_ntlm_auth.py +++ b/source3/torture/test_ntlm_auth.py @@ -80,6 +80,8 @@ def parseCommandLine(): help="Domain the client authenticates for. [default: FOO]") parser.add_option("--client-helper", dest="client_helper",\ help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") + parser.add_option("--client-use-cached-creds", dest="client_use_cached_creds",\ + help="Use winbindd credentials cache (rather than default username/pw)", action="store_true") parser.add_option("--target-hostname", dest="target_hostname",\ help="Target hostname for kerberos") @@ -142,7 +144,10 @@ def main(): client_args = [] client_args.append("--helper-protocol=%s" % opts.client_helper) client_args.append("--username=%s" % opts.client_username) - client_args.append("--password=%s" % opts.client_password) + if opts.client_use_cached_creds: + client_args.append("--use-cached-creds") + else: + client_args.append("--password=%s" % opts.client_password) client_args.append("--domain=%s" % opts.client_domain) client_args.append("--configfile=%s" % opts.config_file) if opts.target_service: -- 1.9.1 From e4a40672d981c0681a4149c7849015de173a1b52 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 15:49:02 +0100 Subject: [PATCH 146/440] selftest/knownfail: s4-winbind doesn't support cached ntlm credentials BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- selftest/knownfail | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index c919a6a..80649c9 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -302,3 +302,5 @@ ^samba.blackbox.wbinfo\(s3member:local\).wbinfo -G check for sane mapping\(s3member:local\) ^samba.ntlm_auth.\(dc:local\).ntlm_auth against winbindd with failed require-membership-of ^samba.ntlm_auth.\(dc:local\).ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind with failed require-membership-of +^samba.ntlm_auth.\(dc:local\).wbinfo store cached credentials +^samba.ntlm_auth.\(dc:local\).ntlm_auth ccached credentials with NTLMSSP client and gss-spnego server -- 1.9.1 From 0b423de83a5cf2ed658ec1e6e74ff1f1f035b573 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 147/440] s3:tests/test_ntlm_auth_s3: test ntlmssp-client-1 with cached credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 9bd1ecffffd070333a22ef2449a179cee3effe5d) --- source3/script/tests/test_ntlm_auth_s3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/script/tests/test_ntlm_auth_s3.sh b/source3/script/tests/test_ntlm_auth_s3.sh index 655556b..bd4ffa1 100755 --- a/source3/script/tests/test_ntlm_auth_s3.sh +++ b/source3/script/tests/test_ntlm_auth_s3.sh @@ -94,6 +94,8 @@ testit "ntlm_auth with NTLMSSP client and gss-spnego server" $PYTHON $SRC3DIR/to testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH $ADDARGS --client-domain=fOo --server-domain=fOo --client-helper=gss-spnego-client --server-helper=gss-spnego || failed=`expr $failed + 1` testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd --client-helper=gss-spnego-client --server-helper=gss-spnego $ADDARGS || failed=`expr $failed + 1` +testit "wbinfo store cached credentials" $BINDIR/wbinfo --ccache-save=$DOMAIN/$USERNAME%$PASSWORD || failed=`expr $failed + 1` +testit "ntlm_auth ccached credentials with NTLMSSP client and gss-spnego server" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH $ADDARGS --client-username=$USERNAME --client-domain=$DOMAIN --client-use-cached-creds --client-helper=ntlmssp-client-1 --server-helper=gss-spnego --server-use-winbindd || failed=`expr $failed + 1` testit "ntlm_auth against winbindd with require-membership-of" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd $ADDARGS --require-membership-of=$SID || failed=`expr $failed + 1` testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind with require-membership-of" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd --client-helper=gss-spnego-client --server-helper=gss-spnego $ADDARGS --require-membership-of=$SID || failed=`expr $failed + 1` -- 1.9.1 From 6172a4b8e94e1706a398c1620ff6aad71e1c733f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 09:07:33 +0100 Subject: [PATCH 148/440] winbindd: pass an memory context to do_ntlm_auth_with_stored_pw() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should avoid using NULL. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 871e8a9fd029bbcbccb79bd17f9c6a2617b8be55) --- source3/winbindd/winbindd_ccache_access.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 7e300db..6ffdb0c 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -48,6 +48,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, const char *password, const DATA_BLOB initial_msg, const DATA_BLOB challenge_msg, + TALLOC_CTX *mem_ctx, DATA_BLOB *auth_msg, uint8_t session_key[16]) { @@ -55,7 +56,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, struct auth_generic_state *auth_generic_state = NULL; DATA_BLOB dummy_msg, reply, session_key_blob; - status = auth_generic_client_prepare(NULL, &auth_generic_state); + status = auth_generic_client_prepare(mem_ctx, &auth_generic_state); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", @@ -120,7 +121,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, /* Now we are ready to handle the server's actual response. */ status = gensec_update(auth_generic_state->gensec_security, - NULL, challenge_msg, &reply); + mem_ctx, challenge_msg, &reply); if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { DEBUG(1, ("We didn't get a response to the challenge! [%s]\n", nt_errstr(status))); @@ -273,7 +274,7 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) result = do_ntlm_auth_with_stored_pw( name_user, name_domain, entry->pass, - initial, challenge, &auth, + initial, challenge, talloc_tos(), &auth, state->response->data.ccache_ntlm_auth.session_key); if (!NT_STATUS_IS_OK(result)) { -- 1.9.1 From 07f158f401523a47e0d0fa26770be9f7e5aa219e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:45:33 +0100 Subject: [PATCH 149/440] s3:auth_generic: make use of the top level NTLMSSP client code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no reason to use gensec_ntlmssp3_client_ops, the WINBINDD_CCACHE_NTLMAUTH isn't available via gensec anyway. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0d66e2d34f656028eb3adb35acb653a45c041890) --- source3/libsmb/auth_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 806c785..82d634e 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -92,7 +92,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st backends[idx++] = &gensec_gse_krb5_security_ops; #endif - backends[idx++] = &gensec_ntlmssp3_client_ops; + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL); -- 1.9.1 From f344be5768ccb1477fb78802f69648695dedd1de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:47:40 +0100 Subject: [PATCH 150/440] s3:ntlmssp: remove unused libsmb/ntlmssp_wrap.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 52c03c07151a12e84fb4d34443864e59583c0db9) --- source3/include/auth_generic.h | 2 - source3/libsmb/ntlmssp_wrap.c | 135 ----------------------------------------- source3/wscript_build | 3 +- 3 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 source3/libsmb/ntlmssp_wrap.c diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index f88ffef..a1558ea 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -48,6 +48,4 @@ NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, const char **sasl_list); -extern const struct gensec_security_ops gensec_ntlmssp3_client_ops; - #endif /* _AUTH_GENERIC_ */ diff --git a/source3/libsmb/ntlmssp_wrap.c b/source3/libsmb/ntlmssp_wrap.c deleted file mode 100644 index 46f68ae..0000000 --- a/source3/libsmb/ntlmssp_wrap.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - NLTMSSP wrappers - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2003,2011 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/ntlmssp_private.h" -#include "auth_generic.h" -#include "auth/gensec/gensec.h" -#include "auth/gensec/gensec_internal.h" -#include "auth/credentials/credentials.h" -#include "librpc/rpc/dcerpc.h" -#include "lib/param/param.h" - -static NTSTATUS gensec_ntlmssp3_client_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - struct tevent_context *ev, - const DATA_BLOB request, - DATA_BLOB *reply) -{ - NTSTATUS status; - struct gensec_ntlmssp_context *gensec_ntlmssp = - talloc_get_type_abort(gensec_security->private_data, - struct gensec_ntlmssp_context); - - status = ntlmssp_update(gensec_ntlmssp->ntlmssp_state, request, reply); - if (NT_STATUS_IS_OK(status) || - NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - talloc_steal(out_mem_ctx, reply->data); - } - - return status; -} - -static NTSTATUS gensec_ntlmssp3_client_start(struct gensec_security *gensec_security) -{ - NTSTATUS nt_status; - struct gensec_ntlmssp_context *gensec_ntlmssp; - const char *user, *domain; - const char *password; - - nt_status = gensec_ntlmssp_start(gensec_security); - NT_STATUS_NOT_OK_RETURN(nt_status); - - gensec_ntlmssp = - talloc_get_type_abort(gensec_security->private_data, - struct gensec_ntlmssp_context); - - nt_status = ntlmssp_client_start(gensec_ntlmssp, - lp_netbios_name(), lp_workgroup(), - lp_client_ntlmv2_auth(), &gensec_ntlmssp->ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - cli_credentials_get_ntlm_username_domain(gensec_security->credentials, gensec_ntlmssp, &user, &domain); - if (!user || !domain) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = ntlmssp_set_username(gensec_ntlmssp->ntlmssp_state, user); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = ntlmssp_set_domain(gensec_ntlmssp->ntlmssp_state, domain); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - password = cli_credentials_get_password(gensec_security->credentials); - if (!password) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = ntlmssp_set_password(gensec_ntlmssp->ntlmssp_state, password); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - - return NT_STATUS_OK; -} - -static const char *gensec_ntlmssp3_client_oids[] = { - GENSEC_OID_NTLMSSP, - NULL -}; - -const struct gensec_security_ops gensec_ntlmssp3_client_ops = { - .name = "ntlmssp3_client", - .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ - .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = gensec_ntlmssp3_client_oids, - .client_start = gensec_ntlmssp3_client_start, - .magic = gensec_ntlmssp_magic, - .update = gensec_ntlmssp3_client_update, - .sig_size = gensec_ntlmssp_sig_size, - .sign_packet = gensec_ntlmssp_sign_packet, - .check_packet = gensec_ntlmssp_check_packet, - .seal_packet = gensec_ntlmssp_seal_packet, - .unseal_packet = gensec_ntlmssp_unseal_packet, - .wrap = gensec_ntlmssp_wrap, - .unwrap = gensec_ntlmssp_unwrap, - .session_key = gensec_ntlmssp_session_key, - .have_feature = gensec_ntlmssp_have_feature, - .enabled = true, - .priority = GENSEC_NTLMSSP -}; diff --git a/source3/wscript_build b/source3/wscript_build index 27f3783..3dea5e3 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -359,8 +359,7 @@ bld.SAMBA3_LIBRARY('smbd_shim', private_library=True) bld.SAMBA3_SUBSYSTEM('LIBNTLMSSP', - source='''libsmb/ntlmssp.c - libsmb/ntlmssp_wrap.c''', + source='''libsmb/ntlmssp.c''', deps='NDR_NTLMSSP NTLMSSP_COMMON wbclient') bld.SAMBA3_SUBSYSTEM('auth_generic', -- 1.9.1 From 28184fa8945f8878579e555bb2b06da1ebf7f9ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Nov 2015 21:41:23 +0100 Subject: [PATCH 151/440] auth/ntlmssp: provide a "ntlmssp_resume_ccache" backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These can be used to implement the winbindd side of the WINBINDD_CCACHE_NTLMAUTH call. It can properly get the initial NEGOTIATE messages injected if available. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit b3d4523ff7810279dc4d3201a09a868545d4d253) --- auth/ntlmssp/ntlmssp.c | 29 +++++++++++ auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 111 +++++++++++++++++++++++++++++++++++++++++ auth/ntlmssp/ntlmssp_private.h | 5 ++ 4 files changed, 146 insertions(+) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 0b7667c..091fdab 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -48,6 +48,10 @@ static const struct ntlmssp_callbacks { .command = NTLMSSP_INITIAL, .sync_fn = ntlmssp_client_initial, },{ + .role = NTLMSSP_CLIENT, + .command = NTLMSSP_NEGOTIATE, + .sync_fn = gensec_ntlmssp_resume_ccache, + },{ .role = NTLMSSP_SERVER, .command = NTLMSSP_NEGOTIATE, .sync_fn = gensec_ntlmssp_server_negotiate, @@ -82,6 +86,15 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_security *gensec_securi if (!input.length) { switch (gensec_ntlmssp->ntlmssp_state->role) { case NTLMSSP_CLIENT: + if (gensec_ntlmssp->ntlmssp_state->resume_ccache) { + /* + * make sure gensec_ntlmssp_resume_ccache() + * will be called + */ + ntlmssp_command = NTLMSSP_NEGOTIATE; + break; + } + ntlmssp_command = NTLMSSP_INITIAL; break; case NTLMSSP_SERVER: @@ -194,6 +207,15 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .priority = GENSEC_NTLMSSP }; +static const struct gensec_security_ops gensec_ntlmssp_resume_ccache_ops = { + .name = "ntlmssp_resume_ccache", + .client_start = gensec_ntlmssp_resume_ccache_start, + .update = gensec_ntlmssp_update, + .session_key = gensec_ntlmssp_session_key, + .have_feature = gensec_ntlmssp_have_feature, + .enabled = true, + .priority = GENSEC_NTLMSSP +}; _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) { @@ -206,6 +228,13 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) return ret; } + ret = gensec_register(&gensec_ntlmssp_resume_ccache_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_ntlmssp_resume_ccache_ops.name)); + return ret; + } + return ret; } diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index b357e42..4d2ddf9 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -62,6 +62,7 @@ struct ntlmssp_state bool unicode; bool use_ntlmv2; bool use_ccache; + bool resume_ccache; bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ bool allow_lm_key; /* The LM_KEY code is not very secure... */ diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 1ac0996..df29aa2 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -114,6 +114,98 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, return NT_STATUS_MORE_PROCESSING_REQUIRED; } +NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; + uint32_t neg_flags = 0; + uint32_t ntlmssp_command; + NTSTATUS status; + bool ok; + + *out = data_blob_null; + + if (in.length == 0) { + /* + * This is compat code for older callers + * which were missing the "initial_blob" + */ + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + /* parse the NTLMSSP packet */ + + if (in.length > UINT16_MAX) { + DEBUG(1, ("%s: reject large request of length %u\n", + __func__, (unsigned int)in.length)); + return NT_STATUS_INVALID_PARAMETER; + } + + ok = msrpc_parse(ntlmssp_state, &in, "Cdd", + "NTLMSSP", + &ntlmssp_command, + &neg_flags); + if (!ok) { + DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n", + __func__, (unsigned int)in.length)); + dump_data(2, in.data, in.length); + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command != NTLMSSP_NEGOTIATE) { + DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n", + __func__, (unsigned int)in.length)); + dump_data(2, in.data, in.length); + return NT_STATUS_INVALID_PARAMETER; + } + + ntlmssp_state->neg_flags = neg_flags; + DEBUG(3, ("Imported Negotiate flags:\n")); + debug_ntlmssp_flags(neg_flags); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_state->unicode = true; + } else { + ntlmssp_state->unicode = false; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + gensec_security->want_features |= GENSEC_FEATURE_SIGN; + + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + gensec_security->want_features |= GENSEC_FEATURE_SEAL; + + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + + if (DEBUGLEVEL >= 10) { + struct NEGOTIATE_MESSAGE *negotiate = talloc( + ntlmssp_state, struct NEGOTIATE_MESSAGE); + if (negotiate != NULL) { + status = ntlmssp_pull_NEGOTIATE_MESSAGE( + &in, negotiate, negotiate); + if (NT_STATUS_IS_OK(status)) { + NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, + negotiate); + } + TALLOC_FREE(negotiate); + } + } + + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + /** * Next state function for the Challenge Packet. Generate an auth packet. * @@ -476,3 +568,22 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) return NT_STATUS_OK; } + +NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = NULL; + NTSTATUS status; + + status = gensec_ntlmssp_client_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + gensec_ntlmssp->ntlmssp_state->use_ccache = false; + gensec_ntlmssp->ntlmssp_state->resume_ccache = true; + gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; + + return NT_STATUS_OK; +} diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index 778d638..ea5703f 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -88,6 +88,10 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out) ; +NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out); + /** * Next state function for the Challenge Packet. Generate an auth packet. * @@ -101,6 +105,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) ; NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security); +NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security); /* The following definitions come from auth/ntlmssp/gensec_ntlmssp_server.c */ -- 1.9.1 From 782c826b1b5fe93972254566b682ad81a6ab5fe4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 13:42:30 +0100 Subject: [PATCH 152/440] auth/gensec: add GENSEC_FEATURE_NTLM_CCACHE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0a93cad337578a7ba61f12726c9a15ecf869db7b) --- auth/gensec/gensec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index fae44df..f09e501 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -61,6 +61,7 @@ struct gensec_target { #define GENSEC_FEATURE_SIGN_PKT_HEADER 0x00000040 #define GENSEC_FEATURE_NEW_SPNEGO 0x00000080 #define GENSEC_FEATURE_UNIX_TOKEN 0x00000100 +#define GENSEC_FEATURE_NTLM_CCACHE 0x00000200 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL -- 1.9.1 From 0de45d65c0affce03947e8bbdbab29d08a6502fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 15:35:40 +0100 Subject: [PATCH 153/440] auth/ntlmssp: implement GENSEC_FEATURE_NTLM_CCACHE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This can used in order to use the WINBINDD_CCACHE_NTLMAUTH code of winbindd to do NTLMSSP authentication with a cached password. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit b133f66e0da5ed05bbe81098e52c744bac4b48ac) --- auth/ntlmssp/ntlmssp_client.c | 94 +++++++++++++++++++++++++++++++++++++++++-- auth/ntlmssp/wscript_build | 2 +- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index df29aa2..0823ebe 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -34,6 +34,7 @@ struct auth_session_info; #include "auth/ntlmssp/ntlmssp_private.h" #include "../librpc/gen_ndr/ndr_ntlmssp.h" #include "../auth/ntlmssp/ntlmssp_ndr.h" +#include "../nsswitch/libwbclient/wbclient.h" /********************************************************************* Client side NTLMSSP @@ -240,6 +241,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, NTSTATUS nt_status; int flags = 0; const char *user = NULL, *domain = NULL, *workstation = NULL; + bool is_anonymous = false; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -345,6 +347,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } + is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials); cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx, &user, &domain); @@ -365,6 +368,87 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } + if (is_anonymous) { + /* + * don't use the ccache for anonymous auth + */ + ntlmssp_state->use_ccache = false; + } + if (ntlmssp_state->use_ccache) { + struct samr_Password *nt_hash = NULL; + + /* + * If we have a password given we don't + * use the ccache + */ + nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials, + mem_ctx); + if (nt_hash != NULL) { + ZERO_STRUCTP(nt_hash); + TALLOC_FREE(nt_hash); + ntlmssp_state->use_ccache = false; + } + } + + if (ntlmssp_state->use_ccache) { + struct wbcCredentialCacheParams params; + struct wbcCredentialCacheInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + struct wbcNamedBlob auth_blobs[1]; + const struct wbcBlob *wbc_auth_blob = NULL; + const struct wbcBlob *wbc_session_key = NULL; + wbcErr wbc_status; + int i; + + params.account_name = user; + params.domain_name = domain; + params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; + + auth_blobs[0].name = "challenge_blob"; + auth_blobs[0].flags = 0; + auth_blobs[0].blob.data = in.data; + auth_blobs[0].blob.length = in.length; + params.num_blobs = ARRAY_SIZE(auth_blobs); + params.blobs = auth_blobs; + + wbc_status = wbcCredentialCache(¶ms, &info, &error); + wbcFreeMemory(error); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_WRONG_CREDENTIAL_HANDLE; + } + + for (i=0; inum_blobs; i++) { + if (strequal(info->blobs[i].name, "auth_blob")) { + wbc_auth_blob = &info->blobs[i].blob; + } + if (strequal(info->blobs[i].name, "session_key")) { + wbc_session_key = &info->blobs[i].blob; + } + } + if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) { + wbcFreeMemory(info); + return NT_STATUS_WRONG_CREDENTIAL_HANDLE; + } + + session_key = data_blob_talloc(mem_ctx, + wbc_session_key->data, + wbc_session_key->length); + if (session_key.length != wbc_session_key->length) { + wbcFreeMemory(info); + return NT_STATUS_NO_MEMORY; + } + *out = data_blob_talloc(mem_ctx, + wbc_auth_blob->data, + wbc_auth_blob->length); + if (out->length != wbc_auth_blob->length) { + wbcFreeMemory(info); + return NT_STATUS_NO_MEMORY; + } + + wbcFreeMemory(info); + goto done; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { flags |= CLI_CRED_NTLM2; } @@ -434,9 +518,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key)); } - DEBUG(3, ("NTLMSSP: Set final flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - /* this generates the actual auth packet */ nt_status = msrpc_gen(mem_ctx, out, auth_gen_string, @@ -454,9 +535,13 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return nt_status; } +done: ntlmssp_state->session_key = session_key; talloc_steal(ntlmssp_state, session_key.data); + DEBUG(3, ("NTLMSSP: Set final flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + talloc_steal(out_mem_ctx, out->data); ntlmssp_state->expected_state = NTLMSSP_DONE; @@ -565,6 +650,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) { + ntlmssp_state->use_ccache = true; + } return NT_STATUS_OK; } diff --git a/auth/ntlmssp/wscript_build b/auth/ntlmssp/wscript_build index 8725a80..e28d4eb 100644 --- a/auth/ntlmssp/wscript_build +++ b/auth/ntlmssp/wscript_build @@ -7,7 +7,7 @@ bld.SAMBA_SUBSYSTEM('NTLMSSP_COMMON', ntlmssp_server.c ntlmssp_sign.c gensec_ntlmssp_server.c''', - deps='samba-util NDR_NTLMSSP MSRPC_PARSE NTLM_CHECK samba-credentials') + deps='samba-util NDR_NTLMSSP MSRPC_PARSE NTLM_CHECK samba-credentials wbclient') bld.SAMBA_MODULE('gensec_ntlmssp', source='''''', -- 1.9.1 From 141ceed810f9562b012734d2c9f173ef7c2336fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Dec 2015 15:42:51 +0100 Subject: [PATCH 154/440] s3:auth_generic: add "ntlmssp_resume_ccache" backend in auth_generic_client_prepare() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used by winbindd in order to correctly implement WINBINDD_CCACHE_NTLMAUTH. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8bcde9ec625547df42915e9138d696deeabdb62d) --- source3/libsmb/auth_generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 82d634e..2e45cdb 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -78,7 +78,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st } backends = talloc_zero_array(gensec_settings, - const struct gensec_security_ops *, 6); + const struct gensec_security_ops *, 7); if (backends == NULL) { TALLOC_FREE(ans); return NT_STATUS_NO_MEMORY; @@ -93,6 +93,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st #endif backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); + backends[idx++] = gensec_security_by_name(NULL, "ntlmssp_resume_ccache"); backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL); -- 1.9.1 From 6da1d5e9482a5a9a0ab038e2ce1aff0a2762d471 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:46:52 +0100 Subject: [PATCH 155/440] winbindd: make use of ntlmssp_resume_ccache backend for WINBINDD_CCACHE_NTLMAUTH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 716e78f3b294210130f3cf253f496391534819b0) --- source3/winbindd/winbindd_ccache_access.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 6ffdb0c..838711e 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -54,7 +54,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, { NTSTATUS status; struct auth_generic_state *auth_generic_state = NULL; - DATA_BLOB dummy_msg, reply, session_key_blob; + DATA_BLOB reply, session_key_blob; status = auth_generic_client_prepare(mem_ctx, &auth_generic_state); @@ -88,29 +88,26 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, goto done; } - gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY); + if (initial_msg.length == 0) { + gensec_want_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SESSION_KEY); + } - status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP); + status = auth_generic_client_start_by_name(auth_generic_state, + "ntlmssp_resume_ccache"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not start NTLMSSP mech: %s\n", + DEBUG(1, ("Could not start NTLMSSP resume mech: %s\n", nt_errstr(status))); goto done; } - /* We need to get our protocol handler into the right state. So first - we ask it to generate the initial message. Actually the client has already - sent its own initial message, so we're going to drop this one on the floor. - The client might have sent a different message, for example with different - negotiation options, but as far as I can tell this won't hurt us. (Unless - the client sent a different username or domain, in which case that's their - problem for telling us the wrong username or domain.) - Since we have a copy of the initial message that the client sent, we could - resolve any discrepancies if we had to. - */ - dummy_msg = data_blob_null; + /* + * We inject the inital NEGOTIATE message our caller used + * in order to get the state machine into the correct possition. + */ reply = data_blob_null; status = gensec_update(auth_generic_state->gensec_security, - talloc_tos(), dummy_msg, &reply); + talloc_tos(), initial_msg, &reply); data_blob_free(&reply); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { -- 1.9.1 From bb6dfe2ed4ab79f5a207025a3af54c9ca1e05b61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 10:54:56 +0100 Subject: [PATCH 156/440] s3:ntlm_auth: also use gensec for "ntlmssp-client-1" and "gss-spnego-client" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implicitly fixes bug #10708. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10708 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 279d58c1e68c9466a76e4a67d2cfea22e8719d31) --- source3/utils/ntlm_auth.c | 789 +++++++--------------------------------------- 1 file changed, 110 insertions(+), 679 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index ddc54b2..d37aeb5 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -29,7 +29,6 @@ #include "popt_common.h" #include "utils/ntlm_auth.h" #include "../libcli/auth/libcli_auth.h" -#include "../libcli/auth/spnego.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/gensec/gensec.h" #include "auth/gensec/gensec_internal.h" @@ -38,7 +37,6 @@ #include "smb_krb5.h" #include "lib/util/tiniparser.h" #include "../lib/crypto/arcfour.h" -#include "libads/kerberos_proto.h" #include "nsswitch/winbind_client.h" #include "librpc/gen_ndr/krb5pac.h" #include "../lib/util/asn1.h" @@ -100,6 +98,10 @@ typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, struct ntlm_auth_state *state, char *buf, int length, void **private2); +static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, + struct loadparm_context *lp_ctx, + char *buf, int length, void **private1); + static void manage_squid_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, @@ -254,6 +256,10 @@ static void gensec_want_feature_list(struct gensec_security *state, char* featur DEBUG(10, ("want GENSEC_FEATURE_SEAL\n")); gensec_want_feature(state, GENSEC_FEATURE_SEAL); } + if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { + DEBUG(10, ("want GENSEC_FEATURE_NTLM_CCACHE\n")); + gensec_want_feature(state, GENSEC_FEATURE_NTLM_CCACHE); + } } static char winbind_separator(void) @@ -953,57 +959,75 @@ static NTSTATUS local_pw_check(struct auth4_context *auth4_context, return nt_status; } -static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state) +static NTSTATUS ntlm_auth_prepare_gensec_client(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct gensec_security **gensec_security_out) { - NTSTATUS status; - if ( (opt_username == NULL) || (opt_domain == NULL) ) { - status = NT_STATUS_UNSUCCESSFUL; - DEBUG(1, ("Need username and domain for NTLMSSP\n")); - return NT_STATUS_INVALID_PARAMETER; - } + struct gensec_security *gensec_security = NULL; + NTSTATUS nt_status; + TALLOC_CTX *tmp_ctx; + const struct gensec_security_ops **backends = NULL; + struct gensec_settings *gensec_settings = NULL; + size_t idx = 0; - status = ntlmssp_client_start(NULL, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), - client_ntlmssp_state); + tmp_ctx = talloc_new(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not start NTLMSSP client: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx); + if (gensec_settings == NULL) { + DEBUG(10, ("lpcfg_gensec_settings failed\n")); + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; } - status = ntlmssp_set_username(*client_ntlmssp_state, opt_username); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set username: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + backends = talloc_zero_array(gensec_settings, + const struct gensec_security_ops *, 4); + if (backends == NULL) { + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; } + gensec_settings->backends = backends; + + gensec_init(); + + /* These need to be in priority order, krb5 before NTLMSSP */ +#if defined(HAVE_KRB5) + backends[idx++] = &gensec_gse_krb5_security_ops; +#endif - status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain); + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); + + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set domain: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + nt_status = gensec_client_start(NULL, &gensec_security, + gensec_settings); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; } - if (opt_password) { - status = ntlmssp_set_password(*client_ntlmssp_state, opt_password); + talloc_unlink(tmp_ctx, gensec_settings); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set password: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + if (opt_target_service != NULL) { + nt_status = gensec_set_target_service(gensec_security, + opt_target_service); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; + } + } + + if (opt_target_hostname != NULL) { + nt_status = gensec_set_target_hostname(gensec_security, + opt_target_hostname); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; } } + *gensec_security_out = talloc_steal(mem_ctx, gensec_security); + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } @@ -1140,249 +1164,13 @@ static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/******************************************************************* - Used by firefox to drive NTLM auth to IIS servers. -*******************************************************************/ - -static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_msg, - DATA_BLOB *reply) -{ - struct winbindd_request wb_request; - struct winbindd_response wb_response; - int ctrl = 0; - NSS_STATUS result; - - /* get winbindd to do the ntlmssp step on our behalf */ - ZERO_STRUCT(wb_request); - ZERO_STRUCT(wb_response); - - /* - * This is tricky here. If we set krb5_auth in pam_winbind.conf - * creds for users in trusted domain will be stored the winbindd - * child of the trusted domain. If we ask the primary domain for - * ntlm_ccache_auth, it will fail. So, we have to ask the trusted - * domain's child for ccache_ntlm_auth. that is to say, we have to - * set WBFLAG_PAM_CONTACT_TRUSTDOM in request.flags. - */ - ctrl = get_pam_winbind_config(); - - if (ctrl & WINBIND_KRB5_AUTH) { - wb_request.flags |= WBFLAG_PAM_CONTACT_TRUSTDOM; - } - - fstr_sprintf(wb_request.data.ccache_ntlm_auth.user, - "%s%c%s", opt_domain, winbind_separator(), opt_username); - wb_request.data.ccache_ntlm_auth.uid = geteuid(); - wb_request.data.ccache_ntlm_auth.initial_blob_len = initial_msg.length; - wb_request.data.ccache_ntlm_auth.challenge_blob_len = challenge_msg.length; - wb_request.extra_len = initial_msg.length + challenge_msg.length; - - if (wb_request.extra_len > 0) { - wb_request.extra_data.data = SMB_MALLOC_ARRAY(char, wb_request.extra_len); - if (wb_request.extra_data.data == NULL) { - return NT_STATUS_NO_MEMORY; - } - - memcpy(wb_request.extra_data.data, initial_msg.data, initial_msg.length); - memcpy(wb_request.extra_data.data + initial_msg.length, - challenge_msg.data, challenge_msg.length); - } - - result = winbindd_request_response(NULL, WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response); - SAFE_FREE(wb_request.extra_data.data); - - if (result != NSS_STATUS_SUCCESS) { - winbindd_free_response(&wb_response); - return NT_STATUS_UNSUCCESSFUL; - } - - if (reply) { - *reply = data_blob(wb_response.extra_data.data, - wb_response.data.ccache_ntlm_auth.auth_blob_len); - if (wb_response.data.ccache_ntlm_auth.auth_blob_len > 0 && - reply->data == NULL) { - winbindd_free_response(&wb_response); - return NT_STATUS_NO_MEMORY; - } - } - - winbindd_free_response(&wb_response); - return NT_STATUS_OK; -} - static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, char *buf, int length, void **private2) { - DATA_BLOB request, reply; - NTSTATUS nt_status; - - if (!opt_username || !*opt_username) { - x_fprintf(x_stderr, "username must be specified!\n\n"); - exit(1); - } - - if (strlen(buf) < 2) { - DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); - return; - } - - if (strlen(buf) > 3) { - if(strncmp(buf, "SF ", 3) == 0) { - DEBUG(10, ("Looking for flags to negotiate\n")); - talloc_free(state->want_feature_list); - state->want_feature_list = talloc_strdup(state->mem_ctx, - buf+3); - x_fprintf(x_stdout, "OK\n"); - return; - } - request = base64_decode_data_blob(buf + 3); - } else { - request = data_blob_null; - } - - if (strncmp(buf, "PW ", 3) == 0) { - /* We asked for a password and obviously got it :-) */ - - opt_password = SMB_STRNDUP((const char *)request.data, - request.length); - - if (opt_password == NULL) { - DEBUG(1, ("Out of memory\n")); - x_fprintf(x_stdout, "BH Out of memory\n"); - data_blob_free(&request); - return; - } - - x_fprintf(x_stdout, "OK\n"); - data_blob_free(&request); - return; - } - - if (!state->ntlmssp_state && use_cached_creds) { - /* check whether cached credentials are usable. */ - DATA_BLOB empty_blob = data_blob_null; - - nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); - if (!NT_STATUS_IS_OK(nt_status)) { - /* failed to use cached creds */ - use_cached_creds = False; - } - } - - if (opt_password == NULL && !use_cached_creds) { - /* Request a password from the calling process. After - sending it, the calling process should retry asking for the - negotiate. */ - - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return; - } - - if (strncmp(buf, "YR", 2) == 0) { - TALLOC_FREE(state->ntlmssp_state); - state->cli_state = CLIENT_INITIAL; - } else if (strncmp(buf, "TT", 2) == 0) { - /* No special preprocessing required */ - } else if (strncmp(buf, "GF", 2) == 0) { - DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - - if(state->cli_state == CLIENT_FINISHED) { - x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); - } - else { - x_fprintf(x_stdout, "BH\n"); - } - - data_blob_free(&request); - return; - } else if (strncmp(buf, "GK", 2) == 0 ) { - DEBUG(10, ("Requested session key\n")); - - if(state->cli_state == CLIENT_FINISHED) { - char *key64 = base64_encode_data_blob(state->mem_ctx, - state->session_key); - x_fprintf(x_stdout, "GK %s\n", key64?key64:""); - TALLOC_FREE(key64); - } - else { - x_fprintf(x_stdout, "BH\n"); - } - - data_blob_free(&request); - return; - } else { - DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); - return; - } - - if (!state->ntlmssp_state) { - nt_status = ntlm_auth_start_ntlmssp_client( - &state->ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); - return; - } - ntlmssp_want_feature_list(state->ntlmssp_state, - state->want_feature_list); - state->initial_message = data_blob_null; - } - - DEBUG(10, ("got NTLMSSP packet:\n")); - dump_data(10, request.data, request.length); - - if (use_cached_creds && !opt_password && - (state->cli_state == CLIENT_RESPONSE)) { - nt_status = do_ccache_ntlm_auth(state->initial_message, request, - &reply); - } else { - nt_status = ntlmssp_update(state->ntlmssp_state, request, - &reply); - } - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(state->mem_ctx, - reply); - if (state->cli_state == CLIENT_INITIAL) { - x_fprintf(x_stdout, "YR %s\n", reply_base64); - state->initial_message = reply; - state->cli_state = CLIENT_RESPONSE; - } else { - x_fprintf(x_stdout, "KK %s\n", reply_base64); - data_blob_free(&reply); - } - TALLOC_FREE(reply_base64); - DEBUG(10, ("NTLMSSP challenge\n")); - } else if (NT_STATUS_IS_OK(nt_status)) { - char *reply_base64 = base64_encode_data_blob(talloc_tos(), - reply); - x_fprintf(x_stdout, "AF %s\n", reply_base64); - TALLOC_FREE(reply_base64); - - if(state->have_session_key) - data_blob_free(&state->session_key); - - state->session_key = data_blob( - state->ntlmssp_state->session_key.data, - state->ntlmssp_state->session_key.length); - state->neg_flags = state->ntlmssp_state->neg_flags; - state->have_session_key = true; - - DEBUG(10, ("NTLMSSP OK!\n")); - state->cli_state = CLIENT_FINISHED; - TALLOC_FREE(state->ntlmssp_state); - } else { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); - DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - state->cli_state = CLIENT_ERROR; - TALLOC_FREE(state->ntlmssp_state); - } - - data_blob_free(&request); + manage_gensec_request(stdio_helper_mode, lp_ctx, buf, length, &state->gensec_private_1); + return; } static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, @@ -1501,11 +1289,42 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, if (!(state->gensec_state)) { switch (stdio_helper_mode) { case GSS_SPNEGO_CLIENT: + /* + * cached credentials are only supported by + * NTLMSSP_CLIENT_1 for now. + */ + use_cached_creds = false; + /* fall through */ case NTLMSSP_CLIENT_1: /* setup the client side */ - nt_status = gensec_client_start(NULL, &state->gensec_state, - lpcfg_gensec_settings(NULL, lp_ctx)); + if (state->set_password != NULL) { + use_cached_creds = false; + } + + if (use_cached_creds) { + struct wbcCredentialCacheParams params; + struct wbcCredentialCacheInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + wbcErr wbc_status; + + params.account_name = opt_username; + params.domain_name = opt_domain; + params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; + params.num_blobs = 0; + params.blobs = NULL; + + wbc_status = wbcCredentialCache(¶ms, &info, + &error); + wbcFreeMemory(error); + if (!WBC_ERROR_IS_OK(wbc_status)) { + use_cached_creds = false; + } + wbcFreeMemory(info); + } + + nt_status = ntlm_auth_prepare_gensec_client(state, lp_ctx, + &state->gensec_state); if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH GENSEC mech failed to start: %s\n", nt_errstr(nt_status)); talloc_free(mem_ctx); @@ -1520,7 +1339,10 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, if (opt_domain) { cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED); } - if (state->set_password) { + if (use_cached_creds) { + gensec_want_feature(state->gensec_state, + GENSEC_FEATURE_NTLM_CCACHE); + } else if (state->set_password) { cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED); } else { cli_credentials_set_password_callback(creds, get_password); @@ -1615,12 +1437,17 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, return; } - if (stdio_helper_mode == SQUID_2_5_NTLMSSP && strncmp(buf, "GF", 2) == 0) { + if (strncmp(buf, "GF", 2) == 0) { uint32_t neg_flags; + DEBUG(10, ("Requested negotiated NTLMSSP feature flags\n")); + neg_flags = gensec_ntlmssp_neg_flags(state->gensec_state); + if (neg_flags == 0) { + x_fprintf(x_stdout, "BH\n"); + return; + } - DEBUG(10, ("Requested negotiated feature flags\n")); x_fprintf(x_stdout, "GF 0x%08x\n", neg_flags); return; } @@ -1724,408 +1551,12 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } -static struct ntlmssp_state *client_ntlmssp_state = NULL; - -static bool manage_client_ntlmssp_init(struct spnego_data spnego) -{ - NTSTATUS status; - DATA_BLOB null_blob = data_blob_null; - DATA_BLOB to_server; - char *to_server_base64; - const char *my_mechs[] = {OID_NTLMSSP, NULL}; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n")); - - if (client_ntlmssp_state != NULL) { - DEBUG(1, ("Request for initial SPNEGO request where " - "we already have a state\n")); - return False; - } - - if (!client_ntlmssp_state) { - if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); - return False; - } - } - - - if (opt_password == NULL) { - - /* Request a password from the calling process. After - sending it, the calling process should retry with - the negTokenInit. */ - - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return True; - } - - spnego.type = SPNEGO_NEG_TOKEN_INIT; - spnego.negTokenInit.mechTypes = my_mechs; - spnego.negTokenInit.reqFlags = data_blob_null; - spnego.negTokenInit.reqFlagsPadding = 0; - spnego.negTokenInit.mechListMIC = null_blob; - - status = ntlmssp_update(client_ntlmssp_state, null_blob, - &spnego.negTokenInit.mechToken); - - if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || - NT_STATUS_IS_OK(status)) ) { - DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n", - nt_errstr(status))); - TALLOC_FREE(client_ntlmssp_state); - return False; - } - - spnego_write_data(ctx, &to_server, &spnego); - data_blob_free(&spnego.negTokenInit.mechToken); - - to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); - data_blob_free(&to_server); - x_fprintf(x_stdout, "KK %s\n", to_server_base64); - TALLOC_FREE(to_server_base64); - return True; -} - -static void manage_client_ntlmssp_targ(struct spnego_data spnego) -{ - NTSTATUS status; - DATA_BLOB null_blob = data_blob_null; - DATA_BLOB request; - DATA_BLOB to_server; - char *to_server_base64; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n")); - - if (client_ntlmssp_state == NULL) { - DEBUG(1, ("Got NTLMSSP tArg without a client state\n")); - x_fprintf(x_stdout, "BH Got NTLMSSP tArg without a client state\n"); - return; - } - - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - x_fprintf(x_stdout, "NA\n"); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) { - x_fprintf(x_stdout, "AF\n"); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - status = ntlmssp_update(client_ntlmssp_state, - spnego.negTokenTarg.responseToken, - &request); - - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED or OK from " - "ntlmssp_client_update, got: %s\n", - nt_errstr(status))); - x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from " - "ntlmssp_client_update\n"); - data_blob_free(&request); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - spnego.type = SPNEGO_NEG_TOKEN_TARG; - spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego.negTokenTarg.supportedMech = (const char *)OID_NTLMSSP; - spnego.negTokenTarg.responseToken = request; - spnego.negTokenTarg.mechListMIC = null_blob; - - spnego_write_data(ctx, &to_server, &spnego); - data_blob_free(&request); - - to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); - data_blob_free(&to_server); - x_fprintf(x_stdout, "KK %s\n", to_server_base64); - TALLOC_FREE(to_server_base64); - return; -} - -#ifdef HAVE_KRB5 - -static bool manage_client_krb5_init(struct spnego_data spnego) -{ - char *principal; - DATA_BLOB tkt, tkt_wrapped, to_server; - DATA_BLOB session_key_krb5 = data_blob_null; - struct spnego_data reply; - char *reply_base64; - int retval; - - const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL}; - ssize_t len; - TALLOC_CTX *ctx = talloc_tos(); - - principal = spnego.negTokenInit.targetPrincipal; - - /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us - */ - if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) { - principal = NULL; - } - - if (principal == NULL && - opt_target_service && opt_target_hostname && !is_ipaddress(opt_target_hostname)) { - DEBUG(3,("manage_client_krb5_init: using target " - "hostname not SPNEGO principal\n")); - - principal = kerberos_get_principal_from_service_hostname(talloc_tos(), - opt_target_service, - opt_target_hostname, - lp_realm()); - - if (!principal) { - return false; - } - - DEBUG(3,("manage_client_krb5_init: guessed " - "server principal=%s\n", - principal ? principal : "")); - } - - if (principal == NULL) { - DEBUG(3,("manage_client_krb5_init: could not guess server principal\n")); - return false; - } - - retval = cli_krb5_get_ticket(ctx, principal, 0, - &tkt, &session_key_krb5, - 0, NULL, NULL, NULL); - if (retval) { - char *user = NULL; - - /* Let's try to first get the TGT, for that we need a - password. */ - - if (opt_password == NULL) { - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return True; - } - - user = talloc_asprintf(talloc_tos(), "%s@%s", opt_username, opt_domain); - if (!user) { - return false; - } - - if ((retval = kerberos_kinit_password(user, opt_password, 0, NULL))) { - DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval))); - return False; - } - - retval = cli_krb5_get_ticket(ctx, principal, 0, - &tkt, &session_key_krb5, - 0, NULL, NULL, NULL); - if (retval) { - DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval))); - return False; - } - - } - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ); - - data_blob_free(&session_key_krb5); - - ZERO_STRUCT(reply); - - reply.type = SPNEGO_NEG_TOKEN_INIT; - reply.negTokenInit.mechTypes = my_mechs; - reply.negTokenInit.reqFlags = data_blob_null; - reply.negTokenInit.reqFlagsPadding = 0; - reply.negTokenInit.mechToken = tkt_wrapped; - reply.negTokenInit.mechListMIC = data_blob_null; - - len = spnego_write_data(ctx, &to_server, &reply); - data_blob_free(&tkt); - - if (len == -1) { - DEBUG(1, ("Could not write SPNEGO data blob\n")); - return False; - } - - reply_base64 = base64_encode_data_blob(talloc_tos(), to_server); - x_fprintf(x_stdout, "KK %s *\n", reply_base64); - - TALLOC_FREE(reply_base64); - data_blob_free(&to_server); - DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n")); - return True; -} - -static void manage_client_krb5_targ(struct spnego_data spnego) -{ - switch (spnego.negTokenTarg.negResult) { - case SPNEGO_ACCEPT_INCOMPLETE: - DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n")); - x_fprintf(x_stdout, "BH Got a Kerberos negTokenTarg with " - "ACCEPT_INCOMPLETE\n"); - break; - case SPNEGO_ACCEPT_COMPLETED: - DEBUG(10, ("Accept completed\n")); - x_fprintf(x_stdout, "AF\n"); - break; - case SPNEGO_REJECT: - DEBUG(10, ("Rejected\n")); - x_fprintf(x_stdout, "NA\n"); - break; - default: - DEBUG(1, ("Got an invalid negTokenTarg\n")); - x_fprintf(x_stdout, "AF\n"); - } -} - -#endif - static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, char *buf, int length, void **private2) { - DATA_BLOB request; - struct spnego_data spnego; - ssize_t len; - TALLOC_CTX *ctx = talloc_tos(); - - if (!opt_username || !*opt_username) { - x_fprintf(x_stderr, "username must be specified!\n\n"); - exit(1); - } - - if (strlen(buf) <= 3) { - DEBUG(1, ("SPNEGO query [%s] too short\n", buf)); - x_fprintf(x_stdout, "BH SPNEGO query too short\n"); - return; - } - - request = base64_decode_data_blob(buf+3); - - if (strncmp(buf, "PW ", 3) == 0) { - - /* We asked for a password and obviously got it :-) */ - - opt_password = SMB_STRNDUP((const char *)request.data, request.length); - - if (opt_password == NULL) { - DEBUG(1, ("Out of memory\n")); - x_fprintf(x_stdout, "BH Out of memory\n"); - data_blob_free(&request); - return; - } - - x_fprintf(x_stdout, "OK\n"); - data_blob_free(&request); - return; - } - - if ( (strncmp(buf, "TT ", 3) != 0) && - (strncmp(buf, "AF ", 3) != 0) && - (strncmp(buf, "NA ", 3) != 0) ) { - DEBUG(1, ("SPNEGO request [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH SPNEGO request invalid\n"); - data_blob_free(&request); - return; - } - - /* So we got a server challenge to generate a SPNEGO - client-to-server request... */ - - len = spnego_read_data(ctx, request, &spnego); - data_blob_free(&request); - - if (len == -1) { - DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf)); - x_fprintf(x_stdout, "BH Could not read SPNEGO data\n"); - return; - } - - if (spnego.type == SPNEGO_NEG_TOKEN_INIT) { - - /* The server offers a list of mechanisms */ - - const char *const *mechType = spnego.negTokenInit.mechTypes; - - while (*mechType != NULL) { - -#ifdef HAVE_KRB5 - if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) || - (strcmp(*mechType, OID_KERBEROS5) == 0) ) { - if (manage_client_krb5_init(spnego)) - goto out; - } -#endif - - if (strcmp(*mechType, OID_NTLMSSP) == 0) { - if (manage_client_ntlmssp_init(spnego)) - goto out; - } - - mechType++; - } - - DEBUG(1, ("Server offered no compatible mechanism\n")); - x_fprintf(x_stdout, "BH Server offered no compatible mechanism\n"); - return; - } - - if (spnego.type == SPNEGO_NEG_TOKEN_TARG) { - - if (spnego.negTokenTarg.supportedMech == NULL) { - /* On accept/reject Windows does not send the - mechanism anymore. Handle that here and - shut down the mechanisms. */ - - switch (spnego.negTokenTarg.negResult) { - case SPNEGO_ACCEPT_COMPLETED: - x_fprintf(x_stdout, "AF\n"); - break; - case SPNEGO_REJECT: - x_fprintf(x_stdout, "NA\n"); - break; - default: - DEBUG(1, ("Got a negTokenTarg with no mech and an " - "unknown negResult: %d\n", - spnego.negTokenTarg.negResult)); - x_fprintf(x_stdout, "BH Got a negTokenTarg with" - " no mech and an unknown " - "negResult\n"); - } - - TALLOC_FREE(client_ntlmssp_state); - goto out; - } - - if (strcmp(spnego.negTokenTarg.supportedMech, - OID_NTLMSSP) == 0) { - manage_client_ntlmssp_targ(spnego); - goto out; - } - -#if HAVE_KRB5 - if (strcmp(spnego.negTokenTarg.supportedMech, - OID_KERBEROS5_OLD) == 0) { - manage_client_krb5_targ(spnego); - goto out; - } -#endif - - } - - DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf)); - x_fprintf(x_stdout, "BH Got an SPNEGO token I could not handle\n"); - return; - - out: - spnego_free_data(&spnego); + manage_gensec_request(stdio_helper_mode, lp_ctx, buf, length, &state->gensec_private_1); return; } -- 1.9.1 From 2b8b8f66717ec0b5ce620087ad8844a4fb056ca5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:16:02 +0100 Subject: [PATCH 157/440] auth/ntlmssp: split out a debug_ntlmssp_flags_raw() that's more complete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit e63442a1c27c475e373048893d9cf04859dd1792) --- auth/ntlmssp/ntlmssp_util.c | 77 +++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 96793ab..dee909a 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -25,6 +25,41 @@ #include "../auth/ntlmssp/ntlmssp.h" #include "../auth/ntlmssp/ntlmssp_private.h" +static void debug_ntlmssp_flags_raw(int level, uint32_t flags) +{ +#define _PRINT_FLAG_LINE(v) do { \ + if (flags & (v)) { \ + DEBUGADD(level, (" " #v "\n")); \ + } \ +} while (0) + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_UNICODE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM); + _PRINT_FLAG_LINE(NTLMSSP_REQUEST_TARGET); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SIGN); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SEAL); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_DATAGRAM); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_LM_KEY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NETWARE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NTLM); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NT_ONLY); + _PRINT_FLAG_LINE(NTLMSSP_ANONYMOUS); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_ALWAYS_SIGN); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_DOMAIN); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SERVER); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SHARE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_IDENTIFY); + _PRINT_FLAG_LINE(NTLMSSP_REQUEST_NON_NT_SESSION_KEY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_TARGET_INFO); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_VERSION); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_128); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_KEY_EXCH); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_56); +} + /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -32,47 +67,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) { DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) - DEBUGADD(4, (" NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_VERSION) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_VERSION\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_56) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n")); + debug_ntlmssp_flags_raw(4, neg_flags); } void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, -- 1.9.1 From 274ebf7f470533ad068f969ad1c9a068ef3555d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 158/440] auth/ntlmssp: NTLMSSP_NEGOTIATE_VERSION is not a negotiated option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NTLMSSP_NEGOTIATE_VERSION only indicates the existence of the version information in the packet. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 30d626024c7e8f275d64f835632717b0130be4b2) --- auth/ntlmssp/ntlmssp_util.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index dee909a..96a9991 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -119,10 +119,6 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION; - } - if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } -- 1.9.1 From 7e2144d92a62a993a3607222236d6847842bc727 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 159/440] auth/ntlmssp: define all client neg_flags in gensec_ntlmssp_client_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit afba38dbf5c954abbcfc485a81f510255b69a426) --- auth/ntlmssp/ntlmssp_client.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 0823ebe..114f8b0 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -71,16 +71,6 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, workstation = ""; } - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } else { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, out, "CddAA", @@ -604,6 +594,12 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } else { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; } @@ -631,6 +627,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_ntlmv2 = false; } + if (ntlmssp_state->use_ntlmv2) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* * We need to set this to allow a later SetPassword -- 1.9.1 From 73638f373b4f53c24336642ed55cc89809e19c94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Dec 2015 13:59:42 +0100 Subject: [PATCH 160/440] auth/ntlmssp: set NTLMSSP_ANONYMOUS for anonymous authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a modern Windows client. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit efd4986794889f1315dbd011b94b8673d785053a) --- auth/ntlmssp/ntlmssp_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 114f8b0..afd5a00 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -359,6 +359,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if (is_anonymous) { + ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS; /* * don't use the ccache for anonymous auth */ -- 1.9.1 From 548bbfc0979ca1f0f98cdf217c1291ec9760f903 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 161/440] auth/ntlmssp: don't send domain and workstation in the NEGOTIATE_MESSAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't set NTLMSSP_NEGOTIATE_OEM_{DOMAIN,WORKSTATION}_SUPPLIED anyway. This matches modern Windows clients. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 4fca8eaaae23955e704dc9c45d373fe78bf88201) --- auth/ntlmssp/ntlmssp_client.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index afd5a00..61ca886 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -58,28 +58,16 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; - const char *domain = ntlmssp_state->client.netbios_domain; - const char *workstation = ntlmssp_state->client.netbios_name; NTSTATUS status; - /* These don't really matter in the initial packet, so don't panic if they are not set */ - if (!domain) { - domain = ""; - } - - if (!workstation) { - workstation = ""; - } - /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, out, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, - domain, - workstation); - + "", /* domain */ + ""); /* workstation */ if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("ntlmssp_client_initial: failed to generate " "ntlmssp negotiate packet\n")); -- 1.9.1 From aa3784042d36bce0cba2697976efa69aa31edec8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:05:17 +0100 Subject: [PATCH 162/440] auth/ntlmssp: add ntlmssp_version_blob() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit a61ab398ccc1036edce677e00569fd7f58b70995) --- auth/ntlmssp/ntlmssp_private.h | 1 + auth/ntlmssp/ntlmssp_util.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index ea5703f..29eca35 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -61,6 +61,7 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, void debug_ntlmssp_flags(uint32_t neg_flags); void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, uint32_t neg_flags, bool allow_lm); +const DATA_BLOB ntlmssp_version_blob(void); /* The following definitions come from auth/ntlmssp_server.c */ diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 96a9991..bfe27f9 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -133,3 +133,38 @@ bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob) return false; } } + +const DATA_BLOB ntlmssp_version_blob(void) +{ + /* + * This is a simplified version of + * + * enum ndr_err_code err; + * struct ntlmssp_VERSION vers; + * + * ZERO_STRUCT(vers); + * vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6; + * vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1; + * vers.ProductBuild = 0; + * vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; + * + * err = ndr_push_struct_blob(&version_blob, + * ntlmssp_state, + * &vers, + * (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION); + * + * if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + * data_blob_free(&struct_blob); + * return NT_STATUS_NO_MEMORY; + * } + */ + static const uint8_t version_buffer[8] = { + NTLMSSP_WINDOWS_MAJOR_VERSION_6, + NTLMSSP_WINDOWS_MINOR_VERSION_1, + 0x00, 0x00, /* product build */ + 0x00, 0x00, 0x00, /* reserved */ + NTLMSSP_REVISION_W2K3 + }; + + return data_blob_const(version_buffer, ARRAY_SIZE(version_buffer)); +} -- 1.9.1 From fcb3678a89b09ab050101fd997c3e550f57bde59 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 163/440] auth/ntlmssp: let the client always include NTLMSSP_NEGOTIATE_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a modern Windows client. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 4a1809cb14dcb03e9ba386af5b90650400377875) --- auth/ntlmssp/ntlmssp_client.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 61ca886..523a842 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -59,15 +59,17 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; NTSTATUS status; + const DATA_BLOB version_blob = ntlmssp_version_blob(); /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, - out, "CddAA", + out, "CddAAb", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, - "", /* domain */ - ""); /* workstation */ + "", /* domain */ + "", /* workstation */ + version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("ntlmssp_client_initial: failed to generate " "ntlmssp negotiate packet\n")); @@ -220,6 +222,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, int flags = 0; const char *user = NULL, *domain = NULL, *workstation = NULL; bool is_anonymous = false; + const DATA_BLOB version_blob = ntlmssp_version_blob(); TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -253,7 +256,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string = "CdUdbdd"; chal_parse_string_short = "CdUdb"; } - auth_gen_string = "CdBBUUUBd"; + auth_gen_string = "CdBBUUUBdb"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; @@ -262,7 +265,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string_short = "CdAdb"; } - auth_gen_string = "CdBBAAABd"; + auth_gen_string = "CdBBAAABdb"; } if (!msrpc_parse(mem_ctx, @@ -508,7 +511,8 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, user, workstation, encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags); + ntlmssp_state->neg_flags, + version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; @@ -581,6 +585,7 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_VERSION | NTLMSSP_REQUEST_TARGET; if (ntlmssp_state->unicode) { -- 1.9.1 From 2fce75ae3183149bfe2871a462510ff98386a145 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:07:23 +0100 Subject: [PATCH 164/440] auth/ntlmssp: use ntlmssp_version_blob() in the server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already set NTLMSSP_NEGOTIATE_VERSION in gensec_ntlmssp_server_start(), so it's always set in chal_flags. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8af6b8d2eb6b873620131b4b5b570ec24985d86a) --- auth/ntlmssp/ntlmssp_server.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 2f3f0bb..94692cd 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -168,29 +168,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security { /* Marshal the packet in the right format, be it unicode or ASCII */ const char *gen_string; - DATA_BLOB version_blob = data_blob_null; - - if (chal_flags & NTLMSSP_NEGOTIATE_VERSION) { - enum ndr_err_code err; - struct ntlmssp_VERSION vers; - - /* "What Windows returns" as a version number. */ - ZERO_STRUCT(vers); - vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6; - vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1; - vers.ProductBuild = 0; - vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; - - err = ndr_push_struct_blob(&version_blob, - ntlmssp_state, - &vers, - (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION); - - if (!NDR_ERR_CODE_IS_SUCCESS(err)) { - data_blob_free(&struct_blob); - return NT_STATUS_NO_MEMORY; - } - } + const DATA_BLOB version_blob = ntlmssp_version_blob(); if (ntlmssp_state->unicode) { gen_string = "CdUdbddBb"; @@ -209,13 +187,10 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&version_blob); data_blob_free(&struct_blob); return status; } - data_blob_free(&version_blob); - if (DEBUGLEVEL >= 10) { struct CHALLENGE_MESSAGE *challenge = talloc( ntlmssp_state, struct CHALLENGE_MESSAGE); -- 1.9.1 From 3305a2911ea4b0f253869d56532eb2848d3221d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:06:56 +0100 Subject: [PATCH 165/440] security.idl: add LSAP_TOKEN_INFO_INTEGRITY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is used in [MS-KILE] and implicit in [MS-NLMP]. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 1f88812316144b06b11eb3dc90a6081cb57783da) --- librpc/idl/security.idl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index bf7c955..88d8936 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -649,6 +649,15 @@ interface security 0); /* + * See [MS-KILE] 2.2.5 LSAP_TOKEN_INFO_INTEGRITY + */ + typedef [public,gensize,flag(NDR_PAHEX)] struct { + uint32 Flags; + uint32 TokenIL; + uint8 MachineId[32]; + } LSAP_TOKEN_INFO_INTEGRITY; + + /* * See [MS-KILE] 2.2.6 Supported Encryption Types Bit Flags */ typedef [public,bitmap32bit] bitmap { -- 1.9.1 From 183b1eb914c0d153a09485abfc210c13915e589b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:07:57 +0100 Subject: [PATCH 166/440] ntlmssp.idl: MsAvRestrictions is MsvAvSingleHost now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit ab54e0fd7040e7717fe979b54fb4dfa16813524f) --- librpc/idl/ntlmssp.idl | 19 ++++++++++--------- source4/torture/ndr/ntlmssp.c | 13 +++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index ed2f02c..fcc5356 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -1,5 +1,7 @@ #include "idl_types.h" +import "security.idl"; + /* ntlmssp interface definition */ @@ -126,20 +128,19 @@ interface ntlmssp MsvAvDnsTreeName = 5, MsvAvFlags = 6, MsvAvTimestamp = 7, - MsAvRestrictions = 8, + MsvAvSingleHost = 8, MsvAvTargetName = 9, MsvChannelBindings = 10 } ntlmssp_AvId; - /* [MS-NLMP] 2.2.2.2 Restriction_Encoding */ + /* [MS-NLMP] 2.2.2.2 SingleHostData */ - typedef struct { - uint32 Size; + typedef [flag(NDR_PAHEX)] struct { + [value(8+ndr_size_LSAP_TOKEN_INFO_INTEGRITY(&r->token_info, 0)+r->remaining.length)] uint32 Size; [value(0)] uint32 Z4; - boolean32 IntegrityLevel; - uint32 SubjectIntegrityLevel; - uint8 MachineId[32]; - } Restriction_Encoding; + LSAP_TOKEN_INFO_INTEGRITY token_info; + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } ntlmssp_SingleHostData; typedef [bitmap32bit] bitmap { NTLMSSP_AVFLAG_CONSTRAINTED_ACCOUNT = 0x00000001, @@ -156,7 +157,7 @@ interface ntlmssp [case(MsvAvDnsTreeName)] [flag(ndr_ntlmssp_negotiated_string_flags(NTLMSSP_NEGOTIATE_UNICODE))] string AvDnsTreeName; [case(MsvAvFlags)] ntlmssp_AvFlags AvFlags; [case(MsvAvTimestamp)] NTTIME AvTimestamp; - [case(MsAvRestrictions)] Restriction_Encoding AvRestrictions; + [case(MsvAvSingleHost)] ntlmssp_SingleHostData AvSingleHost; [case(MsvAvTargetName)] [flag(ndr_ntlmssp_negotiated_string_flags(NTLMSSP_NEGOTIATE_UNICODE))] string AvTargetName; [case(MsvChannelBindings)] uint8 ChannelBindings[16]; [default] [flag(NDR_REMAINING)] DATA_BLOB blob; diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index ae56192..aeac26f 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -225,13 +225,14 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, AvPairs.pair[3].AvLen, 46, "AvLen"); torture_assert_str_equal(tctx, AvPairs.pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "Value.AvDnsComputerName"); - torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsAvRestrictions, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsvAvSingleHost, "AvId"); torture_assert_int_equal(tctx, AvPairs.pair[4].AvLen, 48, "AvLen"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Size, 48, "Value.AvRestrictions.Size"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Z4, 0, "Value.AvRestrictions.Z4"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.IntegrityLevel, 0, "Value.AvRestrictions.IntegrityLevel"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.SubjectIntegrityLevel, 0x00003000, "Value.AvRestrictions.SubjectIntegrityLevel"); - torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.MachineId, MachineId, 32, "Value.AvRestrictions.MachineId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.Size, 48, "Value.AvSingleHost.Size"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.Z4, 0, "Value.AvSingleHost.Z4"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.Flags, 0, "Value.AvSingleHost.token_info.Flags"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.TokenIL, 0x00003000, "Value.AvSingleHost.token_info.TokenIL"); + torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.MachineId, MachineId, 32, "Value.AvSingleHost.token_info.MachineId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.remaining.length, 0, "Value.AvSingleHost.remaining.length"); torture_assert_int_equal(tctx, AvPairs.pair[5].AvId, MsvChannelBindings, "AvId"); torture_assert_int_equal(tctx, AvPairs.pair[5].AvLen, 16, "AvLen"); -- 1.9.1 From a3b879edd00fec9803f8e96caebe47263f1f41cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 15:38:02 +0100 Subject: [PATCH 167/440] ntlmssp.idl: make AV_PAIR_LIST public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit f4ff3510164748977de056bb8cdbbd22e5fedb3c) --- librpc/idl/ntlmssp.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index fcc5356..2151275 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -171,7 +171,7 @@ interface ntlmssp [subcontext(0),subcontext_size(AvLen),switch_is(AvId)] ntlmssp_AvValue Value; } AV_PAIR; - typedef [gensize,nopush,nopull,flag(NDR_NOALIGN)] struct { + typedef [public,gensize,nopush,nopull,flag(NDR_NOALIGN)] struct { uint32 count; AV_PAIR pair[count]; } AV_PAIR_LIST; -- 1.9.1 From 50ca63aff7c7ba9a5ee597262d591c8e6cbf1095 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 15:40:29 +0100 Subject: [PATCH 168/440] librpc/ndr: add ndr_ntlmssp_find_av() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit c1e2a1f0a75605a8792b615a41392fc018198a10) --- librpc/ndr/ndr_ntlmssp.c | 16 ++++++++++++++++ librpc/ndr/ndr_ntlmssp.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/librpc/ndr/ndr_ntlmssp.c b/librpc/ndr/ndr_ntlmssp.c index d024da5..7027ac0 100644 --- a/librpc/ndr/ndr_ntlmssp.c +++ b/librpc/ndr/ndr_ntlmssp.c @@ -176,4 +176,20 @@ _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, } } +_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, + enum ntlmssp_AvId AvId) +{ + struct AV_PAIR *res = NULL; + uint32_t i = 0; + + for (i = 0; i < av_list->count; i++) { + if (av_list->pair[i].AvId != AvId) { + continue; + } + res = discard_const_p(struct AV_PAIR, &av_list->pair[i]); + break; + } + + return res; +} diff --git a/librpc/ndr/ndr_ntlmssp.h b/librpc/ndr/ndr_ntlmssp.h index e07ff15..5c979ff 100644 --- a/librpc/ndr/ndr_ntlmssp.h +++ b/librpc/ndr/ndr_ntlmssp.h @@ -31,3 +31,5 @@ _PUBLIC_ void ndr_print_ntlmssp_lm_response(TALLOC_CTX *mem_ctx, bool ntlmv2); _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r); +_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, + enum ntlmssp_AvId AvId); -- 1.9.1 From 88c08dac0541c79bb628013a62069933022fa61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 19 Aug 2009 00:40:12 +0200 Subject: [PATCH 169/440] auth/ntlmssp: use ndr_push_AV_PAIR_LIST in gensec_ntlmssp_server_negotiate(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Günther Deschner BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit f6b9e1feab8d435b1e44fef81e867c01ed01db95) --- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_server.c | 43 +++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 4d2ddf9..f1af224 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -82,6 +82,7 @@ struct ntlmssp_state const char *netbios_domain; const char *dns_name; const char *dns_domain; + struct AV_PAIR_LIST av_pair_list; } server; DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 94692cd..4bb2a64 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -150,16 +150,39 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security cryptkey, 8); /* This creates the 'blob' of names that appears at the end of the packet */ - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) - { - status = msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa", - MsvAvNbDomainName, target_name, - MsvAvNbComputerName, ntlmssp_state->server.netbios_name, - MsvAvDnsDomainName, ntlmssp_state->server.dns_domain, - MsvAvDnsComputerName, ntlmssp_state->server.dns_name, - MsvAvEOL, ""); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { + enum ndr_err_code err; + struct AV_PAIR *pairs = NULL; + uint32_t count = 5; + + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count); + if (pairs == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pairs[0].AvId = MsvAvNbDomainName; + pairs[0].Value.AvNbDomainName = target_name; + + pairs[1].AvId = MsvAvNbComputerName; + pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name; + + pairs[2].AvId = MsvAvDnsDomainName; + pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain; + + pairs[3].AvId = MsvAvDnsComputerName; + pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; + + pairs[4].AvId = MsvAvEOL; + + ntlmssp_state->server.av_pair_list.count = count; + ntlmssp_state->server.av_pair_list.pair = pairs; + + err = ndr_push_struct_blob(&struct_blob, + ntlmssp_state, + &ntlmssp_state->server.av_pair_list, + (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return NT_STATUS_NO_MEMORY; } } else { struct_blob = data_blob_null; -- 1.9.1 From 8fc70c25d47e5f13ab02fd8a883a41ff9a97c8c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 170/440] auth/gensec: add GENSEC_FEATURE_LDAP_STYLE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used for LDAP connections and may trigger backend specific behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 069aee42c2f12ed5feb23c19dc0a4771d913619a) --- auth/gensec/gensec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index f09e501..e8bd7b1 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -62,6 +62,7 @@ struct gensec_target { #define GENSEC_FEATURE_NEW_SPNEGO 0x00000080 #define GENSEC_FEATURE_UNIX_TOKEN 0x00000100 #define GENSEC_FEATURE_NTLM_CCACHE 0x00000200 +#define GENSEC_FEATURE_LDAP_STYLE 0x00000400 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL -- 1.9.1 From 64af6c377b3e5b997469d07703f82b71b2fe8ec4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 171/440] auth/ntlmssp: implement GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to handle NTLMSSP_NEGOTIATE_SIGN as NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE is requested. This works arround a bug in Windows, which allow signed only messages using NTLMSSP and LDAP. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit f3dbe19e14eaf7a462f14485c6a9138a7348db2e) --- auth/ntlmssp/gensec_ntlmssp_server.c | 9 +++++++++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_client.c | 9 +++++++++ auth/ntlmssp/ntlmssp_sign.c | 16 ++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 69c56fb..997738a 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -152,6 +152,15 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + + if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + */ + ntlmssp_state->force_wrap_seal = true; + } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index f1af224..c63c23d 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -94,6 +94,8 @@ struct ntlmssp_state uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + bool force_wrap_seal; + union ntlmssp_crypt_state *crypt; }; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 523a842..652c8f1 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -639,6 +639,15 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + + if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + */ + ntlmssp_state->force_wrap_seal = true; + } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index c0be914..743ba2b 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -558,6 +558,22 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) return NT_STATUS_NO_MEMORY; } + if (ntlmssp_state->force_wrap_seal && + (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) + { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + * + * The negotiation of flags (and authentication) + * is completed when ntlmssp_sign_init() is called + * so we can safely pretent NTLMSSP_NEGOTIATE_SEAL + * was negotiated. + */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; -- 1.9.1 From 625e15fd26de15950051dcfa903ec80e0b3a366c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 172/440] auth/ntlmssp: add more compat for GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want also work against old Samba servers which didn't had GENSEC_FEATURE_LDAP_STYLE we negotiate SEAL too. We may remove this in a few years. As all servers should support GENSEC_FEATURE_LDAP_STYLE by then. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 122a5f6b58e6cead061a7ee64033ccc1940742ed) --- auth/ntlmssp/ntlmssp_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 652c8f1..fe9e5d4 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -647,6 +647,14 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * is requested. */ ntlmssp_state->force_wrap_seal = true; + /* + * We want also work against old Samba servers + * which didn't had GENSEC_FEATURE_LDAP_STYLE + * we negotiate SEAL too. We may remove this + * in a few years. As all servers should have + * GENSEC_FEATURE_LDAP_STYLE by then. + */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { -- 1.9.1 From c22403ac62702487d9d3178b3c2ddfc1fae4d394 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 12:58:51 +0100 Subject: [PATCH 173/440] auth/ntlmssp: remove ntlmssp_unwrap() fallback for LDAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is now handled by GENSEC_FEATURE_LDAP_STYLE. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 59301830e27bf537d04808d2ac37d6cf9ef56713) --- auth/ntlmssp/ntlmssp_sign.c | 49 +++++---------------------------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index 743ba2b..2f8c6de 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -479,57 +479,18 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, &sig); } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { - NTSTATUS status; - struct ntlmssp_crypt_direction save_direction; - if (in->length < NTLMSSP_SIG_SIZE) { return NT_STATUS_INVALID_PARAMETER; } sig.data = in->data; sig.length = NTLMSSP_SIG_SIZE; - *out = data_blob_talloc(out_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - save_direction = ntlmssp_state->crypt->ntlm2.receiving; - } else { - save_direction = ntlmssp_state->crypt->ntlm; - } - - status = ntlmssp_check_packet(ntlmssp_state, - out->data, out->length, - out->data, out->length, - &sig); - if (!NT_STATUS_IS_OK(status)) { - NTSTATUS check_status = status; - /* - * The Windows LDAP libraries seems to have a bug - * and always use sealing even if only signing was - * negotiated. So we need to fallback. - */ - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - ntlmssp_state->crypt->ntlm2.receiving = save_direction; - } else { - ntlmssp_state->crypt->ntlm = save_direction; - } - status = ntlmssp_unseal_packet(ntlmssp_state, - out->data, - out->length, - out->data, - out->length, - &sig); - if (NT_STATUS_IS_OK(status)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } else { - status = check_status; - } - } + *out = data_blob_talloc(out_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("NTLMSSP packet check for unwrap failed due to invalid signature\n")); - } - return status; + return ntlmssp_check_packet(ntlmssp_state, + out->data, out->length, + out->data, out->length, + &sig); } else { *out = data_blob_talloc(out_mem_ctx, in->data, in->length); if (!out->data) { -- 1.9.1 From 923f98a6e71ecf1e1c8834fa80249a236b9071c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 174/440] s4:libcli/ldap: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit d04663b8b075a69141fe2f45d0906b528d99ab85) --- source4/libcli/ldap/ldap_bind.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index daa7662..2e1cd5c 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -318,6 +318,13 @@ try_logon_again: * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); + /* + * This is an indication for the NTLMSSP backend to + * also encrypt when only GENSEC_FEATURE_SIGN is requested + * in gensec_[un]wrap(). + */ + gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE); + if (conn->host) { status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From e6970264b1550632e02e8c0a68b679e5d16eeeed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 13:10:58 +0100 Subject: [PATCH 175/440] s4:libcli/ldap: fix retry authentication after a bad password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to start with an empty input buffer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit d9d0d2d5a2667ea8984772b678272650a8719c21) --- source4/libcli/ldap/ldap_bind.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2e1cd5c..7af3823 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -291,6 +291,8 @@ try_logon_again: gensec session. The logon_retries counter ensures we don't loop forever. */ + data_blob_free(&input); + TALLOC_FREE(conn->gensec); status = gensec_client_start(conn, &conn->gensec, lpcfg_gensec_settings(conn, lp_ctx)); @@ -441,8 +443,6 @@ try_logon_again: new credentials, or get a new ticket if using kerberos */ - talloc_free(conn->gensec); - conn->gensec = NULL; goto try_logon_again; } } -- 1.9.1 From b16305ea89cee95487ef6a1837f2d30b693b1c9b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 09:54:08 +0100 Subject: [PATCH 176/440] s4:selftest: we don't need to run ldap test with --option=socket:testnonblock=true MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LDAP client library uses tstream and that handles non blocking sockets natively. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (similar to commit 5cf8546674a4f49618bdade1567fac00d72db454) --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c20fc67..c9c956c 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -43,7 +43,7 @@ smbclient4 = binpath('smbclient4') bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP -for options in ['-U"$USERNAME%$PASSWORD" --option=socket:testnonblock=true', '-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: +for options in ['-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: plantestsuite("samba4.ldb.ldap with options %s(dc)" % options, "dc", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side -- 1.9.1 From 37018379200d747746e43d2d18d2635e64b83522 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:46:22 +0100 Subject: [PATCH 177/440] s4:selftest: simplify the loops over samba4.ldb.ldap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (similar to commit c431543fb989938898e33e1ffdb80cb97e4a3bb2) --- source4/selftest/tests.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c9c956c..deda384 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -43,8 +43,11 @@ smbclient4 = binpath('smbclient4') bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP -for options in ['-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: - plantestsuite("samba4.ldb.ldap with options %s(dc)" % options, "dc", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) +for auth_type in ['', '-k no', '-k yes']: + for auth_level in ['', '--sign', '--encrypt']: + creds = '-U"$USERNAME%$PASSWORD"' + options = creds + ' ' + auth_type + ' ' + auth_level + plantestsuite("samba4.ldb.ldap with options %r(dc)" % options, "dc", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side try: -- 1.9.1 From 6f10c4565bce96051e219378dee7c6929a14cd78 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 178/440] s4:ldap_server: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0ebe929810e922e7cf7742a1f3e4ad222006377f) --- source4/ldap_server/ldap_bind.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 69a6b61..fb7a6ed 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -181,6 +181,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); gensec_want_feature(conn->gensec, GENSEC_FEATURE_ASYNC_REPLIES); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE); status = gensec_start_mech_by_sasl_name(conn->gensec, req->creds.SASL.mechanism); -- 1.9.1 From d561a83b4898b81a0085a5ef832a09090c2358f7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:53:45 +0100 Subject: [PATCH 179/440] s3:libads: add missing TALLOC_FREE(frame) in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 8f9a9633e4f55f85a3f68bf2e8c78414f31511ea) --- source3/libads/sasl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 720ee78..e1dd506 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -46,6 +46,7 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t } if ((ads->ldap.out.size - 4) < wrapped.length) { + TALLOC_FREE(frame); return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); } -- 1.9.1 From 14a50864801f9225d68928c0cb65a48004bef119 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:04:02 +0100 Subject: [PATCH 180/440] s3:libads: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is more generic and will handle the ntlmssp_[un]wrap() behaviour at the right level. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 357d37fa11b7d944e9f5fe2e0cc6730d498bc2dc) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e1dd506..0251980 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -158,11 +158,11 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } else { /* * windows servers are broken with sign only, - * so we need to use seal here too + * so we let the NTLMSSP backend to seal here, + * via GENSEC_FEATURE_LDAP_STYLE. */ gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN); - gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL); - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_LDAP_STYLE); } break; case ADS_SASLWRAP_TYPE_PLAIN: -- 1.9.1 From 4d3b96ac28bb7a88830ad3242e09667738d71ba9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:02:29 +0100 Subject: [PATCH 181/440] s3:libads: make use of GENSEC_OID_SPNEGO in ads_sasl_spnego_ntlmssp_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids using the hand made spnego code, that doesn't support the GENSEC_FEATURE_NEW_SPNEGO protection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit c6f79cfa86e23217a510c6fe205da0c18ef2a9b2) --- source3/libads/sasl.c | 110 +++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 65 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0251980..ba33c1d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -19,6 +19,7 @@ #include "includes.h" #include "../libcli/auth/spnego.h" +#include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #include "auth_generic.h" #include "ads.h" @@ -120,16 +121,11 @@ static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - DATA_BLOB msg1 = data_blob_null; - DATA_BLOB blob = data_blob_null; DATA_BLOB blob_in = data_blob_null; DATA_BLOB blob_out = data_blob_null; - struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; ADS_STATUS status; - int turn = 1; - struct auth_generic_state *auth_generic_state; nt_status = auth_generic_client_prepare(NULL, &auth_generic_state); @@ -147,6 +143,9 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + cli_credentials_set_kerberos_state(auth_generic_state->credentials, + CRED_DONT_USE_KERBEROS); + switch (ads->ldap.wrap_type) { case ADS_SASLWRAP_TYPE_SEAL: gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN); @@ -169,87 +168,68 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) break; } - nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP); + nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO); if (!NT_STATUS_IS_OK(nt_status)) { return ADS_ERROR_NT(nt_status); } + rc = LDAP_SASL_BIND_IN_PROGRESS; + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; blob_in = data_blob_null; + blob_out = data_blob_null; + + while (true) { + struct berval cred, *scred = NULL; - do { nt_status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), blob_in, &blob_out); data_blob_free(&blob_in); - if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) - || NT_STATUS_IS_OK(nt_status)) - && blob_out.length) { - if (turn == 1) { - const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; - /* and wrap it in a SPNEGO wrapper */ - msg1 = spnego_gen_negTokenInit(talloc_tos(), - OIDs_ntlm, &blob_out, NULL); - } else { - /* wrap it in SPNEGO */ - msg1 = spnego_gen_auth(talloc_tos(), blob_out); - } - + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + && !NT_STATUS_IS_OK(nt_status)) + { + TALLOC_FREE(auth_generic_state); data_blob_free(&blob_out); + return ADS_ERROR_NT(nt_status); + } - cred.bv_val = (char *)msg1.data; - cred.bv_len = msg1.length; - scred = NULL; - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - data_blob_free(&msg1); - if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { - if (scred) { - ber_bvfree(scred); - } + if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_out.length == 0) { + break; + } - TALLOC_FREE(auth_generic_state); - return ADS_ERROR(rc); - } + cred.bv_val = (char *)blob_out.data; + cred.bv_len = blob_out.length; + scred = NULL; + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + data_blob_free(&blob_out); + if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { - blob = data_blob(scred->bv_val, scred->bv_len); ber_bvfree(scred); - } else { - blob = data_blob_null; } - } else { - TALLOC_FREE(auth_generic_state); - data_blob_free(&blob_out); - return ADS_ERROR_NT(nt_status); + return ADS_ERROR(rc); } - - if ((turn == 1) && - (rc == LDAP_SASL_BIND_IN_PROGRESS)) { - DATA_BLOB tmp_blob = data_blob_null; - /* the server might give us back two challenges */ - if (!spnego_parse_challenge(talloc_tos(), blob, &blob_in, - &tmp_blob)) { - - TALLOC_FREE(auth_generic_state); - data_blob_free(&blob); - DEBUG(3,("Failed to parse challenges\n")); - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - data_blob_free(&tmp_blob); - } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { - if (!spnego_parse_auth_response(talloc_tos(), blob, nt_status, OID_NTLMSSP, - &blob_in)) { - + if (scred) { + blob_in = data_blob_talloc(talloc_tos(), + scred->bv_val, + scred->bv_len); + if (blob_in.length != scred->bv_len) { + ber_bvfree(scred); TALLOC_FREE(auth_generic_state); - data_blob_free(&blob); - DEBUG(3,("Failed to parse auth response\n")); - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + ber_bvfree(scred); + } else { + blob_in = data_blob_null; } - data_blob_free(&blob); - data_blob_free(&blob_out); - turn++; - } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); - + if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_in.length == 0) { + break; + } + } + + data_blob_free(&blob_in); + data_blob_free(&blob_out); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security); ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); -- 1.9.1 From 21f7f90882255543bd77b5054fef82290dbcd395 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:14:05 +0100 Subject: [PATCH 182/440] s3:libads: provide a generic ads_sasl_spnego_gensec_bind() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be possible to use this for more than just NTLMSSP in future. Similar to https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 139ce7d8b687cc54560ce353ea6f86a4d2d2ae04) --- source3/libads/sasl.c | 81 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index ba33c1d..6f1a987 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -29,7 +29,7 @@ #ifdef HAVE_LDAP -static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) +static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -62,7 +62,7 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t return ADS_SUCCESS; } -static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -96,7 +96,7 @@ static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) return ADS_SUCCESS; } -static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) +static void ads_sasl_gensec_disconnect(ADS_STRUCT *ads) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -108,18 +108,23 @@ static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) ads->ldap.wrap_private_data = NULL; } -static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { - .name = "ntlmssp", - .wrap = ads_sasl_ntlmssp_wrap, - .unwrap = ads_sasl_ntlmssp_unwrap, - .disconnect = ads_sasl_ntlmssp_disconnect +static const struct ads_saslwrap_ops ads_sasl_gensec_ops = { + .name = "gensec", + .wrap = ads_sasl_gensec_wrap, + .unwrap = ads_sasl_gensec_unwrap, + .disconnect = ads_sasl_gensec_disconnect }; /* - perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + perform a LDAP/SASL/SPNEGO/{NTLMSSP,KRB5} bind (just how many layers can we fit on one socket??) */ -static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, + const char *sasl, + enum credentials_use_kerberos krb5_state, + const char *target_service, + const char *target_hostname, + const DATA_BLOB server_blob) { DATA_BLOB blob_in = data_blob_null; DATA_BLOB blob_out = data_blob_null; @@ -127,6 +132,8 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) NTSTATUS nt_status; ADS_STATUS status; struct auth_generic_state *auth_generic_state; + bool use_spnego_principal = lp_client_use_spnego_principal(); + const char *sasl_list[] = { sasl, NULL }; nt_status = auth_generic_client_prepare(NULL, &auth_generic_state); if (!NT_STATUS_IS_OK(nt_status)) { @@ -143,8 +150,38 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + if (server_blob.length == 0) { + use_spnego_principal = false; + } + + if (krb5_state == CRED_DONT_USE_KERBEROS) { + use_spnego_principal = false; + } + cli_credentials_set_kerberos_state(auth_generic_state->credentials, - CRED_DONT_USE_KERBEROS); + krb5_state); + + if (target_service != NULL) { + nt_status = gensec_set_target_service( + auth_generic_state->gensec_security, + target_service); + if (!NT_STATUS_IS_OK(nt_status)) { + return ADS_ERROR_NT(nt_status); + } + } + + if (target_hostname != NULL) { + nt_status = gensec_set_target_hostname( + auth_generic_state->gensec_security, + target_hostname); + if (!NT_STATUS_IS_OK(nt_status)) { + return ADS_ERROR_NT(nt_status); + } + } + + if (target_service != NULL && target_hostname != NULL) { + use_spnego_principal = false; + } switch (ads->ldap.wrap_type) { case ADS_SASLWRAP_TYPE_SEAL: @@ -168,14 +205,23 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) break; } - nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO); + nt_status = auth_generic_client_start_by_sasl(auth_generic_state, + sasl_list); if (!NT_STATUS_IS_OK(nt_status)) { return ADS_ERROR_NT(nt_status); } rc = LDAP_SASL_BIND_IN_PROGRESS; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; - blob_in = data_blob_null; + if (use_spnego_principal) { + blob_in = data_blob_dup_talloc(talloc_tos(), server_blob); + if (blob_in.length == 0) { + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + } else { + blob_in = data_blob_null; + } blob_out = data_blob_null; while (true) { @@ -199,7 +245,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) cred.bv_val = (char *)blob_out.data; cred.bv_len = blob_out.length; scred = NULL; - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, sasl, &cred, NULL, NULL, &scred); data_blob_free(&blob_out); if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { @@ -237,7 +283,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped; ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; ads->ldap.in.max_wrapped = max_wrapped; - status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, auth_generic_state->gensec_security); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); @@ -1024,7 +1070,10 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ - return ads_sasl_spnego_ntlmssp_bind(ads); + return ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_DONT_USE_KERBEROS, + NULL, NULL, + data_blob_null); failed: return status; -- 1.9.1 From b4e38a408ca6b0556e23d75dba3b284a7dc91620 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:31:01 +0100 Subject: [PATCH 183/440] s3:libads: don't pass given_principal to ads_generate_service_principal() anymore. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0c204e11925982d8bd835830985479792b8cc820) --- source3/libads/sasl.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 6f1a987..65d3cc1 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -858,7 +858,6 @@ out: } static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, - const char *given_principal, struct ads_service_principal *p) { ADS_STATUS status; @@ -873,27 +872,9 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of - the SASL bind reply. So we guess based on server - name and realm. --jerry */ - /* Also try best guess when we get the w2k8 ignore principal - back, or when we are configured to ignore it - gd, - abartlet */ - - if (!lp_client_use_spnego_principal() || - !given_principal || - strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - - status = ads_guess_service_principal(ads, &p->string); - if (!ADS_ERR_OK(status)) { - return status; - } - } else { - p->string = SMB_STRDUP(given_principal); - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } + status = ads_guess_service_principal(ads, &p->string); + if (!ADS_ERR_OK(status)) { + return status; } #ifdef HAVE_KRB5 @@ -1008,6 +989,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) goto failed; } data_blob_free(&blob); + TALLOC_FREE(given_principal); /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { @@ -1020,7 +1002,6 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif talloc_free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && @@ -1028,8 +1009,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { struct ads_service_principal p; - status = ads_generate_service_principal(ads, given_principal, &p); - TALLOC_FREE(given_principal); + status = ads_generate_service_principal(ads, &p); if (!ADS_ERR_OK(status)) { return status; } @@ -1061,11 +1041,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { return status; } - } else -#endif - { - TALLOC_FREE(given_principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 @@ -1297,7 +1274,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; struct ads_service_principal p; - status = ads_generate_service_principal(ads, NULL, &p); + status = ads_generate_service_principal(ads, &p); if (!ADS_ERR_OK(status)) { return status; } -- 1.9.1 From cfc675ce78734652d2a3cf726c29ba34932fb148 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:33:04 +0100 Subject: [PATCH 184/440] s3:libads: keep service and hostname separately in ads_service_principal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caller will use them instead of the full principal in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit c5d7956364047925dee5d6f71a5b92a38c73e5a6) --- source3/libads/sasl.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 65d3cc1..5d47fd4 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -742,14 +742,18 @@ failed: #ifdef HAVE_KRB5 struct ads_service_principal { - char *string; + char *service; + char *hostname; + char *string; #ifdef HAVE_KRB5 - gss_name_t name; + gss_name_t name; #endif }; static void ads_free_service_principal(struct ads_service_principal *p) { + SAFE_FREE(p->service); + SAFE_FREE(p->hostname); SAFE_FREE(p->string); #ifdef HAVE_KRB5 @@ -761,9 +765,10 @@ static void ads_free_service_principal(struct ads_service_principal *p) ZERO_STRUCTP(p); } - -static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, - char **returned_principal) +static ADS_STATUS ads_guess_target(ADS_STRUCT *ads, + char **service, + char **hostname, + char **principal) { ADS_STATUS status = ADS_ERROR(LDAP_NO_MEMORY); char *princ = NULL; @@ -843,13 +848,26 @@ static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, goto out; } + *service = SMB_STRDUP("ldap"); + if (*service == NULL) { + status = ADS_ERROR(LDAP_PARAM_ERROR); + goto out; + } + *hostname = SMB_STRDUP(server); + if (*hostname == NULL) { + SAFE_FREE(*service); + status = ADS_ERROR(LDAP_PARAM_ERROR); + goto out; + } rc = asprintf(&princ, "ldap/%s@%s", server, realm); if (rc == -1 || princ == NULL) { + SAFE_FREE(*service); + SAFE_FREE(*hostname); status = ADS_ERROR(LDAP_PARAM_ERROR); goto out; } - *returned_principal = princ; + *principal = princ; status = ADS_SUCCESS; out: @@ -872,7 +890,10 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - status = ads_guess_service_principal(ads, &p->string); + status = ads_guess_target(ads, + &p->service, + &p->hostname, + &p->string); if (!ADS_ERR_OK(status)) { return status; } -- 1.9.1 From 2929a029a1a123163c9e35d95b510686f27d61a4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:42:51 +0100 Subject: [PATCH 185/440] s3:libads: make use of ads_sasl_spnego_gensec_bind() for GSS-SPNEGO with Kerberos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 2cb07ba50decdfd6d08271cd2b3d893ff95f5af9) --- source3/libads/sasl.c | 384 ++++---------------------------------------------- 1 file changed, 28 insertions(+), 356 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5d47fd4..e707228 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -464,280 +464,6 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { .disconnect = ads_sasl_gssapi_disconnect }; -/* - perform a LDAP/SASL/SPNEGO/GSSKRB5 bind -*/ -static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) -{ - ADS_STATUS status; - bool ok; - uint32_t minor_status; - int gss_rc, rc; - gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; - gss_OID_desc krb5_mech_type = - {9, discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; - gss_OID mech_type = &krb5_mech_type; - gss_OID actual_mech_type = GSS_C_NULL_OID; - const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; - gss_buffer_desc input_token, output_token; - uint32_t req_flags, ret_flags; - uint32_t req_tmp, ret_tmp; - DATA_BLOB unwrapped; - DATA_BLOB wrapped; - struct berval cred, *scred = NULL; - uint32_t context_validity = 0; - time_t context_endtime = 0; - - status = ads_init_gssapi_cred(ads, &gss_cred); - if (!ADS_ERR_OK(status)) { - goto failed; - } - - input_token.value = NULL; - input_token.length = 0; - - req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; - switch (ads->ldap.wrap_type) { - case ADS_SASLWRAP_TYPE_SEAL: - req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; - break; - case ADS_SASLWRAP_TYPE_SIGN: - req_flags |= GSS_C_INTEG_FLAG; - break; - case ADS_SASLWRAP_TYPE_PLAIN: - break; - } - - /* Note: here we explicit ask for the krb5 mech_type */ - gss_rc = gss_init_sec_context(&minor_status, - gss_cred, - &context_handle, - serv_name, - mech_type, - req_flags, - 0, - NULL, - &input_token, - &actual_mech_type, - &output_token, - &ret_flags, - NULL); - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - /* - * As some gssapi krb5 mech implementations - * automaticly add GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG - * to req_flags internaly, it's not possible to - * use plain or signing only connection via - * the gssapi interface. - * - * Because of this we need to check it the ret_flags - * has more flags as req_flags and correct the value - * of ads->ldap.wrap_type. - * - * I ads->auth.flags has ADS_AUTH_SASL_FORCE - * we need to give an error. - */ - req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - - if (req_tmp == ret_tmp) { - /* everythings fine... */ - - } else if (req_flags & GSS_C_CONF_FLAG) { - /* - * here we wanted sealing but didn't got it - * from the gssapi library - */ - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - - } else if ((req_flags & GSS_C_INTEG_FLAG) && - !(ret_flags & GSS_C_INTEG_FLAG)) { - /* - * here we wanted siging but didn't got it - * from the gssapi library - */ - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - - } else if (ret_flags & GSS_C_CONF_FLAG) { - /* - * here we didn't want sealing - * but the gssapi library forces it - * so correct the needed wrap_type if - * the caller didn't forced siging only - */ - if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - } - - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; - req_flags = ret_flags; - - } else if (ret_flags & GSS_C_INTEG_FLAG) { - /* - * here we didn't want signing - * but the gssapi library forces it - * so correct the needed wrap_type if - * the caller didn't forced plain - */ - if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - } - - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; - req_flags = ret_flags; - } else { - /* - * This could (should?) not happen - */ - status = ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); - goto failed; - - } - - /* and wrap that in a shiny SPNEGO wrapper */ - unwrapped = data_blob_const(output_token.value, output_token.length); - wrapped = spnego_gen_negTokenInit(talloc_tos(), - spnego_mechs, &unwrapped, NULL); - gss_release_buffer(&minor_status, &output_token); - if (unwrapped.length > wrapped.length) { - status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto failed; - } - - cred.bv_val = (char *)wrapped.data; - cred.bv_len = wrapped.length; - - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, - &scred); - data_blob_free(&wrapped); - if (rc != LDAP_SUCCESS) { - status = ADS_ERROR(rc); - goto failed; - } - - if (scred) { - wrapped = data_blob_const(scred->bv_val, scred->bv_len); - } else { - wrapped = data_blob_null; - } - - ok = spnego_parse_auth_response(talloc_tos(), wrapped, NT_STATUS_OK, - OID_KERBEROS5_OLD, - &unwrapped); - if (scred) ber_bvfree(scred); - if (!ok) { - status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); - goto failed; - } - - input_token.value = unwrapped.data; - input_token.length = unwrapped.length; - - /* - * As we asked for mutal authentication - * we need to pass the servers response - * to gssapi - */ - gss_rc = gss_init_sec_context(&minor_status, - gss_cred, - &context_handle, - serv_name, - mech_type, - req_flags, - 0, - NULL, - &input_token, - &actual_mech_type, - &output_token, - &ret_flags, - NULL); - data_blob_free(&unwrapped); - if (gss_rc) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - gss_release_buffer(&minor_status, &output_token); - - /* - * If we the sign and seal options - * doesn't match after getting the response - * from the server, we don't want to use the connection - */ - req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - - if (req_tmp != ret_tmp) { - /* everythings fine... */ - status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); - goto failed; - } - - gss_rc = - gss_context_time(&minor_status, context_handle, &context_validity); - if (gss_rc == GSS_S_COMPLETE) { - if (context_validity != 0) { - context_endtime = time(NULL) + context_validity; - DEBUG(10, ("context (service ticket) valid for " - "%u seconds\n", - context_validity)); - } else { - DEBUG(10, ("context (service ticket) expired\n")); - } - } else { - DEBUG(1, ("gss_context_time failed (%d,%u) -" - " this will be a one-time context\n", - gss_rc, minor_status)); - if (gss_rc == GSS_S_CONTEXT_EXPIRED) { - DEBUG(10, ("context (service ticket) expired\n")); - } - } - - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; - - gss_rc = gss_wrap_size_limit(&minor_status, context_handle, - (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), - GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max_unwrapped); - if (gss_rc) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; - ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ - ads->ldap.in.max_wrapped = max_msg_size; - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", - ads_errstr(status))); - goto failed; - } - /* make sure we don't free context_handle */ - context_handle = GSS_C_NO_CONTEXT; - } - - ads->auth.tgs_expire = context_endtime; - status = ADS_SUCCESS; - -failed: - if (gss_cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&minor_status, &gss_cred); - if (context_handle != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - return status; -} - #endif /* HAVE_KRB5 */ #ifdef HAVE_KRB5 @@ -912,63 +638,6 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, return ADS_SUCCESS; } -/* - perform a LDAP/SASL/SPNEGO/KRB5 bind -*/ -static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal) -{ - DATA_BLOB blob = data_blob_null; - struct berval cred, *scred = NULL; - DATA_BLOB session_key = data_blob_null; - int rc; - - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - } - - rc = spnego_gen_krb5_negTokenInit(talloc_tos(), principal, - ads->auth.time_offset, &blob, &session_key, 0, - ads->auth.ccache_name, - &ads->auth.tgs_expire); - - if (rc) { - return ADS_ERROR_KRB5(rc); - } - - /* now send the auth packet and we should be done */ - cred.bv_val = (char *)blob.data; - cred.bv_len = blob.length; - - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - - data_blob_free(&blob); - data_blob_free(&session_key); - if(scred) - ber_bvfree(scred); - - return ADS_ERROR(rc); -} - -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, - struct ads_service_principal *p) -{ -#ifdef HAVE_KRB5 - /* - * we only use the gsskrb5 based implementation - * when sasl sign or seal is requested. - * - * This has the following reasons: - * - it's likely that the gssapi krb5 mech implementation - * doesn't support to negotiate plain connections - * - the ads_sasl_spnego_rawkrb5_bind is more robust - * against clock skew errors - */ - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ads_sasl_spnego_gsskrb5_bind(ads, p->name); - } -#endif - return ads_sasl_spnego_rawkrb5_bind(ads, p->string); -} #endif /* HAVE_KRB5 */ /* @@ -976,6 +645,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, */ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { + TALLOC_CTX *frame = talloc_stackframe(); + struct ads_service_principal p; struct berval *scred=NULL; int rc, i; ADS_STATUS status; @@ -990,7 +661,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); - goto failed; + goto done; } blob = data_blob(scred->bv_val, scred->bv_len); @@ -1005,11 +676,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) reply */ if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) || OIDs[0] == NULL) { - data_blob_free(&blob); status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto failed; + goto done; } - data_blob_free(&blob); TALLOC_FREE(given_principal); /* make sure the server understands kerberos */ @@ -1024,43 +693,45 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) talloc_free(OIDs[i]); } + status = ads_generate_service_principal(ads, &p); + if (!ADS_ERR_OK(status)) { + goto done; + } + #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - struct ads_service_principal p; - - status = ads_generate_service_principal(ads, &p); - if (!ADS_ERR_OK(status)) { - return status; - } - - status = ads_sasl_spnego_krb5_bind(ads, &p); + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_MUST_USE_KERBEROS, + p.service, p.hostname, + blob); if (ADS_ERR_OK(status)) { ads_free_service_principal(&p); - return status; + goto done; } - DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, " + DEBUG(10,("ads_sasl_spnego_gensec_bind(KRB5) failed with: %s, " "calling kinit\n", ads_errstr(status))); status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { - status = ads_sasl_spnego_krb5_bind(ads, &p); + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_MUST_USE_KERBEROS, + p.service, p.hostname, + blob); if (!ADS_ERR_OK(status)) { DEBUG(0,("kinit succeeded but " - "ads_sasl_spnego_krb5_bind failed: %s\n", + "ads_sasl_spnego_gensec_bind(KRB5) failed: %s\n", ads_errstr(status))); } } - ads_free_service_principal(&p); - /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { - return status; + goto done; } } #endif @@ -1068,12 +739,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ - return ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_DONT_USE_KERBEROS, - NULL, NULL, - data_blob_null); - -failed: + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_DONT_USE_KERBEROS, + p.service, p.hostname, + data_blob_null); +done: + ads_free_service_principal(&p); + TALLOC_FREE(frame); return status; } -- 1.9.1 From bb4e0c0cf0d48960b823b6c74603ae9ec993cc2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 14:34:46 +0100 Subject: [PATCH 186/440] s3:libsmb: make use gensec based SPNEGO/NTLMSSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 4f6fe27c7020822dd1ce88b7dd63725d6082b190) --- source3/libsmb/cliconnect.c | 179 +++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 84 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8d5721f..2a072b0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -26,7 +26,10 @@ #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" #include "smb_krb5.h" -#include "../auth/ntlmssp/ntlmssp.h" +#include "auth/credentials/credentials.h" +#include "auth/gensec/gensec.h" +#include "auth/ntlmssp/ntlmssp.h" +#include "auth_generic.h" #include "libads/kerberos_proto.h" #include "krb5_env.h" #include "../lib/util/tevent_ntstatus.h" @@ -1416,17 +1419,18 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) struct cli_session_setup_ntlmssp_state { struct tevent_context *ev; struct cli_state *cli; - struct ntlmssp_state *ntlmssp_state; - int turn; + struct auth_generic_state *auth_generic; + bool is_anonymous; + DATA_BLOB blob_in; DATA_BLOB blob_out; + DATA_BLOB session_key; }; static int cli_session_setup_ntlmssp_state_destructor( struct cli_session_setup_ntlmssp_state *state) { - if (state->ntlmssp_state != NULL) { - TALLOC_FREE(state->ntlmssp_state); - } + TALLOC_FREE(state->auth_generic); + data_blob_clear_free(&state->session_key); return 0; } @@ -1439,8 +1443,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( struct tevent_req *req, *subreq; struct cli_session_setup_ntlmssp_state *state; NTSTATUS status; - DATA_BLOB blob_out; - const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; req = tevent_req_create(mem_ctx, &state, struct cli_session_setup_ntlmssp_state); @@ -1449,51 +1451,85 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } state->ev = ev; state->cli = cli; - state->turn = 1; - state->ntlmssp_state = NULL; talloc_set_destructor( state, cli_session_setup_ntlmssp_state_destructor); - status = ntlmssp_client_start(state, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), - &state->ntlmssp_state); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + status = auth_generic_client_prepare(state, &state->auth_generic); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - ntlmssp_want_feature(state->ntlmssp_state, - NTLMSSP_FEATURE_SESSION_KEY); + + gensec_want_feature(state->auth_generic->gensec_security, + GENSEC_FEATURE_SESSION_KEY); if (cli->use_ccache) { - ntlmssp_want_feature(state->ntlmssp_state, - NTLMSSP_FEATURE_CCACHE); + gensec_want_feature(state->auth_generic->gensec_security, + GENSEC_FEATURE_NTLM_CCACHE); + if (pass != NULL && strlen(pass) == 0) { + /* + * some callers pass "" as no password + * + * GENSEC_FEATURE_NTLM_CCACHE only handles + * NULL as no password. + */ + pass = NULL; + } } - status = ntlmssp_set_username(state->ntlmssp_state, user); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + status = auth_generic_set_username(state->auth_generic, user); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - status = ntlmssp_set_domain(state->ntlmssp_state, domain); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + status = auth_generic_set_domain(state->auth_generic, domain); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } + if (cli->pw_nt_hash) { - status = ntlmssp_set_password_hash(state->ntlmssp_state, pass); + struct samr_Password nt_hash; + size_t converted; + bool ok; + + converted = strhex_to_str((char *)nt_hash.hash, + sizeof(nt_hash.hash), + pass, strlen(pass)); + if (converted != sizeof(nt_hash.hash)) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + ok = cli_credentials_set_nt_hash(state->auth_generic->credentials, + &nt_hash, CRED_SPECIFIED); + if (!ok) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } } else { - status = ntlmssp_set_password(state->ntlmssp_state, pass); + status = auth_generic_set_password(state->auth_generic, pass); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } } - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + cli_credentials_set_kerberos_state(state->auth_generic->credentials, + CRED_DONT_USE_KERBEROS); + + state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials); + + status = auth_generic_client_start(state->auth_generic, + GENSEC_OID_SPNEGO); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - status = ntlmssp_update(state->ntlmssp_state, data_blob_null, - &blob_out); + + status = gensec_update(state->auth_generic->gensec_security, + state, state->blob_in, &state->blob_out); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto fail; + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); } - state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); - data_blob_free(&blob_out); - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { state->cli->smb2.session = smbXcli_session_create(cli, cli->conn); @@ -1508,9 +1544,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); return req; -fail: - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); } static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) @@ -1519,32 +1552,41 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) subreq, struct tevent_req); struct cli_session_setup_ntlmssp_state *state = tevent_req_data( req, struct cli_session_setup_ntlmssp_state); - DATA_BLOB blob_in, msg_in, blob_out; uint8_t *inbuf = NULL; struct iovec *recv_iov = NULL; - bool parse_ret; NTSTATUS status; - status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, + status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, &inbuf, &recv_iov); TALLOC_FREE(subreq); data_blob_free(&state->blob_out); if (NT_STATUS_IS_OK(status)) { - if (state->cli->server_domain[0] == '\0') { + const char *server_domain = NULL; + + server_domain = gensec_ntlmssp_server_domain( + state->auth_generic->gensec_security); + + if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { TALLOC_FREE(state->cli->server_domain); state->cli->server_domain = talloc_strdup(state->cli, - state->ntlmssp_state->server.netbios_domain); + server_domain); if (state->cli->server_domain == NULL) { tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } } + status = gensec_session_key(state->auth_generic->gensec_security, + state, &state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } + if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { struct smbXcli_session *session = state->cli->smb2.session; - if (ntlmssp_is_anonymous(state->ntlmssp_state)) { + if (state->is_anonymous) { /* * Windows server does not set the * SMB2_SESSION_FLAG_IS_GUEST nor @@ -1554,13 +1596,12 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) * to verify a signature on the final * session setup response. */ - TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } status = smb2cli_session_set_session_key(session, - state->ntlmssp_state->session_key, + state->session_key, recv_iov); if (tevent_req_nterror(req, status)) { return; @@ -1569,20 +1610,19 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) struct smbXcli_session *session = state->cli->smb1.session; status = smb1cli_session_set_session_key(session, - state->ntlmssp_state->session_key); + state->session_key); if (tevent_req_nterror(req, status)) { return; } if (smb1cli_conn_activate_signing( - state->cli->conn, state->ntlmssp_state->session_key, + state->cli->conn, state->session_key, data_blob_null) && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return; } } - TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } @@ -1591,49 +1631,20 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } - if (blob_in.length == 0) { + if (state->blob_in.length == 0) { tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); return; } - if ((state->turn == 1) - && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB tmp_blob = data_blob_null; - /* the server might give us back two challenges */ - parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, - &tmp_blob); - data_blob_free(&tmp_blob); - } else { - parse_ret = spnego_parse_auth_response(state, blob_in, status, - OID_NTLMSSP, &msg_in); - } - state->turn += 1; - - if (!parse_ret) { - DEBUG(3,("Failed to parse auth response\n")); - if (NT_STATUS_IS_OK(status) - || NT_STATUS_EQUAL(status, - NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror( - req, NT_STATUS_INVALID_NETWORK_RESPONSE); - return; - } - } - - status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); - + status = gensec_update(state->auth_generic->gensec_security, + state, state->blob_in, &state->blob_out); + data_blob_free(&state->blob_in); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - TALLOC_FREE(state->ntlmssp_state); tevent_req_nterror(req, status); return; } - state->blob_out = spnego_gen_auth(state, blob_out); - if (tevent_req_nomem(state->blob_out.data, req)) { - return; - } - subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, state->blob_out); if (tevent_req_nomem(subreq, req)) { -- 1.9.1 From d8a7f5ea1674dbef70d7df70315ec7f059a203e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 11:49:37 +0100 Subject: [PATCH 187/440] s3:libsmb: unused ntlmssp.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything uses the top level ntlmssp code via gensec now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit afffe797547a97ec839913e1ca89045989bbea49) --- source3/include/proto.h | 25 -- source3/libsmb/ntlmssp.c | 765 ----------------------------------------------- source3/wscript_build | 9 +- 3 files changed, 2 insertions(+), 797 deletions(-) delete mode 100644 source3/libsmb/ntlmssp.c diff --git a/source3/include/proto.h b/source3/include/proto.h index ce23289..a34ccff 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -903,31 +903,6 @@ bool get_dc_name(const char *domain, fstring srv_name, struct sockaddr_storage *ss_out); -/* The following definitions come from libsmb/ntlmssp.c */ -struct ntlmssp_state; -NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) ; -NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) ; -NTSTATUS ntlmssp_set_password_hash(struct ntlmssp_state *ntlmssp_state, - const char *hash); -NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ; -void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list); -void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature); -NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB in, DATA_BLOB *out) ; -bool ntlmssp_is_anonymous(struct ntlmssp_state *ntlmssp_state); -NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, - bool is_standalone, - const char *netbios_name, - const char *netbios_domain, - const char *dns_name, - const char *dns_domain, - struct ntlmssp_state **ntlmssp_state); -NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct ntlmssp_state **_ntlmssp_state); - /* The following definitions come from libsmb/passchange.c */ NTSTATUS remote_password_change(const char *remote_machine, const char *user_name, diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c deleted file mode 100644 index e661aeb..0000000 --- a/source3/libsmb/ntlmssp.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0 - handle NLTMSSP, server side - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2010 - 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 - 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, - 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, see . -*/ - -#include "includes.h" -#include "../auth/ntlmssp/ntlmssp.h" -#include "../auth/ntlmssp/ntlmssp_private.h" -#include "../libcli/auth/libcli_auth.h" -#include "../librpc/gen_ndr/ndr_ntlmssp.h" -#include "../auth/ntlmssp/ntlmssp_ndr.h" -#include "../lib/crypto/md5.h" -#include "../lib/crypto/arcfour.h" -#include "../lib/crypto/hmacmd5.h" -#include "../nsswitch/libwbclient/wbclient.h" - -static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB reply, DATA_BLOB *next_request); -static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, /* Unused at this time */ - const DATA_BLOB reply, DATA_BLOB *next_request); -/** - * Callbacks for NTLMSSP - for both client and server operating modes - * - */ - -static const struct ntlmssp_callbacks { - enum ntlmssp_role role; - enum ntlmssp_message_type ntlmssp_command; - NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out); -} ntlmssp_callbacks[] = { - {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp3_client_initial}, - {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp3_client_challenge}, - {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, - {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} -}; - -/** - * Set a username on an NTLMSSP context - ensures it is talloc()ed - * - */ - -NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) -{ - ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" ); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Converts a password to the hashes on an NTLMSSP context. - * - */ -NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) -{ - uint8_t lm_hash[16]; - uint8_t nt_hash[16]; - - TALLOC_FREE(ntlmssp_state->lm_hash); - TALLOC_FREE(ntlmssp_state->nt_hash); - - if (password == NULL) { - return NT_STATUS_OK; - } - - if (E_deshash(password, lm_hash)) { - ntlmssp_state->lm_hash = (uint8_t *) - talloc_memdup(ntlmssp_state, lm_hash, 16); - if (!ntlmssp_state->lm_hash) { - return NT_STATUS_NO_MEMORY; - } - } - - E_md4hash(password, nt_hash); - - ntlmssp_state->nt_hash = (uint8_t *) - talloc_memdup(ntlmssp_state, nt_hash, 16); - if (!ntlmssp_state->nt_hash) { - TALLOC_FREE(ntlmssp_state->lm_hash); - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_password_hash(struct ntlmssp_state *state, - const char *pwhash) -{ - char nt_hash[16]; - size_t converted; - - converted = strhex_to_str( - nt_hash, sizeof(nt_hash), pwhash, strlen(pwhash)); - if (converted != sizeof(nt_hash)) { - return NT_STATUS_INVALID_PARAMETER; - } - - TALLOC_FREE(state->lm_hash); - TALLOC_FREE(state->nt_hash); - - state->nt_hash = (uint8_t *)talloc_memdup(state, nt_hash, 16); - if (!state->nt_hash) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set a domain on an NTLMSSP context - ensures it is talloc()ed - * - */ -NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state, - domain ? domain : "" ); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Request features for the NTLMSSP negotiation - * - * @param ntlmssp_state NTLMSSP state - * @param feature_list List of space separated features requested from NTLMSSP. - */ -void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list) -{ - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - */ - if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { - ntlmssp_state->use_ccache = true; - } -} - -/** - * Request a feature for the NTLMSSP negotiation - * - * @param ntlmssp_state NTLMSSP state - * @param feature Bit flag specifying the requested feature - */ -void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature) -{ - /* As per JRA's comment above */ - if (feature & NTLMSSP_FEATURE_SESSION_KEY) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (feature & NTLMSSP_FEATURE_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (feature & NTLMSSP_FEATURE_SEAL) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - if (feature & NTLMSSP_FEATURE_CCACHE) { - ntlmssp_state->use_ccache = true; - } -} - -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB input, DATA_BLOB *out) -{ - uint32_t ntlmssp_command; - int i; - - if (ntlmssp_state->expected_state == NTLMSSP_DONE) { - /* Called update after negotiations finished. */ - DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - *out = data_blob_null; - - if (!input.length) { - switch (ntlmssp_state->role) { - case NTLMSSP_CLIENT: - ntlmssp_command = NTLMSSP_INITIAL; - break; - case NTLMSSP_SERVER: - /* 'datagram' mode - no neg packet */ - ntlmssp_command = NTLMSSP_NEGOTIATE; - break; - default: - DEBUG(1, ("Invalid role: %d\n", ntlmssp_state->role)); - return NT_STATUS_INVALID_PARAMETER; - } - } else { - if (!msrpc_parse(ntlmssp_state, &input, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); - dump_data(2, input.data, input.length); - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } - - for (i=0; ntlmssp_callbacks[i].fn; i++) { - if (ntlmssp_callbacks[i].role == ntlmssp_state->role - && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { - return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out); - } - } - - DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", - ntlmssp_state->role, ntlmssp_command)); - - return NT_STATUS_INVALID_PARAMETER; -} - -/********************************************************************* - Client side NTLMSSP -*********************************************************************/ - -/** - * Next state function for the Initial packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out) -{ - const char *domain = ntlmssp_state->client.netbios_domain; - const char *workstation = ntlmssp_state->client.netbios_name; - NTSTATUS status; - - /* These don't really matter in the initial packet, so don't panic if they are not set */ - if (!domain) { - domain = ""; - } - - if (!workstation) { - workstation = ""; - } - - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } else { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - - /* generate the ntlmssp negotiate packet */ - status = msrpc_gen(out_mem_ctx, - out, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - domain, - workstation); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ntlmssp_client_initial: failed to generate " - "ntlmssp negotiate packet\n")); - return status; - } - - if (DEBUGLEVEL >= 10) { - struct NEGOTIATE_MESSAGE *negotiate = talloc( - talloc_tos(), struct NEGOTIATE_MESSAGE); - if (negotiate != NULL) { - status = ntlmssp_pull_NEGOTIATE_MESSAGE( - out, negotiate, negotiate); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, - negotiate); - } - TALLOC_FREE(negotiate); - } - } - - ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -bool ntlmssp_is_anonymous(struct ntlmssp_state *ntlmssp_state) -{ - const char *user = ntlmssp_state->user; - - if (user == NULL) { - return true; - } - - if (strlen(user) == 0) { - return true; - } - - return false; -} - -/** - * Next state function for the Challenge Packet. Generate an auth packet. - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, /* Unused at this time */ - const DATA_BLOB reply, DATA_BLOB *next_request) -{ - uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0; - DATA_BLOB server_domain_blob; - DATA_BLOB challenge_blob; - DATA_BLOB struct_blob = data_blob_null; - char *server_domain; - const char *chal_parse_string; - const char *chal_parse_string_short = NULL; - const char *auth_gen_string; - DATA_BLOB lm_response = data_blob_null; - DATA_BLOB nt_response = data_blob_null; - DATA_BLOB session_key = data_blob_null; - DATA_BLOB encrypted_session_key = data_blob_null; - NTSTATUS nt_status = NT_STATUS_OK; - bool anon = ntlmssp_is_anonymous(ntlmssp_state); - - if (!anon && ntlmssp_state->use_ccache) { - struct wbcCredentialCacheParams params; - struct wbcCredentialCacheInfo *info = NULL; - struct wbcAuthErrorInfo *error = NULL; - struct wbcNamedBlob auth_blob; - struct wbcBlob *wbc_next = NULL; - struct wbcBlob *wbc_session_key = NULL; - wbcErr wbc_status; - int i; - - /* - * We need to set the netbios name or we are not able to connect - * a Windows DC. - */ - if (ntlmssp_state->server.netbios_domain == NULL || - ntlmssp_state->server.netbios_domain[0] == '\0') { - ntlmssp_state->server.netbios_domain = ntlmssp_state->domain; - } - - params.account_name = ntlmssp_state->user; - params.domain_name = ntlmssp_state->domain; - params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; - - auth_blob.name = "challenge_blob"; - auth_blob.flags = 0; - auth_blob.blob.data = reply.data; - auth_blob.blob.length = reply.length; - params.num_blobs = 1; - params.blobs = &auth_blob; - - wbc_status = wbcCredentialCache(¶ms, &info, &error); - wbcFreeMemory(error); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto noccache; - } - - for (i=0; inum_blobs; i++) { - if (strequal(info->blobs[i].name, "auth_blob")) { - wbc_next = &info->blobs[i].blob; - } - if (strequal(info->blobs[i].name, "session_key")) { - wbc_session_key = &info->blobs[i].blob; - } - } - if ((wbc_next == NULL) || (wbc_session_key == NULL)) { - wbcFreeMemory(info); - goto noccache; - } - - *next_request = data_blob_talloc(ntlmssp_state, - wbc_next->data, - wbc_next->length); - ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, - wbc_session_key->data, - wbc_session_key->length); - - wbcFreeMemory(info); - goto done; - } - -noccache: - - if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags)) { - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, reply.data, reply.length); - - return NT_STATUS_INVALID_PARAMETER; - } - - if (DEBUGLEVEL >= 10) { - struct CHALLENGE_MESSAGE *challenge = talloc( - talloc_tos(), struct CHALLENGE_MESSAGE); - if (challenge != NULL) { - NTSTATUS status; - challenge->NegotiateFlags = chal_flags; - status = ntlmssp_pull_CHALLENGE_MESSAGE( - &reply, challenge, challenge); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, - challenge); - } - TALLOC_FREE(challenge); - } - } - - data_blob_free(&server_domain_blob); - - DEBUG(3, ("Got challenge flags:\n")); - debug_ntlmssp_flags(chal_flags); - - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); - - if (ntlmssp_state->unicode) { - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { - chal_parse_string = "CdUdbddB"; - } else { - chal_parse_string = "CdUdbdd"; - chal_parse_string_short = "CdUdb"; - } - auth_gen_string = "CdBBUUUBd"; - } else { - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { - chal_parse_string = "CdAdbddB"; - } else { - chal_parse_string = "CdAdbdd"; - chal_parse_string_short = "CdAdb"; - } - - auth_gen_string = "CdBBAAABd"; - } - - DEBUG(3, ("NTLMSSP: Set final flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - - if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - - bool ok = false; - - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - - if (chal_parse_string_short != NULL) { - /* - * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO - * is not used, some NTLMSSP servers don't return - * the unused unkn1 and unkn2 fields. - * See bug: - * https://bugzilla.samba.org/show_bug.cgi?id=10016 - * for packet traces. - * Try and parse again without them. - */ - ok = msrpc_parse(ntlmssp_state, &reply, - chal_parse_string_short, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8); - if (!ok) { - DEBUG(1, ("Failed to short parse " - "the NTLMSSP Challenge: (#2)\n")); - } - } - - if (!ok) { - dump_data(2, reply.data, reply.length); - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { - ntlmssp_state->server.is_standalone = true; - } else { - ntlmssp_state->server.is_standalone = false; - } - /* TODO: parse struct_blob and fill in the rest */ - ntlmssp_state->server.netbios_name = ""; - ntlmssp_state->server.netbios_domain = server_domain; - ntlmssp_state->server.dns_name = ""; - ntlmssp_state->server.dns_domain = ""; - - if (challenge_blob.length != 8) { - data_blob_free(&struct_blob); - return NT_STATUS_INVALID_PARAMETER; - } - - if (anon || !ntlmssp_state->nt_hash) { - static const uint8_t zeros[16] = {0, }; - /* do nothing - blobs are zero length */ - - /* session key is all zeros */ - session_key = data_blob_talloc(ntlmssp_state, zeros, 16); - - /* not doing NLTM2 without a password */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } else if (ntlmssp_state->use_ntlmv2) { - if (!struct_blob.length) { - /* be lazy, match win2k - we can't do NTLMv2 without it */ - DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* TODO: if the remote server is standalone, then we should replace 'domain' - with the server name as supplied above */ - - if (!SMBNTLMv2encrypt_hash(ntlmssp_state, - ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->nt_hash, &challenge_blob, - &struct_blob, - &lm_response, &nt_response, NULL, - &session_key)) { - data_blob_free(&challenge_blob); - data_blob_free(&struct_blob); - return NT_STATUS_NO_MEMORY; - } - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - MD5_CTX md5_session_nonce_ctx; - uint8_t session_nonce[16]; - uint8_t session_nonce_hash[16]; - uint8_t user_session_key[16]; - - lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); - generate_random_buffer(lm_response.data, 8); - memset(lm_response.data+8, 0, 16); - - memcpy(session_nonce, challenge_blob.data, 8); - memcpy(&session_nonce[8], lm_response.data, 8); - - MD5Init(&md5_session_nonce_ctx); - MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); - MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); - MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - - DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); - DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); - - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt_hash(ntlmssp_state->nt_hash, - session_nonce_hash, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key); - hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); - dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - } else { - /* lanman auth is insecure, it may be disabled */ - if (lp_client_lanman_auth() && ntlmssp_state->lm_hash) { - lm_response = data_blob_talloc(ntlmssp_state, - NULL, 24); - SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data, - lm_response.data); - } - - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth() && ntlmssp_state->lm_hash) { - SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data, - session_key.data); - dump_data_pw("LM session key\n", session_key.data, session_key.length); - } else { - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data); - dump_data_pw("NT session key:\n", session_key.data, session_key.length); - } - } - data_blob_free(&struct_blob); - - /* Key exchange encryptes a new client-generated session key with - the password-derived key */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - /* Make up a new session key */ - uint8_t client_session_key[16]; - generate_random_buffer(client_session_key, sizeof(client_session_key)); - - /* Encrypt the new session key with the old one */ - encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); - dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key); - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - - /* Mark the new session key as the 'real' session key */ - data_blob_free(&session_key); - session_key = data_blob_talloc(ntlmssp_state, - client_session_key, - sizeof(client_session_key)); - } - - /* this generates the actual auth packet */ - nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->client.netbios_name, - encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags); - - if (!NT_STATUS_IS_OK(nt_status)) { - return NT_STATUS_NO_MEMORY; - } - - if (DEBUGLEVEL >= 10) { - struct AUTHENTICATE_MESSAGE *authenticate = talloc( - talloc_tos(), struct AUTHENTICATE_MESSAGE); - if (authenticate != NULL) { - NTSTATUS status; - authenticate->NegotiateFlags = - ntlmssp_state->neg_flags; - status = ntlmssp_pull_AUTHENTICATE_MESSAGE( - next_request, authenticate, authenticate); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, - authenticate); - } - TALLOC_FREE(authenticate); - } - } - - data_blob_free(&encrypted_session_key); - - data_blob_free(&ntlmssp_state->chal); - - ntlmssp_state->session_key = session_key; - - ntlmssp_state->chal = challenge_blob; - ntlmssp_state->lm_resp = lm_response; - ntlmssp_state->nt_resp = nt_response; - -done: - - ntlmssp_state->expected_state = NTLMSSP_DONE; - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { - DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); - } - - return nt_status; -} - -NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct ntlmssp_state **_ntlmssp_state) -{ - struct ntlmssp_state *ntlmssp_state; - - if (!netbios_name) { - netbios_name = ""; - } - - if (!netbios_domain) { - netbios_domain = ""; - } - - ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state); - if (!ntlmssp_state) { - return NT_STATUS_NO_MEMORY; - } - - ntlmssp_state->role = NTLMSSP_CLIENT; - - ntlmssp_state->unicode = True; - - ntlmssp_state->use_ntlmv2 = use_ntlmv2; - - ntlmssp_state->expected_state = NTLMSSP_INITIAL; - - ntlmssp_state->neg_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_NTLM2 | - NTLMSSP_NEGOTIATE_KEY_EXCH | - NTLMSSP_REQUEST_TARGET; - - ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name); - if (!ntlmssp_state->client.netbios_name) { - talloc_free(ntlmssp_state); - return NT_STATUS_NO_MEMORY; - } - ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain); - if (!ntlmssp_state->client.netbios_domain) { - talloc_free(ntlmssp_state); - return NT_STATUS_NO_MEMORY; - } - - *_ntlmssp_state = ntlmssp_state; - return NT_STATUS_OK; -} diff --git a/source3/wscript_build b/source3/wscript_build index 3dea5e3..2935031 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -358,13 +358,9 @@ bld.SAMBA3_LIBRARY('smbd_shim', deps='talloc', private_library=True) -bld.SAMBA3_SUBSYSTEM('LIBNTLMSSP', - source='''libsmb/ntlmssp.c''', - deps='NDR_NTLMSSP NTLMSSP_COMMON wbclient') - bld.SAMBA3_SUBSYSTEM('auth_generic', source='libsmb/auth_generic.c', - deps='LIBNTLMSSP gse gensec') + deps='gse gensec') bld.SAMBA3_LIBRARY('libsmb', source='''libsmb/clientgen.c @@ -392,7 +388,6 @@ bld.SAMBA3_LIBRARY('libsmb', libsmb/smbsock_connect.c libsmb/cli_smb2_fnum.c''', deps=''' - LIBNTLMSSP auth_generic CLDAP LIBNMB @@ -1411,7 +1406,7 @@ bld.SAMBA3_BINARY('ntlm_auth', tiniparser libsmb popt_samba3 - LIBNTLMSSP gse gensec''') + gse gensec''') bld.SAMBA3_BINARY('timelimit', source='script/tests/timelimit.c', -- 1.9.1 From c74ad7e23a1bbc9298b58ef0d1c179bac893ac89 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 18:31:50 +0100 Subject: [PATCH 188/440] s3:libsmb: let cli_session_setup_ntlmssp*() use gensec_update_send/recv() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 576257f6e1488a623306dc368c806e218b1fcdf2) --- source3/libsmb/cliconnect.c | 283 ++++++++++++++++++++++++++++++-------------- 1 file changed, 191 insertions(+), 92 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2a072b0..accb170 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1422,7 +1422,11 @@ struct cli_session_setup_ntlmssp_state { struct auth_generic_state *auth_generic; bool is_anonymous; DATA_BLOB blob_in; + uint8_t *inbuf; + struct iovec *recv_iov; DATA_BLOB blob_out; + bool local_ready; + bool remote_ready; DATA_BLOB session_key; }; @@ -1434,13 +1438,17 @@ static int cli_session_setup_ntlmssp_state_destructor( return 0; } -static void cli_session_setup_ntlmssp_done(struct tevent_req *req); +static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req); +static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq); +static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req); +static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq); +static void cli_session_setup_ntlmssp_ready(struct tevent_req *req); static struct tevent_req *cli_session_setup_ntlmssp_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, const char *user, const char *pass, const char *domain) { - struct tevent_req *req, *subreq; + struct tevent_req *req; struct cli_session_setup_ntlmssp_state *state; NTSTATUS status; @@ -1523,13 +1531,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( return tevent_req_post(req, ev); } - status = gensec_update(state->auth_generic->gensec_security, - state, state->blob_in, &state->blob_out); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { state->cli->smb2.session = smbXcli_session_create(cli, cli->conn); @@ -1538,125 +1539,223 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } } - subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); - if (tevent_req_nomem(subreq, req)) { + cli_session_setup_ntlmssp_local_next(req); + if (!tevent_req_is_in_progress(req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); + return req; } -static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) +static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) { - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = tevent_req_data( - req, struct cli_session_setup_ntlmssp_state); - uint8_t *inbuf = NULL; - struct iovec *recv_iov = NULL; + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + struct tevent_req *subreq = NULL; + + if (state->local_ready) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + subreq = gensec_update_send(state, state->ev, + state->auth_generic->gensec_security, + state->blob_in); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_local_done, req); +} + +static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); NTSTATUS status; - status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, - &inbuf, &recv_iov); + status = gensec_update_recv(subreq, state, &state->blob_out); TALLOC_FREE(subreq); - data_blob_free(&state->blob_out); + state->blob_in = data_blob_null; + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + { + tevent_req_nterror(req, status); + return; + } if (NT_STATUS_IS_OK(status)) { - const char *server_domain = NULL; + state->local_ready = true; + } - server_domain = gensec_ntlmssp_server_domain( - state->auth_generic->gensec_security); + if (state->local_ready && state->remote_ready) { + cli_session_setup_ntlmssp_ready(req); + return; + } - if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { - TALLOC_FREE(state->cli->server_domain); - state->cli->server_domain = talloc_strdup(state->cli, - server_domain); - if (state->cli->server_domain == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } + cli_session_setup_ntlmssp_remote_next(req); +} - status = gensec_session_key(state->auth_generic->gensec_security, - state, &state->session_key); - if (tevent_req_nterror(req, status)) { - return; - } +static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) +{ + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + struct tevent_req *subreq = NULL; - if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { - struct smbXcli_session *session = state->cli->smb2.session; + if (state->remote_ready) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } - if (state->is_anonymous) { - /* - * Windows server does not set the - * SMB2_SESSION_FLAG_IS_GUEST nor - * SMB2_SESSION_FLAG_IS_NULL flag. - * - * This fix makes sure we do not try - * to verify a signature on the final - * session setup response. - */ - tevent_req_done(req); - return; - } + subreq = cli_sesssetup_blob_send(state, state->ev, + state->cli, state->blob_out); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, + cli_session_setup_ntlmssp_remote_done, + req); +} - status = smb2cli_session_set_session_key(session, - state->session_key, - recv_iov); - if (tevent_req_nterror(req, status)) { - return; - } - } else { - struct smbXcli_session *session = state->cli->smb1.session; +static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + NTSTATUS status; - status = smb1cli_session_set_session_key(session, - state->session_key); - if (tevent_req_nterror(req, status)) { - return; - } + TALLOC_FREE(state->inbuf); + TALLOC_FREE(state->recv_iov); - if (smb1cli_conn_activate_signing( - state->cli->conn, state->session_key, - data_blob_null) - && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - tevent_req_done(req); + status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, + &state->inbuf, &state->recv_iov); + TALLOC_FREE(subreq); + data_blob_free(&state->blob_out); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + { + tevent_req_nterror(req, status); return; } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); + + if (NT_STATUS_IS_OK(status)) { + state->remote_ready = true; + } + + if (state->local_ready && state->remote_ready) { + cli_session_setup_ntlmssp_ready(req); return; } - if (state->blob_in.length == 0) { - tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); + cli_session_setup_ntlmssp_local_next(req); +} + +static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) +{ + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + const char *server_domain = NULL; + NTSTATUS status; + + if (state->blob_in.length != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } - status = gensec_update(state->auth_generic->gensec_security, - state, state->blob_in, &state->blob_out); - data_blob_free(&state->blob_in); - if (!NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); + if (state->blob_out.length != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } - subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, - state->blob_out); - if (tevent_req_nomem(subreq, req)) { + /* + * We can remove this later + * and leave the server domain empty for SMB2 and above + * in future releases. + */ + server_domain = gensec_ntlmssp_server_domain( + state->auth_generic->gensec_security); + + if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { + TALLOC_FREE(state->cli->server_domain); + state->cli->server_domain = talloc_strdup(state->cli, + server_domain); + if (state->cli->server_domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + } + + status = gensec_session_key(state->auth_generic->gensec_security, + state, &state->session_key); + if (tevent_req_nterror(req, status)) { return; } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); + + if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { + struct smbXcli_session *session = state->cli->smb2.session; + + if (state->is_anonymous) { + /* + * Windows server does not set the + * SMB2_SESSION_FLAG_IS_GUEST nor + * SMB2_SESSION_FLAG_IS_NULL flag. + * + * This fix makes sure we do not try + * to verify a signature on the final + * session setup response. + */ + tevent_req_done(req); + return; + } + + status = smb2cli_session_set_session_key(session, + state->session_key, + state->recv_iov); + if (tevent_req_nterror(req, status)) { + return; + } + } else { + struct smbXcli_session *session = state->cli->smb1.session; + bool active; + + status = smb1cli_session_set_session_key(session, + state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } + + active = smb1cli_conn_activate_signing(state->cli->conn, + state->session_key, + data_blob_null); + if (active) { + bool ok; + + ok = smb1cli_conn_check_signing(state->cli->conn, + state->inbuf, 1); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } + } + } + + tevent_req_done(req); } static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = tevent_req_data( - req, struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { -- 1.9.1 From 6621658c559cacd94b444f83b79a091d7c709e65 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 15:47:11 +0100 Subject: [PATCH 189/440] s3:libsmb: provide generic cli_session_setup_gensec_send/recv() pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be possible to use this for more than just NTLMSSP in future. This prepares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 285c342f01a6e9a892f03360f8d2d0097e7a41cb) --- source3/libsmb/cliconnect.c | 151 ++++++++++++++++++++++++++++++-------------- 1 file changed, 103 insertions(+), 48 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index accb170..6b1fc33 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1416,7 +1416,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -struct cli_session_setup_ntlmssp_state { +struct cli_session_setup_gensec_state { struct tevent_context *ev; struct cli_state *cli; struct auth_generic_state *auth_generic; @@ -1430,30 +1430,35 @@ struct cli_session_setup_ntlmssp_state { DATA_BLOB session_key; }; -static int cli_session_setup_ntlmssp_state_destructor( - struct cli_session_setup_ntlmssp_state *state) +static int cli_session_setup_gensec_state_destructor( + struct cli_session_setup_gensec_state *state) { TALLOC_FREE(state->auth_generic); data_blob_clear_free(&state->session_key); return 0; } -static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req); -static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq); -static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req); -static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq); -static void cli_session_setup_ntlmssp_ready(struct tevent_req *req); +static void cli_session_setup_gensec_local_next(struct tevent_req *req); +static void cli_session_setup_gensec_local_done(struct tevent_req *subreq); +static void cli_session_setup_gensec_remote_next(struct tevent_req *req); +static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq); +static void cli_session_setup_gensec_ready(struct tevent_req *req); -static struct tevent_req *cli_session_setup_ntlmssp_send( +static struct tevent_req *cli_session_setup_gensec_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *user, const char *pass, const char *domain) + const char *user, const char *pass, const char *domain, + enum credentials_use_kerberos krb5_state, + const char *target_service, + const char *target_hostname, + const char *target_principal) { struct tevent_req *req; - struct cli_session_setup_ntlmssp_state *state; + struct cli_session_setup_gensec_state *state; NTSTATUS status; + bool use_spnego_principal = lp_client_use_spnego_principal(); req = tevent_req_create(mem_ctx, &state, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); if (req == NULL) { return NULL; } @@ -1461,7 +1466,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( state->cli = cli; talloc_set_destructor( - state, cli_session_setup_ntlmssp_state_destructor); + state, cli_session_setup_gensec_state_destructor); status = auth_generic_client_prepare(state, &state->auth_generic); if (tevent_req_nterror(req, status)) { @@ -1521,7 +1526,49 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } cli_credentials_set_kerberos_state(state->auth_generic->credentials, - CRED_DONT_USE_KERBEROS); + krb5_state); + + if (krb5_state == CRED_DONT_USE_KERBEROS) { + use_spnego_principal = false; + } + + if (target_service != NULL) { + status = gensec_set_target_service( + state->auth_generic->gensec_security, + target_service); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + } + + if (target_hostname != NULL) { + status = gensec_set_target_hostname( + state->auth_generic->gensec_security, + target_hostname); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + } + + if (target_principal != NULL) { + status = gensec_set_target_principal( + state->auth_generic->gensec_security, + target_principal); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + use_spnego_principal = false; + } else if (target_service != NULL && target_hostname != NULL) { + use_spnego_principal = false; + } + + if (use_spnego_principal) { + const DATA_BLOB *b; + b = smbXcli_conn_server_gss_blob(cli->conn); + if (b != NULL) { + state->blob_in = *b; + } + } state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials); @@ -1539,7 +1586,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } } - cli_session_setup_ntlmssp_local_next(req); + cli_session_setup_gensec_local_next(req); if (!tevent_req_is_in_progress(req)) { return tevent_req_post(req, ev); } @@ -1547,11 +1594,11 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( return req; } -static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) +static void cli_session_setup_gensec_local_next(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); struct tevent_req *subreq = NULL; if (state->local_ready) { @@ -1565,17 +1612,17 @@ static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_local_done, req); + tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req); } -static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) +static void cli_session_setup_gensec_local_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; status = gensec_update_recv(subreq, state, &state->blob_out); @@ -1593,18 +1640,18 @@ static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) } if (state->local_ready && state->remote_ready) { - cli_session_setup_ntlmssp_ready(req); + cli_session_setup_gensec_ready(req); return; } - cli_session_setup_ntlmssp_remote_next(req); + cli_session_setup_gensec_remote_next(req); } -static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) +static void cli_session_setup_gensec_remote_next(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); struct tevent_req *subreq = NULL; if (state->remote_ready) { @@ -1618,18 +1665,18 @@ static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) return; } tevent_req_set_callback(subreq, - cli_session_setup_ntlmssp_remote_done, + cli_session_setup_gensec_remote_done, req); } -static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) +static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; TALLOC_FREE(state->inbuf); @@ -1651,18 +1698,18 @@ static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) } if (state->local_ready && state->remote_ready) { - cli_session_setup_ntlmssp_ready(req); + cli_session_setup_gensec_ready(req); return; } - cli_session_setup_ntlmssp_local_next(req); + cli_session_setup_gensec_local_next(req); } -static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) +static void cli_session_setup_gensec_ready(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); const char *server_domain = NULL; NTSTATUS status; @@ -1677,6 +1724,9 @@ static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) } /* + * gensec_ntlmssp_server_domain() returns NULL + * if NTLMSSP is not used. + * * We can remove this later * and leave the server domain empty for SMB2 and above * in future releases. @@ -1751,11 +1801,11 @@ static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) tevent_req_done(req); } -static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) +static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { @@ -1835,6 +1885,7 @@ static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx, struct cli_session_setup_spnego_state { struct tevent_context *ev; struct cli_state *cli; + const char *target_hostname; const char *user; const char *account; const char *pass; @@ -1879,6 +1930,7 @@ static struct tevent_req *cli_session_setup_spnego_send( return tevent_req_post(req, ev); } + state->target_hostname = smbXcli_conn_remote_name(cli->conn); server_blob = smbXcli_conn_server_gss_blob(cli->conn); DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", @@ -1933,12 +1985,10 @@ static struct tevent_req *cli_session_setup_spnego_send( * and do not store results */ if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) { - const char *remote_name = smbXcli_conn_remote_name(cli->conn); char *tmp; - tmp = cli_session_setup_get_principal( - talloc_tos(), principal, remote_name, dest_realm); + talloc_tos(), principal, state->target_hostname, dest_realm); TALLOC_FREE(principal); principal = tmp; @@ -1974,8 +2024,11 @@ static struct tevent_req *cli_session_setup_spnego_send( #endif ntlmssp: - subreq = cli_session_setup_ntlmssp_send( - state, ev, cli, state->account, pass, user_domain); + subreq = cli_session_setup_gensec_send( + state, state->ev, state->cli, + state->account, state->pass, state->user_domain, + CRED_DONT_USE_KERBEROS, + "cifs", state->target_hostname, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2001,9 +2054,11 @@ static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq) return; } - subreq = cli_session_setup_ntlmssp_send( - state, state->ev, state->cli, state->account, state->pass, - state->user_domain); + subreq = cli_session_setup_gensec_send( + state, state->ev, state->cli, + state->account, state->pass, state->user_domain, + CRED_DONT_USE_KERBEROS, + "cifs", state->target_hostname, NULL); if (tevent_req_nomem(subreq, req)) { return; } @@ -2020,7 +2075,7 @@ static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq) req, struct cli_session_setup_spnego_state); NTSTATUS status; - status = cli_session_setup_ntlmssp_recv(subreq); + status = cli_session_setup_gensec_recv(subreq); TALLOC_FREE(subreq); state->result = ADS_ERROR_NT(status); tevent_req_done(req); -- 1.9.1 From 7f01c04ee0dd8c1f35b2f88c2a6624061959aca1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:35:21 +0100 Subject: [PATCH 190/440] s3:libsmb: call cli_state_remote_realm() within cli_session_setup_spnego_send() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 907e2b1f665cdafc863f4702ede5dcf16e6cc269) --- source3/libsmb/cliconnect.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6b1fc33..96084fb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1902,14 +1902,14 @@ static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq); static struct tevent_req *cli_session_setup_spnego_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *user, const char *pass, const char *user_domain, - const char *dest_realm) + const char *user, const char *pass, const char *user_domain) { struct tevent_req *req, *subreq; struct cli_session_setup_spnego_state *state; char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; int i; + const char *dest_realm = cli_state_remote_realm(cli); const DATA_BLOB *server_blob; NTSTATUS status; @@ -2189,10 +2189,8 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, } if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - const char *remote_realm = cli_state_remote_realm(cli); - subreq = cli_session_setup_spnego_send( - state, ev, cli, user, pass, workgroup, remote_realm); + state, ev, cli, user, pass, workgroup); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2252,10 +2250,8 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, /* if the server supports extended security then use SPNEGO */ if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) { - const char *remote_realm = cli_state_remote_realm(cli); - subreq = cli_session_setup_spnego_send( - state, ev, cli, user, pass, workgroup, remote_realm); + state, ev, cli, user, pass, workgroup); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } -- 1.9.1 From d96bbc3b7e949997bf9c1c508205894865b895d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:58:30 +0100 Subject: [PATCH 191/440] s3:libsmb: make use of cli_session_setup_gensec*() for Kerberos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0e1b2ebf884c6f2033b3b9aa7b6f72af54a716b2) --- source3/libsmb/cliconnect.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 96084fb..b8e0f7b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1288,7 +1288,7 @@ static void use_in_memory_ccache(void) { /**************************************************************************** Do a spnego/kerberos encrypted session setup. ****************************************************************************/ - +#if 0 struct cli_session_setup_kerberos_state { struct cli_state *cli; DATA_BLOB negTokenTarg; @@ -1409,7 +1409,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) } return state->ads_status; } - +#endif #endif /* HAVE_KRB5 */ /**************************************************************************** @@ -2010,8 +2010,11 @@ static struct tevent_req *cli_session_setup_spnego_send( } if (principal) { - subreq = cli_session_setup_kerberos_send( - state, ev, cli, principal); + subreq = cli_session_setup_gensec_send( + state, ev, cli, + state->account, pass, user_domain, + CRED_MUST_USE_KERBEROS, + "cifs", state->target_hostname, principal); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2044,9 +2047,11 @@ static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq) subreq, struct tevent_req); struct cli_session_setup_spnego_state *state = tevent_req_data( req, struct cli_session_setup_spnego_state); + NTSTATUS status; - state->result = cli_session_setup_kerberos_recv(subreq); + status = cli_session_setup_gensec_recv(subreq); TALLOC_FREE(subreq); + state->result = ADS_ERROR_NT(status); if (ADS_ERR_OK(state->result) || !state->cli->fallback_after_kerberos) { -- 1.9.1 From 489ccf90d3e6f692e8b4f9ac2af21317dfe7efa5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:16 +0100 Subject: [PATCH 192/440] s3:libsmb: remove unused cli_session_setup_kerberos*() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit 95b953950d1fd454121ff23a43a8b13a34385ef1) --- source3/libsmb/cliconnect.c | 125 -------------------------------------------- 1 file changed, 125 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b8e0f7b..c116d73 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1285,131 +1285,6 @@ static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } -/**************************************************************************** - Do a spnego/kerberos encrypted session setup. -****************************************************************************/ -#if 0 -struct cli_session_setup_kerberos_state { - struct cli_state *cli; - DATA_BLOB negTokenTarg; - DATA_BLOB session_key_krb5; - ADS_STATUS ads_status; -}; - -static void cli_session_setup_kerberos_done(struct tevent_req *subreq); - -static struct tevent_req *cli_session_setup_kerberos_send( - TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *principal) -{ - struct tevent_req *req, *subreq; - struct cli_session_setup_kerberos_state *state; - int rc; - - DEBUG(2,("Doing kerberos session setup\n")); - - req = tevent_req_create(mem_ctx, &state, - struct cli_session_setup_kerberos_state); - if (req == NULL) { - return NULL; - } - state->cli = cli; - state->ads_status = ADS_SUCCESS; - - /* - * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if - * we have to acquire a ticket. To be fixed later :-) - */ - rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg, - &state->session_key_krb5, 0, NULL, NULL); - if (rc) { - DEBUG(1, ("cli_session_setup_kerberos: " - "spnego_gen_krb5_negTokenInit failed: %s\n", - error_message(rc))); - state->ads_status = ADS_ERROR_KRB5(rc); - tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); - return tevent_req_post(req, ev); - } - -#if 0 - file_save("negTokenTarg.dat", state->negTokenTarg.data, - state->negTokenTarg.length); -#endif - - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - state->cli->smb2.session = smbXcli_session_create(cli, - cli->conn); - if (tevent_req_nomem(state->cli->smb2.session, req)) { - return tevent_req_post(req, ev); - } - } - - subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req); - return req; -} - -static void cli_session_setup_kerberos_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_session_setup_kerberos_state *state = tevent_req_data( - req, struct cli_session_setup_kerberos_state); - uint8_t *inbuf = NULL; - struct iovec *recv_iov = NULL; - NTSTATUS status; - - status = cli_sesssetup_blob_recv(subreq, state, - NULL, &inbuf, &recv_iov); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - - if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { - struct smbXcli_session *session = state->cli->smb2.session; - status = smb2cli_session_set_session_key(session, - state->session_key_krb5, - recv_iov); - if (tevent_req_nterror(req, status)) { - return; - } - } else { - struct smbXcli_session *session = state->cli->smb1.session; - - status = smb1cli_session_set_session_key(session, - state->session_key_krb5); - if (tevent_req_nterror(req, status)) { - return; - } - - if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5, - data_blob_null) - && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - - tevent_req_done(req); -} - -static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) -{ - struct cli_session_setup_kerberos_state *state = tevent_req_data( - req, struct cli_session_setup_kerberos_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return ADS_ERROR_NT(status); - } - return state->ads_status; -} -#endif #endif /* HAVE_KRB5 */ /**************************************************************************** -- 1.9.1 From 6d1d996c9af99317a636fc69d1e9cc4e2092027c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:41 +0100 Subject: [PATCH 193/440] s3:libsmb: remove unused functions in clispnego.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit 14335018229801dd6d2b18f8d19ab5b45b8394fc) --- source3/include/proto.h | 19 --- source3/libsmb/clispnego.c | 282 --------------------------------------------- 2 files changed, 301 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index a34ccff..2236af9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -732,13 +732,6 @@ bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx, struct in_addr **pservers, int *pnum_servers); unsigned wins_srv_count_tag(const char *tag); -/* The following definitions come from libsmb/clispnego.c */ - -DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, - const char *OIDs[], - DATA_BLOB *psecblob, - const char *principal); - #ifndef ASN1_MAX_OIDS #define ASN1_MAX_OIDS 20 #endif @@ -748,18 +741,6 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, char **principal, DATA_BLOB *secblob); DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2]); -int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, - const char *principal, int time_offset, - DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, - const char *ccname, time_t *expire_time); -bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, - DATA_BLOB *chal1, DATA_BLOB *chal2); -DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob); -bool spnego_parse_auth_response(TALLOC_CTX *ctx, - DATA_BLOB blob, NTSTATUS nt_status, - const char *mechOID, - DATA_BLOB *auth); /* The following definitions come from libsmb/conncache.c */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 320da41..959eaa4 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -26,81 +26,6 @@ #include "../lib/util/asn1.h" /* - generate a negTokenInit packet given a list of supported - OIDs (the mechanisms) a blob, and a principal name string -*/ - -DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, - const char *OIDs[], - DATA_BLOB *psecblob, - const char *principal) -{ - int i; - ASN1_DATA *data; - DATA_BLOB ret = data_blob_null; - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return data_blob_null; - } - - if (!asn1_push_tag(data,ASN1_APPLICATION(0))) goto err; - if (!asn1_write_OID(data,OID_SPNEGO)) goto err; - if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err; - - if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err; - for (i=0; OIDs[i]; i++) { - if (!asn1_write_OID(data,OIDs[i])) goto err; - } - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (psecblob && psecblob->length && psecblob->data) { - if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err; - if (!asn1_write_OctetString(data,psecblob->data, - psecblob->length)) goto err; - if (!asn1_pop_tag(data)) goto err; - } - - if (principal) { - if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err; - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err; - if (!asn1_write_GeneralString(data,principal)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - } - - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_extract_blob(data, ctx, &ret)) { - goto err; - } - - asn1_free(data); - data = NULL; - - err: - - if (data != NULL) { - if (asn1_has_error(data)) { - DEBUG(1, ("Failed to build negTokenInit at offset %d\n", - (int)asn1_current_ofs(data))); - } - - asn1_free(data); - } - - return ret; -} - -/* parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ @@ -278,210 +203,3 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui return ret; } - -/* - generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY - kerberos session setup -*/ -int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, - const char *principal, int time_offset, - DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, - const char *ccname, time_t *expire_time) -{ - int retval; - DATA_BLOB tkt, tkt_wrapped; - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - - /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(ctx, principal, time_offset, - &tkt, session_key_krb5, - extra_ap_opts, ccname, - expire_time, NULL); - if (retval) { - return retval; - } - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ); - - /* and wrap that in a shiny SPNEGO wrapper */ - *targ = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL); - - data_blob_free(&tkt_wrapped); - data_blob_free(&tkt); - - return retval; -} - - -/* - parse a spnego NTLMSSP challenge packet giving two security blobs -*/ -bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - bool ret = false; - ASN1_DATA *data; - - ZERO_STRUCTP(chal1); - ZERO_STRUCTP(chal2); - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return false; - } - - if (!asn1_load(data, blob)) goto err; - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_check_enumerated(data,1)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_check_OID(data, OID_NTLMSSP)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; - if (!asn1_read_OctetString(data, ctx, chal1)) goto err; - if (!asn1_end_tag(data)) goto err; - - /* the second challenge is optional (XP doesn't send it) */ - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err; - if (!asn1_read_OctetString(data, ctx, chal2)) goto err; - if (!asn1_end_tag(data)) goto err; - } - - if (!asn1_end_tag(data)) goto err; - if (!asn1_end_tag(data)) goto err; - - ret = !asn1_has_error(data); - - err: - - if (asn1_has_error(data)) { - data_blob_free(chal1); - data_blob_free(chal2); - } - - asn1_free(data); - return ret; -} - - -/* - generate a SPNEGO auth packet. This will contain the encrypted passwords -*/ -DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob) -{ - ASN1_DATA *data; - DATA_BLOB ret = data_blob_null; - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return data_blob_null; - } - - if (!asn1_push_tag(data, ASN1_CONTEXT(1))) goto err; - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err; - if (!asn1_write_OctetString(data,blob.data,blob.length)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_extract_blob(data, ctx, &ret)) { - goto err; - } - - err: - - asn1_free(data); - - return ret; -} - -/* - parse a SPNEGO auth packet. This contains the encrypted passwords -*/ -bool spnego_parse_auth_response(TALLOC_CTX *ctx, - DATA_BLOB blob, NTSTATUS nt_status, - const char *mechOID, - DATA_BLOB *auth) -{ - ASN1_DATA *data; - uint8 negResult; - bool ret = false; - - if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_ACCEPT_COMPLETED; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_ACCEPT_INCOMPLETE; - } else { - negResult = SPNEGO_REJECT; - } - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return false; - } - - *auth = data_blob_null; - - if (!asn1_load(data, blob)) goto err; - if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err; - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto err; - if (!asn1_check_enumerated(data, negResult)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_check_OID(data, mechOID)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; - if (!asn1_read_OctetString(data, ctx, auth)) goto err; - if (!asn1_end_tag(data)) goto err; - } - } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) { - asn1_set_error(data); - goto err; - } - - /* Binding against Win2K DC returns a duplicate of the responseToken in - * the optional mechListMIC field. This is a bug in Win2K. We ignore - * this field if it exists. Win2K8 may return a proper mechListMIC at - * which point we need to implement the integrity checking. */ - if (asn1_tag_remaining(data) > 0) { - DATA_BLOB mechList = data_blob_null; - if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err; - if (!asn1_read_OctetString(data, ctx, &mechList)) goto err; - data_blob_free(&mechList); - if (!asn1_end_tag(data)) goto err; - DEBUG(5,("spnego_parse_auth_response received mechListMIC, " - "ignoring.\n")); - } - - if (!asn1_end_tag(data)) goto err; - if (!asn1_end_tag(data)) goto err; - - ret = !asn1_has_error(data); - - err: - - if (asn1_has_error(data)) { - DEBUG(3, ("spnego_parse_auth_response failed at %d\n", - (int)asn1_current_ofs(data))); - asn1_free(data); - data_blob_free(auth); - return false; - } - - asn1_free(data); - return ret; -} -- 1.9.1 From fa9c900377ed3c53cd0d74323976284d76a96340 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Dec 2015 08:55:03 +0100 Subject: [PATCH 194/440] s4:torture/rpc: do testjoin only via ncalrpc or ncacn_np MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ncacn_ip_tcp doesn't have the required session key. It used to be the wellknown "SystemLibraryDTC" constant, but that's not available in modern systems anymore. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0400f301e3bcf495748cff009755426a040596fa) --- source4/torture/rpc/testjoin.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 5ee2c2a..7fbf301 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -503,10 +503,36 @@ _PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx, struct test_join *tj; struct samr_SetUserInfo s; union samr_UserInfo u; - + const char *binding_str = NULL; + struct dcerpc_binding *binding = NULL; + enum dcerpc_transport_t transport; + tj = talloc_zero(tctx, struct test_join); if (!tj) return NULL; + binding_str = torture_setting_string(tctx, "binding", NULL); + if (binding_str == NULL) { + const char *host = torture_setting_string(tctx, "host", NULL); + binding_str = talloc_asprintf(tj, "ncacn_np:%s", host); + } + status = dcerpc_parse_binding(tj, binding_str, &binding); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("dcerpc_parse_binding(%s) failed - %s\n", + binding_str, nt_errstr(status))); + talloc_free(tj); + return NULL; + } + transport = dcerpc_binding_get_transport(binding); + switch (transport) { + case NCALRPC: + case NCACN_UNIX_STREAM: + break; + default: + dcerpc_binding_set_transport(binding, NCACN_NP); + dcerpc_binding_set_flags(binding, 0, DCERPC_AUTH_OPTIONS); + break; + } + libnet_r = talloc_zero(tj, struct libnet_JoinDomain); if (!libnet_r) { talloc_free(tj); @@ -522,9 +548,10 @@ _PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx, tj->libnet_r = libnet_r; libnet_ctx->cred = cmdline_credentials; - libnet_r->in.binding = torture_setting_string(tctx, "binding", NULL); - if (!libnet_r->in.binding) { - libnet_r->in.binding = talloc_asprintf(libnet_r, "ncacn_np:%s", torture_setting_string(tctx, "host", NULL)); + libnet_r->in.binding = dcerpc_binding_string(libnet_r, binding); + if (libnet_r->in.binding == NULL) { + talloc_free(tj); + return NULL; } libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED; libnet_r->in.netbios_name = machine_name; -- 1.9.1 From 8a08ff785fcbe116246e9445750d27198c9574b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Feb 2016 07:47:39 +0100 Subject: [PATCH 195/440] s4:torture: the backupkey tests need to use ncacn_np: for LSA calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit c793b23ddb7c048110bc4718574e5b99d5bbcfae) --- source4/torture/rpc/backupkey.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/source4/torture/rpc/backupkey.c b/source4/torture/rpc/backupkey.c index 1a57bd2..119b1d6 100644 --- a/source4/torture/rpc/backupkey.c +++ b/source4/torture/rpc/backupkey.c @@ -1542,8 +1542,10 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, struct bkrp_server_side_wrapped *server_side_wrapped, enum test_wrong wrong) { - struct dcerpc_pipe *lsa_p; - struct dcerpc_binding_handle *lsa_b; + char *lsa_binding_string = NULL; + struct dcerpc_binding *lsa_binding = NULL; + struct dcerpc_pipe *lsa_p = NULL; + struct dcerpc_binding_handle *lsa_b = NULL; struct lsa_OpenSecret r_secret; struct lsa_QuerySecret r_query_secret; struct policy_handle *handle, sec_handle; @@ -1568,9 +1570,20 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, ZERO_STRUCT(r_query_secret); /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */ - + + /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */ + lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s", + torture_setting_string(tctx, "host", NULL)); + torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string"); + + torture_assert_ntstatus_ok(tctx, + dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding), + "Failed to parse dcerpc binding"); + torture_assert_ntstatus_ok(tctx, - torture_rpc_connection(tctx, &lsa_p, &ndr_table_lsarpc), + dcerpc_pipe_connect_b(tctx, &lsa_p, + lsa_binding, &ndr_table_lsarpc, + cmdline_credentials, tctx->ev, tctx->lp_ctx), "Opening LSA pipe"); lsa_b = lsa_p->binding_handle; -- 1.9.1 From 4c7a96232626ba5e8f4de178da686231451e8ecc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 20:18:42 +0100 Subject: [PATCH 196/440] s4:selftest: run rpc.samr over ncacn_np instead of ncacn_ip_tcp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It requires a transport session key, which is only reliable available over SMB. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit f699eb3b1a0660ace3ca99d3f3b5d79ed5537c80) --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index deda384..c1d2b79 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -89,8 +89,8 @@ ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.alt ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests -slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] -slow_ncacn_ip_tcp_tests = ["rpc.samr", "rpc.cracknames"] +slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] +slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] all_rpc_tests = ncalrpc_tests + ncacn_np_tests + ncacn_ip_tcp_tests + slow_ncacn_np_tests + slow_ncacn_ip_tcp_tests + ["rpc.lsa.secrets", "rpc.pac", "rpc.samba3-sharesec", "rpc.countcalls"] -- 1.9.1 From d18617da4a287a61f05ff1c307784aad049f4e2b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 22:44:24 +0100 Subject: [PATCH 197/440] s4:torture:samba3rpc: use an authenticated SMB connection and an anonymous DCERPC connection on top MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the only way to get a reliable transport session key. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit af8c4ebf9be314ddd13ef9ca17a0237927dd2ede) --- source4/torture/rpc/samba3rpc.c | 55 ++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 6f5477f..dd4c45c 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1318,7 +1318,6 @@ static bool torture_netlogon_samba3(struct torture_context *torture) { NTSTATUS status; struct smbcli_state *cli; - struct cli_credentials *anon_creds; struct cli_credentials *wks_creds; const char *wks_name; int i; @@ -1330,10 +1329,6 @@ static bool torture_netlogon_samba3(struct torture_context *torture) wks_name = get_myname(torture); } - if (!(anon_creds = cli_credentials_init_anon(torture))) { - torture_fail(torture, "create_anon_creds failed\n"); - } - lpcfg_smbcli_options(torture->lp_ctx, &options); lpcfg_smbcli_session_options(torture->lp_ctx, &session_options); @@ -1342,7 +1337,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) lpcfg_smb_ports(torture->lp_ctx), "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), - anon_creds, + cmdline_credentials, lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); @@ -1362,7 +1357,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) CRED_SPECIFIED); torture_assert(torture, - join3(torture, cli, false, cmdline_credentials, wks_creds), + join3(torture, cli, false, NULL, wks_creds), "join failed"); cli_credentials_set_domain( @@ -1389,7 +1384,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) } torture_assert(torture, - leave(torture, cli, cmdline_credentials, wks_creds), + leave(torture, cli, NULL, wks_creds), "leave failed"); return true; @@ -1488,26 +1483,14 @@ static bool torture_samba3_sessionkey(struct torture_context *torture) } torture_assert(torture, - test_join3(torture, false, anon_creds, cmdline_credentials, wks_name), - "join using ntlmssp bind on an anonymous smb connection failed"); - - torture_assert(torture, test_join3(torture, false, cmdline_credentials, NULL, wks_name), "join using anonymous bind on an authenticated smb connection failed"); - torture_assert(torture, - test_join3(torture, false, cmdline_credentials, cmdline_credentials, wks_name), - "join using ntlmssp bind on an authenticated smb connection failed"); - /* * The following two are tests for setuserinfolevel 25 */ torture_assert(torture, - test_join3(torture, true, anon_creds, cmdline_credentials, wks_name), - "join using ntlmssp bind on an anonymous smb connection failed"); - - torture_assert(torture, test_join3(torture, true, cmdline_credentials, NULL, wks_name), "join using anonymous bind on an authenticated smb connection failed"); @@ -1792,20 +1775,6 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) lpcfg_smbcli_options(torture->lp_ctx, &options); lpcfg_smbcli_session_options(torture->lp_ctx, &session_options); - status = smbcli_full_connection( - torture, &cli, torture_setting_string(torture, "host", NULL), - lpcfg_smb_ports(torture->lp_ctx), - "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), cmdline_credentials, - lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, - &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); - torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n"); - - if (!(user_sid = whoami(torture, torture, cli->tree))) { - torture_fail(torture, "whoami on auth'ed connection failed\n"); - } - - talloc_free(cli); - if (!(anon_creds = cli_credentials_init_anon(torture))) { torture_fail(torture, "create_anon_creds failed\n"); } @@ -1826,6 +1795,20 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) torture_assert_sid_equal(torture, user_sid, dom_sid_parse_talloc(torture, "s-1-5-7"), "Anon lsa_GetUserName returned unexpected SID"); + talloc_free(cli); + + status = smbcli_full_connection( + torture, &cli, torture_setting_string(torture, "host", NULL), + lpcfg_smb_ports(torture->lp_ctx), + "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), cmdline_credentials, + lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, + &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); + torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n"); + + if (!(user_sid = whoami(torture, torture, cli->tree))) { + torture_fail(torture, "whoami on auth'ed connection failed\n"); + } + if (!(user_creds = cli_credentials_init(torture))) { torture_fail(torture, "cli_credentials_init failed\n"); } @@ -1837,7 +1820,7 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) generate_random_password(user_creds, 8, 255), CRED_SPECIFIED); - if (!create_user(torture, torture, cli, cmdline_credentials, + if (!create_user(torture, torture, cli, NULL, cli_credentials_get_username(user_creds), cli_credentials_get_password(user_creds), &domain_name, &created_sid)) { @@ -1892,7 +1875,7 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) del: if (!delete_user(torture, cli, - cmdline_credentials, + NULL, cli_credentials_get_username(user_creds))) { torture_fail(torture, "delete_user failed\n"); } -- 1.9.1 From 41ca89cf454b094a6ac20008461660ac358886c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 198/440] s4:librpc/rpc: dcerpc_generic_session_key() should only be available on local transports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (similar to commit 5a397216d40ff18fd1c0980cd9b7b7c0a970bbbb) --- selftest/knownfail | 4 ++++ source4/librpc/rpc/dcerpc_util.c | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 80649c9..ff9ea40 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -86,6 +86,9 @@ ^samba4.rpc.lsalookup with seal,padcheck ^samba4.rpc.lsalookup with validate ^samba4.rpc.lsalookup with bigendian +^samba4.rpc.lsa on ncacn_np with seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY +^samba4.rpc.lsa with seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY +^samba4.rpc.lsa.secrets.*seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY ^samba4.rpc.netlogon.*.LogonUasLogon ^samba4.rpc.netlogon.*.LogonUasLogoff ^samba4.rpc.netlogon.*.DatabaseSync @@ -215,6 +218,7 @@ ^samba3.smb2.replay.replay4 ^samba3.smb2.lock.*replay ^samba3.raw.session.*reauth2 # maybe fix this? +^samba3.rpc.lsa.secrets.seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY ^samba3.rpc.samr.passwords.badpwdcount.samr.badPwdCount\(s3dc\) # We fail this test currently ^samba3.rpc.samr.passwords.lockout.*\(s3dc\)$ # We fail this test currently ^samba3.rpc.spoolss.printer.addprinter.driver_info_winreg # knownfail or flapping? diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index de960b2..95d600a34 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -760,6 +760,16 @@ _PUBLIC_ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx, NTSTATUS dcerpc_generic_session_key(struct dcecli_connection *c, DATA_BLOB *session_key) { + *session_key = data_blob_null; + + if (c != NULL) { + if (c->transport.transport != NCALRPC && + c->transport.transport != NCACN_UNIX_STREAM) + { + return NT_STATUS_LOCAL_USER_SESSION_KEY; + } + } + /* this took quite a few CPU cycles to find ... */ session_key->data = discard_const_p(unsigned char, "SystemLibraryDTC"); session_key->length = 16; -- 1.9.1 From 2e299f2b5f8889281887c4289f3059aca78813e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Feb 2016 16:41:10 +0100 Subject: [PATCH 199/440] s4:rpc_server/samr: hide a possible NO_USER_SESSION_KEY error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows servers doesn't return the raw NT_STATUS_NO_USER_SESSION_KEY error, but return WRONG_PASSWORD or even hide the error by using a random session key, that results in an invalid, unknown, random NTHASH. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 58b33896b65c5b51486eaf01f5f935ace2369fd0) --- source4/rpc_server/samr/samr_password.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 1466dec..f053dad 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -419,7 +419,10 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + DEBUG(3,("samr: failed to get session key: %s " + "=> NT_STATUS_WRONG_PASSWORD\n", + nt_errstr(nt_status))); + return NT_STATUS_WRONG_PASSWORD; } arcfour_crypt_blob(pwbuf->data, 516, &session_key); @@ -458,7 +461,10 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + DEBUG(3,("samr: failed to get session key: %s " + "=> NT_STATUS_WRONG_PASSWORD\n", + nt_errstr(nt_status))); + return NT_STATUS_WRONG_PASSWORD; } co_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -500,11 +506,26 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, const uint8_t *nt_pwd_hash) { struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL; + uint8_t random_session_key[16] = { 0, }; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB in, out; NTSTATUS nt_status = NT_STATUS_OK; nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) { + DEBUG(3,("samr: failed to get session key: %s " + "=> use a random session key\n", + nt_errstr(nt_status))); + + /* + * Windows just uses a random key + */ + generate_random_buffer(random_session_key, + sizeof(random_session_key)); + session_key = data_blob_const(random_session_key, + sizeof(random_session_key)); + nt_status = NT_STATUS_OK; + } if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- 1.9.1 From 923fbe337edb56a140307b474e0302fd7d0b29e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 200/440] s4:rpc_server: dcesrv_generic_session_key should only work on local transports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches modern Windows servers. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Mar 10 10:15:21 CET 2016 on sn-devel-144 (cherry picked from commit 645e777b0aca7d997867e0b3f0b48bfb138cc25c) --- source4/rpc_server/common/reply.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 007b680..8e56e1e 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -259,5 +259,12 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *c, DATA_BLOB *session_key) { + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(c->endpoint->ep_description); + + if (transport != NCALRPC && transport != NCACN_UNIX_STREAM) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + return dcerpc_generic_session_key(NULL, session_key); } -- 1.9.1 From f2ab3f04c150d2f46c87648c8bdd630b30f6750f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 16 Jan 2016 13:57:47 +0100 Subject: [PATCH 201/440] selftest: s!plugindc.samba.example.com!plugindom.samba.example.com! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's confusing to have plugindc.samba.example.com as domain name and plugindc.plugindc.samba.example.com as hostname. We now have plugindom.samba.example.com as domain name and plugindc.plugindom.samba.example.com as hostname. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit c561a42ff68bc4561147839e3a65951924f6af21) --- selftest/target/Samba4.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index ab31248..23f70a6 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1615,7 +1615,7 @@ sub provision_plugin_s4_dc($$) "domain controller", "plugindc", "PLUGINDOMAIN", - "plugindc.samba.example.com", + "plugindom.samba.example.com", "2008", "locDCpass1", undef, $extra_smbconf_options, -- 1.9.1 From 6cf0f48ce429c1bf8ef9d9da8d5c28ae939cf6fc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 202/440] selftest: add some helper scripts to mange a CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is partly based on the SmartCard HowTo from: https://wiki.samba.org/index.php/Samba_AD_Smart_Card_Login BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b0bdbeeef44259782c9941b5cfff7d4925e1f2f2) --- selftest/manage-ca/manage-ca.sh | 387 +++++++++++++++++++++ .../manage-CA-example.com.cnf | 17 + .../openssl-BASE-template.cnf | 201 +++++++++++ .../manage-ca.templates.d/openssl-CA-template.cnf | 2 + .../manage-ca.templates.d/openssl-DC-template.cnf | 49 +++ .../openssl-USER-template.cnf | 41 +++ 6 files changed, 697 insertions(+) create mode 100755 selftest/manage-ca/manage-ca.sh create mode 100644 selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf diff --git a/selftest/manage-ca/manage-ca.sh b/selftest/manage-ca/manage-ca.sh new file mode 100755 index 0000000..ab796b7 --- /dev/null +++ b/selftest/manage-ca/manage-ca.sh @@ -0,0 +1,387 @@ +#!/bin/bash +# + +set -e +set -u +#set -x + +umask 022 + +function print_usage() +{ + echo "Usage:" + echo "" + echo "${0} [ []]" + echo "" + echo "${0} init_ca" + echo "${0} update_crl" + echo "${0} publish_crl" + echo "${0} create_dc " + echo "${0} revoke_dc " + echo "${0} create_user " + echo "${0} revoke_user " + echo "" +} + +function check_arg() +{ + local k="${1}" + local v="${2}" + + test -n "${v}" || { + print_usage + echo "ERROR: CMD[${CMD}] argument <${k}> missing" + return 1 + } + + return 0 +} +CNF="${1-}" +test -n "${CNF}" || { + print_usage + echo "ERROR: speficy see manage-ca.templates.d/manage-CA-example.com.cnf" + exit 1 +} +test -e "${CNF}" || { + print_usage + echo "ERROR: CNF_FILE[${CNF}] does not exist" + exit 1 +} +CMD="${2-}" +CMDARG1="${3-}" +CMDARG2="${4-}" + +TEMPLATE_DIR="manage-ca.templates.d" +DEFAULT_VARS="" +DEFAULT_VARS="${DEFAULT_VARS} CRL_HTTP_BASE DNS_DOMAIN DEFAULT_BITS" +DEFAULT_VARS="${DEFAULT_VARS} DEFAULT_BITS DEFAULT_DAYS DEFAULT_CRL_DAYS" +DEFAULT_VARS="${DEFAULT_VARS} COUNTRY_NAME STATE_NAME LOCALITY_NAME ORGANIZATION_NAME" +DEFAULT_VARS="${DEFAULT_VARS} ORGANIZATIONAL_UNIT_NAME COMMON_NAME EMAIL_ADDRESS" + +source "${CNF}" + +DEFAULT_BITS=${DEFAULT_BITS:=8192} +CA_BITS=${CA_BITS:=${DEFAULT_BITS}} +DC_BITS=${DC_BITS:=${DEFAULT_BITS}} +USER_BITS=${USER_BITS:=${DEFAULT_BITS}} + +CA_DAYS=${CA_DAYS:=3650} +CRL_DAYS=${CRL_DAYS:=30} +DC_DAYS=${DC_DAYS:=730} +USER_DAYS=${USER_DAYS:=730} + +CA_DIR="CA-${DNS_DOMAIN}" +DEFAULT_VARS="${DEFAULT_VARS} CA_DIR" + +CACERT_PEM="${CA_DIR}/Public/CA-${DNS_DOMAIN}-cert.pem" +CACERT_CER="${CA_DIR}/Public/CA-${DNS_DOMAIN}-cert.cer" +CACRL_PEM="${CA_DIR}/Public/CA-${DNS_DOMAIN}-crl.pem" +CACRL_CRL="${CA_DIR}/Public/CA-${DNS_DOMAIN}-crl.crl" +CA_SERIAL="${CA_DIR}/Private/CA-${DNS_DOMAIN}-serial.txt" + +function generate_from_template() +{ + local base_template="${TEMPLATE_DIR}/$1" + local cmd_template="${TEMPLATE_DIR}/$2" + local cnf_file="$3" + shift 3 + local vars="$@" + + test -f "${base_template}" || { + echo "base_template[${base_template}] does not exists" + return 1 + } + test -f "${cmd_template}" || { + echo "cmd_template[${cmd_template}] does not exists" + return 1 + } + test -e "${cnf_file}" && { + echo "cnf_file[${cnf_file}] already exists" + return 1 + } + + local sedargs="" + for k in $vars; do + v=$(eval echo "\${${k}}") + sedargs="${sedargs} -e 's!@@${k}@@!${v}!g'" + done + + #echo "sedargs[${sedargs}]" + cat "${base_template}" "${cmd_template}" | eval sed ${sedargs} > "${cnf_file}" + grep '@@' "${cnf_file}" | wc -l | grep -q '^0' || { + echo "invalid context in cnf_file[${cnf_file}]" + grep '@@' "${cnf_file}" + return 1 + } + + return 0 +} + +case "${CMD}" in +init_ca) + test -e "${CA_DIR}" && { + echo "CA with CA_DIR[${CA_DIR}] already exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + CA_INDEX="${CA_DIR}/Private/CA-${DNS_DOMAIN}-index.txt" + CA_CRLNUMBER="${CA_DIR}/Private/CA-${DNS_DOMAIN}-crlnumber.txt" + PRIVATEKEY="${CA_DIR}/Private/CA-${DNS_DOMAIN}-private-key.pem" + + ORGANIZATIONAL_UNIT_NAME="CA Administration" + COMMON_NAME="CA of ${DNS_DOMAIN}" + EMAIL_ADDRESS="ca-${DNS_DOMAIN}@${DNS_DOMAIN}" + + DEFAULT_BITS="${CA_BITS}" + DEFAULT_DAYS="1" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + mkdir -p "${CA_DIR}/"{,Public} + umask 077 + mkdir -p "${CA_DIR}/"{,Private,NewCerts,DCs,Users} + umask 022 + touch "${CA_INDEX}" + echo "00" > "${CA_SERIAL}" + echo "00" > "${CA_CRLNUMBER}" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-CA-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} + openssl req -new -x509 -sha256 -extensions v3_ca -days "${CA_DAYS}" -keyout "${PRIVATEKEY}" -out "${CACERT_PEM}" -config "${OPENSSLCNF}" + openssl x509 -in "${CACERT_PEM}" -inform PEM -out "${CACERT_CER}" -outform DER + echo -n "Generate CRL [ENTER] to continue" + read + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CA_DIR}"/Public/CA-* + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +update_crl) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +publish_crl) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + + echo "Upload ${CACRL_CRL} to ${CRL_SSH_BASE}/" + rsync -a -P "${CACRL_CRL}" "${CRL_SSH_BASE}/" + echo "Check ${CRL_HTTP_BASE}/CA-${DNS_DOMAIN}-crl.crl" + exit 0 + ;; +create_dc) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + # + # + # ldbsearch -H ldap://DC_DNS_NAME '(dnsHostName=DC_DNS_NAME)' distinguishedName --controls=search_options:1:1 --controls=extended_dn:1:0 + DC_DNS_NAME="${CMDARG1}" + check_arg "DC_DNS_NAME" "${DC_DNS_NAME}" + DC_OBJECTGUID_HEX=$(echo "${CMDARG2}" | tr a-z A-Z) + check_arg "DC_OBJECTGUID_HEX" "${DC_OBJECTGUID_HEX}" + + DC_DIR="${CA_DIR}/DCs/${DC_DNS_NAME}" + test -e "${DC_DIR}" && { + echo "DC with DC_DIR[${DC_DIR}] already exists" + exit 1 + } + + NEXT_SERIAL=$(cat "${CA_SERIAL}" | xargs) + DCFILE_BASE="DC-${DC_DNS_NAME}-S${NEXT_SERIAL}" + OPENSSLCNF="${DC_DIR}/${DCFILE_BASE}-openssl.cnf" + DCKEY_PEM="${DC_DIR}/${DCFILE_BASE}-key.pem" + DCKEY_PRIVATE_PEM="${DC_DIR}/${DCFILE_BASE}-private-key.pem" + DCKEY_PRIVATE_PEM_BASE="${DCFILE_BASE}-private-key.pem" + DCKEY_PRIVATE_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-private-key.pem" + DCREQ_PEM="${DC_DIR}/${DCFILE_BASE}-req.pem" + DCCERT_PEM="${DC_DIR}/${DCFILE_BASE}-cert.pem" + DCCERT_PEM_BASE="${DCFILE_BASE}-cert.pem" + DCCERT_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-cert.pem" + DCCERT_CER="${DC_DIR}/${DCFILE_BASE}-cert.cer" + DCCERT_P12="${DC_DIR}/${DCFILE_BASE}-private.p12" + + ORGANIZATIONAL_UNIT_NAME="Domain Controllers" + COMMON_NAME="${DC_DNS_NAME}" + EMAIL_ADDRESS="ca-${DNS_DOMAIN}@${DNS_DOMAIN}" + + DEFAULT_BITS="${DC_BITS}" + DEFAULT_DAYS="${DC_DAYS}" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + umask 077 + mkdir -p "${DC_DIR}/" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-DC-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} DC_DNS_NAME DC_OBJECTGUID_HEX + + openssl req -new -newkey rsa -keyout "${DCKEY_PEM}" -out "${DCREQ_PEM}" -config "${OPENSSLCNF}" + openssl rsa -in "${DCKEY_PEM}" -inform PEM -out "${DCKEY_PRIVATE_PEM}" -outform PEM + openssl ca -config "${OPENSSLCNF}" -in "${DCREQ_PEM}" -out "${DCCERT_PEM}" + ln -s "${DCKEY_PRIVATE_PEM_BASE}" "${DCKEY_PRIVATE_PEM_LINK}" + ln -s "${DCCERT_PEM_BASE}" "${DCCERT_PEM_LINK}" + openssl x509 -in "${DCCERT_PEM}" -inform PEM -out "${DCCERT_CER}" -outform DER + echo "Generate ${DCCERT_P12}" + openssl pkcs12 -in "${DCCERT_PEM}" -inkey "${DCKEY_PRIVATE_PEM}" -export -out "${DCCERT_P12}" + ls -la "${DC_DIR}"/*.* + exit 0 + ;; +revoke_dc) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + DC_DNS_NAME="${CMDARG1}" + check_arg "DC_DNS_NAME" "${DC_DNS_NAME}" + REVOKE_REASON="${CMDARG2}" + check_arg "REVOKE_REASON" "${REVOKE_REASON}" + + DC_DIR="${CA_DIR}/DCs/${DC_DNS_NAME}" + test -e "${DC_DIR}" || { + echo "DC with DC_DIR[${DC_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + DCKEY_PRIVATE_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-private-key.pem" + DCCERT_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-cert.pem" + + REVOKE_DATE=$(date +%Y%m%d-%H%M%S) + REVOKE_DC_DIR="${DC_DIR}.${REVOKE_DATE}.revoked-${REVOKE_REASON}" + + openssl ca -config "${OPENSSLCNF}" -revoke "${DCCERT_PEM_LINK}" -crl_reason "${REVOKE_REASON}" + + mv "${DCKEY_PRIVATE_PEM_LINK}" "${DCKEY_PRIVATE_PEM_LINK}.revoked" + mv "${DCCERT_PEM_LINK}" "${DCCERT_PEM_LINK}.revoked" + mv "${DC_DIR}" "${REVOKE_DC_DIR}" + echo "${REVOKE_DC_DIR}" + + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +create_user) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + USER_PRINCIPAL_NAME="${CMDARG1}" + check_arg "USER_PRINCIPAL_NAME" "${USER_PRINCIPAL_NAME}" + + USER_DIR="${CA_DIR}/Users/${USER_PRINCIPAL_NAME}" + test -e "${USER_DIR}" && { + echo "USER with USER_DIR[${USER_DIR}] already exists" + exit 1 + } + + NEXT_SERIAL=$(cat "${CA_SERIAL}" | xargs) + USERFILE_BASE="USER-${USER_PRINCIPAL_NAME}-S${NEXT_SERIAL}" + OPENSSLCNF="${USER_DIR}/${USERFILE_BASE}-openssl.cnf" + USERKEY_PEM="${USER_DIR}/${USERFILE_BASE}-key.pem" + USERKEY_PRIVATE_PEM="${USER_DIR}/${USERFILE_BASE}-private-key.pem" + USERKEY_PRIVATE_PEM_BASE="${USERFILE_BASE}-private-key.pem" + USERKEY_PRIVATE_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-private-key.pem" + USERREQ_PEM="${USER_DIR}/${USERFILE_BASE}-req.pem" + USERCERT_PEM="${USER_DIR}/${USERFILE_BASE}-cert.pem" + USERCERT_PEM_BASE="${USERFILE_BASE}-cert.pem" + USERCERT_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-cert.pem" + USERCERT_CER="${USER_DIR}/${USERFILE_BASE}-cert.cer" + USERCERT_P12="${USER_DIR}/${USERFILE_BASE}-private.p12" + + ORGANIZATIONAL_UNIT_NAME="Users" + COMMON_NAME="${USER_PRINCIPAL_NAME}" + EMAIL_ADDRESS="${USER_PRINCIPAL_NAME}" + + DEFAULT_BITS="${USER_BITS}" + DEFAULT_DAYS="${USER_DAYS}" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + umask 077 + mkdir -p "${USER_DIR}/" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-USER-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} USER_PRINCIPAL_NAME + + openssl req -new -newkey rsa -keyout "${USERKEY_PEM}" -out "${USERREQ_PEM}" -config "${OPENSSLCNF}" + openssl rsa -in "${USERKEY_PEM}" -inform PEM -out "${USERKEY_PRIVATE_PEM}" -outform PEM + openssl ca -config "${OPENSSLCNF}" -in "${USERREQ_PEM}" -out "${USERCERT_PEM}" + ln -s "${USERKEY_PRIVATE_PEM_BASE}" "${USERKEY_PRIVATE_PEM_LINK}" + ln -s "${USERCERT_PEM_BASE}" "${USERCERT_PEM_LINK}" + openssl x509 -in "${USERCERT_PEM}" -inform PEM -out "${USERCERT_CER}" -outform DER + echo "Generate ${USERCERT_P12}" + openssl pkcs12 -in "${USERCERT_PEM}" -inkey "${USERKEY_PRIVATE_PEM}" -export -out "${USERCERT_P12}" + ls -la "${USER_DIR}"/*.* + exit 0 + ;; +revoke_user) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + USER_PRINCIPAL_NAME="${CMDARG1}" + check_arg "USER_PRINCIPAL_NAME" "${USER_PRINCIPAL_NAME}" + REVOKE_REASON="${CMDARG2}" + check_arg "REVOKE_REASON" "${REVOKE_REASON}" + + USER_DIR="${CA_DIR}/Users/${USER_PRINCIPAL_NAME}" + test -e "${USER_DIR}" || { + echo "USER with USER_DIR[${USER_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + USERKEY_PRIVATE_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-private-key.pem" + USERCERT_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-cert.pem" + + REVOKE_DATE=$(date +%Y%m%d-%H%M%S) + REVOKE_USER_DIR="${USER_DIR}.${REVOKE_DATE}.revoked-${REVOKE_REASON}" + + openssl ca -config "${OPENSSLCNF}" -revoke "${USERCERT_PEM_LINK}" -crl_reason "${REVOKE_REASON}" + + mv "${USERKEY_PRIVATE_PEM_LINK}" "${USERKEY_PRIVATE_PEM_LINK}.revoked" + mv "${USERCERT_PEM_LINK}" "${USERCERT_PEM_LINK}.revoked" + mv "${USER_DIR}" "${REVOKE_USER_DIR}.revoked" + echo "${REVOKE_USER_DIR}" + + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +usage) + print_usage + exit 1 + ;; +*) + print_usage + echo "ERROR: CMD[${CMD}] - unknown" + exit 1 + ;; +esac + +exit 1 diff --git a/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf b/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf new file mode 100644 index 0000000..1f3d24e --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf @@ -0,0 +1,17 @@ + +CRL_HTTP_BASE="http://www.example.com/crls" +CRL_SSH_BASE="www.example.com:/path/to/crls" +DNS_DOMAIN="example.com" + +#CA_BITS="8192" +#DC_BITS="8192" +#USER_BITS="8192" +#CA_DAYS="3650" +#CRL_DAYS="30" +#DC_DAYS="730" +#USER_DAYS="730" + +COUNTRY_NAME="US" +STATE_NAME="ExampleState" +LOCALITY_NAME="ExampleCity" +ORGANIZATION_NAME="ExampleOrganization" diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf new file mode 100644 index 0000000..ca8415b --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf @@ -0,0 +1,201 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = @@CRL_HTTP_BASE@@/CA-@@DNS_DOMAIN@@-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = @@CA_DIR@@ # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-@@DNS_DOMAIN@@-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-@@DNS_DOMAIN@@-cert.pem # The CA certificate +serial = $dir/Private/CA-@@DNS_DOMAIN@@-serial.txt # The current serial number +crlnumber = $dir/Private/CA-@@DNS_DOMAIN@@-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-@@DNS_DOMAIN@@-crl.pem # The current CRL +crl = $dir/Public/CA-@@DNS_DOMAIN@@-crl.crl # The current CRL +private_key = $dir/Private/CA-@@DNS_DOMAIN@@-private-key.pem # The private key +RANDFILE = $dir/Private/CA-@@DNS_DOMAIN@@.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = @@DEFAULT_DAYS@@ # how long to certify for +default_crl_days= @@DEFAULT_CRL_DAYS@@ # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = @@DEFAULT_BITS@@ +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = @@COUNTRY_NAME@@ +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = @@STATE_NAME@@ + +localityName = Locality Name (eg, city) +localityName_default = @@LOCALITY_NAME@@ + +organizationName = Organization Name (eg, company) +organizationName_default = @@ORGANIZATION_NAME@@ + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = @@ORGANIZATIONAL_UNIT_NAME@@ + +commonName = Common Name (eg, YOUR name) +commonName_default = @@COMMON_NAME@@ +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = @@EMAIL_ADDRESS@@ +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf new file mode 100644 index 0000000..4c6bb4a --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf @@ -0,0 +1,2 @@ +[ template_x509_extensions ] + diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf new file mode 100644 index 0000000..0b0424d --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf @@ -0,0 +1,49 @@ +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate @@DC_DNS_NAME@@" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=@@DC_DNS_NAME@@ +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:@@DC_OBJECTGUID_HEX@@ diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf new file mode 100644 index 0000000..71674b9 --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf @@ -0,0 +1,41 @@ +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for @@USER_PRINCIPAL_NAME@@" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:@@USER_PRINCIPAL_NAME@@ + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + -- 1.9.1 From 5df34c184d5c2d1fa99030a50ea1c2e948d3404e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:08:02 +0100 Subject: [PATCH 203/440] selftest: add config and script to create a samba.example.com CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit bdc1f036a8a66256afe8dc88f8a9dc47655640bd) --- selftest/manage-ca/manage-CA-samba.example.com.cnf | 21 +++++++++++++++++++++ selftest/manage-ca/manage-CA-samba.example.com.sh | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 selftest/manage-ca/manage-CA-samba.example.com.cnf create mode 100644 selftest/manage-ca/manage-CA-samba.example.com.sh diff --git a/selftest/manage-ca/manage-CA-samba.example.com.cnf b/selftest/manage-ca/manage-CA-samba.example.com.cnf new file mode 100644 index 0000000..65c9b95 --- /dev/null +++ b/selftest/manage-ca/manage-CA-samba.example.com.cnf @@ -0,0 +1,21 @@ +# +# All passwords are "1234" +# + +CRL_HTTP_BASE="http://www.samba.example.com/crls" +CRL_SSH_BASE="none@samba.example.com:/none/crls" +DNS_DOMAIN="samba.example.com" + +CA_BITS="8192" +DC_BITS="4096" +USER_BITS="2048" +# 20 years should be enough +CA_DAYS="7300" +CRL_DAYS="7300" +DC_DAYS="7300" +USER_DAYS="7300" + +COUNTRY_NAME="US" +STATE_NAME="SambaState" +LOCALITY_NAME="SambaCity" +ORGANIZATION_NAME="SambaSelfTesting" diff --git a/selftest/manage-ca/manage-CA-samba.example.com.sh b/selftest/manage-ca/manage-CA-samba.example.com.sh new file mode 100644 index 0000000..4a24039 --- /dev/null +++ b/selftest/manage-ca/manage-CA-samba.example.com.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# + +set -e +set -u +set -x + +# +# All passwords are "1234" +# + +./manage-ca.sh manage-CA-samba.example.com.cnf init_ca + +./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF +./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com + +./manage-ca.sh manage-CA-samba.example.com.cnf create_dc plugindc.plugindom.samba.example.com 0123456789ABCDEF +./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@plugindom.samba.example.com -- 1.9.1 From 0c2a656ecc0e98fe82188dc3c6bbff33c3b03d43 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:09:31 +0100 Subject: [PATCH 204/440] selftest: add CA-samba.example.com (non-binary) files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The binary files will follow in the next, this allows the next commit to be skipped as the binary files are not used by samba yet. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit 520c85a15fa1f4718e2e793303327abea22db149) --- .../DC-localdc.samba.example.com-S00-cert.pem | 190 ++++++++++++++++ .../DC-localdc.samba.example.com-S00-key.pem | 54 +++++ .../DC-localdc.samba.example.com-S00-openssl.cnf | 250 +++++++++++++++++++++ ...C-localdc.samba.example.com-S00-private-key.pem | 51 +++++ .../DC-localdc.samba.example.com-S00-req.pem | 30 +++ .../DC-localdc.samba.example.com-cert.pem | 1 + .../DC-localdc.samba.example.com-private-key.pem | 1 + ...ugindc.plugindom.samba.example.com-S02-cert.pem | 191 ++++++++++++++++ ...lugindc.plugindom.samba.example.com-S02-key.pem | 54 +++++ ...ndc.plugindom.samba.example.com-S02-openssl.cnf | 250 +++++++++++++++++++++ ...plugindom.samba.example.com-S02-private-key.pem | 51 +++++ ...lugindc.plugindom.samba.example.com-S02-req.pem | 30 +++ ...C-plugindc.plugindom.samba.example.com-cert.pem | 1 + ...ndc.plugindom.samba.example.com-private-key.pem | 1 + .../manage-ca/CA-samba.example.com/NewCerts/00.pem | 190 ++++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/01.pem | 169 ++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/02.pem | 191 ++++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/03.pem | 170 ++++++++++++++ .../Private/CA-samba.example.com-crlnumber.txt | 1 + .../Private/CA-samba.example.com-crlnumber.txt.old | 1 + .../Private/CA-samba.example.com-index.txt | 4 + .../Private/CA-samba.example.com-index.txt.attr | 1 + .../CA-samba.example.com-index.txt.attr.old | 1 + .../Private/CA-samba.example.com-index.txt.old | 3 + .../Private/CA-samba.example.com-openssl.cnf | 203 +++++++++++++++++ .../Private/CA-samba.example.com-private-key.pem | 102 +++++++++ .../Private/CA-samba.example.com-serial.txt | 1 + .../Private/CA-samba.example.com-serial.txt.old | 1 + .../Public/CA-samba.example.com-cert.pem | 62 +++++ .../Public/CA-samba.example.com-crl.pem | 32 +++ ...trator@plugindom.samba.example.com-S03-cert.pem | 170 ++++++++++++++ ...strator@plugindom.samba.example.com-S03-key.pem | 30 +++ ...tor@plugindom.samba.example.com-S03-openssl.cnf | 242 ++++++++++++++++++++ ...plugindom.samba.example.com-S03-private-key.pem | 27 +++ ...strator@plugindom.samba.example.com-S03-req.pem | 19 ++ ...inistrator@plugindom.samba.example.com-cert.pem | 1 + ...tor@plugindom.samba.example.com-private-key.pem | 1 + ...ER-administrator@samba.example.com-S01-cert.pem | 169 ++++++++++++++ ...SER-administrator@samba.example.com-S01-key.pem | 30 +++ ...administrator@samba.example.com-S01-openssl.cnf | 242 ++++++++++++++++++++ ...nistrator@samba.example.com-S01-private-key.pem | 27 +++ ...SER-administrator@samba.example.com-S01-req.pem | 19 ++ .../USER-administrator@samba.example.com-cert.pem | 1 + ...administrator@samba.example.com-private-key.pem | 1 + 44 files changed, 3266 insertions(+) create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem new file mode 100644 index 0000000..2a1f36f --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem @@ -0,0 +1,190 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:44:51 2016 GMT + Not After : Mar 13 11:44:51 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:e6:5f:4f:b7:ba:64:00:94:b2:0b:a0:29:3b:66: + 1f:28:85:cd:fa:bb:d7:de:18:8e:e2:4b:14:ab:33: + 17:4c:5f:8b:84:0e:b2:19:cd:32:ae:2a:8e:fc:8c: + 4b:51:c0:d9:2e:de:7f:d2:d3:7a:83:9d:95:66:6d: + e0:08:1a:25:10:2f:d3:27:bf:c7:ae:3a:f9:33:e4: + 65:87:af:a2:80:87:cc:f7:69:a3:4d:8d:65:30:81: + b3:20:ca:3f:54:28:b7:d9:1f:fe:90:92:8f:34:0b: + 0c:44:eb:48:b1:54:3e:66:29:c3:aa:e8:f4:f7:2d: + 6a:0c:cc:c2:31:f5:35:76:48:ba:82:c8:d0:06:42: + 2f:cd:4e:3f:20:b5:fc:f6:72:fc:0e:fe:92:a3:97: + 16:c7:9b:40:e4:ca:5c:47:39:bd:b1:4c:09:e3:a7: + 42:c2:0d:a8:b5:3e:f9:dc:7d:39:05:4d:c8:5f:c8: + 69:dc:85:5c:3c:9a:23:07:bc:30:33:38:a6:c4:03: + 07:59:e3:97:55:84:61:65:52:80:60:fa:77:b6:76: + 5a:31:32:51:a6:22:98:b5:ab:dc:67:51:23:76:08: + 09:8e:38:1c:75:0b:9c:59:43:1f:41:04:dd:60:69: + d9:fa:31:b8:16:5e:b8:f8:27:82:16:8e:c6:ce:d9: + 56:01:68:e4:5f:f8:2d:0f:31:85:27:37:92:fa:4d: + 0b:b3:f3:6a:f4:be:30:15:0d:8e:00:b5:87:f8:67: + 5c:ae:6a:25:59:23:8c:bf:a5:02:eb:b7:cc:0c:fc: + bc:3b:bd:80:08:fc:a3:86:5f:2d:ec:79:05:8e:e4: + d2:d2:c4:a6:ab:84:e3:da:aa:58:c3:db:8b:28:4b: + 15:49:79:7e:58:19:8b:7d:3e:87:9e:79:28:15:e1: + 8a:ad:75:10:0b:71:1e:8f:e8:1f:cd:d4:9b:11:e1: + 47:26:1a:f8:d4:a3:0b:7d:08:de:a6:f1:7a:93:26: + fb:bd:78:a3:60:8a:8b:29:fe:f8:9f:7b:5e:d7:64: + 03:e1:58:23:ac:23:35:3f:4f:b9:f7:3d:d6:d7:64: + 1f:0b:6b:11:9b:10:1f:2b:49:b2:f9:63:e8:cf:bf: + ac:da:9e:b7:f7:12:91:e4:01:77:9a:7f:31:c8:b6: + af:7d:5e:4e:55:ee:3d:2a:f9:0d:56:11:49:e3:f6: + 09:8c:2f:d0:06:eb:f4:f7:65:9f:db:85:0a:57:7e: + 9a:b8:1a:60:11:18:d1:3d:1c:c0:53:65:9b:e8:00: + 93:e4:91:61:b6:e8:7b:63:d3:d8:ec:70:8d:92:54: + 12:8b:56:1f:cf:83:34:d5:44:86:cd:b6:0b:fc:95: + 8f:f9:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate localdc.samba.example.com + X509v3 Subject Key Identifier: + CD:25:BC:9E:49:98:02:88:4F:A7:5C:4F:2D:68:B9:E3:61:9F:AE:2E + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + DNS:localdc.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 15:c0:31:31:7f:65:7c:7c:a4:db:1c:23:1b:81:bf:e8:c8:ad: + c0:2e:ce:c6:8e:3a:a2:d7:8f:ad:19:9a:e9:ea:72:bd:25:bc: + 26:3c:57:a7:53:4e:c5:24:a2:3c:70:59:48:9d:f5:df:2c:bd: + b5:b4:71:fe:a6:58:15:eb:31:86:83:c9:7a:39:47:80:f1:9d: + 31:ed:e1:5a:26:3f:9c:be:06:45:93:96:d9:3b:7d:d1:9c:b2: + ea:7b:a3:71:f0:9d:c7:a1:29:ba:38:eb:e4:be:bc:e9:9d:e8: + e1:be:eb:57:5a:1e:d1:09:58:dc:77:04:85:48:ba:94:19:73: + 8f:3a:31:6d:3c:ec:37:a6:d7:94:25:e3:98:e9:3c:f6:85:c6: + 6a:8e:d5:cd:32:05:1f:76:b7:b0:5a:c5:45:c0:81:20:16:4f: + e0:bb:e7:42:06:5c:6c:ff:e6:8a:73:7b:8c:1c:98:fe:2d:47: + 8a:e0:06:38:53:77:5b:6b:13:82:f4:a6:0b:c3:b2:88:2a:05: + 96:c8:04:66:cb:59:19:08:d4:9b:0f:1f:e3:3a:48:65:32:07: + 69:39:34:d4:a3:2e:d5:19:09:c7:07:d9:71:4d:62:81:fc:5a: + be:f1:da:65:3a:24:1e:2c:40:c8:78:4a:bb:0a:4f:a4:3d:ab: + 3c:b9:22:fb:0b:5c:9f:09:95:76:6f:6b:53:3d:1f:ee:fd:3f: + cd:be:7a:61:3e:08:3b:99:69:68:91:a9:9f:b8:4f:b8:c9:1f: + d4:ed:86:61:aa:6f:4f:a8:6a:4d:b6:79:e9:af:37:d2:83:9b: + f7:61:6a:65:f6:8c:f7:f9:3b:23:b6:cc:78:bf:16:ee:a0:50: + 1f:7e:38:7b:72:1b:62:ef:17:60:db:6f:c9:29:c1:c2:53:f7: + e8:27:de:3e:22:da:f0:5f:ba:55:9f:57:6f:b9:8f:c4:7a:c5: + 72:9a:a3:95:cc:ac:fd:f3:a6:a9:da:d6:57:d3:28:7f:72:60: + a8:5b:2f:c3:b1:07:c4:c7:af:d9:3c:a9:e9:78:e1:5a:0f:da: + c9:d0:e6:5d:9a:bd:61:ef:1d:25:7f:54:08:aa:f2:6c:11:1e: + a4:46:8e:9e:e2:79:c8:c2:dd:09:1b:62:27:e6:70:7a:e4:f3: + 66:db:57:30:ce:3f:27:f5:c6:c8:f2:3f:a1:bc:dd:ec:fe:3a: + c4:b9:ad:21:73:d8:83:a5:9f:02:ba:d0:52:8a:f2:d5:25:63: + 15:82:38:25:e2:74:ce:a6:a5:32:9a:6c:52:33:ba:45:ba:01: + 16:14:5f:ce:66:89:9e:03:ed:8a:95:80:c4:cf:20:24:d4:c5: + 5b:e5:c3:51:62:57:1e:45:be:0a:47:24:b7:cb:a4:dd:6e:54: + 2c:f4:25:80:a3:85:a9:74:0c:c0:65:c9:f8:2f:9a:22:bc:85: + c9:63:8a:08:f3:c9:1c:77:9b:a8:42:5a:45:dd:be:21:be:9d: + e7:15:9b:67:19:6c:d3:da:9b:67:a8:1d:22:35:d4:16:89:ad: + 4c:c3:17:bb:9e:f5:e5:3b:a2:a6:81:34:e0:4c:36:be:bb:e5: + a3:60:7d:28:30:82:db:99:ef:c6:19:43:d1:73:24:f0:8e:d1: + 6c:3b:cc:f8:cb:1a:14:79:67:07:ea:b5:47:08:bf:11:33:29: + 01:2e:fd:44:14:33:f6:36:65:8b:a8:f8:e6:0b:84:6d:a1:91: + 08:56:c1:5d:ca:12:b6:00:ba:9c:7e:7e:9b:26:3f:d3:dd:e1: + 2f:ae:f5:76:45:ed:a2:9b:b4:a1:a9:d6:b6:f5:7e:68:80:17: + 81:fb:ef:24:dc:84:de:38:20:45:34:6c:72:e5:d6:08:61:e7: + dd:45:43:d2:06:2b:ae:d9:73:a1:fb:bb:04:3c:61:45:d3:9e: + fc:45:c0:e3:db:02:ae:45:e3:de:d1:34:00:b0:1b:0f:ce:f8: + 33:0f:87:9c:9b:5d:49:11:7a:30:15:e3:9f:76:02:82:18:c2: + a6:dd:25:a6:e0:84:1f:1d:0d:db:81:7c:df:a1:65:9b:5b:08: + e0:4e:6d:4c:76:8a:0b:09:14:7c:e1:23:ad:18:4c:02:6b:e3: + f4:e0:22:26:e1:30:7e:a5:59:22:5b:a5:73:5a:23:24:1f:1a: + 7b:e5:46:f7:0c:14:00:53:72:33:4d:c4:c4:59:3e:04:17:33: + 34:04:67:1e:cd:a0:e5:9f:85:87:77:f6:dd:03:f0:74:cf:56: + e9:99:a8:95:3a:52:db:d1:61:72:91:60:9f:80:bf:22:26:da: + d7:09:4e:df:81:30:dc:9b:b4:c1:c7:cb:97:93:bc:b7:93:a3: + db:88:cc:5e:9f:39:94:57:a5:57:d6:cd:1b:12:a4:86:62:4f: + b2:08:22:4e:d9:07:8e:27:06:82:d9:f1:ec:70:30:82:56:0c: + f7:d9:56:bf:f1:7f:fd:65:90:8d:5e:d5:13:b3:31:89:5d:e8: + df:35:2f:77:6b:b7:c7:e8:7d:89:f8:cf:9e:a5:1c:60:be:7c: + 6c:b7:0f:fa:8e:62:8e:b0:72:10:8a:04:6a:50:83:3a:38:dc: + 13:8b:89:8f:6c:0f:fc:3e:c7:36:15:37:78:5f:24:87:8a:70: + cc:3e:5a:fc:88:78:19:70:89:65:a0:c7:47:67:f2:bc:1e:f5: + 04:e7:94:ba:74:ea:2a:a7:c1:26:b1:2e:ac:64:0b:fa +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ0NTFaFw0zNjAzMTMxMTQ0NTFaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOZfT7e6ZACUsgugKTtmHyiFzfq7194YjuJLFKszF0xfi4QOshnNMq4qjvyMS1HA +2S7ef9LTeoOdlWZt4AgaJRAv0ye/x646+TPkZYevooCHzPdpo02NZTCBsyDKP1Qo +t9kf/pCSjzQLDETrSLFUPmYpw6ro9PctagzMwjH1NXZIuoLI0AZCL81OPyC1/PZy +/A7+kqOXFsebQOTKXEc5vbFMCeOnQsINqLU++dx9OQVNyF/IadyFXDyaIwe8MDM4 +psQDB1njl1WEYWVSgGD6d7Z2WjEyUaYimLWr3GdRI3YICY44HHULnFlDH0EE3WBp +2foxuBZeuPgnghaOxs7ZVgFo5F/4LQ8xhSc3kvpNC7PzavS+MBUNjgC1h/hnXK5q +JVkjjL+lAuu3zAz8vDu9gAj8o4ZfLex5BY7k0tLEpquE49qqWMPbiyhLFUl5flgZ +i30+h555KBXhiq11EAtxHo/oH83UmxHhRyYa+NSjC30I3qbxepMm+714o2CKiyn+ ++J97XtdkA+FYI6wjNT9Pufc91tdkHwtrEZsQHytJsvlj6M+/rNqet/cSkeQBd5p/ +Mci2r31eTlXuPSr5DVYRSeP2CYwv0Abr9Pdln9uFCld+mrgaYBEY0T0cwFNlm+gA +k+SRYbboe2PT2OxwjZJUEotWH8+DNNVEhs22C/yVj/kRAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFM0lvJ5JmAKIT6dcTy1oueNhn64uMB8GA1UdIwQYMBaAFEaH +hsLnGc8WTAxiy3N//Y8Z5LVCMD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBABXAMTF/ZXx8pNscIxuBv+jI +rcAuzsaOOqLXj60Zmunqcr0lvCY8V6dTTsUkojxwWUid9d8svbW0cf6mWBXrMYaD +yXo5R4DxnTHt4VomP5y+BkWTltk7fdGcsup7o3HwncehKbo46+S+vOmd6OG+61da +HtEJWNx3BIVIupQZc486MW087Dem15Ql45jpPPaFxmqO1c0yBR92t7BaxUXAgSAW +T+C750IGXGz/5opze4wcmP4tR4rgBjhTd1trE4L0pgvDsogqBZbIBGbLWRkI1JsP +H+M6SGUyB2k5NNSjLtUZCccH2XFNYoH8Wr7x2mU6JB4sQMh4SrsKT6Q9qzy5IvsL +XJ8JlXZva1M9H+79P82+emE+CDuZaWiRqZ+4T7jJH9TthmGqb0+oak22eemvN9KD +m/dhamX2jPf5OyO2zHi/Fu6gUB9+OHtyG2LvF2Dbb8kpwcJT9+gn3j4i2vBfulWf +V2+5j8R6xXKao5XMrP3zpqna1lfTKH9yYKhbL8OxB8THr9k8qel44VoP2snQ5l2a +vWHvHSV/VAiq8mwRHqRGjp7iecjC3QkbYifmcHrk82bbVzDOPyf1xsjyP6G83ez+ +OsS5rSFz2IOlnwK60FKK8tUlYxWCOCXidM6mpTKabFIzukW6ARYUX85miZ4D7YqV +gMTPICTUxVvlw1FiVx5FvgpHJLfLpN1uVCz0JYCjhal0DMBlyfgvmiK8hcljigjz +yRx3m6hCWkXdviG+necVm2cZbNPam2eoHSI11BaJrUzDF7ue9eU7oqaBNOBMNr67 +5aNgfSgwgtuZ78YZQ9FzJPCO0Ww7zPjLGhR5ZwfqtUcIvxEzKQEu/UQUM/Y2ZYuo ++OYLhG2hkQhWwV3KErYAupx+fpsmP9Pd4S+u9XZF7aKbtKGp1rb1fmiAF4H77yTc +hN44IEU0bHLl1ghh591FQ9IGK67Zc6H7uwQ8YUXTnvxFwOPbAq5F497RNACwGw/O ++DMPh5ybXUkRejAV4592AoIYwqbdJabghB8dDduBfN+hZZtbCOBObUx2igsJFHzh +I60YTAJr4/TgIibhMH6lWSJbpXNaIyQfGnvlRvcMFABTcjNNxMRZPgQXMzQEZx7N +oOWfhYd39t0D8HTPVumZqJU6UtvRYXKRYJ+AvyIm2tcJTt+BMNybtMHHy5eTvLeT +o9uIzF6fOZRXpVfWzRsSpIZiT7IIIk7ZB44nBoLZ8exwMIJWDPfZVr/xf/1lkI1e +1ROzMYld6N81L3drt8fofYn4z56lHGC+fGy3D/qOYo6wchCKBGpQgzo43BOLiY9s +D/w+xzYVN3hfJIeKcMw+WvyIeBlwiWWgx0dn8rwe9QTnlLp06iqnwSaxLqxkC/o= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem new file mode 100644 index 0000000..0dec984 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIJljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI/ffRVypD9HkCAggA +MBQGCCqGSIb3DQMHBAjv05OkfOwFaQSCCVCbev4X3oUISTe03sWAz0bzijH5Wg7w +Vc9+SnYwt0pFZTaUw6MkvhFNUD+BEw0fePpCeBzf2DTVqCQ4RVY7ps3/DmTZQlWa +KDLbermsiT5n1dc22iYeA1zsHc/h020djrm+Eem5rcNGsxlfln3fRMVwSPEEBBnK +7k/8tM1SeXe/QmFtm3CRJ02dNzvr11xcYLDN9i2bVskqIFME/+Vi57/rdEAhyaBB +osJBhv+vvfoyTbZ8buRIxN2rUxkPp27jPqckyZoC9IWE6MXoyyaKYIvkscIIU6Xf +hj4K/FdozbD6TkCC84KfHqXgMy+CFN04yTt9fORl0L/3NHHJoMjXQsg26wSfbCFY +t9FK5QQlm0MqimsOaxCTEd1LivRw16KYLOva20t2/1aMpc8nBP4ROheugGhEOsCB +RwbvANTmg4E/uBWORDsDRu4OQN3XE/nzW3R7uokv4aGON8Ob6M7DExDIQCdsbGvB +8DdziETmvXAj6yGH0LfqaZhNXpj5uyuNVVt7ROoKYFIOdkUXPC1DFOcLRiClaM87 +8XU8Zy2l/tFh56jgWMzMcqoIlLxIpMMCZl5P533+5nQ2tQtdRynTpKuipdDIFu/r +JjMsTYgh8knG8C5qSXqNT0hu0yRleGNRVslTBnc7JqjMdqcZBS1Ut4asU7aVn6Fv +egGmgPXTsC8tnYy6lT+lam+jjdk65SHP+/HUNuyhVzmDKPXaUG/bdh4NmCHaxE4y +WjLTKMkEs/NBkGDxbqgw3HtatSBiK+JG1zUeaDomxbROjv8VYGGF1RXrp38KOqao +Tg6gEUzcktbEdcvm+q1Pkau2vPxRcnnOQSSmnqr+w0+kh9OawaZ5B+VMr5eV9mdZ +oj2yT0nw7+BFJq3zeaIt1ksSkqUaXLVspeJkBC/DbC/MyoOLdMgzHfkxc1/hq0WV +UoQtHI4lTk+3aWu4ZD47BrigLbeDOvvW/oMF6CdVZBghhsyhvmpWASQ1kiVN7k18 +A19iX5W33x9bjD+0392mSPo525BR24z5x8bTklLng0Kro84sXfRPHMXqIoCEDXz0 +z8QGJtdVdUi9wVLqcCyW+8U51ACTWnrxv0oTlRy7ESbj229Cj29o3qGdCXaU7XVz +g5WGtziVR1Lquql+hzCckwPLjm6olLyxZwk6d83KwMUckhvLeYXJ65/ZRRaE2R91 +2X0ir7Csk802NPjaV21No3/EJVuw57dZ9xxUUW8Q+OfCQAxKxdKfWcK3JjdNvZn4 +778E/kWg+KdhcQ1yb6MHZafrjnkwAp4qm3Kp936zL5a/nsTT2e0661pC/8FBxfNQ +H+CFLylW77vpVo/iFSeHzGmOEuUC7hsbqjX8y4x8czuY1sCNA0Ty3tf5gOVhemuP +xgfJRQF/bUAnlWnCb83peSYq5SUQq1LTtkKGghXCgV1d3MzryAoOr6znZTcE0CSG +GDUk7vzaZmzKp8TySAFUcuo6Ve297yi9A+dGNsuOyqmFwS7pjrwYI9HPj2BKu7Gw +Ns/aPs9lJhGR7tjpqyX2Ok4OQBBcwdP3OfjdCQdwdjAjVXlj5BeNiSQ7HiRECYza +kGzvwuO+10DXTSwcLhakNZZtONFpuMU5JoSCcICUaJ+4AAqJdfO13TiOYHRLN9VC +2h2/4wGPcvLdYg9ByiE5wt5bysGl0jOtmTA5boK6TD1qF5fD8+WNd7VPDmFS/uUo +65JXn63Q8A8MC7sQNLOsyoFkXOVr5uLNdZMzbcOqre9h3y1GCucXRAhQ4eOefJPA +2u/vFk0opk8dMq0FA9LH4zbvhpTBytHdcnkwlsCmv8XO7j544gSbrUNKMqSkY2DT +R37qxq6iCzaSkNnpxLH8kY5KydCnxqxLhbECbNqdIIajxPgctCbzKJrOe/I9CUzu +qsXY8+ZVRD2wBOnP8p9oWq0pbilmgNquQD5/maO0Rm09A6Eg4vvki/PJxBC9KRfv +VXmgk4LsmAPxh/anJFJlK36LRUNosmBFSOZ+NnCMAhEGjH+5VER4hWmWxr4znLfD +QsIh+uui2fZWr8dBmpArzGyq7C3sB4sIXqacaExu+ed8f/tvU414Y1b75XaIMGX/ +CcSDf/NgGw1+Ucf0hp7nHU6/u7dhuwvrw8LLhXhuGU9al7vVP8n8aEwzNPo1OAnd +0DcPWGFaFGQlSWL6oOXDsE2KVkI82+2XJZopLL2Envh5ntct0a49DHIi4TP+aVbT +Q37EU2SvNYvJk0h8dUibrM/hd5UZ8PKWgIamOjhhi+0mTON2sW9Jitr3NSFRw6sn +NOC9p5kH2R5TGH8r34RbfEU6Zy3bSukuW/63FknS8VLWu0AWfzqNRTIZj8xfoaGd +MsNTsgTdXHt/9pgbtMRU/EDs9ZfNmbLM1uw5Kfp7garX4TuZefgPAWHzoZM4zD71 +xe6aVOTiPatdDceFuynFdijK3RljO25CgOURQe0OYNNOJIrXGtkmC2szD3LTqW/x +wn51DiIijGQLrFIzrflw/V7is5VpujyU5dn8/Wk6OTbhoVctmlhOyKVvM/fo2m/g +q4pSD4TvLWgJW+aU3XZTw55P0hV9zYzienmWc6Ny1zen+829pm6gbYW9N/qsU5CB +W5h4+rBgp9htUVeeu2mKiaZW9V5Y2IN7frKwZxUQPe3FMS3TEfEjBAqcdJHGPZEZ +tqFB4CiW7F0w0Tt30ATdoPIbnK/RQa025JhAWjSCLZg88Busik2uEvoZLe8Z+6bc +hTQnKcHY63LbkqqpYBKvsE/MjYUts7K7QKYQPmFvxoQpgpmqdfQ53ibvDnGeWnxj +j+5qXgx73cUaKPU14ObiLrhieVCnhEqSRot2aUx2hllbJn7CXj4OUkznFL6k2GGg +HzOe7PsZUhXWdUaBvSjbr6Whg8erCumJq2b346deoiGl3o/RsgFu4V3tZHN+v1Lj +gorQXOmnqXOhUbquM+2p5TRiKRfn6ARLf7Ja4UZhmk0w8e1vw+u0WKScMaNQ+BVT +91lBpJcHqWZiMAVDvgyZk3oM954xEgyr6guG/8eoTUXECUUn0HPbMOqmoLsMH6Ok +bFR2t1mtan8Qp9zYW8wIMAAdnkOMoYrUgB9KImr8Mr/DCa6ouqybNcO6xuVnVwq3 +vCmSqd5+XPORqnDF1wPZUbKh825VMXENa6RIX4rkiZwG+j4ALtzOqt5u6k3MZNIe +fmluaS0MnFk2mw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf new file mode 100644 index 0000000..bf4131f --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf @@ -0,0 +1,250 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Domain Controllers + +commonName = Common Name (eg, YOUR name) +commonName_default = localdc.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate localdc.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=localdc.samba.example.com +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:0123456789ABCDEF diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem new file mode 100644 index 0000000..f8c3c40 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKgIBAAKCAgEA5l9Pt7pkAJSyC6ApO2YfKIXN+rvX3hiO4ksUqzMXTF+LhA6y +Gc0yriqO/IxLUcDZLt5/0tN6g52VZm3gCBolEC/TJ7/Hrjr5M+Rlh6+igIfM92mj +TY1lMIGzIMo/VCi32R/+kJKPNAsMROtIsVQ+ZinDquj09y1qDMzCMfU1dki6gsjQ +BkIvzU4/ILX89nL8Dv6So5cWx5tA5MpcRzm9sUwJ46dCwg2otT753H05BU3IX8hp +3IVcPJojB7wwMzimxAMHWeOXVYRhZVKAYPp3tnZaMTJRpiKYtavcZ1EjdggJjjgc +dQucWUMfQQTdYGnZ+jG4Fl64+CeCFo7GztlWAWjkX/gtDzGFJzeS+k0Ls/Nq9L4w +FQ2OALWH+GdcrmolWSOMv6UC67fMDPy8O72ACPyjhl8t7HkFjuTS0sSmq4Tj2qpY +w9uLKEsVSXl+WBmLfT6HnnkoFeGKrXUQC3Eej+gfzdSbEeFHJhr41KMLfQjepvF6 +kyb7vXijYIqLKf74n3te12QD4VgjrCM1P0+59z3W12QfC2sRmxAfK0my+WPoz7+s +2p639xKR5AF3mn8xyLavfV5OVe49KvkNVhFJ4/YJjC/QBuv092Wf24UKV36auBpg +ERjRPRzAU2Wb6ACT5JFhtuh7Y9PY7HCNklQSi1Yfz4M01USGzbYL/JWP+RECAwEA +AQKCAgEA1iZfupFACPIxGHGIIrlp2YeY1K3tm34ExQO6cPMLg2mGDfqDQUzpAdJ6 +HPZlxdeZjOI0vMzuJI9GpHMbQSzcq1Fp3pd+jc4wfjag0yNH0mdq98txjNQV7qOC +2sZnXFqFnQcK42X6TQzAGQkHCCEh6GKGi8gGgAftf3yQQVSKoCw3hQAbsNWyDg3g +zQ2f25FEEsQ/mGcJPABssMIUSfm5BqmCv+dqPW3pGKM0Le0SJoYJ8FAjaGVoOsWm +LriXreXJ0IhoOv1AXrSyvTeWM5Bh3HHkobr+/4tFngvm1PwuFLif+V7bxUpHywqE +cTKOf+OmR9gUImdnVveTDFkpInwSX3UH88lKwg2t9rANuSgrfnhX9MgLxWT52qFw +hRwtLHamnKZw9IrYq002O00NPAoS2AFApFzAbPBxTy5cOKVzOzBr27w5Qxam+GoH +LVk/1qePWI0CwP68DN2jFM5TWd9zGUpXnSHcsX0j/qs6UKamUbmszbRenskOtn0b +d3Et/gKQt6168aBDSkCxFsdkeWMKI9xcnfSi97i/dRCvqIfEGRqoQLwknk2DMoE6 +2Z23hs+tRVRHu49CWABPnMBf5FqN2rocjr15wKAphgbbMIA3tw2wo03wmaMYNzxJ +M57ejJc+6MNfRyb0nLRaClsveU30qpfWhd36eKdKLZtrfj0Be2ECggEBAP90L6gM +83MA4hIOvLO5zhMMPdbm0+hOLlKpKUqBsNaCeJWutF9TcnqajoaYy9p+gKlASO5s +BgQiwMy3JlHc2KrbMXruksUER3d4Oprv/DKS+XfRciRZ0//+jCrNHrBvMB5VQHYs +wTB9Sdbdgfc1YiPdkF4JRBqmUrMS9b7iv8BLzAxbcdXz2xoXhkmbwgTJghdQAigq +GnoeXoc8qbA8IYKQefFevd6TzBL6UR+ZFHOjz2A2gX/1G31i6z5cjZc2XRjvI9aC +rBorjzYg2M7KBusbKhr8zYDqn/Rl0e/vK9NhZEz7Vg2FXUT25WZPlktQV1b3TVtY +yoWhJj2vy4ffqz0CggEBAObdZdE2I3UY/TTk/jK6LKg+uTB7/AjjaTga4T770IoV +pdAYEiGAFO1Y22gK14FAzq1CY7/SGtPtie3fBDCDcbv+K/qw7sVZvkXWKKSpvYCq +pB0xkmTWJGReAYh8QeI9KHuNhfEX2OO6fW2Tx9rt6ZzGxAZrQL7f1gKLjICEtYKp +dG6OjHHHVZprsFt/czFkfY+cVFvuTOSD8MmCjO5ErM48lCWAVXhJnfDR+rSMjiq7 +2SSqN120vp6Bdm6jatoxsUV4KUIp0kkO8UPA5vJsn+wwX+gXfDjZnqBSTbkia9Mw +xQ3mCSgYfhyxK8UCVoH466SXCqM7StqV3G04TqJVsmUCggEBALJOtikWCSQ//Izg +LoVA73/KLqv/aPChCaJ3IzQ3fGjunx7T2GEljSXZFh0LMFetrz70eTO6wSRH4c3D +FYNUpQP1hf8p4daVWxEgIcAePSpL/sfMsWCANwNb+RizHnXG1o6FsT4LlTm0akMJ +UHtujrc8I1YQH7J+YAFQ/amk+nVOMvp5JedSlKAMxZZBm1beFOkS1r6UTPDqm87H +4CX8guNw1z1MhTmEbpDcmp10q5rgP5MH2LKpMuv9jPh1f/uJXchWu+wyP9DwkMEW +gl8tE1EuH+DAju0qWEYugDB7AFtGgs1dLj631VebApq8eMrPJHe2nQ9i1dIanue1 ++lo4HH0CggEAQuU4UYzsbUvWYvNPrQdBVWcHZkMm3rR2kqlHR2bUII7xQwEWj9p7 +NeMfgGBT3cIXoSCxoq2Q1IPqCaErp5sO47hcqgGGzmyYs8fAcyY0IQpRD5yDnPBo +DyUmMJRAyvuJtXNmsluEn0g0fAHsUUXLAYCe4HVHh4d4jbg9+Cd8KOZNNJPdokJu +TZaSvZCKom9J6skTsKe2ZCjPJrTLfWcs432uN8ed/ILoXxWZHaP0tfFElFk2PdLX +wTomRRzZI2xuv4B4BBH2OvE3e7hzsx9Cn7/MqoXTmu2EB1SR7OlKcSGal9JmKNYg +BNRZqHZq9rJYJZMWpAHUSM5P1t4P+v31+QKCAQEAvkx6xN6DubYIgzHlaBW38iM3 +4pMUOA9DXIxQzDuYX1XCpxTv0d/9Y+nEWGJ9UeVAfRnyThYVoALAcI8xF/YLU9S9 +DiKgG89G6S8ZyVvYSWuJZWi1Y/Dup/SDcGXWuVO0fWS9UaDqzib4zFEtVtjjvkep +xRZYetMM/v0xTKFCLU9hvsy/Ngb485ChPLgr12ajldubfkHZrmfqbBfqGAsUsmXA +AP2BKkaopnNY/x8TYFcuYLiypYufXk8Hh/cUhWT0GiuAsPNmB4KwJjkXdktMbkpM +6enkjxXX4TPfbxe4ftV2GpCdfR7sWFgcJTn+C45Lsl7QT+P65Onr1QNGyKIp7g== +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem new file mode 100644 index 0000000..d0fe335 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFDzCCAvcCAQAwgckxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +GzAZBgNVBAsMEkRvbWFpbiBDb250cm9sbGVyczEiMCAGA1UEAwwZbG9jYWxkYy5z +YW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Etc2FtYmEuZXhhbXBs +ZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDmX0+3umQAlLILoCk7Zh8ohc36u9feGI7iSxSrMxdMX4uEDrIZzTKu +Ko78jEtRwNku3n/S03qDnZVmbeAIGiUQL9Mnv8euOvkz5GWHr6KAh8z3aaNNjWUw +gbMgyj9UKLfZH/6Qko80CwxE60ixVD5mKcOq6PT3LWoMzMIx9TV2SLqCyNAGQi/N +Tj8gtfz2cvwO/pKjlxbHm0DkylxHOb2xTAnjp0LCDai1PvncfTkFTchfyGnchVw8 +miMHvDAzOKbEAwdZ45dVhGFlUoBg+ne2dloxMlGmIpi1q9xnUSN2CAmOOBx1C5xZ +Qx9BBN1gadn6MbgWXrj4J4IWjsbO2VYBaORf+C0PMYUnN5L6TQuz82r0vjAVDY4A +tYf4Z1yuaiVZI4y/pQLrt8wM/Lw7vYAI/KOGXy3seQWO5NLSxKarhOPaqljD24so +SxVJeX5YGYt9PoeeeSgV4YqtdRALcR6P6B/N1JsR4UcmGvjUowt9CN6m8XqTJvu9 +eKNgiosp/vife17XZAPhWCOsIzU/T7n3PdbXZB8LaxGbEB8rSbL5Y+jPv6zanrf3 +EpHkAXeafzHItq99Xk5V7j0q+Q1WEUnj9gmML9AG6/T3ZZ/bhQpXfpq4GmARGNE9 +HMBTZZvoAJPkkWG26Htj09jscI2SVBKLVh/PgzTVRIbNtgv8lY/5EQIDAQABoAAw +DQYJKoZIhvcNAQELBQADggIBAEO4n5lMOyBsZBuVKOyYYC2uFUCnIXepxLwpTN16 ++8wNjXG25B0nm0dgmPpsq4zvYLAMY32vyxo81LKX2fh0f6xyovN7VOmXBUcwHVtl +6GZIIFDOm8uMQutqX0HV25S9Q5nxqoX1K4stBNmHxAFmyp0vZgz5CcoOn36bWIr1 +CRLKt0RF0unUlzXKdQIdlmugxnfitKg6gkr2MN2ae2wQmZB2Z7Q6edfda82xw2l7 +yE2qwwpstjlgPSrM/W53byiXO5w+5UI1U4mbF8J5eB5xlaLaaoPwuDteOlw0TN+9 +FOgFp0MZq2Mu4YdO8Bcl7k+rTXyviyzNG9MiABYsMwZQ9XSClF6OUIxQFqXBgY7Z +Xo2wp8ggCsWHgA5uofVXxbnkxquI4pEH9ZzI1jJT7nZIw7Dyb0RJcbMlLArPEbZ6 +pRQapv8vK4Sc3DVxLwu5bnxwzllTjGPQH9Z/uRjft7EK3cByO6x7jZJXpUOKK+0C +eF8nvmsoqnPfx92tfNZ4tYXga/1hq5warOl++nDSpIPVNlLEhyATuFakxYj9qiag +fn2qIrXEyoOmjKlTdUJehKIFviUVD+2o/9bBsS3x+fZLPxs8BbWHeq5BuZM5o9qV +F5A1BrytjQwDWWznU9E/SSiWh0JqQeQaGWLBr1XAejSb7Xk5ecqsO+6aaWvYL9JD +vI4t +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem new file mode 120000 index 0000000..b7549bb --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem @@ -0,0 +1 @@ +DC-localdc.samba.example.com-S00-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem new file mode 120000 index 0000000..21601b4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem @@ -0,0 +1 @@ +DC-localdc.samba.example.com-S00-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-cert.pem new file mode 100644 index 0000000..4cc42aa --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-cert.pem @@ -0,0 +1,191 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:45:30 2016 GMT + Not After : Mar 13 11:45:30 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=plugindc.plugindom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:aa:a3:74:2b:4b:6d:29:43:67:03:dc:c0:be:ce: + a6:e3:43:99:e5:87:34:34:42:70:4b:bb:50:87:6d: + e8:65:2b:5e:1a:b3:68:0d:9f:27:eb:dc:b8:84:bb: + 3d:f4:40:28:c0:c7:aa:e5:8d:a1:d5:7f:c7:6b:36: + 96:6b:3e:65:72:37:0e:d4:2c:03:4d:ee:e6:f8:41: + 5c:27:bf:32:53:6c:13:28:1f:be:78:9c:7c:80:53: + eb:4d:0a:19:1a:88:49:95:a9:c6:65:23:5b:3e:24: + 27:06:eb:7c:58:24:c6:e7:a4:d9:98:02:c4:ce:b3: + 1e:01:34:4c:bd:9c:28:da:10:4d:36:e9:7d:a8:68: + 04:75:18:eb:f0:58:94:05:b1:61:97:d5:9a:b3:db: + 09:71:74:90:05:87:d4:1c:ff:06:2b:c0:51:b6:26: + ca:28:8b:c2:08:3a:93:62:f8:69:b4:3b:c3:6d:9b: + 0f:80:1d:f8:c3:51:93:78:64:83:63:c7:d0:21:e8: + 05:cd:22:3e:3e:e2:c2:66:af:46:6c:c6:7d:d8:ed: + 53:b9:cc:42:e9:a2:43:94:31:f4:9e:45:fa:45:35: + ab:7f:32:93:95:a5:1b:4a:9d:27:c0:5f:bf:03:7f: + ca:37:c3:c2:c9:6f:b6:6e:5f:05:55:56:f5:2f:40: + c2:41:12:17:ee:23:1b:3a:9c:39:74:d5:cc:b1:47: + 6a:24:85:95:f5:aa:e6:35:40:0c:d3:8f:1e:d3:df: + b5:1b:7c:ff:3f:df:7e:7a:d3:f8:e1:92:b0:41:14: + f6:aa:1d:8c:36:3d:5c:c5:c5:b7:2f:b8:f8:09:47: + c2:51:58:de:80:41:c2:a5:18:c6:a9:16:39:d4:8e: + ef:f3:a9:c6:13:db:1e:f5:8a:e7:37:16:7c:df:28: + fe:19:44:7b:58:98:ee:72:fa:41:a2:f5:e0:77:c2: + 5e:fa:e1:94:87:96:17:66:75:07:45:c8:df:6a:40: + 19:3b:da:4d:48:e8:51:a3:1f:ba:41:62:0a:48:f5: + 62:42:9e:69:49:aa:ac:36:bd:6f:41:32:bb:62:8a: + 96:6b:01:aa:de:14:05:3a:43:e9:45:f2:00:9a:dc: + 71:20:b7:65:f2:f0:7d:b3:74:a0:43:1c:3f:5e:22: + 47:df:47:8d:5e:cb:93:1a:14:6e:b4:29:0f:af:1c: + 07:9c:11:74:24:38:09:23:76:0e:ca:fc:60:8f:1a: + e2:dc:d4:fd:fe:cb:12:f8:a7:83:c4:ae:db:a4:c7: + 74:b3:a5:76:90:93:9d:a3:78:01:97:e0:ec:09:78: + b9:98:ff:b7:2a:9d:05:03:5e:cf:b2:01:80:79:6b: + f9:5d:f5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate plugindc.plugindom.samba.example.com + X509v3 Subject Key Identifier: + DB:4F:D4:70:C3:38:E6:26:37:6F:1B:50:5E:7D:E5:80:7D:B4:08:0D + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + DNS:plugindc.plugindom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + ab:ed:44:9c:0d:f9:df:d6:8d:f2:98:05:cb:97:0c:14:9d:0c: + b3:2b:49:6c:4f:d6:8f:81:dd:c7:d9:67:be:ad:5b:f6:08:34: + 44:09:88:3a:9d:e9:fe:0b:91:89:f8:32:92:43:43:af:cf:04: + 5c:35:a4:d2:04:77:04:bf:37:45:57:2b:70:94:d0:7a:5f:b9: + d6:9c:47:ac:46:e4:4c:c2:87:5d:78:b7:3c:be:80:42:dc:3c: + 36:3b:c0:57:fb:ec:95:3a:bb:58:7e:09:ff:57:4e:4f:59:73: + 2a:65:0e:6e:a8:b3:8e:22:6b:40:0c:b5:5b:96:f3:a1:35:92: + 17:12:24:f3:43:fe:54:1d:ac:f9:f1:72:cb:97:b8:43:2f:e1: + ac:9c:a6:e7:78:98:38:ad:83:eb:c9:77:0b:ea:5a:21:6a:76: + f7:b2:4c:d7:7b:d4:57:eb:4c:a4:6e:be:eb:be:60:99:ae:ce: + 13:1c:6a:9f:58:e5:64:a2:b6:4e:2a:2e:62:99:d8:fa:af:11: + 5c:7e:51:d3:cf:7e:84:1c:f4:8b:a5:df:c8:b2:39:4c:c3:40: + 48:2e:b6:9d:3d:bf:b1:7b:58:39:f0:38:60:72:42:f4:8c:2a: + b3:66:c1:e9:12:bc:2a:51:75:55:1e:56:2a:bc:6e:40:1c:2b: + 16:25:90:97:18:4e:b4:63:dc:ff:7a:31:5e:b2:38:c4:17:65: + 3d:1a:31:47:04:75:3a:b7:83:c3:59:09:d5:99:56:45:4d:a0: + c8:6f:3e:87:61:17:4f:2e:7b:5c:34:76:45:e1:b5:bf:c4:fe: + 32:31:ff:2c:95:52:9c:12:2a:c3:b8:04:f9:25:a3:11:64:35: + c8:5d:92:f9:fc:2c:ba:45:18:d0:dc:95:1c:dd:30:16:3f:56: + a4:15:45:85:9b:52:55:3f:f6:a8:dd:54:53:d2:84:1b:d3:1a: + 97:61:8a:60:d6:fb:a1:75:f3:15:8f:b7:f3:f4:41:dc:7d:24: + 90:9a:62:23:a1:ef:c1:01:69:d4:a1:69:82:58:5f:35:b4:83: + b1:7c:cf:dc:f2:ca:23:af:5a:ac:e9:53:53:bd:33:8e:22:2a: + 1b:cf:ea:e7:e0:24:b2:f5:f7:ff:f6:99:6c:34:13:e9:f2:50: + 70:a1:0f:ec:f9:12:22:99:58:08:5d:f0:49:86:f8:14:3b:1b: + e6:49:eb:9b:fb:b1:07:60:e0:05:e6:4f:13:39:d1:ea:07:6b: + e8:85:33:eb:4f:b7:d3:7f:bd:9b:f4:a4:40:f4:a4:4a:f6:5f: + db:04:f5:f8:04:fa:1a:13:1b:cc:75:6f:c2:df:9d:89:12:5b: + f1:fa:cf:df:b6:32:3c:3c:5e:e0:26:9a:c7:e7:87:e7:5b:9a: + 76:b3:41:a3:0f:e1:f2:12:69:db:1b:32:57:a4:ad:5b:52:32: + 8d:7e:ec:34:c4:ce:d2:ee:6b:96:56:0e:ef:97:9a:26:a3:b5: + a0:4c:9a:e0:4f:9b:8d:07:df:92:46:1b:53:53:eb:96:62:74: + a8:13:03:e3:1f:13:0e:48:22:ca:ba:94:7f:86:80:c0:76:ab: + 08:36:e4:02:f3:ad:31:2f:97:00:06:57:09:12:66:d5:4e:8f: + 5b:88:67:7c:e3:0f:df:1c:97:17:85:9f:b9:08:4c:6e:88:e3: + e7:b9:53:06:87:98:e8:a3:9f:7c:7d:c9:07:d8:69:74:d1:e7: + c1:e6:46:e9:0f:2d:4f:04:6d:41:e8:b8:a7:87:d4:5b:1f:89: + e4:b1:c0:ba:78:2e:7d:cf:84:56:25:56:95:f7:93:dd:4a:47: + 88:b5:ac:d7:da:a7:b3:c9:8c:c5:41:34:8c:31:24:84:d4:51: + bb:46:4a:3c:db:72:e6:1b:c1:c2:15:6e:1a:ac:61:bd:ce:f1: + a3:ff:60:d9:a7:90:5a:3a:3e:1c:28:13:ed:cf:ef:ed:f1:fb: + 79:3a:57:ac:41:de:e6:17:d0:92:c6:fc:bd:6a:1c:e0:44:c7: + d7:ce:80:b4:c2:59:75:a8:bc:8b:32:4e:ea:2a:ff:89:fb:f9: + 98:6b:04:1a:fd:9e:2e:b9:bf:60:d5:84:80:f8:5b:03:0d:d9: + 1e:30:cf:4e:78:2c:a1:88:6d:ee:80:a2:ec:d9:96:00:c9:82: + a2:81:c0:6e:74:4b:69:9f:fd:c2:ed:0a:f7:31:a9:dc:89:f7: + c5:83:83:51:bf:f0:f6:8f:22:72:8e:f6:0b:54:d0:b8:7a:39: + 62:d1:d8:76:bd:c3:85:be:18:41:e9:42:c2:80:21:1c:86:20: + f9:4b:55:5f:e3:e1:6e:ae:ab:0a:4a:0c:05:1f:0d:b5:1f:a0: + d6:92:dd:20:71:56:74:e8:13:83:2f:4f:d0:72:98:b8:57:b5: + cc:06:63:3b:29:5b:f7:be:fc:e1:0e:24:94:da:1c:d1:ba:9f: + 7b:af:0d:d9:80:ed:18:85:74:73:62:2f:cb:37:e2:8c:85:90: + e9:86:dc:2b:78:b5:2a:47:fb:a1:41:f1:d4:2f:66:87:17:a5: + 24:20:54:61:99:03:72:56:5f:96:92:bf:25:4e:d0:20:a0:26: + 85:ac:b1:d2:7b:b9:b9:e9:9c:9d:01:52:a7:29:32:bd:94:65: + fb:bc:41:d2:9e:6c:59:c7:9a:b6:92:38:ba:fa:08:fc:1f:c7: + 72:9a:a3:a2:cb:02:e3:fc:29:20:20:b7:15:76:73:ab +-----BEGIN CERTIFICATE----- +MIIKDDCCBfSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ1MzBaFw0zNjAzMTMxMTQ1MzBaMIHAMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMS0wKwYDVQQDDCRwbHVnaW5kYy5wbHVnaW5k +b20uc2FtYmEuZXhhbXBsZS5jb20xNTAzBgkqhkiG9w0BCQEWJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEAqqN0K0ttKUNnA9zAvs6m40OZ5Yc0NEJwS7tQh23oZSteGrNo +DZ8n69y4hLs99EAowMeq5Y2h1X/HazaWaz5lcjcO1CwDTe7m+EFcJ78yU2wTKB++ +eJx8gFPrTQoZGohJlanGZSNbPiQnBut8WCTG56TZmALEzrMeATRMvZwo2hBNNul9 +qGgEdRjr8FiUBbFhl9Was9sJcXSQBYfUHP8GK8BRtibKKIvCCDqTYvhptDvDbZsP +gB34w1GTeGSDY8fQIegFzSI+PuLCZq9GbMZ92O1TucxC6aJDlDH0nkX6RTWrfzKT +laUbSp0nwF+/A3/KN8PCyW+2bl8FVVb1L0DCQRIX7iMbOpw5dNXMsUdqJIWV9arm +NUAM048e09+1G3z/P99+etP44ZKwQRT2qh2MNj1cxcW3L7j4CUfCUVjegEHCpRjG +qRY51I7v86nGE9se9YrnNxZ83yj+GUR7WJjucvpBovXgd8Je+uGUh5YXZnUHRcjf +akAZO9pNSOhRox+6QWIKSPViQp5pSaqsNr1vQTK7YoqWawGq3hQFOkPpRfIAmtxx +ILdl8vB9s3SgQxw/XiJH30eNXsuTGhRutCkPrxwHnBF0JDgJI3YOyvxgjxri3NT9 +/ssS+KeDxK7bpMd0s6V2kJOdo3gBl+DsCXi5mP+3Kp0FA17PsgGAeWv5XfUCAwEA +AaOCAgcwggIDMAkGA1UdEwQCMAAwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3 +dy5zYW1iYS5leGFtcGxlLmNvbS9jcmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNy +bC5jcmwwEQYJYIZIAYb4QgEBBAQDAgZAMAsGA1UdDwQEAwIF4DBRBglghkgBhvhC +AQ0ERBZCRG9tYWluIENvbnRyb2xsZXIgQ2VydGlmaWNhdGUgcGx1Z2luZGMucGx1 +Z2luZG9tLnNhbWJhLmV4YW1wbGUuY29tMB0GA1UdDgQWBBTbT9RwwzjmJjdvG1Be +feWAfbQIDTAfBgNVHSMEGDAWgBRGh4bC5xnPFkwMYstzf/2PGeS1QjBIBgNVHREE +QTA/giRwbHVnaW5kYy5wbHVnaW5kb20uc2FtYmEuZXhhbXBsZS5jb22gFwYJKwYB +BAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUu +Y29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRwOi8vd3d3 +LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5jb20tY3Js +LmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJ +KoZIhvcNAQELBQADggQBAKvtRJwN+d/WjfKYBcuXDBSdDLMrSWxP1o+B3cfZZ76t +W/YINEQJiDqd6f4LkYn4MpJDQ6/PBFw1pNIEdwS/N0VXK3CU0HpfudacR6xG5EzC +h114tzy+gELcPDY7wFf77JU6u1h+Cf9XTk9ZcyplDm6os44ia0AMtVuW86E1khcS +JPND/lQdrPnxcsuXuEMv4aycpud4mDitg+vJdwvqWiFqdveyTNd71FfrTKRuvuu+ +YJmuzhMcap9Y5WSitk4qLmKZ2PqvEVx+UdPPfoQc9Iul38iyOUzDQEgutp09v7F7 +WDnwOGByQvSMKrNmwekSvCpRdVUeViq8bkAcKxYlkJcYTrRj3P96MV6yOMQXZT0a +MUcEdTq3g8NZCdWZVkVNoMhvPodhF08ue1w0dkXhtb/E/jIx/yyVUpwSKsO4BPkl +oxFkNchdkvn8LLpFGNDclRzdMBY/VqQVRYWbUlU/9qjdVFPShBvTGpdhimDW+6F1 +8xWPt/P0Qdx9JJCaYiOh78EBadShaYJYXzW0g7F8z9zyyiOvWqzpU1O9M44iKhvP +6ufgJLL19//2mWw0E+nyUHChD+z5EiKZWAhd8EmG+BQ7G+ZJ65v7sQdg4AXmTxM5 +0eoHa+iFM+tPt9N/vZv0pED0pEr2X9sE9fgE+hoTG8x1b8LfnYkSW/H6z9+2Mjw8 +XuAmmsfnh+dbmnazQaMP4fISadsbMlekrVtSMo1+7DTEztLua5ZWDu+XmiajtaBM +muBPm40H35JGG1NT65ZidKgTA+MfEw5IIsq6lH+GgMB2qwg25ALzrTEvlwAGVwkS +ZtVOj1uIZ3zjD98clxeFn7kITG6I4+e5UwaHmOijn3x9yQfYaXTR58HmRukPLU8E +bUHouKeH1FsfieSxwLp4Ln3PhFYlVpX3k91KR4i1rNfap7PJjMVBNIwxJITUUbtG +SjzbcuYbwcIVbhqsYb3O8aP/YNmnkFo6PhwoE+3P7+3x+3k6V6xB3uYX0JLG/L1q +HOBEx9fOgLTCWXWovIsyTuoq/4n7+ZhrBBr9ni65v2DVhID4WwMN2R4wz054LKGI +be6AouzZlgDJgqKBwG50S2mf/cLtCvcxqdyJ98WDg1G/8PaPInKO9gtU0Lh6OWLR +2Ha9w4W+GEHpQsKAIRyGIPlLVV/j4W6uqwpKDAUfDbUfoNaS3SBxVnToE4MvT9By +mLhXtcwGYzspW/e+/OEOJJTaHNG6n3uvDdmA7RiFdHNiL8s34oyFkOmG3Ct4tSpH ++6FB8dQvZocXpSQgVGGZA3JWX5aSvyVO0CCgJoWssdJ7ubnpnJ0BUqcpMr2UZfu8 +QdKebFnHmraSOLr6CPwfx3Kao6LLAuP8KSAgtxV2c6s= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-key.pem new file mode 100644 index 0000000..21de683 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI8qLXeXVBnvQCAggA +MBQGCCqGSIb3DQMHBAgbmdRIPfia2ASCCUi97VRXS5hQ6b+T8cv5YOs0CdVw+XBd +3ZiBBM1FF4lFjGMpA+YRLkcC2ksn+dW4Obyimqi6ODk3jhikXJ8LhgCa4uo22ghU +Pmqsgs3xScwJEM6VHZSGQ0ULJ+wce6mgIPCVzNRkpkREZ+jT9NAPTxSQoBJDYggV +WERdMf+3us7i2uyn4l+mAbuggEMWgJgXcz5QVCDmMilYW3CHeuT/6VW04ma0dyGa +d6O4y5DHZiO9u+oCPiHzPWrR9VCD6uq3Yr7JU5B0Aee3Fj/5NXAFsPq5a9VCP76R +oF7maYitgl1RtPYmD60bGA4yJI1hEsq+xiq/VM0ZHkvKOQJp7Jvp4xR2QPnr71IF +gmx4GAekWd02sFd3cjt7MV/nRm4W8TWGtQfm8c8Ino5T8zs74EGViNnAMg8wdzqL +tlmwkOgN94VFXl/taY4qLlmskTD/sdsfwuF6Q+4tef8iDQfxko8dWr8nT3Vj9VWD +5lQMiolcdJ96CfCitxZXkPL9lPr1LNBOFhTEZ71mhjcXFx7fPdbhTekKAMm060uV +6ycl+iLWjsJngA4SJZoeBNB+aMCWq/HT9yMWQOQHx80f65AsygGUJlZFkVBO8oQh +GLIZzZ425ZGwGF235GrQ7gKHYvZcFL+rmhPJAO/xPS0oM87fS760kVfriOwP9JPV +S7VlmLbdZ3jmz5XWggD2M1Stl0A9+Mwiss6/5IxHgcvew2VCYRQnxss5KCS52UOB +6ZMG7QlAhLMds/0dEPW5tvupojXMQj2GD1kC1LAWUGrhN2QkJ0efIs4I7sRvYyr0 +5QHBlQACNT8J/W9DiTXAbgMernAgrCGw0RN9Ibnlf2Uf8KWB1HPv7LWnjjyeU6Sj +8WdAOHPZUkYj71WhAy/UqO9gZ1RbbYtmQ4PnU0tWdzABJbRQQCnXbP0C/b3QNA5Q +ocTzBg0IUYN2SVw4ApVz8prSHiXNlNxMAnVKGdIbBB3t+a3vXCkHden01MemoP6m +ybUFPlQ479TvSNut7v7ZwQjtTliiU3plPUuT6fwvXlJfnn+QzKCh0CEbgadQvYam +lZ8bzkVOTtX+eLG3ZOGUrY6yFf+jFuPx94kE4BJU/DtK9mP/gPWrD6dm476X5xRX +J2+zPWYogBxkHhANoNI18B3VszEzB9MYzngIUJDJU+5gC8lYtT3O4ZZNlDbj1n/e +NOEZWxXUaGbGZ84RTbCJxWcZoEVQ0YUWAG7ALNPVBweLcxtx+wH1ctxsv1jNz8uP +poUMKGbX6EYkE8Ytvq5a3/hlwXcxxX+ynII6X5UJ8jssD3vmMJdHQyY0QhgIoRgJ +fV0DIqP42bwsEe03F5VFqjBbeGT5Db2RLenoPeYRiBCGjnJvWD20T+mqepBy2Ugj +I0/+SpELZhID7Ltpfdg5CKqN4/YCaO+gxY3A9Spw2iSmaVCwNXEmlbzh6gv/fRuD +J3rad27S302caZunZkw6yIjYAcvtT694Wd7mUMFQtjiB6QJPfeNBo1XnSvstWv4b +yEsKK1gJGTyiYn3/+zUGfuky7TRaKkNyA1baHlQdz42fzX8OHQwausFOjy3HgICM +pgkirbylxyS9b0utYO1utqOButyfd0P8Y5WKyBZtYV9vY0WlJKwDSRxZBpv9tL6K +LANEpcSmWZ9gKjpFtmaAIvN03GoLc2aYOwKL3vVOnbkyuUXN7XQDWpMX+xy7AlVR +IdR2Po2xTH/Hk3kFJW7MxrURNuSGKuHj7HVdWy5pTem/g6RL/OjPbiS3ys76XcoM +44h71IPOCGTxIGqMpPUAnJk59pOSJFaJLU3Gh87dBAk/amwbPfjRc2VI/d1hVpdB +jyIFhLOSKOQlIey/29ueDXWVxKbeOSVVPv2QxrI9EvpC7Uayq+ADd4kNDHfz/Jz8 +MknA/T9VmstCyjTQ4mgpwyvoAZCRa+V8nrLWm3Di6fIg8QUv7SZ+qWYKAhgG363t +5IRnnfoFD3ikCeBKYtiqhvtXoCQIm/rbOvTuLMOx43nF6Vw/nOBHG46ZZUzdwC8u +2EZnRjKOnxCtAGMkbHf6yMgG8zgM+obAHiD41CpBgDogpzS6zphTQEfDRAiqRNVQ +XrAaME5bn8aXozGEudPLJD0A0jqaXQiO8UXhToTBefGRqttXSE7XpuweUJ+34j0J +StpyjL/rXYBb0lfBV+jyOwNB4PCuGcKdEQWiX3usQH1NTJvhRt1iJx17E/GOBGMR +ygZIMK8vPKSLVfUOuwaXtJBQyH3BfNzwNyBFB2UvZ0xxrlVpi8ro3/6VUDPNNA4F +ld1bLhG0+M9LNuhset/qvYN41Y8fsQm+bHkIC9IDyCJ5I3bKfPEKFVBDDMKHT3R2 +NVKsCzQSmqLfmhGxgubdjt4fUVDK0BAfQDYsEp9DK9miD6igAy7IM+RkYfK2TqSW +bOFaf+1YN3W3WMllBYTHuaz+NwgjS6L4z9fgm/f10rEp1HY/Qqvkj9hdw7W5r8IK +vcCdXa5jM4tuXIpF/GdvwXskFQl8aGGTflU8GNjV7TJ/7SACWdHillQlkkq3VljI +hqo17cJgHC4NWFhR1X/gnpTOe80Ljkg4QIC7Nam/6rm77+acnfYtJKxOaxv3W6i2 +NCAjBeMRaKrKTIa+YCRQnAYrq8Cx2vWspb/kM7rDMiHaIbDvh0sST6MWXWYqudNs +Oxdal0PIZx5D1KvtHrX4PhomnTzYcQ81Jz/ufqg9DrpmYZGOm2mVVgRuxjHtBBpk +97t8sq3kpxXwcDAc1QeQyNekq+mG+qIevkyI5T/lPJEKEJkcpNYqkLoThegtNgzD +l+lyL5sC9VYcgDhpKH8UoalSFWFVNBu71yXF0lYorRRBFcCFEiEKQOgOvJyB3ire +f9aRNfo4ukS74BjBu5rqPoQe5JUlO8QGCQjk8y9t6Iz+WoBSZFUGVOeXWSPaWif2 +3y/zTwfvWW7FQB3hqUkqEQg3G2pJbK2a9jspy8vC2nQdr7Lip6FRBQk4Gt8Dp9rq +EancUwVeMfMRT58jgEH90yJfZk/f8VF1MQh+ByIl2YWfVZjydFOVetG/iHAH4cZs +/Y/XEG0L79XHlJu+Ccl2T4V6hhRJl6bD234FEsGPO5XFa7oueoy4w0ejdC3D8Ayu +mwYpvmsfsGJm4C3dbiQLZ8568OkOy32Dq1CSiE/lz6YgcqBlj+T7H6ZWpHN9dkMo +5zs= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-openssl.cnf new file mode 100644 index 0000000..56b1839 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-openssl.cnf @@ -0,0 +1,250 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Domain Controllers + +commonName = Common Name (eg, YOUR name) +commonName_default = plugindc.plugindom.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate plugindc.plugindom.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=plugindc.plugindom.samba.example.com +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:0123456789ABCDEF diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-private-key.pem new file mode 100644 index 0000000..c436d7d --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-private-key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAqqN0K0ttKUNnA9zAvs6m40OZ5Yc0NEJwS7tQh23oZSteGrNo +DZ8n69y4hLs99EAowMeq5Y2h1X/HazaWaz5lcjcO1CwDTe7m+EFcJ78yU2wTKB++ +eJx8gFPrTQoZGohJlanGZSNbPiQnBut8WCTG56TZmALEzrMeATRMvZwo2hBNNul9 +qGgEdRjr8FiUBbFhl9Was9sJcXSQBYfUHP8GK8BRtibKKIvCCDqTYvhptDvDbZsP +gB34w1GTeGSDY8fQIegFzSI+PuLCZq9GbMZ92O1TucxC6aJDlDH0nkX6RTWrfzKT +laUbSp0nwF+/A3/KN8PCyW+2bl8FVVb1L0DCQRIX7iMbOpw5dNXMsUdqJIWV9arm +NUAM048e09+1G3z/P99+etP44ZKwQRT2qh2MNj1cxcW3L7j4CUfCUVjegEHCpRjG +qRY51I7v86nGE9se9YrnNxZ83yj+GUR7WJjucvpBovXgd8Je+uGUh5YXZnUHRcjf +akAZO9pNSOhRox+6QWIKSPViQp5pSaqsNr1vQTK7YoqWawGq3hQFOkPpRfIAmtxx +ILdl8vB9s3SgQxw/XiJH30eNXsuTGhRutCkPrxwHnBF0JDgJI3YOyvxgjxri3NT9 +/ssS+KeDxK7bpMd0s6V2kJOdo3gBl+DsCXi5mP+3Kp0FA17PsgGAeWv5XfUCAwEA +AQKCAgBgQ44Jzqdqm+fFugfSnOpxU3XCkx/US5bmYmnvvQVZ7blM/uE4rgzrdr1x +w+ATpw5Wk03J6rjdpRRvW4BISA8a/AyVja7fjGMosla25ZoSjenQvPfLOxzRmIYq +FARNf41jrT+LVwLmb6bEtJyVbUn47HsE0qsMoOfQbhzM6wfw3TlyPQ7yrpu1I7YX +BSGchJE2Av8fb/ZH1yZYuGPlZ8mnbPur8v4hGZcA5Wq4bsPTNdPuRYfdEwt/xMmZ +Jbsp01OLjUWYkDTlbS+WllL4kpH0iw6sxpsJCs1tETGbCIdD/B8fxvyTc22ODlKa +qGkuJC2EgB+nXCpi4aA0oLX5TmNHPnzIAb1d5OEqw20Iwr/tV39RYC7xuLV1FidU +3qj0jNCJkf+v7TIB0E1CoEbPIRj7plQJWWgTj+EEHtTz/b1lyPLnRUYxfTm1Pcje +SbYjDd/GxKmUhNQyxIGuNR1B2JA6qZiaYfjFCp4h54NwHWvt0yMR5xUglG7+IGof +jcLPHlsZtnCit/bGUz35JdbirQFbBWIAHpqLlPf7dqVzaTwI/nw6jdQ/bUxq24kz +p8f3V7OEzKdemXfGBV9bk9hD+zeCQwm3EqILmPU3Be+sF2xWlkWwR2Xygy8xQ0q5 +2/BnLkY2dXZQMEEJJi5gZRN+irvpC33G4X1qXGZfDjvkeqOeAQKCAQEA1QoWw3Xi +qyxoSf7F/KZefo1IsXsIsuXYG25fLWExDHncpxEpXl+IqQx1icfMeM0EP/jUFjWu +Ti9V09u9FcP5Dl+uHfHqc3zFBJfAGhlPH+7YhVcjAzBx5LA7J65GqO3CHSUVk74G +4nvAr51R1ba85VfgCavllaS6oJcEOZxECBT+1DicaD4Ir6QSDH0+d19t4LUDw1G8 +ARlOpC9rP/eSGL5LqOTiZ8LjjruGI55GG0vpgoG3bEli/Or8uqZzqZjYR5dD9Wfo +MIjqdDjmojOiZMh9m/coZlphQaGl3Rqb3e2RZkZ2n+wyyo8g5DknyPKyiN0qu9nt +86m/B3bE0RaFIQKCAQEAzQx3hpsD5PtTXL/K43OXVb4/r9OTwF55TuCnne4xBqgv +jHMtMsgF481gCtrIbbZ+TH6B5FdYNHBui2hfrN4R1XZoAjAuCRxgHQn8UPd9G415 +aieSIj/wPUQgl8AIOygxDw28FvjDqf7khKF9z+pDsxNDqkTxFl04zYb2cLUBW9/r +xQ68sb8BxxQ7qbR94gyOnSGO0+9Vy3MQNUAfLbbqMyBKbFym4gPGkVdGCvAaMsHn +Hu2Z0oZSEwe3hAVL6ZnrqvMOxDbJ7RKZev1YfZGdno8YemAXKwRk3LOxXxodAF4x +bUUOaY/AVqYvLGu7SJ4h4LBFn/DPnEbpceN3IO/qVQKCAQBH3NZe6rYiXaF0TG/G +0OwRLmF2FPWTOzsRzcJnUWC1P6ox5PUac4lq1NwVNQOBQE8NsUcBkuwQTaFbDMWU +wP2TXq0iRsd6W30uFm5jn2P0dqItIH6cBcx1gwkBUqVdOI6BPFAx/SjfXzVZR+0h +9Tl095aITKbuOpoFr8tqD49XVpW7Srlf5IUTknnQIrNemx86bHUvfrO3fyzq71/z +PPTYSeDFwSeqLrCKJjGSdEJb1NiZAF66NWshu7ay05EyhW93fswazQkizhygRc1u +q5I9AvB0GwRSumwSMo/7rI0laIzifiRnv8pGT8+djLYh79RPnKNcqJ++0OSyhNrR +WRJhAoIBAQCjzjjSNJY44DopVyJ68AXOvqxcBzb6r75TMA9XkEhkHAnYNs69yaNC +5/e41CzX0Lk23L1hsBFL2yHEhr4f+Evg7rWKQfkU2DFEIY0LFZtBXpTHJBOO/usp +1nn/IK6yq5n9f6hp5ZNSA8mE1woOBgTNUy90H51Fk3VkY1QOl9sdDVZpVyuRB5kg +893x5bnG0uc/SeazEnjEjgg9shr2RzDzZPFvfdjnp8KCq2jOJh+XuuWrBH8k+p8o +irqlYiHR3V+ycneycl5/4KLx6OA/eAul9oTEhm0btWfqFDc3VUIj4Bu2QjuQQwGR +dzMqVmoISiOgPtFwQ01neBLYI7Iwgtj9AoIBAApZsr/9mYNwzPamSGc1zyDF/9j5 +EM6MXgFAQxpxzQlC36EDliZ8RvrQSJ5HjWxIihcZP/iR0rUBn71kitj5B88iURbF +lsKyjbX4ZfrmClWiFkmJv0Js4n8+H3YdqFeUPgD3gQ1UfcViJgEt0iOv6N6qN32Q ++ofcWP6cdMEzXmfK+q53U6C38d2WD3QFoc/5qB0NnDYMr7Al4LHcfNwOmxIHDd7q +C/0ang9tkbjVehX6S1DozFEgmMxYU8ZrB/KwYRMEXTUNSjyn2PXgTNqMch9OZpsD +c9jmUdN9x7Pi7pyaxiREBpRDp9Cj0RZEcASeUKH2lpuEl7dT9YZaShBeY20= +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-req.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-req.pem new file mode 100644 index 0000000..4fc6722 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-S02-req.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFGjCCAwICAQAwgdQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +GzAZBgNVBAsMEkRvbWFpbiBDb250cm9sbGVyczEtMCsGA1UEAwwkcGx1Z2luZGMu +cGx1Z2luZG9tLnNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1z +YW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAKqjdCtLbSlDZwPcwL7OpuNDmeWHNDRCcEu7UIdt +6GUrXhqzaA2fJ+vcuIS7PfRAKMDHquWNodV/x2s2lms+ZXI3DtQsA03u5vhBXCe/ +MlNsEygfvnicfIBT600KGRqISZWpxmUjWz4kJwbrfFgkxuek2ZgCxM6zHgE0TL2c +KNoQTTbpfahoBHUY6/BYlAWxYZfVmrPbCXF0kAWH1Bz/BivAUbYmyiiLwgg6k2L4 +abQ7w22bD4Ad+MNRk3hkg2PH0CHoBc0iPj7iwmavRmzGfdjtU7nMQumiQ5Qx9J5F ++kU1q38yk5WlG0qdJ8BfvwN/yjfDwslvtm5fBVVW9S9AwkESF+4jGzqcOXTVzLFH +aiSFlfWq5jVADNOPHtPftRt8/z/ffnrT+OGSsEEU9qodjDY9XMXFty+4+AlHwlFY +3oBBwqUYxqkWOdSO7/OpxhPbHvWK5zcWfN8o/hlEe1iY7nL6QaL14HfCXvrhlIeW +F2Z1B0XI32pAGTvaTUjoUaMfukFiCkj1YkKeaUmqrDa9b0Eyu2KKlmsBqt4UBTpD +6UXyAJrccSC3ZfLwfbN0oEMcP14iR99HjV7LkxoUbrQpD68cB5wRdCQ4CSN2Dsr8 +YI8a4tzU/f7LEving8Su26THdLOldpCTnaN4AZfg7Al4uZj/tyqdBQNez7IBgHlr ++V31AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEAXdU/NQs8tIc2BsjClwmdZYXo +HRV/QyyrtxwZyDhIt8jG/DE/rggGXPLOaQQwbPgax7JCYbeyolCLQtOIP/sWwpje +0rADXkdvwdUyEmEUl6ARmxJNm9j4DTKttAQCFquww70di9X1C7IHXrb5VR2HrvgI +JChexYX3Nt2Aj01Y1vc7Wn1EStWJ5CUZg3yHe4x5aZ9t0/8J7fXLzmhyNO96S2dy +BiPz3S7SNv8kRLqHDsKEZq6gzY54lQaCIpj4gCyd573YBm3YogMak9Su58+/AWE5 +lrwAJLSb6nfN0YZhVsq3kAhhD2yT/x1vH3JG/0LcaGqW/zOa0ZLWU2qPk4y5UIKo +EdC0/FGvmHBDLmb7YPKsjBnrtZ0pGlyxu8vempDG3qa7elsVBW9VvI3R6fPcNfZe +WJhNuS8RnnANRQJkavZEpPcM/IwBvje5toOH9uHIw9SzG3i8XHuelQ9g49zbpz0h +JoGalDcQDk1vriIivNPsEo17T2jXxNiZY+BFF2hGNmxjDjenbdFu1N/TQU5ouUag +SO/h/AqO6ONCXUaPnqcYXYcaC5kY/4Ea4Vp+DcbzKu25FrQLQDcDc4Iq1RpAdHPS +WJNnR1/IKkTGBvhPHGmp8ZRohynJXPJ6AbLChhpJrJjb+fLsboLNTjIjoOsesxe9 +jzOfD9FSF9kL1esrz70= +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-cert.pem new file mode 120000 index 0000000..cf090b3 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-cert.pem @@ -0,0 +1 @@ +DC-plugindc.plugindom.samba.example.com-S02-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-private-key.pem new file mode 120000 index 0000000..64ddc96 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/plugindc.plugindom.samba.example.com/DC-plugindc.plugindom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +DC-plugindc.plugindom.samba.example.com-S02-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem new file mode 100644 index 0000000..2a1f36f --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem @@ -0,0 +1,190 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:44:51 2016 GMT + Not After : Mar 13 11:44:51 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:e6:5f:4f:b7:ba:64:00:94:b2:0b:a0:29:3b:66: + 1f:28:85:cd:fa:bb:d7:de:18:8e:e2:4b:14:ab:33: + 17:4c:5f:8b:84:0e:b2:19:cd:32:ae:2a:8e:fc:8c: + 4b:51:c0:d9:2e:de:7f:d2:d3:7a:83:9d:95:66:6d: + e0:08:1a:25:10:2f:d3:27:bf:c7:ae:3a:f9:33:e4: + 65:87:af:a2:80:87:cc:f7:69:a3:4d:8d:65:30:81: + b3:20:ca:3f:54:28:b7:d9:1f:fe:90:92:8f:34:0b: + 0c:44:eb:48:b1:54:3e:66:29:c3:aa:e8:f4:f7:2d: + 6a:0c:cc:c2:31:f5:35:76:48:ba:82:c8:d0:06:42: + 2f:cd:4e:3f:20:b5:fc:f6:72:fc:0e:fe:92:a3:97: + 16:c7:9b:40:e4:ca:5c:47:39:bd:b1:4c:09:e3:a7: + 42:c2:0d:a8:b5:3e:f9:dc:7d:39:05:4d:c8:5f:c8: + 69:dc:85:5c:3c:9a:23:07:bc:30:33:38:a6:c4:03: + 07:59:e3:97:55:84:61:65:52:80:60:fa:77:b6:76: + 5a:31:32:51:a6:22:98:b5:ab:dc:67:51:23:76:08: + 09:8e:38:1c:75:0b:9c:59:43:1f:41:04:dd:60:69: + d9:fa:31:b8:16:5e:b8:f8:27:82:16:8e:c6:ce:d9: + 56:01:68:e4:5f:f8:2d:0f:31:85:27:37:92:fa:4d: + 0b:b3:f3:6a:f4:be:30:15:0d:8e:00:b5:87:f8:67: + 5c:ae:6a:25:59:23:8c:bf:a5:02:eb:b7:cc:0c:fc: + bc:3b:bd:80:08:fc:a3:86:5f:2d:ec:79:05:8e:e4: + d2:d2:c4:a6:ab:84:e3:da:aa:58:c3:db:8b:28:4b: + 15:49:79:7e:58:19:8b:7d:3e:87:9e:79:28:15:e1: + 8a:ad:75:10:0b:71:1e:8f:e8:1f:cd:d4:9b:11:e1: + 47:26:1a:f8:d4:a3:0b:7d:08:de:a6:f1:7a:93:26: + fb:bd:78:a3:60:8a:8b:29:fe:f8:9f:7b:5e:d7:64: + 03:e1:58:23:ac:23:35:3f:4f:b9:f7:3d:d6:d7:64: + 1f:0b:6b:11:9b:10:1f:2b:49:b2:f9:63:e8:cf:bf: + ac:da:9e:b7:f7:12:91:e4:01:77:9a:7f:31:c8:b6: + af:7d:5e:4e:55:ee:3d:2a:f9:0d:56:11:49:e3:f6: + 09:8c:2f:d0:06:eb:f4:f7:65:9f:db:85:0a:57:7e: + 9a:b8:1a:60:11:18:d1:3d:1c:c0:53:65:9b:e8:00: + 93:e4:91:61:b6:e8:7b:63:d3:d8:ec:70:8d:92:54: + 12:8b:56:1f:cf:83:34:d5:44:86:cd:b6:0b:fc:95: + 8f:f9:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate localdc.samba.example.com + X509v3 Subject Key Identifier: + CD:25:BC:9E:49:98:02:88:4F:A7:5C:4F:2D:68:B9:E3:61:9F:AE:2E + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + DNS:localdc.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 15:c0:31:31:7f:65:7c:7c:a4:db:1c:23:1b:81:bf:e8:c8:ad: + c0:2e:ce:c6:8e:3a:a2:d7:8f:ad:19:9a:e9:ea:72:bd:25:bc: + 26:3c:57:a7:53:4e:c5:24:a2:3c:70:59:48:9d:f5:df:2c:bd: + b5:b4:71:fe:a6:58:15:eb:31:86:83:c9:7a:39:47:80:f1:9d: + 31:ed:e1:5a:26:3f:9c:be:06:45:93:96:d9:3b:7d:d1:9c:b2: + ea:7b:a3:71:f0:9d:c7:a1:29:ba:38:eb:e4:be:bc:e9:9d:e8: + e1:be:eb:57:5a:1e:d1:09:58:dc:77:04:85:48:ba:94:19:73: + 8f:3a:31:6d:3c:ec:37:a6:d7:94:25:e3:98:e9:3c:f6:85:c6: + 6a:8e:d5:cd:32:05:1f:76:b7:b0:5a:c5:45:c0:81:20:16:4f: + e0:bb:e7:42:06:5c:6c:ff:e6:8a:73:7b:8c:1c:98:fe:2d:47: + 8a:e0:06:38:53:77:5b:6b:13:82:f4:a6:0b:c3:b2:88:2a:05: + 96:c8:04:66:cb:59:19:08:d4:9b:0f:1f:e3:3a:48:65:32:07: + 69:39:34:d4:a3:2e:d5:19:09:c7:07:d9:71:4d:62:81:fc:5a: + be:f1:da:65:3a:24:1e:2c:40:c8:78:4a:bb:0a:4f:a4:3d:ab: + 3c:b9:22:fb:0b:5c:9f:09:95:76:6f:6b:53:3d:1f:ee:fd:3f: + cd:be:7a:61:3e:08:3b:99:69:68:91:a9:9f:b8:4f:b8:c9:1f: + d4:ed:86:61:aa:6f:4f:a8:6a:4d:b6:79:e9:af:37:d2:83:9b: + f7:61:6a:65:f6:8c:f7:f9:3b:23:b6:cc:78:bf:16:ee:a0:50: + 1f:7e:38:7b:72:1b:62:ef:17:60:db:6f:c9:29:c1:c2:53:f7: + e8:27:de:3e:22:da:f0:5f:ba:55:9f:57:6f:b9:8f:c4:7a:c5: + 72:9a:a3:95:cc:ac:fd:f3:a6:a9:da:d6:57:d3:28:7f:72:60: + a8:5b:2f:c3:b1:07:c4:c7:af:d9:3c:a9:e9:78:e1:5a:0f:da: + c9:d0:e6:5d:9a:bd:61:ef:1d:25:7f:54:08:aa:f2:6c:11:1e: + a4:46:8e:9e:e2:79:c8:c2:dd:09:1b:62:27:e6:70:7a:e4:f3: + 66:db:57:30:ce:3f:27:f5:c6:c8:f2:3f:a1:bc:dd:ec:fe:3a: + c4:b9:ad:21:73:d8:83:a5:9f:02:ba:d0:52:8a:f2:d5:25:63: + 15:82:38:25:e2:74:ce:a6:a5:32:9a:6c:52:33:ba:45:ba:01: + 16:14:5f:ce:66:89:9e:03:ed:8a:95:80:c4:cf:20:24:d4:c5: + 5b:e5:c3:51:62:57:1e:45:be:0a:47:24:b7:cb:a4:dd:6e:54: + 2c:f4:25:80:a3:85:a9:74:0c:c0:65:c9:f8:2f:9a:22:bc:85: + c9:63:8a:08:f3:c9:1c:77:9b:a8:42:5a:45:dd:be:21:be:9d: + e7:15:9b:67:19:6c:d3:da:9b:67:a8:1d:22:35:d4:16:89:ad: + 4c:c3:17:bb:9e:f5:e5:3b:a2:a6:81:34:e0:4c:36:be:bb:e5: + a3:60:7d:28:30:82:db:99:ef:c6:19:43:d1:73:24:f0:8e:d1: + 6c:3b:cc:f8:cb:1a:14:79:67:07:ea:b5:47:08:bf:11:33:29: + 01:2e:fd:44:14:33:f6:36:65:8b:a8:f8:e6:0b:84:6d:a1:91: + 08:56:c1:5d:ca:12:b6:00:ba:9c:7e:7e:9b:26:3f:d3:dd:e1: + 2f:ae:f5:76:45:ed:a2:9b:b4:a1:a9:d6:b6:f5:7e:68:80:17: + 81:fb:ef:24:dc:84:de:38:20:45:34:6c:72:e5:d6:08:61:e7: + dd:45:43:d2:06:2b:ae:d9:73:a1:fb:bb:04:3c:61:45:d3:9e: + fc:45:c0:e3:db:02:ae:45:e3:de:d1:34:00:b0:1b:0f:ce:f8: + 33:0f:87:9c:9b:5d:49:11:7a:30:15:e3:9f:76:02:82:18:c2: + a6:dd:25:a6:e0:84:1f:1d:0d:db:81:7c:df:a1:65:9b:5b:08: + e0:4e:6d:4c:76:8a:0b:09:14:7c:e1:23:ad:18:4c:02:6b:e3: + f4:e0:22:26:e1:30:7e:a5:59:22:5b:a5:73:5a:23:24:1f:1a: + 7b:e5:46:f7:0c:14:00:53:72:33:4d:c4:c4:59:3e:04:17:33: + 34:04:67:1e:cd:a0:e5:9f:85:87:77:f6:dd:03:f0:74:cf:56: + e9:99:a8:95:3a:52:db:d1:61:72:91:60:9f:80:bf:22:26:da: + d7:09:4e:df:81:30:dc:9b:b4:c1:c7:cb:97:93:bc:b7:93:a3: + db:88:cc:5e:9f:39:94:57:a5:57:d6:cd:1b:12:a4:86:62:4f: + b2:08:22:4e:d9:07:8e:27:06:82:d9:f1:ec:70:30:82:56:0c: + f7:d9:56:bf:f1:7f:fd:65:90:8d:5e:d5:13:b3:31:89:5d:e8: + df:35:2f:77:6b:b7:c7:e8:7d:89:f8:cf:9e:a5:1c:60:be:7c: + 6c:b7:0f:fa:8e:62:8e:b0:72:10:8a:04:6a:50:83:3a:38:dc: + 13:8b:89:8f:6c:0f:fc:3e:c7:36:15:37:78:5f:24:87:8a:70: + cc:3e:5a:fc:88:78:19:70:89:65:a0:c7:47:67:f2:bc:1e:f5: + 04:e7:94:ba:74:ea:2a:a7:c1:26:b1:2e:ac:64:0b:fa +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ0NTFaFw0zNjAzMTMxMTQ0NTFaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOZfT7e6ZACUsgugKTtmHyiFzfq7194YjuJLFKszF0xfi4QOshnNMq4qjvyMS1HA +2S7ef9LTeoOdlWZt4AgaJRAv0ye/x646+TPkZYevooCHzPdpo02NZTCBsyDKP1Qo +t9kf/pCSjzQLDETrSLFUPmYpw6ro9PctagzMwjH1NXZIuoLI0AZCL81OPyC1/PZy +/A7+kqOXFsebQOTKXEc5vbFMCeOnQsINqLU++dx9OQVNyF/IadyFXDyaIwe8MDM4 +psQDB1njl1WEYWVSgGD6d7Z2WjEyUaYimLWr3GdRI3YICY44HHULnFlDH0EE3WBp +2foxuBZeuPgnghaOxs7ZVgFo5F/4LQ8xhSc3kvpNC7PzavS+MBUNjgC1h/hnXK5q +JVkjjL+lAuu3zAz8vDu9gAj8o4ZfLex5BY7k0tLEpquE49qqWMPbiyhLFUl5flgZ +i30+h555KBXhiq11EAtxHo/oH83UmxHhRyYa+NSjC30I3qbxepMm+714o2CKiyn+ ++J97XtdkA+FYI6wjNT9Pufc91tdkHwtrEZsQHytJsvlj6M+/rNqet/cSkeQBd5p/ +Mci2r31eTlXuPSr5DVYRSeP2CYwv0Abr9Pdln9uFCld+mrgaYBEY0T0cwFNlm+gA +k+SRYbboe2PT2OxwjZJUEotWH8+DNNVEhs22C/yVj/kRAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFM0lvJ5JmAKIT6dcTy1oueNhn64uMB8GA1UdIwQYMBaAFEaH +hsLnGc8WTAxiy3N//Y8Z5LVCMD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBABXAMTF/ZXx8pNscIxuBv+jI +rcAuzsaOOqLXj60Zmunqcr0lvCY8V6dTTsUkojxwWUid9d8svbW0cf6mWBXrMYaD +yXo5R4DxnTHt4VomP5y+BkWTltk7fdGcsup7o3HwncehKbo46+S+vOmd6OG+61da +HtEJWNx3BIVIupQZc486MW087Dem15Ql45jpPPaFxmqO1c0yBR92t7BaxUXAgSAW +T+C750IGXGz/5opze4wcmP4tR4rgBjhTd1trE4L0pgvDsogqBZbIBGbLWRkI1JsP +H+M6SGUyB2k5NNSjLtUZCccH2XFNYoH8Wr7x2mU6JB4sQMh4SrsKT6Q9qzy5IvsL +XJ8JlXZva1M9H+79P82+emE+CDuZaWiRqZ+4T7jJH9TthmGqb0+oak22eemvN9KD +m/dhamX2jPf5OyO2zHi/Fu6gUB9+OHtyG2LvF2Dbb8kpwcJT9+gn3j4i2vBfulWf +V2+5j8R6xXKao5XMrP3zpqna1lfTKH9yYKhbL8OxB8THr9k8qel44VoP2snQ5l2a +vWHvHSV/VAiq8mwRHqRGjp7iecjC3QkbYifmcHrk82bbVzDOPyf1xsjyP6G83ez+ +OsS5rSFz2IOlnwK60FKK8tUlYxWCOCXidM6mpTKabFIzukW6ARYUX85miZ4D7YqV +gMTPICTUxVvlw1FiVx5FvgpHJLfLpN1uVCz0JYCjhal0DMBlyfgvmiK8hcljigjz +yRx3m6hCWkXdviG+necVm2cZbNPam2eoHSI11BaJrUzDF7ue9eU7oqaBNOBMNr67 +5aNgfSgwgtuZ78YZQ9FzJPCO0Ww7zPjLGhR5ZwfqtUcIvxEzKQEu/UQUM/Y2ZYuo ++OYLhG2hkQhWwV3KErYAupx+fpsmP9Pd4S+u9XZF7aKbtKGp1rb1fmiAF4H77yTc +hN44IEU0bHLl1ghh591FQ9IGK67Zc6H7uwQ8YUXTnvxFwOPbAq5F497RNACwGw/O ++DMPh5ybXUkRejAV4592AoIYwqbdJabghB8dDduBfN+hZZtbCOBObUx2igsJFHzh +I60YTAJr4/TgIibhMH6lWSJbpXNaIyQfGnvlRvcMFABTcjNNxMRZPgQXMzQEZx7N +oOWfhYd39t0D8HTPVumZqJU6UtvRYXKRYJ+AvyIm2tcJTt+BMNybtMHHy5eTvLeT +o9uIzF6fOZRXpVfWzRsSpIZiT7IIIk7ZB44nBoLZ8exwMIJWDPfZVr/xf/1lkI1e +1ROzMYld6N81L3drt8fofYn4z56lHGC+fGy3D/qOYo6wchCKBGpQgzo43BOLiY9s +D/w+xzYVN3hfJIeKcMw+WvyIeBlwiWWgx0dn8rwe9QTnlLp06iqnwSaxLqxkC/o= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem new file mode 100644 index 0000000..deb2b73 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:45:11 2016 GMT + Not After : Mar 13 11:45:11 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:07:44:3a:5f:f6:34:5f:27:8a:7a:6e:2f:fb: + 45:1f:c3:3d:dd:2c:43:65:f1:7a:29:3f:42:26:bd: + ff:4f:5d:91:c0:bb:75:e3:81:14:7d:59:72:78:96: + 1a:5e:8d:95:93:f4:5d:92:79:0e:24:77:4f:8b:08: + 4e:72:b1:99:88:63:06:74:b2:dc:f7:82:62:e9:dd: + 6f:e5:a7:b4:c9:44:0c:e4:43:41:f8:57:a9:20:b1: + 70:c1:76:a1:48:5b:e9:54:b6:4f:22:50:93:90:f0: + 62:32:50:9a:6e:22:6b:37:a0:f7:1f:fc:b1:5f:ae: + e2:0b:88:6d:ea:29:b6:01:27:b2:84:ef:10:4d:6c: + 0a:df:ea:a9:8a:82:98:60:a7:52:73:a4:f7:7c:b2: + 4a:b9:f0:9b:c4:f8:19:5a:c0:84:54:52:35:c8:92: + 4f:16:af:d6:36:a6:78:57:55:e5:5e:6b:62:00:fa: + 48:c2:7a:e7:17:38:b5:23:d5:a8:fb:7d:df:42:5c: + 03:f4:7c:ef:ff:f1:a0:e6:d8:27:93:06:b3:a3:21: + 68:0e:c4:60:20:02:46:2f:2b:d8:88:e4:2b:01:c2: + 31:5a:55:28:be:55:03:f2:06:2b:e4:ec:48:60:e4: + b6:db:a1:f0:c5:24:ba:e1:a8:e2:6a:fb:0b:40:6c: + 3d:f5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@samba.example.com + X509v3 Subject Key Identifier: + 70:86:EC:68:B4:51:8A:1C:12:65:A0:2A:B3:43:33:12:65:83:8D:40 + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + email:administrator@samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 5d:b1:10:f8:36:dd:a9:fd:8d:be:31:53:1d:cf:b5:ea:33:1a: + 85:0f:13:8d:cc:67:91:41:97:e4:e9:67:6a:0c:ce:a4:9a:06: + b3:53:bf:e6:6d:f1:d1:32:7d:54:5d:6a:a8:94:fe:d4:f6:62: + 85:0f:e0:73:f8:ce:51:32:18:65:50:34:f9:f2:66:f8:ec:fd: + 94:c2:1d:28:6f:ce:3c:b3:0a:0a:cc:8b:fb:2c:e8:44:d2:d8: + 64:d7:19:1c:a4:25:5f:75:63:bc:44:56:64:cb:ca:8c:43:75: + 1e:95:36:98:a1:c6:49:e6:14:60:ad:87:91:af:d8:3c:d2:63: + 52:82:02:0a:42:c0:e3:7b:50:51:37:d5:c0:a5:0c:09:ac:2d: + a0:b3:29:e4:9e:bf:d3:df:01:82:00:a5:ad:fb:35:e8:f6:1c: + d7:cb:d1:3c:54:1f:d2:73:38:ce:a6:0a:e2:77:0a:fc:e5:ff: + 7e:68:a6:c7:57:fd:c7:cf:95:48:9f:97:6f:fe:2e:9f:e3:d6: + b0:a5:b5:33:9f:12:c1:e6:12:15:77:33:8f:1e:35:b5:88:f8: + 6b:47:88:e4:cb:49:f7:11:ba:19:39:55:5e:4a:5a:65:76:7e: + cc:3a:a7:fa:91:9a:ef:b5:c1:bf:f0:e7:a2:c6:9f:08:17:fc: + 4c:a4:ef:0b:d8:c7:a4:f9:74:36:b3:67:90:5e:84:26:83:bd: + 36:89:0d:c6:8c:1d:03:ce:8f:80:c9:0c:c6:c0:1e:eb:42:e7: + 97:7f:21:ac:b1:64:06:f6:1d:6d:0c:87:ff:c9:30:23:d3:21: + 1f:53:05:69:21:d5:26:ca:7f:ce:3a:4e:8d:d1:40:16:7e:a2: + c0:0f:95:0c:67:90:47:d2:e2:cf:87:ef:dc:35:18:2a:a2:21: + cd:67:b0:b2:14:9f:75:94:93:ba:8c:4d:45:71:cb:e9:df:cd: + f5:e3:f0:ff:c3:38:77:c2:41:55:d6:60:96:d8:bd:5f:09:22: + 97:44:8d:4d:b1:dd:68:39:04:1b:7a:57:3b:ca:56:27:87:31: + 55:84:6c:f0:65:af:ec:0b:52:87:28:0b:2d:52:c0:ce:a3:7d: + 7b:47:07:df:8a:65:e9:6f:da:e7:b6:94:06:69:b8:55:3d:11: + 01:c6:bf:0b:61:1b:cc:30:47:ab:cf:fb:72:62:f3:eb:66:11: + cd:1c:ab:4e:29:bf:b7:78:d6:09:ec:d7:67:5b:17:b9:34:cc: + af:5e:d9:02:0b:33:fc:a1:f2:64:33:c4:af:11:5b:08:f7:af: + ba:0d:68:d7:cf:d2:40:2f:56:20:34:da:82:18:7c:0e:71:61: + a6:58:60:00:30:a6:c7:25:3a:90:70:a0:14:e6:da:d8:12:e9: + b3:6a:c4:96:85:41:80:a6:71:17:b5:cf:4f:a2:2d:51:93:fd: + 26:eb:44:3c:2a:84:6a:da:18:10:d6:48:e3:8e:0f:c9:69:05: + 96:8c:96:f9:74:06:ab:11:d2:e4:e5:d7:22:db:13:93:d6:f9: + 24:84:56:7c:6a:43:a9:b8:30:33:2c:a4:42:9f:ec:f6:56:2d: + 46:cf:ec:26:49:5e:da:53:21:6b:8c:05:0d:b7:12:26:29:43: + 32:b2:6c:ed:07:47:75:2b:0b:7e:5d:28:1b:5b:7b:b5:63:13: + 55:4d:f7:a3:f6:fd:2d:f5:6d:43:83:40:46:b3:0d:d6:28:99: + d4:fb:89:fb:41:c6:15:35:a5:ee:1a:08:33:b3:0b:75:0a:d0: + fc:31:ec:77:80:e2:f0:ab:20:cc:43:24:67:42:a5:d7:e6:b0: + b9:84:fd:43:a0:5e:d9:78:10:97:d3:d1:b7:d9:33:70:0f:4d: + f0:a1:ac:22:d7:36:53:68:6d:39:e0:14:dc:d7:ea:1e:c2:92: + 1b:f8:2a:99:97:14:76:2c:89:3f:b7:89:c7:69:6e:5b:dd:8e: + 47:7a:f0:0e:a4:d0:18:c6:c4:34:f0:b8:84:3a:6e:ee:1e:7b: + 84:58:d2:10:a6:a2:0c:14:a8:55:e9:c5:7e:ab:97:e4:9d:b5: + f0:9f:2e:36:ac:2f:73:30:c8:b1:fc:b4:ce:b4:39:bd:59:75: + b8:24:5a:b1:67:de:34:3f:4e:17:5d:d3:bc:bb:6a:6a:b7:3e: + 0b:e8:4d:3b:08:d6:de:a7:9a:d7:8d:60:56:bb:3e:6c:d0:a7: + f8:45:a2:52:a3:b5:1e:ef:56:df:14:62:52:ed:36:ab:cc:7a: + a1:96:14:9a:e9:de:4a:28:68:bd:21:2d:60:d5:06:8a:e9:5e: + b6:ce:e1:b4:ed:56:9f:99:87:fe:20:bb:d5:8d:0d:72:1d:7e: + 88:27:9c:66:d5:26:aa:32:0a:ad:64:de:b8:13:2d:51:cc:8b: + e2:f4:c1:63:a6:64:e8:03:08:42:38:bf:f4:fe:b3:25:03:1b: + 14:b9:68:81:14:b9:5d:b9:6a:eb:f0:a9:24:41:8e:49:03:be: + 0b:55:cf:ac:77:68:ed:54:ae:55:40:dd:31:c4:3a:e2:d7:86: + d5:d5:e4:5e:5b:ce:9e:da:a1:90:58:e1:b3:7c:a6:87:15:bd: + 3a:67:b9:ab:29:de:4f:af:08:98:89:45:62:8f:db:5b:2e:2b: + e8:97:35:a2:fc:4f:cf:63:7d:56:a0:51:dd:3f:b2:90:a6:9b: + a0:9b:9e:93:8d:9d:92:b2:ed:36:d5:e1:f1:e3:97:dc +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ1MTFaFw0zNjAzMTMxMTQ1MTFaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJB0Q6X/Y0XyeKem4v ++0Ufwz3dLENl8XopP0Imvf9PXZHAu3XjgRR9WXJ4lhpejZWT9F2SeQ4kd0+LCE5y +sZmIYwZ0stz3gmLp3W/lp7TJRAzkQ0H4V6kgsXDBdqFIW+lUtk8iUJOQ8GIyUJpu +Ims3oPcf/LFfruILiG3qKbYBJ7KE7xBNbArf6qmKgphgp1JzpPd8skq58JvE+Bla +wIRUUjXIkk8Wr9Y2pnhXVeVea2IA+kjCeucXOLUj1aj7fd9CXAP0fO//8aDm2CeT +BrOjIWgOxGAgAkYvK9iI5CsBwjFaVSi+VQPyBivk7Ehg5LbbofDFJLrhqOJq+wtA +bD31AgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFHCG7Gi0UYoc +EmWgKrNDMxJlg41AMB8GA1UdIwQYMBaAFEaHhsLnGc8WTAxiy3N//Y8Z5LVCMFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAXbEQ+Dbdqf2NvjFTHc+1 +6jMahQ8TjcxnkUGX5OlnagzOpJoGs1O/5m3x0TJ9VF1qqJT+1PZihQ/gc/jOUTIY +ZVA0+fJm+Oz9lMIdKG/OPLMKCsyL+yzoRNLYZNcZHKQlX3VjvERWZMvKjEN1HpU2 +mKHGSeYUYK2Hka/YPNJjUoICCkLA43tQUTfVwKUMCawtoLMp5J6/098BggClrfs1 +6PYc18vRPFQf0nM4zqYK4ncK/OX/fmimx1f9x8+VSJ+Xb/4un+PWsKW1M58SweYS +FXczjx41tYj4a0eI5MtJ9xG6GTlVXkpaZXZ+zDqn+pGa77XBv/DnosafCBf8TKTv +C9jHpPl0NrNnkF6EJoO9NokNxowdA86PgMkMxsAe60Lnl38hrLFkBvYdbQyH/8kw +I9MhH1MFaSHVJsp/zjpOjdFAFn6iwA+VDGeQR9Liz4fv3DUYKqIhzWewshSfdZST +uoxNRXHL6d/N9ePw/8M4d8JBVdZglti9Xwkil0SNTbHdaDkEG3pXO8pWJ4cxVYRs +8GWv7AtShygLLVLAzqN9e0cH34pl6W/a57aUBmm4VT0RAca/C2EbzDBHq8/7cmLz +62YRzRyrTim/t3jWCezXZ1sXuTTMr17ZAgsz/KHyZDPErxFbCPevug1o18/SQC9W +IDTaghh8DnFhplhgADCmxyU6kHCgFOba2BLps2rEloVBgKZxF7XPT6ItUZP9JutE +PCqEatoYENZI444PyWkFloyW+XQGqxHS5OXXItsTk9b5JIRWfGpDqbgwMyykQp/s +9lYtRs/sJkle2lMha4wFDbcSJilDMrJs7QdHdSsLfl0oG1t7tWMTVU33o/b9LfVt +Q4NARrMN1iiZ1PuJ+0HGFTWl7hoIM7MLdQrQ/DHsd4Di8KsgzEMkZ0Kl1+awuYT9 +Q6Be2XgQl9PRt9kzcA9N8KGsItc2U2htOeAU3NfqHsKSG/gqmZcUdiyJP7eJx2lu +W92OR3rwDqTQGMbENPC4hDpu7h57hFjSEKaiDBSoVenFfquX5J218J8uNqwvczDI +sfy0zrQ5vVl1uCRasWfeND9OF13TvLtqarc+C+hNOwjW3qea141gVrs+bNCn+EWi +UqO1Hu9W3xRiUu02q8x6oZYUmuneSihovSEtYNUGiulets7htO1Wn5mH/iC71Y0N +ch1+iCecZtUmqjIKrWTeuBMtUcyL4vTBY6Zk6AMIQji/9P6zJQMbFLlogRS5Xblq +6/CpJEGOSQO+C1XPrHdo7VSuVUDdMcQ64teG1dXkXlvOntqhkFjhs3ymhxW9Ome5 +qyneT68ImIlFYo/bWy4r6Jc1ovxPz2N9VqBR3T+ykKaboJuek42dkrLtNtXh8eOX +3A== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem new file mode 100644 index 0000000..4cc42aa --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem @@ -0,0 +1,191 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:45:30 2016 GMT + Not After : Mar 13 11:45:30 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=plugindc.plugindom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:aa:a3:74:2b:4b:6d:29:43:67:03:dc:c0:be:ce: + a6:e3:43:99:e5:87:34:34:42:70:4b:bb:50:87:6d: + e8:65:2b:5e:1a:b3:68:0d:9f:27:eb:dc:b8:84:bb: + 3d:f4:40:28:c0:c7:aa:e5:8d:a1:d5:7f:c7:6b:36: + 96:6b:3e:65:72:37:0e:d4:2c:03:4d:ee:e6:f8:41: + 5c:27:bf:32:53:6c:13:28:1f:be:78:9c:7c:80:53: + eb:4d:0a:19:1a:88:49:95:a9:c6:65:23:5b:3e:24: + 27:06:eb:7c:58:24:c6:e7:a4:d9:98:02:c4:ce:b3: + 1e:01:34:4c:bd:9c:28:da:10:4d:36:e9:7d:a8:68: + 04:75:18:eb:f0:58:94:05:b1:61:97:d5:9a:b3:db: + 09:71:74:90:05:87:d4:1c:ff:06:2b:c0:51:b6:26: + ca:28:8b:c2:08:3a:93:62:f8:69:b4:3b:c3:6d:9b: + 0f:80:1d:f8:c3:51:93:78:64:83:63:c7:d0:21:e8: + 05:cd:22:3e:3e:e2:c2:66:af:46:6c:c6:7d:d8:ed: + 53:b9:cc:42:e9:a2:43:94:31:f4:9e:45:fa:45:35: + ab:7f:32:93:95:a5:1b:4a:9d:27:c0:5f:bf:03:7f: + ca:37:c3:c2:c9:6f:b6:6e:5f:05:55:56:f5:2f:40: + c2:41:12:17:ee:23:1b:3a:9c:39:74:d5:cc:b1:47: + 6a:24:85:95:f5:aa:e6:35:40:0c:d3:8f:1e:d3:df: + b5:1b:7c:ff:3f:df:7e:7a:d3:f8:e1:92:b0:41:14: + f6:aa:1d:8c:36:3d:5c:c5:c5:b7:2f:b8:f8:09:47: + c2:51:58:de:80:41:c2:a5:18:c6:a9:16:39:d4:8e: + ef:f3:a9:c6:13:db:1e:f5:8a:e7:37:16:7c:df:28: + fe:19:44:7b:58:98:ee:72:fa:41:a2:f5:e0:77:c2: + 5e:fa:e1:94:87:96:17:66:75:07:45:c8:df:6a:40: + 19:3b:da:4d:48:e8:51:a3:1f:ba:41:62:0a:48:f5: + 62:42:9e:69:49:aa:ac:36:bd:6f:41:32:bb:62:8a: + 96:6b:01:aa:de:14:05:3a:43:e9:45:f2:00:9a:dc: + 71:20:b7:65:f2:f0:7d:b3:74:a0:43:1c:3f:5e:22: + 47:df:47:8d:5e:cb:93:1a:14:6e:b4:29:0f:af:1c: + 07:9c:11:74:24:38:09:23:76:0e:ca:fc:60:8f:1a: + e2:dc:d4:fd:fe:cb:12:f8:a7:83:c4:ae:db:a4:c7: + 74:b3:a5:76:90:93:9d:a3:78:01:97:e0:ec:09:78: + b9:98:ff:b7:2a:9d:05:03:5e:cf:b2:01:80:79:6b: + f9:5d:f5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate plugindc.plugindom.samba.example.com + X509v3 Subject Key Identifier: + DB:4F:D4:70:C3:38:E6:26:37:6F:1B:50:5E:7D:E5:80:7D:B4:08:0D + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + DNS:plugindc.plugindom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + ab:ed:44:9c:0d:f9:df:d6:8d:f2:98:05:cb:97:0c:14:9d:0c: + b3:2b:49:6c:4f:d6:8f:81:dd:c7:d9:67:be:ad:5b:f6:08:34: + 44:09:88:3a:9d:e9:fe:0b:91:89:f8:32:92:43:43:af:cf:04: + 5c:35:a4:d2:04:77:04:bf:37:45:57:2b:70:94:d0:7a:5f:b9: + d6:9c:47:ac:46:e4:4c:c2:87:5d:78:b7:3c:be:80:42:dc:3c: + 36:3b:c0:57:fb:ec:95:3a:bb:58:7e:09:ff:57:4e:4f:59:73: + 2a:65:0e:6e:a8:b3:8e:22:6b:40:0c:b5:5b:96:f3:a1:35:92: + 17:12:24:f3:43:fe:54:1d:ac:f9:f1:72:cb:97:b8:43:2f:e1: + ac:9c:a6:e7:78:98:38:ad:83:eb:c9:77:0b:ea:5a:21:6a:76: + f7:b2:4c:d7:7b:d4:57:eb:4c:a4:6e:be:eb:be:60:99:ae:ce: + 13:1c:6a:9f:58:e5:64:a2:b6:4e:2a:2e:62:99:d8:fa:af:11: + 5c:7e:51:d3:cf:7e:84:1c:f4:8b:a5:df:c8:b2:39:4c:c3:40: + 48:2e:b6:9d:3d:bf:b1:7b:58:39:f0:38:60:72:42:f4:8c:2a: + b3:66:c1:e9:12:bc:2a:51:75:55:1e:56:2a:bc:6e:40:1c:2b: + 16:25:90:97:18:4e:b4:63:dc:ff:7a:31:5e:b2:38:c4:17:65: + 3d:1a:31:47:04:75:3a:b7:83:c3:59:09:d5:99:56:45:4d:a0: + c8:6f:3e:87:61:17:4f:2e:7b:5c:34:76:45:e1:b5:bf:c4:fe: + 32:31:ff:2c:95:52:9c:12:2a:c3:b8:04:f9:25:a3:11:64:35: + c8:5d:92:f9:fc:2c:ba:45:18:d0:dc:95:1c:dd:30:16:3f:56: + a4:15:45:85:9b:52:55:3f:f6:a8:dd:54:53:d2:84:1b:d3:1a: + 97:61:8a:60:d6:fb:a1:75:f3:15:8f:b7:f3:f4:41:dc:7d:24: + 90:9a:62:23:a1:ef:c1:01:69:d4:a1:69:82:58:5f:35:b4:83: + b1:7c:cf:dc:f2:ca:23:af:5a:ac:e9:53:53:bd:33:8e:22:2a: + 1b:cf:ea:e7:e0:24:b2:f5:f7:ff:f6:99:6c:34:13:e9:f2:50: + 70:a1:0f:ec:f9:12:22:99:58:08:5d:f0:49:86:f8:14:3b:1b: + e6:49:eb:9b:fb:b1:07:60:e0:05:e6:4f:13:39:d1:ea:07:6b: + e8:85:33:eb:4f:b7:d3:7f:bd:9b:f4:a4:40:f4:a4:4a:f6:5f: + db:04:f5:f8:04:fa:1a:13:1b:cc:75:6f:c2:df:9d:89:12:5b: + f1:fa:cf:df:b6:32:3c:3c:5e:e0:26:9a:c7:e7:87:e7:5b:9a: + 76:b3:41:a3:0f:e1:f2:12:69:db:1b:32:57:a4:ad:5b:52:32: + 8d:7e:ec:34:c4:ce:d2:ee:6b:96:56:0e:ef:97:9a:26:a3:b5: + a0:4c:9a:e0:4f:9b:8d:07:df:92:46:1b:53:53:eb:96:62:74: + a8:13:03:e3:1f:13:0e:48:22:ca:ba:94:7f:86:80:c0:76:ab: + 08:36:e4:02:f3:ad:31:2f:97:00:06:57:09:12:66:d5:4e:8f: + 5b:88:67:7c:e3:0f:df:1c:97:17:85:9f:b9:08:4c:6e:88:e3: + e7:b9:53:06:87:98:e8:a3:9f:7c:7d:c9:07:d8:69:74:d1:e7: + c1:e6:46:e9:0f:2d:4f:04:6d:41:e8:b8:a7:87:d4:5b:1f:89: + e4:b1:c0:ba:78:2e:7d:cf:84:56:25:56:95:f7:93:dd:4a:47: + 88:b5:ac:d7:da:a7:b3:c9:8c:c5:41:34:8c:31:24:84:d4:51: + bb:46:4a:3c:db:72:e6:1b:c1:c2:15:6e:1a:ac:61:bd:ce:f1: + a3:ff:60:d9:a7:90:5a:3a:3e:1c:28:13:ed:cf:ef:ed:f1:fb: + 79:3a:57:ac:41:de:e6:17:d0:92:c6:fc:bd:6a:1c:e0:44:c7: + d7:ce:80:b4:c2:59:75:a8:bc:8b:32:4e:ea:2a:ff:89:fb:f9: + 98:6b:04:1a:fd:9e:2e:b9:bf:60:d5:84:80:f8:5b:03:0d:d9: + 1e:30:cf:4e:78:2c:a1:88:6d:ee:80:a2:ec:d9:96:00:c9:82: + a2:81:c0:6e:74:4b:69:9f:fd:c2:ed:0a:f7:31:a9:dc:89:f7: + c5:83:83:51:bf:f0:f6:8f:22:72:8e:f6:0b:54:d0:b8:7a:39: + 62:d1:d8:76:bd:c3:85:be:18:41:e9:42:c2:80:21:1c:86:20: + f9:4b:55:5f:e3:e1:6e:ae:ab:0a:4a:0c:05:1f:0d:b5:1f:a0: + d6:92:dd:20:71:56:74:e8:13:83:2f:4f:d0:72:98:b8:57:b5: + cc:06:63:3b:29:5b:f7:be:fc:e1:0e:24:94:da:1c:d1:ba:9f: + 7b:af:0d:d9:80:ed:18:85:74:73:62:2f:cb:37:e2:8c:85:90: + e9:86:dc:2b:78:b5:2a:47:fb:a1:41:f1:d4:2f:66:87:17:a5: + 24:20:54:61:99:03:72:56:5f:96:92:bf:25:4e:d0:20:a0:26: + 85:ac:b1:d2:7b:b9:b9:e9:9c:9d:01:52:a7:29:32:bd:94:65: + fb:bc:41:d2:9e:6c:59:c7:9a:b6:92:38:ba:fa:08:fc:1f:c7: + 72:9a:a3:a2:cb:02:e3:fc:29:20:20:b7:15:76:73:ab +-----BEGIN CERTIFICATE----- +MIIKDDCCBfSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ1MzBaFw0zNjAzMTMxMTQ1MzBaMIHAMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMS0wKwYDVQQDDCRwbHVnaW5kYy5wbHVnaW5k +b20uc2FtYmEuZXhhbXBsZS5jb20xNTAzBgkqhkiG9w0BCQEWJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEAqqN0K0ttKUNnA9zAvs6m40OZ5Yc0NEJwS7tQh23oZSteGrNo +DZ8n69y4hLs99EAowMeq5Y2h1X/HazaWaz5lcjcO1CwDTe7m+EFcJ78yU2wTKB++ +eJx8gFPrTQoZGohJlanGZSNbPiQnBut8WCTG56TZmALEzrMeATRMvZwo2hBNNul9 +qGgEdRjr8FiUBbFhl9Was9sJcXSQBYfUHP8GK8BRtibKKIvCCDqTYvhptDvDbZsP +gB34w1GTeGSDY8fQIegFzSI+PuLCZq9GbMZ92O1TucxC6aJDlDH0nkX6RTWrfzKT +laUbSp0nwF+/A3/KN8PCyW+2bl8FVVb1L0DCQRIX7iMbOpw5dNXMsUdqJIWV9arm +NUAM048e09+1G3z/P99+etP44ZKwQRT2qh2MNj1cxcW3L7j4CUfCUVjegEHCpRjG +qRY51I7v86nGE9se9YrnNxZ83yj+GUR7WJjucvpBovXgd8Je+uGUh5YXZnUHRcjf +akAZO9pNSOhRox+6QWIKSPViQp5pSaqsNr1vQTK7YoqWawGq3hQFOkPpRfIAmtxx +ILdl8vB9s3SgQxw/XiJH30eNXsuTGhRutCkPrxwHnBF0JDgJI3YOyvxgjxri3NT9 +/ssS+KeDxK7bpMd0s6V2kJOdo3gBl+DsCXi5mP+3Kp0FA17PsgGAeWv5XfUCAwEA +AaOCAgcwggIDMAkGA1UdEwQCMAAwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3 +dy5zYW1iYS5leGFtcGxlLmNvbS9jcmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNy +bC5jcmwwEQYJYIZIAYb4QgEBBAQDAgZAMAsGA1UdDwQEAwIF4DBRBglghkgBhvhC +AQ0ERBZCRG9tYWluIENvbnRyb2xsZXIgQ2VydGlmaWNhdGUgcGx1Z2luZGMucGx1 +Z2luZG9tLnNhbWJhLmV4YW1wbGUuY29tMB0GA1UdDgQWBBTbT9RwwzjmJjdvG1Be +feWAfbQIDTAfBgNVHSMEGDAWgBRGh4bC5xnPFkwMYstzf/2PGeS1QjBIBgNVHREE +QTA/giRwbHVnaW5kYy5wbHVnaW5kb20uc2FtYmEuZXhhbXBsZS5jb22gFwYJKwYB +BAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUu +Y29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRwOi8vd3d3 +LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5jb20tY3Js +LmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJ +KoZIhvcNAQELBQADggQBAKvtRJwN+d/WjfKYBcuXDBSdDLMrSWxP1o+B3cfZZ76t +W/YINEQJiDqd6f4LkYn4MpJDQ6/PBFw1pNIEdwS/N0VXK3CU0HpfudacR6xG5EzC +h114tzy+gELcPDY7wFf77JU6u1h+Cf9XTk9ZcyplDm6os44ia0AMtVuW86E1khcS +JPND/lQdrPnxcsuXuEMv4aycpud4mDitg+vJdwvqWiFqdveyTNd71FfrTKRuvuu+ +YJmuzhMcap9Y5WSitk4qLmKZ2PqvEVx+UdPPfoQc9Iul38iyOUzDQEgutp09v7F7 +WDnwOGByQvSMKrNmwekSvCpRdVUeViq8bkAcKxYlkJcYTrRj3P96MV6yOMQXZT0a +MUcEdTq3g8NZCdWZVkVNoMhvPodhF08ue1w0dkXhtb/E/jIx/yyVUpwSKsO4BPkl +oxFkNchdkvn8LLpFGNDclRzdMBY/VqQVRYWbUlU/9qjdVFPShBvTGpdhimDW+6F1 +8xWPt/P0Qdx9JJCaYiOh78EBadShaYJYXzW0g7F8z9zyyiOvWqzpU1O9M44iKhvP +6ufgJLL19//2mWw0E+nyUHChD+z5EiKZWAhd8EmG+BQ7G+ZJ65v7sQdg4AXmTxM5 +0eoHa+iFM+tPt9N/vZv0pED0pEr2X9sE9fgE+hoTG8x1b8LfnYkSW/H6z9+2Mjw8 +XuAmmsfnh+dbmnazQaMP4fISadsbMlekrVtSMo1+7DTEztLua5ZWDu+XmiajtaBM +muBPm40H35JGG1NT65ZidKgTA+MfEw5IIsq6lH+GgMB2qwg25ALzrTEvlwAGVwkS +ZtVOj1uIZ3zjD98clxeFn7kITG6I4+e5UwaHmOijn3x9yQfYaXTR58HmRukPLU8E +bUHouKeH1FsfieSxwLp4Ln3PhFYlVpX3k91KR4i1rNfap7PJjMVBNIwxJITUUbtG +SjzbcuYbwcIVbhqsYb3O8aP/YNmnkFo6PhwoE+3P7+3x+3k6V6xB3uYX0JLG/L1q +HOBEx9fOgLTCWXWovIsyTuoq/4n7+ZhrBBr9ni65v2DVhID4WwMN2R4wz054LKGI +be6AouzZlgDJgqKBwG50S2mf/cLtCvcxqdyJ98WDg1G/8PaPInKO9gtU0Lh6OWLR +2Ha9w4W+GEHpQsKAIRyGIPlLVV/j4W6uqwpKDAUfDbUfoNaS3SBxVnToE4MvT9By +mLhXtcwGYzspW/e+/OEOJJTaHNG6n3uvDdmA7RiFdHNiL8s34oyFkOmG3Ct4tSpH ++6FB8dQvZocXpSQgVGGZA3JWX5aSvyVO0CCgJoWssdJ7ubnpnJ0BUqcpMr2UZfu8 +QdKebFnHmraSOLr6CPwfx3Kao6LLAuP8KSAgtxV2c6s= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem new file mode 100644 index 0000000..223d407 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem @@ -0,0 +1,170 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:46:04 2016 GMT + Not After : Mar 13 11:46:04 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@plugindom.samba.example.com/emailAddress=administrator@plugindom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bc:1c:03:de:e6:1e:17:1a:85:5b:13:b8:a9:b1: + 26:36:b2:7c:4e:d2:8a:3f:20:37:ea:57:f6:46:38: + 9e:86:26:cd:73:cc:6d:a6:a1:4e:21:29:89:f0:7e: + 75:a5:8d:5f:92:42:9d:88:81:21:66:8c:2f:1b:f5: + 14:54:6b:ed:18:c9:a7:a6:a7:16:07:10:27:77:31: + d4:90:a5:cd:a2:9c:96:c0:18:92:76:f9:12:40:ec: + 51:54:12:36:ce:c5:02:fd:9e:b9:80:4c:81:e9:7e: + 5b:59:2d:4a:7c:0a:35:0c:0f:85:a0:b9:93:23:77: + 35:8b:de:18:e7:5d:3e:25:27:cc:0e:f0:0f:ab:40: + a5:08:02:84:f1:cf:9b:66:37:12:37:02:4c:03:43: + 04:d5:a9:ad:6e:d2:88:c4:85:fa:f3:9f:f2:5d:6d: + 1f:f4:54:a1:d7:4a:93:c5:42:e9:cb:da:ff:bd:70: + 8b:27:75:4d:77:b0:ea:97:f1:80:75:84:57:5e:1e: + e5:a5:d9:89:28:e8:44:a0:77:66:08:64:51:c0:4a: + d0:06:c7:b1:b4:1e:6b:0a:94:a0:61:5a:9e:7b:5b: + d6:48:ab:1e:7e:65:43:d9:e0:91:51:f5:2b:43:99: + a1:94:bb:7f:aa:2b:e9:54:69:c4:e3:f1:e0:38:77: + 9f:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@plugindom.samba.example.com + X509v3 Subject Key Identifier: + 1D:D6:74:30:69:F7:2D:5F:81:E4:83:F1:7E:B0:08:F3:9C:06:41:E4 + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + email:administrator@plugindom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 2c:23:ad:2f:a2:83:57:e8:42:b3:27:43:7f:aa:9d:99:ae:9d: + 20:7f:0a:b0:f4:32:33:ad:ee:fe:33:aa:20:09:8e:4b:4b:0d: + 12:b1:d5:0c:29:bc:13:aa:04:49:ce:2c:b7:01:e7:68:e9:ef: + 77:a9:dd:b6:9a:0a:11:bf:88:46:0c:09:7b:ac:6b:ed:6a:8e: + 72:fc:d8:28:46:21:48:8f:27:04:67:2c:17:2b:33:f7:8c:18: + ca:c6:3d:0e:76:36:fe:6b:03:77:eb:97:28:a9:64:4b:46:32: + 38:23:f5:6f:d9:43:b6:4e:c6:b5:14:0c:c5:09:0c:55:94:06: + 92:26:10:66:44:90:64:fa:e8:ae:75:43:a0:bd:14:9a:31:37: + 87:30:b7:61:87:65:40:b7:c1:2e:94:4c:0a:ed:4c:c2:75:2d: + 60:57:f9:b3:cf:b2:ef:19:c3:96:a6:25:d3:1d:92:16:9e:af: + e4:e4:ca:87:77:4b:13:31:48:de:99:1a:9c:ea:9a:27:96:bc: + 16:48:af:83:41:8c:56:d4:9c:6f:c5:9a:31:c9:35:3a:a5:c9: + cc:7f:9f:3d:c2:56:03:6b:df:b3:ac:c0:47:ce:53:5c:bd:38: + 7d:57:d4:c3:59:c9:b7:0a:89:ac:c2:15:a4:4d:50:84:67:91: + 59:6d:28:a1:78:0c:2e:20:39:06:9d:0c:2d:a7:c4:dc:98:eb: + 4f:b4:58:6d:6a:ba:b0:5a:e9:87:7f:c9:11:a5:7c:b7:91:49: + f5:0a:e7:f9:c9:7c:ba:30:3d:95:a7:8a:66:47:ed:49:53:74: + 85:e3:63:d5:38:34:76:e7:3e:2c:74:b6:58:23:5b:93:be:eb: + b2:98:9c:7e:bd:0e:5f:fa:98:4d:76:13:b7:5d:22:bc:76:5b: + 13:88:8d:84:8b:fc:a4:25:99:82:3b:1e:2e:58:2a:8f:d7:36: + ec:fb:d6:1e:76:b8:0a:31:fa:56:18:38:96:d5:0e:d7:dd:ac: + 70:a6:c1:80:0e:9c:9b:44:e7:e8:b6:8a:64:8d:7c:9c:57:6a: + 90:ce:2b:c1:c6:da:f5:68:1d:c4:37:58:70:f7:ba:3d:4f:2e: + 6c:a6:a2:3b:12:1e:1c:ea:99:bb:ac:54:57:18:c0:d3:7f:8a: + c8:7e:73:8e:b1:06:6b:55:57:e3:4f:46:9e:db:50:55:1d:c9: + 61:99:de:31:79:75:bc:b1:d6:fe:17:b2:fd:cb:36:3a:12:6b: + 0f:c8:b0:a6:be:e1:a4:de:5b:76:02:bc:e4:9b:f9:df:e1:ed: + bb:dc:40:62:1b:05:34:c0:53:10:47:ac:c7:18:6e:7c:17:37: + 86:f3:84:91:17:00:f3:69:45:3f:fe:fe:3c:c6:b2:13:82:70: + fa:fc:1b:51:d0:56:19:b0:9e:9f:1d:27:75:27:81:f1:85:b2: + 15:7f:ac:f1:8d:de:fe:3a:57:0f:13:4f:d8:7c:9d:f3:49:a2: + fe:5a:e8:91:8c:38:c2:4b:9a:f3:49:0c:92:70:62:8e:ed:91: + 8a:3e:da:ab:96:d6:46:5f:25:e6:82:cd:29:03:20:83:3b:63: + c2:5b:34:92:12:98:13:b4:56:2d:1d:cf:4b:22:f8:40:fb:7f: + ae:3e:49:52:54:de:02:95:0a:f2:22:6f:e1:2c:bd:a4:08:8d: + ec:83:79:4a:a8:ee:27:0e:b8:6a:65:4f:ba:be:8a:94:02:ad: + ef:72:3e:07:52:52:51:58:6c:e7:20:e4:81:49:da:7f:f1:dd: + ea:2b:56:f4:29:75:16:df:b8:19:da:63:b2:a0:d3:93:5d:a6: + 81:f4:2d:d3:fb:cb:7c:e3:04:8e:38:9d:66:9d:29:57:28:22: + e3:7a:5b:48:cf:6e:79:32:24:6e:e4:dc:7a:05:22:2c:a4:0e: + 30:74:41:cd:34:ef:3d:33:4e:01:3e:65:25:01:cc:5d:73:5a: + 10:d6:df:45:24:93:69:fa:d3:ab:7f:c8:b7:5a:86:1c:88:be: + 32:05:2f:f8:2a:26:02:f5:cc:30:4a:dd:97:0a:3a:db:c0:0c: + 67:36:90:9b:f9:2c:e3:d0:04:26:46:c1:a3:4e:a0:46:be:f3: + 8b:91:9c:d5:f0:32:09:c5:f0:a3:51:bf:05:70:83:51:25:ba: + 6f:8c:25:ea:30:96:52:e6:53:64:38:ac:0e:de:54:e7:5f:da: + 30:e0:39:9b:d8:64:d5:3b:70:4f:9a:27:96:36:98:9b:f5:07: + 0b:4a:89:40:06:18:9d:6d:e2:6c:40:51:af:83:66:73:87:56: + 5c:fa:38:96:a8:dd:4a:28:4a:82:d2:09:0f:e4:77:db:09:ff: + 50:34:c9:dc:0e:27:fe:94:1d:65:71:56:59:19:1d:62:a2:1a: + 93:bc:25:7b:be:6e:06:2a:e6:ce:ef:fa:cf:30:a2:e6:ce:26: + 28:e5:eb:6e:03:64:3c:8f:65:ce:32:33:08:ab:dc:45:69:78: + 4e:d3:b5:87:4f:03:48:e0:c3:24:48:cf:74:79:62:1e:b1:e0: + 39:12:02:08:db:fe:f8:78:a7:43:7f:e1:e8:86:b4:04:3c:e1: + fe:26:71:75:9d:32:4c:3a:ad:84:cb:e6:be:f5:7f:20:9d:04: + 4f:ba:41:d1:78:4d:f7:3a:93:89:ef:a4:4e:b4:83:4c:92:70: + 39:1d:21:de:c8:4c:9b:5d:26:55:1b:ad:93:48:79:19 +-----BEGIN CERTIFICATE----- +MIIJLzCCBRegAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ2MDRaFw0zNjAzMTMxMTQ2MDRaMIG7MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxMjAwBgNVBAMMKWFkbWluaXN0cmF0b3JAcGx1Z2luZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTgwNgYJKoZIhvcNAQkBFilhZG1pbmlzdHJhdG9yQHBsdWdp +bmRvbS5zYW1iYS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALwcA97mHhcahVsTuKmxJjayfE7Sij8gN+pX9kY4noYmzXPMbaahTiEp +ifB+daWNX5JCnYiBIWaMLxv1FFRr7RjJp6anFgcQJ3cx1JClzaKclsAYknb5EkDs +UVQSNs7FAv2euYBMgel+W1ktSnwKNQwPhaC5kyN3NYveGOddPiUnzA7wD6tApQgC +hPHPm2Y3EjcCTANDBNWprW7SiMSF+vOf8l1tH/RUoddKk8VC6cva/71wiyd1TXew +6pfxgHWEV14e5aXZiSjoRKB3ZghkUcBK0AbHsbQeawqUoGFanntb1kirHn5lQ9ng +kVH1K0OZoZS7f6or6VRpxOPx4Dh3n/kCAwEAAaOCAi8wggIrMAkGA1UdEwQCMAAw +TwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3dy5zYW1iYS5leGFtcGxlLmNvbS9j +cmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNybC5jcmwwEQYJYIZIAYb4QgEBBAQD +AgWgMAsGA1UdDwQEAwIF4DBZBglghkgBhvhCAQ0ETBZKU21hcnQgQ2FyZCBMb2dp +biBDZXJ0aWZpY2F0ZSBmb3IgYWRtaW5pc3RyYXRvckBwbHVnaW5kb20uc2FtYmEu +ZXhhbXBsZS5jb20wHQYDVR0OBBYEFB3WdDBp9y1fgeSD8X6wCPOcBkHkMB8GA1Ud +IwQYMBaAFEaHhsLnGc8WTAxiy3N//Y8Z5LVCMG8GA1UdEQRoMGaBKWFkbWluaXN0 +cmF0b3JAcGx1Z2luZG9tLnNhbWJhLmV4YW1wbGUuY29toDkGCisGAQQBgjcUAgOg +KwwpYWRtaW5pc3RyYXRvckBwbHVnaW5kb20uc2FtYmEuZXhhbXBsZS5jb20wMQYD +VR0SBCowKIEmY2Etc2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20w +TQYJYIZIAYb4QgEEBEAWPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Js +cy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMB8GA1UdJQQYMBYGCCsGAQUF +BwMCBgorBgEEAYI3FAICMA0GCSqGSIb3DQEBCwUAA4IEAQAsI60vooNX6EKzJ0N/ +qp2Zrp0gfwqw9DIzre7+M6ogCY5LSw0SsdUMKbwTqgRJziy3Aedo6e93qd22mgoR +v4hGDAl7rGvtao5y/NgoRiFIjycEZywXKzP3jBjKxj0Odjb+awN365coqWRLRjI4 +I/Vv2UO2Tsa1FAzFCQxVlAaSJhBmRJBk+uiudUOgvRSaMTeHMLdhh2VAt8EulEwK +7UzCdS1gV/mzz7LvGcOWpiXTHZIWnq/k5MqHd0sTMUjemRqc6ponlrwWSK+DQYxW +1JxvxZoxyTU6pcnMf589wlYDa9+zrMBHzlNcvTh9V9TDWcm3ComswhWkTVCEZ5FZ +bSiheAwuIDkGnQwtp8TcmOtPtFhtarqwWumHf8kRpXy3kUn1Cuf5yXy6MD2Vp4pm +R+1JU3SF42PVODR25z4sdLZYI1uTvuuymJx+vQ5f+phNdhO3XSK8dlsTiI2Ei/yk +JZmCOx4uWCqP1zbs+9YedrgKMfpWGDiW1Q7X3axwpsGADpybROfotopkjXycV2qQ +zivBxtr1aB3EN1hw97o9Ty5spqI7Eh4c6pm7rFRXGMDTf4rIfnOOsQZrVVfjT0ae +21BVHclhmd4xeXW8sdb+F7L9yzY6EmsPyLCmvuGk3lt2Arzkm/nf4e273EBiGwU0 +wFMQR6zHGG58FzeG84SRFwDzaUU//v48xrITgnD6/BtR0FYZsJ6fHSd1J4HxhbIV +f6zxjd7+OlcPE0/YfJ3zSaL+WuiRjDjCS5rzSQyScGKO7ZGKPtqrltZGXyXmgs0p +AyCDO2PCWzSSEpgTtFYtHc9LIvhA+3+uPklSVN4ClQryIm/hLL2kCI3sg3lKqO4n +DrhqZU+6voqUAq3vcj4HUlJRWGznIOSBSdp/8d3qK1b0KXUW37gZ2mOyoNOTXaaB +9C3T+8t84wSOOJ1mnSlXKCLjeltIz255MiRu5Nx6BSIspA4wdEHNNO89M04BPmUl +Acxdc1oQ1t9FJJNp+tOrf8i3WoYciL4yBS/4KiYC9cwwSt2XCjrbwAxnNpCb+Szj +0AQmRsGjTqBGvvOLkZzV8DIJxfCjUb8FcINRJbpvjCXqMJZS5lNkOKwO3lTnX9ow +4Dmb2GTVO3BPmieWNpib9QcLSolABhidbeJsQFGvg2Zzh1Zc+jiWqN1KKEqC0gkP +5HfbCf9QNMncDif+lB1lcVZZGR1iohqTvCV7vm4GKubO7/rPMKLmziYo5etuA2Q8 +j2XOMjMIq9xFaXhO07WHTwNI4MMkSM90eWIeseA5EgII2/74eKdDf+HohrQEPOH+ +JnF1nTJMOq2Ey+a+9X8gnQRPukHReE33OpOJ76ROtINMknA5HSHeyEybXSZVG62T +SHkZ +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt new file mode 100644 index 0000000..8a0f05e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt @@ -0,0 +1 @@ +01 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old @@ -0,0 +1 @@ +00 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt new file mode 100644 index 0000000..27e6ac3 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt @@ -0,0 +1,4 @@ +V 360313114451Z 00 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360313114511Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360313114530Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=plugindc.plugindom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360313114604Z 03 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@plugindom.samba.example.com/emailAddress=administrator@plugindom.samba.example.com diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr new file mode 100644 index 0000000..8f7e63a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old new file mode 100644 index 0000000..8f7e63a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old new file mode 100644 index 0000000..04d6e6b --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old @@ -0,0 +1,3 @@ +V 360313114451Z 00 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360313114511Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360313114530Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=plugindc.plugindom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf new file mode 100644 index 0000000..17a5571 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf @@ -0,0 +1,203 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 1 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 8192 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = CA Administration + +commonName = Common Name (eg, YOUR name) +commonName_default = CA of samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ template_x509_extensions ] + diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem new file mode 100644 index 0000000..852b53d --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem @@ -0,0 +1,102 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIISjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI8K/V4PKOJq0CAggA +MBQGCCqGSIb3DQMHBAj0N1BCFJkjIQSCEki8nJ5Sf4sV5cwTX0t2wqkXcZkP0L8f +wc/F/B9+EmqsJiTpH6wnH1ztcEqTBVfOsln6TYeF9oUgQrEZgYDQE4Hwxq7QKreK +vOvJlSX5Grk727s32msLjqiH+ccQOFiFme8SiTJqfCeyJyYOWoBMwmney3Ao7+Ab +1CtJtw6zOHKOeiBM6gNu9hM362ESUSPPiwgfx90koHuilOy3vxHPuGSWtaCt1cGB +Vuvp/rPY04vUgs4lSXacWB61Jy0qnFu0dGmzeBRP5P4TGzvdAOJY54lAwNxaEZg6 +okVQ32JdNxze708N+uObWE9LYgQpMriEww8f/anKE9yMRD+K8cvMkvMph4qRJuVj +W9OKJxOpfnRopbVYbh0O+gK3zA9RWQmfvrZ7O30sGqbKQhZWneU1Pa8WfEflfrBs +TDLQdJ7J9Jdar41faSFDg4jSzqhk8FGtSP7hkmJRII4ltPoXjHUEmpSeGsOtT9Ey +25QcVcizyHl0ckJ0efib6pUWmhpOF05uf/RTTY7seBv+NY0XPFpMtH5PS6p0dNTt +bg+MgJqewwfWCcv577MMAdyXHV7aOTUJ+g4V6YME/20tL6sMyQafMfWq4yLMHtmL +MC/RU8hKnTHT0uh2QHkxFiUWZL7yLwKgXKRU3y00dDJ3QvwnrOdVSXod//H64dyZ +BYwc/st24DswlAs/xclapNzKm2BjRJxsaeGuEmUpSOQn4iV6r54CEwEgcNB6rKMT +mYefJ2pKlswCDtZz744LeVqYFb/Tp6bV1Jq3of90GgIf53Ziq5eWILuubWw9ZMJ5 +2ex6A2Lb/+GiXaKdITeJmUvxme6ZxH6efvGE2yciTLki0oPDmPFywcsdJK/FzVNv +F3gOqD558Oo/uUf2aw/VwUZeFIA465RQbIEXj06F1KnA3JwMlRNJy2Jz10sLcyJR +vVykjjRZVb36coOrnMt/rGpiXXci77a2hUX/nNrEXL8A2wobS2kGVOPz4klD0Rfh +/B4kqa3pnPXjUKn0xNe3CHwOd/qOPgzlUYkGDZP+GnuMpaFWfz4tWmLaOElKnWwi +MbzDAt6Fh+nddHMusxtQv/iyADq5CC7XcZsFfnQQBR9yyrdoMwJxiEbF1oyB2LvS +iQqWxtoT6Y2PjfBS+zmbLEVQfwxL0UiQ/TrdgWumsIVi02AlEvyj4aIhc52aSevk +M5rWkKqrJqec9bLeXYlIpS57VYwxd+8FZjkxM/bIrGh7Bas7t1BQ3anh7+t7H6xr +XU8rwuGDtw0LawkGUC+0OgcmM+45WQdR1LtTP2xrwH1MdIoX0BrVtqW4ZpOBjjyD +UpG1bv/CGQwRXtZ/pVrWMfohYZOiNqyyiTEgmHjCuoon161mLRnRb6vVKp6eRUH4 +GMW8UM/k1spF/zMUfkuymdyFwkGrdhuDuaiaW3A3sgECqSKY4p4VXa1Awm8v2t0J +tHTuOAlbuhgtZXE6P1dtas+sc2WbsKC6X6ul+dhzvaBJo31Dz16ly74h+U/UUS9u +iS6p+UMCdg33R96AITJJ83RNQBIFG6sEZDTEy9fvH31uBVbeuW5GOhT5cMBf9b24 +o9B/gl5CVEmEAdwQ8BY6W7Ujk/GN7q44kmATT8C0zW5vJIbK1SRrYyfhiPjN+uv1 +bVrQDajrmP94MdpPB1YW1q0fZwRsz4836SN0uMSvC++rHzqgT9nhcJM7eHbvXtkY +u/57OnCTNtSIxzgcnS8TfMJTrHF/f4o/RuBbVBMFZFWHUIN4+OKwf7qzmNYHleMR +WN+2nTxACLL58RPOzCrQWLsbPFdOE81XSTQjp9YXF7H1MeMVaUhkXZDHShk8SOMX +oewF6ZvcM6sxgdYz8Ib/5dBDOLxBESc8ctvBgbmDGRopwTdCfDY9+TwZUE4n9Lj3 +EkcNh4282btr1MosBnH/udb5QZhlsXQCwrpvdxNTEsmpLpV5t390B+3Rt6wMxTLG +j4nNQuK2rj9D3to+S4wyfmg3QOmiUMrVCuW3anmoEcwlHsQN+BSkCF1PleGklCET +DI4DuQdv5CTg61nN8zIIqqVtCAXiSHX/FM4KAQHD1oLEozoOiS3AH6mx6cJ9rEP6 +iWylQzI2Ppv7hYTKpheboVlL8UsMbr982rUXeIUsGqvM2dSEuX8EjKQKqfDmo+1C +AA1puZvpGsVgvgEb9cDgklBKFOHRUhV3KP4oe7Zx4SsyTIuNYBG1U1ykIPiTLpQd +jzu/PwO94AIMiqF3NwEfOU+NBdG3cADdIau2cJucQTzfvBgQz0YkcnQq8dTTUaf/ +P76bviKsNqzy3fawbRziHkPk6VBsNwOkOSz9T9TYrmFlOSC9hJp/7k92TUy6vPxM +UbsUEZmS2dwmSjtGzjLyTv9yF50qHq5u03LpaKU5IHZHHoi2RnDvwblhtZlm8w9s +mRrbXiZkYAXg2BKDS7rTWIR3RBptG2iYPuQaUQ4XgMFvDIsGmEgm29GJOpLmIKy2 +NXBL2hRgmDGvUkMdRTKMm2sh+/ml6iW58kXgXyeIp/Z450zq2q2oa2Vd+LCoM+2a +zEa6ykn6gRIMFIu7VbGNtYrVDixZLqsqGDZc8O1Ob/fGzMiNL8cM+N9GCLRmIV+E +EqhwyrmF2gKj3mP1D4y1hdcgJvQpYdaPdpTe8cUaDpYtptl/TwS7s9YWjFnPXzfs +hU4TquWDthGpuIT4D3N6rd3gWHb8wmT67FEjYt7pC8IIkquIaerlkLN5Z5bX+MhH +1yiZBTmJ7vx+EWG5UMDW4khYNR5ggH1kN3pYbmwQW84GIAiJ6GJcp658QIT8/WKv +H3kHl+3m5Oduncy6HpuN37Fbzbak0AAevOPtjwTHTyyb7dgbMzp7Z3yApZ9h4ENz +0tk+2bRG0TPsBBmHYyGx66r9s23yQV+7ewmBY07Z2YkJGJ1ezzwYypseQIFWWxY8 +zmuehkT2sXycF89zGoVWL1Bcrpdg5Bi20rUOtKlkFWzcVNdOXdbcMu8u5RVxeLEj +ftBInNO8gY9tjvzPKMv7KOj3RE6sPNiVZS/UIicAIEuvgt3Pu8WooG7y32hBE66H +vITJWK+RvDN6BPfmFMQAAUXLpBTsqkmferPWrgxSd2T3cgbjS5JvAquxt0Mad3TH +ERPHOoDi62x4jX7UiElNQUGArcVw7MNuo2txkRvCnb8GZK8JiWcBVzuka8Fs1JBe +kw6tqoauNM+uNRaVgY7o1NPfW3uA53B5N2OHl+t5jmXi+llTmQz5VXE+UiCacxE8 +Vlhtos6w3E7CfCXDfwlvaZHniPM4PZic/jpDZEE+XBWvtcXkgstG3Ufs9MpCIqCj +ktjiiVBNE+QLaCpw7sNZGq1QOxmdMw97/HRwVGWtzvx63B7a44JBfnVbPAp2e30k +vTPI2v/4b0+7AvKMnnON7VZHmifngEr6Ok+m7+O1yn2KyigOANPPdzTkGV69tv9c +XoIkvCXYXDrEpi0n7z4SSze09qAZ12jDAOY+H+/ag1nOar/bP68WSISL1uE3wYWX +kbdp3xdES5BPXZK/EldVGlHvvqwYBKHI9XmG361+/b/mxLVIcfBwtiiFIaJvnRcc +pzefHJo01aW34//OYGs1lc7s39Ox2094Xj4uqorNBu4f3hKna5cnzBLqDK/zZUA+ +RV4CutR/OZTw30xv2ho7FKb7uHg7o3jk2cRQgBy3ep2DwxhBZ1HrtozDOLZs2nFL +9/+GdKahJS+ZOmfSOVKUpyWw2OtlnGYIp3NxsWdGtrK8/aLrFgY9wOHJ7A19Lb2Z +wTMn+wqrGv7rp4TBdND5eAj5+P+1027GHn20fHtF3yqDsIjwd9Qaoh6JRnB7f0KS +cQI7X3J7uv6uRT9uNdxk8BV9cliz0OHIvxPdov43QSRetpVMZez1nDwJRx2hkh1X +tl+qLG9tZvB69Wwh+bFQ5vwtH9YJHHBlg8rdCFMj4IHY1dEPvzpmvd0xxj7lVX1/ +CzN232aaYblfn2SCFUbsnxhAMrb762FIp37VOXw8Uu1ylF0hput46oJhqeheI95X +0/eLTjE5ZYPYXD6tiGx5JC2R3jSUZ9JDC50YFOYEALyagBc1vzcmMUxbi8SHEGd8 +sgCpWVmCcZfWA6yJRTiuip7pDkXW8E1sm63moYsSZ9DdNboYM500z7Swm6TsOejf +2m8axEhXJorasZKMw6nLUEO6fyMbbp6ZZRjRd0dBjEdCF9oPKhK5vx+A9e8eiwJ1 +io15AMh94DOVUBtZpMl/oLurGsPyMzbPY3D9FtACDQ5fZ/T1gM3CBQj0YhaoZ8vK +Zj1F/CdQMhm4GoTaFeZAjOLQb03h7PuDYDBGMk43SIt2ogCYfmQWWQy3TfHZqcFV +IdT3eYMi/j9cmCrxBJwoftBYVg+qPtGyRisD+CPVJKVGA6Q6T2Fcr5AQdzwtvFjj +7OTEPEo9cDvS+Y7sTKHULBmHAZAAYQr2CsNZ1G9e0xXvp3+++S4EZ/Xp2xE1iImX +Uup72cVMZPcm9s7s6u/rS0pEtgf20US7Ct9B77Govevcp5xeNVQHQFehF6Ksd4b0 +dnQCfNZ5bCBjC2D9S2rnPL+N5mkKSMwk+zFjc7owno/INs7za/TGU7wosnS4+nuT +6J1ya0RrTjPU6eh453R5QKfYof8C1qpHvAhNhLqI/dJK5XSDeBVEcdCj+pEekTC4 +3fFJ2ZNxXIoE7Folwc/VAmlI1lsq/ZimNwL2UQ/Yh06dxm1G9W98F+8m1vNdwudG +moMbwmrPLnnxTwAOhAQkdtpYKKaiXkH9xkJXNRew/Jaer3YvPF87yyu78eU83ZP/ +3ua/5Aq6L+6FK78nfGfv1FhtYCdsMNZv/xGQS6LVAdOON5A4+0C8A97mAQUYen2F +34j5TY9iuqeLvXFxSZ/s+hafuRbN682PQ3Mdrd7CINjQmtGHSLoRp+6gTQ844bl4 +kaJhsawxBE8rE63I58w0E715u/o/460N1bYaLBY4n2wbv3pDRVNtJcJRSOeLUSZJ +2slbE8Ok7jmAexFNlj/cjFwcdMPSjk5J5hVXhRiQgbpVVEpvUPgGuULwXpfot6o5 +uREHPjf/PP9Oneny69Eoijtee8f9SIYEkLsiMpUrdm+3JXc8ohI8DqjmDsr+YUUl +yJJ5yXyUQjG3YZU5S+3lH0G9VQsIPpIUuqOtllOPLZjZe+7g35GUASeh3TLoO2l7 +Jeub0I5apqXwNSf/Xw+fIbiunMKGGOFotKCYDn7w6HT2HLsFFGu2NJigeBzBsl2N +Ngms0Ur1r+8EUsmIP2Fox02saKbCyiaTvpMUMTrXPsZ1L83galem8QWr6AiHCk06 +heOu0leO77baMA8hgPjpY1RnVYl4/ZX+fTGkq1rNAmNHt7x46FQEK/yuFtMt1sNh +DgA+HJpNLh8FTDesiIymfaesoXk79FSD7amsPfT4oNzjo1aqsrQ6qteKD0XqLjOA +juvUF3O/MhD2frSDT6yHs8Pd5aPDb7DwX8gRaQ68kFwyUXPijpU9rFAylIT15WNb +xXfwYgq1g5V0eqtEVlLisQj70wRJOADYCRAAcEUYiaf86pN6SUxH3a48XrqZqcVi +vPteMicbitpcJjmVHAKiKlwqwmFmnwzb57J2xYijG9Y2TKE9HBCDkaKIx3BUQRdq +VcZJ+wm7rBtScBXhECkyzFbJVOLCSYX/ziKf33BBZKhRY6cCr0UuH1G5nj8wxiin +fod7Go8slrBS0pnPRWczxH3LqbvpRBA1lfTaKNyBSAjDuVJF5QifiIjRqk5AziCU +Bk3F3pVIoA72OnXlmdDa2HkG85iH9NyiWEfOkou5goAuQvILu94cX0+gw3bGYNPc +Uc+LprTR5cXT2aA5D7uRMMWJ+Znrw3/4pnKtVmRGkbMsuFej/gKXvl+UCmYkywXa +RyE1BeThrRgA4/QeU9x2aqCnZyTmszFW43PtzzZqfks48qpBxYq47NbrfLV5w9av +1XzVj8NIechjFlB/KUIY6jylY+fAdx8Za8I/RyCFWwlhsDQ4Ef3aWtumlevYu0d6 +1Z63Of+ySvOdlvsoV2fOHAJGa2aeAh+ibXe8h8myNOrzVDx4blParf0F28ikaVOj +IzH8Rk/UEsCElY+Cb/KVPoPtk1zxtFhAElqq18LGrRbQBT7Ntd/FYf84POZ5ItKu +B1z8hmq2EIb0FUKV7Hx4coFE6cb8y1NcMs5T0z09nfCiDZJl5Vr0NR6bWDRBWm3L +seXEEGHblpFl4UTVMZ3szBHGveDSoKujIiqbHC8o4GshhmQBhyIhw0lnxmh40FPk +R1Y= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt new file mode 100644 index 0000000..6496923 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt @@ -0,0 +1 @@ +04 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old new file mode 100644 index 0000000..75016ea --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old @@ -0,0 +1 @@ +03 diff --git a/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem new file mode 100644 index 0000000..2b3d7fb --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIILPDCCBySgAwIBAgIJAMjuQLBy0LOvMA0GCSqGSIb3DQEBCwUAMIHGMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKU2FtYmFTdGF0ZTESMBAGA1UEBwwJU2FtYmFDaXR5 +MRkwFwYDVQQKDBBTYW1iYVNlbGZUZXN0aW5nMRowGAYDVQQLDBFDQSBBZG1pbmlz +dHJhdGlvbjEgMB4GA1UEAwwXQ0Egb2Ygc2FtYmEuZXhhbXBsZS5jb20xNTAzBgkq +hkiG9w0BCQEWJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29t +MB4XDTE2MDMxODExNDQzNVoXDTM2MDMxMzExNDQzNVowgcYxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApTYW1iYVN0YXRlMRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNV +BAoMEFNhbWJhU2VsZlRlc3RpbmcxGjAYBgNVBAsMEUNBIEFkbWluaXN0cmF0aW9u +MSAwHgYDVQQDDBdDQSBvZiBzYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJ +ARYmY2Etc2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggQiMA0G +CSqGSIb3DQEBAQUAA4IEDwAwggQKAoIEAQDRaY4kvh518y/goY9ZM+e7Z2ihJ0fB +dC7vMPyl+5GjcatbL4pqe/FQWDPVKZrTQzLEjDjoTjfFIaZDE8WGeShDS1Z0vaNf +u4NPCPyTwYpzH76E5a/gvQVt6c0tJC74pD3Z2u7JdCEkL5ywv/RggMPqVz4SmHZn +Ul53Y+/GgNoqb3Cbd2IAbD8QxNgbwKoYbP2+31DZALlL3pR4yUYSvf7OxPuY4nRY +npYpr/C77Zi5nx5nSmplYN15ab2swx2qMMF6LGrxyKK7yfLoDJn2iZa9JswL/gTx +3Tc+gkEvQQby3wzffWKSA2m7wFGxd1mytsFFnsohloueVj4b/FdTHuJM2SKD5JXf +l9Jh6ECMcYolcKNpWRZPsv5eAJNiwfy0f2+fuz9x0sB6F5hP0ttEdvYto2ZkMNT/ +hRsBGsAI1NP6AGNgDuGbi9ZLML7kWD0ZH+8ceFl5QKcvDw3QCBiwkc/LtGcnMyRV +5Fkjiptu7jlNsjYi+h/N8n/sFawjcERYrnaevD0J4qgekq0VuzdcYLZnW7j7L/+A +klQlJsyP8OD7VRvAbRDmRWRqVKa6wvuOC/zb/QCn10WcabsD6IsbjP5AS8DEosW3 +ld71mCeskTG50TK2+fFoofHTjqJl2g3JCwmBJ/OWj+i986+JG9MaXxqajLGkd0rZ +AroMHllkSB3STiybQb9uLyJG1hrVeVeYz9uFhCSjQvcYLZ+weIt2C/43BYLp06Ss +ZHjMy96kiGnUnw6PIMsPW+sZOzfby183kZjdKOWw6TIlDEznlWwFLa43mZqPRLhx +xsLd6wZAXXYBK2k0fcSMLIGnzLyvzcS6XVD93G136IvZpGgmryZkVBmzkGyoigMy +h2dzVpj99qu6JNig92YkS5nVRXgt5V63vS4cavwWgxZbMr6q1nOPmphCa8pTJ68u +PeRS71B9TTF6Wx5T/qeQ/Qzx9aa35eNO3LpogxFRWWJP48yFmjEZ4fKtLYlted1f +ZfFRlnkYmfuaqCaDUQKnxI1TWaLUMIWxZRNSen471p/x5+M7Vn5q7RLiu+UprFYM +j1swJ/EBw00KqEtlb6QNHuegqOqwUat1D2F9w/BIq/krR7lhM9UyB9FXttXFwJLS +WaBXL/S5ZrIXeHvIObOM6ovhza7dtRQuAJSs8DwBfhcNn1JxUGGHkAkg2xSr9Pl8 +wBigczSjGw35YxO+Ne++mF6dlHcoexrm3ZVI84kr1jB4dyFKuVCZ+6TabxeCNytp +s2+6YoCcu7b1ie2ljt0jhCcw0oEY3OTv0lAdOS4mst4rwgPr8kB3IqlLGnTPUFGg +g2clRN1JzWE9auTElWA0j4ECRbq4/HXrJB/L2TGi4kfqSGmCzLXgYCe/AgMBAAGj +ggEpMIIBJTAdBgNVHQ4EFgQURoeGwucZzxZMDGLLc3/9jxnktUIwHwYDVR0jBBgw +FoAURoeGwucZzxZMDGLLc3/9jxnktUIwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3dy5zYW1iYS5leGFtcGxlLmNv +bS9jcmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNybC5jcmwwEQYJYIZIAYb4QgEB +BAQDAgEGMDEGA1UdEQQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4 +YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJh +LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IEAQBeOC+ekA3OZ2DRFN6VQED2 +87IsASYi8kfZhRe/vA6Cx42jqbmJcbdDtc8v2GqMXbuO6nFZCOmhxvShL6ScQI+j +Scx6pNZYi8s4tg/2KGsTNRhhNXYzQ1hbEpQuDi8cHvft95cKlBTZrZHXyBTJbOZJ +jy3jbHmzsE+RiuMvBM+QVvo/ykQ2ySc6O8rzOhRwmSvrW+zZEjrOZEjQVFMisq/S +LkJ8Y8SkxH9F95EBexVztpOzfY20hkc8UDaqDP7OQhoY95mjJ0j90/7TjNTFT1bi +GmOVMr+K+3RWqUcCvAY0tIG9cPDvRFT5frEcV87W/R1ffG0FnNaq+Y8AGI24UO4s +TDll92OOX5KDbVunVerw/CII3+9k+tB9lbDYsdfDaoFJaIWLV0kXV9uUS/Ninp8T +M6smq594Hbjuy8hcse3USKrnMP1lLkb9s3I3U+UV098wf5qFx/sFjeXsPhZcD6Gt +oL9uGY2M6ZWxgkvOUDtdzfyhplWi7Ps+n+qR6JuCp5cemb8WGarqekeZNuJfve/f +eWXgpwac5CgJTSOI37LqzYKQehaBD9vJnS9RUMacSxOiH3puXGrxgPye88Yh6YOY +bkdsDQY17JLdLw6zHObJ1MrywCVLYa9aZlzrISJ2oka4qza+rfl6QVoYNcKUK/oh +hKcWpcfJOrDlxHneow4iA9uYY2MrKDKuTEgNS+lWYD3EO5iq9cC56anBO581xBXM +6ZBEijuIHOETlu6Hyks2iVkEEeSDT4JGVn720WXuMuZYMWh+TOTJz9Sq1M4orlsE +BszVqrfcOV6eb1n1ZeZ8mjxqyTtuuxIbpccNm4kEwH8EDPQvDTF0lnM4qjAYXJxp +uBEgHVyQY2Y4s6aDtbvoZiTQ4+0YcS/2db4puesXO9UzlBuVgKh4ta8MrYFIhl5t +V/U8t6/lXC82hyYuX5dNPhKQeScfZiW2VJZYyrVX+gRXyRuP0s9dB7q6G3o0kDCu +a/H6Hqf59dLppWIJE6aJClCaxhI9B95UeDMg1+eL8nKjrWkgIt6bdNpXGF6CPHeP +zVB+syvGwNdsYQBb313IpkkADoKtPb0PAK+3tC0Mm06fV/7ORq1/zLU2P8T5adxh +iXQ7ZkkxO+UVSdIveppG+uCzQrL0n0UmtQLP8euVaXe36vbjq6qECB89r0YFon90 +BHCIuegU2PUFL8sBs8ln3BAG+2sdDslIoQCT1k0Ce7kGoRDubIH7mK+t7ahvZHlu +jHaSopM+TIQYnwftvb4RVdwHhErHMovIoIirAZ50WALRNIUvMyWNi2uBwBLCyONY +3DVIyudGERIDT7RXvryvBXplH4Aj3ubu+KSB7WAceHyFpP5GVPULR5m1tAuHAR+K +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem new file mode 100644 index 0000000..df9445f --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem @@ -0,0 +1,32 @@ +-----BEGIN X509 CRL----- +MIIFdTCCAV0CAQEwDQYJKoZIhvcNAQELBQAwgcYxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApTYW1iYVN0YXRlMRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNh +bWJhU2VsZlRlc3RpbmcxGjAYBgNVBAsMEUNBIEFkbWluaXN0cmF0aW9uMSAwHgYD +VQQDDBdDQSBvZiBzYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Et +c2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20XDTE2MDMxODExNDQz +OFoXDTM2MDMxMzExNDQzOFqgYjBgMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1w +bGUuY29tQHNhbWJhLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFEaHhsLnGc8WTAxi +y3N//Y8Z5LVCMAoGA1UdFAQDAgEAMA0GCSqGSIb3DQEBCwUAA4IEAQDCY6ioFWXc +znAwARBrMTLSu0eqm2gIK4luXEDM7w8875kGKfp6Xf+SVMpagQwNIWApDsVU59FO +zGn7GSD6sRaV0FSNiio/XBxIuCLGUrOss6tcClrtpwt8Y/GLv3SMpMwtH0GRsP4w +INrsUGxC/gh0njEcE6YXZH9QL+p4UBWwPvkFfAT3WijF2WLMCsI18ZPZ/q1ONkNt +sb3Kr+lowxVbLb5B+YDqP6ncRe1U49l6A1Q/8s0SDDmBnhiMtwSy0rdAxJ5eD2Wn +HlAkd/JS6xSR68XvG7fD6NrwHVZtGBNBZQvXJth/xS67ym2m36oGffO8w1z1/uxb +Zmr9HQAomubfc5rKCMQV1fREgnJGtY0VsWpiBqHxIXMK/A4DGVWrcg4GB5h5DHZi +bb62HjXrm8pQDMkRLS3smmnMbFrfuJ/2jH8hyfoSesQKcHGUJfF2UJh6yuGp8ud4 +uX4YTmb84u5UvrF848etp/Ij4l/qOJjj+C4rCt0CiPHetuMLhfLQuLt5JD220E38 +ESVi9cuj2cjPkpNoPOqqP8p5wOiJ7JZgrBLtZ/ha4gYyDiYqaX63Krp8uBJM2Kqa +BGgI5aKNzb9aXZhuZaXoiF2hXu+pD0XzmQ3B11hXa7DRwXdQiUcW0K28o/Kfvvzk +2jubHMiWt+NS8Jw7WeJjNB8rSNjWYGTgf/i8LNi8569AZH7q32wvm/KVUsB2MGAH +HRXk/yiPW2l4nIKD6/kxHEViVVG0k14IxohhPa8XMqHSt5/sOdZoaD4/7MJ4ci3L +DXAh/AoNTBhx0PSXGgfb0m8/pDykcdp6m6Ggf6Gzptu4iZroXC3rDMIkkvhKNX5c +ZanlSgpwcqSr18SEyPjOAWGBoTDStmoVVH1pWgdyL/u6kB4/pEpypQfXJrIV+pjg +EY6EQEZYtv1h2doJ2K9XkFDE0nPyw0QvdgAWqDTdOCaUhmTL2QbDdcjViV65cXwk +XyDq8C6aGYLz6Qqi2wzJRyGYfKBC7kDNvB5DIHC4ByFy5oEwm5fDWTkQcJ6hOHeh +of3zYCts39/dBD90jFFlM3dmSzUNCKJDaO6sudF1BuT1OfjnH6ABSkMfklNbqvKc +iAnDkmRt1edr3SUyA7RiBsJ4bTjs3YPbvN+zBEOIuRRi0OC8iO9zGG+2nFKtjTzd +Kz4JdSiGkcNTWoYBDqdiwUvPDDLT5nqO4XDC+1fHST0cy1IP1ggSRh1+YsBZbUnF +11gHE6WuMoRIQelLqiGjZhXrO8nB2dwu1uR70z2S1zI/Om5B7z/vREDZqewkht9U +YLmlkGMdhTdMmon9yVkXGEi6va/kyi24O81nJE7cyUnySoKp43zvpr5dZjbtUP0a +qcBp6pW4976r +-----END X509 CRL----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-cert.pem new file mode 100644 index 0000000..223d407 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-cert.pem @@ -0,0 +1,170 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:46:04 2016 GMT + Not After : Mar 13 11:46:04 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@plugindom.samba.example.com/emailAddress=administrator@plugindom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bc:1c:03:de:e6:1e:17:1a:85:5b:13:b8:a9:b1: + 26:36:b2:7c:4e:d2:8a:3f:20:37:ea:57:f6:46:38: + 9e:86:26:cd:73:cc:6d:a6:a1:4e:21:29:89:f0:7e: + 75:a5:8d:5f:92:42:9d:88:81:21:66:8c:2f:1b:f5: + 14:54:6b:ed:18:c9:a7:a6:a7:16:07:10:27:77:31: + d4:90:a5:cd:a2:9c:96:c0:18:92:76:f9:12:40:ec: + 51:54:12:36:ce:c5:02:fd:9e:b9:80:4c:81:e9:7e: + 5b:59:2d:4a:7c:0a:35:0c:0f:85:a0:b9:93:23:77: + 35:8b:de:18:e7:5d:3e:25:27:cc:0e:f0:0f:ab:40: + a5:08:02:84:f1:cf:9b:66:37:12:37:02:4c:03:43: + 04:d5:a9:ad:6e:d2:88:c4:85:fa:f3:9f:f2:5d:6d: + 1f:f4:54:a1:d7:4a:93:c5:42:e9:cb:da:ff:bd:70: + 8b:27:75:4d:77:b0:ea:97:f1:80:75:84:57:5e:1e: + e5:a5:d9:89:28:e8:44:a0:77:66:08:64:51:c0:4a: + d0:06:c7:b1:b4:1e:6b:0a:94:a0:61:5a:9e:7b:5b: + d6:48:ab:1e:7e:65:43:d9:e0:91:51:f5:2b:43:99: + a1:94:bb:7f:aa:2b:e9:54:69:c4:e3:f1:e0:38:77: + 9f:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@plugindom.samba.example.com + X509v3 Subject Key Identifier: + 1D:D6:74:30:69:F7:2D:5F:81:E4:83:F1:7E:B0:08:F3:9C:06:41:E4 + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + email:administrator@plugindom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 2c:23:ad:2f:a2:83:57:e8:42:b3:27:43:7f:aa:9d:99:ae:9d: + 20:7f:0a:b0:f4:32:33:ad:ee:fe:33:aa:20:09:8e:4b:4b:0d: + 12:b1:d5:0c:29:bc:13:aa:04:49:ce:2c:b7:01:e7:68:e9:ef: + 77:a9:dd:b6:9a:0a:11:bf:88:46:0c:09:7b:ac:6b:ed:6a:8e: + 72:fc:d8:28:46:21:48:8f:27:04:67:2c:17:2b:33:f7:8c:18: + ca:c6:3d:0e:76:36:fe:6b:03:77:eb:97:28:a9:64:4b:46:32: + 38:23:f5:6f:d9:43:b6:4e:c6:b5:14:0c:c5:09:0c:55:94:06: + 92:26:10:66:44:90:64:fa:e8:ae:75:43:a0:bd:14:9a:31:37: + 87:30:b7:61:87:65:40:b7:c1:2e:94:4c:0a:ed:4c:c2:75:2d: + 60:57:f9:b3:cf:b2:ef:19:c3:96:a6:25:d3:1d:92:16:9e:af: + e4:e4:ca:87:77:4b:13:31:48:de:99:1a:9c:ea:9a:27:96:bc: + 16:48:af:83:41:8c:56:d4:9c:6f:c5:9a:31:c9:35:3a:a5:c9: + cc:7f:9f:3d:c2:56:03:6b:df:b3:ac:c0:47:ce:53:5c:bd:38: + 7d:57:d4:c3:59:c9:b7:0a:89:ac:c2:15:a4:4d:50:84:67:91: + 59:6d:28:a1:78:0c:2e:20:39:06:9d:0c:2d:a7:c4:dc:98:eb: + 4f:b4:58:6d:6a:ba:b0:5a:e9:87:7f:c9:11:a5:7c:b7:91:49: + f5:0a:e7:f9:c9:7c:ba:30:3d:95:a7:8a:66:47:ed:49:53:74: + 85:e3:63:d5:38:34:76:e7:3e:2c:74:b6:58:23:5b:93:be:eb: + b2:98:9c:7e:bd:0e:5f:fa:98:4d:76:13:b7:5d:22:bc:76:5b: + 13:88:8d:84:8b:fc:a4:25:99:82:3b:1e:2e:58:2a:8f:d7:36: + ec:fb:d6:1e:76:b8:0a:31:fa:56:18:38:96:d5:0e:d7:dd:ac: + 70:a6:c1:80:0e:9c:9b:44:e7:e8:b6:8a:64:8d:7c:9c:57:6a: + 90:ce:2b:c1:c6:da:f5:68:1d:c4:37:58:70:f7:ba:3d:4f:2e: + 6c:a6:a2:3b:12:1e:1c:ea:99:bb:ac:54:57:18:c0:d3:7f:8a: + c8:7e:73:8e:b1:06:6b:55:57:e3:4f:46:9e:db:50:55:1d:c9: + 61:99:de:31:79:75:bc:b1:d6:fe:17:b2:fd:cb:36:3a:12:6b: + 0f:c8:b0:a6:be:e1:a4:de:5b:76:02:bc:e4:9b:f9:df:e1:ed: + bb:dc:40:62:1b:05:34:c0:53:10:47:ac:c7:18:6e:7c:17:37: + 86:f3:84:91:17:00:f3:69:45:3f:fe:fe:3c:c6:b2:13:82:70: + fa:fc:1b:51:d0:56:19:b0:9e:9f:1d:27:75:27:81:f1:85:b2: + 15:7f:ac:f1:8d:de:fe:3a:57:0f:13:4f:d8:7c:9d:f3:49:a2: + fe:5a:e8:91:8c:38:c2:4b:9a:f3:49:0c:92:70:62:8e:ed:91: + 8a:3e:da:ab:96:d6:46:5f:25:e6:82:cd:29:03:20:83:3b:63: + c2:5b:34:92:12:98:13:b4:56:2d:1d:cf:4b:22:f8:40:fb:7f: + ae:3e:49:52:54:de:02:95:0a:f2:22:6f:e1:2c:bd:a4:08:8d: + ec:83:79:4a:a8:ee:27:0e:b8:6a:65:4f:ba:be:8a:94:02:ad: + ef:72:3e:07:52:52:51:58:6c:e7:20:e4:81:49:da:7f:f1:dd: + ea:2b:56:f4:29:75:16:df:b8:19:da:63:b2:a0:d3:93:5d:a6: + 81:f4:2d:d3:fb:cb:7c:e3:04:8e:38:9d:66:9d:29:57:28:22: + e3:7a:5b:48:cf:6e:79:32:24:6e:e4:dc:7a:05:22:2c:a4:0e: + 30:74:41:cd:34:ef:3d:33:4e:01:3e:65:25:01:cc:5d:73:5a: + 10:d6:df:45:24:93:69:fa:d3:ab:7f:c8:b7:5a:86:1c:88:be: + 32:05:2f:f8:2a:26:02:f5:cc:30:4a:dd:97:0a:3a:db:c0:0c: + 67:36:90:9b:f9:2c:e3:d0:04:26:46:c1:a3:4e:a0:46:be:f3: + 8b:91:9c:d5:f0:32:09:c5:f0:a3:51:bf:05:70:83:51:25:ba: + 6f:8c:25:ea:30:96:52:e6:53:64:38:ac:0e:de:54:e7:5f:da: + 30:e0:39:9b:d8:64:d5:3b:70:4f:9a:27:96:36:98:9b:f5:07: + 0b:4a:89:40:06:18:9d:6d:e2:6c:40:51:af:83:66:73:87:56: + 5c:fa:38:96:a8:dd:4a:28:4a:82:d2:09:0f:e4:77:db:09:ff: + 50:34:c9:dc:0e:27:fe:94:1d:65:71:56:59:19:1d:62:a2:1a: + 93:bc:25:7b:be:6e:06:2a:e6:ce:ef:fa:cf:30:a2:e6:ce:26: + 28:e5:eb:6e:03:64:3c:8f:65:ce:32:33:08:ab:dc:45:69:78: + 4e:d3:b5:87:4f:03:48:e0:c3:24:48:cf:74:79:62:1e:b1:e0: + 39:12:02:08:db:fe:f8:78:a7:43:7f:e1:e8:86:b4:04:3c:e1: + fe:26:71:75:9d:32:4c:3a:ad:84:cb:e6:be:f5:7f:20:9d:04: + 4f:ba:41:d1:78:4d:f7:3a:93:89:ef:a4:4e:b4:83:4c:92:70: + 39:1d:21:de:c8:4c:9b:5d:26:55:1b:ad:93:48:79:19 +-----BEGIN CERTIFICATE----- +MIIJLzCCBRegAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ2MDRaFw0zNjAzMTMxMTQ2MDRaMIG7MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxMjAwBgNVBAMMKWFkbWluaXN0cmF0b3JAcGx1Z2luZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTgwNgYJKoZIhvcNAQkBFilhZG1pbmlzdHJhdG9yQHBsdWdp +bmRvbS5zYW1iYS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALwcA97mHhcahVsTuKmxJjayfE7Sij8gN+pX9kY4noYmzXPMbaahTiEp +ifB+daWNX5JCnYiBIWaMLxv1FFRr7RjJp6anFgcQJ3cx1JClzaKclsAYknb5EkDs +UVQSNs7FAv2euYBMgel+W1ktSnwKNQwPhaC5kyN3NYveGOddPiUnzA7wD6tApQgC +hPHPm2Y3EjcCTANDBNWprW7SiMSF+vOf8l1tH/RUoddKk8VC6cva/71wiyd1TXew +6pfxgHWEV14e5aXZiSjoRKB3ZghkUcBK0AbHsbQeawqUoGFanntb1kirHn5lQ9ng +kVH1K0OZoZS7f6or6VRpxOPx4Dh3n/kCAwEAAaOCAi8wggIrMAkGA1UdEwQCMAAw +TwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3dy5zYW1iYS5leGFtcGxlLmNvbS9j +cmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNybC5jcmwwEQYJYIZIAYb4QgEBBAQD +AgWgMAsGA1UdDwQEAwIF4DBZBglghkgBhvhCAQ0ETBZKU21hcnQgQ2FyZCBMb2dp +biBDZXJ0aWZpY2F0ZSBmb3IgYWRtaW5pc3RyYXRvckBwbHVnaW5kb20uc2FtYmEu +ZXhhbXBsZS5jb20wHQYDVR0OBBYEFB3WdDBp9y1fgeSD8X6wCPOcBkHkMB8GA1Ud +IwQYMBaAFEaHhsLnGc8WTAxiy3N//Y8Z5LVCMG8GA1UdEQRoMGaBKWFkbWluaXN0 +cmF0b3JAcGx1Z2luZG9tLnNhbWJhLmV4YW1wbGUuY29toDkGCisGAQQBgjcUAgOg +KwwpYWRtaW5pc3RyYXRvckBwbHVnaW5kb20uc2FtYmEuZXhhbXBsZS5jb20wMQYD +VR0SBCowKIEmY2Etc2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20w +TQYJYIZIAYb4QgEEBEAWPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Js +cy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMB8GA1UdJQQYMBYGCCsGAQUF +BwMCBgorBgEEAYI3FAICMA0GCSqGSIb3DQEBCwUAA4IEAQAsI60vooNX6EKzJ0N/ +qp2Zrp0gfwqw9DIzre7+M6ogCY5LSw0SsdUMKbwTqgRJziy3Aedo6e93qd22mgoR +v4hGDAl7rGvtao5y/NgoRiFIjycEZywXKzP3jBjKxj0Odjb+awN365coqWRLRjI4 +I/Vv2UO2Tsa1FAzFCQxVlAaSJhBmRJBk+uiudUOgvRSaMTeHMLdhh2VAt8EulEwK +7UzCdS1gV/mzz7LvGcOWpiXTHZIWnq/k5MqHd0sTMUjemRqc6ponlrwWSK+DQYxW +1JxvxZoxyTU6pcnMf589wlYDa9+zrMBHzlNcvTh9V9TDWcm3ComswhWkTVCEZ5FZ +bSiheAwuIDkGnQwtp8TcmOtPtFhtarqwWumHf8kRpXy3kUn1Cuf5yXy6MD2Vp4pm +R+1JU3SF42PVODR25z4sdLZYI1uTvuuymJx+vQ5f+phNdhO3XSK8dlsTiI2Ei/yk +JZmCOx4uWCqP1zbs+9YedrgKMfpWGDiW1Q7X3axwpsGADpybROfotopkjXycV2qQ +zivBxtr1aB3EN1hw97o9Ty5spqI7Eh4c6pm7rFRXGMDTf4rIfnOOsQZrVVfjT0ae +21BVHclhmd4xeXW8sdb+F7L9yzY6EmsPyLCmvuGk3lt2Arzkm/nf4e273EBiGwU0 +wFMQR6zHGG58FzeG84SRFwDzaUU//v48xrITgnD6/BtR0FYZsJ6fHSd1J4HxhbIV +f6zxjd7+OlcPE0/YfJ3zSaL+WuiRjDjCS5rzSQyScGKO7ZGKPtqrltZGXyXmgs0p +AyCDO2PCWzSSEpgTtFYtHc9LIvhA+3+uPklSVN4ClQryIm/hLL2kCI3sg3lKqO4n +DrhqZU+6voqUAq3vcj4HUlJRWGznIOSBSdp/8d3qK1b0KXUW37gZ2mOyoNOTXaaB +9C3T+8t84wSOOJ1mnSlXKCLjeltIz255MiRu5Nx6BSIspA4wdEHNNO89M04BPmUl +Acxdc1oQ1t9FJJNp+tOrf8i3WoYciL4yBS/4KiYC9cwwSt2XCjrbwAxnNpCb+Szj +0AQmRsGjTqBGvvOLkZzV8DIJxfCjUb8FcINRJbpvjCXqMJZS5lNkOKwO3lTnX9ow +4Dmb2GTVO3BPmieWNpib9QcLSolABhidbeJsQFGvg2Zzh1Zc+jiWqN1KKEqC0gkP +5HfbCf9QNMncDif+lB1lcVZZGR1iohqTvCV7vm4GKubO7/rPMKLmziYo5etuA2Q8 +j2XOMjMIq9xFaXhO07WHTwNI4MMkSM90eWIeseA5EgII2/74eKdDf+HohrQEPOH+ +JnF1nTJMOq2Ey+a+9X8gnQRPukHReE33OpOJ76ROtINMknA5HSHeyEybXSZVG62T +SHkZ +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-key.pem new file mode 100644 index 0000000..f0c97b7 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIywzM9NUqYIYCAggA +MBQGCCqGSIb3DQMHBAg/PHGo9J8k2ASCBMgInucWaWmW19O/FNVi2NqcCenKvxfb +rM1b9KigeRKo1GABmMVen0Ugy5A4YxIF9nrjCYjI+eDfsZjLaP5Fzn3Nt7/eX1bV +dvKK3N4Zwks0SuMtksyYs2wshT86dVjnHbIXC5p9cJFjPEyxSp/M77ypQnmqTwDM +2GhYQywPoOQ8b3JwhAREevJnbA6bQw79E/9NzmtrhXJkvahqLWkNGR0yPx9iH0tN +9qfPP5Svz8un8cHlulb2VoY9BgsoxG0AO9V62slwX3WRv7BKtkyM8E0HXD3sBSNB +fpt1FhqFW2nQM9F0gikA6LIh4QYBd5c5zMDF1FW5kbFp5OTQaUEvIKw3TTHXQdhs +bnXfiJ6DxdIdeSubOGP3RxRv9gLmSYMq9UqyVQM4jHKsDMA2RLSj5yc6DTUGYe3a +OHNk4v0mNLLvW9VJTkoQrnSpr2Px1ZIB2uTBY4+1VV3eALtZTTvW9cJmV7uaPirJ +gEAQMY2uWHJTOPqzDdB1RwAB3P46b208nPgWuW/DG2+NFhnkGxQGceITRSIc9StF +icJtVeYPTgOuVsV01V1SrdpgtUg2sEXCfJKWxHROXkFnf0lxibC1m1gRiaLMDHkZ +sFDPgBpNuGNcf5wtqDxBTwiRhsgwqtMRtXLTzNxh7VDUIXnu4CrwD4Pcmeul/qnd +5hrHyz7MF0ZUep0IkcR0O3ullo09Ayptsaxv8xcSjKPP7Kt8U1h7YQie/hVQ5roi +Uhjf1PeaNtIsZtrf0nJnrbj4yY/ZdIXP8uVDWT0+GCDW055cEw6XfTdsRdMzMQqc +ZfpR7kh2quAuvTzVVzrHve+bVB/AmHXJr1MKPLS7wfyaqESCbVmP+9k7bybjwCKU +LlPuQVFFtE7ZBSgzkORTfjIMSY0XwISzZY8clowrkHU/ATj6MTZo5mWq18ddEBl3 +3dbUHqM8g9BnSd0oOXORQqInZY1G0U2+O/AJB6haaQAI2LBeSqf0GH+5BU9Ty7wH +QEfQaQLnwTG3gwugluYTSjn1K9SiHptDHfNxBnCPOflm2PriDAvkylgnHHIRjbsn +PnC/Wn0QiVUvP4WuVb+p0cfR7s0f6diBuaWaWY6acd0vbrXqs1qp78sqKZ1qVCMA +FJ+S8IJmu4q9Up92XiyWgMQWi/oa2u9HoNh1K9+LMrXiEnson0VJlCy+SQ+QxTpK +rOp0bThlqaZF9VYSoawfGiLjbwr2rh8fJ/1bIENy0sIyWvPyRFyl63ku9nI46Ze+ +qQFiG9GRURzRCjyhDZIWJT4F6m65o5LoKFeFTi2WwAV9UK744F06SxsIGHNMm5EV +iXLIkipWqGJZ/UUEv3vleirud0STQFpp2NYBIGNtEH1LbhjIeF0rALx8+lnPx54F +atNh52qKkiz/VMBnZ/q/z3+qK9G4ou4b/AB4xzPOQUMLUQ3/aiJciFGRpBCm5QTn +bnO0IiCpLIgQu6rmEJ59iF5pbujMFXgF5W9DdxvSSvWhsRgu1+V9vUVfR7h9HXc3 +hIglijRDwVSzlvuVslMLtmy+fkzzezFvsmgRPy6t5dGpqmvfGel/wC6m3kQ+0IHt +t/GUTgPoVS52YhB4xurMsGLYQbjuLnnZ8rc/2O7ciqHhW0tB40D04L6Ap7rCLuqK +oRY= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-openssl.cnf new file mode 100644 index 0000000..8016fb3 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-openssl.cnf @@ -0,0 +1,242 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Users + +commonName = Common Name (eg, YOUR name) +commonName_default = administrator@plugindom.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = administrator@plugindom.samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for administrator@plugindom.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:administrator@plugindom.samba.example.com + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-private-key.pem new file mode 100644 index 0000000..a68aaac --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvBwD3uYeFxqFWxO4qbEmNrJ8TtKKPyA36lf2RjiehibNc8xt +pqFOISmJ8H51pY1fkkKdiIEhZowvG/UUVGvtGMmnpqcWBxAndzHUkKXNopyWwBiS +dvkSQOxRVBI2zsUC/Z65gEyB6X5bWS1KfAo1DA+FoLmTI3c1i94Y510+JSfMDvAP +q0ClCAKE8c+bZjcSNwJMA0ME1amtbtKIxIX685/yXW0f9FSh10qTxULpy9r/vXCL +J3VNd7Dql/GAdYRXXh7lpdmJKOhEoHdmCGRRwErQBsextB5rCpSgYVqee1vWSKse +fmVD2eCRUfUrQ5mhlLt/qivpVGnE4/HgOHef+QIDAQABAoIBABUKwTgW37jP46j7 +fMWmplKqBpO+o25KSVbyff7+6GSzRHo2nPFty9KT1fVMABcDyHQQ9ZRGdZkGB2MG +OD71T7FdJV7UA/fIS9HehhukIGuXPpnAZenfFLakeLiBzRW2Hg6GydNbO5EF7Gv+ +T/2uGp79wYHoIFhwRlIeBwUifggjyWuLFproK+JGLtzNLEWnn12k/5oSbXTYOcvJ +mPKGe0XmBMtY8IqlH6BLi04XFWBFT+DE+U0Yx9OzrRi51srq4+acpX06GiaH2Q3E +J61gr4e2EcDf6AJiz+jihLLBrVgTFda+eldoRyS2eG8EPsD/O7jakiBbKuCIDWwo +YZnOrYECgYEA3gxYEohP1P/B9D8cSOBYOhwZL3aZBXnWMACup0ppJBWlDkUvNUJa +ScVZJuj7s6zPp1boWMjfQvfX8q4M7gC3mccotnYGR4zRm1iDbYuUUBmM1ChQ6Cks +nZRcvYskTOl+ja+aULEde/I6/kYIQFUWyYR6UmKHxXcV0Co9I0DcnVECgYEA2N8z +qGuVHpZOJPhCod4eFXxKUh1WYUzkMcH4RlJ/h+Y2BYkUDSQb26KBur7KvVHmJm1G +28zBqLS76/3nha8XuHlLmHnD+6R4LEe8d4sm7RHJWgQMzvrnqle30Db2hBK0dwNI +JkI9zzQZv7FIqT0DHZ8aWKc+D2luJdDdbboIDikCgYEAh5b8FNz9+q/ubMo46Ftu +JJXR30TJbimW3Bsei3MJvwokjxE6IYiR/6gtp2/veykUaDfOi6CljIwxZrRXmuH/ +Ozz9JGXvsbNQr06eer8X4s2nTEoOFaZG4zacZvXXRcvzBmvrjEiLG4uv8GMtWLNc +xdNKqpIWHEN6o3GXgbZywPECgYEAuWbfh70pR3PhrHNcq3rzJxURiG+yOA5/Cxaz +RJMkma6yQjs1HCLhefvMgjS3p/ALHJDRQfkjGjIgcZinxD6yva9cdCas6EVrwxc0 +xNH+Xi+VflH2DUCsqpDBAMzsJG7FPvVcSfDZXHlDBgDuiFgzgLBS2rVnNc/BLa0I +j9S5LDkCgYA8Cz5qcVfTU8QoS2ZrYxzLJM7m2h+BwLTaFtV8Gu0nkPQXT/Wa9QJj +h6eFGIYRvImNe0ASurTqDqQBmmWsFK9SofuPOGW8T+nBm+3ApjtTxev1zugV9YXO +cc2Opy84+OYqE4prg+qxg8/zgNtUF6IQ+LDB7AXS3FJGCyeCSMmILg== +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-req.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-req.pem new file mode 100644 index 0000000..0e58e9a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-S03-req.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDFTCCAf0CAQAwgc8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +DjAMBgNVBAsMBVVzZXJzMTIwMAYDVQQDDClhZG1pbmlzdHJhdG9yQHBsdWdpbmRv +bS5zYW1iYS5leGFtcGxlLmNvbTE4MDYGCSqGSIb3DQEJARYpYWRtaW5pc3RyYXRv +ckBwbHVnaW5kb20uc2FtYmEuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC8HAPe5h4XGoVbE7ipsSY2snxO0oo/IDfqV/ZGOJ6GJs1z +zG2moU4hKYnwfnWljV+SQp2IgSFmjC8b9RRUa+0YyaempxYHECd3MdSQpc2inJbA +GJJ2+RJA7FFUEjbOxQL9nrmATIHpfltZLUp8CjUMD4WguZMjdzWL3hjnXT4lJ8wO +8A+rQKUIAoTxz5tmNxI3AkwDQwTVqa1u0ojEhfrzn/JdbR/0VKHXSpPFQunL2v+9 +cIsndU13sOqX8YB1hFdeHuWl2Yko6ESgd2YIZFHAStAGx7G0HmsKlKBhWp57W9ZI +qx5+ZUPZ4JFR9StDmaGUu3+qK+lUacTj8eA4d5/5AgMBAAGgADANBgkqhkiG9w0B +AQsFAAOCAQEADZFjHLUC/AZU07Ax6GmjmSvP4OIxFm3NWS6OSD3a1MrPN/v6IGBl +joVTlMpIrVFg2/iXZnLSJechq9HFDJ7wyeIX+QgFwuTDG1cfH7Ji5Xk3HgN2oVyD +Eea02tTbTOLVGJk27yFJaKCmpGJ3mKiOBFmfZRXitE15hEvOMXVkJVR2FtxxW0fk +PLYDX74e4fLFZUCgmOh47Seuc0bZk4pLROAaUhxFPOuLiLs//YbdkY8LLz6MYXdv +ia08JhcEq6zbrPPvTxRtGTFHWSJUhpOkEroRfeT/8vgirwnGLlkeLXIL5l7iyUi+ +3Z01Qrv/frJxsAgMaXdBB4YZES+Z/qoiNA== +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-cert.pem new file mode 120000 index 0000000..282971d --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-cert.pem @@ -0,0 +1 @@ +USER-administrator@plugindom.samba.example.com-S03-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-private-key.pem new file mode 120000 index 0000000..b3fec41 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@plugindom.samba.example.com/USER-administrator@plugindom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +USER-administrator@plugindom.samba.example.com-S03-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem new file mode 100644 index 0000000..deb2b73 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 18 11:45:11 2016 GMT + Not After : Mar 13 11:45:11 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:07:44:3a:5f:f6:34:5f:27:8a:7a:6e:2f:fb: + 45:1f:c3:3d:dd:2c:43:65:f1:7a:29:3f:42:26:bd: + ff:4f:5d:91:c0:bb:75:e3:81:14:7d:59:72:78:96: + 1a:5e:8d:95:93:f4:5d:92:79:0e:24:77:4f:8b:08: + 4e:72:b1:99:88:63:06:74:b2:dc:f7:82:62:e9:dd: + 6f:e5:a7:b4:c9:44:0c:e4:43:41:f8:57:a9:20:b1: + 70:c1:76:a1:48:5b:e9:54:b6:4f:22:50:93:90:f0: + 62:32:50:9a:6e:22:6b:37:a0:f7:1f:fc:b1:5f:ae: + e2:0b:88:6d:ea:29:b6:01:27:b2:84:ef:10:4d:6c: + 0a:df:ea:a9:8a:82:98:60:a7:52:73:a4:f7:7c:b2: + 4a:b9:f0:9b:c4:f8:19:5a:c0:84:54:52:35:c8:92: + 4f:16:af:d6:36:a6:78:57:55:e5:5e:6b:62:00:fa: + 48:c2:7a:e7:17:38:b5:23:d5:a8:fb:7d:df:42:5c: + 03:f4:7c:ef:ff:f1:a0:e6:d8:27:93:06:b3:a3:21: + 68:0e:c4:60:20:02:46:2f:2b:d8:88:e4:2b:01:c2: + 31:5a:55:28:be:55:03:f2:06:2b:e4:ec:48:60:e4: + b6:db:a1:f0:c5:24:ba:e1:a8:e2:6a:fb:0b:40:6c: + 3d:f5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@samba.example.com + X509v3 Subject Key Identifier: + 70:86:EC:68:B4:51:8A:1C:12:65:A0:2A:B3:43:33:12:65:83:8D:40 + X509v3 Authority Key Identifier: + keyid:46:87:86:C2:E7:19:CF:16:4C:0C:62:CB:73:7F:FD:8F:19:E4:B5:42 + + X509v3 Subject Alternative Name: + email:administrator@samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 5d:b1:10:f8:36:dd:a9:fd:8d:be:31:53:1d:cf:b5:ea:33:1a: + 85:0f:13:8d:cc:67:91:41:97:e4:e9:67:6a:0c:ce:a4:9a:06: + b3:53:bf:e6:6d:f1:d1:32:7d:54:5d:6a:a8:94:fe:d4:f6:62: + 85:0f:e0:73:f8:ce:51:32:18:65:50:34:f9:f2:66:f8:ec:fd: + 94:c2:1d:28:6f:ce:3c:b3:0a:0a:cc:8b:fb:2c:e8:44:d2:d8: + 64:d7:19:1c:a4:25:5f:75:63:bc:44:56:64:cb:ca:8c:43:75: + 1e:95:36:98:a1:c6:49:e6:14:60:ad:87:91:af:d8:3c:d2:63: + 52:82:02:0a:42:c0:e3:7b:50:51:37:d5:c0:a5:0c:09:ac:2d: + a0:b3:29:e4:9e:bf:d3:df:01:82:00:a5:ad:fb:35:e8:f6:1c: + d7:cb:d1:3c:54:1f:d2:73:38:ce:a6:0a:e2:77:0a:fc:e5:ff: + 7e:68:a6:c7:57:fd:c7:cf:95:48:9f:97:6f:fe:2e:9f:e3:d6: + b0:a5:b5:33:9f:12:c1:e6:12:15:77:33:8f:1e:35:b5:88:f8: + 6b:47:88:e4:cb:49:f7:11:ba:19:39:55:5e:4a:5a:65:76:7e: + cc:3a:a7:fa:91:9a:ef:b5:c1:bf:f0:e7:a2:c6:9f:08:17:fc: + 4c:a4:ef:0b:d8:c7:a4:f9:74:36:b3:67:90:5e:84:26:83:bd: + 36:89:0d:c6:8c:1d:03:ce:8f:80:c9:0c:c6:c0:1e:eb:42:e7: + 97:7f:21:ac:b1:64:06:f6:1d:6d:0c:87:ff:c9:30:23:d3:21: + 1f:53:05:69:21:d5:26:ca:7f:ce:3a:4e:8d:d1:40:16:7e:a2: + c0:0f:95:0c:67:90:47:d2:e2:cf:87:ef:dc:35:18:2a:a2:21: + cd:67:b0:b2:14:9f:75:94:93:ba:8c:4d:45:71:cb:e9:df:cd: + f5:e3:f0:ff:c3:38:77:c2:41:55:d6:60:96:d8:bd:5f:09:22: + 97:44:8d:4d:b1:dd:68:39:04:1b:7a:57:3b:ca:56:27:87:31: + 55:84:6c:f0:65:af:ec:0b:52:87:28:0b:2d:52:c0:ce:a3:7d: + 7b:47:07:df:8a:65:e9:6f:da:e7:b6:94:06:69:b8:55:3d:11: + 01:c6:bf:0b:61:1b:cc:30:47:ab:cf:fb:72:62:f3:eb:66:11: + cd:1c:ab:4e:29:bf:b7:78:d6:09:ec:d7:67:5b:17:b9:34:cc: + af:5e:d9:02:0b:33:fc:a1:f2:64:33:c4:af:11:5b:08:f7:af: + ba:0d:68:d7:cf:d2:40:2f:56:20:34:da:82:18:7c:0e:71:61: + a6:58:60:00:30:a6:c7:25:3a:90:70:a0:14:e6:da:d8:12:e9: + b3:6a:c4:96:85:41:80:a6:71:17:b5:cf:4f:a2:2d:51:93:fd: + 26:eb:44:3c:2a:84:6a:da:18:10:d6:48:e3:8e:0f:c9:69:05: + 96:8c:96:f9:74:06:ab:11:d2:e4:e5:d7:22:db:13:93:d6:f9: + 24:84:56:7c:6a:43:a9:b8:30:33:2c:a4:42:9f:ec:f6:56:2d: + 46:cf:ec:26:49:5e:da:53:21:6b:8c:05:0d:b7:12:26:29:43: + 32:b2:6c:ed:07:47:75:2b:0b:7e:5d:28:1b:5b:7b:b5:63:13: + 55:4d:f7:a3:f6:fd:2d:f5:6d:43:83:40:46:b3:0d:d6:28:99: + d4:fb:89:fb:41:c6:15:35:a5:ee:1a:08:33:b3:0b:75:0a:d0: + fc:31:ec:77:80:e2:f0:ab:20:cc:43:24:67:42:a5:d7:e6:b0: + b9:84:fd:43:a0:5e:d9:78:10:97:d3:d1:b7:d9:33:70:0f:4d: + f0:a1:ac:22:d7:36:53:68:6d:39:e0:14:dc:d7:ea:1e:c2:92: + 1b:f8:2a:99:97:14:76:2c:89:3f:b7:89:c7:69:6e:5b:dd:8e: + 47:7a:f0:0e:a4:d0:18:c6:c4:34:f0:b8:84:3a:6e:ee:1e:7b: + 84:58:d2:10:a6:a2:0c:14:a8:55:e9:c5:7e:ab:97:e4:9d:b5: + f0:9f:2e:36:ac:2f:73:30:c8:b1:fc:b4:ce:b4:39:bd:59:75: + b8:24:5a:b1:67:de:34:3f:4e:17:5d:d3:bc:bb:6a:6a:b7:3e: + 0b:e8:4d:3b:08:d6:de:a7:9a:d7:8d:60:56:bb:3e:6c:d0:a7: + f8:45:a2:52:a3:b5:1e:ef:56:df:14:62:52:ed:36:ab:cc:7a: + a1:96:14:9a:e9:de:4a:28:68:bd:21:2d:60:d5:06:8a:e9:5e: + b6:ce:e1:b4:ed:56:9f:99:87:fe:20:bb:d5:8d:0d:72:1d:7e: + 88:27:9c:66:d5:26:aa:32:0a:ad:64:de:b8:13:2d:51:cc:8b: + e2:f4:c1:63:a6:64:e8:03:08:42:38:bf:f4:fe:b3:25:03:1b: + 14:b9:68:81:14:b9:5d:b9:6a:eb:f0:a9:24:41:8e:49:03:be: + 0b:55:cf:ac:77:68:ed:54:ae:55:40:dd:31:c4:3a:e2:d7:86: + d5:d5:e4:5e:5b:ce:9e:da:a1:90:58:e1:b3:7c:a6:87:15:bd: + 3a:67:b9:ab:29:de:4f:af:08:98:89:45:62:8f:db:5b:2e:2b: + e8:97:35:a2:fc:4f:cf:63:7d:56:a0:51:dd:3f:b2:90:a6:9b: + a0:9b:9e:93:8d:9d:92:b2:ed:36:d5:e1:f1:e3:97:dc +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTgxMTQ1MTFaFw0zNjAzMTMxMTQ1MTFaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJB0Q6X/Y0XyeKem4v ++0Ufwz3dLENl8XopP0Imvf9PXZHAu3XjgRR9WXJ4lhpejZWT9F2SeQ4kd0+LCE5y +sZmIYwZ0stz3gmLp3W/lp7TJRAzkQ0H4V6kgsXDBdqFIW+lUtk8iUJOQ8GIyUJpu +Ims3oPcf/LFfruILiG3qKbYBJ7KE7xBNbArf6qmKgphgp1JzpPd8skq58JvE+Bla +wIRUUjXIkk8Wr9Y2pnhXVeVea2IA+kjCeucXOLUj1aj7fd9CXAP0fO//8aDm2CeT +BrOjIWgOxGAgAkYvK9iI5CsBwjFaVSi+VQPyBivk7Ehg5LbbofDFJLrhqOJq+wtA +bD31AgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFHCG7Gi0UYoc +EmWgKrNDMxJlg41AMB8GA1UdIwQYMBaAFEaHhsLnGc8WTAxiy3N//Y8Z5LVCMFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAXbEQ+Dbdqf2NvjFTHc+1 +6jMahQ8TjcxnkUGX5OlnagzOpJoGs1O/5m3x0TJ9VF1qqJT+1PZihQ/gc/jOUTIY +ZVA0+fJm+Oz9lMIdKG/OPLMKCsyL+yzoRNLYZNcZHKQlX3VjvERWZMvKjEN1HpU2 +mKHGSeYUYK2Hka/YPNJjUoICCkLA43tQUTfVwKUMCawtoLMp5J6/098BggClrfs1 +6PYc18vRPFQf0nM4zqYK4ncK/OX/fmimx1f9x8+VSJ+Xb/4un+PWsKW1M58SweYS +FXczjx41tYj4a0eI5MtJ9xG6GTlVXkpaZXZ+zDqn+pGa77XBv/DnosafCBf8TKTv +C9jHpPl0NrNnkF6EJoO9NokNxowdA86PgMkMxsAe60Lnl38hrLFkBvYdbQyH/8kw +I9MhH1MFaSHVJsp/zjpOjdFAFn6iwA+VDGeQR9Liz4fv3DUYKqIhzWewshSfdZST +uoxNRXHL6d/N9ePw/8M4d8JBVdZglti9Xwkil0SNTbHdaDkEG3pXO8pWJ4cxVYRs +8GWv7AtShygLLVLAzqN9e0cH34pl6W/a57aUBmm4VT0RAca/C2EbzDBHq8/7cmLz +62YRzRyrTim/t3jWCezXZ1sXuTTMr17ZAgsz/KHyZDPErxFbCPevug1o18/SQC9W +IDTaghh8DnFhplhgADCmxyU6kHCgFOba2BLps2rEloVBgKZxF7XPT6ItUZP9JutE +PCqEatoYENZI444PyWkFloyW+XQGqxHS5OXXItsTk9b5JIRWfGpDqbgwMyykQp/s +9lYtRs/sJkle2lMha4wFDbcSJilDMrJs7QdHdSsLfl0oG1t7tWMTVU33o/b9LfVt +Q4NARrMN1iiZ1PuJ+0HGFTWl7hoIM7MLdQrQ/DHsd4Di8KsgzEMkZ0Kl1+awuYT9 +Q6Be2XgQl9PRt9kzcA9N8KGsItc2U2htOeAU3NfqHsKSG/gqmZcUdiyJP7eJx2lu +W92OR3rwDqTQGMbENPC4hDpu7h57hFjSEKaiDBSoVenFfquX5J218J8uNqwvczDI +sfy0zrQ5vVl1uCRasWfeND9OF13TvLtqarc+C+hNOwjW3qea141gVrs+bNCn+EWi +UqO1Hu9W3xRiUu02q8x6oZYUmuneSihovSEtYNUGiulets7htO1Wn5mH/iC71Y0N +ch1+iCecZtUmqjIKrWTeuBMtUcyL4vTBY6Zk6AMIQji/9P6zJQMbFLlogRS5Xblq +6/CpJEGOSQO+C1XPrHdo7VSuVUDdMcQ64teG1dXkXlvOntqhkFjhs3ymhxW9Ome5 +qyneT68ImIlFYo/bWy4r6Jc1ovxPz2N9VqBR3T+ykKaboJuek42dkrLtNtXh8eOX +3A== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem new file mode 100644 index 0000000..8fd071e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIoZ6d4mqaZJgCAggA +MBQGCCqGSIb3DQMHBAjIgOrp5hZNzwSCBMjN+4OCjg+nTVC3WPMEHePoX4Utg7nv +KymusJKn1Uh6tuVjP3JJtxQUtFblEeeeNtFGH7voDbW/BUFWJMgwleNdH6yeB4jw +8AaSFNB325sUKTK4jzzVJPPbV2zf59ZnJN334RqlcJIMc4ptd/L2kvZhkEhQmAXW +z70lz1ufz498vdeFu1FvyC2TQInHglCVbJBBde+hxVe66O2/ztjzpYhYEvPrPaGm +TWjEdBsd1bpcspsbXhGd+gyA23S+Tg3VHXooLFW8C5AFFBVyEn8f7dv3ThGLCrG8 +/bkBr+WegR6r/etNwIGeXerdGzS+NMZZ2t0x7eoAAJetUtj4YJHWcaInvRlB8bJ/ +dJ64q6iOjACecIk17+DOksqjnxX8d2xTRxVd41wMMPoJ0rw/Se6fPty2Iyz+z+pK +XahP6Nj/TpXwnqvB44tMiWHENTN6+HbWecFyCVHcx1NOsWex50JZbsufsmwffi6H +Sk8tDuz+NseFnkbT1dDJirO/PkMaGk9+YqC9Hi/+prXFowcSKC0xrzuoz3PghxD9 +XoAdDhU3OGEfegwWT4GMQM4bOhiT2TOMmpoPuyi2bhtb/0v2pj3OaDxqUku9GBfK ++W7KSmRVLbHJkTZoLPaFtXvk0qOP6b6LH/bevMuPEz2YKiyhb8JDrIIspn/CfjJA +DbIINBH0d3HNUduX4+GhIKAKDJenciTQXAwA6wjsxIpEwb7jvgup+o+7cAW2GcWu +mQCrpRQDwM0jU/ATFx/aAJoTJjwEESn0h2AhZfnTbx4d0Re9tjzm2CwOvr6ZPc3H +eQzuC5Z+fksITab2ZG+s++qV09cUqlwjCm73ISVyqkajv774YjDSYTDw77wB6Xu7 +7i7mKDXGqGdUgaIry6wMmJI+dumMArzBtcG0AGI8f/WvpK5R50q5Msx0fS4aBva7 +QDcqWfz89yIjJvxW6R+56PsZDV4uOSwFfSMqizNVc1fwoGmgLmPx2ACqxksIetX1 +7rvd1OZG2Q5Mmbs2VX9+LPWgXQkOvW2OL7Ywr6oWdlsOyNWzUaZFkhmKLnTqT9kG +hzt64fR4XZMrSpCHNFhECve2GCMqQDzUaoNwOFM5t6G9xSbHfZlA6AvE4fS1so7r +NiEycl/JBwatJyYHw8OpN4Honry/OHJONj95Hl3LUL4s1YXuXyOFsovPDH1ot5t6 +tLSiK1ggdpi8nxQY7j86beu1JGOMVoZF15RGPbam8HoGJM93iCe6yI+pEa9rytfy +PFg6QscmaAe5oA2Aw3HTjTcyz4sKOct8mYkbWdSgoRLhN4fXM+5/lgTolBpsrFVZ +4bxkFmkRlc5CDBpGkY/4j4AsXiKZSsB+iX3abQvXL4f1YFqggFLBLVEtaECcarfN +dINQJCQvfK79ZBuMYZAieAoiuF7CEPDQCfwRJ8H/35JdcnXg3vEusKhapEfJg+Dg +xbNJc9Vlzta/ABTaj4nxKFXGWJEY/IYcWwM2NN+SdrEwzoykrOUGkwIrCVqshXZx +bgN8qnt6D9OPlm5xos12RGwmlDIenmQMt+aG7RXGOWVa0nmv/VTVkLmRfrBcEJ6F +XYsKJ6oz2vgItlKoZLDpjiRB+ENbRwfJy1Hd6lPTi/a8bw9izyEQXef3X3pT9YfM +Tow= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf new file mode 100644 index 0000000..db72360 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf @@ -0,0 +1,242 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Users + +commonName = Common Name (eg, YOUR name) +commonName_default = administrator@samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = administrator@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for administrator@samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:administrator@samba.example.com + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem new file mode 100644 index 0000000..1d5ceeb --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAyQdEOl/2NF8ninpuL/tFH8M93SxDZfF6KT9CJr3/T12RwLt1 +44EUfVlyeJYaXo2Vk/RdknkOJHdPiwhOcrGZiGMGdLLc94Ji6d1v5ae0yUQM5ENB ++FepILFwwXahSFvpVLZPIlCTkPBiMlCabiJrN6D3H/yxX67iC4ht6im2ASeyhO8Q +TWwK3+qpioKYYKdSc6T3fLJKufCbxPgZWsCEVFI1yJJPFq/WNqZ4V1XlXmtiAPpI +wnrnFzi1I9Wo+33fQlwD9Hzv//Gg5tgnkwazoyFoDsRgIAJGLyvYiOQrAcIxWlUo +vlUD8gYr5OxIYOS226HwxSS64ajiavsLQGw99QIDAQABAoIBAFcGeUfYEQpdAw4U +sCy/Vw5IBDkCF29DWUIP64BAEg12kUlhHcjOMWOOXFrNiD7UhiNVz0hAdZnduKaU +gvlt3uxHCh1s7PGNFWrufKlrr3zNo9MRNrbepA3OIuTtiSZ8+4a7oYhWX3uIRMpJ +UIFLDyU23qSPTO4CFEMv3X1Ybz0SALtUxZr5fwtAOn/EdiqSQzF65tBe0OzMWzfc +Jm1Uvv3H/Dm8intOUMDQk+8KmQSp/Mj1Fwi4jU77WbZWXmAuDE1bQ6TSUHUBYBdp +FgmRPk8gcOOHNjvEa62hZ2KIyKixjXoRKm9Sxr3jeZWG9QZcJFyVRMH37wa9vU8U +d9lszkUCgYEA7ZkeFNO7ISqi4G5VeaTiZFMtGwHBUHYU30ccPg5T1gNNb0rOo17Y +BOuqPE3HbqsfRiN1jTIkEE68ngP1VCE9H7WQ1pxMZSqBIotgGqZLFBkvbKTnlCNL +dAtgTFQbZuBP/M/JN8g934kgjn33LOfPKoCzCnO9XZwEKVyRivQBV48CgYEA2JkT +wVvLxB6NgshStjLBcLbeIPADT24xcH7Wyr7WoSx+F/J0q3nT5qHAFmVDttFMujc2 +EVBeJclMxmC529O+SPid8X3/Y9BqOwSzBdFIEBw0xbv0ntgCr0qYNHkkqqvvDNCm +4VsIOeNi4YvNwHFuUB4+7upAkG/khGORJnIJ8DsCgYEAiG9Rb8I5hY0XJGsXGBgP +jG6ayxRR7qMvzxrlY9kUWSNiVtMNH5D52LF++svrBmirN7pq6R5uyRJ9ivtY5+uC +TvAS8LmlwL4Mk0qXcBYnrK3dprR26oDt9gAGVy5A4e1S4ShsMmUA6piyokBBLH8c +XhqzNQBLMDLDzQCD7te44Y8CgYEAnVYlCZIa5G2lMdk+a+dWqP/NP3PZk7th4mvg +rwoNcqqVNeQDaARpLuFUXXBVzdkfuS0d81nD6gLd6ESe/dZEJVGjuaZi/CiK4jA5 +swIhLMKweupbeX9EA/1VrthJEEkwrshqUM0FnrdUPq6FWUOMdFpkMLytBb6h6qFA +8QJpwb0CgYEA11acodjgxuuLPOOxUG7sl++ZNT8/2Upx02QbPknJ/Hmu63CHv2qL +HxGvsynw3ardm9flgbpxSuU5K2ntQjo64SfZxgTC5z5Oqr0m6oIoMutQTNvTnbtm +AhQ9V9Z795DcLaDDNAQB3LmEvQWT5FSDSdi2lLXzQWlHf//VGDIipjE= +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem new file mode 100644 index 0000000..7c2f163 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDATCCAekCAQAwgbsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +DjAMBgNVBAsMBVVzZXJzMSgwJgYDVQQDDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4 +YW1wbGUuY29tMS4wLAYJKoZIhvcNAQkBFh9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4 +YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyQdEOl/2 +NF8ninpuL/tFH8M93SxDZfF6KT9CJr3/T12RwLt144EUfVlyeJYaXo2Vk/RdknkO +JHdPiwhOcrGZiGMGdLLc94Ji6d1v5ae0yUQM5ENB+FepILFwwXahSFvpVLZPIlCT +kPBiMlCabiJrN6D3H/yxX67iC4ht6im2ASeyhO8QTWwK3+qpioKYYKdSc6T3fLJK +ufCbxPgZWsCEVFI1yJJPFq/WNqZ4V1XlXmtiAPpIwnrnFzi1I9Wo+33fQlwD9Hzv +//Gg5tgnkwazoyFoDsRgIAJGLyvYiOQrAcIxWlUovlUD8gYr5OxIYOS226HwxSS6 +4ajiavsLQGw99QIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAGx2x4siii0Z5wAL +u/UPPTQqqKvOdtAGpQzeT/pBw1ttXq8G3tgSJ4H0KAcqFfUFdjTVqMbzSGFF3InX +uop0fkZIG4A5uMKNget2atlP6BUejlVoHWA2Tyuioo+iYDAosN9fI3RkgOgEl4T2 +fwcOkae2uTVTUloDaBfzQNPRd86RCHVEYc+PSjVfNUoTjRug/BhR+7ZOTcDRFQ4N +61LeMll9j/ooFEYgpfXBygoDpx44mEH69c/7aLjydq/nLMKbCtNG7NYDAEUbruB4 +D48JYBDHB/1XqzvIYwmXLAdlZ3prNaF+c/O7KHqa+R2kilZ+YvhUuyuHLEMecNsD +owjRHmw= +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem new file mode 120000 index 0000000..3b134b6 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem @@ -0,0 +1 @@ +USER-administrator@samba.example.com-S01-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem new file mode 120000 index 0000000..964892e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem @@ -0,0 +1 @@ +USER-administrator@samba.example.com-S01-private-key.pem \ No newline at end of file -- 1.9.1 From 9134944fe2b8129c264718ed331fbb5b203bfb49 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 205/440] selftest: mark commands in manage-CA-samba.example.com.sh as DONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit 2a96885ac706ae3e7c6fd7aaff0215f3f171bc27) --- selftest/manage-ca/manage-CA-samba.example.com.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/selftest/manage-ca/manage-CA-samba.example.com.sh b/selftest/manage-ca/manage-CA-samba.example.com.sh index 4a24039..449a58a 100644 --- a/selftest/manage-ca/manage-CA-samba.example.com.sh +++ b/selftest/manage-ca/manage-CA-samba.example.com.sh @@ -9,10 +9,10 @@ set -x # All passwords are "1234" # -./manage-ca.sh manage-CA-samba.example.com.cnf init_ca - -./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF -./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com - -./manage-ca.sh manage-CA-samba.example.com.cnf create_dc plugindc.plugindom.samba.example.com 0123456789ABCDEF -./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@plugindom.samba.example.com +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf init_ca +# DONE # +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com +# DONE # +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_dc plugindc.plugindom.samba.example.com 0123456789ABCDEF +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@plugindom.samba.example.com -- 1.9.1 From 12a6a183884ca7a76b2043dc7ed625a53ff33072 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 206/440] selftest: add Samba::prepare_keyblobs() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This copies the certificates from the samba.example.com CA if they exist. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit a6447fd6d010b525d235b894d5be62c807922cb5) --- selftest/target/Samba.pm | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm index ccc63f3..dabe442 100644 --- a/selftest/target/Samba.pm +++ b/selftest/target/Samba.pm @@ -75,6 +75,111 @@ sub nss_wrapper_winbind_so_path($) { return $ret; } +sub copy_file_content($$) +{ + my ($in, $out) = @_; + open(IN, "${in}") or die("failed to open in[${in}] for reading: $!"); + open(OUT, ">${out}") or die("failed to open out[${out}] for writing: $!"); + while() { + print OUT $_; + } + close(OUT); + close(IN); +} + +sub prepare_keyblobs($) +{ + my ($ctx) = @_; + + my $cadir = "$ENV{SRCDIR_ABS}/selftest/manage-ca/CA-samba.example.com"; + my $cacert = "$cadir/Public/CA-samba.example.com-cert.pem"; + my $cacrl_pem = "$cadir/Public/CA-samba.example.com-crl.pem"; + my $dcdnsname = "$ctx->{hostname}.$ctx->{dnsname}"; + my $dcdir = "$cadir/DCs/$dcdnsname"; + my $dccert = "$dcdir/DC-$dcdnsname-cert.pem"; + my $dckey_private = "$dcdir/DC-$dcdnsname-private-key.pem"; + my $userprincipalname = "administrator\@$ctx->{dnsname}"; + my $userdir = "$cadir/Users/$userprincipalname"; + my $usercert = "$userdir/USER-$userprincipalname-cert.pem"; + my $userkey_private = "$userdir/USER-$userprincipalname-private-key.pem"; + + my $tlsdir = "$ctx->{tlsdir}"; + my $pkinitdir = "$ctx->{prefix_abs}/pkinit"; + #TLS and PKINIT crypto blobs + my $dhfile = "$tlsdir/dhparms.pem"; + my $cafile = "$tlsdir/ca.pem"; + my $crlfile = "$tlsdir/crl.pem"; + my $certfile = "$tlsdir/cert.pem"; + my $keyfile = "$tlsdir/key.pem"; + my $usercertfile = "$pkinitdir/USER-$userprincipalname-cert.pem"; + my $userkeyfile = "$pkinitdir/USER-$userprincipalname-private-key.pem"; + + mkdir($tlsdir, 0700); + mkdir($pkinitdir, 0700); + my $oldumask = umask; + umask 0077; + + # This is specified here to avoid draining entropy on every run + # generate by + # openssl dhparam -out dhparms.pem -text -2 8192 + open(DHFILE, ">$dhfile"); + print DHFILE < Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 207/440] selftest: use Samba::prepare_keyblobs() and use the certs from the new CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit c321a59f267d1a997eff6f864a79437ef759adeb) --- selftest/target/Samba4.pm | 218 +--------------------------------------------- 1 file changed, 3 insertions(+), 215 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 23f70a6..dbf901b 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -247,219 +247,6 @@ sub mk_openldap($$) return ($slapd_conf_d, $pidfile); } -sub mk_keyblobs($$) -{ - my ($self, $tlsdir) = @_; - - #TLS and PKINIT crypto blobs - my $dhfile = "$tlsdir/dhparms.pem"; - my $cafile = "$tlsdir/ca.pem"; - my $certfile = "$tlsdir/cert.pem"; - my $reqkdc = "$tlsdir/req-kdc.der"; - my $kdccertfile = "$tlsdir/kdc.pem"; - my $keyfile = "$tlsdir/key.pem"; - my $adminkeyfile = "$tlsdir/adminkey.pem"; - my $reqadmin = "$tlsdir/req-admin.der"; - my $admincertfile = "$tlsdir/admincert.pem"; - my $admincertupnfile = "$tlsdir/admincertupn.pem"; - - mkdir($tlsdir, 0700); - my $oldumask = umask; - umask 0077; - - #This is specified here to avoid draining entropy on every run - open(DHFILE, ">$dhfile"); - print DHFILE <$keyfile"); - print KEYFILE <$adminkeyfile"); - - print ADMINKEYFILE <$cafile"); - print CAFILE <$certfile"); - print CERTFILE <$kdccertfile"); - print KDCCERTFILE <$admincertfile"); - print ADMINCERTFILE <$admincertupnfile"); - print ADMINCERTUPNFILE <{smb_conf}$?"); return undef; } + + Samba::prepare_keyblobs($ctx); + print CONFFILE " [global] netbios name = $ctx->{netbiosname} @@ -668,8 +458,6 @@ sub provision_raw_step1($$) "; close(CONFFILE); - $self->mk_keyblobs($ctx->{tlsdir}); - #Default the KDC IP to the server's IP if (not defined($ctx->{kdc_ipv4})) { $ctx->{kdc_ipv4} = $ctx->{ipv4}; -- 1.9.1 From ea242962d6a93028c388f48698226b1f54afd028 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 208/440] selftest: set tls crlfile if it exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b2c0f71db026353060ad47fd0a85241a3df8c703) --- selftest/target/Samba4.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index dbf901b..eb9c572 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -400,6 +400,8 @@ sub provision_raw_step1($$) } Samba::prepare_keyblobs($ctx); + my $crlfile = "$ctx->{tlsdir}/crl.pem"; + $crlfile = "" unless -e ${crlfile}; print CONFFILE " [global] @@ -420,6 +422,7 @@ sub provision_raw_step1($$) name resolve order = file bcast interfaces = $ctx->{interfaces} tls dh params file = $ctx->{tlsdir}/dhparms.pem + tls crlfile = ${crlfile} panic action = $RealBin/gdb_backtrace \%d wins support = yes server role = $ctx->{server_role} -- 1.9.1 From ea202507e47683b8be57887539403a9bde276458 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 209/440] selftest: setup information of new samba.example.com CA in the client environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b00c38afc6203f1e1f566db31a63cedba632dfab) --- selftest/selftest.pl | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/selftest/selftest.pl b/selftest/selftest.pl index 1d5826d..2707f72 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -27,6 +27,7 @@ use Cwd qw(abs_path); use lib "$RealBin"; use Subunit; use SocketWrapper; +use target::Samba; eval { require Time::HiRes; @@ -505,6 +506,42 @@ sub write_clientconf($$$) mkdir("$clientdir/ncalrpcdir", 0755); umask $mask; + my $cadir = "$ENV{SRCDIR_ABS}/selftest/manage-ca/CA-samba.example.com"; + my $cacert = "$cadir/Public/CA-samba.example.com-cert.pem"; + my $cacrl_pem = "$cadir/Public/CA-samba.example.com-crl.pem"; + my $ca_users_dir = "$cadir/Users"; + + if ( -d "$clientdir/pkinit" ) { + unlink <$clientdir/pkinit/*>; + } else { + mkdir("$clientdir/pkinit", 0700); + } + + # each user has a USER-${USER_PRINCIPAL_NAME}-cert.pem and + # USER-${USER_PRINCIPAL_NAME}-private-key.pem symlink + # We make a copy here and make the certificated easily + # accessable in the client environment. + my $mask = umask; + umask 0077; + opendir USERS, "${ca_users_dir}" or die "Could not open dir '${ca_users_dir}': $!"; + for my $d (readdir USERS) { + my $user_dir = "${ca_users_dir}/${d}"; + next if ${d} =~ /^\./; + next if (! -d "${user_dir}"); + opendir USER, "${user_dir}" or die "Could not open dir '${user_dir}': $!"; + for my $l (readdir USER) { + my $user_link = "${user_dir}/${l}"; + next if ${l} =~ /^\./; + next if (! -l "${user_link}"); + + my $dest = "${clientdir}/pkinit/${l}"; + Samba::copy_file_content(${user_link}, ${dest}); + } + closedir USER; + } + closedir USERS; + umask $mask; + open(CF, ">$conffile"); print CF "[global]\n"; print CF "\tnetbios name = client\n"; @@ -538,6 +575,8 @@ sub write_clientconf($$$) #We don't want to run 'speed' tests for very long torture:timelimit = 1 winbind separator = / + tls cafile = ${cacert} + tls crlfile = ${cacrl_pem} "; close(CF); } -- 1.9.1 From c2e88e7ab366c6e34ecd9af9088665823d3b6206 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 07:10:06 +0100 Subject: [PATCH 210/440] s3:selftest: rpc.samr.passwords.validate should run with [seal] in order to be realistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit 2c36501640207604a5c66fb582c2d5981619147e) --- source3/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index a4ff473..8b92921 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -341,8 +341,8 @@ for t in tests: plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ') plansmbtorture4testsuite(t, "plugin_s4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "rpc.samr.passwords.validate": - plansmbtorture4testsuite(t, "s3dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') - plansmbtorture4testsuite(t, "plugin_s4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "s3dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "plugin_s4_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "smb2.durable-open" or t == "smb2.durable-v2-open" or t == "smb2.replay": plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') -- 1.9.1 From a623e4b83c22a1021d81974e271cf9d3b373d834 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 09:13:46 +0100 Subject: [PATCH 211/440] s3:test_rpcclient_samlogon.sh: test samlogon with schannel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit f9a1915238dc7a573c58dd8c7bac3637689af265) --- source3/script/tests/test_rpcclient_samlogon.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source3/script/tests/test_rpcclient_samlogon.sh b/source3/script/tests/test_rpcclient_samlogon.sh index 01af7f8..a41ae44 100755 --- a/source3/script/tests/test_rpcclient_samlogon.sh +++ b/source3/script/tests/test_rpcclient_samlogon.sh @@ -12,16 +12,21 @@ PASSWORD="$2" shift 2 ADDARGS="$*" -rpcclient_samlogon() +rpcclient_samlogon_schannel_seal() { - $VALGRIND $BINDIR/rpcclient -U% -c "samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ + $VALGRIND $BINDIR/rpcclient -U% -c "schannel;samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ } +rpcclient_samlogon_schannel_sign() +{ + $VALGRIND $BINDIR/rpcclient -U% -c "schannelsign;samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ +} incdir=`dirname $0`/../../../testprogs/blackbox . $incdir/subunit.sh testit "rpcclient dsenumdomtrusts" $VALGRIND $BINDIR/rpcclient $ADDARGS -U% -c "dsenumdomtrusts" || failed=`expr $failed + 1` testit "rpcclient getdcsitecoverage" $VALGRIND $BINDIR/rpcclient $ADDARGS -U% -c "getdcsitecoverage" || failed=`expr $failed + 1` -testit "rpcclient samlogon" rpcclient_samlogon $ADDARGS || failed=`expr $failed +1` +testit "rpcclient samlogon schannel seal" rpcclient_samlogon_schannel_seal $ADDARGS || failed=`expr $failed +1` +testit "rpcclient samlogon schannel sign" rpcclient_samlogon_schannel_sign $ADDARGS || failed=`expr $failed +1` testok $0 $failed -- 1.9.1 From ee039ce7a09b8fbf5cb4f023f8bb1d1598458e15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 12:10:12 +0100 Subject: [PATCH 212/440] s4:torture/netlogon: add/use test_SetupCredentialsPipe() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This create a schannel connection to netlogon, this makes the tests more realistic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit 1a7d8b8602a687ff6eef45f15f597694e94e14b1) --- source4/torture/rpc/forest_trust.c | 12 +++-- source4/torture/rpc/netlogon.c | 98 +++++++++++++++++++++++++++++++------- source4/torture/rpc/netlogon.h | 7 +++ source4/torture/rpc/remote_pac.c | 34 ++++++++----- 4 files changed, 121 insertions(+), 30 deletions(-) diff --git a/source4/torture/rpc/forest_trust.c b/source4/torture/rpc/forest_trust.c index 74a56ef..758befc 100644 --- a/source4/torture/rpc/forest_trust.c +++ b/source4/torture/rpc/forest_trust.c @@ -592,7 +592,8 @@ static bool test_validate_trust(struct torture_context *tctx, NTSTATUS status; struct cli_credentials *credentials; struct dcerpc_binding *b; - struct dcerpc_pipe *p; + struct dcerpc_pipe *p1 = NULL; + struct dcerpc_pipe *p = NULL; struct netr_GetForestTrustInformation fr; struct lsa_ForestTrustInformation *forest_trust_info; @@ -620,7 +621,7 @@ static bool test_validate_trust(struct torture_context *tctx, trusted_dom_name, CRED_SPECIFIED); cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN); - status = dcerpc_pipe_connect_b(tctx, &p, b, + status = dcerpc_pipe_connect_b(tctx, &p1, b, &ndr_table_netlogon, credentials, tctx->ev, tctx->lp_ctx); @@ -632,11 +633,16 @@ static bool test_validate_trust(struct torture_context *tctx, return false; } - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES, credentials, &creds)) { torture_comment(tctx, "test_SetupCredentials3 failed.\n"); return false; } + if (!test_SetupCredentialsPipe(p1, tctx, credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + torture_comment(tctx, "test_SetupCredentialsPipe failed.\n"); + return false; + } netlogon_creds_client_authenticator(creds, &a); diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index a2450cf..32e4e1e 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -359,6 +359,35 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, return true; } +bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, + struct torture_context *tctx, + struct cli_credentials *machine_credentials, + struct netlogon_creds_CredentialState *creds, + uint32_t additional_flags, + struct dcerpc_pipe **_p2) +{ + NTSTATUS status; + struct dcerpc_binding *b2 = NULL; + struct dcerpc_pipe *p2 = NULL; + + b2 = dcerpc_binding_dup(tctx, p1->binding); + torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup"); + dcerpc_binding_set_flags(b2, + DCERPC_SCHANNEL | additional_flags, + DCERPC_AUTH_OPTIONS); + + cli_credentials_set_netlogon_creds(machine_credentials, creds); + status = dcerpc_pipe_connect_b(tctx, &p2, b2, + &ndr_table_netlogon, + machine_credentials, + tctx->ev, tctx->lp_ctx); + cli_credentials_set_netlogon_creds(machine_credentials, NULL); + torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel"); + + *_p2 = p2; + return true; +} + /* try a change password for our machine account */ @@ -436,7 +465,7 @@ static bool test_SetPassword(struct torture_context *tctx, try a change password for our machine account */ static bool test_SetPassword_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t negotiate_flags) { @@ -445,14 +474,20 @@ static bool test_SetPassword_flags(struct torture_context *tctx, struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential, return_authenticator; struct samr_Password new_password; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials2(p, tctx, negotiate_flags, + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -532,7 +567,7 @@ static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len) try a change password for our machine account */ static bool test_SetPassword2_with_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t flags) { @@ -544,11 +579,19 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx, struct samr_Password nt_hash; struct netr_Authenticator credential, return_authenticator; struct netr_CryptPassword new_password; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) { + if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials, + cli_credentials_get_secure_channel_type(machine_credentials), + &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -2454,7 +2497,7 @@ static bool test_LogonControl2Ex(struct torture_context *tctx, } static bool test_netr_GetForestTrustInformation(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { struct netr_GetForestTrustInformation r; @@ -2462,12 +2505,18 @@ static bool test_netr_GetForestTrustInformation(struct torture_context *tctx, struct netr_Authenticator a; struct netr_Authenticator return_authenticator; struct lsa_ForestTrustInformation *forest_trust_info; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; netlogon_creds_client_authenticator(creds, &a); @@ -3290,7 +3339,7 @@ static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx, } static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t negotiate_flags) { @@ -3303,14 +3352,20 @@ static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx, struct netr_TrustInfo *trust_info; struct netlogon_creds_CredentialState *creds; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; struct samr_Password nt_hash; - if (!test_SetupCredentials3(p, tctx, negotiate_flags, + if (!test_SetupCredentials3(p1, tctx, negotiate_flags, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; netlogon_creds_client_authenticator(creds, &a); @@ -3360,7 +3415,7 @@ static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx, } static bool test_GetDomainInfo(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { struct netr_LogonGetDomainInfo r; @@ -3383,14 +3438,20 @@ static bool test_GetDomainInfo(struct torture_context *tctx, char **spns = NULL; int num_spns = 0; char *temp_str; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n"); - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; /* We won't double-check this when we are over 'local' transports */ if (dcerpc_server_name(p)) { @@ -3815,7 +3876,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, } static bool test_GetDomainInfo_async(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { NTSTATUS status; @@ -3829,6 +3890,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, int i; union netr_WorkstationInfo query; union netr_DomainInfo info; + struct dcerpc_pipe *p = NULL; torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT); @@ -3836,6 +3898,10 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } ZERO_STRUCT(r); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); diff --git a/source4/torture/rpc/netlogon.h b/source4/torture/rpc/netlogon.h index f2f2a6f..a4ab8f0 100644 --- a/source4/torture/rpc/netlogon.h +++ b/source4/torture/rpc/netlogon.h @@ -28,3 +28,10 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, uint32_t negotiate_flags, struct cli_credentials *machine_credentials, struct netlogon_creds_CredentialState **creds_out); + +bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, + struct torture_context *tctx, + struct cli_credentials *machine_credentials, + struct netlogon_creds_CredentialState *creds, + uint32_t additional_flags, + struct dcerpc_pipe **_p2); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index a6d49fc..ffe79da 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -118,7 +118,7 @@ static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx, /* Also happens to be a really good one-step verfication of our Kerberos stack */ static bool test_PACVerify(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *credentials, enum netr_SchannelType secure_channel_type, const char *test_machine_name, @@ -151,7 +151,8 @@ static bool test_PACVerify(struct torture_context *tctx, struct auth_session_info *session_info; struct pac_data *pac_data; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; TALLOC_CTX *tmp_ctx = talloc_new(tctx); torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed"); @@ -175,11 +176,16 @@ static bool test_PACVerify(struct torture_context *tctx, credentials); torture_assert(tctx, server_creds, "Failed to copy of credentials"); - if (!test_SetupCredentials2(p, tctx, negotiate_flags, + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, server_creds, secure_channel_type, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -525,14 +531,15 @@ static bool test_PACVerify_workstation_des(struct torture_context *tctx, /* Check various ways to get the PAC, in particular check the group membership and other details between the PAC from a normal kinit, S2U4Self and a SamLogon */ static bool test_S2U4Self(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *credentials, enum netr_SchannelType secure_channel_type, const char *test_machine_name, uint32_t negotiate_flags) { NTSTATUS status; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; struct netr_LogonSamLogon r; @@ -584,6 +591,17 @@ static bool test_S2U4Self(struct torture_context *tctx, credentials); torture_assert(tctx, server_creds, "Failed to copy of credentials"); + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, + server_creds, secure_channel_type, + &creds)) { + return false; + } + if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; + auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -744,12 +762,6 @@ static bool test_S2U4Self(struct torture_context *tctx, r.out.validation = &validation; r.out.authoritative = &authoritative; - if (!test_SetupCredentials2(p, tctx, negotiate_flags, - server_creds, secure_channel_type, - &creds)) { - return false; - } - ZERO_STRUCT(auth2); netlogon_creds_client_authenticator(creds, &auth); -- 1.9.1 From 8b85c966cd9eaf698a16e2e9a1bf67a913417cc1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:24:03 +0100 Subject: [PATCH 213/440] s4:torture/rpc/samr: use DCERPC_SEAL in setup_schannel_netlogon_pipe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 26e5ef68188d2e44d42f75ed6aabf2557c9ce5ce) --- source4/torture/rpc/samr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 293b672..0c786c1 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -3257,7 +3257,8 @@ static bool setup_schannel_netlogon_pipe(struct torture_context *tctx, * with INTERNAL_ERROR */ status = dcerpc_binding_set_flags(b, - DCERPC_SCHANNEL | DCERPC_SIGN | + DCERPC_SCHANNEL | + DCERPC_SIGN | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO, DCERPC_AUTH_OPTIONS); torture_assert_ntstatus_ok(tctx, status, "set flags"); -- 1.9.1 From 01e333cc9f6e2b9b8f0389810a8411bfb19b7700 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 01:56:07 +0100 Subject: [PATCH 214/440] s4:torture/rpc/samlogon: use DCERPC_SEAL for netr_LogonSamLogonEx and validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 050a1d0653716fd7c166d35a7236a014bf1d1516) --- source4/torture/rpc/samlogon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 3c5398d..bfa8b63 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -1754,7 +1754,8 @@ bool torture_rpc_samlogon(struct torture_context *torture) * with INTERNAL_ERROR */ status = dcerpc_binding_set_flags(b, - DCERPC_SCHANNEL | DCERPC_SIGN | + DCERPC_SCHANNEL | + DCERPC_SIGN | DCERPC_SEAL | DCERPC_SCHANNEL_128, DCERPC_AUTH_OPTIONS); torture_assert_ntstatus_ok(torture, status, "set flags"); -- 1.9.1 From 7d4a80ed770594208393ae0be3d6b8677768e5eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 18:09:26 +0100 Subject: [PATCH 215/440] s4:torture/rpc: correctly use torture_skip() for test_ManyGetDCName() without NCACN_NP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 50581689d924032de1765ec884dbd160652888be) --- source4/torture/rpc/netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 32e4e1e..c5c565f 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -3973,7 +3973,7 @@ static bool test_ManyGetDCName(struct torture_context *tctx, int i; if (p->conn->transport.transport != NCACN_NP) { - return true; + torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP"); } torture_comment(tctx, "Torturing GetDCName\n"); -- 1.9.1 From c91dbaf0752bf61b56f4a0a4323b76e580c36bb9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 02:55:30 +0100 Subject: [PATCH 216/440] s4:torture/rpc/schannel: don't use validation level 6 without privacy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 733ccd13209c20f8e76ae7b47e1741791c1cd6ba) --- source4/torture/rpc/schannel.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index de93fca..e04f938 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -62,6 +62,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct netr_SamBaseInfo *base; const char *crypto_alg = ""; bool can_do_validation_6 = true; + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (lpcfg_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; @@ -131,16 +132,26 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, } } - r.in.validation_level = 6; + dcerpc_binding_handle_auth_info(b, NULL, &auth_level); + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + r.in.validation_level = 6; - torture_comment(tctx, - "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", - ninfo.identity_info.account_name.string, crypto_alg, - r.in.validation_level); + torture_comment(tctx, + "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + + torture_assert_ntstatus_ok(tctx, + dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), + "LogonSamLogonEx failed"); + } else { + torture_comment(tctx, + "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + auth_level, ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + r.out.result = NT_STATUS_INVALID_INFO_CLASS; + } - torture_assert_ntstatus_ok(tctx, - dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), - "LogonSamLogonEx failed"); if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) { can_do_validation_6 = false; } else { -- 1.9.1 From b006b667974203d428cbe9e1fe09e5b5514f7c2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:01:47 +0200 Subject: [PATCH 217/440] auth/gensec: make sure gensec_security_by_auth_type() returns NULL for AUTH_TYPE_NONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ops->auth_type == 0, means the backend doesn't support DCERPC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit cc3dea5a8104eef2cfd1f8c05e25da186c334320) --- auth/gensec/gensec_start.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index c7356d2..cb836f4 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -226,7 +226,13 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_auth_type( int i; const struct gensec_security_ops **backends; const struct gensec_security_ops *backend; - TALLOC_CTX *mem_ctx = talloc_new(gensec_security); + TALLOC_CTX *mem_ctx; + + if (auth_type == DCERPC_AUTH_TYPE_NONE) { + return NULL; + } + + mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } -- 1.9.1 From cc519bf9f55c235616a1970b95bcf7ae9a067292 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:08:43 +0100 Subject: [PATCH 218/440] auth/gensec: split out a gensec_verify_dcerpc_auth_level() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only need this logic once. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 57946ac7c19c4e9bd8893c3acb9daf7c4bd02159) --- auth/gensec/gensec.c | 103 +++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 01cceaf..548091a 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -217,6 +217,50 @@ _PUBLIC_ size_t gensec_max_update_size(struct gensec_security *gensec_security) return gensec_security->max_update_size; } +static NTSTATUS gensec_verify_dcerpc_auth_level(struct gensec_security *gensec_security) +{ + if (gensec_security->dcerpc_auth_level == 0) { + return NT_STATUS_OK; + } + + /* + * Because callers using the + * gensec_start_mech_by_auth_type() never call + * gensec_want_feature(), it isn't sensible for them + * to have to call gensec_have_feature() manually, and + * these are not points of negotiation, but are + * asserted by the client + */ + switch (gensec_security->dcerpc_auth_level) { + case DCERPC_AUTH_LEVEL_INTEGRITY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + case DCERPC_AUTH_LEVEL_PRIVACY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SEAL for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + break; + } + + return NT_STATUS_OK; +} + _PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, struct tevent_context *ev, @@ -261,31 +305,9 @@ _PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security, * these are not points of negotiation, but are * asserted by the client */ - switch (gensec_security->dcerpc_auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SEAL for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - break; - default: - break; + status = gensec_verify_dcerpc_auth_level(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; } return NT_STATUS_OK; @@ -458,34 +480,9 @@ static void gensec_update_subreq_done(struct tevent_req *subreq) * these are not points of negotiation, but are * asserted by the client */ - switch (state->gensec_security->dcerpc_auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SEAL for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - break; - default: - break; + status = gensec_verify_dcerpc_auth_level(state->gensec_security); + if (tevent_req_nterror(req, status)) { + return; } tevent_req_done(req); -- 1.9.1 From ae13c035a47182b2150e68de93f82436ab95239c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 219/440] s4:rpc_server: require access to the machine account credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even a standalone server should be selfjoined. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 31f07d05629bc05ef99edc86ad2a3e95ec8599f1) --- source4/rpc_server/dcesrv_auth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 374c2e0..52fe26f 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -39,7 +39,7 @@ */ bool dcesrv_auth_bind(struct dcesrv_call_state *call) { - struct cli_credentials *server_credentials; + struct cli_credentials *server_credentials = NULL; struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = &dce_conn->auth_state; @@ -69,9 +69,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) cli_credentials_set_conf(server_credentials, call->conn->dce_ctx->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, call->conn->dce_ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); - talloc_free(server_credentials); - server_credentials = NULL; + DEBUG(1, ("Failed to obtain server credentials: %s\n", + nt_errstr(status))); + return false; } status = samba_server_gensec_start(dce_conn, call->event_ctx, -- 1.9.1 From 706a5951012e7a866a860e406f872b385e8f7424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 02:18:44 +0200 Subject: [PATCH 220/440] s4-smb_server: check for return code of cli_credentials_set_machine_account(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We keep anonymous server_credentials structure in order to let the rpc.spoolss.notify start it's test server. Pair-Programmed-With: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Signed-off-by: Stefan Metzmacher (cherry picked from commit fe93a09889a854d7c93f9b349d5794bdbb9403ba) --- source4/smb_server/smb/negprot.c | 6 ++++-- source4/smb_server/smb2/negprot.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index cdfa2b4..dfcc1a2 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -387,8 +387,10 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); - talloc_free(server_credentials); - server_credentials = NULL; + /* + * We keep the server_credentials as anonymous + * this is required for the spoolss.notify test + */ } nt_status = samba_server_gensec_start(req, diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index b48b170..e654392 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -49,8 +49,10 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); - talloc_free(server_credentials); - server_credentials = NULL; + /* + * We keep the server_credentials as anonymous + * this is required for the spoolss.notify test + */ } req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials); -- 1.9.1 From 21baf2e96e363c30c6d302149025338b465b1021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 02:20:50 +0200 Subject: [PATCH 221/440] s3-auth: check for return code of cli_credentials_set_machine_account(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Mar 17 20:43:19 CET 2016 on sn-devel-144 (cherry picked from commit c06058a99be4cf3ad3431dc263d4595ffc226fcf) --- source3/auth/auth_samba4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c index 0a80d17..4f37fea 100644 --- a/source3/auth/auth_samba4.c +++ b/source3/auth/auth_samba4.c @@ -245,8 +245,8 @@ static NTSTATUS prepare_gensec(const struct auth_context *auth_context, status = cli_credentials_set_machine_account(server_credentials, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); - talloc_free(server_credentials); - server_credentials = NULL; + TALLOC_FREE(frame); + return status; } status = samba_server_gensec_start(mem_ctx, -- 1.9.1 From 309065414572d92e5c1af44b16a417a88ca1d514 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 21:00:30 +0100 Subject: [PATCH 222/440] libsmb: Fix CID 1356312 Explicit null dereferenced BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit f50c3fb1c58700522f1b742539dab9bd9ae7fd39) --- source3/libsmb/cliconnect.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c116d73..a406ceb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1379,6 +1379,11 @@ static struct tevent_req *cli_session_setup_gensec_send( size_t converted; bool ok; + if (pass == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + converted = strhex_to_str((char *)nt_hash.hash, sizeof(nt_hash.hash), pass, strlen(pass)); -- 1.9.1 From 4c000896acaf9917c636ee0ea5290d09d2dad4e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 20:34:27 +0100 Subject: [PATCH 223/440] libads: Fix CID 1356316 Uninitialized pointer read BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit dcaa88158e6f0a9964ad051b4062d82e9f279b8c) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e707228..e205e9f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -646,7 +646,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { TALLOC_CTX *frame = talloc_stackframe(); - struct ads_service_principal p; + struct ads_service_principal p = {0}; struct berval *scred=NULL; int rc, i; ADS_STATUS status; -- 1.9.1 From 5f569dd4f5e99983ada208024eef91c78ad22d3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 15:30:00 +0100 Subject: [PATCH 224/440] s4:selftest: run rpc.netlogon.admin also over ncalrpc and ncacn_ip_tcp BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Mar 18 12:39:51 CET 2016 on sn-devel-144 (cherry picked from commit e8e2386bf6bd05c60a0f897587a9a676c86dee76) --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c1d2b79..8ccbaee 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -86,9 +86,9 @@ else: # add tests to this list as they start passing, so we test # that they stay passing ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] -ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] +ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") -ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests +ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] -- 1.9.1 From 2aa6aae1633f41ef31f47f3c23f378fd8bb5dab4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 23:32:50 +0100 Subject: [PATCH 225/440] s3:rpc_server/samr: correctly handle session_extract_session_key() failures BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 0906d61bb2f3446483d82928b55f5b797bac4804) --- source3/rpc_server/samr/srv_samr_nt.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c index 76703d1..32640f9 100644 --- a/source3/rpc_server/samr/srv_samr_nt.c +++ b/source3/rpc_server/samr/srv_samr_nt.c @@ -5097,7 +5097,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 18: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { - return status; + break; } /* Used by AS/U JRA. */ status = set_user_info_18(&info->info18, @@ -5114,7 +5114,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 21: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { - return status; + break; } status = set_user_info_21(&info->info21, p->mem_ctx, @@ -5124,6 +5124,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 23: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } arcfour_crypt_blob(info->info23.password.data, 516, &session_key); @@ -5137,6 +5140,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 24: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } arcfour_crypt_blob(info->info24.password.data, 516, &session_key); @@ -5150,6 +5156,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 25: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } encode_or_decode_arc4_passwd_buffer( info->info25.password.data, &session_key); @@ -5163,6 +5172,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 26: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } encode_or_decode_arc4_passwd_buffer( info->info26.password.data, &session_key); -- 1.9.1 From 7123d84de72cc4be65b7a41712988b16cff8c427 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 19:41:53 +0100 Subject: [PATCH 226/440] s3:ntlm_auth: pass manage_squid_request() needs a valid struct ntlm_auth_state from within get_password() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Mar 22 19:20:38 CET 2016 on sn-devel-144 (cherry picked from commit ef1ad0e122659b5ff9097f0f7046f10fc2f3ec30) --- source3/utils/ntlm_auth.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index d37aeb5..d01c522 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -227,13 +227,25 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod static const char *get_password(struct cli_credentials *credentials) { + TALLOC_CTX *frame = talloc_stackframe(); char *password = NULL; + struct ntlm_auth_state *state; + + state = talloc_zero(frame, struct ntlm_auth_state); + if (state == NULL) { + DEBUG(0, ("squid_stream: Failed to talloc ntlm_auth_state\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state->mem_ctx = state; /* Ask for a password */ x_fprintf(x_stdout, "PW\n"); - manage_squid_request(NUM_HELPER_MODES /* bogus */, NULL, NULL, manage_gensec_get_pw_request, (void **)&password); + manage_squid_request(NUM_HELPER_MODES /* bogus */, NULL, state, manage_gensec_get_pw_request, (void **)&password); talloc_steal(credentials, password); + TALLOC_FREE(frame); return password; } -- 1.9.1 From f20acd0c344c947271ebb811668ac661be33d42a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 23:07:12 +0100 Subject: [PATCH 227/440] CVE-2016-2110(<=4.2): s4:winbind: implement the WBFLAG_BIG_NTLMV2_BLOB flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NTLMv2 blobs can become large... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/winbind/wb_samba3_cmd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c index 9ec3c4b..2e6a260 100644 --- a/source4/winbind/wb_samba3_cmd.c +++ b/source4/winbind/wb_samba3_cmd.c @@ -643,8 +643,13 @@ NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) chal.data = s3call->request->data.auth_crap.chal; chal.length = sizeof(s3call->request->data.auth_crap.chal); - nt_resp.data = (uint8_t *)s3call->request->data.auth_crap.nt_resp; - nt_resp.length = s3call->request->data.auth_crap.nt_resp_len; + if (s3call->request->flags & WBFLAG_BIG_NTLMV2_BLOB) { + nt_resp.data = (uint8_t *)s3call->request->extra_data.data; + nt_resp.length = s3call->request->extra_len; + } else { + nt_resp.data = (uint8_t *)s3call->request->data.auth_crap.nt_resp; + nt_resp.length = s3call->request->data.auth_crap.nt_resp_len; + } lm_resp.data = (uint8_t *)s3call->request->data.auth_crap.lm_resp; lm_resp.length = s3call->request->data.auth_crap.lm_resp_len; -- 1.9.1 From 559f3fa751551d2954db24575277fee886a3678e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 08:46:45 +0100 Subject: [PATCH 228/440] CVE-2016-2110: auth/ntlmssp: let ntlmssp_handle_neg_flags() return NTSTATUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In future we can do a more fine granted negotiation and assert specific security features. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 6 +++++- auth/ntlmssp/ntlmssp_private.h | 4 ++-- auth/ntlmssp/ntlmssp_server.c | 15 ++++++++++++--- auth/ntlmssp/ntlmssp_util.c | 26 ++++++++++++++------------ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index fe9e5d4..bf3b8c0 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -247,7 +247,11 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); + nt_status = ntlmssp_handle_neg_flags(ntlmssp_state, + chal_flags, "challenge"); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index 29eca35..e938e5c 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -59,8 +59,8 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, /* The following definitions come from auth/ntlmssp_util.c */ void debug_ntlmssp_flags(uint32_t neg_flags); -void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, bool allow_lm); +NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32_t neg_flags, const char *name); const DATA_BLOB ntlmssp_version_blob(void); /* The following definitions come from auth/ntlmssp_server.c */ diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 4bb2a64..513d4a6 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -117,7 +117,10 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security } } - ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); + status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate"); + if (!NT_STATUS_IS_OK(status)){ + return status; + } /* Ask our caller what challenge they would like in the packet */ if (auth_context->get_ntlm_challenge) { @@ -331,8 +334,14 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, talloc_steal(state, state->encrypted_session_key.data); - if (auth_flags) - ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key); + if (auth_flags != 0) { + nt_status = ntlmssp_handle_neg_flags(ntlmssp_state, + auth_flags, + "authenticate"); + if (!NT_STATUS_IS_OK(nt_status)){ + return nt_status; + } + } if (DEBUGLEVEL >= 10) { struct AUTHENTICATE_MESSAGE *authenticate = talloc( diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index bfe27f9..8f11df1 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -70,10 +70,10 @@ void debug_ntlmssp_flags(uint32_t neg_flags) debug_ntlmssp_flags_raw(4, neg_flags); } -void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, bool allow_lm) +NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32_t flags, const char *name) { - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + if (flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; ntlmssp_state->unicode = true; @@ -83,7 +83,7 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = false; } - if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { + if ((flags & NTLMSSP_NEGOTIATE_LM_KEY) && ntlmssp_state->allow_lm_key) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ntlmssp_state->use_ntlmv2 = false; @@ -91,37 +91,39 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { + if (!(flags & NTLMSSP_NEGOTIATE_128)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { + if (!(flags & NTLMSSP_NEGOTIATE_56)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; } - if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { + if ((flags & NTLMSSP_REQUEST_TARGET)) { ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } + + return NT_STATUS_OK; } /* Does this blob looks like it could be NTLMSSP? */ -- 1.9.1 From a25cb9f097fb63a9d4fe1a055de50adb7c72b1e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 229/440] CVE-2016-2110: auth/ntlmssp: maintain conf_flags and required_flags variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now give an error when required flags are missing. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 3 +++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_client.c | 6 ++++++ auth/ntlmssp/ntlmssp_util.c | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 997738a..02ad33f 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -224,6 +224,9 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + return NT_STATUS_OK; } diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index c63c23d..31062e5 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -92,6 +92,8 @@ struct ntlmssp_state DATA_BLOB nt_resp; DATA_BLOB session_key; + uint32_t conf_flags; + uint32_t required_flags; uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ bool force_wrap_seal; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index bf3b8c0..c8b7c43 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -168,6 +168,9 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + if (DEBUGLEVEL >= 10) { struct NEGOTIATE_MESSAGE *negotiate = talloc( ntlmssp_state, struct NEGOTIATE_MESSAGE); @@ -669,6 +672,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_ccache = true; } + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + return NT_STATUS_OK; } diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 8f11df1..262bf61 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -73,6 +73,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags) NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, uint32_t flags, const char *name) { + uint32_t missing_flags = ntlmssp_state->required_flags; + if (flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; @@ -123,6 +125,24 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } + missing_flags &= ~ntlmssp_state->neg_flags; + if (missing_flags != 0) { + HRESULT hres = HRES_SEC_E_UNSUPPORTED_FUNCTION; + NTSTATUS status = NT_STATUS(HRES_ERROR_V(hres)); + DEBUG(1, ("%s: Got %s flags[0x%08x] " + "- possible downgrade detected! " + "missing_flags[0x%08x] - %s\n", + __func__, name, + (unsigned)flags, + (unsigned)missing_flags, + nt_errstr(status))); + debug_ntlmssp_flags_raw(1, missing_flags); + DEBUGADD(4, ("neg_flags[0x%08x]\n", + (unsigned)ntlmssp_state->neg_flags)); + debug_ntlmssp_flags_raw(4, ntlmssp_state->neg_flags); + return status; + } + return NT_STATUS_OK; } -- 1.9.1 From c21e5f1b04fc3608fd58903d97bd5658b2f1bdf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:58:19 +0100 Subject: [PATCH 230/440] CVE-2016-2110: auth/ntlmssp: split allow_lm_response from allow_lm_key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 5 ++++- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 8 +++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 02ad33f..7c378d6 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -117,7 +117,10 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; - if (lpcfg_lanman_auth(gensec_security->settings->lp_ctx) && + ntlmssp_state->allow_lm_response = + lpcfg_lanman_auth(gensec_security->settings->lp_ctx); + + if (ntlmssp_state->allow_lm_response && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false)) { diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 31062e5..8c254f3 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -64,6 +64,7 @@ struct ntlmssp_state bool use_ccache; bool resume_ccache; bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ + bool allow_lm_response;/* The LM_RESPONSE code is not very secure... */ bool allow_lm_key; /* The LM_KEY code is not very secure... */ const char *user; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index c8b7c43..8a7d58f 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -447,7 +447,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, if (ntlmssp_state->use_nt_response) { flags |= CLI_CRED_NTLM_AUTH; } - if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) { + if (ntlmssp_state->allow_lm_response) { flags |= CLI_CRED_LANMAN_AUTH; } @@ -474,7 +474,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { + && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) { DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); if (lm_response.length == 24) { SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, @@ -582,7 +582,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); - ntlmssp_state->allow_lm_key = (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) + ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx); + + ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false) || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false))); -- 1.9.1 From 5d2c976460328d3b4f8766ffce44e6ddec40a698 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:01:09 +0100 Subject: [PATCH 231/440] CVE-2016-2110: auth/ntlmssp: don't allow a downgrade from NTLMv2 to LM_AUTH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit man smb.conf says "client ntlmv2 auth = yes" the default disables, "client lanman auth = yes": ... Likewise, if the client ntlmv2 auth parameter is enabled, then only NTLMv2 logins will be attempted. ... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 8a7d58f..839d059 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -632,6 +632,8 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) if (ntlmssp_state->use_ntlmv2) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->allow_lm_response = false; + ntlmssp_state->allow_lm_key = false; } if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { -- 1.9.1 From fdb05e044c242603cb021e0e239a9b65dfc1cb79 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:06:09 +0100 Subject: [PATCH 232/440] CVE-2016-2110: auth/ntlmssp: don't let ntlmssp_handle_neg_flags() change ntlmssp_state->use_ntlmv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ntlmssp_handle_neg_flags() can only disable flags, but not set them. All supported flags are set at start time. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 4 ++++ auth/ntlmssp/ntlmssp_client.c | 4 ++++ auth/ntlmssp/ntlmssp_util.c | 22 +++++++++++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 7c378d6..e1aaa81 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -150,6 +150,10 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } + if (ntlmssp_state->allow_lm_key) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; } diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 839d059..096d48d 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -636,6 +636,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->allow_lm_key = false; } + if (ntlmssp_state->allow_lm_key) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* * We need to set this to allow a later SetPassword diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 262bf61..4ae6101 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -85,20 +85,24 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = false; } - if ((flags & NTLMSSP_NEGOTIATE_LM_KEY) && ntlmssp_state->allow_lm_key) { - /* other end forcing us to use LM */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->use_ntlmv2 = false; - } else { + /* + * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) + * has priority over NTLMSSP_NEGOTIATE_LM_KEY + */ + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } if (!(flags & NTLMSSP_NEGOTIATE_128)) { -- 1.9.1 From da5b41c3c7346c42867c64111a6d91b91244838e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 233/440] CVE-2016-2110: auth/ntlmssp: let gensec_ntlmssp_client_start require flags depending on the requested features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 096d48d..1b7f87a 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -115,6 +115,8 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, * This is compat code for older callers * which were missing the "initial_blob" */ + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->required_flags = 0; ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -158,14 +160,14 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { gensec_security->want_features |= GENSEC_FEATURE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; } if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { gensec_security->want_features |= GENSEC_FEATURE_SEAL; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; @@ -650,10 +652,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * that it thinks is only used for NTLMSSP signing and * sealing. (It is actually pulled out and used directly) */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { /* @@ -669,12 +671,12 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * in a few years. As all servers should have * GENSEC_FEATURE_LDAP_STYLE by then. */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) { ntlmssp_state->use_ccache = true; -- 1.9.1 From 819886bf97a2cf59b59414cf5dbac556656aa309 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 234/440] CVE-2016-2110: auth/ntlmssp: let gensec_ntlmssp_client_start require NTLM2 (EXTENDED_SESSIONSECURITY) when using ntlmv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 1b7f87a..49933cb 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -633,7 +633,7 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) } if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2; ntlmssp_state->allow_lm_response = false; ntlmssp_state->allow_lm_key = false; } -- 1.9.1 From d17b9c67876a90e92620bee7305f629712616d94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 14:06:18 +0100 Subject: [PATCH 235/440] CVE-2016-2110: winbindd: add new_spnego to the WINBINDD_CCACHE_NTLMAUTH response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need to change the protocol version because: 1. An old client may provide the "initial_blob" (which was and is still ignored when going via the wbcCredentialCache() function) and the new winbindd won't use new_spnego. 2. A new client will just get a zero byte from an old winbindd. As it uses talloc_zero() to create struct winbindd_response. 3. Changing the version number would introduce problems with backports to older Samba versions. New clients which are capable of using the new_spnego field will use "negotiate_blob" instead of "initial_blob". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- nsswitch/libwbclient/wbc_pam.c | 21 ++++++++++++++++++++- nsswitch/winbind_struct_protocol.h | 1 + source3/winbindd/winbindd_ccache_access.c | 8 ++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 390d73e..4ae2de1 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -1290,7 +1290,17 @@ wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, } for (i=0; inum_blobs; i++) { - if (strcasecmp(params->blobs[i].name, "initial_blob") == 0) { + /* + * Older callers may used to provide the NEGOTIATE request + * as "initial_blob", but it was completely ignored by winbindd. + * + * So we keep ignoring it. + * + * A new callers that is capable to support "new_spnego", + * will provide the NEGOTIATE request as "negotiate_blob" + * instead. + */ + if (strcasecmp(params->blobs[i].name, "negotiate_blob") == 0) { if (initial_blob != NULL) { status = WBC_ERR_INVALID_PARAM; goto fail; @@ -1388,6 +1398,15 @@ wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, if (!WBC_ERROR_IS_OK(status)) { goto fail; } + if (response.data.ccache_ntlm_auth.new_spnego) { + status = wbcAddNamedBlob( + &result->num_blobs, &result->blobs, "new_spnego", 0, + &response.data.ccache_ntlm_auth.new_spnego, + sizeof(response.data.ccache_ntlm_auth.new_spnego)); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + } *info = result; result = NULL; diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 0dffa4b..245162d 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -486,6 +486,7 @@ struct winbindd_response { struct { uint8_t session_key[16]; uint32_t auth_blob_len; /* blob in extra_data */ + uint8_t new_spnego; } ccache_ntlm_auth; struct { fstring dc_unc; diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 838711e..9bcbf0b 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -50,7 +50,8 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, const DATA_BLOB challenge_msg, TALLOC_CTX *mem_ctx, DATA_BLOB *auth_msg, - uint8_t session_key[16]) + uint8_t session_key[16], + uint8_t *new_spnego) { NTSTATUS status; struct auth_generic_state *auth_generic_state = NULL; @@ -144,6 +145,8 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, memcpy(session_key, session_key_blob.data, 16); data_blob_free(&session_key_blob); *auth_msg = reply; + *new_spnego = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_NEW_SPNEGO); status = NT_STATUS_OK; done: @@ -272,7 +275,8 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) result = do_ntlm_auth_with_stored_pw( name_user, name_domain, entry->pass, initial, challenge, talloc_tos(), &auth, - state->response->data.ccache_ntlm_auth.session_key); + state->response->data.ccache_ntlm_auth.session_key, + &state->response->data.ccache_ntlm_auth.new_spnego); if (!NT_STATUS_IS_OK(result)) { goto process_result; -- 1.9.1 From f687f268a357e69a0e1e7ee201caef7e186804be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:06 +0100 Subject: [PATCH 236/440] CVE-2016-2110: libcli/auth: use enum spnego_negResult instead of uint8_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/spnego.h | 2 +- libcli/auth/spnego_parse.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libcli/auth/spnego.h b/libcli/auth/spnego.h index 539b903..73196e6 100644 --- a/libcli/auth/spnego.h +++ b/libcli/auth/spnego.h @@ -58,7 +58,7 @@ struct spnego_negTokenInit { }; struct spnego_negTokenTarg { - uint8_t negResult; + enum spnego_negResult negResult; const char *supportedMech; DATA_BLOB responseToken; DATA_BLOB mechListMIC; diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index 1b294df..1230376 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -203,7 +203,9 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, while (!asn1_has_error(asn1) && 0 < asn1_tag_remaining(asn1)) { uint8_t context; + uint8_t neg_result; char *oid; + if (!asn1_peek_uint8(asn1, &context)) { asn1_set_error(asn1); break; @@ -213,7 +215,8 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, case ASN1_CONTEXT(0): if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false; if (!asn1_start_tag(asn1, ASN1_ENUMERATED)) return false; - if (!asn1_read_uint8(asn1, &token->negResult)) return false; + if (!asn1_read_uint8(asn1, &neg_result)) return false; + token->negResult = neg_result; if (!asn1_end_tag(asn1)) return false; if (!asn1_end_tag(asn1)) return false; break; -- 1.9.1 From af2bbf1d1a65ceb1ac0a7467791c9edbea7b850c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:35 +0100 Subject: [PATCH 237/440] CVE-2016-2110: libcli/auth: add SPNEGO_REQUEST_MIC to enum spnego_negResult MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is defined in http://www.ietf.org/rfc/rfc4178.txt. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/spnego.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libcli/auth/spnego.h b/libcli/auth/spnego.h index 73196e6..49645e0 100644 --- a/libcli/auth/spnego.h +++ b/libcli/auth/spnego.h @@ -45,7 +45,11 @@ enum spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, SPNEGO_REJECT = 2, - SPNEGO_NONE_RESULT = 3 + SPNEGO_REQUEST_MIC = 3, + /* + * The max value is 0xff (255) on the wire + */ + SPNEGO_NONE_RESULT = 256 }; struct spnego_negTokenInit { -- 1.9.1 From a5ab9b00f65fda44286662e66b1fded4fbd490f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 238/440] CVE-2016-2110: auth/gensec: fix the client side of a new_spnego exchange MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even for SMB where the server provides its mech list, the client needs to remember its own mech list for the mechListMIC calculation. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 74ed234..af5231a 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -784,6 +784,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA const char *my_mechs[] = {NULL, NULL}; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; + bool ok; if (!in.length) { /* client to produce negTokenInit */ @@ -846,6 +847,14 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + ok = spnego_write_mech_types(spnego_state, + my_mechs, + &spnego_state->mech_types); + if (!ok) { + DEBUG(1, ("SPNEGO: Failed to write mechTypes\n")); + return NT_STATUS_NO_MEMORY; + } + /* set next state */ spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; -- 1.9.1 From ae101622fc40844dd4034d78e51ddfc7acb770e4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 239/440] CVE-2016-2110: auth/gensec: fix the client side of a spnego downgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New servers response with SPNEGO_REQUEST_MIC instead of SPNEGO_ACCEPT_INCOMPLETE to a downgrade. With just KRB5 and NTLMSSP this doesn't happen, but we want to be prepared for the future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index af5231a..3fcd057 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -970,13 +970,15 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } /* Server didn't like our choice of mech, and chose something else */ - if ((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) && + if (((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) || + (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC)) && spnego.negTokenTarg.supportedMech && strcmp(spnego.negTokenTarg.supportedMech, spnego_state->neg_oid) != 0) { DEBUG(3,("GENSEC SPNEGO: client preferred mech (%s) not accepted, server wants: %s\n", - gensec_get_name_by_oid(gensec_security, spnego.negTokenTarg.supportedMech), - gensec_get_name_by_oid(gensec_security, spnego_state->neg_oid))); + gensec_get_name_by_oid(gensec_security, spnego_state->neg_oid), + gensec_get_name_by_oid(gensec_security, spnego.negTokenTarg.supportedMech))); + spnego_state->no_response_expected = false; talloc_free(spnego_state->sub_sec_security); nt_status = gensec_subcontext_start(spnego_state, gensec_security, -- 1.9.1 From 461344d1258a82e8d0f80f0a0a6f3107a5b2c21a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 20:13:24 +0100 Subject: [PATCH 240/440] CVE-2016-2110: auth/gensec: require spnego mechListMIC exchange for new_spnego backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This used to work more or less before, but only for krb5 with the server finishing first. With NTLMSSP and new_spnego the client will finish first. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 262 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 208 insertions(+), 54 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 3fcd057..7978f7b 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -53,6 +53,11 @@ struct spnego_state { const char *neg_oid; DATA_BLOB mech_types; + size_t num_targs; + bool mic_requested; + bool needs_mic_sign; + bool needs_mic_check; + bool done_mic_check; /* * The following is used to implement @@ -416,6 +421,11 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ spnego_state->neg_oid = all_sec[i].oid; *unwrapped_out = data_blob_null; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + /* + * Indicate the downgrade and request a + * mic. + */ + spnego_state->mic_requested = true; break; } @@ -674,22 +684,27 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct spnego_state *spnego_st /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; + spnego_out.negTokenTarg.mechListMIC = mech_list_mic; spnego_out.negTokenTarg.supportedMech = NULL; if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + if (spnego_state->mic_requested) { + spnego_out.negTokenTarg.negResult = SPNEGO_REQUEST_MIC; + spnego_state->mic_requested = false; + } else { + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + } spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { if (unwrapped_out.data) { spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid; } spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; - spnego_out.negTokenTarg.mechListMIC = mech_list_mic; spnego_state->state_position = SPNEGO_DONE; } else { spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); spnego_state->state_position = SPNEGO_DONE; } @@ -700,6 +715,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct spnego_state *spnego_st } spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->num_targs++; return nt_status; } @@ -892,18 +908,57 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; + if (!spnego_state->sub_sec_security) { DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } + if (spnego_state->needs_mic_check) { + if (spnego.negTokenTarg.responseToken.length != 0) { + DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); + spnego_free_data(&spnego); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + } else { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + } + goto server_response; + } + nt_status = gensec_update_ev(spnego_state->sub_sec_security, - out_mem_ctx, ev, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - if (NT_STATUS_IS_OK(nt_status) && spnego.negTokenTarg.mechListMIC.length > 0) { + out_mem_ctx, ev, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + if (!NT_STATUS_IS_OK(nt_status)) { + goto server_response; + } + + new_spnego = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_NEW_SPNEGO); + if (spnego.negTokenTarg.mechListMIC.length > 0) { new_spnego = true; + } + + if (new_spnego) { + spnego_state->needs_mic_check = true; + spnego_state->needs_mic_sign = true; + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { nt_status = gensec_check_packet(spnego_state->sub_sec_security, spnego_state->mech_types.data, spnego_state->mech_types.length, @@ -913,9 +968,14 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", nt_errstr(nt_status))); + goto server_response; } + + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; } - if (NT_STATUS_IS_OK(nt_status) && new_spnego) { + + if (spnego_state->needs_mic_sign) { nt_status = gensec_sign_packet(spnego_state->sub_sec_security, out_mem_ctx, spnego_state->mech_types.data, @@ -926,9 +986,16 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", nt_errstr(nt_status))); + goto server_response; } + spnego_state->needs_mic_sign = false; } + if (spnego_state->needs_mic_check) { + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + server_response: nt_status = gensec_spnego_server_negTokenTarg(spnego_state, out_mem_ctx, nt_status, @@ -942,7 +1009,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } case SPNEGO_CLIENT_TARG: { - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; + if (!in.length) { return NT_STATUS_INVALID_PARAMETER; } @@ -964,11 +1032,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { spnego_free_data(&spnego); return NT_STATUS_LOGON_FAILURE; } + if (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC) { + spnego_state->mic_requested = true; + } + /* Server didn't like our choice of mech, and chose something else */ if (((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) || (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC)) && @@ -995,64 +1069,143 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } - nt_status = gensec_update_ev(spnego_state->sub_sec_security, - out_mem_ctx, ev, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - spnego_state->neg_oid = talloc_strdup(spnego_state, spnego.negTokenTarg.supportedMech); - } else if (spnego_state->no_response_expected) { - if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - DEBUG(3,("GENSEC SPNEGO: client GENSEC accepted, but server rejected (bad password?)\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else if (spnego.negTokenTarg.responseToken.length) { - DEBUG(2,("GENSEC SPNEGO: client GENSEC accepted, but server continued negotiation!\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else { - nt_status = NT_STATUS_OK; + spnego_state->neg_oid = talloc_strdup(spnego_state, + spnego.negTokenTarg.supportedMech); + if (spnego_state->neg_oid == NULL) { + spnego_free_data(&spnego); + return NT_STATUS_NO_MEMORY; + }; + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { + if (spnego_state->no_response_expected) { + spnego_state->needs_mic_check = true; } - if (NT_STATUS_IS_OK(nt_status) && spnego.negTokenTarg.mechListMIC.length > 0) { - nt_status = gensec_check_packet(spnego_state->sub_sec_security, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - &spnego.negTokenTarg.mechListMIC); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", - nt_errstr(nt_status))); - } + } + + if (spnego_state->needs_mic_check) { + if (spnego.negTokenTarg.responseToken.length != 0) { + DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); + spnego_free_data(&spnego); + return NT_STATUS_INVALID_PARAMETER; } - } else { - bool new_spnego = false; + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; + } + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + goto client_response; + } + + if (!spnego_state->no_response_expected) { nt_status = gensec_update_ev(spnego_state->sub_sec_security, out_mem_ctx, ev, spnego.negTokenTarg.responseToken, &unwrapped_out); + if (!NT_STATUS_IS_OK(nt_status)) { + goto client_response; + } + + spnego_state->no_response_expected = true; + } else { + nt_status = NT_STATUS_OK; + } + + if (spnego_state->no_response_expected && + !spnego_state->done_mic_check) + { + bool new_spnego = false; + + new_spnego = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_NEW_SPNEGO); + + switch (spnego.negTokenTarg.negResult) { + case SPNEGO_ACCEPT_COMPLETED: + case SPNEGO_NONE_RESULT: + if (spnego_state->num_targs == 1) { + /* + * the first exchange doesn't require + * verification + */ + new_spnego = false; + } + break; - if (NT_STATUS_IS_OK(nt_status) - && spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - new_spnego = gensec_have_feature(spnego_state->sub_sec_security, - GENSEC_FEATURE_NEW_SPNEGO); + case SPNEGO_ACCEPT_INCOMPLETE: + case SPNEGO_REQUEST_MIC: + if (spnego.negTokenTarg.mechListMIC.length > 0) { + new_spnego = true; + } + break; + default: + break; } - if (NT_STATUS_IS_OK(nt_status) && new_spnego) { - nt_status = gensec_sign_packet(spnego_state->sub_sec_security, - out_mem_ctx, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - &mech_list_mic); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", - nt_errstr(nt_status))); + + if (spnego_state->mic_requested) { + bool sign; + + sign = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_SIGN); + if (sign) { + new_spnego = true; } } - if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->no_response_expected = true; + + if (new_spnego) { + spnego_state->needs_mic_check = true; + spnego_state->needs_mic_sign = true; + } + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; + } + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + } + + if (spnego_state->needs_mic_sign) { + nt_status = gensec_sign_packet(spnego_state->sub_sec_security, + out_mem_ctx, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &mech_list_mic); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; } - } + spnego_state->needs_mic_sign = false; + } + + if (spnego_state->needs_mic_check) { + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } + client_response: spnego_free_data(&spnego); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) @@ -1076,6 +1229,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; spnego_state->state_position = SPNEGO_CLIENT_TARG; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; } else { -- 1.9.1 From 723996cc1fb1e83b6d7cd74d849acc9b7d452544 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 241/440] CVE-2016-2110: auth/gensec: add gensec_may_reset_crypto() infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [MS-SPNG] requires the NTLMSSP RC4 states to be reset after the SPNEGO exchange with mechListMic verification (new_spnego). This provides the infrastructure for this feature. The 'reset_full' parameter is needed to support the broken behavior that windows only resets the RC4 states but not the sequence numbers. Which means this functionality is completely useless... But we want to work against all windows versions... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/gensec.c | 10 ++++++++++ auth/gensec/gensec_internal.h | 5 +++++ auth/gensec/spnego.c | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 548091a..4d0968b 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -30,6 +30,16 @@ #include "auth/gensec/gensec_internal.h" #include "librpc/gen_ndr/dcerpc.h" +_PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + if (!gensec_security->ops->may_reset_crypto) { + return NT_STATUS_OK; + } + + return gensec_security->ops->may_reset_crypto(gensec_security, full_reset); +} + /* wrappers for the gensec function pointers */ diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 2751196..5535241 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -47,6 +47,8 @@ struct gensec_security_ops { NTSTATUS (*update_recv)(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); + NTSTATUS (*may_reset_crypto)(struct gensec_security *gensec_security, + bool full_reset); NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, @@ -121,4 +123,7 @@ struct gensec_critical_sizes { int sizeof_gensec_security; }; +NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset); + #endif /* __GENSEC_H__ */ diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 7978f7b..1d4b172 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1426,7 +1426,14 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu data_blob_free(&spnego_state->in_frag); spnego_state->in_needed = 0; if (NT_STATUS_IS_OK(status)) { + bool reset_full = true; + gensec_security->child_security = spnego_state->sub_sec_security; + + reset_full = !spnego_state->done_mic_check; + + status = gensec_may_reset_crypto(spnego_state->sub_sec_security, + reset_full); } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { -- 1.9.1 From 7e460a391e3240df650413e7693341f00d4770ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Dec 2013 11:27:27 +0100 Subject: [PATCH 242/440] CVE-2016-2110: auth/ntlmssp: call ntlmssp_sign_init if we provide GENSEC_FEATURE_SIGN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's important to check if got the GENSEC_FEATURE_SIGN and if the caller wanted it. The caller may only asked for GENSEC_FEATURE_SESSION_KEY which implicitly negotiates NTLMSSP_NEGOTIATE_SIGN, which might indicate GENSEC_FEATURE_SIGN to the SPNEGO glue code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 +- auth/ntlmssp/ntlmssp_server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 49933cb..e91692b 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -538,7 +538,7 @@ done: ntlmssp_state->expected_state = NTLMSSP_DONE; - if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) { + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 513d4a6..7013df7 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -598,7 +598,7 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, talloc_steal(ntlmssp_state, session_key.data); } - if (ntlmssp_state->session_key.length) { + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); } -- 1.9.1 From 3e9f3942077885da216ae715707bedfb4f04378d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 243/440] CVE-2016-2110: auth/ntlmssp: implement gensec_ntlmssp_may_reset_crypto() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [MS-SPNG] requires the NTLMSSP RC4 states to be reset after the SPNEGO exchange with mechListMic verification (new_spnego). The 'reset_full' parameter is needed to support the broken behavior that windows only resets the RC4 states but not the sequence numbers. Which means this functionality is completely useless... But we want to work against all windows versions... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp.c | 25 +++++++++++++++++++++++++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_sign.c | 40 ++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 091fdab..4abab88 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -179,6 +179,30 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static NTSTATUS gensec_ntlmssp_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; + NTSTATUS status; + bool reset_seqnums = full_reset; + + if (!gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_OK; + } + + status = ntlmssp_sign_reset(ntlmssp_state, reset_seqnums); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not reset NTLMSSP signing/sealing system (error was: %s)\n", + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} + static const char *gensec_ntlmssp_oids[] = { GENSEC_OID_NTLMSSP, NULL @@ -193,6 +217,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .server_start = gensec_ntlmssp_server_start, .magic = gensec_ntlmssp_magic, .update = gensec_ntlmssp_update, + .may_reset_crypto= gensec_ntlmssp_may_reset_crypto, .sig_size = gensec_ntlmssp_sig_size, .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 8c254f3..bb8807d 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -130,6 +130,8 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_stae, TALLOC_CTX *out_mem_ctx, const DATA_BLOB *in, DATA_BLOB *out); +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums); NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state); bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob); diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index 2f8c6de..a975725 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -503,20 +503,14 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums) { DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (ntlmssp_state->session_key.length < 8) { - DEBUG(3, ("NO session key, cannot intialise signing\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - ntlmssp_state->crypt = talloc_zero(ntlmssp_state, - union ntlmssp_crypt_state); if (ntlmssp_state->crypt == NULL) { - return NT_STATUS_NO_MEMORY; + return NT_STATUS_INVALID_PARAMETER_MIX; } if (ntlmssp_state->force_wrap_seal && @@ -606,7 +600,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.sending.seal_state); /* SEND: seq num */ - ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + } /* RECV: sign key */ calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.receiving.sign_key, @@ -626,7 +622,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.receiving.seal_state); /* RECV: seq num */ - ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + } } else { uint8_t weak_session_key[8]; DATA_BLOB seal_session_key = ntlmssp_state->session_key; @@ -676,8 +674,26 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) dump_arc4_state("NTLMv1 arc4 state:\n", &ntlmssp_state->crypt->ntlm.seal_state); - ntlmssp_state->crypt->ntlm.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm.seq_num = 0; + } } return NT_STATUS_OK; } + +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +{ + if (ntlmssp_state->session_key.length < 8) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + ntlmssp_state->crypt = talloc_zero(ntlmssp_state, + union ntlmssp_crypt_state); + if (ntlmssp_state->crypt == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return ntlmssp_sign_reset(ntlmssp_state, true); +} -- 1.9.1 From f7fbd9b8453d558f8d9fae29c8001f262199fba9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 21:24:47 +0100 Subject: [PATCH 244/440] CVE-2016-2110: auth/credentials: clear the LMv2 key for NTLMv2 in cli_credentials_get_ntlm_response() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we clear CLI_CRED_LANMAN_AUTH and we should also clear the lm_response buffer and don't send it over the net. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials_ntlm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index 8c6be39..cf152fc 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -110,6 +110,12 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred /* LM Key is incompatible... */ *flags &= ~CLI_CRED_LANMAN_AUTH; + if (lm_response.length != 0) { + /* + * We should not expose the lm key. + */ + memset(lm_response.data, 0, lm_response.length); + } } else if (*flags & CLI_CRED_NTLM2) { MD5_CTX md5_session_nonce_ctx; uint8_t session_nonce[16]; -- 1.9.1 From c3a621f67b4a66dac68b5a77cff8c31a53490178 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:29:11 +0100 Subject: [PATCH 245/440] CVE-2016-2110: auth/credentials: pass server_timestamp to cli_credentials_get_ntlm_response() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials.h | 4 +++- auth/credentials/credentials_ntlm.c | 4 +++- auth/ntlmssp/ntlmssp_client.c | 5 +++-- source4/libcli/smb_composite/sesssetup.c | 2 ++ source4/torture/rpc/netlogon.c | 1 + source4/torture/rpc/remote_pac.c | 1 + source4/torture/rpc/samba3rpc.c | 2 +- source4/torture/rpc/samr.c | 1 + source4/torture/rpc/schannel.c | 2 ++ 9 files changed, 17 insertions(+), 5 deletions(-) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 2da47d2..f56a121 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -80,7 +80,9 @@ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALL const char **domain); NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, int *flags, - DATA_BLOB challenge, DATA_BLOB target_info, + DATA_BLOB challenge, + const NTTIME *server_timestamp, + DATA_BLOB target_info, DATA_BLOB *_lm_response, DATA_BLOB *_nt_response, DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key); const char *cli_credentials_get_realm(struct cli_credentials *cred); diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index cf152fc..5928305 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -30,7 +30,9 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, int *flags, - DATA_BLOB challenge, DATA_BLOB target_info, + DATA_BLOB challenge, + const NTTIME *server_timestamp, + DATA_BLOB target_info, DATA_BLOB *_lm_response, DATA_BLOB *_nt_response, DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key) { diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index e91692b..af4d249 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -228,6 +228,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, const char *user = NULL, *domain = NULL, *workstation = NULL; bool is_anonymous = false; const DATA_BLOB version_blob = ntlmssp_version_blob(); + const NTTIME *server_timestamp = NULL; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -454,10 +455,10 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, - &flags, challenge_blob, target_info, + &flags, challenge_blob, + server_timestamp, target_info, &lm_response, &nt_response, &lm_session_key, &session_key); - if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index e4964c1..903055f 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -332,6 +332,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, + NULL, /* server_timestamp */ names_blob, &state->setup.nt1.in.password1, &state->setup.nt1.in.password2, @@ -426,6 +427,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, + NULL, /* server_timestamp */ names_blob, &state->setup.old.in.password, NULL, diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index c5c565f..66f09a2 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -881,6 +881,7 @@ static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index ffe79da..83fc839 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -735,6 +735,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = cli_credentials_get_ntlm_response(client_creds, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index dd4c45c..c211115 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1148,7 +1148,7 @@ static bool schan(struct torture_context *tctx, cli_credentials_get_workstation(user_creds), cli_credentials_get_domain(user_creds)); status = cli_credentials_get_ntlm_response( - user_creds, mem_ctx, &flags, chal, names_blob, + user_creds, mem_ctx, &flags, chal, NULL, names_blob, &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "cli_credentials_get_ntlm_response failed:" diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 0c786c1..dcdbb8a 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -3096,6 +3096,7 @@ static bool test_SamLogon(struct torture_context *tctx, status = cli_credentials_get_ntlm_response(test_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index e04f938..d5de134 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -87,6 +87,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); @@ -752,6 +753,7 @@ static bool torture_schannel_bench_start(struct torture_schannel_bench_conn *con status = cli_credentials_get_ntlm_response(user_creds, conn->tmp, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); -- 1.9.1 From 5264e238afb94c1b36296de43fd6e973d2b006b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:29:11 +0100 Subject: [PATCH 246/440] CVE-2016-2110(<=4.2): auth/credentials: pass server_timestamp to cli_credentials_get_ntlm_response() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the build in 4.2 and older versions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/winbind/wb_pam_auth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/winbind/wb_pam_auth.c b/source4/winbind/wb_pam_auth.c index c84b51f..bb9cf42 100644 --- a/source4/winbind/wb_pam_auth.c +++ b/source4/winbind/wb_pam_auth.c @@ -250,7 +250,9 @@ struct composite_context *wb_cmd_pam_auth_send(TALLOC_CTX *mem_ctx, cli_credentials_get_domain(credentials)); status = cli_credentials_get_ntlm_response( - credentials, mem_ctx, &flags, chal, names_blob, + credentials, mem_ctx, &flags, chal, + NULL, /* server_timestamp */ + names_blob, &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { return NULL; -- 1.9.1 From 7b39f6691e66100c888e7966d526eaab82dab849 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:31:35 +0100 Subject: [PATCH 247/440] CVE-2016-2110: libcli/auth: pass server_timestamp to SMBNTLMv2encrypt_hash() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials.h | 1 + auth/credentials/credentials_ntlm.c | 2 +- libcli/auth/proto.h | 1 + libcli/auth/smbencrypt.c | 36 +++++++++++++++++++++++++++--------- source4/auth/ntlm/auth_util.c | 4 +++- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index f56a121..6c5c2c8 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -22,6 +22,7 @@ #ifndef __CREDENTIALS_H__ #define __CREDENTIALS_H__ +#include "../lib/util/time.h" #include "../lib/util/data_blob.h" #include "librpc/gen_ndr/misc.h" diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index 5928305..c1d0c00 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -104,7 +104,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred user, domain, nt_hash->hash, &challenge, - &target_info, + server_timestamp, &target_info, &lm_response, &nt_response, NULL, &session_key)) { return NT_STATUS_NO_MEMORY; diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 0c319d3..e7689e2 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -144,6 +144,7 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, + const NTTIME *server_timestamp, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ; diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index ec819cd..6edcaa3 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -387,14 +387,13 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, return names_blob; } -static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) +static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, + NTTIME nttime, + const DATA_BLOB *names_blob) { uint8_t client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); uint8_t long_date[8]; - NTTIME nttime; - - unix_to_nt_time(&nttime, time(NULL)); generate_random_buffer(client_chal, sizeof(client_chal)); @@ -417,6 +416,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal, + NTTIME nttime, const DATA_BLOB *names_blob) { uint8_t ntlmv2_response[16]; @@ -433,7 +433,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, /* NTLMv2 */ /* generate some data to pass into the response function - including the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); + ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, nttime, names_blob); /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); @@ -479,6 +479,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, + const NTTIME *server_timestamp, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) @@ -494,8 +495,19 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, } if (nt_response) { + const NTTIME *nttime = server_timestamp; + NTTIME _now = 0; + + if (nttime == NULL) { + struct timeval tv_now = timeval_current(); + _now = timeval_to_nttime(&tv_now); + nttime = &_now; + } + *nt_response = NTLMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal, + ntlm_v2_hash, + server_chal, + *nttime, names_blob); if (user_session_key) { *user_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -509,8 +521,13 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, /* LMv2 */ if (lm_response) { - *lm_response = LMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal); + if (server_timestamp != NULL) { + *lm_response = data_blob_talloc_zero(mem_ctx, 24); + } else { + *lm_response = LMv2_generate_response(mem_ctx, + ntlm_v2_hash, + server_chal); + } if (lm_session_key) { *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -535,7 +552,8 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, E_md4hash(password, nt_hash); return SMBNTLMv2encrypt_hash(mem_ctx, - user, domain, nt_hash, server_chal, names_blob, + user, domain, nt_hash, + server_chal, NULL, names_blob, lm_response, nt_response, lm_session_key, user_session_key); } diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 16977fa..3e5a0da 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -350,7 +350,9 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte if (!SMBNTLMv2encrypt_hash(user_info_temp, user_info_in->client.account_name, user_info_in->client.domain_name, - user_info_in->password.hash.nt->hash, &chall_blob, + user_info_in->password.hash.nt->hash, + &chall_blob, + NULL, /* server_timestamp */ &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { -- 1.9.1 From 65c419570e22213c61a92386267c21683375d3b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 30 Nov 2015 09:13:14 +0100 Subject: [PATCH 248/440] CVE-2016-2110: ntlmssp.idl: add NTLMSSP_MIC_{OFFSET,SIZE} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/idl/ntlmssp.idl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 2151275..95b4f11 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -243,9 +243,12 @@ interface ntlmssp [default] NTLMv2_RESPONSE v2; } ntlmssp_NTLM_RESPONSE; + const int NTLMSSP_MIC_OFFSET = 72; + const int NTLMSSP_MIC_SIZE = 16; + typedef [flag(NDR_PAHEX)] struct { - uint8 MIC[16]; - } MIC; + uint8 MIC[NTLMSSP_MIC_SIZE]; + } ntlmssp_MIC; /* [MS-NLMP] 2.2.1.3 AUTHENTICATE_MESSAGE */ @@ -274,7 +277,7 @@ interface ntlmssp [switch_is(NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)] ntlmssp_Version Version; /* MIC (Message Integrity) is only included when the client has * sent a timestap Av struct in the CHALLENGE_MESSAGE AvPair */ - /* [flag(NDR_REMAINING)] MIC mic; */ + /* [flag(NDR_REMAINING)] ntlmssp_MIC mic; */ } AUTHENTICATE_MESSAGE; /* NTLMSSP signature version */ -- 1.9.1 From 49b79c5e5c08a8c71977bc0898ae43bd91ff99ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:02:58 +0100 Subject: [PATCH 249/440] CVE-2016-2110: auth/ntlmssp: implement new_spnego support including MIC checking (as server) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now include a MsvAvTimestamp in our target info as indication for the client to include a NTLMSSP_MIC in the AUTH_MESSAGE. If the client uses NTLMv2 we check NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE and require a valid MIC. This is still disabled if the "map to guest" feature is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp.c | 9 + auth/ntlmssp/gensec_ntlmssp_server.c | 23 ++- auth/ntlmssp/ntlmssp.h | 6 + auth/ntlmssp/ntlmssp_server.c | 341 ++++++++++++++++++++++++++++++++++- 4 files changed, 367 insertions(+), 12 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp.c b/auth/ntlmssp/gensec_ntlmssp.c index 5672589..329d8eb 100644 --- a/auth/ntlmssp/gensec_ntlmssp.c +++ b/auth/ntlmssp/gensec_ntlmssp.c @@ -105,6 +105,15 @@ bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { return true; } + if (feature & GENSEC_FEATURE_NEW_SPNEGO) { + if (!ntlmssp_state->session_key.length) { + return false; + } + if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + return false; + } + return ntlmssp_state->new_spnego; + } return false; } diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index e1aaa81..6147b14 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -34,7 +34,7 @@ #include "auth/gensec/gensec_internal.h" #include "auth/common_auth.h" #include "param/param.h" - +#include "param/loadparm.h" /** * Return the credentials of a logged on user, including session keys @@ -98,6 +98,9 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) const char *netbios_domain; const char *dns_name; const char *dns_domain; + enum server_role role; + + role = lpcfg_server_role(gensec_security->settings->lp_ctx); nt_status = gensec_ntlmssp_start(gensec_security); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -127,6 +130,22 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->allow_lm_key = true; } + if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST) { + /* + * map to guest is not secure anyway, so + * try to make it work and don't try to + * negotiate new_spnego and MIC checking + */ + ntlmssp_state->force_old_spnego = true; + } + + if (role == ROLE_ACTIVE_DIRECTORY_DC) { + /* + * map to guest is not supported on an AD DC. + */ + ntlmssp_state->force_old_spnego = false; + } + ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION; @@ -174,7 +193,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) { + if (role == ROLE_STANDALONE) { ntlmssp_state->server.is_standalone = true; } else { ntlmssp_state->server.is_standalone = false; diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index bb8807d..bc2a822 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -72,6 +72,11 @@ struct ntlmssp_state uint8_t *nt_hash; uint8_t *lm_hash; + DATA_BLOB negotiate_blob; + DATA_BLOB challenge_blob; + bool new_spnego; + bool force_old_spnego; + struct { const char *netbios_name; const char *netbios_domain; @@ -83,6 +88,7 @@ struct ntlmssp_state const char *netbios_domain; const char *dns_name; const char *dns_domain; + NTTIME challenge_endtime; struct AV_PAIR_LIST av_pair_list; } server; diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 7013df7..17d5ade 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "lib/util/time_basic.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/ntlmssp_private.h" #include "../librpc/gen_ndr/ndr_ntlmssp.h" @@ -84,6 +85,27 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security uint8_t cryptkey[8]; const char *target_name; NTSTATUS status; + struct timeval tv_now = timeval_current(); + /* + * See [MS-NLMP] + * + * Windows NT 4.0, windows_2000: use 30 minutes, + * Windows XP, Windows Server 2003, Windows Vista, + * Windows Server 2008, Windows 7, and Windows Server 2008 R2 + * use 36 hours. + * + * Newer systems doesn't check this, likely because the + * connectionless NTLMSSP is no longer supported. + * + * As we expect the AUTHENTICATION_MESSAGE to arrive + * directly after the NEGOTIATE_MESSAGE (typically less than + * as 1 second later). We use a hard timeout of 30 Minutes. + * + * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp + * instead we just remember our own time. + */ + uint32_t max_lifetime = 30 * 60; + struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0); /* parse the NTLMSSP packet */ #if 0 @@ -91,6 +113,12 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security #endif if (request.length) { + if (request.length > UINT16_MAX) { + DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n", + (unsigned int)request.length)); + return NT_STATUS_INVALID_PARAMETER; + } + if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", "NTLMSSP", &ntlmssp_command, @@ -141,6 +169,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security */ chal_flags = ntlmssp_state->neg_flags; + ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end); /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, @@ -158,7 +187,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security struct AV_PAIR *pairs = NULL; uint32_t count = 5; - pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count); + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1); if (pairs == NULL) { return NT_STATUS_NO_MEMORY; } @@ -175,7 +204,16 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security pairs[3].AvId = MsvAvDnsComputerName; pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; - pairs[4].AvId = MsvAvEOL; + if (!ntlmssp_state->force_old_spnego) { + pairs[4].AvId = MsvAvTimestamp; + pairs[4].Value.AvTimestamp = + timeval_to_nttime(&tv_now); + count += 1; + + pairs[5].AvId = MsvAvEOL; + } else { + pairs[4].AvId = MsvAvEOL; + } ntlmssp_state->server.av_pair_list.count = count; ntlmssp_state->server.av_pair_list.pair = pairs; @@ -235,6 +273,18 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security data_blob_free(&struct_blob); + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + request); + if (ntlmssp_state->negotiate_blob.length != request.length) { + return NT_STATUS_NO_MEMORY; + } + + ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state, + *reply); + if (ntlmssp_state->challenge_blob.length != reply->length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_AUTH; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -267,19 +317,24 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, struct auth4_context *auth_context = gensec_security->auth_context; uint32_t ntlmssp_command, auth_flags; NTSTATUS nt_status; - + const unsigned int version_len = 8; + DATA_BLOB version_blob = data_blob_null; + const unsigned int mic_len = NTLMSSP_MIC_SIZE; + DATA_BLOB mic_blob = data_blob_null; uint8_t session_nonce_hash[16]; - const char *parse_string; + bool ok; + struct timeval endtime; + bool expired = false; #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif if (ntlmssp_state->unicode) { - parse_string = "CdBBUUUBd"; + parse_string = "CdBBUUUBdbb"; } else { - parse_string = "CdBBAAABd"; + parse_string = "CdBBAAABdbb"; } /* zero these out */ @@ -292,7 +347,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, ntlmssp_state->client.netbios_name = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state, &request, parse_string, + ok = msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, @@ -301,7 +356,35 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, &ntlmssp_state->user, &ntlmssp_state->client.netbios_name, &state->encrypted_session_key, - &auth_flags)) { + &auth_flags, + &version_blob, version_len, + &mic_blob, mic_len); + if (!ok) { + DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); + dump_data(10, request.data, request.length); + + data_blob_free(&version_blob); + data_blob_free(&mic_blob); + + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUUBd"; + } else { + parse_string = "CdBBAAABd"; + } + + ok = msrpc_parse(ntlmssp_state, &request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->client.netbios_name, + &state->encrypted_session_key, + &auth_flags); + } + + if (!ok) { DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); dump_data(10, request.data, request.length); @@ -370,6 +453,194 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif + if (ntlmssp_state->nt_resp.length > 24) { + struct NTLMv2_RESPONSE v2_resp; + enum ndr_err_code err; + uint32_t i = 0; + uint32_t count = 0; + const struct AV_PAIR *flags = NULL; + const struct AV_PAIR *eol = NULL; + uint32_t av_flags = 0; + + err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp, + ntlmssp_state, + &v2_resp, + (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + nt_status = ndr_map_error2ntstatus(err); + DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for " + "user=[%s] domain=[%s] workstation=[%s] - %s %s\n", + __func__, ntlmssp_state->nt_resp.length, + ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name, + ndr_errstr(err), nt_errstr(nt_status))); + return nt_status; + } + + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp); + } + + eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvEOL); + if (eol == NULL) { + DEBUG(1,("%s: missing MsvAvEOL for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvFlags); + if (flags != NULL) { + av_flags = flags->Value.AvFlags; + } + + if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) { + if (mic_blob.length != NTLMSSP_MIC_SIZE) { + DEBUG(1,("%s: mic_blob.length[%u] for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + (unsigned)mic_blob.length, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + if (request.length < + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE)) + { + DEBUG(1,("%s: missing MIC " + "request.length[%u] for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + (unsigned)request.length, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + ntlmssp_state->new_spnego = true; + } + + count = ntlmssp_state->server.av_pair_list.count; + if (v2_resp.Challenge.AvPairs.count < count) { + return NT_STATUS_INVALID_PARAMETER; + } + + for (i = 0; i < count; i++) { + const struct AV_PAIR *sp = + &ntlmssp_state->server.av_pair_list.pair[i]; + const struct AV_PAIR *cp = NULL; + + if (sp->AvId == MsvAvEOL) { + continue; + } + + cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + sp->AvId); + if (cp == NULL) { + DEBUG(1,("%s: AvId 0x%x missing for" + "user=[%s] domain=[%s] " + "workstation=[%s]\n", + __func__, + (unsigned)sp->AvId, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + switch (cp->AvId) { +#define CASE_STRING(v) case Msv ## v: do { \ + int cmp; \ + if (sp->Value.v == NULL) { \ + return NT_STATUS_INTERNAL_ERROR; \ + } \ + if (cp->Value.v == NULL) { \ + DEBUG(1,("%s: invalid %s " \ + "got[%s] expect[%s] for " \ + "user=[%s] domain=[%s] workstation=[%s]\n", \ + __func__, #v, \ + cp->Value.v, \ + sp->Value.v, \ + ntlmssp_state->user, \ + ntlmssp_state->domain, \ + ntlmssp_state->client.netbios_name)); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ + cmp = strcmp(cp->Value.v, sp->Value.v); \ + if (cmp != 0) { \ + DEBUG(1,("%s: invalid %s " \ + "got[%s] expect[%s] for " \ + "user=[%s] domain=[%s] workstation=[%s]\n", \ + __func__, #v, \ + cp->Value.v, \ + sp->Value.v, \ + ntlmssp_state->user, \ + ntlmssp_state->domain, \ + ntlmssp_state->client.netbios_name)); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ +} while(0); break + CASE_STRING(AvNbComputerName); + CASE_STRING(AvNbDomainName); + CASE_STRING(AvDnsComputerName); + CASE_STRING(AvDnsDomainName); + CASE_STRING(AvDnsTreeName); + case MsvAvTimestamp: + if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) { + struct timeval ct; + struct timeval st; + struct timeval_buf tmp1; + struct timeval_buf tmp2; + + nttime_to_timeval(&ct, + cp->Value.AvTimestamp); + nttime_to_timeval(&st, + sp->Value.AvTimestamp); + + DEBUG(1,("%s: invalid AvTimestamp " + "got[%s] expect[%s] for " + "user=[%s] domain=[%s] " + "workstation=[%s]\n", + __func__, + timeval_str_buf(&ct, false, + true, &tmp1), + timeval_str_buf(&st, false, + true, &tmp2), + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + break; + default: + /* + * This can't happen as we control + * ntlmssp_state->server.av_pair_list + */ + return NT_STATUS_INTERNAL_ERROR; + } + } + } + + nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime); + expired = timeval_expired(&endtime); + if (expired) { + struct timeval_buf tmp; + DEBUG(1,("%s: challenge invalid (expired %s) for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + timeval_str_buf(&endtime, false, true, &tmp), + ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a client challenge @@ -481,7 +752,8 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, struct gensec_ntlmssp_context *gensec_ntlmssp, - struct ntlmssp_server_auth_state *state) + struct ntlmssp_server_auth_state *state, + DATA_BLOB request) { struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; DATA_BLOB user_session_key = state->user_session_key; @@ -598,6 +870,55 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, talloc_steal(ntlmssp_state, session_key.data); } + if (ntlmssp_state->new_spnego) { + HMACMD5Context ctx; + uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, }; + int cmp; + + hmac_md5_init_limK_to_64(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length, + &ctx); + + hmac_md5_update(ntlmssp_state->negotiate_blob.data, + ntlmssp_state->negotiate_blob.length, + &ctx); + hmac_md5_update(ntlmssp_state->challenge_blob.data, + ntlmssp_state->challenge_blob.length, + &ctx); + + /* checked were we set ntlmssp_state->new_spnego */ + SMB_ASSERT(request.length > + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE)); + + hmac_md5_update(request.data, NTLMSSP_MIC_OFFSET, &ctx); + hmac_md5_update(mic_buffer, NTLMSSP_MIC_SIZE, &ctx); + hmac_md5_update(request.data + + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE), + request.length - + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE), + &ctx); + hmac_md5_final(mic_buffer, &ctx); + + cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET, + mic_buffer, NTLMSSP_MIC_SIZE); + if (cmp != 0) { + DEBUG(1,("%s: invalid NTLMSSP_MIC for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + dump_data(1, request.data + NTLMSSP_MIC_OFFSET, + NTLMSSP_MIC_SIZE); + dump_data(1, mic_buffer, + NTLMSSP_MIC_SIZE); + return NT_STATUS_INVALID_PARAMETER; + } + } + + data_blob_free(&ntlmssp_state->negotiate_blob); + data_blob_free(&ntlmssp_state->challenge_blob); + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); } @@ -663,7 +984,7 @@ NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security, ntlmssp_state->check_password, the ntlmssp_server_postpath can be done in a callback */ - nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state); + nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state, in); TALLOC_FREE(state); return nt_status; } -- 1.9.1 From 4804521004448d6a40e95282e96998393b7c2a09 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:02:58 +0100 Subject: [PATCH 250/440] CVE-2016-2110(<=4.2): auth/ntlmssp: implement new_spnego support including MIC checking (as server) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the build in 4.2 and older versions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_server.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 17d5ade..9549641 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -608,10 +608,8 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, "user=[%s] domain=[%s] " "workstation=[%s]\n", __func__, - timeval_str_buf(&ct, false, - true, &tmp1), - timeval_str_buf(&st, false, - true, &tmp2), + timeval_str_buf(&ct, true, &tmp1), + timeval_str_buf(&st, true, &tmp2), ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->client.netbios_name)); @@ -635,7 +633,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, DEBUG(1,("%s: challenge invalid (expired %s) for " "user=[%s] domain=[%s] workstation=[%s]\n", __func__, - timeval_str_buf(&endtime, false, true, &tmp), + timeval_str_buf(&endtime, true, &tmp), ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->client.netbios_name)); return NT_STATUS_INVALID_PARAMETER; -- 1.9.1 From 629afd79d613504dd070ce66db70c71fe08feaf8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:26:49 +0100 Subject: [PATCH 251/440] CVE-2016-2110: auth/ntlmssp: implement new_spnego support including MIC generation (as client) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now detect a MsvAvTimestamp in target info as indication of the server to support NTLMSSP_MIC in the AUTH_MESSAGE. If the client uses NTLMv2 we provide NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE and valid MIC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 206 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 5 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index bc2a822..2412768 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -80,6 +80,7 @@ struct ntlmssp_state struct { const char *netbios_name; const char *netbios_domain; + struct AV_PAIR_LIST av_pair_list; } client; struct { diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index af4d249..b419615 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -90,6 +90,12 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, } } + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + *out); + if (ntlmssp_state->negotiate_blob.length != out->length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -113,8 +119,15 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, if (in.length == 0) { /* * This is compat code for older callers - * which were missing the "initial_blob" + * which were missing the "initial_blob"/"negotiate_blob". + * + * That means we can't calculate the NTLMSSP_MIC + * field correctly and need to force the + * old_spnego behaviour. */ + DEBUG(10, ("%s: in.length==%u force_old_spnego!\n", + __func__, (unsigned int)in.length)); + ntlmssp_state->force_old_spnego = true; ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; ntlmssp_state->required_flags = 0; ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -187,6 +200,12 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, } } + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + in); + if (ntlmssp_state->negotiate_blob.length != in.length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -229,6 +248,9 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, bool is_anonymous = false; const DATA_BLOB version_blob = ntlmssp_version_blob(); const NTTIME *server_timestamp = NULL; + uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, }; + DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer)); + HMACMD5Context ctx; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -266,7 +288,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string = "CdUdbdd"; chal_parse_string_short = "CdUdb"; } - auth_gen_string = "CdBBUUUBdb"; + auth_gen_string = "CdBBUUUBdbb"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; @@ -275,7 +297,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string_short = "CdAdb"; } - auth_gen_string = "CdBBAAABdb"; + auth_gen_string = "CdBBAAABdbb"; } if (!msrpc_parse(mem_ctx, @@ -386,11 +408,12 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, struct wbcCredentialCacheParams params; struct wbcCredentialCacheInfo *info = NULL; struct wbcAuthErrorInfo *error = NULL; - struct wbcNamedBlob auth_blobs[1]; + struct wbcNamedBlob auth_blobs[2]; const struct wbcBlob *wbc_auth_blob = NULL; const struct wbcBlob *wbc_session_key = NULL; wbcErr wbc_status; int i; + bool new_spnego = false; params.account_name = user; params.domain_name = domain; @@ -400,6 +423,10 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, auth_blobs[0].flags = 0; auth_blobs[0].blob.data = in.data; auth_blobs[0].blob.length = in.length; + auth_blobs[1].name = "negotiate_blob"; + auth_blobs[1].flags = 0; + auth_blobs[1].blob.data = ntlmssp_state->negotiate_blob.data; + auth_blobs[1].blob.length = ntlmssp_state->negotiate_blob.length; params.num_blobs = ARRAY_SIZE(auth_blobs); params.blobs = auth_blobs; @@ -416,6 +443,9 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, if (strequal(info->blobs[i].name, "session_key")) { wbc_session_key = &info->blobs[i].blob; } + if (strequal(info->blobs[i].name, "new_spnego")) { + new_spnego = true; + } } if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) { wbcFreeMemory(info); @@ -436,6 +466,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, wbcFreeMemory(info); return NT_STATUS_NO_MEMORY; } + ntlmssp_state->new_spnego = new_spnego; wbcFreeMemory(info); goto done; @@ -454,6 +485,150 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, flags |= CLI_CRED_LANMAN_AUTH; } + if (target_info.length != 0 && !is_anonymous) { + struct AV_PAIR *pairs = NULL; + uint32_t count = 0; + enum ndr_err_code err; + struct AV_PAIR *timestamp = NULL; + struct AV_PAIR *eol = NULL; + uint32_t i = 0; + const char *service = NULL; + const char *hostname = NULL; + + err = ndr_pull_struct_blob(&target_info, + ntlmssp_state, + &ntlmssp_state->server.av_pair_list, + (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return ndr_map_error2ntstatus(err); + } + + count = ntlmssp_state->server.av_pair_list.count; + /* + * We need room for Flags, SingleHost, + * ChannelBindings and Target + */ + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, + count + 4); + if (pairs == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < count; i++) { + pairs[i] = ntlmssp_state->server.av_pair_list.pair[i]; + } + + ntlmssp_state->client.av_pair_list.count = count; + ntlmssp_state->client.av_pair_list.pair = pairs; + + eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvEOL); + if (eol == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvTimestamp); + if (timestamp != NULL) { + uint32_t sign_features = + GENSEC_FEATURE_SESSION_KEY | + GENSEC_FEATURE_SIGN | + GENSEC_FEATURE_SEAL; + + server_timestamp = ×tamp->Value.AvTimestamp; + + if (ntlmssp_state->force_old_spnego) { + sign_features = 0; + } + + if (gensec_security->want_features & sign_features) { + struct AV_PAIR *av_flags = NULL; + + av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvFlags); + if (av_flags == NULL) { + av_flags = eol; + eol++; + count++; + *eol = *av_flags; + av_flags->AvId = MsvAvFlags; + av_flags->Value.AvFlags = 0; + } + + av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE; + ntlmssp_state->new_spnego = true; + } + } + + { + struct AV_PAIR *SingleHost = NULL; + + SingleHost = eol; + eol++; + count++; + *eol = *SingleHost; + + /* + * This is not really used, but we want to + * add some more random bytes and match + * Windows. + */ + SingleHost->AvId = MsvAvSingleHost; + SingleHost->Value.AvSingleHost.token_info.Flags = 0; + SingleHost->Value.AvSingleHost.token_info.TokenIL = 0; + generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId, + sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId)); + SingleHost->Value.AvSingleHost.remaining = data_blob_null; + } + + { + struct AV_PAIR *ChannelBindings = NULL; + + ChannelBindings = eol; + eol++; + count++; + *eol = *ChannelBindings; + + /* + * gensec doesn't support channel bindings yet, + * but we want to match Windows on the wire + */ + ChannelBindings->AvId = MsvChannelBindings; + memset(ChannelBindings->Value.ChannelBindings, 0, + sizeof(ChannelBindings->Value.ChannelBindings)); + } + + service = gensec_get_target_service(gensec_security); + hostname = gensec_get_target_hostname(gensec_security); + if (service != NULL && hostname != NULL) { + struct AV_PAIR *target = NULL; + + target = eol; + eol++; + count++; + *eol = *target; + + target->AvId = MsvAvTargetName; + target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s", + service, + hostname); + if (target->Value.AvTargetName == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + + ntlmssp_state->client.av_pair_list.count = count; + ntlmssp_state->client.av_pair_list.pair = pairs; + + err = ndr_push_struct_blob(&target_info, + ntlmssp_state, + &ntlmssp_state->client.av_pair_list, + (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return NT_STATUS_NO_MEMORY; + } + } + nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, &flags, challenge_blob, server_timestamp, target_info, @@ -522,13 +697,34 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, workstation, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags, - version_blob.data, version_blob.length); + version_blob.data, version_blob.length, + mic_blob.data, mic_blob.length); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } + /* + * We always include the MIC, even without: + * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE; + * ntlmssp_state->new_spnego = true; + * + * This matches a Windows client. + */ + hmac_md5_init_limK_to_64(session_key.data, + session_key.length, + &ctx); + hmac_md5_update(ntlmssp_state->negotiate_blob.data, + ntlmssp_state->negotiate_blob.length, + &ctx); + hmac_md5_update(in.data, in.length, &ctx); + hmac_md5_update(out->data, out->length, &ctx); + hmac_md5_final(mic_buffer, &ctx); + memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE); + done: + data_blob_free(&ntlmssp_state->negotiate_blob); + ntlmssp_state->session_key = session_key; talloc_steal(ntlmssp_state, session_key.data); -- 1.9.1 From d88fd1fd5e0c84e78f91e92e41767683fe38c0cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:11:32 +0100 Subject: [PATCH 252/440] CVE-2016-2111: auth/gensec: require DCERPC_AUTH_LEVEL_INTEGRITY or higher in schannel_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn't make any sense to allow other auth levels. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/schannel.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c index ee23e77..c2cfd3b 100644 --- a/auth/gensec/schannel.c +++ b/auth/gensec/schannel.c @@ -467,6 +467,16 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ *out = data_blob(NULL, 0); + if (gensec_security->dcerpc_auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + return NT_STATUS_INVALID_PARAMETER_MIX; + case GENSEC_SERVER: + return NT_STATUS_INVALID_PARAMETER; + } + return NT_STATUS_INTERNAL_ERROR; + } + switch (gensec_security->gensec_role) { case GENSEC_CLIENT: if (state != NULL) { -- 1.9.1 From 9cbb359de88706c113f212f5052b4e38df0cd034 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:10:20 +0100 Subject: [PATCH 253/440] CVE-2016-2111: auth/gensec: correctly report GENSEC_FEATURE_{SIGN,SEAL} in schannel_have_feature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This depends on the DCERPC auth level. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/schannel.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c index c2cfd3b..1acf7fe 100644 --- a/auth/gensec/schannel.c +++ b/auth/gensec/schannel.c @@ -679,9 +679,15 @@ static NTSTATUS schannel_client_start(struct gensec_security *gensec_security) static bool schannel_have_feature(struct gensec_security *gensec_security, uint32_t feature) { - if (feature & (GENSEC_FEATURE_SIGN | - GENSEC_FEATURE_SEAL)) { - return true; + if (gensec_security->dcerpc_auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + if (feature & GENSEC_FEATURE_SIGN) { + return true; + } + } + if (gensec_security->dcerpc_auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + if (feature & GENSEC_FEATURE_SEAL) { + return true; + } } if (feature & GENSEC_FEATURE_DCE_STYLE) { return true; -- 1.9.1 From 337625339b3c67abb0a2c2ed5640960c9306310c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Mar 2016 15:31:23 +0100 Subject: [PATCH 254/440] CVE-2016-2111: s4:rpc_server: implement 'server schannel = yes' restriction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index b2f0073..0459088 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -126,6 +126,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx); bool reject_des_client = !allow_nt4_crypto; bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx); + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool reject_none_rpc = (schannel == true); ZERO_STRUCTP(r->out.return_credentials); *r->out.rid = 0; @@ -198,6 +200,10 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca negotiate_flags = *r->in.negotiate_flags & server_flags; + if (negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC) { + reject_none_rpc = false; + } + if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { reject_des_client = false; } @@ -234,6 +240,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca */ *r->out.negotiate_flags = negotiate_flags; + if (reject_none_rpc) { + /* schannel must be used, but client did not offer it. */ + DEBUG(0,("%s: schannel required but client failed " + "to offer it. Client was %s\n", + __func__, r->in.account_name)); + return NT_STATUS_ACCESS_DENIED; + } + switch (r->in.secure_channel_type) { case SEC_CHAN_WKSTA: case SEC_CHAN_DNS_DOMAIN: @@ -488,7 +502,8 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc { NTSTATUS nt_status; struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; - bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */ + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool schannel_global_required = (schannel == true); if (schannel_global_required) { nt_status = schannel_check_required(auth_info, -- 1.9.1 From 2c895e280a02c10d7a0fb6b67ed9cf11f3e2512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 01:29:10 +0200 Subject: [PATCH 255/440] CVE-2016-2111: s3:rpc_server/netlogon: always go through netr_creds_server_step_check() The ensures we apply the "server schannel = yes" restrictions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Guenther Deschner Signed-off-by: Stefan Metzmacher --- source3/rpc_server/netlogon/srv_netlog_nt.c | 40 ++++++++++------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index b487c31..7348f80 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -2456,22 +2456,16 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p, NTSTATUS status; struct netlogon_creds_CredentialState *creds; struct lsa_ForestTrustInformation *info, **info_ptr; - struct loadparm_context *lp_ctx; /* TODO: check server name */ - lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers()); - if (lp_ctx == NULL) { - DEBUG(0, ("loadparm_init_s3 failed\n")); - return NT_STATUS_INTERNAL_ERROR; - } - - status = schannel_check_creds_state(p->mem_ctx, lp_ctx, - r->in.computer_name, - r->in.credential, - r->out.return_authenticator, - &creds); - talloc_unlink(p->mem_ctx, lp_ctx); + become_root(); + status = netr_creds_server_step_check(p, p->mem_ctx, + r->in.computer_name, + r->in.credential, + r->out.return_authenticator, + &creds); + unbecome_root(); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2558,22 +2552,16 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p, bool trusted; struct netr_TrustInfo *trust_info; struct pdb_trusted_domain *td; - struct loadparm_context *lp_ctx; - - lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers()); - if (lp_ctx == NULL) { - DEBUG(0, ("loadparm_init_s3 failed\n")); - return NT_STATUS_INTERNAL_ERROR; - } /* TODO: check server name */ - status = schannel_check_creds_state(p->mem_ctx, lp_ctx, - r->in.computer_name, - r->in.credential, - r->out.return_authenticator, - &creds); - talloc_unlink(p->mem_ctx, lp_ctx); + become_root(); + status = netr_creds_server_step_check(p, p->mem_ctx, + r->in.computer_name, + r->in.credential, + r->out.return_authenticator, + &creds); + unbecome_root(); if (!NT_STATUS_IS_OK(status)) { return status; } -- 1.9.1 From 8fc4fa658a84de78f0a6ea94b84b977a134caa9b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 256/440] CVE-2016-2111: s4:rpc_server/netlogon: require DCERPC_AUTH_LEVEL_PRIVACY for validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0459088..0523dd4 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -904,6 +904,16 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal break; case 6: + if (dce_call->conn->auth_state.auth_info == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (dce_call->conn->auth_state.auth_info->auth_level != + DCERPC_AUTH_LEVEL_PRIVACY) + { + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, user_info_dc, &sam3); -- 1.9.1 From 2fc6d1d7d22f609a6f9d8d94ef2cd2f04fe6e24a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 257/440] CVE-2016-2111: s3:rpc_server/netlogon: require DCERPC_AUTH_LEVEL_PRIVACY for validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/netlogon/srv_netlog_nt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index 7348f80..a6af1d2 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1707,6 +1707,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, r->out.validation->sam3); break; case 6: + /* Only allow this if the pipe is protected. */ + if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { + DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n", + get_remote_machine_name())); + status = NT_STATUS_INVALID_PARAMETER; + break; + } + status = serverinfo_to_SamInfo6(server_info, r->out.validation->sam6); break; -- 1.9.1 From f66df79e8f8f1dd4698215531dc9d5b6555fb061 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 258/440] CVE-2016-2111: s4:torture/rpc: fix rpc.samba3.netlogon ntlmv2 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The computer name of the NTLMv2 blob needs to match the schannel connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/torture/rpc/samba3rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index c211115..cec3aaa 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1145,8 +1145,8 @@ static bool schan(struct torture_context *tctx, generate_random_buffer(chal.data, chal.length); names_blob = NTLMv2_generate_names_blob( mem_ctx, - cli_credentials_get_workstation(user_creds), - cli_credentials_get_domain(user_creds)); + cli_credentials_get_workstation(wks_creds), + cli_credentials_get_domain(wks_creds)); status = cli_credentials_get_ntlm_response( user_creds, mem_ctx, &flags, chal, NULL, names_blob, &lm_resp, &nt_resp, NULL, NULL); -- 1.9.1 From 81507dc8a11d59ffdd7aa040c6e1327359e4b334 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 259/440] CVE-2016-2111: s4:torture/rpc: fix rpc.pac ntlmv2 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The computer name of the NTLMv2 blob needs to match the schannel connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/torture/rpc/remote_pac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 83fc839..aaf08e0 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -729,8 +729,8 @@ static bool test_S2U4Self(struct torture_context *tctx, chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); - names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(client_creds), - cli_credentials_get_domain(client_creds)); + names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(server_creds), + cli_credentials_get_domain(server_creds)); status = cli_credentials_get_ntlm_response(client_creds, tctx, &flags, -- 1.9.1 From 1a57fdf3e3acd4abf50431d32175332353b6d8d8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Feb 2016 19:08:31 +0100 Subject: [PATCH 260/440] CVE-2016-2111: libcli/auth: add NTLMv2_RESPONSE_verify_netlogon_creds() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the function that prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/proto.h | 5 ++ libcli/auth/smbencrypt.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index e7689e2..a4949d0 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -155,6 +155,11 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ; +NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, + const char *account_domain, + const DATA_BLOB response, + const struct netlogon_creds_CredentialState *creds, + const char *workgroup); /*********************************************************** encode a password buffer with a unicode password. The buffer diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index 6edcaa3..c88fbd6 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -26,7 +26,7 @@ #include "../libcli/auth/msrpc_parse.h" #include "../lib/crypto/crypto.h" #include "../libcli/auth/libcli_auth.h" -#include "../librpc/gen_ndr/ntlmssp.h" +#include "../librpc/gen_ndr/ndr_ntlmssp.h" void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]) { @@ -557,6 +557,138 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, lm_response, nt_response, lm_session_key, user_session_key); } +NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, + const char *account_domain, + const DATA_BLOB response, + const struct netlogon_creds_CredentialState *creds, + const char *workgroup) +{ + TALLOC_CTX *frame = NULL; + /* RespType + HiRespType */ + static const char *magic = "\x01\x01"; + int cmp; + struct NTLMv2_RESPONSE v2_resp; + enum ndr_err_code err; + const struct AV_PAIR *av_nb_cn = NULL; + const struct AV_PAIR *av_nb_dn = NULL; + + if (response.length < 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes. + */ + return NT_STATUS_OK; + } + + cmp = memcmp(response.data + 16, magic, 2); + if (cmp != 0) { + /* + * It doesn't look like a valid NTLMv2_RESPONSE + */ + return NT_STATUS_OK; + } + + frame = talloc_stackframe(); + + err = ndr_pull_struct_blob(&response, frame, &v2_resp, + (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + NTSTATUS status; + status = ndr_map_error2ntstatus(err); + DEBUG(2,("Failed to parse NTLMv2_RESPONSE " + "length %u - %s - %s\n", + (unsigned)response.length, + ndr_map_error2string(err), + nt_errstr(status))); + dump_data(2, response.data, response.length); + TALLOC_FREE(frame); + return status; + } + + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp); + } + + /* + * Make sure the netbios computer name in the + * NTLMv2_RESPONSE matches the computer name + * in the secure channel credentials for workstation + * trusts. + * + * And the netbios domain name matches our + * workgroup. + * + * This prevents workstations from requesting + * the session key of NTLMSSP sessions of clients + * to other hosts. + */ + if (creds->secure_channel_type == SEC_CHAN_WKSTA) { + av_nb_cn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvNbComputerName); + av_nb_dn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvNbDomainName); + } + + if (av_nb_cn != NULL) { + const char *v = NULL; + char *a = NULL; + size_t len; + + v = av_nb_cn->Value.AvNbComputerName; + + a = talloc_strdup(frame, creds->account_name); + if (a == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + len = strlen(a); + if (len > 0 && a[len - 1] == '$') { + a[len - 1] = '\0'; + } + + cmp = strcasecmp_m(a, v); + if (cmp != 0) { + DEBUG(2,("%s: NTLMv2_RESPONSE with " + "NbComputerName[%s] rejected " + "for user[%s\\%s] " + "against SEC_CHAN_WKSTA[%s/%s] " + "in workgroup[%s]\n", + __func__, v, + account_domain, + account_name, + creds->computer_name, + creds->account_name, + workgroup)); + TALLOC_FREE(frame); + return NT_STATUS_LOGON_FAILURE; + } + } + if (av_nb_dn != NULL) { + const char *v = NULL; + + v = av_nb_dn->Value.AvNbDomainName; + + cmp = strcasecmp_m(workgroup, v); + if (cmp != 0) { + DEBUG(2,("%s: NTLMv2_RESPONSE with " + "NbDomainName[%s] rejected " + "for user[%s\\%s] " + "against SEC_CHAN_WKSTA[%s/%s] " + "in workgroup[%s]\n", + __func__, v, + account_domain, + account_name, + creds->computer_name, + creds->account_name, + workgroup)); + TALLOC_FREE(frame); + return NT_STATUS_LOGON_FAILURE; + } + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + /*********************************************************** encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. -- 1.9.1 From 6d825878ede9597a1d2b6f2d149c83f6625437ca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 261/440] CVE-2016-2111: s4:rpc_server/netlogon: check NTLMv2_RESPONSE values for SEC_CHAN_WKSTA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0523dd4..14811b5 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -739,6 +739,8 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) { + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const char *workgroup = lpcfg_workgroup(lp_ctx); struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; @@ -809,6 +811,13 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length); user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length); + nt_status = NTLMv2_RESPONSE_verify_netlogon_creds( + user_info->client.account_name, + user_info->client.domain_name, + user_info->password.response.nt, + creds, workgroup); + NT_STATUS_NOT_OK_RETURN(nt_status); + break; -- 1.9.1 From 27bdf7b788af3b6022e400c9f8e95cf0622c5b2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 262/440] CVE-2016-2111: s3:rpc_server/netlogon: check NTLMv2_RESPONSE values for SEC_CHAN_WKSTA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/netlogon/srv_netlog_nt.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index a6af1d2..932df1d 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1573,6 +1573,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, case NetlogonNetworkTransitiveInformation: { const char *wksname = nt_workstation; + const char *workgroup = lp_workgroup(); status = make_auth_context_fixed(talloc_tos(), &auth_context, logon->network->challenge); @@ -1599,6 +1600,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, logon->network->nt.length)) { status = NT_STATUS_NO_MEMORY; } + + if (NT_STATUS_IS_OK(status)) { + status = NTLMv2_RESPONSE_verify_netlogon_creds( + user_info->client.account_name, + user_info->client.domain_name, + user_info->password.response.nt, + creds, workgroup); + } break; } case NetlogonInteractiveInformation: -- 1.9.1 From 34d85fdbd13ba239929838e4731d8ad7fd6293b2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 263/440] CVE-2016-2111: s4:torture/raw: don't use ntlmv2 for dos connection in raw.samba3badpath BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/torture/raw/samba3misc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index a818c6b..9758653 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -440,22 +440,29 @@ bool torture_samba3_badpath(struct torture_context *torture) bool ret = true; TALLOC_CTX *mem_ctx; bool nt_status_support; + bool client_ntlmv2_auth; torture_assert(torture, mem_ctx = talloc_init("torture_samba3_badpath"), "talloc_init failed"); nt_status_support = lpcfg_nt_status_support(torture->lp_ctx); + client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n"); torture_assert_goto(torture, torture_open_connection(&cli_nt, torture, 0), ret, fail, "Could not open NTSTATUS connection\n"); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n"); torture_assert_goto(torture, torture_open_connection(&cli_dos, torture, 1), ret, fail, "Could not open DOS connection\n"); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", nt_status_support ? "yes":"no"), ret, fail, "Could not set 'nt status support' back to where it was\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", + client_ntlmv2_auth ? "yes":"no"), + ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n"); torture_assert(torture, torture_setup_dir(cli_nt, dirname), "creating test directory"); -- 1.9.1 From d4efdfc9a80f8a47d5ee8ce5e8a7e9db3e6bef1b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 264/440] CVE-2016-2111: s4:torture/base: don't use ntlmv2 for dos connection in base.samba3error BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/torture/basic/base.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index 6a792b2..5d4efc7 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -1527,6 +1527,7 @@ static bool torture_chkpath_test(struct torture_context *tctx, static bool torture_samba3_errorpaths(struct torture_context *tctx) { bool nt_status_support; + bool client_ntlmv2_auth; struct smbcli_state *cli_nt = NULL, *cli_dos = NULL; bool result = false; int fnum; @@ -1536,18 +1537,27 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) NTSTATUS status; nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx); + client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx); if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) { torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n"); goto fail; } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) { + torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n"); + goto fail; + } if (!torture_open_connection(&cli_nt, tctx, 0)) { goto fail; } if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) { - torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n"); + torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n"); + goto fail; + } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) { + torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n"); goto fail; } @@ -1557,7 +1567,12 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", nt_status_support ? "yes":"no")) { - torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support = yes'"); + torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'"); + goto fail; + } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", + client_ntlmv2_auth ? "yes":"no")) { + torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'"); goto fail; } -- 1.9.1 From cf069ca30a7fe530ad400d9c17766e3de9aeda99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 265/440] CVE-2016-2111: s4:libcli: don't allow the LANMAN2 session setup without "client lanman auth = yes" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/libcli/smb_composite/sesssetup.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 903055f..f09a3f8 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -393,24 +393,13 @@ static NTSTATUS session_setup_old(struct composite_context *c, struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - const char *domain = cli_credentials_get_domain(io->in.credentials); /* * domain controllers tend to reject the NTLM v2 blob * if the netbiosname is not valid (e.g. IP address or FQDN) * so just leave it away (as Windows client do) */ - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, NULL, domain); - DATA_BLOB session_key; - int flags = 0; - if (session->options.lanman_auth) { - flags |= CLI_CRED_LANMAN_AUTH; - } - - if (session->options.ntlmv2_auth) { - flags |= CLI_CRED_NTLMv2_AUTH; - } state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; @@ -424,6 +413,17 @@ static NTSTATUS session_setup_old(struct composite_context *c, &state->setup.old.in.domain); if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + DATA_BLOB names_blob = data_blob_null; + int flags = 0; + + if (!cli_credentials_is_anonymous(io->in.credentials) && + !session->options.lanman_auth) + { + return NT_STATUS_INVALID_PARAMETER; + } + + flags |= CLI_CRED_LANMAN_AUTH; + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, -- 1.9.1 From 217b81646f3019326617556134ea57fefe582de0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 266/440] CVE-2016-2111: s4:param: use "client use spnego" to initialize options->use_spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index af3313f..71331fb 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -36,7 +36,7 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx, { options->max_xmit = lpcfg_max_xmit(lp_ctx); options->max_mux = lpcfg_max_mux(lp_ctx); - options->use_spnego = lpcfg_nt_status_support(lp_ctx) && lpcfg_use_spnego(lp_ctx); + options->use_spnego = lpcfg_nt_status_support(lp_ctx) && lpcfg_client_use_spnego(lp_ctx); options->signing = lpcfg_client_signing(lp_ctx); options->request_timeout = SMB_REQUEST_TIMEOUT; options->ntstatus_support = lpcfg_nt_status_support(lp_ctx); -- 1.9.1 From 5217d11c5b2564ed38bf5f14c0e515da7a3d2fa0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 267/440] CVE-2016-2111: s4:libcli: don't send a raw NTLMv2 response when we want to use spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/libcli/smb_composite/sesssetup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index f09a3f8..9f989f2 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -329,6 +329,17 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + if (!cli_credentials_is_anonymous(io->in.credentials) && + session->options.ntlmv2_auth && + session->transport->options.use_spnego) + { + /* + * Don't send an NTLMv2_RESPONSE without NTLMSSP + * if we want to use spnego + */ + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, -- 1.9.1 From c5b9d83bbf20f038c9c0e3b080137b68821307f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 268/440] CVE-2016-2111: s3:libsmb: don't send a raw NTLMv2 response when we want to use spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source3/libsmb/cliconnect.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a406ceb..4d0d2f2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2145,6 +2145,17 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, return req; } else { /* otherwise do a NT1 style session setup */ + if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) { + /* + * Don't send an NTLMv2 response without NTLMSSP + * if we want to use spnego support + */ + DEBUG(1, ("Server does not support EXTENDED_SECURITY " + " but 'client use spnego = yes" + " and 'client ntlmv2 auth = yes'\n")); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return tevent_req_post(req, ev); + } subreq = cli_session_setup_nt1_send( state, ev, cli, user, pass, passlen, ntpass, ntpasslen, -- 1.9.1 From 055b81f29960b3467ec85f7432f52529ec76da12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 27 Mar 2016 01:09:05 +0100 Subject: [PATCH 269/440] CVE-2016-2111: docs-xml: document the new "client NTLMv2 auth" and "client use spnego" interaction BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/protocol/clientusespnego.xml | 5 +++++ docs-xml/smbdotconf/security/clientntlmv2auth.xml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs-xml/smbdotconf/protocol/clientusespnego.xml b/docs-xml/smbdotconf/protocol/clientusespnego.xml index c688a65..e538745 100644 --- a/docs-xml/smbdotconf/protocol/clientusespnego.xml +++ b/docs-xml/smbdotconf/protocol/clientusespnego.xml @@ -9,6 +9,11 @@ supporting servers (including WindowsXP, Windows2000 and Samba 3.0) to agree upon an authentication mechanism. This enables Kerberos authentication in particular. + + When is also set to + yes extended security (SPNEGO) is required + in order to use NTLMv2 only within NTLMSSP. This behavior was + introduced with the patches for CVE-2016-2111. yes diff --git a/docs-xml/smbdotconf/security/clientntlmv2auth.xml b/docs-xml/smbdotconf/security/clientntlmv2auth.xml index 7f30356..451e180 100644 --- a/docs-xml/smbdotconf/security/clientntlmv2auth.xml +++ b/docs-xml/smbdotconf/security/clientntlmv2auth.xml @@ -28,6 +28,11 @@ NTLMv2 by default, and some sites (particularly those following 'best practice' security polices) only allow NTLMv2 responses, and not the weaker LM or NTLM. + + When is also set to + yes extended security (SPNEGO) is required + in order to use NTLMv2 only within NTLMSSP. This behavior was + introduced with the patches for CVE-2016-2111. yes -- 1.9.1 From e7137c8b8186872c3142092ee31cd5b395de877a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:02:34 +0100 Subject: [PATCH 270/440] CVE-2016-2111: docs-xml: add "raw NTLMv2 auth" defaulting to "yes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/rawntlmv2auth.xml | 20 ++++++++++++++++++++ lib/param/loadparm.c | 1 + source3/param/loadparm.c | 1 + 3 files changed, 22 insertions(+) create mode 100644 docs-xml/smbdotconf/security/rawntlmv2auth.xml diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml new file mode 100644 index 0000000..ef26297 --- /dev/null +++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml @@ -0,0 +1,20 @@ + + + This parameter determines whether or not smbd + 8 will allow SMB1 clients without + extended security (without SPNEGO) to use NTLMv2 authentication. + + If this option, lanman auth + and ntlm auth are all disabled, + then only clients with SPNEGO support will be permitted. + That means NTLMv2 is only supported within NTLMSSP. + + Note that the default will change to "no" with Samba 4.5. + + +yes +no + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 0de9793..21410ac 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2509,6 +2509,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False"); lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True"); + lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 360d997..5819a0e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -660,6 +660,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */ Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */ Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */ + Globals.raw_ntlmv2_auth = true; /* Allow NTLMv2 without NTLMSSP */ Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ -- 1.9.1 From fa7ed95ff941dfbefa836b979297a128ec623edf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:02:34 +0100 Subject: [PATCH 271/440] CVE-2016-2111(<=4.3): docs-xml: add "raw NTLMv2 auth" defaulting to "yes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Ralph Boehme --- lib/param/param_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 57cb382..aad3b4d 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -728,6 +728,14 @@ struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { + .label = "raw NTLMv2 auth", + .type = P_BOOL, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(raw_ntlmv2_auth), + .special = NULL, + .enum_list = NULL, + }, + { .label = "client NTLMv2 auth", .type = P_BOOL, .p_class = P_GLOBAL, -- 1.9.1 From 3e26d1cb6989b9cfb46bd08b3b22935cd2bacc02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 272/440] CVE-2016-2111: s3:auth: implement "raw NTLMv2 auth" checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/auth/auth_util.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 2b355e4..c1aa997 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -34,6 +34,7 @@ #include "../auth/auth_sam_reply.h" #include "../librpc/gen_ndr/idmap.h" #include "lib/param/loadparm.h" +#include "../lib/tsocket/tsocket.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -353,6 +354,20 @@ NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx, const struct tsocket_address *remote_address, DATA_BLOB lm_resp, DATA_BLOB nt_resp) { + bool allow_raw = lp_raw_ntlmv2_auth(); + + if (!allow_raw && nt_resp.length >= 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes + * and should only be supported via NTLMSSP. + */ + DEBUG(2,("Rejecting raw NTLMv2 authentication with " + "user [%s\\%s] from[%s]\n", + client_domain, smb_name, + tsocket_address_string(remote_address, mem_ctx))); + return NT_STATUS_INVALID_PARAMETER; + } + return make_user_info(mem_ctx, user_info, smb_name, smb_name, client_domain, client_domain, -- 1.9.1 From d25ad5b8a0e73a54386b8b8d4835135308a32880 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 273/440] CVE-2016-2111: s4:smb_server: implement "raw NTLMv2 auth" checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/smb_server/smb/sesssetup.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index 4ebc0c4..e06853a 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -263,6 +263,7 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess) const char *remote_machine = NULL; struct tevent_req *subreq; struct sesssetup_context *state; + bool allow_raw = lpcfg_raw_ntlmv2_auth(req->smb_conn->lp_ctx); sess->nt1.out.vuid = 0; sess->nt1.out.action = 0; @@ -338,6 +339,15 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess) user_info->password.response.nt = sess->nt1.in.password2; user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data); + if (!allow_raw && user_info->password.response.nt.length >= 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes + * and should only be supported via NTLMSSP. + */ + status = NT_STATUS_INVALID_PARAMETER; + goto failed; + } + subreq = auth_check_password_send(state, req->smb_conn->connection->event.ctx, state->auth_context, -- 1.9.1 From 31c1c3d0946e69f63f80e49ac6b94528d9c3c2ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:08:38 +0100 Subject: [PATCH 274/440] CVE-2016-2111: selftest:Samba3: use "raw NTLMv2 auth = yes" for nt4_dc BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- selftest/target/Samba3.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index ac8bfb7..bb1fd5b 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -210,6 +210,7 @@ sub setup_s3dc($$) domain master = yes domain logons = yes lanman auth = yes + raw NTLMv2 auth = yes rpc_server:epmapper = external rpc_server:spoolss = external -- 1.9.1 From 0de6cb7cfbb2f908c9d0e122ef5322a7f8bbc8dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:59:42 +0100 Subject: [PATCH 275/440] CVE-2016-2111: docs-xml/smbdotconf: default "raw NTLMv2 auth" to "no" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/rawntlmv2auth.xml | 7 +++---- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml index ef26297..30e7280 100644 --- a/docs-xml/smbdotconf/security/rawntlmv2auth.xml +++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml @@ -11,10 +11,9 @@ and ntlm auth are all disabled, then only clients with SPNEGO support will be permitted. That means NTLMv2 is only supported within NTLMSSP. - - Note that the default will change to "no" with Samba 4.5. -yes -no +lanman auth +ntlm auth +no diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 21410ac..ce745c4 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2509,7 +2509,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False"); lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True"); - lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "True"); + lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5819a0e..32adb43 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -660,7 +660,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */ Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */ Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */ - Globals.raw_ntlmv2_auth = true; /* Allow NTLMv2 without NTLMSSP */ + Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */ Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ -- 1.9.1 From 9028d12eb7fdd5f4b992437985eff0f0ac851e9f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Mar 2016 15:50:49 +0100 Subject: [PATCH 276/440] CVE-2016-2112: s3:libads: make sure we detect downgrade attacks BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Pair-programmed-with: Ralph Boehme Signed-off-by: Stefan Metzmacher Signed-off-by: Ralph Boehme --- source3/libads/sasl.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e205e9f..4fcd733 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -276,6 +276,37 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, data_blob_free(&blob_in); data_blob_free(&blob_out); + if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) { + bool ok; + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SEAL); + if (!ok) { + DEBUG(0,("The gensec feature sealing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The gensec feature signing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) { + bool ok; + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The gensec feature signing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + } + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security); ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); -- 1.9.1 From 1519dfda7b5d89f31643d080aa7c91ef5daf3605 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 277/440] CVE-2016-2112: s4:libcli/ldap: honour "client ldap sasl wrapping" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 7af3823..162f785 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -32,6 +32,7 @@ #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" #include "param/param.h" +#include "param/loadparm.h" struct ldap_simple_creds { const char *dn; @@ -216,7 +217,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct ldap_SearchResEntry *search; int count, i; bool first = true; - + int wrap_flags = 0; const char **sasl_names; uint32_t old_gensec_features; static const char *supported_sasl_mech_attrs[] = { @@ -285,6 +286,21 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, gensec_init(); + if (conn->sockets.active == conn->sockets.tls) { + /* + * require Kerberos SIGN/SEAL only if we don't use SSL + * Windows seem not to like double encryption + */ + wrap_flags = 0; + } else if (cli_credentials_is_anonymous(creds)) { + /* + * anonymous isn't protected + */ + wrap_flags = 0; + } else { + wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx); + } + try_logon_again: /* we loop back here on a logon failure, and re-create the @@ -301,10 +317,8 @@ try_logon_again: goto failed; } - /* require Kerberos SIGN/SEAL only if we don't use SSL - * Windows seem not to like double encryption */ old_gensec_features = cli_credentials_get_gensec_features(creds); - if (conn->sockets.active == conn->sockets.tls) { + if (wrap_flags == 0) { cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); } @@ -320,6 +334,14 @@ try_logon_again: * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); + if (wrap_flags & ADS_AUTH_SASL_SEAL) { + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); + } + if (wrap_flags & ADS_AUTH_SASL_SIGN) { + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); + } + /* * This is an indication for the NTLMSSP backend to * also encrypt when only GENSEC_FEATURE_SIGN is requested -- 1.9.1 From f65e306e8aa4f76428a783c93bad1cb6dabd7fc1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 278/440] CVE-2016-2112: s4:libcli/ldap: make sure we detect downgrade attacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 162f785..41037e7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -495,6 +495,20 @@ try_logon_again: conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; + if (wrap_flags & ADS_AUTH_SASL_SEAL) { + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + } else if (wrap_flags & ADS_AUTH_SASL_SIGN) { + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + } + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) && !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { return NT_STATUS_OK; -- 1.9.1 From 0ce80505c0b2de29440c5671d89ee8f09ab6a0e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 279/440] CVE-2016-2112: s4:libcli/ldap: auto upgrade to SIGN after STRONG_AUTH_REQUIRED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 41037e7..397b4cb 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -437,6 +437,13 @@ try_logon_again: result = response->r.BindResponse.response.resultcode; + if (result == LDAP_STRONG_AUTH_REQUIRED) { + if (wrap_flags == 0) { + wrap_flags = ADS_AUTH_SASL_SIGN; + goto try_logon_again; + } + } + if (result == LDAP_INVALID_CREDENTIALS) { /* try a second time on invalid credentials, to -- 1.9.1 From 6beabfeeb83a1d83d047311d99033e3432370533 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:56:29 +0100 Subject: [PATCH 280/440] CVE-2016-2112: s4:selftest: use --option=clientldapsaslwrapping=plain for plain connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8ccbaee..32bd73e 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -44,7 +44,7 @@ bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP for auth_type in ['', '-k no', '-k yes']: - for auth_level in ['', '--sign', '--encrypt']: + for auth_level in ['--option=clientldapsaslwrapping=plain', '--sign', '--encrypt']: creds = '-U"$USERNAME%$PASSWORD"' options = creds + ' ' + auth_type + ' ' + auth_level plantestsuite("samba4.ldb.ldap with options %r(dc)" % options, "dc", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) -- 1.9.1 From d3d229d8a454f15d6646f2ae853c5ef85cce1f05 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 12:45:56 +0100 Subject: [PATCH 281/440] CVE-2016-2112: s4:ldap_server: reduce scope of old_session_info variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/ldap_server/ldap_bind.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index fb7a6ed..7113b63 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -218,7 +218,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) result = LDAP_SASL_BIND_IN_PROGRESS; errstr = NULL; } else if (NT_STATUS_IS_OK(status)) { - struct auth_session_info *old_session_info=NULL; struct ldapsrv_sasl_postprocess_context *context = NULL; result = LDAP_SUCCESS; @@ -266,14 +265,13 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) } if (result != LDAP_SUCCESS) { - conn->session_info = old_session_info; } else if (!NT_STATUS_IS_OK(status)) { - conn->session_info = old_session_info; result = LDAP_OPERATIONS_ERROR; errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to setup SASL socket: %s", req->creds.SASL.mechanism, nt_errstr(status)); } else { + struct auth_session_info *old_session_info=NULL; old_session_info = conn->session_info; conn->session_info = NULL; -- 1.9.1 From 9f9bba6e6ead8837c51c527f9abc2b0ee32bdedf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 12:03:56 +0100 Subject: [PATCH 282/440] CVE-2016-2112: docs-xml: add "ldap server require strong auth" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- .../ldap/ldapserverrequirestrongauth.xml | 28 ++++++++++++++++++++++ lib/param/loadparm.c | 2 ++ lib/param/loadparm.h | 6 +++++ lib/param/param_table.c | 12 ++++++++++ source3/param/loadparm.c | 3 +++ 5 files changed, 51 insertions(+) create mode 100644 docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml new file mode 100644 index 0000000..18d695b --- /dev/null +++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml @@ -0,0 +1,28 @@ + + + + The defines whether + the ldap server requires ldap traffic to be signed or signed and encrypted (sealed). + Possible values are no, allow_sasl_over_tls + and yes. + + + A value of no allows simple and sasl binds over + all transports. + + A value of allow_sasl_over_tls allows simple and sasl binds + (without sign or seal) over TLS encrypted connections. Unencrypted connections only + allow sasl binds with sign or seal. + + A value of yes allows only simple binds + over TLS encrypted connections. Unencrypted connections only + allow sasl binds with sign or seal. + + Note the default will change to yes with Samba 4.5. + +no + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index ce745c4..e3486e8 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2688,6 +2688,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "sign"); + lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "no"); + lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes"); lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800"); diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h index 11632de..2d460dc 100644 --- a/lib/param/loadparm.h +++ b/lib/param/loadparm.h @@ -201,6 +201,12 @@ enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, #define ADS_AUTH_SASL_FORCE 0x0080 #define ADS_AUTH_USER_CREDS 0x0100 +enum ldap_server_require_strong_auth { + LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, + LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS, + LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, +}; + /* DNS update settings */ enum dns_update_settings {DNS_UPDATE_OFF, DNS_UPDATE_ON, DNS_UPDATE_SIGNED}; diff --git a/lib/param/param_table.c b/lib/param/param_table.c index aad3b4d..efe5a89 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -216,6 +216,18 @@ static const struct enum_list enum_ldap_sasl_wrapping[] = { {-1, NULL} }; +static const struct enum_list enum_ldap_server_require_strong_auth_vals[] = { + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "No" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "False" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "0" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS, + "allow_sasl_over_tls" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "Yes" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "True" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "1" }, + {-1, NULL} +}; + static const struct enum_list enum_ldap_ssl[] = { {LDAP_SSL_OFF, "no"}, {LDAP_SSL_OFF, "off"}, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 32adb43..e2236fb 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -708,6 +708,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; + Globals.ldap_server_require_strong_auth = + LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will * forget the token. Set to 0 to get NEVERDATE.*/ -- 1.9.1 From ea90292f01c14026820e56775bff5cc7c3fbbabe Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:09:46 +0100 Subject: [PATCH 283/440] CVE-2016-2112(<=4.3): docs-xml: add "ldap server require strong auth" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher --- lib/param/param_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index efe5a89..32a725d 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -1683,6 +1683,14 @@ struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { + .label = "ldap server require strong auth", + .type = P_ENUM, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(ldap_server_require_strong_auth), + .special = NULL, + .enum_list = enum_ldap_server_require_strong_auth_vals + }, + { .label = "enable asu support", .type = P_BOOL, .p_class = P_GLOBAL, -- 1.9.1 From 55472c8f466af1c42421e6c659060fc0487cf62c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Aug 2015 12:19:37 +0200 Subject: [PATCH 284/440] CVE-2016-2112: s4:ldap_server: implement "ldap server require strong auth" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/ldap_server/ldap_bind.c | 45 ++++++++++++++++++++++++++++++++++----- source4/ldap_server/ldap_server.c | 6 ++++++ source4/ldap_server/ldap_server.h | 2 ++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 7113b63..99ca148 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -45,6 +45,23 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) DEBUG(10, ("BindSimple dn: %s\n",req->dn)); + reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); + if (!reply) { + return NT_STATUS_NO_MEMORY; + } + + if (req->dn != NULL && + strlen(req->dn) != 0 && + call->conn->require_strong_auth > LDAP_SERVER_REQUIRE_STRONG_AUTH_NO && + call->conn->sockets.active != call->conn->sockets.tls) + { + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "BindSimple: Transport encryption required."); + goto do_reply; + } + status = crack_auto_name_to_nt4_name(call, call->conn->connection->event.ctx, call->conn->lp_ctx, req->dn, &nt4_domain, &nt4_account); if (NT_STATUS_IS_OK(status)) { status = authenticate_username_pw(call, @@ -58,11 +75,6 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) &session_info); } - reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); - if (!reply) { - return NT_STATUS_NO_MEMORY; - } - if (NT_STATUS_IS_OK(status)) { result = LDAP_SUCCESS; errstr = NULL; @@ -86,6 +98,7 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) errstr = talloc_asprintf(reply, "Simple Bind Failed: %s", nt_errstr(status)); } +do_reply: resp = &reply->msg->r.BindResponse; resp->response.resultcode = result; resp->response.errormessage = errstr; @@ -262,6 +275,28 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) status = NT_STATUS_NO_MEMORY; } } + } else { + switch (call->conn->require_strong_auth) { + case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO: + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS: + if (call->conn->sockets.active == call->conn->sockets.tls) { + break; + } + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "SASL:[%s]: not allowed if TLS is used.", + req->creds.SASL.mechanism); + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES: + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "SASL:[%s]: Sign or Seal are required.", + req->creds.SASL.mechanism); + break; + } } if (result != LDAP_SUCCESS) { diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index d849ed3..f4134d7 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -334,6 +334,12 @@ static void ldapsrv_accept(struct stream_connection *c, conn->sockets.active = conn->sockets.raw; + if (conn->is_privileged) { + conn->require_strong_auth = LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + } else { + conn->require_strong_auth = lpcfg_ldap_server_require_strong_auth(conn->lp_ctx); + } + if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 6f8b433..87a7163 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -22,6 +22,7 @@ #include "lib/socket/socket.h" #include "lib/stream/packet.h" #include "system/network.h" +#include "lib/param/loadparm.h" struct ldapsrv_connection { struct loadparm_context *lp_ctx; @@ -42,6 +43,7 @@ struct ldapsrv_connection { bool global_catalog; bool is_privileged; + enum ldap_server_require_strong_auth require_strong_auth; struct { int initial_timeout; -- 1.9.1 From 96bdf1ca5ea08d2e70400aebf8008bfef0fb8368 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:07:02 +0100 Subject: [PATCH 285/440] CVE-2016-2112: s4:selftest: run samba4.ldap.bind against fl2008r2dc This uses "ldap server require strong auth = no". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 32bd73e..8784f6c 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -508,7 +508,7 @@ plantestsuite("samba4.blackbox.setpassword.py", "none", ["PYTHON=%s" % python, o plantestsuite("samba4.blackbox.newuser.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_newuser.sh"), '$PREFIX/provision']) plantestsuite("samba4.blackbox.group.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_group.sh"), '$PREFIX/provision']) plantestsuite("samba4.blackbox.spn.py(dc:local)", "dc:local", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_spn.sh"), '$PREFIX/dc']) -plantestsuite_loadlist("samba4.ldap.bind(dc)", "dc", [python, os.path.join(srcdir(), "auth/credentials/tests/bind.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '$LOADLIST', '$LISTOPT']) +plantestsuite_loadlist("samba4.ldap.bind(fl2008r2dc)", "fl2008r2dc", [python, os.path.join(srcdir(), "auth/credentials/tests/bind.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '$LOADLIST', '$LISTOPT']) # This makes sure we test the rid allocation code t = "rpc.samr.large-dc" -- 1.9.1 From 4073ffe7d6f5c83d6d28cedc796d07b7aea03ce5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:27:33 +0100 Subject: [PATCH 286/440] CVE-2016-2112: selftest: servers with explicit "ldap server require strong auth" options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default is "ldap server require strong auth = yes", ad_dc_ntvfs uses "ldap server require strong auth = allow_sasl_over_tls", fl2008r2dc uses "ldap server require strong auth = no". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Alexander Bokovoy --- selftest/target/Samba4.pm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index eb9c572..4b9f158 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -430,6 +430,7 @@ sub provision_raw_step1($$) dcerpc endpoint servers = +winreg +srvsvc notify:inotify = false ldb:nosync = true + ldap server require strong auth = yes #We don't want to pass our self-tests if the PAC code is wrong gensec:require_pac = true log file = $ctx->{logdir}/log.\%m @@ -1105,7 +1106,9 @@ sub provision_dc($$) print "PROVISIONING DC..."; my $extra_conf_options = "netbios aliases = localDC1-a - server services = +winbind -winbindd"; + server services = +winbind -winbindd + ldap server require strong auth = allow_sasl_over_tls + "; my $ret = $self->provision($prefix, "domain controller", "localdc", @@ -1211,6 +1214,7 @@ sub provision_fl2008r2dc($$) my ($self, $prefix) = @_; print "PROVISIONING DC..."; + my $extra_conf_options = "ldap server require strong auth = no"; my $ret = $self->provision($prefix, "domain controller", "dc7", @@ -1218,7 +1222,8 @@ sub provision_fl2008r2dc($$) "samba2008R2.example.com", "2008_R2", "locDCpass7", - undef, "", "", undef); + undef, $extra_conf_options, + "", undef); unless ($self->add_wins_config("$prefix/private")) { warn("Unable to add wins configuration"); -- 1.9.1 From 2b89f338a0e628c86364a5707dcccc016eb1b7e4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:04:48 +0100 Subject: [PATCH 287/440] CVE-2016-2112: s4:selftest: run some ldap test against ad_dc_ntvfs, fl2008r2dc and fl2003dc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to test against all "ldap server require strong auth" combinations. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Alexander Bokovoy --- selftest/knownfail | 6 +++++ source4/selftest/tests.py | 24 ++++++++++++++++++++ testprogs/blackbox/test_ldb_simple.sh | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100755 testprogs/blackbox/test_ldb_simple.sh diff --git a/selftest/knownfail b/selftest/knownfail index ff9ea40..7202796 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -308,3 +308,9 @@ ^samba.ntlm_auth.\(dc:local\).ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind with failed require-membership-of ^samba.ntlm_auth.\(dc:local\).wbinfo store cached credentials ^samba.ntlm_auth.\(dc:local\).ntlm_auth ccached credentials with NTLMSSP client and gss-spnego server +# +## We assert all "ldap server require strong auth" combinations +# +^samba4.ldb.simple.ldap with SIMPLE-BIND.*ad_dc_ntvfs # ldap server require strong auth = allow_sasl_over_tls +^samba4.ldb.simple.ldap with SIMPLE-BIND.*fl2003dc # ldap server require strong auth = yes +^samba4.ldb.simple.ldaps with SASL-BIND.*fl2003dc # ldap server require strong auth = yes diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8784f6c..79a60f3 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -67,6 +67,30 @@ if have_tls_support: plantestsuite("samba4.ldb.ldaps with options %s(dc)" % options, "dc", "%s/test_ldb.sh ldaps $SERVER_IP %s" % (bbdir, options)) +# test all "ldap server require strong auth" combinations +for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: + options = '--simple-bind-dn="$USERNAME@$REALM" --password="$PASSWORD"' + plantestsuite("samba4.ldb.simple.ldap with SIMPLE-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) + if have_tls_support: + plantestsuite("samba4.ldb.simple.ldaps with SIMPLE-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) + + auth_options = [ + '--option=clientldapsaslwrapping=plain', + '--sign', + '--encrypt', + ] + + for auth_option in auth_options: + options = '-U"$USERNAME%$PASSWORD"' + ' ' + auth_option + plantestsuite("samba4.ldb.simple.ldap with SASL-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) + if have_tls_support: + options = '-U"$USERNAME%$PASSWORD"' + plantestsuite("samba4.ldb.simple.ldaps with SASL-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) + for options in ['-U"$USERNAME%$PASSWORD"']: plantestsuite("samba4.ldb.ldapi with options %s(dc:local)" % options, "dc:local", "%s/test_ldb.sh ldapi $PREFIX_ABS/dc/private/ldapi %s" % (bbdir, options)) diff --git a/testprogs/blackbox/test_ldb_simple.sh b/testprogs/blackbox/test_ldb_simple.sh new file mode 100755 index 0000000..7375cbf --- /dev/null +++ b/testprogs/blackbox/test_ldb_simple.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +if [ $# -lt 2 ]; then +cat < Date: Fri, 25 Mar 2016 19:24:20 +0100 Subject: [PATCH 288/440] CVE-2016-2112: docs-xml: change the default of "ldap server require strong auth" to "yes" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml | 4 +--- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml index 18d695b..02bdd81 100644 --- a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml +++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml @@ -21,8 +21,6 @@ A value of yes allows only simple binds over TLS encrypted connections. Unencrypted connections only allow sasl binds with sign or seal. - - Note the default will change to yes with Samba 4.5. -no +yes diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index e3486e8..6de3e43 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2688,7 +2688,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "sign"); - lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "no"); + lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes"); lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e2236fb..7cb2757 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -709,7 +709,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; Globals.ldap_server_require_strong_auth = - LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + LDAP_SERVER_REQUIRE_STRONG_AUTH_YES; /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will -- 1.9.1 From f68a0b009e0529782c07ec2ef7394881ba4c99ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 15:39:48 +0100 Subject: [PATCH 289/440] CVE-2016-2113: s4:lib/tls: create better certificates and sign the host cert with the ca cert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generated ca cert (in ca.pem) was completely useless, it could be replaced by cert.pem. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/lib/tls/tlscert.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c index 8eab04a..f1808d7 100644 --- a/source4/lib/tls/tlscert.c +++ b/source4/lib/tls/tlscert.c @@ -30,9 +30,10 @@ #endif #define ORGANISATION_NAME "Samba Administration" -#define UNIT_NAME "Samba - temporary autogenerated certificate" +#define CA_NAME "Samba - temporary autogenerated CA certificate" +#define UNIT_NAME "Samba - temporary autogenerated HOST certificate" #define LIFETIME 700*24*60*60 -#define DH_BITS 1024 +#define RSA_BITS 4096 /* auto-generate a set of self signed certificates @@ -77,11 +78,11 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, DEBUG(3,("Generating private key\n")); TLSCHECK(gnutls_x509_privkey_init(&key)); - TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, DH_BITS, 0)); + TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA private key\n")); TLSCHECK(gnutls_x509_privkey_init(&cakey)); - TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, DH_BITS, 0)); + TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA certificate\n")); TLSCHECK(gnutls_x509_crt_init(&cacrt)); @@ -90,7 +91,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, ORGANISATION_NAME, strlen(ORGANISATION_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, - UNIT_NAME, strlen(UNIT_NAME))); + CA_NAME, strlen(CA_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_COMMON_NAME, 0, hostname, strlen(hostname))); @@ -98,10 +99,8 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial))); TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation)); TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry)); - TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 0)); -#ifdef GNUTLS_KP_TLS_WWW_SERVER - TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(cacrt, GNUTLS_KP_TLS_WWW_SERVER, 0)); -#endif + TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1)); + TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN)); TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3)); TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize)); #if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID @@ -134,6 +133,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize)); #endif TLSCHECK(gnutls_x509_crt_sign(crt, crt, key)); + TLSCHECK(gnutls_x509_crt_sign(crt, cacrt, cakey)); DEBUG(3,("Exporting TLS keys\n")); -- 1.9.1 From d4f7bf49fc59cd73fd73e61aaea1a9dc71049bea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 290/440] CVE-2016-2113: s4:lib/tls: implement infrastructure to do peer verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/lib/tls/tls.h | 23 ++++ source4/lib/tls/tls_tstream.c | 249 ++++++++++++++++++++++++++++++++++++++ source4/lib/tls/wscript | 5 + source4/libcli/ldap/ldap_client.c | 2 + source4/librpc/rpc/dcerpc_roh.c | 2 + 5 files changed, 281 insertions(+) diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index e6c27f3..e600c89 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -68,10 +68,33 @@ const struct socket_ops *socket_tls_ops(enum socket_type type); struct tstream_context; struct tstream_tls_params; +enum tls_verify_peer_state { + TLS_VERIFY_PEER_NO_CHECK = 0, +#define TLS_VERIFY_PEER_NO_CHECK_STRING "no_check" + + TLS_VERIFY_PEER_CA_ONLY = 10, +#define TLS_VERIFY_PEER_CA_ONLY_STRING "ca_only" + + TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE = 20, +#define TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING \ + "ca_and_name_if_available" + + TLS_VERIFY_PEER_CA_AND_NAME = 30, +#define TLS_VERIFY_PEER_CA_AND_NAME_STRING "ca_and_name" + + TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE = 9999, +#define TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING \ + "as_strict_as_possible" +}; + +const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer); + NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *tls_priority, + enum tls_verify_peer_state verify_peer, + const char *peer_name, struct tstream_tls_params **_tlsp); NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 255e2ce..2ccb909 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -20,13 +20,16 @@ #include "includes.h" #include "system/network.h" #include "system/filesys.h" +#include "system/time.h" #include "../util/tevent_unix.h" #include "../lib/tsocket/tsocket.h" #include "../lib/tsocket/tsocket_internal.h" +#include "../lib/util/util_net.h" #include "lib/tls/tls.h" #if ENABLE_GNUTLS #include +#include #define DH_BITS 2048 @@ -34,8 +37,47 @@ typedef gnutls_datum gnutls_datum_t; #endif +/* + * define our own values in a high range + */ +#ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED +#define GNUTLS_CERT_EXPIRED 0x10000000 +#define REQUIRE_CERT_TIME_CHECKS 1 +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED +#define GNUTLS_CERT_NOT_ACTIVATED 0x20000000 +#ifndef REQUIRE_CERT_TIME_CHECKS +#define REQUIRE_CERT_TIME_CHECKS 1 +#endif +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_UNEXPECTED_OWNER +#define GNUTLS_CERT_UNEXPECTED_OWNER 0x40000000 +#endif + #endif /* ENABLE_GNUTLS */ +const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer) +{ + switch (verify_peer) { + case TLS_VERIFY_PEER_NO_CHECK: + return TLS_VERIFY_PEER_NO_CHECK_STRING; + + case TLS_VERIFY_PEER_CA_ONLY: + return TLS_VERIFY_PEER_CA_ONLY_STRING; + + case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE: + return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING; + + case TLS_VERIFY_PEER_CA_AND_NAME: + return TLS_VERIFY_PEER_CA_AND_NAME_STRING; + + case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE: + return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING; + } + + return "unknown tls_verify_peer_state"; +} + static const struct tstream_context_ops tstream_tls_ops; struct tstream_tls { @@ -46,6 +88,9 @@ struct tstream_tls { gnutls_session tls_session; #endif /* ENABLE_GNUTLS */ + enum tls_verify_peer_state verify_peer; + const char *peer_name; + struct tevent_context *current_ev; struct tevent_immediate *retry_im; @@ -871,6 +916,8 @@ struct tstream_tls_params { const char *tls_priority; #endif /* ENABLE_GNUTLS */ bool tls_enabled; + enum tls_verify_peer_state verify_peer; + const char *peer_name; }; static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp) @@ -897,6 +944,8 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *tls_priority, + enum tls_verify_peer_state verify_peer, + const char *peer_name, struct tstream_tls_params **_tlsp) { #if ENABLE_GNUTLS @@ -914,6 +963,21 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_set_destructor(tlsp, tstream_tls_params_destructor); + tlsp->verify_peer = verify_peer; + if (peer_name != NULL) { + tlsp->peer_name = talloc_strdup(tlsp, peer_name); + if (tlsp->peer_name == NULL) { + talloc_free(tlsp); + return NT_STATUS_NO_MEMORY; + } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { + DEBUG(0,("TLS failed to missing peer_name - " + "with 'tls verify peer = %s'\n", + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred); if (ret != GNUTLS_E_SUCCESS) { DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); @@ -931,6 +995,13 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_free(tlsp); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { + DEBUG(0,("TLS failed to missing cafile %s - " + "with 'tls verify peer = %s'\n", + ca_file, + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; } if (crl_file && *crl_file && file_exist(crl_file)) { @@ -943,6 +1014,13 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_free(tlsp); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE) { + DEBUG(0,("TLS failed to missing crlfile %s - " + "with 'tls verify peer = %s'\n", + crl_file, + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; } tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); @@ -997,6 +1075,13 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx, talloc_set_destructor(tlss, tstream_tls_destructor); tlss->plain_stream = plain_stream; + tlss->verify_peer = tls_params->verify_peer; + if (tls_params->peer_name != NULL) { + tlss->peer_name = talloc_strdup(tlss, tls_params->peer_name); + if (tevent_req_nomem(tlss->peer_name, req)) { + return tevent_req_post(req, ev); + } + } tlss->current_ev = ev; tlss->retry_im = tevent_create_immediate(tlss); @@ -1364,6 +1449,170 @@ static void tstream_tls_retry_handshake(struct tstream_context *stream) return; } + if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { + unsigned int status = UINT32_MAX; + bool ip = true; + const char *hostname = NULL; +#ifndef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 + bool need_crt_checks = false; +#endif + + if (tlss->peer_name != NULL) { + ip = is_ipaddress(tlss->peer_name); + } + + if (!ip) { + hostname = tlss->peer_name; + } + + if (tlss->verify_peer == TLS_VERIFY_PEER_CA_ONLY) { + hostname = NULL; + } + + if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { + if (hostname == NULL) { + DEBUG(1,("TLS %s - no hostname available for " + "verify_peer[%s] and peer_name[%s]\n", + __location__, + tls_verify_peer_string(tlss->verify_peer), + tlss->peer_name)); + tlss->error = EINVAL; + tevent_req_error(req, tlss->error); + return; + } + } + +#ifdef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 + ret = gnutls_certificate_verify_peers3(tlss->tls_session, + hostname, + &status); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } +#else /* not HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 */ + ret = gnutls_certificate_verify_peers2(tlss->tls_session, &status); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + if (status == 0) { + if (hostname != NULL) { + need_crt_checks = true; + } +#ifdef REQUIRE_CERT_TIME_CHECKS + need_crt_checks = true; +#endif + } + + if (need_crt_checks) { + gnutls_x509_crt crt; + const gnutls_datum *cert_list; + unsigned int cert_list_size = 0; +#ifdef REQUIRE_CERT_TIME_CHECKS + time_t now = time(NULL); + time_t tret = -1; +#endif + + cert_list = gnutls_certificate_get_peers(tlss->tls_session, + &cert_list_size); + if (cert_list == NULL) { + cert_list_size = 0; + } + if (cert_list_size == 0) { + DEBUG(1,("TLS %s - cert_list_size == 0\n", + __location__)); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + ret = gnutls_x509_crt_init(&crt); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, + gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + ret = gnutls_x509_crt_import(crt, + &cert_list[0], + GNUTLS_X509_FMT_DER); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, + gnutls_strerror(ret))); + gnutls_x509_crt_deinit(crt); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + if (hostname != NULL) { + ret = gnutls_x509_crt_check_hostname(crt, + hostname); + if (ret == 0) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_UNEXPECTED_OWNER; + } + } + +#ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED + /* + * GNUTLS_CERT_NOT_ACTIVATED is defined by ourself + */ + tret = gnutls_x509_crt_get_activation_time(crt); + if ((tret == -1) || (now > tret)) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_NOT_ACTIVATED; + } +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED + /* + * GNUTLS_CERT_EXPIRED is defined by ourself + */ + tret = gnutls_certificate_expiration_time_peers(tlss->tls_session); + if ((tret == -1) || (now > tret)) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_EXPIRED; + } +#endif + gnutls_x509_crt_deinit(crt); + } +#endif + + if (status != 0) { + DEBUG(1,("TLS %s - check failed for " + "verify_peer[%s] and peer_name[%s] " + "status 0x%x (%s%s%s%s%s%s%s%s)\n", + __location__, + tls_verify_peer_string(tlss->verify_peer), + tlss->peer_name, + status, + status & GNUTLS_CERT_INVALID ? "invalid " : "", + status & GNUTLS_CERT_REVOKED ? "revoked " : "", + status & GNUTLS_CERT_SIGNER_NOT_FOUND ? + "signer_not_found " : "", + status & GNUTLS_CERT_SIGNER_NOT_CA ? + "signer_not_ca " : "", + status & GNUTLS_CERT_INSECURE_ALGORITHM ? + "insecure_algorithm " : "", + status & GNUTLS_CERT_NOT_ACTIVATED ? + "not_activated " : "", + status & GNUTLS_CERT_EXPIRED ? + "expired " : "", + status & GNUTLS_CERT_UNEXPECTED_OWNER ? + "unexptected_owner " : "")); + tlss->error = EINVAL; + tevent_req_error(req, tlss->error); + return; + } + } + tevent_req_done(req); #else /* ENABLE_GNUTLS */ tevent_req_error(req, ENOSYS); diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript index 7985c6f..3fd8acaf 100644 --- a/source4/lib/tls/wscript +++ b/source4/lib/tls/wscript @@ -39,6 +39,11 @@ def configure(conf): conf.CHECK_FUNCS_IN('gnutls_global_init', 'gnutls', headers='gnutls/gnutls.h') + conf.CHECK_FUNCS_IN('gnutls_certificate_verify_peers3', 'gnutls', + headers='gnutls/gnutls.h') + conf.CHECK_DECLS('GNUTLS_CERT_EXPIRED GNUTLS_CERT_NOT_ACTIVATED GNUTLS_CERT_UNEXPECTED_OWNER', + headers='gnutls/gnutls.h gnutls/x509.h') + conf.CHECK_VARIABLE('gnutls_x509_crt_set_version', headers='gnutls/gnutls.h gnutls/x509.h', define='HAVE_GNUTLS_X509_CRT_SET_VERSION', diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index b11490f..f585abd 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -475,6 +475,8 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con ca_file, crl_file, tls_priority, + TLS_VERIFY_PEER_NO_CHECK, + NULL, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { composite_error(result, status); diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index 61a22a7..c4842fb 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -187,6 +187,8 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn, if (use_tls) { status = tstream_tls_params_client(state->roh, NULL, NULL, lpcfg_tls_priority(lp_ctx), + TLS_VERIFY_PEER_NO_CHECK, + NULL, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n", -- 1.9.1 From ad3d38963a516dea9638b72a37719c6a01de9478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 22:12:56 +0100 Subject: [PATCH 291/440] CVE-2016-2113: docs-xml: add "tls verify peer" option defaulting to "no_check" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/tlsverifypeer.xml | 51 ++++++++++++++++++++++++++ lib/param/loadparm.c | 1 + lib/param/param_table.c | 15 ++++++++ source3/param/loadparm.c | 2 + 4 files changed, 69 insertions(+) create mode 100644 docs-xml/smbdotconf/security/tlsverifypeer.xml diff --git a/docs-xml/smbdotconf/security/tlsverifypeer.xml b/docs-xml/smbdotconf/security/tlsverifypeer.xml new file mode 100644 index 0000000..ce6897d --- /dev/null +++ b/docs-xml/smbdotconf/security/tlsverifypeer.xml @@ -0,0 +1,51 @@ + + + This controls if and how strict the client will verify the peer's certificate and name. + Possible values are (in increasing order): + no_check, + ca_only, + ca_and_name_if_available, + ca_and_name + and + as_strict_as_possible. + + When set to no_check the certificate is not verified at + all, which allows trivial man in the middle attacks. + + + When set to ca_only the certificate is verified to + be signed from a ca specified in the option. + Setting to a valid file is required. + The certificate lifetime is also verified. If the + option is configured, the certificate is also verified against the ca crl. + + + When set to ca_and_name_if_available all checks from + ca_only are performed. In addition, the peer hostname is verified + against the certificate's name, if it is provided by the application layer and + not given as an ip address string. + + + When set to ca_and_name all checks from + ca_and_name_if_available are performed. + In addition the peer hostname needs to be provided and even an ip + address is checked against the certificate's name. + + + When set to as_strict_as_possible all checks from + ca_and_name are performed. In addition the + needs to be configured. + Future versions of Samba may implement additional checks. + + + Note that the default is likely to change from + no_check to as_strict_as_possible + with Samba 4.5. + + +no_check + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 6de3e43..0730d51 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2554,6 +2554,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600"); lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True"); + lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "no_check"); lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 32a725d..e66c4d5 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -32,6 +32,7 @@ #include "lib/param/loadparm.h" #include "lib/param/param_global.h" #include "libcli/smb/smb_constants.h" +#include "source4/lib/tls/tls.h" #ifndef N_ #define N_(x) x @@ -122,6 +123,20 @@ static const struct enum_list enum_smb_signing_vals[] = { {-1, NULL} }; +static const struct enum_list enum_tls_verify_peer_vals[] = { + {TLS_VERIFY_PEER_NO_CHECK, + TLS_VERIFY_PEER_NO_CHECK_STRING}, + {TLS_VERIFY_PEER_CA_ONLY, + TLS_VERIFY_PEER_CA_ONLY_STRING}, + {TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE, + TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING}, + {TLS_VERIFY_PEER_CA_AND_NAME, + TLS_VERIFY_PEER_CA_AND_NAME_STRING}, + {TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE, + TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING}, + {-1, NULL} +}; + /* DNS update options. */ static const struct enum_list enum_dns_update_settings[] = { {DNS_UPDATE_OFF, "disabled"}, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7cb2757..f5d5c53 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -69,6 +69,7 @@ #include "dbwrap/dbwrap.h" #include "dbwrap/dbwrap_rbt.h" #include "../lib/util/bitmap.h" +#include "source4/lib/tls/tls.h" #ifdef HAVE_SYS_SYSCTL_H #include @@ -833,6 +834,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL); Globals.tls_enabled = true; + Globals.tls_verify_peer = TLS_VERIFY_PEER_NO_CHECK; lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); -- 1.9.1 From 3b3e20147214b6a29a9dc6225bff37990f5d038b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:37:06 +0100 Subject: [PATCH 292/440] CVE-2016-2113(<=4.3): docs-xml: add "tls verify peer" option defaulting to "no_check" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher --- lib/param/param_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index e66c4d5..09d0fe9 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4484,6 +4484,14 @@ struct parm_struct parm_table[] = { .special = NULL, .enum_list = NULL }, + { + .label = "tls verify peer", + .type = P_ENUM, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(tls_verify_peer), + .special = NULL, + .enum_list = enum_tls_verify_peer_vals, + }, {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0} }; -- 1.9.1 From 0436eb59f89fb06a494fc1eceefda89b61ef4b4f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 03:56:22 +0100 Subject: [PATCH 293/440] CVE-2016-2113: s4:selftest: explicitly use '--option="tlsverifypeer=no_check" for some ldaps tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 79a60f3..ff54454 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -73,6 +73,7 @@ for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: plantestsuite("samba4.ldb.simple.ldap with SIMPLE-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) if have_tls_support: + options += ' --option="tlsverifypeer=no_check"' plantestsuite("samba4.ldb.simple.ldaps with SIMPLE-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) @@ -87,7 +88,7 @@ for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: plantestsuite("samba4.ldb.simple.ldap with SASL-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) if have_tls_support: - options = '-U"$USERNAME%$PASSWORD"' + options = '-U"$USERNAME%$PASSWORD" --option="tlsverifypeer=no_check"' plantestsuite("samba4.ldb.simple.ldaps with SASL-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) -- 1.9.1 From 903d9b55e4a560fc1be7672e6ff90c14811be450 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 294/440] CVE-2016-2113: s4:libcli/ldap: verify the server certificate and hostname if configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_client.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f585abd..817863a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -465,18 +465,15 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx); char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx); const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx); - if (!ca_file || !*ca_file) { - composite_error(result, - NT_STATUS_INVALID_PARAMETER_MIX); - return result; - } + enum tls_verify_peer_state verify_peer = + lpcfg_tls_verify_peer(conn->lp_ctx); status = tstream_tls_params_client(state, ca_file, crl_file, tls_priority, - TLS_VERIFY_PEER_NO_CHECK, - NULL, + verify_peer, + conn->host, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { composite_error(result, status); -- 1.9.1 From 1265306193d2270e7a246fc28167e2efd8795d09 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 295/440] CVE-2016-2113: s4:librpc/rpc: verify the rpc_proxy certificate and hostname if configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc_roh.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index c4842fb..6da2978 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -185,10 +185,17 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn, /* Initialize TLS */ if (use_tls) { - status = tstream_tls_params_client(state->roh, NULL, NULL, - lpcfg_tls_priority(lp_ctx), - TLS_VERIFY_PEER_NO_CHECK, - NULL, + char *ca_file = lpcfg_tls_cafile(state, lp_ctx); + char *crl_file = lpcfg_tls_crlfile(state, lp_ctx); + const char *tls_priority = lpcfg_tls_priority(lp_ctx); + enum tls_verify_peer_state verify_peer = + lpcfg_tls_verify_peer(lp_ctx); + + status = tstream_tls_params_client(state->roh, + ca_file, crl_file, + tls_priority, + verify_peer, + state->rpc_proxy, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n", -- 1.9.1 From 7a4a5bad60aa26529aafcd8a13540b257cd44777 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 15:07:36 +0100 Subject: [PATCH 296/440] CVE-2016-2113: selftest: test all "tls verify peer" combinations with ldaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 10 ++++++++++ source4/selftest/tests.py | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 7202796..bb548ba 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -314,3 +314,13 @@ ^samba4.ldb.simple.ldap with SIMPLE-BIND.*ad_dc_ntvfs # ldap server require strong auth = allow_sasl_over_tls ^samba4.ldb.simple.ldap with SIMPLE-BIND.*fl2003dc # ldap server require strong auth = yes ^samba4.ldb.simple.ldaps with SASL-BIND.*fl2003dc # ldap server require strong auth = yes +# These are supposed to fail as we want to verify the "tls verify peer" +# restrictions. Note that fl2008r2dc uses a self-signed certificate +# with does not have a crl file. +# +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=ca_and_name_if_available\( +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=ca_and_name\( +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=as_strict_as_possible\( +^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=ca_and_name\( +^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=as_strict_as_possible\( +^samba4.ldb.simple.ldaps.*SERVER.REALM.*tlsverifypeer=as_strict_as_possible.*fl2008r2dc diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ff54454..793423e 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -67,6 +67,33 @@ if have_tls_support: plantestsuite("samba4.ldb.ldaps with options %s(dc)" % options, "dc", "%s/test_ldb.sh ldaps $SERVER_IP %s" % (bbdir, options)) + creds_options = [ + '--simple-bind-dn=$USERNAME@$REALM --password=$PASSWORD', + ] + peer_options = { + 'SERVER_IP': '$SERVER_IP', + 'SERVER_NAME': '$SERVER', + 'SERVER.REALM': '$SERVER.$REALM', + } + tls_verify_options = [ + '--option="tlsverifypeer=no_check"', + '--option="tlsverifypeer=ca_only"', + '--option="tlsverifypeer=ca_and_name_if_available"', + '--option="tlsverifypeer=ca_and_name"', + '--option="tlsverifypeer=as_strict_as_possible"', + ] + + # we use :local for fl2008r2dc because of the self-signed certificate + for env in ["ad_dc_ntvfs", "fl2008r2dc:local"]: + for peer_key in peer_options.keys(): + peer_val = peer_options[peer_key] + for creds in creds_options: + for tls_verify in tls_verify_options: + options = creds + ' ' + tls_verify + plantestsuite("samba4.ldb.simple.ldaps with options %s %s(%s)" % ( + peer_key, options, env), env, + "%s/test_ldb_simple.sh ldaps %s %s" % (bbdir, peer_val, options)) + # test all "ldap server require strong auth" combinations for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: options = '--simple-bind-dn="$USERNAME@$REALM" --password="$PASSWORD"' -- 1.9.1 From 81b249f0edfc81ae4af76a0d09eaab28c7edc60f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:38:46 +0100 Subject: [PATCH 297/440] CVE-2016-2113: selftest: use "tls verify peer = no_check" Individual tests will check the more secure values. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- selftest/selftest.pl | 1 + selftest/target/Samba4.pm | 1 + 2 files changed, 2 insertions(+) diff --git a/selftest/selftest.pl b/selftest/selftest.pl index 2707f72..4d82b31 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -577,6 +577,7 @@ sub write_clientconf($$$) winbind separator = / tls cafile = ${cacert} tls crlfile = ${cacrl_pem} + tls verify peer = no_check "; close(CF); } diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 4b9f158..7ea1544 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -423,6 +423,7 @@ sub provision_raw_step1($$) interfaces = $ctx->{interfaces} tls dh params file = $ctx->{tlsdir}/dhparms.pem tls crlfile = ${crlfile} + tls verify peer = no_check panic action = $RealBin/gdb_backtrace \%d wins support = yes server role = $ctx->{server_role} -- 1.9.1 From 431ca2e95edabf41fe4faca647ae34ac14a13962 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 13:03:08 +0100 Subject: [PATCH 298/440] CVE-2016-2113: docs-xml: let "tls verify peer" default to "as_strict_as_possible" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/tlsverifypeer.xml | 6 +----- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs-xml/smbdotconf/security/tlsverifypeer.xml b/docs-xml/smbdotconf/security/tlsverifypeer.xml index ce6897d..4f47dd4 100644 --- a/docs-xml/smbdotconf/security/tlsverifypeer.xml +++ b/docs-xml/smbdotconf/security/tlsverifypeer.xml @@ -41,11 +41,7 @@ needs to be configured. Future versions of Samba may implement additional checks. - - Note that the default is likely to change from - no_check to as_strict_as_possible - with Samba 4.5. -no_check +as_strict_as_possible diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 0730d51..f6c2cfb 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2554,7 +2554,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600"); lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True"); - lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "no_check"); + lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible"); lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f5d5c53..ee890b0 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -834,7 +834,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL); Globals.tls_enabled = true; - Globals.tls_verify_peer = TLS_VERIFY_PEER_NO_CHECK; + Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE; lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); -- 1.9.1 From 3c362594202dbd319e621cb9527d85955189893e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 04:45:16 +0200 Subject: [PATCH 299/440] CVE-2016-2114: s4:smb2_server: fix session setup with required signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client can't sign the session setup request... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/smb_server/smb2/sesssetup.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 35a1484..36adafd 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -201,14 +201,6 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses set SMB2_NEGOTIATE_SIGNING_REQUIRED */ if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { smb_sess->smb2_signing.required = true; - } else if (req->smb_conn->smb2_signing_required) { - /* - * if required signing was negotiates in SMB2 Negotiate - * then the client made an error not using it here - */ - DEBUG(1, ("SMB2 signing required on the connection but not used on session\n")); - req->status = NT_STATUS_FOOBAR; - goto failed; } /* disable receipt of more packets on this socket until we've -- 1.9.1 From cb9a0bd6e79e240648af56b37abcc3c3a5c00726 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 300/440] CVE-2016-2114: s3:smbd: use the correct default values for "smb signing" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This means an ad_dc will now require signing by default. This matches the default behavior of Windows dc and avoids man in the middle attacks. The main logic for this hides in lpcfg_server_signing_allowed(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/smbd/negprot.c | 6 ++++-- source3/smbd/smb2_negprot.c | 10 +++++++++- source3/smbd/smb2_sesssetup.c | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index e6a9bde..c922721 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -518,6 +518,7 @@ void reply_negprot(struct smb_request *req) size_t converted_size; struct smbXsrv_connection *xconn = req->xconn; struct smbd_server_connection *sconn = req->sconn; + bool signing_required = true; START_PROFILE(SMBnegprot); @@ -689,8 +690,9 @@ void reply_negprot(struct smb_request *req) DEBUG( 5, ( "negprot index=%d\n", choice ) ); - if ((lp_server_signing() == SMB_SIGNING_REQUIRED) - && (chosen_level < PROTOCOL_NT1)) { + /* We always have xconn->smb1.signing_state also for >= SMB2_02 */ + signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state); + if (signing_required && (chosen_level < PROTOCOL_NT1)) { exit_server_cleanly("SMB signing is required and " "client negotiated a downlevel protocol"); } diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index 1f7f1a9..39fd23b 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -24,6 +24,7 @@ #include "../libcli/smb/smb_common.h" #include "../lib/tsocket/tsocket.h" #include "../librpc/ndr/libndr.h" +#include "../libcli/smb/smb_signing.h" extern fstring remote_proto; @@ -149,6 +150,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) uint32_t max_read = lp_smb2_max_read(); uint32_t max_write = lp_smb2_max_write(); NTTIME now = timeval_to_nttime(&req->request_time); + bool signing_required = true; status = smbd_smb2_request_verify_sizes(req, 0x24); if (!NT_STATUS_IS_OK(status)) { @@ -221,7 +223,13 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; - if (lp_server_signing() == SMB_SIGNING_REQUIRED) { + /* + * We use xconn->smb1.signing_state as that's already present + * and used lpcfg_server_signing_allowed() to get the correct + * defaults, e.g. signing_required for an ad_dc. + */ + signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state); + if (signing_required) { security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED; } diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index e255e46..8b239c9 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -186,7 +186,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, struct smbXsrv_connection *xconn = smb2req->xconn; if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || - lp_server_signing() == SMB_SIGNING_REQUIRED) { + (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) + { x->global->signing_required = true; } -- 1.9.1 From f0c94dcf272358ee2f168b448fb54240962dcae6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:25:32 +0100 Subject: [PATCH 301/440] CVE-2016-2114: libcli/smb: let mandatory signing imply allowed signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/smb/smb_signing.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c index e128e8f..a7bc819 100644 --- a/libcli/smb/smb_signing.c +++ b/libcli/smb/smb_signing.c @@ -424,6 +424,10 @@ bool smb_signing_set_negotiated(struct smb_signing_state *si, return true; } + if (mandatory) { + allowed = true; + } + if (!si->allowed && mandatory) { return false; } -- 1.9.1 From a90d92c8301dc4b66c7c83369b42d0a4a4af778e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:30:42 +0100 Subject: [PATCH 302/440] CVE-2016-2114: s3:smbd: enforce "server signing = mandatory" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression that was introduced by commit abb24bf8e874d525382e994af7ae432212775153 ("s3:smbd: make use of better SMB signing negotiation"). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b261704..33574f7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -37,6 +37,7 @@ #include "../libcli/security/security.h" #include "auth/gensec/gensec.h" #include "lib/conn_tdb.h" +#include "../libcli/smb/smb_signing.h" /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. @@ -598,7 +599,8 @@ void reply_sesssetup_and_X(struct smb_request *req) struct smbd_server_connection *sconn = req->sconn; bool doencrypt = xconn->smb1.negprot.encrypted_passwords; bool signing_allowed = false; - bool signing_mandatory = false; + bool signing_mandatory = smb_signing_is_mandatory( + xconn->smb1.signing_state); START_PROFILE(SMBsesssetupX); -- 1.9.1 From c250b531490ae91260cb6404c9cc9766661c0714 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 303/440] CVE-2016-2114: docs-xml: let the "smb signing" documentation reflect the reality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/serversigning.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/smbdotconf/security/serversigning.xml b/docs-xml/smbdotconf/security/serversigning.xml index c94a3ee..1eb7c41 100644 --- a/docs-xml/smbdotconf/security/serversigning.xml +++ b/docs-xml/smbdotconf/security/serversigning.xml @@ -11,7 +11,7 @@ By default, and when smb signing is set to - default, smb signing enabled when + default, smb signing is required when is active directory domain controller and disabled otherwise. -- 1.9.1 From 04500c2f83b64f2795c5cf725a803a0eb56ef90b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:45:43 +0100 Subject: [PATCH 304/440] CVE-2016-2115: docs-xml: add "client ipc min protocol" and "client ipc max protocol" options BUG: https://bugzilla.samba.org/show_bug.cgi?id=11796 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- .../smbdotconf/protocol/clientipcmaxprotocol.xml | 29 ++++++++++++++++++++++ .../smbdotconf/protocol/clientipcminprotocol.xml | 29 ++++++++++++++++++++++ docs-xml/smbdotconf/protocol/clientmaxprotocol.xml | 9 ++++--- docs-xml/smbdotconf/protocol/clientminprotocol.xml | 6 +++++ lib/param/loadparm.c | 26 +++++++++++++++++++ source3/include/proto.h | 2 ++ source3/param/loadparm.c | 26 +++++++++++++++++++ 7 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml create mode 100644 docs-xml/smbdotconf/protocol/clientipcminprotocol.xml diff --git a/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml b/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml new file mode 100644 index 0000000..408af50 --- /dev/null +++ b/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml @@ -0,0 +1,29 @@ + + + The value of the parameter (a string) is the highest + protocol level that will be supported for IPC$ connections as DCERPC transport. + + Normally this option should not be set as the automatic + negotiation phase in the SMB protocol takes care of choosing + the appropriate protocol. + + The value default refers to the latest + supported protocol, currently SMB3_11. + + See for a full list + of available protocols. The values CORE, COREPLUS, LANMAN1, LANMAN2 + are silently upgraded to NT1. + + +client ipc min protocol +client min protocol +client max protocol + +default +SMB2_10 + diff --git a/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml b/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml new file mode 100644 index 0000000..fc04b78 --- /dev/null +++ b/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml @@ -0,0 +1,29 @@ + + + This setting controls the minimum protocol version that the + will be attempted to use for IPC$ connections as DCERPC transport. + + Normally this option should not be set as the automatic + negotiation phase in the SMB protocol takes care of choosing + the appropriate protocol. + + The value default refers to the higher value + of NT1 and the effective value of + . + + See for a full list + of available protocols. The values CORE, COREPLUS, LANMAN1, LANMAN2 + are silently upgraded to NT1. + + +client ipc max protocol +client min protocol +client max protocol +default +SMB3_11 + diff --git a/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml b/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml index 121eeb8..5a6c9af 100644 --- a/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml @@ -73,13 +73,16 @@ negotiation phase in the SMB protocol takes care of choosing the appropriate protocol. - The value default refers to the default protocol in each - part of the code, currently NT1 in the client tools and - SMB3_02 in winbindd. + The value default refers to NT1. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. server max protocol client min protocol +client ipc min protocol +client ipc max protocol default LANMAN1 diff --git a/docs-xml/smbdotconf/protocol/clientminprotocol.xml b/docs-xml/smbdotconf/protocol/clientminprotocol.xml index 84e03ea..052a42c 100644 --- a/docs-xml/smbdotconf/protocol/clientminprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientminprotocol.xml @@ -13,10 +13,16 @@ See client max protocol for a full list of available protocols. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. client max protocol server min protocol +client ipc min protocol +client ipc max protocol + CORE NT1 diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index f6c2cfb..6fda6d6 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2494,6 +2494,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3"); lpcfg_do_global_parameter(lp_ctx, "client min protocol", "CORE"); lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default"); lpcfg_do_global_parameter(lp_ctx, "security", "AUTO"); lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True"); lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True"); @@ -3181,6 +3183,30 @@ int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx) return client_max_protocol; } +int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx) +{ + int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx); + if (client_ipc_min_protocol == PROTOCOL_DEFAULT) { + client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx); + } + if (client_ipc_min_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_min_protocol; +} + +int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx) +{ + int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx); + if (client_ipc_max_protocol == PROTOCOL_DEFAULT) { + return PROTOCOL_LATEST; + } + if (client_ipc_max_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_max_protocol; +} + bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory) { bool allowed = true; diff --git a/source3/include/proto.h b/source3/include/proto.h index 2236af9..a78d350 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -945,6 +945,8 @@ const char *lp_idmap_default_backend (void); int lp_security(void); int lp_client_max_protocol(void); int lp_winbindd_max_protocol(void); +int lp_client_ipc_min_protocol(void); +int lp_client_ipc_max_protocol(void); int lp_smb2_max_credits(void); int lp_cups_encrypt(void); bool lp_widelinks(int ); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index ee890b0..24c0141 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -610,6 +610,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.server_min_protocol = PROTOCOL_LANMAN1; Globals._client_max_protocol = PROTOCOL_DEFAULT; Globals.client_min_protocol = PROTOCOL_CORE; + Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT; + Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT; Globals._security = SEC_AUTO; Globals.encrypt_passwords = true; Globals.client_schannel = Auto; @@ -4340,6 +4342,30 @@ int lp_winbindd_max_protocol(void) return client_max_protocol; } +int lp_client_ipc_min_protocol(void) +{ + int client_ipc_min_protocol = lp__client_ipc_min_protocol(); + if (client_ipc_min_protocol == PROTOCOL_DEFAULT) { + client_ipc_min_protocol = lp_client_min_protocol(); + } + if (client_ipc_min_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_min_protocol; +} + +int lp_client_ipc_max_protocol(void) +{ + int client_ipc_max_protocol = lp__client_ipc_max_protocol(); + if (client_ipc_max_protocol == PROTOCOL_DEFAULT) { + return PROTOCOL_LATEST; + } + if (client_ipc_max_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_max_protocol; +} + struct loadparm_global * get_globals(void) { return &Globals; -- 1.9.1 From 0198389111839469c6a2ea0631665c5960cc66ac Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 08:58:32 +0100 Subject: [PATCH 305/440] CVE-2016-2115(<=4.3): docs-xml: add "client ipc min protocol" and "client ipc max protocol" options BUG: https://bugzilla.samba.org/show_bug.cgi?id=11796 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/param/param_table.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 09d0fe9..9d12b66 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4492,6 +4492,22 @@ struct parm_struct parm_table[] = { .special = NULL, .enum_list = enum_tls_verify_peer_vals, }, + { + .label = "client ipc max protocol", + .type = P_ENUM, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(_client_ipc_max_protocol), + .special = NULL, + .enum_list = enum_protocol, + }, + { + .label = "client ipc min protocol", + .type = P_ENUM, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(_client_ipc_min_protocol), + .special = NULL, + .enum_list = enum_protocol, + }, {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0} }; -- 1.9.1 From 56ba82ec8c91248d9f5539d047f7d8d3ffed78d5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:43:58 +0100 Subject: [PATCH 306/440] CVE-2016-2115: docs-xml: add "client ipc signing" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- docs-xml/smbdotconf/security/clientipcsigning.xml | 35 +++++++++++++++++++++++ docs-xml/smbdotconf/security/clientsigning.xml | 12 ++++---- lib/param/loadparm.c | 14 +++++++++ source3/include/proto.h | 1 + source3/param/loadparm.c | 14 +++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 docs-xml/smbdotconf/security/clientipcsigning.xml diff --git a/docs-xml/smbdotconf/security/clientipcsigning.xml b/docs-xml/smbdotconf/security/clientipcsigning.xml new file mode 100644 index 0000000..d976f2d --- /dev/null +++ b/docs-xml/smbdotconf/security/clientipcsigning.xml @@ -0,0 +1,35 @@ + + + This controls whether the client is allowed or required to use SMB signing for IPC$ + connections as DCERPC transport. Possible values + are auto, mandatory + and disabled. + + + The default value is the same as the effective value of + if the effective value of + is + NT1. In any other case the default value is + mandatory. + + Note that the default value will be changed to mandatory + in all cases for Samba 4.5 + + When the effective value of this option is mandatory, SMB signing is required. + + When set to auto, SMB signing is offered, but not enforced and if set + to disabled, SMB signing is not offered either. + + Connections from winbindd to Active Directory Domain Controllers + always enforce signing. + + +client signing + +default + diff --git a/docs-xml/smbdotconf/security/clientsigning.xml b/docs-xml/smbdotconf/security/clientsigning.xml index 3b5687f..354cc53 100644 --- a/docs-xml/smbdotconf/security/clientsigning.xml +++ b/docs-xml/smbdotconf/security/clientsigning.xml @@ -9,14 +9,16 @@ and disabled. - When set to auto or default, SMB signing is offered, but not - enforced, except in winbindd, where it is enforced to Active - Directory Domain Controllers. + When set to auto or default, SMB signing is offered, but not enforced. When set to mandatory, SMB signing is required and if set - to disabled, SMB signing is not offered either. - + to disabled, SMB signing is not offered either. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. +client ipc signing + default diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 6fda6d6..13835f1 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2536,6 +2536,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U"); lpcfg_do_global_parameter(lp_ctx, "client signing", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default"); lpcfg_do_global_parameter(lp_ctx, "server signing", "default"); lpcfg_do_global_parameter(lp_ctx, "use spnego", "True"); @@ -3207,6 +3208,19 @@ int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx) return client_ipc_max_protocol; } +int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx) +{ + int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx); + if (client_ipc_signing == SMB_SIGNING_DEFAULT) { + int ipc_min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); + if (ipc_min_protocol >= PROTOCOL_SMB2_02) { + return SMB_SIGNING_REQUIRED; + } + return lpcfg_client_signing(lp_ctx); + } + return client_ipc_signing; +} + bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory) { bool allowed = true; diff --git a/source3/include/proto.h b/source3/include/proto.h index a78d350..f605202 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -947,6 +947,7 @@ int lp_client_max_protocol(void); int lp_winbindd_max_protocol(void); int lp_client_ipc_min_protocol(void); int lp_client_ipc_max_protocol(void); +int lp_client_ipc_signing(void); int lp_smb2_max_credits(void); int lp_cups_encrypt(void); bool lp_widelinks(int ); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 24c0141..1767488 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -789,6 +789,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_use_spnego = true; Globals.client_signing = SMB_SIGNING_DEFAULT; + Globals._client_ipc_signing = SMB_SIGNING_DEFAULT; Globals.server_signing = SMB_SIGNING_DEFAULT; Globals.defer_sharing_violations = true; @@ -4366,6 +4367,19 @@ int lp_client_ipc_max_protocol(void) return client_ipc_max_protocol; } +int lp_client_ipc_signing(void) +{ + int client_ipc_signing = lp__client_ipc_signing(); + if (client_ipc_signing == SMB_SIGNING_DEFAULT) { + int ipc_min_protocol = lp_client_ipc_min_protocol(); + if (ipc_min_protocol >= PROTOCOL_SMB2_02) { + return SMB_SIGNING_REQUIRED; + } + return lp_client_signing(); + } + return client_ipc_signing; +} + struct loadparm_global * get_globals(void) { return &Globals; -- 1.9.1 From 2099c2ef72f865f0d22ba2d6b32dc93a0aff3ab6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:04:37 +0100 Subject: [PATCH 307/440] CVE-2016-2115(<=4.3): docs-xml: add "client ipc signing" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=11796 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/param/param_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 9d12b66..bce4245 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4508,6 +4508,14 @@ struct parm_struct parm_table[] = { .special = NULL, .enum_list = enum_protocol, }, + { + .label = "client ipc signing", + .type = P_ENUM, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(_client_ipc_signing), + .special = NULL, + .enum_list = enum_smb_signing_vals, + }, {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0} }; -- 1.9.1 From da63c3b84bf97a29ff4f3eae77a5d8ee828d7742 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:13:11 +0100 Subject: [PATCH 308/440] CVE-2016-2115: s4:libcli/raw: add smbcli_options.min_protocol BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/raw/libcliraw.h | 1 + source4/param/loadparm.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 95e6943..8220cd7 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -95,6 +95,7 @@ struct smbcli_options { unsigned int use_spnego:1; unsigned int unicode:1; unsigned int ntstatus_support:1; + int min_protocol; int max_protocol; uint32_t max_xmit; uint16_t max_mux; diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 71331fb..f53b2dd 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -40,6 +40,7 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx, options->signing = lpcfg_client_signing(lp_ctx); options->request_timeout = SMB_REQUEST_TIMEOUT; options->ntstatus_support = lpcfg_nt_status_support(lp_ctx); + options->min_protocol = lpcfg_client_min_protocol(lp_ctx); options->max_protocol = lpcfg__client_max_protocol(lp_ctx); options->unicode = lpcfg_unicode(lp_ctx); options->use_oplocks = true; -- 1.9.1 From a1fe66b5848587348a3ca927e8df37006c69bb78 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:14:39 +0100 Subject: [PATCH 309/440] CVE-2016-2115: s4:libcli/smb2: use the configured min_protocol BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/smb2/connect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 9535380..1a6ae34 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -134,6 +134,7 @@ static void smb2_connect_socket_done(struct composite_context *creq) struct tevent_req *subreq; NTSTATUS status; uint32_t timeout_msec; + enum protocol_types min_protocol; status = smbcli_sock_connect_recv(creq, state, &sock); if (tevent_req_nterror(req, status)) { @@ -146,10 +147,14 @@ static void smb2_connect_socket_done(struct composite_context *creq) } timeout_msec = state->transport->options.request_timeout * 1000; + min_protocol = state->transport->options.min_protocol; + if (min_protocol < PROTOCOL_SMB2_02) { + min_protocol = PROTOCOL_SMB2_02; + } subreq = smbXcli_negprot_send(state, state->ev, state->transport->conn, timeout_msec, - PROTOCOL_SMB2_02, + min_protocol, state->transport->options.max_protocol); if (tevent_req_nomem(subreq, req)) { return; -- 1.9.1 From 589f50b8225d60524adb1f98807aba8356ed6b50 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 310/440] CVE-2016-2115: s4:libcli/raw: limit maxprotocol to NT1 in smb_raw_negotiate*() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/raw/rawnegotiate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 9b0ed38..32e8a91 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -51,6 +51,10 @@ struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, } state->transport = transport; + if (maxprotocol > PROTOCOL_NT1) { + maxprotocol = PROTOCOL_NT1; + } + subreq = smbXcli_negprot_send(state, ev, transport->conn, timeout_msec, -- 1.9.1 From f62e7f7e47780ee186c651c961da279de2635c55 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 311/440] CVE-2016-2115: s4:libcli/raw: pass the minprotocol to smb_raw_negotiate*() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/cliconnect.c | 2 +- source4/libcli/raw/rawnegotiate.c | 7 +++++-- source4/libcli/smb_composite/connect.c | 1 + source4/torture/basic/base.c | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 1715192..35d963e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -77,7 +77,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) return NT_STATUS_NO_MEMORY; } - return smb_raw_negotiate(cli->transport, unicode, maxprotocol); + return smb_raw_negotiate(cli->transport, unicode, PROTOCOL_CORE, maxprotocol); } /* wrapper around smb_raw_sesssetup() */ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 32e8a91..4b42c26 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -37,6 +37,7 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq); struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbcli_transport *transport, + int minprotocol, int maxprotocol) { struct tevent_req *req; @@ -58,7 +59,7 @@ struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, subreq = smbXcli_negprot_send(state, ev, transport->conn, timeout_msec, - PROTOCOL_CORE, + minprotocol, maxprotocol); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -131,7 +132,8 @@ NTSTATUS smb_raw_negotiate_recv(struct tevent_req *req) /* Send a negprot command (sync interface) */ -NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int maxprotocol) +NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, + int minprotocol, int maxprotocol) { NTSTATUS status = NT_STATUS_INTERNAL_ERROR; struct tevent_req *subreq = NULL; @@ -140,6 +142,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int subreq = smb_raw_negotiate_send(transport, transport->ev, transport, + minprotocol, maxprotocol); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index d87d5ec..fffa768 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -297,6 +297,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, state->subreq = smb_raw_negotiate_send(state, state->transport->ev, state->transport, + state->transport->options.min_protocol, state->transport->options.max_protocol); NT_STATUS_HAVE_NO_MEMORY(state->subreq); tevent_req_set_callback(state->subreq, subreq_handler, c); diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index 5d4efc7..01ac170 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -371,6 +371,7 @@ static bool run_negprot_nowait(struct torture_context *tctx) struct tevent_req *req; req = smb_raw_negotiate_send(cli, tctx->ev, cli->transport, + PROTOCOL_CORE, PROTOCOL_NT1); tevent_loop_once(tctx->ev); if (!tevent_req_is_in_progress(req)) { -- 1.9.1 From b0b2ecc052a023186b2dfc2ad466a83ca98b5167 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Mar 2014 13:44:29 +0100 Subject: [PATCH 312/440] CVE-2016-2115: s4:librpc/rpc: make use of "client ipc *" options for ncacn_np BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/librpc/rpc/dcerpc_connect.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 9c5dbeb..8ed1257 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -183,6 +183,11 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT conn->in.fallback_to_anonymous = false; } + conn->in.options.min_protocol = PROTOCOL_NT1; + conn->in.options.max_protocol = PROTOCOL_NT1; + + conn->in.options.signing = lpcfg_client_ipc_signing(lp_ctx); + /* send smb connect request */ conn_req = smb_composite_connect_send(conn, s->io.conn, s->io.resolve_ctx, @@ -277,6 +282,17 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( lpcfg_smbcli_options(lp_ctx, &options); + options.min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); + if (options.min_protocol < PROTOCOL_SMB2_02) { + options.min_protocol = PROTOCOL_SMB2_02; + } + options.max_protocol = lpcfg_client_ipc_max_protocol(lp_ctx); + if (options.max_protocol < PROTOCOL_SMB2_02) { + options.max_protocol = PROTOCOL_SMB2_02; + } + + options.signing = lpcfg_client_ipc_signing(lp_ctx); + /* send smb2 connect request */ subreq = smb2_connect_send(s, c->event_ctx, host, @@ -773,6 +789,7 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st struct composite_context *ncacn_unix_req; struct composite_context *ncalrpc_req; enum dcerpc_transport_t transport; + enum protocol_types min_ipc_protocol; uint32_t flags; /* dcerpc pipe connect input parameters */ @@ -786,6 +803,11 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st transport = dcerpc_binding_get_transport(s->binding); flags = dcerpc_binding_get_flags(s->binding); + min_ipc_protocol = lpcfg_client_ipc_min_protocol(s->lp_ctx); + if (min_ipc_protocol >= PROTOCOL_SMB2_02) { + flags |= DCERPC_SMB2; + } + /* connect dcerpc pipe depending on required transport */ switch (transport) { case NCACN_NP: -- 1.9.1 From 6bb75aeab48785e77cca8e64d64ab82eb814c559 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:23:58 +0100 Subject: [PATCH 313/440] CVE-2016-2115: s3:winbindd: use lp_client_ipc_{min,max}_protocol() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/include/proto.h | 1 - source3/param/loadparm.c | 9 --------- source3/winbindd/winbindd_cm.c | 4 ++-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index f605202..be90024 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -944,7 +944,6 @@ const char *lp_idmap_backend(const char *domain_name); const char *lp_idmap_default_backend (void); int lp_security(void); int lp_client_max_protocol(void); -int lp_winbindd_max_protocol(void); int lp_client_ipc_min_protocol(void); int lp_client_ipc_max_protocol(void); int lp_client_ipc_signing(void); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 1767488..09dc217 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4334,15 +4334,6 @@ int lp_client_max_protocol(void) return client_max_protocol; } -int lp_winbindd_max_protocol(void) -{ - int client_max_protocol = lp__client_max_protocol(); - if (client_max_protocol == PROTOCOL_DEFAULT) { - return PROTOCOL_LATEST; - } - return client_max_protocol; -} - int lp_client_ipc_min_protocol(void) { int client_ipc_min_protocol = lp__client_ipc_min_protocol(); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index cbce0c4..e0e905d 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -935,8 +935,8 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, cli_set_timeout(*cli, 10000); /* 10 seconds */ result = smbXcli_negprot((*cli)->conn, (*cli)->timeout, - lp_client_min_protocol(), - lp_winbindd_max_protocol()); + lp_client_ipc_min_protocol(), + lp_client_ipc_max_protocol()); if (!NT_STATUS_IS_OK(result)) { DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result))); -- 1.9.1 From 18075486800258e6f58b89880e1d582a73c15f3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 13:22:16 +0100 Subject: [PATCH 314/440] CVE-2016-2115: s3:winbindd: use lp_client_ipc_signing() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index e0e905d..63175e5 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -882,7 +882,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - enum smb_signing_setting smb_sign_client_connections = lp_client_signing(); + enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing(); if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) { /* -- 1.9.1 From 7c288ee8755d5bcfa0aeb39cd05ad719e055e6a5 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 09:55:37 +0100 Subject: [PATCH 315/440] CVE-2016-2115: s3:libsmb: add signing constant SMB_SIGNING_IPC_DEFAULT SMB_SIGNING_IPC_DEFAULT must be used from s3 client code when opening RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/param/loadparm.c | 5 ++++- libcli/smb/smbXcli_base.c | 1 + libcli/smb/smb_constants.h | 1 + source3/libsmb/clientgen.c | 9 +++++++++ source4/smb_server/smb2/negprot.c | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 13835f1..b2159b6 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3255,10 +3255,13 @@ bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandato case SMB_SIGNING_DESIRED: case SMB_SIGNING_IF_REQUIRED: break; - case SMB_SIGNING_DEFAULT: case SMB_SIGNING_OFF: allowed = false; break; + case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_IPC_DEFAULT: + smb_panic(__location__); + break; } return allowed; diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index b00afbc..7bf48c8 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -363,6 +363,7 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, conn->desire_signing = true; conn->mandatory_signing = false; break; + case SMB_SIGNING_IPC_DEFAULT: case SMB_SIGNING_REQUIRED: /* always */ conn->allow_signing = true; diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index 9b57078..c68c9b3 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -93,6 +93,7 @@ enum protocol_types { #define PROTOCOL_LATEST PROTOCOL_SMB3_02 enum smb_signing_setting { + SMB_SIGNING_IPC_DEFAULT = -2, /* Only used in C code */ SMB_SIGNING_DEFAULT = -1, SMB_SIGNING_OFF = 0, SMB_SIGNING_IF_REQUIRED = 1, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6bed510..79e1392 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -231,6 +231,15 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, use_level_II_oplocks = true; } + if (signing_state == SMB_SIGNING_IPC_DEFAULT) { + /* + * Ensure for IPC/RPC the default is to require + * signing unless explicitly turned off by the + * administrator. + */ + signing_state = lp_client_ipc_signing(); + } + if (signing_state == SMB_SIGNING_DEFAULT) { signing_state = lp_client_signing(); } diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index e654392..addd278 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -147,6 +147,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 switch (signing_setting) { case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_IPC_DEFAULT: smb_panic(__location__); break; case SMB_SIGNING_OFF: -- 1.9.1 From ab578edb192657d5005d32137a3d999574fb4596 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 17:16:04 +0100 Subject: [PATCH 316/440] CVE-2016-2115: s3:libsmb: let SMB_SIGNING_IPC_DEFAULT use "client ipc min/max protocol" We need NT1 => LATEST in order to work against all servers which support DCERPC over ncacn_np. This is a mini step in using SMB2/3 in our client side by default. This gives us a higher chance that SMB signing is supported by the server (as it can't be turned off for SMB2 and higher). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/libsmb/cliconnect.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4d0d2f2..039fba2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3178,6 +3178,8 @@ fail: struct cli_start_connection_state { struct tevent_context *ev; struct cli_state *cli; + int min_protocol; + int max_protocol; }; static void cli_start_connection_connected(struct tevent_req *subreq); @@ -3207,6 +3209,14 @@ static struct tevent_req *cli_start_connection_send( } state->ev = ev; + if (signing_state == SMB_SIGNING_IPC_DEFAULT) { + state->min_protocol = lp_client_ipc_min_protocol(); + state->max_protocol = lp_client_ipc_max_protocol(); + } else { + state->min_protocol = lp_client_min_protocol(); + state->max_protocol = lp_client_max_protocol(); + } + subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port, 0x20, my_name, signing_state, flags); if (tevent_req_nomem(subreq, req)) { @@ -3232,8 +3242,8 @@ static void cli_start_connection_connected(struct tevent_req *subreq) subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn, state->cli->timeout, - lp_client_min_protocol(), - lp_client_max_protocol()); + state->min_protocol, + state->max_protocol); if (tevent_req_nomem(subreq, req)) { return; } -- 1.9.1 From 735abbbd51a459ee46c014f359d6fc7ba3ab68f2 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:00:09 +0100 Subject: [PATCH 317/440] CVE-2016-2115: net: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/utils/net_ads.c | 2 +- source3/utils/net_rpc.c | 2 +- source3/utils/net_util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 5f18bf4..3d7d8a1 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1907,7 +1907,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * c->opt_user_name, c->opt_workgroup, c->opt_password ? c->opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (NT_STATUS_IS_ERR(nt_status)) { d_fprintf(stderr, _("Unable to open a connection to %s to " diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index cd17b2c..8f65a73 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -7395,7 +7395,7 @@ bool net_rpc_check(struct net_context *c, unsigned flags) return false; status = cli_connect_nb(server_name, &server_ss, 0, 0x20, - lp_netbios_name(), SMB_SIGNING_DEFAULT, + lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT, 0, &cli); if (!NT_STATUS_IS_OK(status)) { return false; diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 13a0ef1..de929ff 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -126,7 +126,7 @@ NTSTATUS connect_to_service(struct net_context *c, service_name, service_type, c->opt_user_name, c->opt_workgroup, c->opt_password, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Could not connect to server %s\n"), server_name); -- 1.9.1 From cbaabb050629e06d8169e530f7ccaa3e7c2dcb66 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:01:59 +0100 Subject: [PATCH 318/440] CVE-2016-2115: s3:lib/netapi: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/lib/netapi/cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 801e61f..e9f2863 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -88,7 +88,7 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, if (!auth_info) { return WERR_NOMEM; } - auth_info->signing_state = SMB_SIGNING_DEFAULT; + auth_info->signing_state = SMB_SIGNING_IPC_DEFAULT; set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos); set_cmdline_auth_info_username(auth_info, ctx->username); if (ctx->password) { -- 1.9.1 From 3d55817c390575a2e79ac5a2a657968e754675e6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:13 +0100 Subject: [PATCH 319/440] CVE-2016-2115: s3:auth_domain: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/auth/auth_domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index c3c54f3..b101625 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -98,7 +98,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli_ret, /* Attempt connection */ result = cli_full_connection(&cli, lp_netbios_name(), dc_name, dc_ss, 0, - "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_DEFAULT); + "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ -- 1.9.1 From de045b16fc39c4f0c160996840425e9e0000d13b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:52 +0100 Subject: [PATCH 320/440] CVE-2016-2115: s3:libnet: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 187e524..d7c7679 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -846,7 +846,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc, domain, pass, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); } /**************************************************************** @@ -1407,7 +1407,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, netbios_domain_name, machine_password, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); E_md4hash(machine_password, current_nt_hash.hash); SAFE_FREE(machine_password); @@ -1421,7 +1421,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, NULL, "", 0, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); } if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From 7662214006b3b5bc53f3e63bb7073cbc5b5c511a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:04:35 +0100 Subject: [PATCH 321/440] CVE-2016-2115: s3:libsmb: use SMB_SIGNING_IPC_DEFAULT and lp_client_ipc_{min,max}_protocol() Use SMB_SIGNING_IPC_DEFAULT and lp_client_ipc_{min,max}_protocol() for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/libsmb/passchange.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 9736ada..3b87676 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -57,7 +57,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam *err_str = NULL; result = cli_connect_nb(remote_machine, NULL, 0, 0x20, NULL, - SMB_SIGNING_DEFAULT, 0, &cli); + SMB_SIGNING_IPC_DEFAULT, 0, &cli); if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "Unable to connect to SMB server on " "machine %s. Error was : %s.\n", @@ -67,8 +67,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return result; } - result = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE, - PROTOCOL_NT1); + result = smbXcli_negprot(cli->conn, cli->timeout, + lp_client_ipc_min_protocol(), + lp_client_ipc_max_protocol()); if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "machine %s rejected the negotiate " -- 1.9.1 From d29b9962914a9bad5ae196838020571b2d413818 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 23:52:30 +0100 Subject: [PATCH 322/440] CVE-2016-2115: docs-xml: always default "client ipc signing" to "mandatory" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/clientipcsigning.xml | 11 +---------- lib/param/loadparm.c | 6 +----- source3/param/loadparm.c | 6 +----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/docs-xml/smbdotconf/security/clientipcsigning.xml b/docs-xml/smbdotconf/security/clientipcsigning.xml index d976f2d..0881c6c 100644 --- a/docs-xml/smbdotconf/security/clientipcsigning.xml +++ b/docs-xml/smbdotconf/security/clientipcsigning.xml @@ -11,16 +11,7 @@ and disabled. - The default value is the same as the effective value of - if the effective value of - is - NT1. In any other case the default value is - mandatory. - - Note that the default value will be changed to mandatory - in all cases for Samba 4.5 - - When the effective value of this option is mandatory, SMB signing is required. + When set to mandatory or default, SMB signing is required. When set to auto, SMB signing is offered, but not enforced and if set to disabled, SMB signing is not offered either. diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index b2159b6..8c2a371 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3212,11 +3212,7 @@ int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx) { int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx); if (client_ipc_signing == SMB_SIGNING_DEFAULT) { - int ipc_min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); - if (ipc_min_protocol >= PROTOCOL_SMB2_02) { - return SMB_SIGNING_REQUIRED; - } - return lpcfg_client_signing(lp_ctx); + return SMB_SIGNING_REQUIRED; } return client_ipc_signing; } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 09dc217..cfbc196 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4362,11 +4362,7 @@ int lp_client_ipc_signing(void) { int client_ipc_signing = lp__client_ipc_signing(); if (client_ipc_signing == SMB_SIGNING_DEFAULT) { - int ipc_min_protocol = lp_client_ipc_min_protocol(); - if (ipc_min_protocol >= PROTOCOL_SMB2_02) { - return SMB_SIGNING_REQUIRED; - } - return lp_client_signing(); + return SMB_SIGNING_REQUIRED; } return client_ipc_signing; } -- 1.9.1 From 1b99e87707d4448d3a35da506adb6d74b6fdde39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:12:18 +0200 Subject: [PATCH 323/440] CVE-2016-2118: s4:rpc_server: make it possible to define a min_auth_level on a presentation context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 60 ++++++++++++++++++++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 9 ++++++ 2 files changed, 69 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b1c763b..5828baa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -510,6 +510,35 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context return 0; } +static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) +{ + struct dcesrv_connection_context *context = dce_call->context; + + context->min_auth_level = DCERPC_AUTH_LEVEL_NONE; +} + +NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + if (dce_call->context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; + return NT_STATUS_OK; +} + +NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + if (dce_call->context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; + return NT_STATUS_OK; +} + /* handle a bind request */ @@ -597,6 +626,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) call->context = context; talloc_set_destructor(context, dcesrv_connection_context_destructor); + dcesrv_prepare_context_auth(call); + status = iface->bind(call, iface, if_version); if (!NT_STATUS_IS_OK(status)) { char *uuid_str = GUID_string(call, &uuid); @@ -781,6 +812,8 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ call->context = context; talloc_set_destructor(context, dcesrv_connection_context_destructor); + dcesrv_prepare_context_auth(call); + status = iface->bind(call, iface, if_version); if (!NT_STATUS_IS_OK(status)) { /* we don't want to trigger the iface->unbind() hook */ @@ -982,9 +1015,14 @@ done: */ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { + const struct dcesrv_endpoint *endpoint = call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct ndr_pull *pull; NTSTATUS status; struct dcesrv_connection_context *context; + uint32_t auth_type = DCERPC_AUTH_TYPE_NONE; + uint32_t auth_level = DCERPC_AUTH_LEVEL_NONE; /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && @@ -997,6 +1035,28 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } + if (call->conn->auth_state.auth_info != NULL) { + auth_type = call->conn->auth_state.auth_info->auth_type; + auth_level = call->conn->auth_state.auth_info->auth_level; + } + + if (auth_level < context->min_auth_level) { + char *addr; + + addr = tsocket_address_string(call->conn->remote_address, call); + + DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, + context->min_auth_level, + context->iface->name, + auth_type, auth_level, + derpc_transport_string_by_transport(transport), + addr)); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); NT_STATUS_HAVE_NO_MEMORY(pull); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 8786cd8..3e40710 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -168,6 +168,11 @@ struct dcesrv_connection_context { /* private data for the interface implementation */ void *private_data; + + /* + * the minimum required auth level for this interface + */ + enum dcerpc_AuthLevel min_auth_level; }; @@ -407,5 +412,9 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call); */ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); #endif /* SAMBA_DCERPC_SERVER_H */ -- 1.9.1 From d268667e8a9eb630e0438bac2e9e6e8d619c6996 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 324/440] CVE-2016-2118: s4:rpc_server/drsuapi: require DCERPC_AUTH_LEVEL_PRIVACY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches windows and prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 2 ++ source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 8 ++++++++ source4/selftest/tests.py | 9 ++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index bb548ba..e95d048 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -101,6 +101,8 @@ ^samba4.rpc.netlogon.*.GetTrustPasswords ^samba4.rpc.netlogon.*.DatabaseRedo ^samba4.rpc.netlogon.*.ServerGetTrustInfo +^samba4.rpc.drsuapi.*ncacn_ip_tcp.*validate # should only work with seal +^samba4.rpc.drsuapi.*ncacn_ip_tcp.*bigendian # should only work with seal ^samba4.base.charset.*.Testing partial surrogate ^samba4.*.base.maximum_allowed # broken until we implement NTCREATEX_OPTIONS_BACKUP_INTENT .*net.api.delshare.* # DelShare isn't implemented yet diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 879f63f..c28f557 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -39,6 +39,14 @@ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \ } while (0) +#define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \ + dcesrv_interface_drsuapi_bind(call, iface) +static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_privacy(dce_call, iface); +} + /* drsuapi_DsBind */ diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 793423e..295b719 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -138,9 +138,9 @@ else: # add tests to this list as they start passing, so we test # that they stay passing ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] -ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] +ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") -ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests +ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.drsuapi", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] @@ -190,7 +190,10 @@ for transport in ["ncacn_np", "ncacn_ip_tcp"]: else: raise AssertionError("Invalid transport %r" % transport) for t in tests: - plansmbtorture4testsuite(t, env, ["%s:$SERVER" % transport, '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.%s on %s" % (t, transport)) + bindoptions = '' + if t == 'rpc.cracknames': + bindoptions = 'seal' + plansmbtorture4testsuite(t, env, ["%s:$SERVER[%s]" % (transport,bindoptions), '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.%s on %s with %s" % (t, transport, bindoptions)) # Tests for the DFS referral calls implementation for t in smbtorture4_testsuites("dfs."): -- 1.9.1 From 8285fca2fbd04e579cb25b76791d4f69a5d1a60a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 325/440] CVE-2016-2118: s4:rpc_server/backupkey: require DCERPC_AUTH_LEVEL_PRIVACY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required for the whole interface (which has just one opnum for now). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/backupkey/dcesrv_backupkey.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index 9dea3d6..4037d18 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -54,6 +54,14 @@ static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = { { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL }; +#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ + dcesrv_interface_backupkey_bind(call, iface) +static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_privacy(dce_call, iface); +} + static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *name, @@ -1791,11 +1799,6 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, return WERR_NOT_SUPPORTED; } - if (!dce_call->conn->auth_state.auth_info || - dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { - DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); - } - ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); -- 1.9.1 From 20732f9a50f6e4d1bf1b203d0e3f44b5518554d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 22:15:00 +0100 Subject: [PATCH 326/440] CVE-2016-2118: python:tests/dcerpc: use [sign] for dnsserver tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- python/samba/tests/dcerpc/dnsserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py index 2b421d0..7229877 100644 --- a/python/samba/tests/dcerpc/dnsserver.py +++ b/python/samba/tests/dcerpc/dnsserver.py @@ -27,7 +27,7 @@ class DnsserverTests(RpcInterfaceTestCase): super(DnsserverTests, self).setUp() self.server = env_get_var_value("SERVER_IP") self.zone = env_get_var_value("REALM").lower() - self.conn = dnsserver.dnsserver("ncacn_ip_tcp:%s" % (self.server), + self.conn = dnsserver.dnsserver("ncacn_ip_tcp:%s[sign]" % (self.server), self.get_loadparm(), self.get_credentials()) -- 1.9.1 From 188fa58106482e65ff864bb5668caf94e5ae1925 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 04:06:04 +0100 Subject: [PATCH 327/440] CVE-2016-2118: s4:rpc_server/dnsserver: require at least DCERPC_AUTH_LEVEL_INTEGRITY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches windows and prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index be31500..7571756 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -28,6 +28,14 @@ #include "dnsserver.h" #include "lib/ldb/include/ldb_private.h" +#define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \ + dcesrv_interface_dnsserver_bind(call, iface) +static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_integrity(dce_call, iface); +} + struct dnsserver_state { struct loadparm_context *lp_ctx; struct ldb_context *samdb; -- 1.9.1 From 179c5499679f70fe0ebe42f22bb6461262764854 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 328/440] CVE-2016-2118: s3: rpcclient: change the default auth level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- source3/rpcclient/rpcclient.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index ac7576f..a35e422 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1110,10 +1110,9 @@ out_free: } } if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) { - /* If neither Integrity or Privacy are requested then - * Use just Connect level */ + /* If nothing is requested then default to integrity */ if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) { - pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT; + pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; } } -- 1.9.1 From f110f81f56b60c42adc715a0be39166d07631096 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 329/440] CVE-2016-2118: librpc: change the default auth level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- librpc/rpc/binding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c index 37e0c4f..6407a8d 100644 --- a/librpc/rpc/binding.c +++ b/librpc/rpc/binding.c @@ -591,7 +591,7 @@ _PUBLIC_ void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b, } else if (b->flags & DCERPC_CONNECT) { auth_level = DCERPC_AUTH_LEVEL_CONNECT; } else if (auth_type != DCERPC_AUTH_TYPE_NONE) { - auth_level = DCERPC_AUTH_LEVEL_CONNECT; + auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; } else { auth_level = DCERPC_AUTH_LEVEL_NONE; } -- 1.9.1 From 731c12ce392b718c9f0406ef06560905f52fbe98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 16:02:25 +0100 Subject: [PATCH 330/440] CVE-2016-2118: s4:librpc: use integrity by default for authenticated binds ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- source4/librpc/rpc/dcerpc_util.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 95d600a34..d775750 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -662,15 +662,15 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, /* Perform an authenticated DCE-RPC bind */ - if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) { + if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) { /* we are doing an authenticated connection, - but not using sign or seal. We must force - the CONNECT dcerpc auth type as a NONE auth - type doesn't allow authentication - information to be passed. + which needs to use [connect], [sign] or [seal]. + If nothing is specified, we default to [sign] now. + This give roughly the same protection as + ncacn_np with smb signing. */ - conn->flags |= DCERPC_CONNECT; + conn->flags |= DCERPC_SIGN; } if (conn->flags & DCERPC_AUTH_SPNEGO) { -- 1.9.1 From 15a5b8aca170162c155e1feaae4f307ea8eefe05 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 331/440] CVE-2016-2118: docs-xml: add "allow dcerpc auth level connect" defaulting to "yes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We sadly need to allow this for now by default. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- .../security/allowdcerpcauthlevelconnect.xml | 29 ++++++++++++++++++++++ lib/param/loadparm.c | 2 ++ source3/param/loadparm.c | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml new file mode 100644 index 0000000..27a9733 --- /dev/null +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml @@ -0,0 +1,29 @@ + + + This option controls whether DCERPC services are allowed to + be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication, + but no per message integrity nor privacy protection. + + Some interfaces like samr, lsarpc and netlogon have a hard-coded default of + no and epmapper, mgmt and rpcecho have a hard-coded default of + yes. + + + The behavior can be overwritten per interface name (e.g. lsarpc, netlogon, samr, srvsvc, + winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = yes' as option. + + This option yields precedence to the implementation specific restrictions. + E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY. + The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY. + + + Note the default will very likely change to no for Samba 4.5. + + +yes +no + + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 8c2a371..fca1fe8 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2514,6 +2514,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); + lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "True"); + lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index cfbc196..0ec8c97 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -667,6 +667,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ + Globals.allow_dcerpc_auth_level_connect = true; /* we need to allow this for now by default */ + Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ Globals.enhanced_browsing = true; -- 1.9.1 From 82d713d2211b6db9b5b868245c76797f7167f16f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 08:45:11 +0100 Subject: [PATCH 332/440] CVE-2016-2118(<=4.3) docs-xml: add "allow dcerpc auth level connect" defaulting to "yes" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/param/param_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index bce4245..4bc9198 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4516,6 +4516,14 @@ struct parm_struct parm_table[] = { .special = NULL, .enum_list = enum_smb_signing_vals, }, + { + .label = "allow dcerpc auth level connect", + .type = P_BOOL, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(allow_dcerpc_auth_level_connect), + .special = NULL, + .enum_list = NULL + }, {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0} }; -- 1.9.1 From 5567d469988bc9eb4454d72cbdf41ec5d4b5c410 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 02:46:59 +0100 Subject: [PATCH 333/440] CVE-2016-2118: s4:rpc_server: make use of "allow dcerpc auth level connect" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this option turned off we only allow DCERPC_AUTH_LEVEL_{NONE,INTEGRITY,PRIVACY}, this means the reject any request with AUTH_LEVEL_CONNECT with ACCESS_DENIED. We sadly need to keep this enabled by default for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 104 +++++++++++++++++++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 5 ++ 2 files changed, 109 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5828baa..6da6691 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -512,9 +512,29 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) { + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct dcesrv_connection_context *context = dce_call->context; + const struct dcesrv_interface *iface = context->iface; context->min_auth_level = DCERPC_AUTH_LEVEL_NONE; + + if (transport == NCALRPC) { + context->allow_connect = true; + return; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx); + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); } NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, @@ -539,6 +559,66 @@ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_cal return NT_STATUS_OK; } +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); + struct dcesrv_connection_context *context = dce_call->context; + + if (context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (transport == NCALRPC) { + context->allow_connect = true; + return NT_STATUS_OK; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = false; + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); + struct dcesrv_connection_context *context = dce_call->context; + + if (context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (transport == NCALRPC) { + context->allow_connect = true; + return NT_STATUS_OK; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = true; + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); + return NT_STATUS_OK; +} + /* handle a bind request */ @@ -1040,6 +1120,30 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) auth_level = call->conn->auth_state.auth_info->auth_level; } + switch (auth_level) { + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + break; + default: + if (!context->allow_connect) { + char *addr; + + addr = tsocket_address_string(call->conn->remote_address, + call); + + DEBUG(2, ("%s: restrict auth_level_connect access " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, context->iface->name, + auth_type, auth_level, + derpc_transport_string_by_transport(transport), + addr)); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + break; + } + if (auth_level < context->min_auth_level) { char *addr; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 3e40710..894b2c9 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -173,6 +173,7 @@ struct dcesrv_connection_context { * the minimum required auth level for this interface */ enum dcerpc_AuthLevel min_auth_level; + bool allow_connect; }; @@ -416,5 +417,9 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_sta const struct dcesrv_interface *iface); _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); #endif /* SAMBA_DCERPC_SERVER_H */ -- 1.9.1 From 92fecbb18551a8638523d4bd397e172cca90200e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 334/440] CVE-2016-2118: s4:rpc_server/lsa: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/lsa/dcesrv_lsa.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 53b937e..0218d9d 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -33,6 +33,14 @@ #include "libcli/security/session.h" #include "libcli/lsarpc/util_lsarpc.h" +#define DCESRV_INTERFACE_LSARPC_BIND(call, iface) \ + dcesrv_interface_lsarpc_bind(call, iface) +static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + /* this type allows us to distinguish handle types */ -- 1.9.1 From 854f34a95a88b88e110d6380f8a77a352f322cd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 335/440] CVE-2016-2118: s4:rpc_server/samr: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 2 ++ source4/rpc_server/samr/dcesrv_samr.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index e95d048..fc711ba 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -103,6 +103,8 @@ ^samba4.rpc.netlogon.*.ServerGetTrustInfo ^samba4.rpc.drsuapi.*ncacn_ip_tcp.*validate # should only work with seal ^samba4.rpc.drsuapi.*ncacn_ip_tcp.*bigendian # should only work with seal +^samba4.rpc.samr.passwords.validate.*ncacn_ip_tcp.*with.validate # should only work with seal +^samba4.rpc.samr.passwords.validate.*ncacn_ip_tcp.*with.bigendian # should only work with seal ^samba4.base.charset.*.Testing partial surrogate ^samba4.*.base.maximum_allowed # broken until we implement NTCREATEX_OPTIONS_BACKUP_INTENT .*net.api.delshare.* # DelShare isn't implemented yet diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 8c34e30..3f76378 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -41,6 +41,14 @@ #include "lib/util/tsort.h" #include "libds/common/flag_mapping.h" +#define DCESRV_INTERFACE_SAMR_BIND(call, iface) \ + dcesrv_interface_samr_bind(call, iface) +static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + /* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ #define QUERY_STRING(msg, field, attr) \ -- 1.9.1 From f733c8cb0baaec82888b099b70657032d1e5ee3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:52:48 +0200 Subject: [PATCH 336/440] CVE-2016-2118: s4:rpc_server/netlogon: reject DCERPC_AUTH_LEVEL_CONNECT by default This prevents man in the middle downgrade attacks. Signed-off-by: Stefan Metzmacher --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 14811b5..919945e 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -41,6 +41,14 @@ #include "librpc/gen_ndr/ndr_irpc.h" #include "lib/socket/netif.h" +#define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ + dcesrv_interface_netlogon_bind(call, iface) +static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + static struct memcache *global_challenge_table; struct netlogon_server_pipe_state { -- 1.9.1 From 84fd973827ae9c4769bc6ecb41886533087cd41b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:17:40 +0100 Subject: [PATCH 337/440] CVE-2016-2118: s4:rpc_server/epmapper: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/epmapper/rpc_epmapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c index 62627ce..6b934d7 100644 --- a/source4/rpc_server/epmapper/rpc_epmapper.c +++ b/source4/rpc_server/epmapper/rpc_epmapper.c @@ -24,6 +24,14 @@ #include "librpc/gen_ndr/ndr_epmapper.h" #include "rpc_server/dcerpc_server.h" +#define DCESRV_INTERFACE_EPMAPPER_BIND(call, iface) \ + dcesrv_interface_epmapper_bind(call, iface) +static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} + typedef uint32_t error_status_t; /* handle types for this module */ -- 1.9.1 From f7d9c74d5d7b9c8f25c1452aefb952e838b74b7f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:18:42 +0100 Subject: [PATCH 338/440] CVE-2016-2118: s4:rpc_server/mgmt: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/dcesrv_mgmt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/dcesrv_mgmt.c b/source4/rpc_server/dcesrv_mgmt.c index 8c4eb63..4d3428d 100644 --- a/source4/rpc_server/dcesrv_mgmt.c +++ b/source4/rpc_server/dcesrv_mgmt.c @@ -23,6 +23,14 @@ #include "rpc_server/dcerpc_server.h" #include "librpc/gen_ndr/ndr_mgmt.h" +#define DCESRV_INTERFACE_MGMT_BIND(call, iface) \ + dcesrv_interface_mgmt_bind(call, iface) +static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} + /* mgmt_inq_if_ids */ -- 1.9.1 From b5782574636deeb7433586457e5744131d8bbdfd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:19:04 +0100 Subject: [PATCH 339/440] CVE-2016-2118: s4:rpc_server/rpcecho: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/echo/rpc_echo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/echo/rpc_echo.c b/source4/rpc_server/echo/rpc_echo.c index 4863c77..49c9e23 100644 --- a/source4/rpc_server/echo/rpc_echo.c +++ b/source4/rpc_server/echo/rpc_echo.c @@ -26,6 +26,13 @@ #include "librpc/gen_ndr/ndr_echo.h" #include "lib/events/events.h" +#define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \ + dcesrv_interface_rpcecho_bind(call, iface) +static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} static NTSTATUS dcesrv_echo_AddOne(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_AddOne *r) { -- 1.9.1 From b2a749d14fe43600757f620af8c9812f52ef3829 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Mar 2016 04:40:30 +0100 Subject: [PATCH 340/440] CVE-2016-2118: s3:rpc_server: make use of "allow dcerpc auth level connect" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this option turned off we only allow DCERPC_AUTH_LEVEL_{NONE,INTEGRITY,PRIVACY}, this means the reject any request with AUTH_LEVEL_CONNECT with ACCESS_DENIED. We sadly need to keep this enabled by default for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Pair-Programmed-With: Günther Deschner Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner --- source3/rpc_server/rpc_ncacn_np.c | 2 +- source3/rpc_server/rpc_pipes.h | 4 +++ source3/rpc_server/srv_pipe.c | 56 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index d504847..5514956 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -224,7 +224,7 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, return NULL; } - context_fns = talloc(p, struct pipe_rpc_fns); + context_fns = talloc_zero(p, struct pipe_rpc_fns); if (context_fns == NULL) { DEBUG(0,("talloc() failed!\n")); TALLOC_FREE(p); diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index e65209a..14b8705 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -94,6 +94,10 @@ struct pipe_rpc_fns { uint32_t context_id; struct ndr_syntax_id syntax; + /* + * shall we allow "connect" auth level for this interface ? + */ + bool allow_connect; }; /* diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4ffaa0d..4902676 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -44,6 +44,7 @@ #include "librpc/ndr/ndr_table.h" #include "auth/gensec/gensec.h" #include "librpc/ndr/ndr_dcerpc.h" +#include "lib/tsocket/tsocket.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -338,6 +339,7 @@ static bool check_bind_req(struct pipes_struct *p, { struct pipe_rpc_fns *context_fns; bool ok; + const char *interface_name = NULL; DEBUG(3,("check_bind_req for %s\n", ndr_interface_name(&abstract->uuid, @@ -359,18 +361,34 @@ static bool check_bind_req(struct pipes_struct *p, return false; } - context_fns = talloc(p, struct pipe_rpc_fns); + context_fns = talloc_zero(p, struct pipe_rpc_fns); if (context_fns == NULL) { DEBUG(0,("check_bind_req: talloc() failed!\n")); return false; } + interface_name = ndr_interface_name(&abstract->uuid, + abstract->if_version); + SMB_ASSERT(interface_name != NULL); + context_fns->next = context_fns->prev = NULL; context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract); context_fns->cmds = rpc_srv_get_pipe_cmds(abstract); context_fns->context_id = context_id; context_fns->syntax = *abstract; + context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect(); + /* + * every interface can be modified to allow "connect" auth_level by + * using a parametric option like: + * allow dcerpc auth level connect: + * e.g. + * allow dcerpc auth level connect:samr = yes + */ + context_fns->allow_connect = lp_parm_bool(-1, + "allow dcerpc auth level connect", + interface_name, context_fns->allow_connect); + /* add to the list of open contexts */ DLIST_ADD( p->contexts, context_fns ); @@ -1174,6 +1192,7 @@ static bool api_pipe_request(struct pipes_struct *p, TALLOC_CTX *frame = talloc_stackframe(); bool ret = False; struct pipe_rpc_fns *pipe_fns; + const char *interface_name = NULL; if (!p->pipe_bound) { DEBUG(1, ("Pipe not bound!\n")); @@ -1194,6 +1213,37 @@ static bool api_pipe_request(struct pipes_struct *p, return false; } + interface_name = ndr_interface_name(&pipe_fns->syntax.uuid, + pipe_fns->syntax.if_version); + SMB_ASSERT(interface_name != NULL); + + switch (p->auth.auth_level) { + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + break; + default: + if (!pipe_fns->allow_connect) { + char *addr; + + addr = tsocket_address_string(p->remote_address, frame); + + DEBUG(1, ("%s: restrict auth_level_connect access " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, interface_name, + p->auth.auth_type, + p->auth.auth_level, + derpc_transport_string_by_transport(p->transport), + addr)); + + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); + TALLOC_FREE(frame); + return true; + } + break; + } + if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); @@ -1209,9 +1259,7 @@ static bool api_pipe_request(struct pipes_struct *p, return false; } - DEBUG(5, ("Requested %s rpc service\n", - ndr_interface_name(&pipe_fns->syntax.uuid, - pipe_fns->syntax.if_version))); + DEBUG(5, ("Requested %s rpc service\n", interface_name)); ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds, &pipe_fns->syntax); -- 1.9.1 From 27497eff04ccf48ac01ad2189e06ce1ed4fb58e7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 341/440] CVE-2016-2118: s3:rpc_server/{samr,lsa,netlogon}: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Pair-Programmed-With: Günther Deschner Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner --- selftest/knownfail | 4 ++++ source3/rpc_server/srv_pipe.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index fc711ba..f8a52cf 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -328,3 +328,7 @@ ^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=ca_and_name\( ^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=as_strict_as_possible\( ^samba4.ldb.simple.ldaps.*SERVER.REALM.*tlsverifypeer=as_strict_as_possible.*fl2008r2dc +# +# we don't allow auth_level_connect anymore... +# +^samba3.blackbox.rpcclient.*ncacn_np.*with.*connect.*rpcclient # we don't allow auth_level_connect anymore diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4902676..5704323 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -45,6 +45,9 @@ #include "auth/gensec/gensec.h" #include "librpc/ndr/ndr_dcerpc.h" #include "lib/tsocket/tsocket.h" +#include "../librpc/gen_ndr/ndr_samr.h" +#include "../librpc/gen_ndr/ndr_lsa.h" +#include "../librpc/gen_ndr/ndr_netlogon.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -379,6 +382,22 @@ static bool check_bind_req(struct pipes_struct *p, context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect(); /* + * for the samr, lsarpc and netlogon interfaces we don't allow "connect" + * auth_level by default. + */ + ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + /* * every interface can be modified to allow "connect" auth_level by * using a parametric option like: * allow dcerpc auth level connect: -- 1.9.1 From b39c9e57c8caff9f7a286e2779845880a787270f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:47:42 +0100 Subject: [PATCH 342/440] CVE-2016-2118: s3:rpc_server/{epmapper,echo}: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source3/rpc_server/srv_pipe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5704323..e6e39df 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -48,6 +48,8 @@ #include "../librpc/gen_ndr/ndr_samr.h" #include "../librpc/gen_ndr/ndr_lsa.h" #include "../librpc/gen_ndr/ndr_netlogon.h" +#include "../librpc/gen_ndr/ndr_epmapper.h" +#include "../librpc/gen_ndr/ndr_echo.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -398,6 +400,18 @@ static bool check_bind_req(struct pipes_struct *p, context_fns->allow_connect = false; } /* + * for the epmapper and echo interfaces we allow "connect" + * auth_level by default. + */ + ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id); + if (ok) { + context_fns->allow_connect = true; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id); + if (ok) { + context_fns->allow_connect = true; + } + /* * every interface can be modified to allow "connect" auth_level by * using a parametric option like: * allow dcerpc auth level connect: -- 1.9.1 From 2c222cfa0c2681d592df8f0359cbd645a4a1cfa0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 343/440] CVE-2016-2118: docs-xml: default "allow dcerpc auth level connect" to "no" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml | 6 ++---- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml index 27a9733..03531ad 100644 --- a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml @@ -19,11 +19,9 @@ E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY. The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY. - - Note the default will very likely change to no for Samba 4.5. -yes -no +no +yes diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index fca1fe8..4857c19 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2514,7 +2514,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); - lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "True"); + lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 0ec8c97..c975f1b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -667,7 +667,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ - Globals.allow_dcerpc_auth_level_connect = true; /* we need to allow this for now by default */ + Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */ Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ -- 1.9.1 From b1fa3163c52cb3ca412df241532e900f2332281a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 344/440] CVE-2016-2118: s4:rpc_server/samr: allow _samr_ValidatePassword only with PRIVACY... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This requires transport encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/samr/dcesrv_samr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 3f76378..a992120b 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4321,11 +4321,20 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, NTSTATUS status; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (transport != NCACN_IP_TCP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } + if (dce_call->conn->auth_state.auth_info != NULL) { + auth_level = dce_call->conn->auth_state.auth_info->auth_level; + } + + if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); + } + (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); r2.in.domain_name = NULL; -- 1.9.1 From 1af406c71369bd4eb50df24b4bd7229ff2bdf630 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 345/440] CVE-2016-2118: s3:rpc_server/samr: allow _samr_ValidatePassword only with PRIVACY... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This requires transport encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/samr/srv_samr_nt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c index 32640f9..259b0dd 100644 --- a/source3/rpc_server/samr/srv_samr_nt.c +++ b/source3/rpc_server/samr/srv_samr_nt.c @@ -6746,6 +6746,11 @@ NTSTATUS _samr_ValidatePassword(struct pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + p->fault_state = DCERPC_FAULT_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; + } + if (r->in.level < 1 || r->in.level > 3) { return NT_STATUS_INVALID_INFO_CLASS; } -- 1.9.1 From 5fb7de38b4523ca5206c453cfa3d695ff4877284 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 22:46:05 +0200 Subject: [PATCH 346/440] CVE-2015-5370: dcerpc.idl: add DCERPC_{NCACN_PAYLOAD,FRAG}_MAX_SIZE defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/idl/dcerpc.idl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index f7bf595..015eb3d 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -532,8 +532,10 @@ interface dcerpc const uint8 DCERPC_PFC_OFFSET = 3; const uint8 DCERPC_DREP_OFFSET = 4; const uint8 DCERPC_FRAG_LEN_OFFSET = 8; + const uint32 DCERPC_FRAG_MAX_SIZE = 5840; const uint8 DCERPC_AUTH_LEN_OFFSET = 10; const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; + const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ /* little-endian flag */ const uint8 DCERPC_DREP_LE = 0x10; -- 1.9.1 From 28700e6eb65e9e6bc54447f65bcd0b17b52305de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 347/440] CVE-2015-5370: librpc/rpc: simplify and harden dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++------------ librpc/rpc/rpc_common.h | 4 +-- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 696bcda..8f0ebd0 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -83,31 +83,44 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) * * @return - A NTSTATUS error code. */ -NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, +NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, TALLOC_CTX *mem_ctx, - DATA_BLOB *pkt_trailer, + const DATA_BLOB *pkt_trailer, struct dcerpc_auth *auth, - uint32_t *auth_length, + uint32_t *_auth_length, bool auth_data_only) { struct ndr_pull *ndr; enum ndr_err_code ndr_err; - uint32_t data_and_pad; + uint16_t data_and_pad; + uint16_t auth_length; + uint32_t tmp_length; - data_and_pad = pkt_trailer->length - - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); + ZERO_STRUCTP(auth); + if (_auth_length != NULL) { + *_auth_length = 0; + } - /* paranoia check for pad size. This would be caught anyway by - the ndr_pull_advance() a few lines down, but it scared - Jeremy enough for him to call me, so we might as well check - it now, just to prevent someone posting a bogus YouTube - video in the future. - */ - if (data_and_pad > pkt_trailer->length) { - return NT_STATUS_INFO_LENGTH_MISMATCH; + /* Paranoia checks for auth_length. The caller should check this... */ + if (pkt->auth_length > pkt->frag_length) { + return NT_STATUS_INTERNAL_ERROR; + } + tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET; + tmp_length += DCERPC_AUTH_TRAILER_LENGTH; + tmp_length += pkt->auth_length; + if (tmp_length > pkt->frag_length) { + return NT_STATUS_INTERNAL_ERROR; + } + if (pkt_trailer->length > UINT16_MAX) { + return NT_STATUS_INTERNAL_ERROR; } - *auth_length = pkt_trailer->length - data_and_pad; + auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length; + if (pkt_trailer->length < auth_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + data_and_pad = pkt_trailer->length - auth_length; ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); if (!ndr) { @@ -127,14 +140,28 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); + ZERO_STRUCTP(auth); return ndr_map_error2ntstatus(ndr_err); } + if (data_and_pad < auth->auth_pad_length) { + DEBUG(1, (__location__ ": ERROR: pad length mismatch. " + "Calculated %u got %u\n", + (unsigned)data_and_pad, + (unsigned)auth->auth_pad_length)); + talloc_free(ndr); + ZERO_STRUCTP(auth); + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (auth_data_only && data_and_pad != auth->auth_pad_length) { - DEBUG(1, (__location__ ": WARNING: pad length mismatch. " + DEBUG(1, (__location__ ": ERROR: pad length mismatch. " "Calculated %u got %u\n", (unsigned)data_and_pad, (unsigned)auth->auth_pad_length)); + talloc_free(ndr); + ZERO_STRUCTP(auth); + return NT_STATUS_RPC_PROTOCOL_ERROR; } DEBUG(6,(__location__ ": auth_pad_length %u\n", @@ -143,6 +170,10 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, talloc_steal(mem_ctx, auth->credentials.data); talloc_free(ndr); + if (_auth_length != NULL) { + *_auth_length = auth_length; + } + return NT_STATUS_OK; } diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index a515ddd..286bac2 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -184,9 +184,9 @@ const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, * * @return - A NTSTATUS error code. */ -NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, +NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, TALLOC_CTX *mem_ctx, - DATA_BLOB *pkt_trailer, + const DATA_BLOB *pkt_trailer, struct dcerpc_auth *auth, uint32_t *auth_length, bool auth_data_only); -- 1.9.1 From d37e18f2b984230de0c207a7e91d2190231f7acb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 10:24:45 +0200 Subject: [PATCH 348/440] CVE-2015-5370: s3:librpc/rpc: don't call dcerpc_pull_auth_trailer() if auth_length is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All other paranoia checks are done within dcerpc_pull_auth_trailer() now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 1193baa..96074a4 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -533,16 +533,8 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return NT_STATUS_INVALID_PARAMETER; } - /* Paranioa checks for auth_length. */ - if (pkt->auth_length > pkt->frag_length) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - if (((unsigned int)pkt->auth_length - + DCERPC_AUTH_TRAILER_LENGTH < (unsigned int)pkt->auth_length) || - ((unsigned int)pkt->auth_length - + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) { - /* Integer wrap attempt. */ - return NT_STATUS_INFO_LENGTH_MISMATCH; + if (pkt->auth_length == 0) { + return NT_STATUS_INVALID_PARAMETER; } status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer, -- 1.9.1 From 829fa6a517c2903ae6edb2bfad7c22fb1bb69098 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 16:25:48 +0200 Subject: [PATCH 349/440] CVE-2015-5370: s4:librpc/rpc: send a dcerpc_sec_verification_trailer if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 136 ++++++++++++++++++++++++++++++++++++++++++++ source4/librpc/rpc/dcerpc.h | 5 ++ 2 files changed, 141 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 31b14f1..fecc0f2 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -65,6 +65,8 @@ struct rpc_request { DATA_BLOB request_data; bool ignore_timeout; bool wait_for_sync; + bool verify_bitmask1; + bool verify_pcontext; struct { void (*callback)(struct rpc_request *); @@ -1545,6 +1547,13 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, return; } + if (req->verify_bitmask1) { + req->p->conn->security_state.verified_bitmask1 = true; + } + if (req->verify_pcontext) { + req->p->verified_pcontext = true; + } + if (!(pkt->drep[0] & DCERPC_DREP_LE)) { req->flags |= DCERPC_PULL_BIGENDIAN; } else { @@ -1569,6 +1578,8 @@ req_done: } } +static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req); + /* perform the send side of a async dcerpc request */ @@ -1579,6 +1590,7 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, DATA_BLOB *stub_data) { struct rpc_request *req; + NTSTATUS status; req = talloc_zero(mem_ctx, struct rpc_request); if (req == NULL) { @@ -1601,6 +1613,12 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, req->request_data.length = stub_data->length; req->request_data.data = stub_data->data; + status = dcerpc_request_prepare_vt(req); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + DLIST_ADD_END(p->conn->request_queue, req, struct rpc_request *); talloc_set_destructor(req, dcerpc_req_dequeue); @@ -1615,6 +1633,124 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, return req; } +static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req) +{ + struct dcecli_security *sec = &req->p->conn->security_state; + struct dcerpc_sec_verification_trailer *t; + struct dcerpc_sec_vt *c = NULL; + struct ndr_push *ndr = NULL; + enum ndr_err_code ndr_err; + + if (sec->auth_info == NULL) { + return NT_STATUS_OK; + } + + if (sec->auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + return NT_STATUS_OK; + } + + t = talloc_zero(req, struct dcerpc_sec_verification_trailer); + if (t == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (!sec->verified_bitmask1) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_BITMASK1; + if (req->p->conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) { + c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING; + } + req->verify_bitmask1 = true; + } + + if (!req->p->verified_pcontext) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT; + c->u.pcontext.abstract_syntax = req->p->syntax; + c->u.pcontext.transfer_syntax = req->p->transfer_syntax; + + req->verify_pcontext = true; + } + + if (!(req->p->conn->flags & DCERPC_HEADER_SIGNING)) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_HEADER2; + c->u.header2.ptype = DCERPC_PKT_REQUEST; + if (req->p->conn->flags & DCERPC_PUSH_BIGENDIAN) { + c->u.header2.drep[0] = 0; + } else { + c->u.header2.drep[0] = DCERPC_DREP_LE; + } + c->u.header2.drep[1] = 0; + c->u.header2.drep[2] = 0; + c->u.header2.drep[3] = 0; + c->u.header2.call_id = req->call_id; + c->u.header2.context_id = req->p->context_id; + c->u.header2.opnum = req->opnum; + } + + if (t->count.count == 0) { + TALLOC_FREE(t); + return NT_STATUS_OK; + } + + c = &t->commands[t->count.count - 1]; + c->command |= DCERPC_SEC_VT_COMMAND_END; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t); + } + + ndr = ndr_push_init_ctx(req); + if (ndr == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* + * for now we just copy and append + */ + + ndr_err = ndr_push_bytes(ndr, req->request_data.data, + req->request_data.length); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr, + NDR_SCALARS | NDR_BUFFERS, + t); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + req->request_data = ndr_push_blob(ndr); + + return NT_STATUS_OK; +} + /* Send a request using the transport */ diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index a7d1694..8b2aebe 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -51,6 +51,9 @@ struct dcecli_security { /* get the session key */ NTSTATUS (*session_key)(struct dcecli_connection *, DATA_BLOB *); + + bool verified_bitmask1; + }; /* @@ -126,6 +129,8 @@ struct dcerpc_pipe { */ bool inhibit_timeout_processing; bool timed_out; + + bool verified_pcontext; }; /* default timeout for all rpc requests, in seconds */ -- 1.9.1 From b0e792e72cc1668bb0fb76036107b054a53420de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 350/440] CVE-2015-5370: s4:librpc/rpc: maintain dcecli_security->auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will simplify the following commits and avoids dereferencing dcecli_security->auth_info. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 3 +++ source4/librpc/rpc/dcerpc.h | 3 +++ source4/librpc/rpc/dcerpc_auth.c | 10 +++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index fecc0f2..a05b58d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -141,6 +141,9 @@ static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, } c->call_id = 1; + c->security_state.auth_type = DCERPC_AUTH_TYPE_NONE; + c->security_state.auth_level = DCERPC_AUTH_LEVEL_NONE; + c->security_state.auth_context_id = 0; c->security_state.auth_info = NULL; c->security_state.session_key = dcerpc_generic_session_key; c->security_state.generic_state = NULL; diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 8b2aebe..541afd4 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -46,6 +46,9 @@ struct dcecli_connection; struct gensec_settings; struct cli_credentials; struct dcecli_security { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; struct dcerpc_auth *auth_info; struct gensec_security *generic_state; diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 2d60d38..aec72ca 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -353,14 +353,18 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, return c; } + sec->auth_type = auth_type; + sec->auth_level = auth_level, + sec->auth_context_id = random(); + sec->auth_info = talloc(p, struct dcerpc_auth); if (composite_nomem(sec->auth_info, c)) return c; - sec->auth_info->auth_type = auth_type; - sec->auth_info->auth_level = auth_level, + sec->auth_info->auth_type = sec->auth_type; + sec->auth_info->auth_level = sec->auth_level, sec->auth_info->auth_pad_length = 0; sec->auth_info->auth_reserved = 0; - sec->auth_info->auth_context_id = random(); + sec->auth_info->auth_context_id = sec->auth_context_id; sec->auth_info->credentials = data_blob(NULL, 0); /* The status value here, from GENSEC is vital to the security -- 1.9.1 From 1ed8df970ebfe90f374404117eee40ad96a29c10 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 351/440] CVE-2015-5370: s4:librpc/rpc: use auth_context_id = 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In future we want to verify that the auth_context_id from the server is what we expect. As Samba (<= 4.2.3) use a hardcoded value of 1 in responses, we need to use that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc_auth.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index aec72ca..443c758 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -355,7 +355,12 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, sec->auth_type = auth_type; sec->auth_level = auth_level, - sec->auth_context_id = random(); + /* + * We use auth_context_id = 1 as some older + * Samba versions (<= 4.2.3) use that value hardcoded + * in a response. + */ + sec->auth_context_id = 1; sec->auth_info = talloc(p, struct dcerpc_auth); if (composite_nomem(sec->auth_info, c)) return c; -- 1.9.1 From 401d0dce84758ea74ab4d79456fdf499042780db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 352/440] CVE-2015-5370: s4:librpc/rpc: use a local auth_info variable in ncacn_push_request_sign() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should avoid using the global dcecli_security->auth_info struct for individual requests. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index a05b58d..1f5213f 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -835,13 +835,13 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, size_t payload_length; enum ndr_err_code ndr_err; size_t hdr_size = DCERPC_REQUEST_LENGTH; + struct dcerpc_auth auth_info = { + .auth_type = c->security_state.auth_type, + .auth_level = c->security_state.auth_level, + .auth_context_id = c->security_state.auth_context_id, + }; - /* non-signed packets are simpler */ - if (c->security_state.auth_info == NULL) { - return ncacn_push_auth(blob, mem_ctx, pkt, NULL); - } - - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: if (sig_size == 0) { @@ -888,21 +888,18 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, ndr_push_align() as that is relative to the start of the whole packet, whereas w2k8 wants it relative to the start of the stub */ - c->security_state.auth_info->auth_pad_length = + auth_info.auth_pad_length = DCERPC_AUTH_PAD_LENGTH(pkt->u.request.stub_and_verifier.length); - ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length); + ndr_err = ndr_push_zero(ndr, auth_info.auth_pad_length); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } payload_length = pkt->u.request.stub_and_verifier.length + - c->security_state.auth_info->auth_pad_length; - - /* we start without signature, it will appended later */ - c->security_state.auth_info->credentials = data_blob(NULL,0); + auth_info.auth_pad_length; /* add the auth verifier */ - ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info); + ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth_info); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } @@ -920,7 +917,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, dcerpc_set_auth_length(blob, sig_size); /* sign or seal the packet */ - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(c->security_state.generic_state, mem_ctx, @@ -960,7 +957,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", (unsigned) creds2.length, (unsigned) sig_size, - (unsigned) c->security_state.auth_info->auth_pad_length, + (unsigned) auth_info.auth_pad_length, (unsigned) pkt->u.request.stub_and_verifier.length)); dcerpc_set_frag_length(blob, blob->length + creds2.length); dcerpc_set_auth_length(blob, creds2.length); -- 1.9.1 From d3b14a51c4ad123c554c1e907eb875de6a00060b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 353/440] CVE-2015-5370: s4:librpc/rpc: avoid using hs->p->conn->security_state.auth_info in dcerpc_bh_auth_info() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 1f5213f..854a956 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -225,12 +225,8 @@ static void dcerpc_bh_auth_info(struct dcerpc_binding_handle *h, return; } - if (hs->p->conn->security_state.auth_info == NULL) { - return; - } - - *auth_type = hs->p->conn->security_state.auth_info->auth_type; - *auth_level = hs->p->conn->security_state.auth_info->auth_level; + *auth_type = hs->p->conn->security_state.auth_type; + *auth_level = hs->p->conn->security_state.auth_level; } struct dcerpc_bh_raw_call_state { -- 1.9.1 From 474e82e3a5d065b5b88d118fcf68a1254991e806 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 354/440] CVE-2015-5370: s4:librpc/rpc: avoid using c->security_state.auth_info in ncacn_pull_request_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 854a956..f470e9e 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -742,12 +742,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX struct dcerpc_auth auth; uint32_t auth_length; - if (!c->security_state.auth_info || - !c->security_state.generic_state) { - return NT_STATUS_OK; - } - - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: break; @@ -767,6 +762,14 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX return NT_STATUS_INVALID_LEVEL; } + if (pkt->auth_length == 0) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (c->security_state.generic_state == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + status = dcerpc_pull_auth_trailer(pkt, mem_ctx, &pkt->u.response.stub_and_verifier, &auth, &auth_length, false); @@ -775,7 +778,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX pkt->u.response.stub_and_verifier.length -= auth_length; /* check signature or unseal the packet */ - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(c->security_state.generic_state, raw_packet->data + DCERPC_REQUEST_LENGTH, -- 1.9.1 From 69855b3a92af461213ae5f57e84cbd2d2d34693c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 355/440] CVE-2015-5370: s4:librpc/rpc: always use ncacn_pull_request_auth() for DCERPC_PKT_RESPONSE pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It handles the case of DCERPC_AUTH_TYPE_NONE just fine and it makes it possible to do some verification in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index f470e9e..01fc8e5 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1462,8 +1462,7 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, to run the auth routines so that we don't get the sign/seal info out of step with the server */ - if (c->security_state.auth_info && c->security_state.generic_state && - pkt->ptype == DCERPC_PKT_RESPONSE) { + if (pkt->ptype == DCERPC_PKT_RESPONSE) { status = ncacn_pull_request_auth(c, raw_packet->data, raw_packet, pkt); } -- 1.9.1 From 30f065ba342c80dd9f4e7edd71cdc9e18d16939c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 356/440] CVE-2015-5370: s4:librpc/rpc: avoid dereferencing sec->auth_info in dcerpc_request_prepare_vt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 01fc8e5..0a37509 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1639,11 +1639,7 @@ static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req) struct ndr_push *ndr = NULL; enum ndr_err_code ndr_err; - if (sec->auth_info == NULL) { - return NT_STATUS_OK; - } - - if (sec->auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (sec->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { return NT_STATUS_OK; } -- 1.9.1 From 53fe14c6dc7392aacf8821bd65b3c18aa3a920ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 357/440] CVE-2015-5370: s4:librpc/rpc: simplify checks if gensec is used in dcerpc_ship_next_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 0a37509..9a1b87b 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1774,25 +1774,9 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c) need_async = true; } - if (c->security_state.auth_info && - c->security_state.generic_state) - { - struct gensec_security *gensec = c->security_state.generic_state; - - switch (c->security_state.auth_info->auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - case DCERPC_AUTH_LEVEL_INTEGRITY: - can_async = gensec_have_feature(gensec, + if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + can_async = gensec_have_feature(c->security_state.generic_state, GENSEC_FEATURE_ASYNC_REPLIES); - break; - case DCERPC_AUTH_LEVEL_CONNECT: - case DCERPC_AUTH_LEVEL_NONE: - can_async = true; - break; - default: - can_async = false; - break; - } } if (need_async && !can_async) { @@ -1812,8 +1796,7 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c) request header size */ chunk_size = p->conn->srv_max_recv_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (c->security_state.auth_info && - c->security_state.generic_state) { + if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { size_t max_payload = chunk_size; max_payload -= DCERPC_AUTH_TRAILER_LENGTH; -- 1.9.1 From 2b2314e56d860313f8823f8fddd37302d792179e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 358/440] CVE-2015-5370: s4:librpc/rpc: avoid using dcecli_security->auth_info and use per request values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now avoid reusing the same auth_info structure for incoming and outgoing values. We need to make sure that the remote server doesn't overwrite our own values. This will trigger some failures with our currently broken server, which will be fixed in the next commits. The broken server requires an dcerpc_auth structure with no credentials in order to do an alter_context request that just creates a presentation context without doing authentication. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 4 +++ source4/librpc/rpc/dcerpc.c | 29 ++++++++-------- source4/librpc/rpc/dcerpc.h | 6 +++- source4/librpc/rpc/dcerpc_auth.c | 71 +++++++++++++++++++++++----------------- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index f8a52cf..803439d 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -1,3 +1,7 @@ +# These are temporary failures until the next commits fix it again +# +^samba4.rpc.altercontext.*seal # tmp +^samba4.rpc.altercontext.*ncalrpc # tmp # This file contains a list of regular expressions matching the names of # tests that are expected to fail. # diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 9a1b87b..592890a 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -144,7 +144,6 @@ static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, c->security_state.auth_type = DCERPC_AUTH_TYPE_NONE; c->security_state.auth_level = DCERPC_AUTH_LEVEL_NONE; c->security_state.auth_context_id = 0; - c->security_state.auth_info = NULL; c->security_state.session_key = dcerpc_generic_session_key; c->security_state.generic_state = NULL; c->flags = 0; @@ -1224,7 +1223,7 @@ struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx, /* construct the NDR form of the packet */ status = ncacn_push_auth(&blob, state, &pkt, - p->conn->security_state.auth_info); + p->conn->security_state.tmp_auth_info.out); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -1297,6 +1296,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, tevent_req_data(req, struct dcerpc_bind_state); struct dcecli_connection *conn = state->p->conn; + struct dcecli_security *sec = &conn->security_state; struct dcerpc_binding *b = NULL; NTSTATUS status; uint32_t flags; @@ -1370,11 +1370,13 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, } /* the bind_ack might contain a reply set of credentials */ - if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) { + if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; - status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info, - conn->security_state.auth_info, &auth_length, true); + status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, + &pkt->u.bind_ack.auth_info, + sec->tmp_auth_info.in, + &auth_length, true); if (tevent_req_nterror(req, status)) { return; } @@ -1424,9 +1426,8 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p, } /* construct the NDR form of the packet */ - status = ncacn_push_auth(&blob, mem_ctx, - &pkt, - p->conn->security_state.auth_info); + status = ncacn_push_auth(&blob, mem_ctx, &pkt, + p->conn->security_state.tmp_auth_info.out); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2232,7 +2233,7 @@ struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx, /* construct the NDR form of the packet */ status = ncacn_push_auth(&blob, state, &pkt, - p->conn->security_state.auth_info); + p->conn->security_state.tmp_auth_info.out); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -2305,6 +2306,7 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, tevent_req_data(req, struct dcerpc_alter_context_state); struct dcecli_connection *conn = state->p->conn; + struct dcecli_security *sec = &conn->security_state; NTSTATUS status; /* @@ -2363,12 +2365,13 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, } /* the alter_resp might contain a reply set of credentials */ - if (conn->security_state.auth_info && - pkt->u.alter_resp.auth_info.length) { + if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; - status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.alter_resp.auth_info, - conn->security_state.auth_info, &auth_length, true); + status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, + &pkt->u.alter_resp.auth_info, + sec->tmp_auth_info.in, + &auth_length, true); if (tevent_req_nterror(req, status)) { return; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 541afd4..1b0eb7d 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -49,7 +49,11 @@ struct dcecli_security { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; - struct dcerpc_auth *auth_info; + struct { + struct dcerpc_auth *out; + struct dcerpc_auth *in; + TALLOC_CTX *mem; + } tmp_auth_info; struct gensec_security *generic_state; /* get the session key */ diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 443c758..15a843b 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -124,7 +124,8 @@ _PUBLIC_ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, struct bind_auth_state { struct dcerpc_pipe *pipe; - DATA_BLOB credentials; + struct dcerpc_auth out_auth_info; + struct dcerpc_auth in_auth_info; bool more_processing; /* Is there anything more to do after the * first bind itself received? */ }; @@ -141,6 +142,12 @@ static void bind_auth_next_step(struct composite_context *c) state = talloc_get_type(c->private_data, struct bind_auth_state); sec = &state->pipe->conn->security_state; + state->out_auth_info = (struct dcerpc_auth) { + .auth_type = sec->auth_type, + .auth_level = sec->auth_level, + .auth_context_id = sec->auth_context_id, + }; + /* The status value here, from GENSEC is vital to the security * of the system. Even if the other end accepts, if GENSEC * claims 'MORE_PROCESSING_REQUIRED' then you must keep @@ -156,16 +163,14 @@ static void bind_auth_next_step(struct composite_context *c) c->status = gensec_update_ev(sec->generic_state, state, state->pipe->conn->event_ctx, - sec->auth_info->credentials, - &state->credentials); + state->in_auth_info.credentials, + &state->out_auth_info.credentials); if (state->pipe->timed_out) { composite_error(c, NT_STATUS_IO_TIMEOUT); return; } state->pipe->inhibit_timeout_processing = false; - data_blob_free(&sec->auth_info->credentials); - if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { more_processing = true; c->status = NT_STATUS_OK; @@ -173,18 +178,21 @@ static void bind_auth_next_step(struct composite_context *c) if (!composite_is_ok(c)) return; - if (state->credentials.length == 0) { + if (state->out_auth_info.credentials.length == 0) { composite_done(c); return; } - sec->auth_info->credentials = state->credentials; + state->in_auth_info = (struct dcerpc_auth) { + .auth_type = DCERPC_AUTH_TYPE_NONE, + }; + sec->tmp_auth_info.in = &state->in_auth_info; + sec->tmp_auth_info.mem = state; + sec->tmp_auth_info.out = &state->out_auth_info; if (!more_processing) { /* NO reply expected, so just send it */ c->status = dcerpc_auth3(state->pipe, state); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (!composite_is_ok(c)) return; composite_done(c); @@ -197,8 +205,6 @@ static void bind_auth_next_step(struct composite_context *c) state->pipe, &state->pipe->syntax, &state->pipe->transfer_syntax); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (composite_nomem(subreq, c)) return; tevent_req_set_callback(subreq, bind_auth_recv_alter, c); } @@ -209,6 +215,11 @@ static void bind_auth_recv_alter(struct tevent_req *subreq) struct composite_context *c = tevent_req_callback_data(subreq, struct composite_context); + struct bind_auth_state *state = talloc_get_type(c->private_data, + struct bind_auth_state); + struct dcecli_security *sec = &state->pipe->conn->security_state; + + ZERO_STRUCT(sec->tmp_auth_info); c->status = dcerpc_alter_context_recv(subreq); TALLOC_FREE(subreq); @@ -225,14 +236,15 @@ static void bind_auth_recv_bindreply(struct tevent_req *subreq) struct composite_context); struct bind_auth_state *state = talloc_get_type(c->private_data, struct bind_auth_state); + struct dcecli_security *sec = &state->pipe->conn->security_state; + + ZERO_STRUCT(sec->tmp_auth_info); c->status = dcerpc_bind_recv(subreq); TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) { - struct dcecli_security *sec = &state->pipe->conn->security_state; - gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER); } @@ -362,15 +374,11 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, */ sec->auth_context_id = 1; - sec->auth_info = talloc(p, struct dcerpc_auth); - if (composite_nomem(sec->auth_info, c)) return c; - - sec->auth_info->auth_type = sec->auth_type; - sec->auth_info->auth_level = sec->auth_level, - sec->auth_info->auth_pad_length = 0; - sec->auth_info->auth_reserved = 0; - sec->auth_info->auth_context_id = sec->auth_context_id; - sec->auth_info->credentials = data_blob(NULL, 0); + state->out_auth_info = (struct dcerpc_auth) { + .auth_type = sec->auth_type, + .auth_level = sec->auth_level, + .auth_context_id = sec->auth_context_id, + }; /* The status value here, from GENSEC is vital to the security * of the system. Even if the other end accepts, if GENSEC @@ -386,8 +394,8 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, state->pipe->timed_out = false; c->status = gensec_update_ev(sec->generic_state, state, p->conn->event_ctx, - sec->auth_info->credentials, - &state->credentials); + data_blob_null, + &state->out_auth_info.credentials); if (state->pipe->timed_out) { composite_error(c, NT_STATUS_IO_TIMEOUT); return c; @@ -403,25 +411,28 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, state->more_processing = NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED); - if (state->credentials.length == 0) { + if (state->out_auth_info.credentials.length == 0) { composite_done(c); return c; } - sec->auth_info->credentials = state->credentials; - if (gensec_have_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER)) { - if (auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + if (sec->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { state->pipe->conn->flags |= DCERPC_PROPOSE_HEADER_SIGNING; } } + state->in_auth_info = (struct dcerpc_auth) { + .auth_type = DCERPC_AUTH_TYPE_NONE, + }; + sec->tmp_auth_info.in = &state->in_auth_info; + sec->tmp_auth_info.mem = state; + sec->tmp_auth_info.out = &state->out_auth_info; + /* The first request always is a dcerpc_bind. The subsequent ones * depend on gensec results */ subreq = dcerpc_bind_send(state, p->conn->event_ctx, p, &syntax, &transfer_syntax); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (composite_nomem(subreq, c)) return c; tevent_req_set_callback(subreq, bind_auth_recv_bindreply, c); -- 1.9.1 From b2d569f76922ed5ef9811aff6660514dbf18e283 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 359/440] CVE-2015-5370: s4:librpc/rpc: finally verify the server uses the expected auth_{type,level,context_id} values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 12 ++++++++++++ source4/librpc/rpc/dcerpc_auth.c | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 592890a..bd9c59d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -776,6 +776,18 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX pkt->u.response.stub_and_verifier.length -= auth_length; + if (auth.auth_type != c->security_state.auth_type) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (auth.auth_level != c->security_state.auth_level) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (auth.auth_context_id != c->security_state.auth_context_id) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + /* check signature or unseal the packet */ switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 15a843b..d617b07 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -142,6 +142,21 @@ static void bind_auth_next_step(struct composite_context *c) state = talloc_get_type(c->private_data, struct bind_auth_state); sec = &state->pipe->conn->security_state; + if (state->in_auth_info.auth_type != sec->auth_type) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (state->in_auth_info.auth_level != sec->auth_level) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (state->in_auth_info.auth_context_id != sec->auth_context_id) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + state->out_auth_info = (struct dcerpc_auth) { .auth_type = sec->auth_type, .auth_level = sec->auth_level, -- 1.9.1 From 8465917f1e36491455a5bef3263f339a968f9a40 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 360/440] CVE-2015-5370: librpc/rpc: add a dcerpc_verify_ncacn_packet_header() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ librpc/rpc/rpc_common.h | 5 ++++ 2 files changed, 78 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 8f0ebd0..2f81447 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -177,6 +177,79 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, return NT_STATUS_OK; } +/** +* @brief Verify the fields in ncacn_packet header. +* +* @param pkt - The ncacn_packet strcuture +* @param ptype - The expected PDU type +* @param max_auth_info - The maximum size of a possible auth trailer +* @param required_flags - The required flags for the pdu. +* @param optional_flags - The possible optional flags for the pdu. +* +* @return - A NTSTATUS error code. +*/ +NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, + enum dcerpc_pkt_type ptype, + size_t max_auth_info, + uint8_t required_flags, + uint8_t optional_flags) +{ + if (pkt->rpc_vers != 5) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->rpc_vers_minor != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->auth_length > pkt->frag_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->ptype != ptype) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (max_auth_info > UINT16_MAX) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (pkt->auth_length > 0) { + size_t max_auth_length; + + if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH; + + if (pkt->auth_length > max_auth_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + } + + if ((pkt->pfc_flags & required_flags) != required_flags) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->pfc_flags & ~(optional_flags|required_flags)) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->drep[0] & ~DCERPC_DREP_LE) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[1] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[2] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[3] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + return NT_STATUS_OK; +} + struct dcerpc_read_ncacn_packet_state { #if 0 struct { diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 286bac2..da6c2a2 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -190,6 +190,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, struct dcerpc_auth *auth, uint32_t *auth_length, bool auth_data_only); +NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, + enum dcerpc_pkt_type ptype, + size_t max_auth_info, + uint8_t required_flags, + uint8_t optional_flags); struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct tstream_context *stream); -- 1.9.1 From a0cd1ca8ca9fe30f564ed9d786277b19de1fdbb4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 361/440] CVE-2015-5370: s3:rpc_client: move AS/U hack to the top of cli_pipe_validate_current_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index fd81bf3..15b8f6e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -401,6 +401,19 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, */ *rdata = *pdu; + if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && + !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { + /* + * TODO: do we still need this hack which was introduced + * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0. + * + * I don't even know what AS/U might be... + */ + DEBUG(5, (__location__ ": bug in server (AS/U?), setting " + "fragment first/last ON.\n")); + pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + } + /* Ensure we have the correct type. */ switch (pkt->ptype) { case DCERPC_PKT_ALTER_RESP: @@ -505,17 +518,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, return NT_STATUS_RPC_PROTOCOL_ERROR; } - /* Do this just before return - we don't want to modify any rpc header - data before now as we may have needed to do cryptographic actions on - it before. */ - - if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && - !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { - DEBUG(5, (__location__ ": bug in server (AS/U?), setting " - "fragment first/last ON.\n")); - pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - } - return NT_STATUS_OK; } -- 1.9.1 From e4ed35d55ac5a44181d89d82e836f615b74984ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 362/440] CVE-2015-5370: s3:rpc_client: remove useless frag_length check in rpc_api_pipe_got_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dcerpc_pull_ncacn_packet() already verifies this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 15b8f6e..17f3e2e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -881,14 +881,6 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) return; } - if (state->incoming_frag.length != state->pkt->frag_length) { - DEBUG(5, ("Incorrect pdu length %u, expected %u\n", - (unsigned int)state->incoming_frag.length, - (unsigned int)state->pkt->frag_length)); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - status = cli_pipe_validate_current_pdu(state, state->cli, state->pkt, &state->incoming_frag, -- 1.9.1 From 5fb0e3bcf2d1925ea29bc6101288874f2e47b724 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 363/440] CVE-2015-5370: s4:librpc/rpc: make use of dcerpc_map_ack_reason() in dcerpc_bind_recv_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should give better error messages if the server doesn't support a specific abstract/transfer syntax. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index bd9c59d..c799eab 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1343,13 +1343,21 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, } if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || - (pkt->u.bind_ack.num_results == 0) || - (pkt->u.bind_ack.ctx_list[0].result != 0)) { + (pkt->u.bind_ack.num_results == 0)) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } + if (pkt->u.bind_ack.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.bind_ack.ctx_list[0]); + DEBUG(2,("dcerpc: bind_ack failed - reason %d - %s\n", + pkt->u.bind_ack.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + /* * DCE-RPC 1.1 (c706) specifies * CONST_MUST_RCV_FRAG_SIZE as 1432 -- 1.9.1 From 1536daa4b2ebda6dc56cec3133591ea18194723a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 364/440] CVE-2015-5370: s4:librpc/rpc: handle DCERPC_PKT_FAULT before anything else in dcerpc_alter_context_recv_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index c799eab..f81d558 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2348,17 +2348,6 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, */ tevent_req_defer_callback(req, state->ev); - if (pkt->ptype == DCERPC_PKT_ALTER_RESP && - pkt->u.alter_resp.num_results == 1 && - pkt->u.alter_resp.ctx_list[0].result != 0) { - status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); - DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", - pkt->u.alter_resp.ctx_list[0].reason.value, - nt_errstr(status))); - tevent_req_nterror(req, status); - return; - } - if (pkt->ptype == DCERPC_PKT_FAULT) { DEBUG(5,("dcerpc: alter_resp - rpc fault: %s\n", dcerpc_errstr(state, pkt->u.fault.status))); @@ -2376,6 +2365,17 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, return; } + if (pkt->ptype == DCERPC_PKT_ALTER_RESP && + pkt->u.alter_resp.num_results == 1 && + pkt->u.alter_resp.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); + DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", + pkt->u.alter_resp.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + if (pkt->ptype != DCERPC_PKT_ALTER_RESP || pkt->u.alter_resp.num_results == 0 || pkt->u.alter_resp.ctx_list[0].result != 0) { -- 1.9.1 From c1e12d42c58a7c9114b13653faf3703e415214eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 365/440] CVE-2015-5370: s4:librpc/rpc: use dcerpc_verify_ncacn_packet_header() to verify BIND_ACK,ALTER_RESP,RESPONSE pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 56 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index f81d558..3a6dc57 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -741,6 +741,15 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX struct dcerpc_auth auth; uint32_t auth_length; + status = dcerpc_verify_ncacn_packet_header(pkt, DCERPC_PKT_RESPONSE, + pkt->u.response.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: @@ -1342,8 +1351,20 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, return; } - if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || - (pkt->u.bind_ack.num_results == 0)) { + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND_ACK, + pkt->u.bind_ack.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(status)) { + state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; + tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); + return; + } + + if (pkt->u.bind_ack.num_results != 1) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; @@ -2365,25 +2386,34 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, return; } - if (pkt->ptype == DCERPC_PKT_ALTER_RESP && - pkt->u.alter_resp.num_results == 1 && - pkt->u.alter_resp.ctx_list[0].result != 0) { - status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); - DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", - pkt->u.alter_resp.ctx_list[0].reason.value, - nt_errstr(status))); - tevent_req_nterror(req, status); + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_ALTER_RESP, + pkt->u.alter_resp.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(status)) { + state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; + tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } - if (pkt->ptype != DCERPC_PKT_ALTER_RESP || - pkt->u.alter_resp.num_results == 0 || - pkt->u.alter_resp.ctx_list[0].result != 0) { + if (pkt->u.alter_resp.num_results != 1) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } + if (pkt->u.alter_resp.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); + DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", + pkt->u.alter_resp.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + /* the alter_resp might contain a reply set of credentials */ if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; -- 1.9.1 From fc1fc75be2bb7a842ddb8b8ce5b010972f932676 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:08:46 +0200 Subject: [PATCH 366/440] CVE-2015-5370: s4:librpc/rpc: protect dcerpc_request_recv_data() against too large payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should only allow a combined payload of a response of at max 4 MBytes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 3a6dc57..7b9777f 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1567,6 +1567,15 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, length = pkt->u.response.stub_and_verifier.length; + if (req->payload.length + length > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n", + (unsigned)req->payload.length + length, + DCERPC_NCACN_PAYLOAD_MAX_SIZE)); + req->fault_code = DCERPC_FAULT_OTHER; + req->status = NT_STATUS_NET_WRITE_FAULT; + goto req_done; + } + if (length > 0) { req->payload.data = talloc_realloc(req, req->payload.data, -- 1.9.1 From b5a30ea351f8ff77e23c660675176a8774262292 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 367/440] CVE-2015-5370: s4:rpc_server: make use of talloc_zero() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 4 ++-- source4/rpc_server/dcerpc_server.c | 32 ++++++++++++++++---------------- source4/rpc_server/handles.c | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 8e56e1e..5c02e05 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -118,7 +118,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) ZERO_STRUCT(zeros); pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -206,7 +206,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) struct data_blob_list_item *rep; struct ncacn_packet pkt; - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); NT_STATUS_HAVE_NO_MEMORY(rep); length = MIN(chunk_size, stub.length); diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6da6691..daebe91 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -269,7 +269,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ if ((ep=find_endpoint(dce_ctx, binding))==NULL) { - ep = talloc(dce_ctx, struct dcesrv_endpoint); + ep = talloc_zero(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } @@ -278,7 +278,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, add_ep = true; /* add mgmt interface */ - ifl = talloc(ep, struct dcesrv_if_list); + ifl = talloc_zero(ep, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -297,7 +297,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } /* talloc a new interface list element */ - ifl = talloc(ep, struct dcesrv_if_list); + ifl = talloc_zero(ep, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -474,7 +474,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.versions = &version; pkt.u.bind_nak._pad = data_blob_null; - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -682,7 +682,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) if (iface) { /* add this context to the list of available context_ids */ - struct dcesrv_connection_context *context = talloc(call->conn, + struct dcesrv_connection_context *context = talloc_zero(call->conn, struct dcesrv_connection_context); if (context == NULL) { return dcesrv_bind_nak(call, 0); @@ -771,7 +771,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.secondary_address = ""; } pkt.u.bind_ack.num_results = 1; - pkt.u.bind_ack.ctx_list = talloc(call, struct dcerpc_ack_ctx); + pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.bind_ack.ctx_list) { talloc_free(call->context); call->context = NULL; @@ -789,7 +789,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { talloc_free(call->context); call->context = NULL; @@ -868,7 +868,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ } /* add this context to the list of available context_ids */ - context = talloc(call->conn, struct dcesrv_connection_context); + context = talloc_zero(call->conn, struct dcesrv_connection_context); if (context == NULL) { return NT_STATUS_NO_MEMORY; } @@ -940,7 +940,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, pkt.u.alter_resp.assoc_group_id = 0; } pkt.u.alter_resp.num_results = 1; - pkt.u.alter_resp.ctx_list = talloc_array(call, struct dcerpc_ack_ctx, 1); + pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.alter_resp.ctx_list) { return NT_STATUS_NO_MEMORY; } @@ -961,7 +961,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, return dcesrv_fault(call, 0); } - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -1392,7 +1392,7 @@ _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_ERROR; } - dce_ctx = talloc(mem_ctx, struct dcesrv_context); + dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context); NT_STATUS_HAVE_NO_MEMORY(dce_ctx); dce_ctx->endpoint_list = NULL; dce_ctx->lp_ctx = lp_ctx; @@ -1608,7 +1608,7 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) struct dcesrv_sock_reply_state *substate; struct tevent_req *subreq; - substate = talloc(call, struct dcesrv_sock_reply_state); + substate = talloc_zero(call, struct dcesrv_sock_reply_state); if (!substate) { dcesrv_terminate_connection(dce_conn, "no memory"); return; @@ -1852,7 +1852,7 @@ static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, NTSTATUS status; const char *endpoint; - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -1908,7 +1908,7 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx), endpoint); - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -1942,7 +1942,7 @@ static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, return NT_STATUS_INVALID_PARAMETER; } - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -1980,7 +1980,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct port = atoi(endpoint); } - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index be9f16c..f99ee1d 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -46,7 +46,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; - h = talloc(context->assoc_group, struct dcesrv_handle); + h = talloc_zero(context->assoc_group, struct dcesrv_handle); if (!h) { return NULL; } -- 1.9.1 From 7d46e1ff8611afee3dc1216e1851d10dcb23dc95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 368/440] CVE-2015-5370: s4:rpc_server: no authentication is indicated by pkt->auth_length == 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pkt->u.*.auth_info.length is not the correct thing to check. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 4 ---- source4/rpc_server/dcesrv_auth.c | 28 +++++++++++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 803439d..f8a52cf 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -1,7 +1,3 @@ -# These are temporary failures until the next commits fix it again -# -^samba4.rpc.altercontext.*seal # tmp -^samba4.rpc.altercontext.*ncalrpc # tmp # This file contains a list of regular expressions matching the names of # tests that are expected to fail. # diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 52fe26f..beccc78 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -46,7 +46,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS status; uint32_t auth_length; - if (pkt->u.bind.auth_info.length == 0) { + if (pkt->auth_length == 0) { dce_conn->auth_state.auth_info = NULL; return true; } @@ -119,10 +119,15 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe NTSTATUS status; bool want_header_signing = false; - if (!call->conn->auth_state.gensec_security) { + if (call->pkt.auth_length == 0) { return NT_STATUS_OK; } + /* We can't work without an existing gensec state */ + if (!call->conn->auth_state.gensec_security) { + return NT_STATUS_INTERNAL_ERROR; + } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { dce_conn->auth_state.client_hdr_signing = true; want_header_signing = true; @@ -198,10 +203,16 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) NTSTATUS status; uint32_t auth_length; - /* We can't work without an existing gensec state, and an new blob to feed it */ - if (!dce_conn->auth_state.auth_info || - !dce_conn->auth_state.gensec_security || - pkt->u.auth3.auth_info.length == 0) { + if (pkt->auth_length == 0) { + return false; + } + + if (!dce_conn->auth_state.auth_info) { + return false; + } + + /* We can't work without an existing gensec state */ + if (!dce_conn->auth_state.gensec_security) { return false; } @@ -247,7 +258,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) uint32_t auth_length; /* on a pure interface change there is no auth blob */ - if (pkt->u.alter.auth_info.length == 0) { + if (pkt->auth_length == 0) { return true; } @@ -282,8 +293,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack /* on a pure interface change there is no auth_info structure setup */ - if (!call->conn->auth_state.auth_info || - dce_conn->auth_state.auth_info->credentials.length == 0) { + if (call->pkt.auth_length == 0) { return NT_STATUS_OK; } -- 1.9.1 From f1a90490737e0cdbf35b0eac3e012f39c9f21a57 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 369/440] CVE-2015-5370: s4:rpc_server: check the result of dcerpc_pull_auth_trailer() in dcesrv_auth_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcesrv_auth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index beccc78..c3ba40c 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -59,6 +59,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, dce_conn->auth_state.auth_info, &auth_length, false); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + server_credentials = cli_credentials_init(call); if (!server_credentials) { -- 1.9.1 From 070bc6f75920bc9814eba48b894ec6336d7a6d6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 11:03:58 +0200 Subject: [PATCH 370/440] CVE-2015-5370: s4:rpc_server: maintain dcesrv_auth->auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will simplify checks in the following commits and avoids derefencing dcesrv_auth->auth_info which is not always arround. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.h | 17 +++++++++++++++-- source4/rpc_server/dcesrv_auth.c | 15 +++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 894b2c9..bc1b8a9 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -146,6 +146,9 @@ struct dcesrv_handle { /* hold the authentication state information */ struct dcesrv_auth { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; struct dcerpc_auth *auth_info; struct gensec_security *gensec_security; struct auth_session_info *session_info; @@ -205,8 +208,15 @@ struct dcesrv_connection { DATA_BLOB partial_input; - /* the current authentication state */ - struct dcesrv_auth auth_state; + /* This can be removed in master... */ + struct { + struct dcerpc_auth *auth_info; + struct gensec_security *gensec_security; + struct auth_session_info *session_info; + NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); + bool client_hdr_signing; + bool hdr_signing; + } _unused_auth_state; /* the event_context that will be used for this connection */ struct tevent_context *event_ctx; @@ -238,6 +248,9 @@ struct dcesrv_connection { const struct tsocket_address *local_address; const struct tsocket_address *remote_address; + + /* the current authentication state */ + struct dcesrv_auth auth_state; }; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index c3ba40c..03231a5 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -47,6 +47,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) uint32_t auth_length; if (pkt->auth_length == 0) { + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = 0; dce_conn->auth_state.auth_info = NULL; return true; } @@ -63,6 +66,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + auth->auth_type = dce_conn->auth_state.auth_info->auth_type; + auth->auth_level = dce_conn->auth_state.auth_info->auth_level; + auth->auth_context_id = dce_conn->auth_state.auth_info->auth_context_id; + server_credentials = cli_credentials_init(call); if (!server_credentials) { @@ -100,12 +107,12 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) } } - status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, - auth->auth_info->auth_level); + status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_type, + auth->auth_level); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", - (int)auth->auth_info->auth_type, - (int)auth->auth_info->auth_level, + (int)auth->auth_type, + (int)auth->auth_level, nt_errstr(status))); return false; } -- 1.9.1 From bb62aea8ce2023c8b4b04d23ffc7a9f4de69a72c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 16:02:31 +0100 Subject: [PATCH 371/440] CVE-2015-5370: s4:rpc_server: make use of dce_call->conn->auth_state.auth_* in dcesrv_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index daebe91..0fc7955 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1101,8 +1101,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct ndr_pull *pull; NTSTATUS status; struct dcesrv_connection_context *context; - uint32_t auth_type = DCERPC_AUTH_TYPE_NONE; - uint32_t auth_level = DCERPC_AUTH_LEVEL_NONE; /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && @@ -1115,12 +1113,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } - if (call->conn->auth_state.auth_info != NULL) { - auth_type = call->conn->auth_state.auth_info->auth_type; - auth_level = call->conn->auth_state.auth_info->auth_level; - } - - switch (auth_level) { + switch (call->conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_NONE: case DCERPC_AUTH_LEVEL_INTEGRITY: case DCERPC_AUTH_LEVEL_PRIVACY: @@ -1136,7 +1129,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) "to [%s] with auth[type=0x%x,level=0x%x] " "on [%s] from [%s]\n", __func__, context->iface->name, - auth_type, auth_level, + call->conn->auth_state.auth_type, + call->conn->auth_state.auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); @@ -1144,7 +1138,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) break; } - if (auth_level < context->min_auth_level) { + if (call->conn->auth_state.auth_level < context->min_auth_level) { char *addr; addr = tsocket_address_string(call->conn->remote_address, call); @@ -1155,7 +1149,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) __func__, context->min_auth_level, context->iface->name, - auth_type, auth_level, + call->conn->auth_state.auth_type, + call->conn->auth_state.auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); -- 1.9.1 From 5f7ad071ffdde44c507325a783a8ebfd906af855 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 372/440] CVE-2015-5370: s4:rpc_server/lsa: make use of dce_call->conn->auth_state.auth_{level,type} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/lsa/lsa_lookup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c index 8d92ba8..d90ca70 100644 --- a/source4/rpc_server/lsa/lsa_lookup.c +++ b/source4/rpc_server/lsa/lsa_lookup.c @@ -718,7 +718,7 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; + const struct dcesrv_auth *auth = &dce_call->conn->auth_state; struct lsa_policy_state *policy_state; struct lsa_LookupSids2 q; NTSTATUS status; @@ -731,8 +731,8 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, * We don't have policy handles on this call. So this must be restricted * to crypto connections only. */ - if (auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || + auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } @@ -944,7 +944,7 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; + const struct dcesrv_auth *auth = &dce_call->conn->auth_state; struct lsa_policy_state *policy_state; struct lsa_LookupNames3 q; NTSTATUS status; @@ -957,8 +957,8 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX * We don't have policy handles on this call. So this must be restricted * to crypto connections only. */ - if (auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || + auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 1.9.1 From 2fcdc6974b2424defb6bd6b70e9fd75dd75cc250 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 373/440] CVE-2015-5370: s4:rpc_server/samr: make use of dce_call->conn->auth_state.auth_level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/samr/dcesrv_samr.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index a992120b..55efdac 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4321,17 +4321,12 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, NTSTATUS status; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (transport != NCACN_IP_TCP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } - if (dce_call->conn->auth_state.auth_info != NULL) { - auth_level = dce_call->conn->auth_state.auth_info->auth_level; - } - - if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + if (dce_call->conn->auth_state.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 1.9.1 From 85ebfb5461ba32a4c5a9b76a8be08a1922ec723d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 374/440] CVE-2015-5370: s4:rpc_server/netlogon: make use of dce_call->conn->auth_state.auth_{level,type} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 919945e..9ba2842 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -473,7 +473,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca /* * If schannel is required for this call test that it actually is available. */ -static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info, +static NTSTATUS schannel_check_required(const struct dcesrv_auth *auth_info, const char *computer_name, bool integrity, bool privacy) { @@ -509,12 +509,11 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc struct netlogon_creds_CredentialState **creds_out) { NTSTATUS nt_status; - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); bool schannel_global_required = (schannel == true); if (schannel_global_required) { - nt_status = schannel_check_required(auth_info, + nt_status = schannel_check_required(&dce_call->conn->auth_state, computer_name, true, false); if (!NT_STATUS_IS_OK(nt_status)) { @@ -921,13 +920,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal break; case 6: - if (dce_call->conn->auth_state.auth_info == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (dce_call->conn->auth_state.auth_info->auth_level != - DCERPC_AUTH_LEVEL_PRIVACY) - { + if (dce_call->conn->auth_state.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { return NT_STATUS_INVALID_PARAMETER; } @@ -987,8 +980,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, return nt_status; } - if (!dce_call->conn->auth_state.auth_info || - dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { + if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { return NT_STATUS_ACCESS_DENIED; } return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds); -- 1.9.1 From 592d9b17783625e4957bfd5c09161cc0d2bea677 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 375/440] CVE-2015-5370: s4:rpc_server: correctly maintain dcesrv_connection->max_{recv,xmit}_frag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These values are controlled by the client but only in a range between 2048 and 5840 (including these values in 8 byte steps). recv and xmit result always in same min value. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- source4/rpc_server/dcerpc_server.c | 32 ++++++++++++++++++++++++-------- source4/rpc_server/dcerpc_server.h | 3 ++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 5c02e05..322138c 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -183,7 +183,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) /* we can write a full max_recv_frag size, minus the dcerpc request header size */ - chunk_size = call->conn->cli_max_recv_frag; + chunk_size = call->conn->max_xmit_frag; chunk_size -= DCERPC_REQUEST_LENGTH; if (call->conn->auth_state.auth_info && call->conn->auth_state.gensec_security) { diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0fc7955..6df9f77 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -408,6 +408,8 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->msg_ctx = msg_ctx; p->server_id = server_id; p->state_flags = state_flags; + p->max_recv_frag = 5840; + p->max_xmit_frag = 5840; *_p = p; return NT_STATUS_OK; @@ -633,6 +635,24 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; uint32_t extra_flags = 0; + uint16_t max_req = 0; + uint16_t max_rep = 0; + + /* max_recv_frag and max_xmit_frag result always in the same value! */ + max_req = MIN(call->pkt.u.bind.max_xmit_frag, + call->pkt.u.bind.max_recv_frag); + /* + * The values are between 2048 and 5840 tested against Windows 2012R2 + * via ncacn_ip_tcp on port 135. + */ + max_req = MAX(2048, max_req); + max_rep = MIN(max_req, call->conn->max_recv_frag); + /* They are truncated to an 8 byte boundary. */ + max_rep &= 0xFFF8; + + /* max_recv_frag and max_xmit_frag result always in the same value! */ + call->conn->max_recv_frag = max_rep; + call->conn->max_xmit_frag = max_rep; /* if provided, check the assoc_group is valid @@ -722,10 +742,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } } - if (call->conn->cli_max_recv_frag == 0) { - call->conn->cli_max_recv_frag = MIN(0x2000, call->pkt.u.bind.max_recv_frag); - } - if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) && (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) { call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED; @@ -749,8 +765,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; - pkt.u.bind_ack.max_xmit_frag = call->conn->cli_max_recv_frag; - pkt.u.bind_ack.max_recv_frag = 0x2000; + pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag; + pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag; /* make it possible for iface->bind() to specify the assoc_group_id @@ -932,8 +948,8 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, } } pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; - pkt.u.alter_resp.max_xmit_frag = 0x2000; - pkt.u.alter_resp.max_recv_frag = 0x2000; + pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag; + pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag; if (result == 0) { pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id; } else { diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index bc1b8a9..081c3e7 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -204,7 +204,8 @@ struct dcesrv_connection { struct dcesrv_call_state *call_list; /* the maximum size the client wants to receive */ - uint32_t cli_max_recv_frag; + uint16_t max_recv_frag; + uint16_t max_xmit_frag; DATA_BLOB partial_input; -- 1.9.1 From 932a69d3710a8512936d1cfac1139cff7474c4bc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 376/440] CVE-2015-5370: s4:rpc_server: avoid ZERO_STRUCT() in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 322138c..5d76f4c 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -101,10 +101,10 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) { struct ncacn_packet pkt; struct data_blob_list_item *rep; - uint8_t zeros[4]; + static const uint8_t zeros[4] = { 0, }; NTSTATUS status; - /* setup a bind_ack */ + /* setup a fault */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; @@ -114,8 +114,6 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.u.fault.context_id = 0; pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - - ZERO_STRUCT(zeros); pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); rep = talloc_zero(call, struct data_blob_list_item); -- 1.9.1 From 0f51a5840aaefa1697823b5bcede9241fe6bcdc8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 377/440] CVE-2015-5370: s4:rpc_server: set alloc_hint = 24 in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a Windows 2012R2 server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 5d76f4c..9bbd623 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -110,7 +110,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.u.fault.alloc_hint = 0; + pkt.u.fault.alloc_hint = 24; pkt.u.fault.context_id = 0; pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; -- 1.9.1 From cacb63c5c46d36bd2a80fce639df67a90754ffd0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 378/440] CVE-2015-5370: s4:rpc_server: fill context_id in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This depends on the type of the incoming pdu. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 9bbd623..1ef3d05 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -111,7 +111,20 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.ptype = DCERPC_PKT_FAULT; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.u.fault.alloc_hint = 24; - pkt.u.fault.context_id = 0; + switch (call->pkt.ptype) { + case DCERPC_PKT_REQUEST: + pkt.u.fault.context_id = call->pkt.u.request.context_id; + break; + default: + pkt.u.fault.context_id = 0; + break; + } + if (fault_code == DCERPC_NCA_S_PROTO_ERROR) { + /* + * context_id = 0 is forced on protocol errors. + */ + pkt.u.fault.context_id = 0; + } pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); -- 1.9.1 From 76911dcffe07bef740698bb2a2ac69da7d491ab9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 379/440] CVE-2015-5370: s4:rpc_server: split out a dcesrv_fault_with_flags() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 1ef3d05..57e182a 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -97,7 +97,9 @@ void dcesrv_init_hdr(struct ncacn_packet *pkt, bool bigendian) /* return a dcerpc fault */ -NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) +NTSTATUS dcesrv_fault_with_flags(struct dcesrv_call_state *call, + uint32_t fault_code, + uint8_t extra_flags) { struct ncacn_packet pkt; struct data_blob_list_item *rep; @@ -109,7 +111,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; - pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.fault.alloc_hint = 24; switch (call->pkt.ptype) { case DCERPC_PKT_REQUEST: @@ -153,7 +155,10 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) return NT_STATUS_OK; } - +NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) +{ + return dcesrv_fault_with_flags(call, fault_code, 0); +} _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) { -- 1.9.1 From 329c109687f5d924853d188abb809511ca159458 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 380/440] CVE-2015-5370: s4:rpc_server: add some padding to dcesrv_bind_nak() responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches Windows 2012R2. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6df9f77..c0b770e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -462,6 +462,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) struct dcerpc_bind_nak_version version; struct data_blob_list_item *rep; NTSTATUS status; + static const uint8_t _pad[3] = { 0, }; /* setup a bind_nak */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); @@ -474,7 +475,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) version.rpc_vers_minor = 0; pkt.u.bind_nak.num_versions = 1; pkt.u.bind_nak.versions = &version; - pkt.u.bind_nak._pad = data_blob_null; + pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad)); rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { -- 1.9.1 From 93bb1f928710f806bc6edf648c9710efc4988dc7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 381/440] CVE-2015-5370: s4:rpc_server: return the correct secondary_address in dcesrv_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For now we still force \\PIPE\\ in upper case, we may be able to remove this and change it in our idl files later. But for now we better behave like a windows server without changing too much. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c0b770e..c66b193 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -638,6 +638,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t extra_flags = 0; uint16_t max_req = 0; uint16_t max_rep = 0; + const char *ep_prefix = ""; + const char *endpoint = NULL; /* max_recv_frag and max_xmit_frag result always in the same value! */ max_req = MIN(call->pkt.u.bind.max_xmit_frag, @@ -782,10 +784,31 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } if (iface) { - /* FIXME: Use pipe name as specified by endpoint instead of interface name */ - pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); - } else { - pkt.u.bind_ack.secondary_address = ""; + endpoint = dcerpc_binding_get_string_option( + call->conn->endpoint->ep_description, + "endpoint"); + } + + if (endpoint == NULL) { + endpoint = ""; + } + + if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) { + /* + * TODO: check if this is really needed + * + * Or if we should fix this in our idl files. + */ + ep_prefix = "\\PIPE\\"; + endpoint += 6; + } + + pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s", + ep_prefix, + endpoint); + if (pkt.u.bind_ack.secondary_address == NULL) { + TALLOC_FREE(call->context); + return NT_STATUS_NO_MEMORY; } pkt.u.bind_ack.num_results = 1; pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); -- 1.9.1 From a5997e6f59c7a1a8571d5021817a580fdcbbb3a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 382/440] CVE-2015-5370: s4:rpc_server: make dcesrv_process_ncacn_packet() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c66b193..b7a80be 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1282,9 +1282,9 @@ _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(stru /* process some input to a dcerpc endpoint server. */ -NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, - struct ncacn_packet *pkt, - DATA_BLOB blob) +static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, + struct ncacn_packet *pkt, + DATA_BLOB blob) { NTSTATUS status; struct dcesrv_call_state *call; -- 1.9.1 From dc15c79f0a948b8f50c0767edf8033c96005e40f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 383/440] CVE-2015-5370: s4:rpc_server: add infrastructure to terminate a connection after a response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BIND_NAK or FAULT may mark a connection as to be terminated. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 60 +++++++++++++++++++++++++++++++++++++- source4/rpc_server/dcerpc_server.h | 3 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b7a80be..1b5a924 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1628,6 +1628,7 @@ struct dcesrv_sock_reply_state { }; static void dcesrv_sock_reply_done(struct tevent_req *subreq); +static void dcesrv_call_terminate_step1(struct tevent_req *subreq); static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) { @@ -1654,7 +1655,7 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) DLIST_REMOVE(call->replies, rep); - if (call->replies == NULL) { + if (call->replies == NULL && call->terminate_reason == NULL) { substate->call = call; } @@ -1674,6 +1675,20 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) substate); } + if (call->terminate_reason != NULL) { + struct tevent_req *subreq; + + subreq = tevent_queue_wait_send(call, + dce_conn->event_ctx, + dce_conn->send_queue); + if (!subreq) { + dcesrv_terminate_connection(dce_conn, __location__); + return; + } + tevent_req_set_callback(subreq, dcesrv_call_terminate_step1, + call); + } + DLIST_REMOVE(call->conn->call_list, call); call->list = DCESRV_LIST_NONE; } @@ -1701,8 +1716,51 @@ static void dcesrv_sock_reply_done(struct tevent_req *subreq) } } +static void dcesrv_call_terminate_step2(struct tevent_req *subreq); + +static void dcesrv_call_terminate_step1(struct tevent_req *subreq) +{ + struct dcesrv_call_state *call = tevent_req_callback_data(subreq, + struct dcesrv_call_state); + bool ok; + struct timeval tv; + + /* make sure we stop send queue before removing subreq */ + tevent_queue_stop(call->conn->send_queue); + + ok = tevent_queue_wait_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + + /* disconnect after 200 usecs */ + tv = timeval_current_ofs_usec(200); + subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv); + if (subreq == NULL) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + tevent_req_set_callback(subreq, dcesrv_call_terminate_step2, + call); +} + +static void dcesrv_call_terminate_step2(struct tevent_req *subreq) +{ + struct dcesrv_call_state *call = tevent_req_callback_data(subreq, + struct dcesrv_call_state); + bool ok; + ok = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + dcesrv_terminate_connection(call->conn, call->terminate_reason); +} struct dcesrv_socket_context { const struct dcesrv_endpoint *endpoint; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 081c3e7..e1172c2 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -130,6 +130,9 @@ struct dcesrv_call_state { /* this is used by the boilerplate code to generate DCERPC faults */ uint32_t fault_code; + + /* the reason why we terminate the connection after sending a response */ + const char *terminate_reason; }; #define DCESRV_HANDLE_ANY 255 -- 1.9.1 From 0fdc309aa51d141220d9bb6569e2a0ff4777a0d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 384/440] CVE-2015-5370: s4:rpc_server: verify the protocol headers before processing pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On protocol errors we should send BIND_NAK or FAULT and mark the connection as to be terminated. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 106 +++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1b5a924..0c3af42 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -452,6 +452,18 @@ static void dcesrv_call_set_list(struct dcesrv_call_state *call, } } +static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, + const char *reason) +{ + if (call->conn->terminate != NULL) { + return; + } + + call->terminate_reason = talloc_strdup(call, reason); + if (call->terminate_reason == NULL) { + call->terminate_reason = __location__; + } +} /* return a dcerpc bind_nak @@ -464,6 +476,12 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) NTSTATUS status; static const uint8_t _pad[3] = { 0, }; + /* + * We add the call to the pending_call_list + * in order to defer the termination. + */ + dcesrv_call_disconnect_after(call, "dcesrv_bind_nak"); + /* setup a bind_nak */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; @@ -501,6 +519,19 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) return NT_STATUS_OK; } +static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call, + uint32_t fault_code) +{ + /* + * We add the call to the pending_call_list + * in order to defer the termination. + */ + dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect"); + + return dcesrv_fault_with_flags(call, fault_code, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); +} + static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c) { DLIST_REMOVE(c->conn->contexts, c); @@ -641,6 +672,23 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) const char *ep_prefix = ""; const char *endpoint = NULL; + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_BIND, + call->pkt.u.bind.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED); + } + /* max_recv_frag and max_xmit_frag result always in the same value! */ max_req = MIN(call->pkt.u.bind.max_xmit_frag, call->pkt.u.bind.max_recv_frag); @@ -864,6 +912,24 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) */ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) { + NTSTATUS status; + + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_AUTH3, + call->pkt.u.auth3.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* handle the auth3 in the auth code */ if (!dcesrv_auth_auth3(call)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); @@ -1033,6 +1099,22 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) NTSTATUS status; uint32_t context_id; + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_ALTER, + call->pkt.u.alter.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* handle any authentication that is being requested */ if (!dcesrv_auth_alter(call)) { /* TODO: work out the right reject code */ @@ -1310,9 +1392,27 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* we have to check the signing here, before combining the pdus */ - if (call->pkt.ptype == DCERPC_PKT_REQUEST && - !dcesrv_auth_request(call, &blob)) { - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_REQUEST, + call->pkt.u.request.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_PENDING_CANCEL | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + if (!dcesrv_auth_request(call, &blob)) { + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } } /* see if this is a continued packet */ -- 1.9.1 From 86e0e0f392b02c4da07286314f07f98adacecec8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 385/440] CVE-2015-5370: s4:rpc_server: ensure that the message ordering doesn't violate the spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first pdu is always a BIND. REQUEST pdus are only allowed once the authentication is finished. A simple anonymous authentication is finished after the BIND. Real authentication may need additional ALTER or AUTH3 exchanges. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 41 ++++++++++++++++++++++++++++++++++++-- source4/rpc_server/dcerpc_server.h | 8 ++++++++ source4/rpc_server/dcesrv_auth.c | 12 +++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0c3af42..5d1d76e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -408,6 +408,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->msg_ctx = msg_ctx; p->server_id = server_id; p->state_flags = state_flags; + p->allow_bind = true; p->max_recv_frag = 5840; p->max_xmit_frag = 5840; @@ -459,6 +460,11 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, return; } + call->conn->allow_bind = false; + call->conn->allow_alter = false; + call->conn->allow_auth3 = false; + call->conn->allow_request = false; + call->terminate_reason = talloc_strdup(call, reason); if (call->terminate_reason == NULL) { call->terminate_reason = __location__; @@ -914,6 +920,10 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) { NTSTATUS status; + if (!call->conn->allow_auth3) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_AUTH3, call->pkt.u.auth3.auth_info.length, @@ -1099,6 +1109,10 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) NTSTATUS status; uint32_t context_id; + if (!call->conn->allow_alter) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_ALTER, call->pkt.u.alter.auth_info.length, @@ -1224,6 +1238,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) NTSTATUS status; struct dcesrv_connection_context *context; + if (!call->conn->allow_request) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { @@ -1390,9 +1408,22 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, talloc_set_destructor(call, dcesrv_call_dequeue); + if (call->conn->allow_bind) { + /* + * Only one bind is possible per connection + */ + call->conn->allow_bind = false; + return dcesrv_bind(call); + } + /* we have to check the signing here, before combining the pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + if (!call->conn->allow_request) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_REQUEST, call->pkt.u.request.stub_and_verifier.length, @@ -1488,7 +1519,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, switch (call->pkt.ptype) { case DCERPC_PKT_BIND: - status = dcesrv_bind(call); + status = dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); break; case DCERPC_PKT_AUTH3: status = dcesrv_auth3(call); @@ -1500,7 +1532,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, status = dcesrv_request(call); break; default: - status = NT_STATUS_INVALID_PARAMETER; + status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); break; } @@ -1665,6 +1697,11 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons srv_conn = talloc_get_type(dce_conn->transport.private_data, struct stream_connection); + dce_conn->allow_bind = false; + dce_conn->allow_auth3 = false; + dce_conn->allow_alter = false; + dce_conn->allow_request = false; + if (dce_conn->pending_call_list == NULL) { char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index e1172c2..a881eeb 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -255,6 +255,14 @@ struct dcesrv_connection { /* the current authentication state */ struct dcesrv_auth auth_state; + + /* + * remember which pdu types are allowed + */ + bool allow_bind; + bool allow_auth3; + bool allow_alter; + bool allow_request; }; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 03231a5..f5086ac 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -130,7 +130,11 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe NTSTATUS status; bool want_header_signing = false; + dce_conn->allow_alter = true; + dce_conn->allow_auth3 = true; + if (call->pkt.auth_length == 0) { + dce_conn->allow_request = true; return NT_STATUS_OK; } @@ -161,6 +165,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->allow_request = true; if (!gensec_have_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER)) @@ -246,6 +251,8 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return false; } + dce_conn->allow_request = true; + /* Now that we are authenticated, go back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; return true; @@ -325,6 +332,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->allow_request = true; /* Now that we are authenticated, got back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; @@ -352,6 +360,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) uint32_t auth_length; size_t hdr_size = DCERPC_REQUEST_LENGTH; + if (!dce_conn->allow_request) { + return false; + } + if (!dce_conn->auth_state.auth_info || !dce_conn->auth_state.gensec_security) { if (pkt->auth_length != 0) { -- 1.9.1 From 3541495795ee2e63363ee15392b7c5a8742934af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 386/440] CVE-2015-5370: s4:rpc_server: maintain in and out struct dcerpc_auth per dcesrv_call_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should not use one "global" per connection variable to hold the incoming and outgoing auth_info. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- source4/rpc_server/dcerpc_server.c | 8 +- source4/rpc_server/dcerpc_server.h | 7 +- source4/rpc_server/dcesrv_auth.c | 149 ++++++++++++++++++++----------------- 4 files changed, 94 insertions(+), 72 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 57e182a..8f0e304 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -201,7 +201,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) request header size */ chunk_size = call->conn->max_xmit_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (call->conn->auth_state.auth_info && + if (call->conn->auth_state.auth_finished && call->conn->auth_state.gensec_security) { size_t max_payload = chunk_size; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5d1d76e..19bb48f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -891,7 +891,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } status = ncacn_push_auth(&rep->blob, call, &pkt, - call->conn->auth_state.auth_info); + call->out_auth_info); if (!NT_STATUS_IS_OK(status)) { talloc_free(call->context); call->context = NULL; @@ -924,6 +924,10 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } + if (call->conn->auth_state.auth_finished) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_AUTH3, call->pkt.u.auth3.auth_info.length, @@ -1082,7 +1086,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info); + status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index a881eeb..79bc458 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -133,6 +133,11 @@ struct dcesrv_call_state { /* the reason why we terminate the connection after sending a response */ const char *terminate_reason; + + /* temporary auth_info fields */ + struct dcerpc_auth in_auth_info; + struct dcerpc_auth _out_auth_info; + struct dcerpc_auth *out_auth_info; }; #define DCESRV_HANDLE_ANY 255 @@ -152,12 +157,12 @@ struct dcesrv_auth { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; - struct dcerpc_auth *auth_info; struct gensec_security *gensec_security; struct auth_session_info *session_info; NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); bool client_hdr_signing; bool hdr_signing; + bool auth_finished; }; struct dcesrv_connection_context { diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index f5086ac..565c373 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -50,25 +50,19 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) auth->auth_type = DCERPC_AUTH_TYPE_NONE; auth->auth_level = DCERPC_AUTH_LEVEL_NONE; auth->auth_context_id = 0; - dce_conn->auth_state.auth_info = NULL; return true; } - dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth); - if (!dce_conn->auth_state.auth_info) { - return false; - } - status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, - dce_conn->auth_state.auth_info, + &call->in_auth_info, &auth_length, false); if (!NT_STATUS_IS_OK(status)) { return false; } - auth->auth_type = dce_conn->auth_state.auth_info->auth_type; - auth->auth_level = dce_conn->auth_state.auth_info->auth_level; - auth->auth_context_id = dce_conn->auth_state.auth_info->auth_context_id; + auth->auth_type = call->in_auth_info.auth_type; + auth->auth_level = call->in_auth_info.auth_level; + auth->auth_context_id = call->in_auth_info.auth_context_id; server_credentials = cli_credentials_init(call); @@ -134,6 +128,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe dce_conn->allow_auth3 = true; if (call->pkt.auth_length == 0) { + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; return NT_STATUS_OK; } @@ -152,10 +147,17 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe want_header_signing = false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, @@ -165,6 +167,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; if (!gensec_have_feature(dce_conn->auth_state.gensec_security, @@ -184,9 +187,6 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe dce_conn->auth_state.session_key = dcesrv_generic_session_key; return NT_STATUS_OK; } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - dce_conn->auth_state.auth_info->auth_pad_length = 0; - dce_conn->auth_state.auth_info->auth_reserved = 0; - if (!gensec_have_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER)) { @@ -223,7 +223,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) return false; } - if (!dce_conn->auth_state.auth_info) { + if (dce_conn->auth_state.auth_finished) { return false; } @@ -233,16 +233,23 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) } status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, - dce_conn->auth_state.auth_info, &auth_length, true); + &call->in_auth_info, &auth_length, true); if (!NT_STATUS_IS_OK(status)) { return false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + /* Pass the extra data we got from the client down to gensec for processing */ status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, dce_conn, @@ -251,6 +258,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return false; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; /* Now that we are authenticated, go back to the generic session key... */ @@ -277,22 +285,23 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) /* on a pure interface change there is no auth blob */ if (pkt->auth_length == 0) { + if (!dce_conn->auth_state.auth_finished) { + return false; + } return true; } - /* We can't work without an existing gensec state */ - if (!dce_conn->auth_state.gensec_security) { + if (dce_conn->auth_state.auth_finished) { return false; } - dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth); - if (!dce_conn->auth_state.auth_info) { + /* We can't work without an existing gensec state */ + if (!dce_conn->auth_state.gensec_security) { return false; } status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, - dce_conn->auth_state.auth_info, - &auth_length, true); + &call->in_auth_info, &auth_length, true); if (!NT_STATUS_IS_OK(status)) { return false; } @@ -316,13 +325,20 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack } if (!call->conn->auth_state.gensec_security) { - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_INTERNAL_ERROR; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, @@ -332,14 +348,13 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; /* Now that we are authenticated, got back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; return NT_STATUS_OK; } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - dce_conn->auth_state.auth_info->auth_pad_length = 0; - dce_conn->auth_state.auth_info->auth_reserved = 0; return NT_STATUS_OK; } @@ -355,7 +370,6 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) { struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; - struct dcerpc_auth auth; NTSTATUS status; uint32_t auth_length; size_t hdr_size = DCERPC_REQUEST_LENGTH; @@ -364,19 +378,11 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } - if (!dce_conn->auth_state.auth_info || - !dce_conn->auth_state.gensec_security) { - if (pkt->auth_length != 0) { - return false; - } - return true; - } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { hdr_size += 16; } - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: break; @@ -396,36 +402,41 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } + if (!dce_conn->auth_state.gensec_security) { + return false; + } + status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.request.stub_and_verifier, - &auth, &auth_length, false); + &call->in_auth_info, &auth_length, false); if (!NT_STATUS_IS_OK(status)) { return false; } - if (auth.auth_type != dce_conn->auth_state.auth_info->auth_type) { + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { return false; } - if (auth.auth_level != dce_conn->auth_state.auth_info->auth_level) { + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { return false; } - if (auth.auth_context_id != dce_conn->auth_state.auth_info->auth_context_id) { + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { return false; } pkt->u.request.stub_and_verifier.length -= auth_length; /* check signature or unseal the packet */ - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(dce_conn->auth_state.gensec_security, full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length, full_packet->data, - full_packet->length-auth.credentials.length, - &auth.credentials); + full_packet->length- + call->in_auth_info.credentials.length, + &call->in_auth_info.credentials); memcpy(pkt->u.request.stub_and_verifier.data, full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length); @@ -436,8 +447,9 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) pkt->u.request.stub_and_verifier.data, pkt->u.request.stub_and_verifier.length, full_packet->data, - full_packet->length-auth.credentials.length, - &auth.credentials); + full_packet->length- + call->in_auth_info.credentials.length, + &call->in_auth_info.credentials); break; case DCERPC_AUTH_LEVEL_CONNECT: @@ -451,10 +463,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) } /* remove the indicated amount of padding */ - if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) { + if (pkt->u.request.stub_and_verifier.length < call->in_auth_info.auth_pad_length) { return false; } - pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length; + pkt->u.request.stub_and_verifier.length -= call->in_auth_info.auth_pad_length; return NT_STATUS_IS_OK(status); } @@ -474,13 +486,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, uint32_t payload_length; DATA_BLOB creds2; - /* non-signed packets are simple */ - if (dce_conn->auth_state.auth_info == NULL) { - status = ncacn_push_auth(blob, call, pkt, NULL); - return NT_STATUS_IS_OK(status); - } - - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: if (sig_size == 0) { @@ -505,6 +511,10 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, return false; } + if (!dce_conn->auth_state.gensec_security) { + return false; + } + ndr = ndr_push_init_ctx(call); if (!ndr) { return false; @@ -519,28 +529,31 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, return false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + /* pad to 16 byte multiple in the payload portion of the packet. This matches what w2k3 does. Note that we can't use ndr_push_align() as that is relative to the start of the whole packet, whereas w2k8 wants it relative to the start of the stub */ - dce_conn->auth_state.auth_info->auth_pad_length = + call->out_auth_info->auth_pad_length = DCERPC_AUTH_PAD_LENGTH(pkt->u.response.stub_and_verifier.length); - ndr_err = ndr_push_zero(ndr, - dce_conn->auth_state.auth_info->auth_pad_length); + ndr_err = ndr_push_zero(ndr, call->out_auth_info->auth_pad_length); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } payload_length = pkt->u.response.stub_and_verifier.length + - dce_conn->auth_state.auth_info->auth_pad_length; - - /* we start without signature, it will appended later */ - dce_conn->auth_state.auth_info->credentials = data_blob(NULL, 0); + call->out_auth_info->auth_pad_length; /* add the auth verifier */ ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, - dce_conn->auth_state.auth_info); + call->out_auth_info); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } @@ -558,7 +571,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, dcerpc_set_auth_length(blob, sig_size); /* sign or seal the packet */ - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(dce_conn->auth_state.gensec_security, call, @@ -591,7 +604,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, if (creds2.length != sig_size) { DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", (unsigned)creds2.length, (uint32_t)sig_size, - (unsigned)dce_conn->auth_state.auth_info->auth_pad_length, + (unsigned)call->out_auth_info->auth_pad_length, (unsigned)pkt->u.response.stub_and_verifier.length)); dcerpc_set_frag_length(blob, blob->length + creds2.length); dcerpc_set_auth_length(blob, creds2.length); -- 1.9.1 From b21d9a319e4e3f66c5de1f162feac5b7c3369cf2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 387/440] CVE-2015-5370: s4:rpc_server: make sure alter_context and auth3 can't change auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcesrv_auth.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 565c373..afa584b 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -238,6 +238,18 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) return false; } + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + return false; + } + + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + return false; + } + + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + return false; + } + call->_out_auth_info = (struct dcerpc_auth) { .auth_type = dce_conn->auth_state.auth_type, .auth_level = dce_conn->auth_state.auth_level, @@ -306,6 +318,18 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) return false; } + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + return false; + } + + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + return false; + } + + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + return false; + } + return true; } -- 1.9.1 From ba85cda6fe2e3d086fd1561d1783e55895e03a60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 388/440] CVE-2015-5370: s4:rpc_server: let invalid request fragments disconnect the connection with a protocol error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 19bb48f..6587318 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1456,33 +1456,34 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, struct dcesrv_call_state *call2 = call; uint32_t alloc_size; - /* we only allow fragmented requests, no other packet types */ - if (call->pkt.ptype != DCERPC_PKT_REQUEST) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); - } - /* this is a continuation of an existing call - find the call then tack it on the end */ call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); if (!call) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); + return dcesrv_fault_disconnect(call2, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.ptype != call2->pkt.ptype) { /* trying to play silly buggers are we? */ - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (memcmp(call->pkt.drep, call2->pkt.drep, sizeof(pkt->drep)) != 0) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.call_id != call2->pkt.call_id) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.u.request.context_id != call2->pkt.u.request.context_id) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.u.request.opnum != call2->pkt.u.request.opnum) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } alloc_size = call->pkt.u.request.stub_and_verifier.length + -- 1.9.1 From 39f6748e6b3d1a142bbf821dc36b547c0980057a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 389/440] CVE-2015-5370: s4:rpc_server: remove pointless dcesrv_find_context() from dcesrv_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BIND is the first pdu, which means the list of contexts is always empty. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6587318..7721bc1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -726,12 +726,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } context_id = call->pkt.u.bind.ctx_list[0].context_id; - - /* you can't bind twice on one context */ - if (dcesrv_find_context(call->conn, context_id) != NULL) { - return dcesrv_bind_nak(call, 0); - } - if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid; -- 1.9.1 From 3ac8d5365b0b68b0e8c81e4c8fd0adb7eb352854 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 390/440] CVE-2015-5370: s4:rpc_server: don't derefence an empty ctx_list array in dcesrv_alter() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7721bc1..750a28d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1105,7 +1105,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { NTSTATUS status; - uint32_t context_id; + const struct dcerpc_ctx_list *ctx = NULL; if (!call->conn->allow_alter) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); @@ -1135,12 +1135,18 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_REASON_ASYNTAX); } - context_id = call->pkt.u.alter.ctx_list[0].context_id; + if (call->pkt.u.alter.num_contexts < 1) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + ctx = &call->pkt.u.alter.ctx_list[0]; + if (ctx->num_transfer_syntaxes < 1) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } /* see if they are asking for a new interface */ - call->context = dcesrv_find_context(call->conn, context_id); + call->context = dcesrv_find_context(call->conn, ctx->context_id); if (!call->context) { - status = dcesrv_alter_new_context(call, context_id); + status = dcesrv_alter_new_context(call, ctx->context_id); if (!NT_STATUS_IS_OK(status)) { return dcesrv_alter_resp(call, DCERPC_BIND_PROVIDER_REJECT, -- 1.9.1 From 0f3a86c7c0a7708b434ec83e566aec99c5f3710a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 391/440] CVE-2015-5370: s4:rpc_server: changing an existing presentation context via alter_context is a protocol error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 750a28d..9885524 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1152,6 +1152,27 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_PROVIDER_REJECT, DCERPC_BIND_REASON_ASYNTAX); } + } else { + bool ok; + + ok = ndr_syntax_id_equal(&ctx->abstract_syntax, + &call->context->iface->syntax_id); + if (!ok) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + if (ctx->num_transfer_syntaxes != 1) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0], + &ndr_transfer_syntax_ndr); + if (!ok) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } } if (call->pkt.u.alter.assoc_group_id != 0 && -- 1.9.1 From 8c06c0a46628aefdff980e2caee4bda7ae8782b0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 392/440] CVE-2015-5370: s4:rpc_server: fix the order of error checking in dcesrv_alter() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The basically matches Windows 2012R2, it's not 100% but it's enough for our raw protocol tests to pass. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9885524..ee6ee95 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1106,6 +1106,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { NTSTATUS status; const struct dcerpc_ctx_list *ctx = NULL; + bool auth_ok = false; if (!call->conn->allow_alter) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); @@ -1127,12 +1128,12 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } - /* handle any authentication that is being requested */ - if (!dcesrv_auth_alter(call)) { - /* TODO: work out the right reject code */ - return dcesrv_alter_resp(call, - DCERPC_BIND_PROVIDER_REJECT, - DCERPC_BIND_REASON_ASYNTAX); + auth_ok = dcesrv_auth_alter(call); + if (!auth_ok) { + if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_ACCESS_DENIED); + } } if (call->pkt.u.alter.num_contexts < 1) { @@ -1186,6 +1187,17 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_REASON_ASYNTAX); } + /* handle any authentication that is being requested */ + if (!auth_ok) { + if (call->in_auth_info.auth_type != + call->conn->auth_state.auth_type) + { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_SEC_PKG_ERROR); + } + return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED); + } + return dcesrv_alter_resp(call, DCERPC_BIND_ACK_RESULT_ACCEPTANCE, DCERPC_BIND_ACK_REASON_NOT_SPECIFIED); -- 1.9.1 From 89727af0c169bcb76a18f87de80300aef49dba83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 393/440] CVE-2015-5370: s4:rpc_server: failing authentication should generate a SEC_PKG_ERROR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ee6ee95..d1d2d8c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1066,13 +1066,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, status = dcesrv_auth_alter_ack(call, &pkt); if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) - || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE) - || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) - || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); - } - return dcesrv_fault(call, 0); + return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR); } rep = talloc_zero(call, struct data_blob_list_item); -- 1.9.1 From e3458cc5aab107c74002121d1e9fbcc3e56b1ee4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 394/440] CVE-2015-5370: s4:rpc_server: let a failing auth3 mark the authentication as invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following requests will generate a fault with ACCESS_DENIED. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 2 +- source4/rpc_server/dcerpc_server.h | 1 + source4/rpc_server/dcesrv_auth.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d1d2d8c..9cf7249 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -940,7 +940,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) /* handle the auth3 in the auth code */ if (!dcesrv_auth_auth3(call)) { - return dcesrv_fault(call, DCERPC_FAULT_OTHER); + call->conn->auth_state.auth_invalid = true; } talloc_free(call); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 79bc458..74f0841 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -163,6 +163,7 @@ struct dcesrv_auth { bool client_hdr_signing; bool hdr_signing; bool auth_finished; + bool auth_invalid; }; struct dcesrv_connection_context { diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index afa584b..f3de2c3 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -275,6 +275,13 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) /* Now that we are authenticated, go back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; + + if (call->out_auth_info->credentials.length != 0) { + + DEBUG(4, ("GENSEC produced output token (len=%u) at bind_auth3\n", + (unsigned)call->out_auth_info->credentials.length)); + return false; + } return true; } else { DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_auth3: %s\n", @@ -402,6 +409,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } + if (dce_conn->auth_state.auth_invalid) { + return false; + } + if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { hdr_size += 16; } -- 1.9.1 From 05ec02dcc365927bda3675e5a92e590a56421a71 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 395/440] CVE-2015-5370: s4:rpc_server: disconnect after a failing dcesrv_auth_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9cf7249..b7da76f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1473,6 +1473,13 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, } if (!dcesrv_auth_request(call, &blob)) { + /* + * We don't use dcesrv_fault_disconnect() + * here, because we don't want to set + * DCERPC_PFC_FLAG_DID_NOT_EXECUTE + */ + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - failed"); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); } } -- 1.9.1 From d99bb2e36fa4b8b0be34317dc8c3d4d5217cc779 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:55:27 +0200 Subject: [PATCH 396/440] CVE-2015-5370: s4:rpc_server: give the correct reject reasons for invalid auth_level values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 17 ++++++++++++++--- source4/rpc_server/dcesrv_auth.c | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b7da76f..50b32c9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -805,9 +805,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { - talloc_free(call->context); - call->context = NULL; - return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE); + struct dcesrv_auth *auth = &call->conn->auth_state; + + TALLOC_FREE(call->context); + + if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) { + /* + * We only give INVALID_AUTH_TYPE if the auth_level was + * valid. + */ + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE); + } + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); } /* setup a bind_ack */ diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index f3de2c3..2b3f8b0 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -60,6 +60,30 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + switch (call->in_auth_info.auth_level) { + case DCERPC_AUTH_LEVEL_CONNECT: + case DCERPC_AUTH_LEVEL_CALL: + case DCERPC_AUTH_LEVEL_PACKET: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + /* + * We evaluate auth_type only if auth_level was valid + */ + break; + default: + /* + * Setting DCERPC_AUTH_LEVEL_NONE, + * gives the caller a chance to decide what + * reject_reason to use + * + * Note: DCERPC_AUTH_LEVEL_NONE == 1 + */ + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = 0; + return false; + } + auth->auth_type = call->in_auth_info.auth_type; auth->auth_level = call->in_auth_info.auth_level; auth->auth_context_id = call->in_auth_info.auth_context_id; -- 1.9.1 From 093a9a9c505536fe2aca014f057f61dc63dae7cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 17:21:05 +0200 Subject: [PATCH 397/440] CVE-2015-5370: s4:rpc_server: check frag_length for requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note this is not the negotiated fragment size, but a hardcoded maximum. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 50b32c9..f896606 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1483,6 +1483,21 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) { + /* + * We don't use dcesrv_fault_disconnect() + * here, because we don't want to set + * DCERPC_PFC_FLAG_DID_NOT_EXECUTE + * + * Note that we don't check against the negotiated + * max_recv_frag, but a hard coded value. + */ + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - frag_length too large"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + if (!dcesrv_auth_request(call, &blob)) { /* * We don't use dcesrv_fault_disconnect() -- 1.9.1 From 4e546ce6d8d595ebf08803ea4a5ce0ae5082619e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 14:18:09 +0200 Subject: [PATCH 398/440] CVE-2015-5370: s4:rpc_server: limit allocation and alloc_hint to 4 MByte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 45 +++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f896606..81cb931 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1514,7 +1514,9 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; - uint32_t alloc_size; + size_t available; + size_t alloc_size; + size_t alloc_hint; /* this is a continuation of an existing call - find the call then tack it on the end */ @@ -1546,18 +1548,43 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + /* + * Up to 4 MByte are allowed by all fragments + */ + available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; + if (call->pkt.u.request.stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - current payload too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + available -= call->pkt.u.request.stub_and_verifier.length; + if (call2->pkt.u.request.alloc_hint > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - alloc hint too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + if (call2->pkt.u.request.stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - new payload too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + alloc_hint = call->pkt.u.request.stub_and_verifier.length + + call2->pkt.u.request.alloc_hint; + /* allocate at least 1 byte */ + alloc_hint = MAX(alloc_hint, 1); alloc_size = call->pkt.u.request.stub_and_verifier.length + call2->pkt.u.request.stub_and_verifier.length; - if (call->pkt.u.request.alloc_hint > alloc_size) { - alloc_size = call->pkt.u.request.alloc_hint; - } + alloc_size = MAX(alloc_size, alloc_hint); call->pkt.u.request.stub_and_verifier.data = talloc_realloc(call, call->pkt.u.request.stub_and_verifier.data, uint8_t, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); + TALLOC_FREE(call2); + return dcesrv_fault_with_flags(call, + DCERPC_FAULT_OUT_OF_RESOURCES, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); } memcpy(call->pkt.u.request.stub_and_verifier.data + call->pkt.u.request.stub_and_verifier.length, @@ -1575,6 +1602,14 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, just put it on the incoming_fragmented_call_list and wait for the rest */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + /* + * Up to 4 MByte are allowed by all fragments + */ + if (call->pkt.u.request.alloc_hint > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - initial alloc hint too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST); return NT_STATUS_OK; } -- 1.9.1 From 81e09f7c8703d9c86da17d505f455d8cf6579eaa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 05:01:26 +0200 Subject: [PATCH 399/440] CVE-2015-5370: s4:rpc_server: only allow one fragmented call_id at a time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a protocol error if the client doesn't send all fragments of a request in one go. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 142 +++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 81cb931..d10fe9a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1430,6 +1430,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, { NTSTATUS status; struct dcesrv_call_state *call; + struct dcesrv_call_state *existing = NULL; call = talloc_zero(dce_conn, struct dcesrv_call_state); if (!call) { @@ -1498,6 +1499,54 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) { + /* only one request is possible in the fragmented list */ + if (dce_conn->incoming_fragmented_call_list != NULL) { + TALLOC_FREE(call); + call = dce_conn->incoming_fragmented_call_list; + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - " + "existing fragmented call"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + } else { + const struct dcerpc_request *nr = &call->pkt.u.request; + const struct dcerpc_request *er = NULL; + int cmp; + + existing = dcesrv_find_fragmented_call(dce_conn, + call->pkt.call_id); + if (existing == NULL) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - " + "no existing fragmented call"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + er = &existing->pkt.u.request; + + if (call->pkt.ptype != existing->pkt.ptype) { + /* trying to play silly buggers are we? */ + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + cmp = memcmp(call->pkt.drep, existing->pkt.drep, + sizeof(pkt->drep)); + if (cmp != 0) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + if (nr->context_id != er->context_id) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + if (nr->opnum != er->opnum) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + } + if (!dcesrv_auth_request(call, &blob)) { /* * We don't use dcesrv_fault_disconnect() @@ -1511,91 +1560,60 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, } /* see if this is a continued packet */ - if (call->pkt.ptype == DCERPC_PKT_REQUEST && - !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { - struct dcesrv_call_state *call2 = call; + if (existing != NULL) { + struct dcerpc_request *er = &existing->pkt.u.request; + const struct dcerpc_request *nr = &call->pkt.u.request; size_t available; size_t alloc_size; size_t alloc_hint; - /* this is a continuation of an existing call - find the call - then tack it on the end */ - call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); - if (!call) { - return dcesrv_fault_disconnect(call2, - DCERPC_NCA_S_PROTO_ERROR); - } - - if (call->pkt.ptype != call2->pkt.ptype) { - /* trying to play silly buggers are we? */ - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (memcmp(call->pkt.drep, call2->pkt.drep, sizeof(pkt->drep)) != 0) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.call_id != call2->pkt.call_id) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.u.request.context_id != call2->pkt.u.request.context_id) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.u.request.opnum != call2->pkt.u.request.opnum) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - /* * Up to 4 MByte are allowed by all fragments */ available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; - if (call->pkt.u.request.stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - current payload too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + if (er->stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(existing, + "dcesrv_auth_request - existing payload too large"); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - available -= call->pkt.u.request.stub_and_verifier.length; - if (call2->pkt.u.request.alloc_hint > available) { - dcesrv_call_disconnect_after(call, + available -= er->stub_and_verifier.length; + if (nr->alloc_hint > available) { + dcesrv_call_disconnect_after(existing, "dcesrv_auth_request - alloc hint too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - if (call2->pkt.u.request.stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(call, + if (nr->stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(existing, "dcesrv_auth_request - new payload too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - alloc_hint = call->pkt.u.request.stub_and_verifier.length + - call2->pkt.u.request.alloc_hint; + alloc_hint = er->stub_and_verifier.length + nr->alloc_hint; /* allocate at least 1 byte */ alloc_hint = MAX(alloc_hint, 1); - alloc_size = call->pkt.u.request.stub_and_verifier.length + - call2->pkt.u.request.stub_and_verifier.length; + alloc_size = er->stub_and_verifier.length + + nr->stub_and_verifier.length; alloc_size = MAX(alloc_size, alloc_hint); - call->pkt.u.request.stub_and_verifier.data = - talloc_realloc(call, - call->pkt.u.request.stub_and_verifier.data, + er->stub_and_verifier.data = + talloc_realloc(existing, + er->stub_and_verifier.data, uint8_t, alloc_size); - if (!call->pkt.u.request.stub_and_verifier.data) { - TALLOC_FREE(call2); - return dcesrv_fault_with_flags(call, + if (er->stub_and_verifier.data == NULL) { + TALLOC_FREE(call); + return dcesrv_fault_with_flags(existing, DCERPC_FAULT_OUT_OF_RESOURCES, DCERPC_PFC_FLAG_DID_NOT_EXECUTE); } - memcpy(call->pkt.u.request.stub_and_verifier.data + - call->pkt.u.request.stub_and_verifier.length, - call2->pkt.u.request.stub_and_verifier.data, - call2->pkt.u.request.stub_and_verifier.length); - call->pkt.u.request.stub_and_verifier.length += - call2->pkt.u.request.stub_and_verifier.length; + memcpy(er->stub_and_verifier.data + + er->stub_and_verifier.length, + nr->stub_and_verifier.data, + nr->stub_and_verifier.length); + er->stub_and_verifier.length += nr->stub_and_verifier.length; - call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); + existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); - talloc_free(call2); + TALLOC_FREE(call); + call = existing; } /* this may not be the last pdu in the chain - if its isn't then -- 1.9.1 From f2689cc0526da1ec036b412ef977a94c67a8d198 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 400/440] CVE-2015-5370: s4:rpc_server: the assoc_group is relative to the connection (association) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All presentation contexts of a connection use the same association group. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 76 +++++++------------------------ source4/rpc_server/dcerpc_server.h | 4 ++ source4/rpc_server/handles.c | 8 ++-- source4/rpc_server/remote/dcesrv_remote.c | 8 ++-- 4 files changed, 29 insertions(+), 67 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d10fe9a..b79fded 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -42,9 +42,6 @@ #include "lib/util/samba_modules.h" #include "librpc/gen_ndr/ndr_dcerpc.h" -/* this is only used when the client asks for an unknown interface */ -#define DUMMY_ASSOC_GROUP 0x0FFFFFFF - extern const struct dcesrv_interface dcesrv_mgmt_interface; @@ -74,7 +71,7 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_c assoc_group = dcesrv_assoc_group_find(dce_ctx, id); if (assoc_group == NULL) { - DEBUG(0,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); + DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); return NULL; } return talloc_reference(mem_ctx, assoc_group); @@ -714,10 +711,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* if provided, check the assoc_group is valid */ - if (call->pkt.u.bind.assoc_group_id != 0 && - lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && - dcesrv_assoc_group_find(call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id) == NULL) { - return dcesrv_bind_nak(call, 0); + if (call->pkt.u.bind.assoc_group_id != 0) { + call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn, + call->conn->dce_ctx, + call->pkt.u.bind.assoc_group_id); + } else { + call->conn->assoc_group = dcesrv_assoc_group_new(call->conn, + call->conn->dce_ctx); + } + if (call->conn->assoc_group == NULL) { + return dcesrv_bind_nak(call, 0); } if (call->pkt.u.bind.num_contexts < 1 || @@ -761,17 +764,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) context->conn = call->conn; context->iface = iface; context->context_id = context_id; - if (call->pkt.u.bind.assoc_group_id != 0) { - context->assoc_group = dcesrv_assoc_group_reference(context, - call->conn->dce_ctx, - call->pkt.u.bind.assoc_group_id); - } else { - context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); - } - if (context->assoc_group == NULL) { - talloc_free(context); - return dcesrv_bind_nak(call, 0); - } + /* legacy for openchange dcesrv_mapiproxy.c */ + context->assoc_group = call->conn->assoc_group; context->private_data = NULL; DLIST_ADD(call->conn->contexts, context); call->context = context; @@ -829,18 +823,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag; pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag; - - /* - make it possible for iface->bind() to specify the assoc_group_id - This helps the openchange mapiproxy plugin to work correctly. - - metze - */ - if (call->context) { - pkt.u.bind_ack.assoc_group_id = call->context->assoc_group->id; - } else { - pkt.u.bind_ack.assoc_group_id = DUMMY_ASSOC_GROUP; - } + pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id; if (iface) { endpoint = dcerpc_binding_get_string_option( @@ -1000,18 +983,8 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ context->conn = call->conn; context->iface = iface; context->context_id = context_id; - if (call->pkt.u.alter.assoc_group_id != 0) { - context->assoc_group = dcesrv_assoc_group_reference(context, - call->conn->dce_ctx, - call->pkt.u.alter.assoc_group_id); - } else { - context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); - } - if (context->assoc_group == NULL) { - talloc_free(context); - call->context = NULL; - return NT_STATUS_NO_MEMORY; - } + /* legacy for openchange dcesrv_mapiproxy.c */ + context->assoc_group = call->conn->assoc_group; context->private_data = NULL; DLIST_ADD(call->conn->contexts, context); call->context = context; @@ -1059,11 +1032,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag; pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag; - if (result == 0) { - pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id; - } else { - pkt.u.alter_resp.assoc_group_id = 0; - } + pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id; pkt.u.alter_resp.num_results = 1; pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.alter_resp.ctx_list) { @@ -1181,17 +1150,6 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } } - if (call->pkt.u.alter.assoc_group_id != 0 && - lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && - call->pkt.u.alter.assoc_group_id != call->context->assoc_group->id) { - DEBUG(0,(__location__ ": Failed attempt to use new assoc_group in alter context (0x%08x 0x%08x)\n", - call->context->assoc_group->id, call->pkt.u.alter.assoc_group_id)); - /* TODO: can they ask for a new association group? */ - return dcesrv_alter_resp(call, - DCERPC_BIND_PROVIDER_REJECT, - DCERPC_BIND_REASON_ASYNTAX); - } - /* handle any authentication that is being requested */ if (!auth_ok) { if (call->in_auth_info.auth_type != diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 74f0841..15b25ea 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -170,6 +170,7 @@ struct dcesrv_connection_context { struct dcesrv_connection_context *next, *prev; uint32_t context_id; + /* TODO: remove this legacy (for openchange) in master */ struct dcesrv_assoc_group *assoc_group; /* the connection this is on */ @@ -269,6 +270,9 @@ struct dcesrv_connection { bool allow_auth3; bool allow_alter; bool allow_request; + + /* the association group the connection belongs to */ + struct dcesrv_assoc_group *assoc_group; }; diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index f99ee1d..820da49 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -46,7 +46,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; - h = talloc_zero(context->assoc_group, struct dcesrv_handle); + h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle); if (!h) { return NULL; } @@ -56,12 +56,12 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex talloc_free(h); return NULL; } - h->assoc_group = context->assoc_group; + h->assoc_group = context->conn->assoc_group; h->iface = context->iface; h->wire_handle.handle_type = handle_type; h->wire_handle.uuid = GUID_random(); - DLIST_ADD(context->assoc_group->handles, h); + DLIST_ADD(context->conn->assoc_group->handles, h); talloc_set_destructor(h, dcesrv_handle_destructor); @@ -87,7 +87,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( return dcesrv_handle_new(context, handle_type); } - for (h=context->assoc_group->handles; h; h=h->next) { + for (h=context->conn->assoc_group->handles; h; h=h->next) { if (h->wire_handle.handle_type == p->handle_type && GUID_equal(&p->uuid, &h->wire_handle.uuid)) { if (handle_type != DCESRV_HANDLE_ANY && diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index be4bd12..3eb0ad4 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -117,9 +117,9 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } /* If we already have a remote association group ID, then use that */ - if (dce_call->context->assoc_group->proxied_id != 0) { + if (dce_call->conn->assoc_group->proxied_id != 0) { status = dcerpc_binding_set_assoc_group_id(b, - dce_call->context->assoc_group->proxied_id); + dce_call->conn->assoc_group->proxied_id); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_assoc_group_id() - %s'\n", nt_errstr(status))); @@ -148,8 +148,8 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->context->assoc_group->proxied_id == 0) { - dce_call->context->assoc_group->proxied_id = + if (dce_call->conn->assoc_group->proxied_id == 0) { + dce_call->conn->assoc_group->proxied_id = dcerpc_binding_get_assoc_group_id(priv->c_pipe->binding); } -- 1.9.1 From cfce22f2e4115600ac76deb385b496057a802938 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 401/440] CVE-2015-5370: s4:rpc_server: reject DCERPC_PFC_FLAG_PENDING_CANCEL with DCERPC_FAULT_NO_CALL_ACTIVE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b79fded..278e1af 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1468,6 +1468,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, return dcesrv_fault(call, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_NO_CALL_ACTIVE); + } } else { const struct dcerpc_request *nr = &call->pkt.u.request; const struct dcerpc_request *er = NULL; -- 1.9.1 From ec63d43cfbb4fa9065a4f0b72414727b9331c561 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 402/440] CVE-2015-5370: librpc/rpc: don't allow pkt->auth_length == 0 in dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers should have already checked that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 2f81447..43e1b7f 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -102,6 +102,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, } /* Paranoia checks for auth_length. The caller should check this... */ + if (pkt->auth_length == 0) { + return NT_STATUS_INTERNAL_ERROR; + } + + /* Paranoia checks for auth_length. The caller should check this... */ if (pkt->auth_length > pkt->frag_length) { return NT_STATUS_INTERNAL_ERROR; } -- 1.9.1 From ef68b2ec14292b5af48b4f7590394159619c9c36 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 403/440] CVE-2015-5370: s3:librpc/rpc: remove auth trailer and possible padding within dcerpc_check_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies the callers a lot. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 5 ++--- source3/librpc/rpc/dcerpc_helpers.c | 31 ++++++++++++++++++++----------- source3/rpc_client/cli_pipe.c | 33 ++++++++++----------------------- source3/rpc_server/srv_pipe.c | 17 +---------------- 4 files changed, 33 insertions(+), 53 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index e7d66b7..0a82e7e 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -83,8 +83,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, struct ncacn_packet *pkt, DATA_BLOB *pkt_trailer, - size_t header_size, - DATA_BLOB *raw_pkt, - size_t *pad_len); + uint8_t header_size, + DATA_BLOB *raw_pkt); #endif /* __S3_DCERPC_H__ */ diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 96074a4..bb1da46 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -481,19 +481,18 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, * * @param auth The auth data for the connection * @param pkt The actual ncacn_packet -* @param pkt_trailer The stub_and_verifier part of the packet +* @param pkt_trailer [in][out] The stub_and_verifier part of the packet, +* the auth_trailer and padding will be removed. * @param header_size The header size * @param raw_pkt The whole raw packet data blob -* @param pad_len [out] The padding length used in the packet * * @return A NTSTATUS error code */ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, struct ncacn_packet *pkt, DATA_BLOB *pkt_trailer, - size_t header_size, - DATA_BLOB *raw_pkt, - size_t *pad_len) + uint8_t header_size, + DATA_BLOB *raw_pkt) { struct gensec_security *gensec_security; NTSTATUS status; @@ -502,6 +501,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, DATA_BLOB full_pkt; DATA_BLOB data; + /* + * These check should be done in the caller. + */ + SMB_ASSERT(raw_pkt->length == pkt->frag_length); + SMB_ASSERT(header_size <= pkt->frag_length); + SMB_ASSERT(pkt_trailer->length < pkt->frag_length); + SMB_ASSERT((pkt_trailer->length + header_size) <= pkt->frag_length); + switch (auth->auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: DEBUG(10, ("Requested Privacy.\n")); @@ -515,7 +522,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, if (pkt->auth_length != 0) { break; } - *pad_len = 0; return NT_STATUS_OK; case DCERPC_AUTH_LEVEL_NONE: @@ -524,7 +530,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, "authenticated connection!\n")); return NT_STATUS_INVALID_PARAMETER; } - *pad_len = 0; return NT_STATUS_OK; default: @@ -543,10 +548,11 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return status; } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, - pkt_trailer->length - auth_length); - full_pkt = data_blob_const(raw_pkt->data, - raw_pkt->length - auth_info.credentials.length); + pkt_trailer->length); + full_pkt = data_blob_const(raw_pkt->data, raw_pkt->length); + full_pkt.length -= auth_info.credentials.length; switch (auth->auth_type) { case DCERPC_AUTH_TYPE_NONE: @@ -571,10 +577,13 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, * pkt_trailer actually has a copy of the raw data, and they * are still both used in later calls */ if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + if (pkt_trailer->length != data.length) { + return NT_STATUS_INVALID_PARAMETER; + } memcpy(pkt_trailer->data, data.data, data.length); } - *pad_len = auth_info.auth_pad_length; + pkt_trailer->length -= auth_info.auth_pad_length; data_blob_free(&auth_info.credentials); return NT_STATUS_OK; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 17f3e2e..6b1b40a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -391,9 +391,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, DATA_BLOB *rdata, DATA_BLOB *reply_pdu) { - struct dcerpc_response *r; + const struct dcerpc_response *r = NULL; + DATA_BLOB tmp_stub = data_blob_null; NTSTATUS ret = NT_STATUS_OK; - size_t pad_len = 0; /* * Point the return values at the real data including the RPC @@ -427,37 +427,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, r = &pkt->u.response; + tmp_stub.data = r->stub_and_verifier.data; + tmp_stub.length = r->stub_and_verifier.length; + /* Here's where we deal with incoming sign/seal. */ ret = dcerpc_check_auth(cli->auth, pkt, - &r->stub_and_verifier, + &tmp_stub, DCERPC_RESPONSE_LENGTH, - pdu, &pad_len); + pdu); if (!NT_STATUS_IS_OK(ret)) { return ret; } - if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - /* Point the return values at the NDR data. */ - rdata->data = r->stub_and_verifier.data; - - if (pkt->auth_length) { - /* We've already done integer wrap tests in - * dcerpc_check_auth(). */ - rdata->length = r->stub_and_verifier.length - - pad_len - - DCERPC_AUTH_TRAILER_LENGTH - - pkt->auth_length; - } else { - rdata->length = r->stub_and_verifier.length; - } + *rdata = tmp_stub; - DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", + DEBUG(10, ("Got pdu len %lu, data_len %lu\n", (long unsigned int)pdu->length, - (long unsigned int)rdata->length, - (unsigned int)pad_len)); + (long unsigned int)rdata->length)); /* * If this is the first reply, and the allocation hint is diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e6e39df..e5c7063 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1437,7 +1437,6 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, { NTSTATUS status; size_t hdr_size = DCERPC_REQUEST_LENGTH; - size_t pad_len; DEBUG(10, ("Checking request auth.\n")); @@ -1448,25 +1447,11 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, /* in case of sealing this function will unseal the data in place */ status = dcerpc_check_auth(auth, pkt, &pkt->u.request.stub_and_verifier, - hdr_size, raw_pkt, - &pad_len); + hdr_size, raw_pkt); if (!NT_STATUS_IS_OK(status)) { return status; } - - /* remove padding and auth trailer, - * this way the caller will get just the data */ - if (pkt->auth_length) { - size_t trail_len = pad_len - + DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length; - if (pkt->u.request.stub_and_verifier.length < trail_len) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - pkt->u.request.stub_and_verifier.length -= trail_len; - } - return NT_STATUS_OK; } -- 1.9.1 From dc2c03703e449485a2303480a81c4febf560dcd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 404/440] CVE-2015-5370: s3:librpc/rpc: let dcerpc_check_auth() auth_{type,level} against the expected values. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index bb1da46..054647c 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -548,6 +548,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return status; } + if (auth_info.auth_type != auth->auth_type) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (auth_info.auth_level != auth->auth_level) { + return NT_STATUS_INVALID_PARAMETER; + } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, pkt_trailer->length); -- 1.9.1 From ed2f43dd8c170782f29dd516f11e6e8804a0a3df Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 405/440] CVE-2015-5370: s3:rpc_client: make use of dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The does much more validation than dcerpc_pull_dcerpc_auth(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6b1b40a..49a8b2f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1807,17 +1807,15 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; default: - /* Paranoid lenght checks */ - if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length) { - tevent_req_nterror(req, - NT_STATUS_INFO_LENGTH_MISMATCH); + if (pkt->auth_length == 0) { + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } + /* get auth credentials */ - status = dcerpc_pull_dcerpc_auth(talloc_tos(), - &pkt->u.bind_ack.auth_info, - &auth, false); + status = dcerpc_pull_auth_trailer(pkt, talloc_tos(), + &pkt->u.bind_ack.auth_info, + &auth, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", nt_errstr(status))); -- 1.9.1 From 278a098df6edd6d23b96442ee8bb4ba767f166a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 406/440] CVE-2015-5370: s3:rpc_client: make use of dcerpc_verify_ncacn_packet_header() in cli_pipe_validate_current_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 111 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 15 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 49a8b2f..02d9442 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -416,17 +416,89 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, /* Ensure we have the correct type. */ switch (pkt->ptype) { - case DCERPC_PKT_ALTER_RESP: + case DCERPC_PKT_BIND_NAK: + DEBUG(1, (__location__ ": Bind NACK received from %s!\n", + rpccli_pipe_txt(talloc_tos(), cli))); + + ret = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND_NAK, + 0, /* max_auth_info */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + 0); /* optional flags */ + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + + /* Use this for now... */ + return NT_STATUS_NETWORK_ACCESS_DENIED; + case DCERPC_PKT_BIND_ACK: + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + pkt->u.bind_ack.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } - /* Client code never receives this kind of packets */ break; + case DCERPC_PKT_ALTER_RESP: + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + pkt->u.alter_resp.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + + break; case DCERPC_PKT_RESPONSE: r = &pkt->u.response; + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + r->stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + tmp_stub.data = r->stub_and_verifier.data; tmp_stub.length = r->stub_and_verifier.length; @@ -436,6 +508,12 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, DCERPC_RESPONSE_LENGTH, pdu); if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); return ret; } @@ -465,14 +543,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, break; - case DCERPC_PKT_BIND_NAK: - DEBUG(1, (__location__ ": Bind NACK received from %s!\n", - rpccli_pipe_txt(talloc_tos(), cli))); - /* Use this for now... */ - return NT_STATUS_NETWORK_ACCESS_DENIED; - case DCERPC_PKT_FAULT: + ret = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_FAULT, + 0, /* max_auth_info */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + DEBUG(1, (__location__ ": RPC fault code %s received " "from %s!\n", dcerpc_errstr(talloc_tos(), @@ -489,13 +577,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, return NT_STATUS_RPC_PROTOCOL_ERROR; } - if (pkt->ptype != expected_pkt_type) { - DEBUG(3, (__location__ ": Connection to %s got an unexpected " - "RPC packet type - %u, not %u\n", - rpccli_pipe_txt(talloc_tos(), cli), - pkt->ptype, expected_pkt_type)); - return NT_STATUS_RPC_PROTOCOL_ERROR; - } if (pkt->call_id != call_id) { DEBUG(3, (__location__ ": Connection to %s got an unexpected " -- 1.9.1 From 5742f0c4e46a4864b62a8c1f823474696f113791 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:48:38 +0200 Subject: [PATCH 407/440] CVE-2015-5370: s3:rpc_client: protect rpc_api_pipe_got_pdu() against too large payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 02d9442..63ab507 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -990,6 +990,11 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) return; } + if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + /* Now copy the data portion out of the pdu into rbuf. */ if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, -- 1.9.1 From ac05d169a35f7362aca752b59ab1f4a7b1090e2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 408/440] CVE-2015-5370: s3:rpc_client: verify auth_{type,level} in rpc_pipe_bind_step_one_done() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 63ab507..bd29074 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1908,6 +1908,21 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) tevent_req_nterror(req, status); return; } + + if (auth.auth_type != pauth->auth_type) { + DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n", + auth.auth_type, pauth->auth_type)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (auth.auth_level != pauth->auth_level) { + DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n", + auth.auth_level, pauth->auth_level)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + break; } -- 1.9.1 From bf953a8c2d2a589a53c5cd0bb384e600ba555001 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 409/440] CVE-2015-5370: s3:rpc_server: make use of dcerpc_pull_auth_trailer() in api_pipe_{bind_req,alter_context,bind_auth3}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 62 +++++++++---------------------------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e5c7063..82bc3df 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -733,25 +733,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, * Check if this is an authenticated bind request. */ if (pkt->auth_length) { - /* Quick length check. Won't catch a bad auth footer, - * prevents overrun. */ - - if (pkt->frag_length < RPC_HEADER_LEN + - DCERPC_AUTH_TRAILER_LENGTH + - pkt->auth_length) { - DEBUG(0,("api_pipe_bind_req: auth_len (%u) " - "too long for fragment %u.\n", - (unsigned int)pkt->auth_length, - (unsigned int)pkt->frag_length)); - goto err_exit; - } - /* * Decode the authentication verifier. */ - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.bind.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.bind.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); goto err_exit; @@ -910,23 +897,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } - /* Ensure there's enough data for an authenticated request. */ - if (pkt->frag_length < RPC_HEADER_LEN - + DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length) { - DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len " - "%u is too large.\n", - (unsigned int)pkt->auth_length)); - goto err; - } - /* * Decode the authentication verifier response. */ - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.auth3.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.auth3.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n")); goto err; @@ -1034,34 +1011,21 @@ static bool api_pipe_alter_context(struct pipes_struct *p, * Check if this is an authenticated alter context request. */ if (pkt->auth_length) { - /* Quick length check. Won't catch a bad auth footer, - * prevents overrun. */ - - if (pkt->frag_length < RPC_HEADER_LEN + - DCERPC_AUTH_TRAILER_LENGTH + - pkt->auth_length) { - DEBUG(0,("api_pipe_alter_context: auth_len (%u) " - "too long for fragment %u.\n", - (unsigned int)pkt->auth_length, - (unsigned int)pkt->frag_length )); + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " + "Altering Context not yet supported!\n")); goto err_exit; } - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.bind.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.bind.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); goto err_exit; } - /* We can only finish if the pipe is unbound for now */ - if (p->pipe_bound) { - DEBUG(0, (__location__ ": Pipe already bound, " - "Altering Context not yet supported!\n")); - goto err_exit; - } - if (auth_info.auth_type != p->auth.auth_type) { DEBUG(0, ("Auth type mismatch! Client sent %d, " "but auth was started as type %d!\n", -- 1.9.1 From d7001a5394fb4f05eca24ee3bf46a15a95b73181 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 410/440] CVE-2015-5370: s3:rpc_server: let a failing sec_verification_trailer mark the connection as broken BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 82bc3df..610105c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1243,6 +1243,7 @@ static bool api_pipe_request(struct pipes_struct *p, if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); + set_incoming_fault(p); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); -- 1.9.1 From e7f5462fb4ed5ea363f5820bdbde15e4ca2f1d86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 411/440] CVE-2015-5370: s3:rpc_server: just call pipe_auth_generic_bind() in api_pipe_bind_req() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pipe_auth_generic_bind() does all the required checks already and an explicit DCERPC_AUTH_TYPE_NONE is not supported. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 45 ++++++------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 610105c..07046d4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -500,6 +500,7 @@ static bool pipe_auth_generic_bind(struct pipes_struct *p, p->auth.auth_ctx = gensec_security; p->auth.auth_type = auth_info->auth_type; + p->auth.auth_level = auth_info->auth_level; if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { p->auth.client_hdr_signing = true; @@ -626,7 +627,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, { struct dcerpc_auth auth_info = {0}; uint16_t assoc_gid; - unsigned int auth_type = DCERPC_AUTH_TYPE_NONE; NTSTATUS status; struct ndr_syntax_id id; uint8_t pfc_flags = 0; @@ -744,47 +744,14 @@ static bool api_pipe_bind_req(struct pipes_struct *p, goto err_exit; } - auth_type = auth_info.auth_type; - - /* Work out if we have to sign or seal etc. */ - switch (auth_info.auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY; - break; - case DCERPC_AUTH_LEVEL_CONNECT: - p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT; - break; - default: - DEBUG(0, ("Unexpected auth level (%u).\n", - (unsigned int)auth_info.auth_level )); + if (!pipe_auth_generic_bind(p, pkt, + &auth_info, &auth_resp)) { goto err_exit; } - - switch (auth_type) { - case DCERPC_AUTH_TYPE_NONE: - break; - - default: - if (!pipe_auth_generic_bind(p, pkt, - &auth_info, &auth_resp)) { - goto err_exit; - } - break; - } - } - - if (auth_type == DCERPC_AUTH_TYPE_NONE) { - /* Unauthenticated bind request. */ - /* We're finished - no more packets. */ + } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; - /* We must set the pipe auth_level here also. */ p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->pipe_bound = True; - /* The session key was initialized from the SMB - * session in make_internal_rpc_pipe_p */ } ZERO_STRUCT(u.bind_ack); @@ -836,8 +803,8 @@ static bool api_pipe_bind_req(struct pipes_struct *p, if (auth_resp.length) { status = dcerpc_push_dcerpc_auth(pkt, - auth_type, - auth_info.auth_level, + p->auth.auth_type, + p->auth.auth_level, 0, 1, /* auth_context_id */ &auth_resp, -- 1.9.1 From d6b804d7661cfaf52f8c4542bb991cabd764e1f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 412/440] CVE-2015-5370: s3:rpc_server: don't ignore failures of dcerpc_push_ncacn_packet() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 07046d4..ea9d50d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -798,6 +798,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", nt_errstr(status))); + goto err_exit; } if (auth_resp.length) { @@ -1058,6 +1059,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", nt_errstr(status))); + goto err_exit; } if (auth_resp.length) { -- 1.9.1 From 52b1edeb3b8da0ee09c94a6c6cb8ec5291990c9c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 413/440] CVE-2015-5370: s3:rpc_server: don't allow auth3 if the authentication was already finished MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ea9d50d..2926f06 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -860,8 +860,15 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " + "AUTH3 not supported!\n")); + goto err; + } + if (pkt->auth_length == 0) { - DEBUG(1, ("No auth field sent for bind request!\n")); + DEBUG(1, ("No auth field sent for auth3 request!\n")); goto err; } -- 1.9.1 From 1662d64c40e1cd55dec1f87b6ae9da584ad00eca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 414/440] CVE-2015-5370: s3:rpc_server: let a failing auth3 mark the authentication as invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 2926f06..a37cb3f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -926,7 +926,7 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) return true; err: - + p->pipe_bound = false; TALLOC_FREE(p->auth.auth_ctx); return false; } -- 1.9.1 From bca784fc70abdb8f2d919a9ce2f13ed72355a888 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 415/440] CVE-2015-5370: s3:rpc_server: make sure auth_level isn't changed by alter_context or auth3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a37cb3f..96bf212 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -896,6 +896,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + if (auth_info.auth_level != p->auth.auth_level) { + DEBUG(1, ("Auth level mismatch! Client sent %d, " + "but auth was started as level %d!\n", + auth_info.auth_level, p->auth.auth_level)); + goto err; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, @@ -1008,6 +1015,13 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (auth_info.auth_level != p->auth.auth_level) { + DEBUG(0, ("Auth level mismatch! Client sent %d, " + "but auth was started as level %d!\n", + auth_info.auth_level, p->auth.auth_level)); + goto err_exit; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, pkt, -- 1.9.1 From 58ba2c00d672b1a5ee3db46a008cc426a667d6da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Jul 2015 09:15:39 +0200 Subject: [PATCH 416/440] CVE-2015-5370: s3:rpc_server: ensure that the message ordering doesn't violate the spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first pdu is always a BIND. REQUEST pdus are only allowed once the authentication is finished. A simple anonymous authentication is finished after the BIND. Real authentication may need additional ALTER or AUTH3 exchanges. Pair-Programmed-With: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Jeremy Allison Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_handles.c | 1 + source3/rpc_server/rpc_pipes.h | 7 ++++++ source3/rpc_server/srv_pipe.c | 46 ++++++++++++++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c index 4e2edc6..62b545c 100644 --- a/source3/rpc_server/rpc_handles.c +++ b/source3/rpc_server/rpc_handles.c @@ -69,6 +69,7 @@ int make_base_pipes_struct(TALLOC_CTX *mem_ctx, p->msg_ctx = msg_ctx; p->transport = transport; p->endian = endian; + p->allow_bind = true; p->remote_address = tsocket_address_copy(remote_address, p); if (p->remote_address == NULL) { diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index 14b8705..d44ee92 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -131,6 +131,13 @@ struct pipes_struct { bool pipe_bound; /* + * States we can be in. + */ + bool allow_alter; + bool allow_bind; + bool allow_auth3; + + /* * Set the DCERPC_FAULT to return. */ int fault_state; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 96bf212..3b36a2a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -282,6 +282,9 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->pipe_bound = False; + p->allow_bind = false; + p->allow_alter = false; + p->allow_auth3 = false; return True; } @@ -636,11 +639,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, DATA_BLOB auth_blob = data_blob_null; const struct ndr_interface_table *table; - /* No rebinds on a bound pipe - use alter context. */ - if (p->pipe_bound) { - DEBUG(2,("Rejecting bind request on bound rpc connection\n")); + if (!p->allow_bind) { + DEBUG(2,("Pipe not in allow bind state\n")); return setup_bind_nak(p, pkt); } + p->allow_bind = false; if (pkt->u.bind.num_contexts == 0) { DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); @@ -722,7 +725,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, bind_ack_ctx.reason.value = 0; bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; } else { - p->pipe_bound = False; /* Rejection reason: abstract syntax not supported */ bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; @@ -751,7 +753,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; - p->pipe_bound = True; } ZERO_STRUCT(u.bind_ack); @@ -838,6 +839,22 @@ static bool api_pipe_bind_req(struct pipes_struct *p, p->out_data.current_pdu_sent = 0; TALLOC_FREE(auth_blob.data); + + if (bind_ack_ctx.result == 0) { + p->allow_alter = true; + p->allow_auth3 = true; + if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) { + status = pipe_auth_verify_final(p); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("pipe_auth_verify_final failed: %s\n", + nt_errstr(status))); + goto err_exit; + } + } + } else { + goto err_exit; + } + return True; err_exit: @@ -860,6 +877,11 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + if (!p->allow_auth3) { + DEBUG(1, ("Pipe not in allow auth3 state.\n")); + goto err; + } + /* We can only finish if the pipe is unbound for now */ if (p->pipe_bound) { DEBUG(0, (__location__ ": Pipe already bound, " @@ -934,6 +956,10 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) err: p->pipe_bound = false; + p->allow_bind = false; + p->allow_alter = false; + p->allow_auth3 = false; + TALLOC_FREE(p->auth.auth_ctx); return false; } @@ -957,6 +983,11 @@ static bool api_pipe_alter_context(struct pipes_struct *p, DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__)); + if (!p->allow_alter) { + DEBUG(1, ("Pipe not in allow alter state.\n")); + goto err_exit; + } + if (pkt->u.bind.assoc_group_id != 0) { assoc_gid = pkt->u.bind.assoc_group_id; } else { @@ -982,7 +1013,6 @@ static bool api_pipe_alter_context(struct pipes_struct *p, bind_ack_ctx.reason.value = 0; bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; } else { - p->pipe_bound = False; /* Rejection reason: abstract syntax not supported */ bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; @@ -1383,6 +1413,10 @@ void set_incoming_fault(struct pipes_struct *p) p->in_data.pdu.length = 0; p->fault_state = DCERPC_FAULT_CANT_PERFORM; + p->allow_alter = false; + p->allow_auth3 = false; + p->pipe_bound = false; + DEBUG(10, ("Setting fault state\n")); } -- 1.9.1 From 222c0aa5a6c0c70af3d68b50dba55da51ba5ee5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 417/440] CVE-2015-5370: s3:rpc_server: use 'alter' instead of 'bind' for variables in api_pipe_alter_context() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3b36a2a..3b746cf 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -976,7 +976,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, uint16_t assoc_gid; NTSTATUS status; union dcerpc_payload u; - struct dcerpc_ack_ctx bind_ack_ctx; + struct dcerpc_ack_ctx alter_ack_ctx; DATA_BLOB auth_resp = data_blob_null; DATA_BLOB auth_blob = data_blob_null; struct gensec_security *gensec_security; @@ -988,8 +988,8 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } - if (pkt->u.bind.assoc_group_id != 0) { - assoc_gid = pkt->u.bind.assoc_group_id; + if (pkt->u.alter.assoc_group_id != 0) { + assoc_gid = pkt->u.alter.assoc_group_id; } else { assoc_gid = 0x53f0; } @@ -999,24 +999,24 @@ static bool api_pipe_alter_context(struct pipes_struct *p, */ /* If the requested abstract synt uuid doesn't match our client pipe, - reject the bind_ack & set the transfer interface synt to all 0's, + reject the alter_ack & set the transfer interface synt to all 0's, ver 0 (observed when NT5 attempts to bind to abstract interfaces unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ if (check_bind_req(p, - &pkt->u.bind.ctx_list[0].abstract_syntax, - &pkt->u.bind.ctx_list[0].transfer_syntaxes[0], - pkt->u.bind.ctx_list[0].context_id)) { + &pkt->u.alter.ctx_list[0].abstract_syntax, + &pkt->u.alter.ctx_list[0].transfer_syntaxes[0], + pkt->u.alter.ctx_list[0].context_id)) { - bind_ack_ctx.result = 0; - bind_ack_ctx.reason.value = 0; - bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; + alter_ack_ctx.result = 0; + alter_ack_ctx.reason.value = 0; + alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0]; } else { /* Rejection reason: abstract syntax not supported */ - bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; - bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; - bind_ack_ctx.syntax = ndr_syntax_id_null; + alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; + alter_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; + alter_ack_ctx.syntax = ndr_syntax_id_null; } /* @@ -1031,7 +1031,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, } status = dcerpc_pull_auth_trailer(pkt, pkt, - &pkt->u.bind.auth_info, + &pkt->u.alter.auth_info, &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); @@ -1088,7 +1088,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, u.alter_resp.secondary_address_size = 1; u.alter_resp.num_results = 1; - u.alter_resp.ctx_list = &bind_ack_ctx; + u.alter_resp.ctx_list = &alter_ack_ctx; /* NOTE: We leave the auth_info empty so we can calculate the padding * later and then append the auth_info --simo */ @@ -1108,7 +1108,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, &u, &p->out_data.frag); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", + DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n", nt_errstr(status))); goto err_exit; } -- 1.9.1 From d359ea52c6fde57b0d373a1726b35fb2e1596961 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 418/440] CVE-2015-5370: s3:rpc_server: verify presentation context arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3b746cf..a1304d3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -646,7 +646,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, p->allow_bind = false; if (pkt->u.bind.num_contexts == 0) { - DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); + DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); + goto err_exit; + } + + if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) { + DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n")); goto err_exit; } @@ -988,6 +993,16 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (pkt->u.alter.num_contexts == 0) { + DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); + goto err_exit; + } + + if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) { + DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n")); + goto err_exit; + } + if (pkt->u.alter.assoc_group_id != 0) { assoc_gid = pkt->u.alter.assoc_group_id; } else { -- 1.9.1 From 011c64a8f9cbb49942e5e92bff932bb7b2105b5f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 419/440] CVE-2015-5370: s3:rpc_server: make use of dcerpc_verify_ncacn_packet_header() to verify incoming pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 82 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a1304d3..ad4b7a8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -30,7 +30,7 @@ #include "includes.h" #include "system/filesys.h" #include "srv_pipe_internal.h" -#include "../librpc/gen_ndr/dcerpc.h" +#include "../librpc/gen_ndr/ndr_dcerpc.h" #include "../librpc/rpc/rpc_common.h" #include "dcesrv_auth_generic.h" #include "rpc_server.h" @@ -645,6 +645,25 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } p->allow_bind = false; + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND, + pkt->u.bind.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err_exit; + } + if (pkt->u.bind.num_contexts == 0) { DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); goto err_exit; @@ -887,6 +906,25 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_AUTH3, + pkt->u.auth3.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err; + } + /* We can only finish if the pipe is unbound for now */ if (p->pipe_bound) { DEBUG(0, (__location__ ": Pipe already bound, " @@ -993,6 +1031,25 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_ALTER, + pkt->u.alter.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err_exit; + } + if (pkt->u.alter.num_contexts == 0) { DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); goto err_exit; @@ -1476,6 +1533,29 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt return False; } + /* + * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL. + * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later. + */ + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_REQUEST, + pkt->u.request.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("process_request_pdu: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + set_incoming_fault(p); + return false; + } + hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt); if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) { p->header2 = hdr2; -- 1.9.1 From d0a32c9f0e3e8456e9fcbb1ffbdf21731b179877 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:40:58 +0100 Subject: [PATCH 420/440] CVE-2015-5370: s3:rpc_server: disconnect the connection after a fatal FAULT pdu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_server.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 01a854c..5effe66 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -558,6 +558,12 @@ static void named_pipe_packet_done(struct tevent_req *subreq) return; } + if (npc->p->fault_state != 0) { + DEBUG(2, ("Disconnect after fault\n")); + sys_errno = EINVAL; + goto fail; + } + /* clear out any data that may have been left around */ npc->count = 0; TALLOC_FREE(npc->iov); @@ -1292,6 +1298,12 @@ static void dcerpc_ncacn_packet_done(struct tevent_req *subreq) goto fail; } + if (ncacn_conn->p->fault_state != 0) { + DEBUG(2, ("Disconnect after fault\n")); + sys_errno = EINVAL; + goto fail; + } + /* clear out any data that may have been left around */ ncacn_conn->count = 0; TALLOC_FREE(ncacn_conn->iov); -- 1.9.1 From 1e34d43c13ef5fff5f450836659664468349ad39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 421/440] CVE-2015-5370: s3:rpc_server: let a failing BIND mark the connection as broken MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ad4b7a8..7e33ff0 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -278,6 +278,7 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) p->out_data.data_sent_length = 0; p->out_data.current_pdu_sent = 0; + set_incoming_fault(p); TALLOC_FREE(p->auth.auth_ctx); p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; -- 1.9.1 From dfae9a8246df8d1c885710d55ea33eaaea7f2d5f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 422/440] CVE-2015-5370: s3:rpc_server: use DCERPC_NCA_S_PROTO_ERROR FAULTs for protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7e33ff0..e4e40f1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1484,7 +1484,7 @@ void set_incoming_fault(struct pipes_struct *p) data_blob_free(&p->in_data.data); p->in_data.pdu_needed_len = 0; p->in_data.pdu.length = 0; - p->fault_state = DCERPC_FAULT_CANT_PERFORM; + p->fault_state = DCERPC_NCA_S_PROTO_ERROR; p->allow_alter = false; p->allow_auth3 = false; @@ -1748,7 +1748,7 @@ done: if (!reply) { DEBUG(3,("DCE/RPC fault sent!")); set_incoming_fault(p); - setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); + setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR)); } /* pkt and p->in_data.pdu.data freed by caller */ } -- 1.9.1 From 9ee15359ef16053fef6c62822412655dd9e8dc71 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Jul 2015 10:58:07 +0200 Subject: [PATCH 423/440] CVE-2015-5370: s3:librpc/rpc: remove unused dcerpc_pull_dcerpc_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 4 ---- source3/librpc/rpc/dcerpc_helpers.c | 41 ------------------------------------- 2 files changed, 45 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index 0a82e7e..b7537c2 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -69,10 +69,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, uint32_t auth_context_id, const DATA_BLOB *credentials, DATA_BLOB *blob); -NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - struct dcerpc_auth *r, - bool bigendian); NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, size_t header_len, size_t data_left, size_t max_xmit_frag, diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 054647c..48410bb 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -177,47 +177,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, } /** -* @brief Decodes a dcerpc_auth blob -* -* @param mem_ctx The memory context on which to allocate the packet -* elements -* @param blob The blob of data to decode -* @param r An empty dcerpc_auth structure, must not be NULL -* -* @return a NTSTATUS error code -*/ -NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - struct dcerpc_auth *r, - bool bigendian) -{ - enum ndr_err_code ndr_err; - struct ndr_pull *ndr; - - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - if (bigendian) { - ndr->flags |= LIBNDR_FLAG_BIGENDIAN; - } - - ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r); - - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(ndr); - return ndr_map_error2ntstatus(ndr_err); - } - talloc_free(ndr); - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(dcerpc_auth, r); - } - - return NT_STATUS_OK; -} - -/** * @brief Calculate how much data we can in a packet, including calculating * auth token and pad lengths. * -- 1.9.1 From 3a21c073d7590ada530948a89283a19d1b50db88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 424/440] CVE-2015-5370: s3:rpc_server: check the transfer syntax in check_bind_req() first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e4e40f1..27fd83c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -350,20 +350,30 @@ static bool check_bind_req(struct pipes_struct *p, bool ok; const char *interface_name = NULL; - DEBUG(3,("check_bind_req for %s\n", + DEBUG(3,("check_bind_req for %s context_id=%u\n", ndr_interface_name(&abstract->uuid, - abstract->if_version))); + abstract->if_version), + (unsigned)context_id)); + + ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr); + if (!ok) { + DEBUG(1,("check_bind_req unknown transfer syntax for " + "%s context_id=%u\n", + ndr_interface_name(&abstract->uuid, + abstract->if_version), + (unsigned)context_id)); + return false; + } /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ - if (rpc_srv_pipe_exists_by_id(abstract) && - ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) { - DEBUG(3, ("check_bind_req: %s -> %s rpc service\n", - rpc_srv_get_pipe_cli_name(abstract), - rpc_srv_get_pipe_srv_name(abstract))); - } else { + if (!rpc_srv_pipe_exists_by_id(abstract)) { return false; } + DEBUG(3, ("check_bind_req: %s -> %s rpc service\n", + rpc_srv_get_pipe_cli_name(abstract), + rpc_srv_get_pipe_srv_name(abstract))); + ok = init_pipe_handles(p, abstract); if (!ok) { DEBUG(1, ("Failed to init pipe handles!\n")); -- 1.9.1 From 56975eeb6b05cbae9c928fd5048731cc6a82400a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 425/440] CVE-2015-5370: s3:rpc_server: don't allow an existing context to be changed in check_bind_req() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An alter context can't change the syntax of an existing context, a new context_id will be used for that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 27fd83c..bb3c3e8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -365,6 +365,30 @@ static bool check_bind_req(struct pipes_struct *p, return false; } + for (context_fns = p->contexts; + context_fns != NULL; + context_fns = context_fns->next) + { + if (context_fns->context_id != context_id) { + continue; + } + + ok = ndr_syntax_id_equal(&context_fns->syntax, + abstract); + if (ok) { + return true; + } + + DEBUG(1,("check_bind_req: changing abstract syntax for " + "%s context_id=%u into %s not supported\n", + ndr_interface_name(&context_fns->syntax.uuid, + context_fns->syntax.if_version), + (unsigned)context_id, + ndr_interface_name(&abstract->uuid, + abstract->if_version))); + return false; + } + /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ if (!rpc_srv_pipe_exists_by_id(abstract)) { return false; -- 1.9.1 From 456c92bdbc89eb5522a4f710a72eed375e090ee1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 426/440] CVE-2015-5370: s3:rpc_client: pass struct pipe_auth_data to create_rpc_{bind_auth3,alter_context}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bd29074..5053de8 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1695,9 +1695,8 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, + struct pipe_auth_data *auth, uint32_t rpc_call_id, - enum dcerpc_AuthType auth_type, - enum dcerpc_AuthLevel auth_level, DATA_BLOB *pauth_blob, DATA_BLOB *rpc_out) { @@ -1707,8 +1706,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, u.auth3._pad = 0; status = dcerpc_push_dcerpc_auth(mem_ctx, - auth_type, - auth_level, + auth->auth_type, + auth->auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ pauth_blob, @@ -1740,8 +1739,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, ********************************************************************/ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, - enum dcerpc_AuthType auth_type, - enum dcerpc_AuthLevel auth_level, + struct pipe_auth_data *auth, uint32_t rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, @@ -1752,8 +1750,8 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, NTSTATUS status; status = dcerpc_push_dcerpc_auth(mem_ctx, - auth_type, - auth_level, + auth->auth_type, + auth->auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ pauth_blob, @@ -1983,9 +1981,7 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req *req, /* Now prepare the alter context pdu. */ data_blob_free(&state->rpc_out); - status = create_rpc_alter_context(state, - auth->auth_type, - auth->auth_level, + status = create_rpc_alter_context(state, auth, state->rpc_call_id, &state->cli->abstract_syntax, &state->cli->transfer_syntax, @@ -2018,10 +2014,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, /* Now prepare the auth3 context pdu. */ data_blob_free(&state->rpc_out); - status = create_rpc_bind_auth3(state, state->cli, + status = create_rpc_bind_auth3(state, state->cli, auth, state->rpc_call_id, - auth->auth_type, - auth->auth_level, auth_token, &state->rpc_out); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From e09d28747dd06aef642908d201056211f4743815 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 427/440] CVE-2015-5370: s3:librpc/rpc: add auth_context_id to struct pipe_auth_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index b7537c2..1838012 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -40,6 +40,7 @@ struct gensec_security; struct pipe_auth_data { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; bool client_hdr_signing; bool hdr_signing; bool verified_bitmask1; -- 1.9.1 From 6ebd89d18a5e313411639387a8ce2784d420f692 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 428/440] CVE-2015-5370: s3:rpc_client: make use of pipe_auth_data->auth_context_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is better than using hardcoded values. We need to use auth_context_id = 1 for authenticated connections, as old Samba server (before this patchset) will use a hardcoded value of 1. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5053de8..835aec5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1190,7 +1190,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, &auth_token, &auth_info); if (!NT_STATUS_IS_OK(ret)) { @@ -1709,7 +1709,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, pauth_blob, &u.auth3.auth_info); if (!NT_STATUS_IS_OK(status)) { @@ -1753,7 +1753,7 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, pauth_blob, &auth_info); if (!NT_STATUS_IS_OK(status)) { @@ -2370,6 +2370,7 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = DCERPC_AUTH_TYPE_NONE; result->auth_level = DCERPC_AUTH_LEVEL_NONE; + result->auth_context_id = 0; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2430,6 +2431,7 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = auth_type; result->auth_level = auth_level; + result->auth_context_id = 1; status = auth_generic_client_prepare(result, &auth_generic_ctx); -- 1.9.1 From b9cb6818362e634620bfd09a03b493e7e6475c41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 429/440] CVE-2015-5370: s3:rpc_server: make use of pipe_auth_data->auth_context_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is better than using hardcoded values. We need to use the value the client used in the BIND request. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_ncacn_np.c | 1 + source3/rpc_server/srv_pipe.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index 5514956..5647596 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -977,6 +977,7 @@ static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx, } result->auth->auth_type = DCERPC_AUTH_TYPE_NONE; result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + result->auth->auth_context_id = 0; status = rpccli_anon_bind_data(result, &auth); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bb3c3e8..821623c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -539,6 +539,7 @@ static bool pipe_auth_generic_bind(struct pipes_struct *p, p->auth.auth_ctx = gensec_security; p->auth.auth_type = auth_info->auth_type; p->auth.auth_level = auth_info->auth_level; + p->auth.auth_context_id = auth_info->auth_context_id; if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { p->auth.client_hdr_signing = true; @@ -812,6 +813,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; + p->auth.auth_context_id = 0; } ZERO_STRUCT(u.bind_ack); @@ -862,12 +864,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } if (auth_resp.length) { - status = dcerpc_push_dcerpc_auth(pkt, p->auth.auth_type, p->auth.auth_level, - 0, - 1, /* auth_context_id */ + 0, /* pad_len */ + p->auth.auth_context_id, &auth_resp, &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -1222,10 +1223,10 @@ static bool api_pipe_alter_context(struct pipes_struct *p, if (auth_resp.length) { status = dcerpc_push_dcerpc_auth(pkt, - auth_info.auth_type, - auth_info.auth_level, + p->auth.auth_type, + p->auth.auth_level, 0, /* pad_len */ - 1, /* auth_context_id */ + p->auth.auth_context_id, &auth_resp, &auth_blob); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From dcb86b9c9dadaa7ca37d3f980d0bc694fd22a2e7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 430/440] CVE-2015-5370: s3:librpc/rpc: make use of auth->auth_context_id in dcerpc_add_auth_footer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 48410bb..c030f79 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -403,7 +403,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, auth->auth_type, auth->auth_level, pad_len, - 1 /* context id. */, + auth->auth_context_id, &auth_blob, &auth_info); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From 1efb358eda94ce080865145ac92da1e6e0dfb2cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 431/440] CVE-2015-5370: s3:librpc/rpc: verify auth_context_id in dcerpc_check_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index c030f79..aab43a1 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -515,6 +515,10 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return NT_STATUS_INVALID_PARAMETER; } + if (auth_info.auth_context_id != auth->auth_context_id) { + return NT_STATUS_INVALID_PARAMETER; + } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, pkt_trailer->length); -- 1.9.1 From 3c7cb717d7c941d4e5dd73a9bc8d869a1259bdb2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 432/440] CVE-2015-5370: s3:rpc_client: verify auth_context_id in rpc_pipe_bind_step_one_done() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 835aec5..b0e92f4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1921,6 +1921,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } + if (auth.auth_context_id != pauth->auth_context_id) { + DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n", + (unsigned)auth.auth_context_id, + (unsigned)pauth->auth_context_id)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + break; } -- 1.9.1 From 32f48721f3f6afb3ebd17716831d3aaa025c8a2e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 433/440] CVE-2015-5370: s3:rpc_server: verify auth_context_id in api_pipe_{bind_auth3,alter_context} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 821623c..bcd7e5d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1004,6 +1004,14 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + if (auth_info.auth_context_id != p->auth.auth_context_id) { + DEBUG(0, ("Auth context id mismatch! Client sent %u, " + "but auth was started as level %u!\n", + (unsigned)auth_info.auth_context_id, + (unsigned)p->auth.auth_context_id)); + goto err; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, @@ -1160,6 +1168,14 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (auth_info.auth_context_id != p->auth.auth_context_id) { + DEBUG(0, ("Auth context id mismatch! Client sent %u, " + "but auth was started as level %u!\n", + (unsigned)auth_info.auth_context_id, + (unsigned)p->auth.auth_context_id)); + goto err_exit; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, pkt, -- 1.9.1 From 25f07856d8c612fb9aeba1e7c62d1cba0e268084 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:05:45 +0100 Subject: [PATCH 434/440] CVE-2015-5370: libcli/smb: use a max timeout of 1 second in tstream_smbXcli_np_destructor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/smb/tstream_smbXcli_np.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c index 9cd6302..248bfb0 100644 --- a/libcli/smb/tstream_smbXcli_np.c +++ b/libcli/smb/tstream_smbXcli_np.c @@ -111,7 +111,11 @@ static int tstream_smbXcli_np_destructor(struct tstream_smbXcli_np *cli_nps) * Once we've fixed all callers to call * tstream_disconnect_send()/_recv(), this will * never be called. + * + * We use a maximun timeout of 1 second == 1000 msec. */ + cli_nps->timeout = MIN(cli_nps->timeout, 1000); + if (cli_nps->is_smb1) { status = smb1cli_close(cli_nps->conn, cli_nps->timeout, -- 1.9.1 From 9dfdec600a6441e7cdf26a9a9e4e3b2bb15e85c7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:23:14 +0100 Subject: [PATCH 435/440] CVE-2015-5370: s3:rpc_client: disconnect connection on protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 67 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b0e92f4..cb01338 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -936,6 +936,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt = talloc(state, struct ncacn_packet); if (!state->pkt) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -945,6 +951,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt, !state->endianess); if (!NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, status); return; } @@ -962,6 +974,28 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) (unsigned)state->reply_pdu_offset, nt_errstr(status))); + if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; @@ -986,12 +1020,24 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) "%s\n", state->endianess?"little":"big", state->pkt->drep[0]?"little":"big")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -999,6 +1045,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, state->reply_pdu_offset + rdata.length)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1027,6 +1079,14 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) subreq = get_complete_frag_send(state, state->ev, state->cli, &state->incoming_frag); + if (subreq == NULL) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (tevent_req_nomem(subreq, req)) { return; } @@ -2276,8 +2336,9 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, /* * TODO: do a real async disconnect ... * - * For now the caller needs to free rpc_cli + * For now we do it sync... */ + TALLOC_FREE(hs->rpc_cli->transport); hs->rpc_cli = NULL; tevent_req_done(req); -- 1.9.1 From f1106d57f0e851ff285b26a800da46a46c43d724 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:13:41 +0100 Subject: [PATCH 436/440] CVE-2015-5370: s4:librpc/rpc: call dcerpc_connection_dead() on protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 7b9777f..8274991 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1544,7 +1544,16 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, } if (pkt->ptype == DCERPC_PKT_FAULT) { + status = dcerpc_fault_to_nt_status(pkt->u.fault.status); DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status))); + if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + dcerpc_connection_dead(c, status); + return; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + dcerpc_connection_dead(c, status); + return; + } req->fault_code = pkt->u.fault.status; req->status = NT_STATUS_NET_WRITE_FAULT; goto req_done; @@ -1553,16 +1562,15 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, if (pkt->ptype != DCERPC_PKT_RESPONSE) { DEBUG(2,("Unexpected packet type %d in dcerpc response\n", (int)pkt->ptype)); - req->fault_code = DCERPC_FAULT_OTHER; - req->status = NT_STATUS_NET_WRITE_FAULT; - goto req_done; + dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; } /* now check the status from the auth routines, and if it failed then fail this request accordingly */ if (!NT_STATUS_IS_OK(status)) { - req->status = status; - goto req_done; + dcerpc_connection_dead(c, status); + return; } length = pkt->u.response.stub_and_verifier.length; @@ -1571,9 +1579,8 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n", (unsigned)req->payload.length + length, DCERPC_NCACN_PAYLOAD_MAX_SIZE)); - req->fault_code = DCERPC_FAULT_OTHER; - req->status = NT_STATUS_NET_WRITE_FAULT; - goto req_done; + dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; } if (length > 0) { -- 1.9.1 From dcfd2dc83ce614c67e8e63aa9f26bd8dd11f0f61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 437/440] CVE-2015-5370: python/samba/tests: add infrastructure to do raw protocol tests for DCERPC These are independent from our client library and allow testing of invalid pdus. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher --- python/samba/tests/__init__.py | 525 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index b53c4ea..0499b4e 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -1,5 +1,6 @@ # Unix SMB/CIFS implementation. # Copyright (C) Jelmer Vernooij 2007-2010 +# Copyright (C) Stefan Metzmacher 2014,2015 # # 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 @@ -24,6 +25,12 @@ import samba.auth from samba import param from samba.samdb import SamDB from samba import credentials +import samba.ndr +import samba.dcerpc.dcerpc +import samba.dcerpc.base +import samba.dcerpc.epmapper +import socket +import struct import subprocess import sys import tempfile @@ -222,6 +229,524 @@ cmdline_credentials = None class RpcInterfaceTestCase(TestCase): """DCE/RPC Test case.""" +class RawDCERPCTest(TestCase): + """A raw DCE/RPC Test case.""" + + def _disconnect(self, reason): + if self.s is None: + return + self.s.close() + self.s = None + if self.do_hexdump: + sys.stderr.write("disconnect[%s]\n" % reason) + + def connect(self): + try: + self.a = socket.getaddrinfo(self.host, self.tcp_port, socket.AF_UNSPEC, + socket.SOCK_STREAM, socket.SOL_TCP, + 0) + self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) + self.s.settimeout(10) + self.s.connect(self.a[0][4]) + except socket.error as e: + self.s.close() + raise + except IOError as e: + self.s.close() + raise + except Exception as e: + raise + finally: + pass + + def setUp(self): + super(RawDCERPCTest, self).setUp() + self.do_ndr_print = False + self.do_hexdump = False + + self.host = samba.tests.env_get_var_value('SERVER') + self.tcp_port = 135 + + self.settings = {} + self.settings["lp_ctx"] = self.lp_ctx = samba.tests.env_loadparm() + self.settings["target_hostname"] = self.host + + self.connect() + + def epmap_reconnect(self, abstract): + ndr32 = samba.dcerpc.base.transfer_syntax_ndr() + + tsf0_list = [ndr32] + ctx0 = samba.dcerpc.dcerpc.ctx_list() + ctx0.context_id = 1 + ctx0.num_transfer_syntaxes = len(tsf0_list) + ctx0.abstract_syntax = samba.dcerpc.epmapper.abstract_syntax() + ctx0.transfer_syntaxes = tsf0_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx0]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_ACK, + req.call_id, auth_length=0) + self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEqual(rep.u.secondary_address_size, 4) + self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEqual(len(rep.u._pad1), 2) + self.assertEqual(rep.u._pad1, '\0' * 2) + self.assertEqual(rep.u.num_results, 1) + self.assertEqual(rep.u.ctx_list[0].result, + samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEqual(rep.u.ctx_list[0].reason, + samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEqual(rep.u.auth_info, '\0' * 0) + + # And now try a request + data1 = samba.ndr.ndr_pack(abstract) + lhs1 = samba.dcerpc.epmapper.epm_lhs() + lhs1.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID + lhs1.lhs_data = data1[:18] + rhs1 = samba.dcerpc.epmapper.epm_rhs_uuid() + rhs1.unknown = data1[18:] + floor1 = samba.dcerpc.epmapper.epm_floor() + floor1.lhs = lhs1 + floor1.rhs = rhs1 + data2 = samba.ndr.ndr_pack(ndr32) + lhs2 = samba.dcerpc.epmapper.epm_lhs() + lhs2.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID + lhs2.lhs_data = data2[:18] + rhs2 = samba.dcerpc.epmapper.epm_rhs_uuid() + rhs2.unknown = data1[18:] + floor2 = samba.dcerpc.epmapper.epm_floor() + floor2.lhs = lhs2 + floor2.rhs = rhs2 + lhs3 = samba.dcerpc.epmapper.epm_lhs() + lhs3.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_NCACN + lhs3.lhs_data = "" + floor3 = samba.dcerpc.epmapper.epm_floor() + floor3.lhs = lhs3 + floor3.rhs.minor_version = 0 + lhs4 = samba.dcerpc.epmapper.epm_lhs() + lhs4.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_TCP + lhs4.lhs_data = "" + floor4 = samba.dcerpc.epmapper.epm_floor() + floor4.lhs = lhs4 + floor4.rhs.port = self.tcp_port + lhs5 = samba.dcerpc.epmapper.epm_lhs() + lhs5.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_IP + lhs5.lhs_data = "" + floor5 = samba.dcerpc.epmapper.epm_floor() + floor5.lhs = lhs5 + floor5.rhs.ipaddr = "0.0.0.0" + + floors = [floor1,floor2,floor3,floor4,floor5] + req_tower = samba.dcerpc.epmapper.epm_tower() + req_tower.num_floors = len(floors) + req_tower.floors = floors + req_twr = samba.dcerpc.epmapper.epm_twr_t() + req_twr.tower = req_tower + + pack_twr = samba.ndr.ndr_pack(req_twr) + + # object + stub = "\x01\x00\x00\x00" + stub += "\x00" * 16 + # tower + stub += "\x02\x00\x00\x00" + stub += pack_twr + # padding? + stub += "\x00" * 1 + # handle + stub += "\x00" * 20 + # max_towers + stub += "\x04\x00\x00\x00" + + # we do an epm_Map() request + req = self.generate_request(call_id = 1, + context_id=ctx0.context_id, + opnum=3, + stub=stub) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, + req.call_id, auth_length=0) + self.assertNotEqual(rep.u.alloc_hint, 0) + self.assertEqual(rep.u.context_id, req.u.context_id) + self.assertEqual(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + num_towers = struct.unpack_from(" samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + p.auth_length = len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH + else: + p.auth_length = 0 + p.call_id = call_id + p.u = payload + + pdu = samba.ndr.ndr_pack(p) + p.frag_length = len(pdu) + + return p + + def verify_pdu(self, p, ptype, call_id, + rpc_vers=5, + rpc_vers_minor=0, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + drep = [samba.dcerpc.dcerpc.DCERPC_DREP_LE, 0, 0, 0], + auth_length=None): + + self.assertIsNotNone(p, "No valid pdu") + + if getattr(p.u, 'auth_info', None): + ai = p.u.auth_info + else: + ai = "" + + self.assertEqual(p.rpc_vers, rpc_vers) + self.assertEqual(p.rpc_vers_minor, rpc_vers_minor) + self.assertEqual(p.ptype, ptype) + self.assertEqual(p.pfc_flags, pfc_flags) + self.assertEqual(p.drep, drep) + self.assertGreaterEqual(p.frag_length, + samba.dcerpc.dcerpc.DCERPC_NCACN_PAYLOAD_OFFSET) + if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + self.assertEqual(p.auth_length, + len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) + elif auth_length is not None: + self.assertEqual(p.auth_length, auth_length) + else: + self.assertEqual(p.auth_length, 0) + self.assertEqual(p.call_id, call_id) + + return + + def generate_bind(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + max_xmit_frag=5840, + max_recv_frag=5840, + assoc_group_id=0, + ctx_list=[], + auth_info="", + ndr_print=None, hexdump=None): + + b = samba.dcerpc.dcerpc.bind() + b.max_xmit_frag = max_xmit_frag + b.max_recv_frag = max_recv_frag + b.assoc_group_id = assoc_group_id + b.num_contexts = len(ctx_list) + b.ctx_list = ctx_list + b.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_BIND, + pfc_flags=pfc_flags, + call_id=call_id, + payload=b, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_alter(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + max_xmit_frag=5840, + max_recv_frag=5840, + assoc_group_id=0, + ctx_list=[], + auth_info="", + ndr_print=None, hexdump=None): + + a = samba.dcerpc.dcerpc.bind() + a.max_xmit_frag = max_xmit_frag + a.max_recv_frag = max_recv_frag + a.assoc_group_id = assoc_group_id + a.num_contexts = len(ctx_list) + a.ctx_list = ctx_list + a.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ALTER, + pfc_flags=pfc_flags, + call_id=call_id, + payload=a, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_auth3(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + a = samba.dcerpc.dcerpc.auth3() + a.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_AUTH3, + pfc_flags=pfc_flags, + call_id=call_id, + payload=a, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_request(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + alloc_hint=None, + context_id=None, + opnum=None, + object=None, + stub=None, + auth_info="", + ndr_print=None, hexdump=None): + + if alloc_hint is None: + alloc_hint = len(stub) + + r = samba.dcerpc.dcerpc.request() + r.alloc_hint = alloc_hint + r.context_id = context_id + r.opnum = opnum + if object is not None: + r.object = object + r.stub_and_verifier = stub + auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_REQUEST, + pfc_flags=pfc_flags, + call_id=call_id, + payload=r, + ndr_print=ndr_print, hexdump=hexdump) + + if len(auth_info) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + p.auth_length = len(auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH + + return p + + def generate_co_cancel(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + c = samba.dcerpc.dcerpc.co_cancel() + c.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_CO_CANCEL, + pfc_flags=pfc_flags, + call_id=call_id, + payload=c, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_orphaned(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + o = samba.dcerpc.dcerpc.orphaned() + o.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ORPHANED, + pfc_flags=pfc_flags, + call_id=call_id, + payload=o, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_shutdown(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + ndr_print=None, hexdump=None): + + s = samba.dcerpc.dcerpc.shutdown() + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_SHUTDOWN, + pfc_flags=pfc_flags, + call_id=call_id, + payload=s, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def assertIsConnected(self): + self.assertIsNotNone(self.s, msg="Not connected") + return + + def assertNotConnected(self): + self.assertIsNone(self.s, msg="Is connected") + return + + def assertNDRSyntaxEquals(self, s1, s2): + self.assertEqual(s1.uuid, s2.uuid) + self.assertEqual(s1.if_version, s2.if_version) + return class ValidNetbiosNameTests(TestCase): -- 1.9.1 From 299b1966beb00d43cc1f906fbf6e71df1b469e12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 438/440] CVE-2015-5370: python/samba/tests: add some dcerpc raw_protocol tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are independent from our client library and allow testing of invalid pdus. It can be used like this in standalone mode: SMB_CONF_PATH=/dev/null SERVER=172.31.9.188 python/samba/tests/dcerpc/raw_protocol.py or SMB_CONF_PATH=/dev/null SERVER=172.31.9.188 python/samba/tests/dcerpc/raw_protocol.py -v -f TestDCERPC_BIND.test_invalid_auth_noctx BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- python/samba/tests/dcerpc/raw_protocol.py | 2623 +++++++++++++++++++++++++++++ 1 file changed, 2623 insertions(+) create mode 100755 python/samba/tests/dcerpc/raw_protocol.py diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py new file mode 100755 index 0000000..ccd0f6b --- /dev/null +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -0,0 +1,2623 @@ +#!/usr/bin/env python +# Unix SMB/CIFS implementation. +# Copyright (C) Stefan Metzmacher 2014,2015 +# +# 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 3 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, see . +# + +import sys +import os + +sys.path.insert(0, "bin/python") +os.environ["PYTHONUNBUFFERED"] = "1" + +import samba.dcerpc.dcerpc as dcerpc +import samba.dcerpc.base as base +import samba.dcerpc.epmapper +import samba.dcerpc.mgmt +import samba.dcerpc.netlogon +import struct +from samba.credentials import Credentials +from samba import gensec +from samba.tests import RawDCERPCTest + +global_ndr_print = False +global_hexdump = False + +class TestDCERPC_BIND(RawDCERPCTest): + + def setUp(self): + super(TestDCERPC_BIND, self).setUp() + self.do_ndr_print = global_ndr_print + self.do_hexdump = global_hexdump + + def _test_no_auth_request_bind_pfc_flags(self, req_pfc_flags, rep_pfc_flags): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + pfc_flags=rep_pfc_flags, auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request + req = self.generate_request(call_id = 1, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a alter context + req = self.generate_alter(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, + pfc_flags=rep_pfc_flags, auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 0) + self.assertEquals(rep.u.secondary_address, "") + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request + req = self.generate_request(call_id = 1, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def test_no_auth_request(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_00(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_FIRST(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_LAST(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_LAST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_bind_pfc_HDR_SIGNING(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_request_bind_pfc_08(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 8 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX + # by default + def _test_no_auth_request_bind_pfc_CONC_MPX(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX) + + def test_no_auth_request_bind_pfc_DID_NOT_EXECUTE(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_MAYBE(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_MAYBE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_OBJECT_UUID(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX + # by default + def _test_no_auth_request_bind_pfc_ff(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 0xff | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX) + + def test_no_auth_request_alter_pfc_00(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_FIRST(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_LAST(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_LAST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_alter_pfc_HDR_SIGNING(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_request_alter_pfc_08(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 8 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_CONC_MPX(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_DID_NOT_EXECUTE(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_MAYBE(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_MAYBE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_OBJECT_UUID(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_alter_pfc_ff(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 0xff | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_no_ctx(self): + # send an useless bind + req = self.generate_bind(call_id=0) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + def test_invalid_auth_noctx(self): + req = self.generate_bind(call_id=0) + req.auth_length = dcerpc.DCERPC_AUTH_TRAILER_LENGTH + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + def test_no_auth_valid_valid_request(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # Send a bind again + tsf2_list = [ndr32] + ctx2 = dcerpc.ctx_list() + ctx2.context_id = 2 + ctx2.num_transfer_syntaxes = len(tsf2_list) + ctx2.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx2.transfer_syntaxes = tsf2_list + + req = self.generate_bind(call_id=1, ctx_list=[ctx2]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_no_auth_invalid_valid_request(self): + # send an useless bind + req = self.generate_bind(call_id=0) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_alter_no_auth_no_ctx(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # Send a alter + req = self.generate_alter(call_id=1, ctx_list=[]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + pfc_flags=req.pfc_flags | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, 0) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def _test_auth_none_level_bind(self, auth_level, + reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + ctx_list = [ctx1] + + auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE + auth_context_id = 0 + + auth_info = self.generate_auth(auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + auth_blob="none") + + req = self.generate_bind(call_id=0, + ctx_list=ctx_list, + auth_info=auth_info) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, reason) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_auth_none_none_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_NONE, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_connect_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CONNECT) + + def test_auth_none_call_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CALL) + + def test_auth_none_packet_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PACKET) + + def test_auth_none_integrity_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY) + + def test_auth_none_privacy_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PRIVACY) + + def test_auth_none_0_bind(self): + return self._test_auth_none_level_bind(0, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_7_bind(self): + return self._test_auth_none_level_bind(7, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_255_bind(self): + return self._test_auth_none_level_bind(255, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def _test_auth_none_level_request(self, auth_level): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + ctx_list = [ctx1] + + auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE + auth_context_id = 0 + + req = self.generate_bind(call_id=0, + ctx_list=ctx_list) + + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(len(rep.u.auth_info), 0) + + # And now try a request without auth_info + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + auth_info = self.generate_auth(auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + auth_blob="none") + + req = self.generate_request(call_id = 3, + context_id=ctx1.context_id, + opnum=0, + stub="", + auth_info=auth_info) + self.send_pdu(req) + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_auth_none_none_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_NONE) + + def test_auth_none_connect_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CONNECT) + + def test_auth_none_call_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CALL) + + def _test_neg_xmit_check_values(self, + req_xmit=None, + req_recv=None, + rep_both=None, + alter_xmit=None, + alter_recv=None): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + max_xmit_frag=req_xmit, + max_recv_frag=req_recv, + ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, rep_both) + self.assertEquals(rep.u.max_recv_frag, rep_both) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + assoc_group_id = rep.u.assoc_group_id + if alter_xmit is None: + alter_xmit = rep_both - 8 + if alter_recv is None: + alter_recv = rep_both - 8 + + # max_{xmit,recv}_frag and assoc_group_id are completely + # ignored in alter_context requests + req = self.generate_alter(call_id=1, + max_xmit_frag=alter_xmit, + max_recv_frag=alter_recv, + assoc_group_id=0xffffffff-rep.u.assoc_group_id, + ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, rep_both) + self.assertEquals(rep.u.max_recv_frag, rep_both) + self.assertEquals(rep.u.assoc_group_id, rep.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 0) + self.assertEquals(len(rep.u._pad1), 2) + #self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + chunk_size = rep_both - dcerpc.DCERPC_REQUEST_LENGTH + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req,ndr_print=True,hexdump=True) + rep = self.recv_pdu(ndr_print=True,hexdump=True) + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + chunk_size = 5840 - dcerpc.DCERPC_REQUEST_LENGTH + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + chunk_size += 1 + req = self.generate_request(call_id = 3, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req) + rep = self.recv_pdu() + # We get a fault + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, 0) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_neg_xmit_ffff_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=0xffff, + rep_both=5840) + + def test_neg_xmit_0_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=0xffff, + rep_both=2048, + alter_xmit=0xffff, + alter_recv=0xffff) + + def test_neg_xmit_ffff_0(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=0, + rep_both=2048) + + def test_neg_xmit_0_0(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=0, + rep_both=2048, + alter_xmit=0xffff, + alter_recv=0xffff) + + def test_neg_xmit_3199_0(self): + return self._test_neg_xmit_check_values(req_xmit=3199, + req_recv=0, + rep_both=2048) + def test_neg_xmit_0_3199(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=3199, + rep_both=2048) + + def test_neg_xmit_3199_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=3199, + req_recv=0xffff, + rep_both=3192) + def test_neg_xmit_ffff_3199(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=3199, + rep_both=3192) + + def test_alloc_hint(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx = dcerpc.ctx_list() + ctx.context_id = 0 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + ctx_list=[ctx]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request without auth_info + req = self.generate_request(call_id = 2, + context_id=ctx.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + req = self.generate_request(call_id = 3, + context_id=ctx.context_id, + opnum=1, + alloc_hint=0xffffffff, + stub="\04\00\00\00\00\00\00\00") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + req = self.generate_request(call_id = 4, + context_id=ctx.context_id, + opnum=1, + alloc_hint=1, + stub="\04\00\00\00\00\00\00\00") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def _get_netlogon_ctx(self): + abstract = samba.dcerpc.netlogon.abstract_syntax() + self.epmap_reconnect(abstract) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx = dcerpc.ctx_list() + ctx.context_id = 0 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + ctx_list=[ctx]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + port_str = "%d" % self.tcp_port + port_len = len(port_str) + 1 + mod_len = (2 + port_len) % 4 + if mod_len != 0: + port_pad = 4 - mod_len + else: + port_pad = 0 + self.assertEquals(rep.u.secondary_address_size, port_len) + self.assertEquals(rep.u.secondary_address, port_str) + self.assertEquals(len(rep.u._pad1), port_pad) + self.assertEquals(rep.u._pad1, '\0' * port_pad) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + server = '\\\\' + self.host + server_utf16 = unicode(server, 'utf-8').encode('utf-16-le') + computer = 'UNKNOWNCOMPUTER' + computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le') + + real_stub = struct.pack(' 0: + thistime = min(remaining, chunk) + remaining -= thistime + total += thistime + + pfc_flags = 0 + if first: + pfc_flags |= dcerpc.DCERPC_PFC_FLAG_FIRST + first = False + stub = real_stub + '\x00' * (thistime - len(real_stub)) + else: + stub = "\x00" * thistime + + if remaining == 0: + pfc_flags |= dcerpc.DCERPC_PFC_FLAG_LAST + + # And now try a request without auth_info + # netr_ServerReqChallenge() + req = self.generate_request(call_id = 2, + pfc_flags=pfc_flags, + context_id=ctx.context_id, + opnum=4, + alloc_hint=alloc_hint, + stub=stub) + if alloc_hint >= thistime: + alloc_hint -= thistime + else: + alloc_hint = 0 + self.send_pdu(req,hexdump=False) + if fault_first is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_first) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + if remaining == 0: + break + if total >= 0x400000 and fault_last is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_last) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + rep = self.recv_pdu(timeout=0.01) + self.assertIsNone(rep) + self.assertIsConnected() + + if total >= 0x400000 and fault_last is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_last) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + self.assertEquals(len(rep.u.stub_and_verifier), 12) + status = struct.unpack_from(" Date: Fri, 26 Jun 2015 21:05:53 +0200 Subject: [PATCH 439/440] CVE-2015-5370: s4:selftest: run samba.tests.dcerpc.raw_protocol against plugin_s4_dc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 295b719..5d451e9 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -528,6 +528,7 @@ planpythontestsuite("dc:local", "samba.tests.dcerpc.rpcecho") planoldpythontestsuite("dc:local", "samba.tests.dcerpc.registry", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("plugin_s4_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("plugin_s4_dc", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) plantestsuite_loadlist("samba4.ldap.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.python(dc)", "dc:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite("samba4.sam.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) -- 1.9.1 From 9ccc13f2f8261716072681277678e53b5d7f9575 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Apr 2016 10:05:38 +0200 Subject: [PATCH 440/440] s3:libads: sasl wrapped LDAP connections against with kerberos and arcfour-hmac-md5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression in commit 2cb07ba50decdfd6d08271cd2b3d893ff95f5af9 (s3:libads: make use of ads_sasl_spnego_gensec_bind() for GSS-SPNEGO with Kerberos) that prevents things like 'net ads join' from working against a Windows 2003 domain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/libads/sasl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 4fcd733..22aa9cf 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -312,7 +312,13 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped; - ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; + /* + * Note that we have to truncate this to 0x2C + * (taken from a capture with LDAP unbind), as the + * signature size is not constant for Kerberos with + * arcfour-hmac-md5. + */ + ads->ldap.in.min_wrapped = MIN(ads->ldap.out.sig_size, 0x2C); ads->ldap.in.max_wrapped = max_wrapped; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security); if (!ADS_ERR_OK(status)) { -- 1.9.1