From 3fd1da563ea3ea5fe4faf0e7c910deeb97eebd41 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 24 Aug 2015 20:26:42 -0700 Subject: [PATCH 001/352] 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 11fd93887cf72ddccdd592a3070e3b03657d07a7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Dec 2015 21:49:26 +0100 Subject: [PATCH 002/352] 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 9f4924c..68935eb 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -996,34 +996,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 0874561d40f5e6065a8fdca337a9671d0e04a327 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Dec 2015 10:41:39 +0100 Subject: [PATCH 003/352] 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 68935eb..98cd41c 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -996,7 +996,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; @@ -1008,14 +1008,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 0c664b7..c3b0c59 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -1635,6 +1635,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 @@ -1642,5 +1644,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 d9c500ffae53c6e8e3a7950d933a30c28d41fd01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Dec 2015 13:50:54 +0100 Subject: [PATCH 004/352] 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 98cd41c..6f51820 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 c4e50894c311a8eb3a69db5596f8b1651f0acdda Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Dec 2015 10:57:07 +0100 Subject: [PATCH 005/352] 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 6f51820..d8d0f99 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 8fada2a70afaca2bc683213e7d51230be0327831 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Dec 2015 11:18:47 +0100 Subject: [PATCH 006/352] 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 d8d0f99..dcab2bd 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 5ae9d8d19c07b80c2be9ce1635020822e57daf89 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 17:58:21 +0100 Subject: [PATCH 007/352] 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 dcab2bd..555ec22 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 498fb973149a7d95e55249906570c65640a7321a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 18:11:00 +0100 Subject: [PATCH 008/352] 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 c3b0c59..ba0e5e0 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) @@ -845,7 +845,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; } @@ -960,7 +961,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; } @@ -979,7 +981,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; } @@ -1017,7 +1020,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; } @@ -1618,7 +1622,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 52c19a9..cebe529 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 b1ecd18..2364ae9 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 447656b3b556f11f15d78d206f482b3cb64cda52 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:50:49 +0100 Subject: [PATCH 009/352] 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 555ec22..f17cb47 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 c9b803f3a9e4e56b9928b84124243794980eefbc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:51:07 +0100 Subject: [PATCH 010/352] 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 cebe529..61ccdae 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 2364ae9..96bd05e 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 50be801536876e331e1f963542b5649984db70e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 21:53:23 +0100 Subject: [PATCH 011/352] 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 f17cb47..a869f6d 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -1018,6 +1018,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 5829980c3f1f3e861f57fb05e953420a4751dc57 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Jan 2016 20:10:53 +0100 Subject: [PATCH 012/352] 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 ba0e5e0..42e71e1 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 61ccdae..6b33d61 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 96bd05e..e1ade6a 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 99b51c80f564253d6367df9b64383edf9013254f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:23:20 +0100 Subject: [PATCH 013/352] 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 a869f6d..4fb84d5 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 4417f6d976b72c9e178ac3d740469c78f4253e6f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:24:01 +0100 Subject: [PATCH 014/352] 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 42e71e1..cb3d9b3 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -1625,7 +1625,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 01d9096b8a63b4f0698c174aa460a22b3ba197c6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:25:41 +0100 Subject: [PATCH 015/352] 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 4fb84d5..755b5ce 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 c395af60213f2cf380f3906fa0c6360e208b15c1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 5 Jan 2016 10:55:44 +0100 Subject: [PATCH 016/352] 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 6b33d61..5cf476b 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 e1ade6a..057cddd 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 9be81ab646e1321c6f6ebdae5816d5a4505dcb53 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:30:35 +0100 Subject: [PATCH 017/352] 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 964cb0a..dd9d40b 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 d76620ac14eaa629f85901784fe066b9d71f7e2e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jan 2016 10:42:11 +0100 Subject: [PATCH 018/352] 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 6dd7c64..e4b386a 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 e05ca4a5450d0f9f6440bffae1908aee014bc14c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Jan 2016 21:26:50 +0100 Subject: [PATCH 019/352] 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 755b5ce..fed6590 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 5bda02a1b4360ccb4cdf94e8d8eb933607055153 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Jan 2016 15:03:47 -0800 Subject: [PATCH 020/352] 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 5cf476b..3300c85 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 5477e1f7cd24dc1f56265302c73e3259bdbb1cf2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 15:50:06 +0100 Subject: [PATCH 021/352] 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 3300c85..82f13b7 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 5d86fc8632c676b35eded459321ffcbe01dca255 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 14:48:20 +0100 Subject: [PATCH 022/352] 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 4de89fa55f56f2fa2fdfe7d5a2f09bf8426b3ce6 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 023/352] 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 188a3b80..5c3e9f1 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 7e222f74bf42fbf239ecb0fdb4dbc0aec483cac5 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 024/352] 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 4a9e7c2..83d42a5 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; /* @@ -141,7 +142,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 6ded4f51382c881816bb3fcc6bf90f91ad499fc4 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 025/352] 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 83d42a5..ceccf79 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -186,7 +186,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 ce19ca1744ca64972483d8e4e0f16d9ecbab1593 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 026/352] 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 ceccf79..df6773c 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 ed83a52e27f0ef6ee2ed9cfc358e5faff06b5dbe 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 027/352] 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 a14619ffe827bac0d5251bb446a8d20d220f25b0 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 028/352] 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 36127ce..5339558 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 9b4821e83eaf8097a199c2d7b29e119338147f67 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 029/352] 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 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 5339558..0a593ba 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -54,7 +54,6 @@ static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, return true; } -#if 0 static const uint8_t ntlmssp_CHALLENGE_MESSAGE_data[] = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x38, 0x00, 0x00, 0x00, 0x95, 0x82, 0x89, 0xe2, @@ -126,16 +125,14 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, { return true; } -#endif 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 4fbdc79c4eccf1158cd37d070f9ae826e867db7e 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 030/352] 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 0c7694b0ac45781783c035805aa166809061aef6 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 031/352] 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 27f89de00cfbb0f7f9405399c0a9636c49585d84 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 032/352] 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 99f7abd96ed948330d9698baaff1ceca5a2609d3 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Mon, 8 Feb 2016 23:20:19 +0100 Subject: [PATCH 033/352] 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 7134788855d8ae8c17769db1864a829a8a50899c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Jan 2016 21:49:21 +0100 Subject: [PATCH 034/352] 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 82f13b7..9aab8fd 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 874705509c856ed226ddfe8d01bf0fba3fb4cf89 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 035/352] 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 ba32ae0d23893c0976cb3b61b4166cc5ede68707 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 036/352] 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 d40e6a0ac4f01adb60cb63ce51cee6615d1f8f30 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:47:59 +0100 Subject: [PATCH 037/352] 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 057414c..cc075b9 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 84fa79988cb40d99851abdbd69bbabe2929bbde4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:53:21 +0100 Subject: [PATCH 038/352] 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 (cherry picked from 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 79db4b5..2dfdb1e 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -136,6 +136,9 @@ for env in ["nt4_dc", "nt4_member", "ad_member"]: 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="nt4_dc" +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 ["nt4_member", "ad_member"]: 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 e470bc63dcb5d58f07e4f3672def2eadfa025d57 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 17:15:24 +0200 Subject: [PATCH 039/352] 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 a4d57e71c1631d27290c8d984e8c24e60f083ab4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:35:19 +0200 Subject: [PATCH 040/352] 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 d5f75a877332b5c7d3200ea4254af9fc1d17bace Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:36:36 +0200 Subject: [PATCH 041/352] 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 6508e895083409d12e461522015d7d2e773ab259 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:06:47 +0100 Subject: [PATCH 042/352] 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 6ce0d35..47bf3d0 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2232,6 +2232,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 e529cdd0777d6bc8c3bf175ac7dc5a6fb52074eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:36:14 +0100 Subject: [PATCH 043/352] 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 (cherry picked from commit cd8af25d4bf87a9156cb2afb3dd206c68b1bedd7) --- source3/libads/ads_proto.h | 1 - source3/libads/ldap.c | 134 --------------------------------------------- 2 files changed, 135 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 2e38df1..bc6c060 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -552,140 +552,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) c_realm, c_domain, nt_errstr(status))); return status; } - -/********************************************************************* - *********************************************************************/ - -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; - - if (!realm) - realm = lp_realm(); - - if ((sitename = sitename_fetch(frame, realm)) == NULL) { - ads_lookup_site(); - sitename = sitename_fetch(frame, realm); - } - - 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, - 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 e62aa1188948ad3d9505a3869fbe39af411cffd8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:18:22 +0200 Subject: [PATCH 044/352] 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 4b3a69f..34f81b6 100644 --- a/wscript_configure_system_mitkrb5 +++ b/wscript_configure_system_mitkrb5 @@ -59,7 +59,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') @@ -87,6 +88,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 7f782fd77ebe030195009a055b7abb496e842415 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:05 +0200 Subject: [PATCH 045/352] 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 33a32c3..1540f8cf 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 54a433c66e58ecf69c0956307aeb22ec58c917f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:53 +0200 Subject: [PATCH 046/352] 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 1540f8cf..426e28a 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 2d686efe4e7934b1b31ac8e04329b7d491aca18a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:22:44 +0200 Subject: [PATCH 047/352] 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 426e28a..749fa7a 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 a6f7946a286f13ca8f004872cf776f6b9718e4ed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 17:37:38 +0100 Subject: [PATCH 048/352] 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 749fa7a..68f98a9 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 a4505c1241a1f5b18d5e3b2dd68c4a6fe2b0c164 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:42:41 +0100 Subject: [PATCH 049/352] 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 68f98a9..6cd48a1 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 f536d0649ab79123f7b5d8720486075b0be9a5e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:52:29 +0100 Subject: [PATCH 050/352] 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 6cd48a1..6ea2c4a 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 868ac5bb96f509cd145feb100e6e8f7aa335e9a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Aug 2015 10:53:34 +0200 Subject: [PATCH 051/352] 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 2c98776..b92d0b8 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -540,6 +540,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" }, @@ -577,6 +654,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 1a49bd501f0c5e53cdde46e7bd4702f84e127a56 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 052/352] 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 66485e80a771d36e749a60d67ebc7da45bfd7103 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:29:40 +0100 Subject: [PATCH 053/352] 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 be31697..8d4bfa7 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -211,8 +211,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 e99507401390c0a129d72bc68965b081a711006a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:43:02 +0100 Subject: [PATCH 054/352] 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 8d4bfa7..bb9cd18 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -255,8 +255,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 edf83de6edec896f4ae4b24d799eb64b2907ee6c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:44:02 +0100 Subject: [PATCH 055/352] 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 07df62a..2672dc2 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -42,7 +42,8 @@ NTSTATUS auth_generic_set_creds(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 68d1451..c07445e 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -151,6 +151,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 bafef18bdb96ff994cda47ada1903594c41b82cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:39:04 +0100 Subject: [PATCH 056/352] 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 2672dc2..02d2b4b 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -47,6 +47,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 c07445e..27f4801 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -198,3 +198,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 dde7b9c6ceaf8391e068c8c07bad1048779a3221 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 22:15:50 +0100 Subject: [PATCH 057/352] 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 3a4f8b8683d7a94154f050228420c6b30332a4b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 058/352] 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 375a662d8d74f26df6c233dbd250d0d9abc521b2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 21:23:33 +0100 Subject: [PATCH 059/352] 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 a5fd249..7f5ac9d 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 954849ac1b48ff7d3a7bb9fe49151e7410cfc4a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:11:05 +0100 Subject: [PATCH 060/352] 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 6306c92907b98ac76d6a4f8dc45a62c9e972e63f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 061/352] 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 56abc376b01bfae12b5b4aa959ced4281028ad27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 062/352] 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 1ff59695b746140fe4b53e04ebe5ed5a0be3c7b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 09:07:33 +0100 Subject: [PATCH 063/352] 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 939da9b..ed0543c 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 ad2e8ab0cf58e4c455b2672db729bd2a9e08d660 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:45:33 +0100 Subject: [PATCH 064/352] 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 27f4801..67d27c6 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -100,7 +100,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 ebe14bf667a6a17d94c43da0afc5241c5fdfe971 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:47:40 +0100 Subject: [PATCH 065/352] 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 02d2b4b..0911182 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -50,6 +50,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 ba670d3..506ebf3 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -373,8 +373,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 c54fbf8dfa4a1b186be9bfe493875490ed8f8a9f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Nov 2015 21:41:23 +0100 Subject: [PATCH 066/352] 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 c1af0d29a71561b404c77a75f38d482666a802db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 13:42:30 +0100 Subject: [PATCH 067/352] 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 4fdd817e5e6682152c644925f2c7b0dbc4274e6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 15:35:40 +0100 Subject: [PATCH 068/352] 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 aad6bc4effe3094e1bd43ec1766f005c183af7af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Dec 2015 15:42:51 +0100 Subject: [PATCH 069/352] 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 67d27c6..59560d6 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -86,7 +86,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; @@ -101,6 +101,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 184c10d6e84488427be5513fb6154cb21a6b7ac0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:46:52 +0100 Subject: [PATCH 070/352] 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 ed0543c..ddedf6a 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 68b128aa63d70d9e1fd1aabe4bac946c3faa3152 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 10:54:56 +0100 Subject: [PATCH 071/352] 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 7f5ac9d..077c97b 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 249578846900fa9553b9be854b51bcf9fac51494 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:16:02 +0100 Subject: [PATCH 072/352] 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 fd9b826046e3d9df62c30736ee260bd132f13f21 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 073/352] 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 bdc241c339ae399d3111c1c2cc7084fc64fc6ebd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 074/352] 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 27d614dfb97b53fdd70e5d617260fe54ede4c5b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Dec 2015 13:59:42 +0100 Subject: [PATCH 075/352] 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 69d463db0b71de8f68c43e3d0605a137c8f597db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 076/352] 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 6a2466e5432da1caeda90cb1eca8969c792148cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:05:17 +0100 Subject: [PATCH 077/352] 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 4e56657a3d5f886bf4df981e3ba6d3bbdeda4807 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 078/352] 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 844b4d26e2382f6480e39b0d53ee2acd7898306e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:07:23 +0100 Subject: [PATCH 079/352] 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 bdf079c4defb9db9a3708a840d204a87a6d8d30d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:06:56 +0100 Subject: [PATCH 080/352] 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 b78307e..bb811ae 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 559468fab306e2521bc5c41a393a62573c98a1ba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:07:57 +0100 Subject: [PATCH 081/352] 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 df6773c..5d8a12a 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 */ @@ -127,20 +129,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, @@ -157,7 +158,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 65ed53ee99c1fd3f5443a6aa650e7e37847fa7fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 15:38:02 +0100 Subject: [PATCH 082/352] 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 5d8a12a..15c700e 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -172,7 +172,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 3251e55cd3e22a254b231a7121ec3613e7fcef27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 15:40:29 +0100 Subject: [PATCH 083/352] 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 cace8670a749254b9dc1c06f181d7ef59d89a9ce 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 084/352] 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 ba20371ed9a4887ea92859c98fbf35fe75f97f66 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 085/352] 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 52b4f78acb7eb81472e197c3cc5dbb8c160648a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 086/352] 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 e98e68c6be4139209041ca8adc288cdf8dcfa155 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 087/352] 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 09c8c53411993791587f0533e5b9c77aace11bbb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 12:58:51 +0100 Subject: [PATCH 088/352] 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 e814e05fbe20dc33c0d5c10db0c8333862b6df79 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 089/352] 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 0da49f3..b10b79d 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 7eaf94e18563ed375c7a30326cf42a4fa88e2475 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 13:10:58 +0100 Subject: [PATCH 090/352] 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 b10b79d..d2f4ca7 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 9f86bd32be4a0ae372ad54d14bbd91fedcc28a34 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 09:54:08 +0100 Subject: [PATCH 091/352] 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 (cherry picked from 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 69330f2..2c226a7 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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side -- 1.9.1 From 2c1cb713eb3e85c5e63d8291df57930cc893da6e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:46:22 +0100 Subject: [PATCH 092/352] 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 (cherry picked from 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 2c226a7..e044113 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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side try: -- 1.9.1 From 46edf6fb4c800c2d418a98f161f8730a5bc227d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 093/352] 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 7d70c076d17930a60877bccb6489325f09156edd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:53:45 +0100 Subject: [PATCH 094/352] 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 5f05a2b055c0e34e16370c35558f6e3f65b8e405 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:04:02 +0100 Subject: [PATCH 095/352] 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 8e67479ac933870e14957c3cc1b0b4b141aa83d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:02:29 +0100 Subject: [PATCH 096/352] 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 b3712a9399b32fecff0714f01d87ccd06c711130 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:14:05 +0100 Subject: [PATCH 097/352] 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 d9e421c47337ad29c0ae65bb494b6c5135b09a58 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:31:01 +0100 Subject: [PATCH 098/352] 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 e542049c0486d0bb4eb85cd37596f2278420dcfa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:33:04 +0100 Subject: [PATCH 099/352] 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 d1eb908b10463a320dc9323f88d820030582362c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:42:51 +0100 Subject: [PATCH 100/352] 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 4ac2818d85b2f8b1775f0dc17597c18df1952179 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 14:34:46 +0100 Subject: [PATCH 101/352] 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 530f5c3..e71b8cb 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" @@ -1414,17 +1417,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; } @@ -1437,8 +1441,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); @@ -1447,51 +1449,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); @@ -1506,9 +1542,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) @@ -1517,32 +1550,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 @@ -1552,13 +1594,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; @@ -1567,20 +1608,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; } @@ -1589,49 +1629,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 ab3b34882e49624ac8b7f373cbbe08ef01d4c53c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 11:49:37 +0100 Subject: [PATCH 102/352] 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 4b86db0..bd8c4a1 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -899,31 +899,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 506ebf3..be0b831 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -372,13 +372,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 @@ -406,7 +402,6 @@ bld.SAMBA3_LIBRARY('libsmb', libsmb/smbsock_connect.c libsmb/cli_smb2_fnum.c''', deps=''' - LIBNTLMSSP auth_generic CLDAP LIBNMB @@ -1452,7 +1447,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 b3dae62c7229129833a79a1103b15b7b30e9f36f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 18:31:50 +0100 Subject: [PATCH 103/352] 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 e71b8cb..9f75b89 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1420,7 +1420,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; }; @@ -1432,13 +1436,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; @@ -1521,13 +1529,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); @@ -1536,125 +1537,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 2b2a71b73c340baf90d3534005f16b1b3f37e73b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 15:47:11 +0100 Subject: [PATCH 104/352] 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 9f75b89..bb8d018 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1414,7 +1414,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; @@ -1428,30 +1428,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; } @@ -1459,7 +1464,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)) { @@ -1519,7 +1524,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); @@ -1537,7 +1584,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); } @@ -1545,11 +1592,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) { @@ -1563,17 +1610,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); @@ -1591,18 +1638,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) { @@ -1616,18 +1663,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); @@ -1649,18 +1696,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; @@ -1675,6 +1722,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. @@ -1749,11 +1799,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)) { @@ -1833,6 +1883,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; @@ -1876,6 +1927,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", @@ -1923,12 +1975,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; @@ -1964,8 +2014,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); } @@ -1991,9 +2044,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; } @@ -2010,7 +2065,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 06b248e39b0a389495431779367e4c0d78228f6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:35:21 +0100 Subject: [PATCH 105/352] 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 bb8d018..84ad783 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1900,14 +1900,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; req = tevent_req_create(mem_ctx, &state, @@ -2179,10 +2179,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); } @@ -2242,10 +2240,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 ac64bfd348afd20c64492b8cf91225b9288e3de6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:58:30 +0100 Subject: [PATCH 106/352] 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 84ad783..a4e4828 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1270,7 +1270,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; @@ -1407,7 +1407,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) tevent_req_received(req); return ADS_SUCCESS; } - +#endif #endif /* HAVE_KRB5 */ /**************************************************************************** @@ -2000,8 +2000,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); } @@ -2034,9 +2037,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 1eed22c5f6b37e4d5b70c4978137e1145a18057b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:16 +0100 Subject: [PATCH 107/352] 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 (cherry picked from commit 95b953950d1fd454121ff23a43a8b13a34385ef1) --- source3/libsmb/cliconnect.c | 141 -------------------------------------------- 1 file changed, 141 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a4e4828..97d0352 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1267,147 +1267,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) { - NTSTATUS status; - - state->ads_status = ADS_ERROR_KRB5(rc); - status = ads_ntstatus(state->ads_status); - if (NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL)) { - status = NT_STATUS_LOGON_FAILURE; - state->ads_status = ADS_ERROR_NT(status); - } - DEBUG(1, ("cli_session_setup_kerberos: " - "spnego_gen_krb5_negTokenInit failed: %s - %s\n", - error_message(rc), nt_errstr(status))); - tevent_req_nterror(req, status); - 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)) { - ADS_STATUS ads = state->ads_status; - - if (!ADS_ERR_OK(state->ads_status)) { - ads = state->ads_status; - } else { - ads = ADS_ERROR_NT(status); - } - tevent_req_received(req); - return ads; - } - tevent_req_received(req); - return ADS_SUCCESS; -} -#endif #endif /* HAVE_KRB5 */ /**************************************************************************** -- 1.9.1 From 230b3436f57bfd3d035521af31a1fe762d00fb96 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:41 +0100 Subject: [PATCH 108/352] 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 (cherry picked from 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 bd8c4a1..ecab853 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -729,13 +729,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 @@ -745,18 +738,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_t 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_t 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 9aab8fd..4a0fbcd 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_t 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_t 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 8e770a185a00b2b601a753749ce894f71cff7577 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Dec 2015 08:55:03 +0100 Subject: [PATCH 109/352] 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 0dd5c17cb9d78ef00618e5874a51261d62ea5c68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Feb 2016 07:47:39 +0100 Subject: [PATCH 110/352] 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 a3b8aaa..a4d36aa 100644 --- a/source4/torture/rpc/backupkey.c +++ b/source4/torture/rpc/backupkey.c @@ -1545,8 +1545,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; @@ -1571,9 +1573,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 eb324f1ece5d37dd22babc0aea37c346e04514fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 20:18:42 +0100 Subject: [PATCH 111/352] 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 e044113..322d4d5 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 62272c86400db8b40994c54b25bf4e325b6fd724 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 22:44:24 +0100 Subject: [PATCH 112/352] 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 ade4a40..5f3f3d5 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1362,7 +1362,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; @@ -1374,10 +1373,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); @@ -1386,7 +1381,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)); @@ -1406,7 +1401,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( @@ -1433,7 +1428,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; @@ -1532,26 +1527,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"); @@ -1799,20 +1782,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"); } @@ -1833,6 +1802,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"); } @@ -1844,7 +1827,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)) { @@ -1899,7 +1882,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 6e9e63f36e8e098232e80035eabcff0fdeb3d912 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 113/352] 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 (cherry picked from 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 d9e2823..09a0f79 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 @@ -211,6 +214,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\(nt4_dc\) # We fail this test currently ^samba3.rpc.samr.passwords.lockout.*\(nt4_dc\)$ # 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 ff3e60e..9adaa61 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -776,6 +776,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 1172db8e12ccfd87d3cf1fd8e170a60dc2e58543 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Feb 2016 16:41:10 +0100 Subject: [PATCH 114/352] 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 2a33afd90ba96ab659b26f534568acda36edffaa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 115/352] 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 adc4b5a5d471afac474ebde7f4f1e9bed5695899 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 16 Jan 2016 13:57:47 +0100 Subject: [PATCH 116/352] selftest: s!addc.samba.example.com!addom.samba.example.com! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's confusing to have addc.samba.example.com as domain name and addc.addc.samba.example.com as hostname. We now have addom.samba.example.com as domain name and addc.addom.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 (cherry picked from 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 65308e2..8ac3286 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1864,7 +1864,7 @@ sub provision_ad_dc($$) "domain controller", "addc", "ADDOMAIN", - "addc.samba.example.com", + "addom.samba.example.com", "2008", "locDCpass1", undef, -- 1.9.1 From 808e0e770315029147995d4ae4d58b795b81059f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 117/352] 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 6b8b3e1d2fd128caf36979ddc804dd25d2c24849 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:08:02 +0100 Subject: [PATCH 118/352] 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..86956aa --- /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 addc.addom.samba.example.com 0123456789ABCDEF +./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.samba.example.com -- 1.9.1 From eddf0f725a9602ba2b43c784aaa37671062ca468 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:09:31 +0100 Subject: [PATCH 119/352] 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-addc.addom.samba.example.com-S02-cert.pem | 191 ++++++++++++++++ .../DC-addc.addom.samba.example.com-S02-key.pem | 54 +++++ ...DC-addc.addom.samba.example.com-S02-openssl.cnf | 250 +++++++++++++++++++++ ...ddc.addom.samba.example.com-S02-private-key.pem | 51 +++++ .../DC-addc.addom.samba.example.com-S02-req.pem | 30 +++ .../DC-addc.addom.samba.example.com-cert.pem | 1 + ...DC-addc.addom.samba.example.com-private-key.pem | 1 + .../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 + .../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 | 169 ++++++++++++++ .../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 +++ ...inistrator@addom.samba.example.com-S03-cert.pem | 169 ++++++++++++++ ...ministrator@addom.samba.example.com-S03-key.pem | 30 +++ ...strator@addom.samba.example.com-S03-openssl.cnf | 242 ++++++++++++++++++++ ...tor@addom.samba.example.com-S03-private-key.pem | 27 +++ ...ministrator@addom.samba.example.com-S03-req.pem | 19 ++ ...-administrator@addom.samba.example.com-cert.pem | 1 + ...strator@addom.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, 3264 insertions(+) create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem 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/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@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.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/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem new file mode 100644 index 0000000..2e2a8b9 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.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 16 23:29:25 2016 GMT + Not After : Mar 11 23:29:25 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=addc.addom.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:a6:c4:a9:bf:75:ea:4c:8d:3b:fd:8a:0f:b0:a2: + b6:c7:a8:1f:e4:0e:3e:41:ef:d6:10:48:77:7b:4e: + 4c:59:e1:bf:6d:c7:18:7b:a8:01:a7:d5:d2:2c:21: + 3e:d0:1a:da:58:03:e8:42:f1:53:0e:a7:91:b9:2c: + b9:e7:7a:c9:de:5e:ed:4c:93:6b:cc:dd:17:d0:c7: + d1:f1:7c:3d:0d:6f:df:5d:53:5a:b1:1f:a3:7b:5b: + 41:65:0c:7c:ea:53:df:bb:da:41:15:da:49:e3:b9: + 2d:bb:b5:af:ef:8c:b8:84:74:d0:18:16:8e:5c:e4: + c2:e7:a1:87:8f:e3:87:8b:0b:bb:90:30:e8:e0:f3: + eb:c0:50:5f:b5:7f:54:9a:1b:34:43:fd:be:5a:80: + 6e:0f:63:a2:b3:79:42:4a:85:c8:07:c7:82:55:23: + 88:d4:4e:03:2f:f1:95:bd:ed:15:2d:3e:16:cd:ff: + c7:9b:03:29:36:a6:5d:c9:1a:1e:89:a5:ba:66:83: + 0f:96:a8:07:9f:24:b9:1b:8f:02:9a:b8:50:29:8b: + be:63:45:fa:45:c3:38:23:a0:98:3a:b4:6b:42:99: + 13:36:4b:84:ef:27:89:39:34:79:f8:67:16:7b:9c: + 2a:03:41:15:63:46:e4:db:2f:f2:3e:6d:fe:7c:20: + 1e:9f:02:48:a4:bc:15:42:a6:f8:38:86:dc:6b:7c: + 4e:67:a3:31:81:8e:b6:30:1a:eb:3d:08:25:19:5f: + 42:dc:39:ec:79:1d:30:0a:fb:16:8f:3d:19:14:cc: + f5:af:d7:c6:75:cf:b3:96:a2:b2:9b:d9:03:01:a3: + ca:88:1d:72:ed:6f:d1:bf:57:56:8e:b9:07:9b:b9: + 04:13:1e:0b:5a:06:6b:2b:43:a2:dc:d5:b7:f4:ba: + d3:ae:9d:ad:fd:d3:8a:7c:2f:87:32:fa:89:88:58: + 00:ae:16:2b:9c:1d:58:82:4d:e5:21:da:d5:6c:f7: + a8:40:8b:c7:02:d5:36:30:ef:3f:09:9b:a6:d2:31: + a3:bf:20:d4:a2:9e:26:c4:b4:c3:0f:0b:6c:00:d1: + 2c:16:b1:2a:eb:06:d9:d5:98:c3:cd:cb:20:68:ad: + 0a:2c:a1:2f:27:41:5c:91:de:49:62:ed:d8:3a:ef: + 68:1c:6d:fe:94:c3:28:68:32:60:08:65:cd:02:9f: + 97:96:2f:0f:87:27:3d:b9:0f:85:62:e8:2b:9a:b4: + f4:d3:d7:c1:93:96:27:23:29:88:b1:39:99:53:3a: + 20:aa:88:44:3b:4a:24:2a:8b:e0:b4:8d:dd:66:30: + df:a6:6e:b7:fc:21:43:16:9e:3e:12:20:c8:7a:30: + c1:3d:ab + 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 addc.addom.samba.example.com + X509v3 Subject Key Identifier: + 3D:BC:70:0C:74:D4:B8:85:49:1D:08:84:C4:1B:27:F2:AF:72:37:D3 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:addc.addom.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 + 9e:8b:bb:0a:7a:dc:c0:94:33:bc:18:a5:e6:4a:1f:ff:8e:21: + b1:8f:33:f0:3e:8b:6c:72:55:c4:47:71:5f:ce:e7:31:ef:5b: + 62:04:b7:57:8f:a8:27:9f:ed:69:d2:ec:a8:0d:e2:76:33:8d: + 41:3a:67:61:5c:53:60:c7:53:ed:d7:99:72:29:1d:ae:d3:ee: + c9:76:1c:6d:18:47:e9:94:dd:2e:97:3f:99:af:b5:f4:a1:7c: + 92:f6:4d:b5:c1:7a:0c:38:ba:d1:b6:19:9a:9f:e2:02:84:d4: + 54:01:38:7b:55:86:4a:ee:3d:85:48:01:da:34:09:69:43:25: + 7e:6e:06:73:e0:b9:7c:b5:9c:4e:9c:b5:52:85:32:62:62:25: + 39:fa:02:4b:51:2e:df:8e:52:17:02:50:f4:99:29:bf:7e:97: + 53:91:12:85:9a:69:62:45:59:c4:5b:3f:af:18:e6:7b:e4:86: + 5d:f1:9e:5a:2b:3e:14:6e:7e:d4:47:24:ef:d9:a8:ec:d9:a6: + cb:b8:4f:1a:86:d9:43:20:41:16:15:5f:81:0d:fe:6b:31:53: + c1:f6:84:4c:f3:03:64:d2:e6:44:3d:7a:60:79:d7:37:6f:33: + de:c0:a8:b9:6e:fe:b2:79:ac:b4:53:92:b8:0a:59:2b:cc:6b: + 37:c4:6f:c6:44:02:f7:7c:c5:c6:a6:6f:c2:ad:de:78:1e:48: + 96:cc:fe:59:2e:53:ce:34:d6:e8:f0:56:43:30:32:90:6f:f9: + 47:76:ab:99:63:e3:e8:a3:f3:83:98:e9:05:2b:ea:f9:f9:9d: + 66:70:c7:2c:00:c2:9e:57:3e:31:43:50:50:c8:db:a8:2d:21: + 4e:6f:39:c2:bd:ef:d8:47:99:27:0d:48:b2:58:f1:be:45:bd: + fe:c4:a2:56:fc:06:02:dc:19:33:85:53:ed:38:59:01:16:bc: + aa:c5:d3:4b:37:54:83:1b:e5:c1:4b:dd:34:6b:e5:d8:35:86: + 95:e6:9f:d2:22:84:b1:e2:4f:a7:2e:4d:e6:9c:eb:db:df:42: + e1:b4:66:e6:58:d3:28:10:34:97:f3:9c:6b:5f:05:2c:47:2c: + e3:75:eb:6f:74:0a:ec:d7:1d:30:80:56:44:12:26:f6:4e:5f: + ff:92:f4:62:02:36:9c:62:eb:39:98:53:68:68:95:fb:94:68: + 69:b8:3c:66:1a:ce:78:c4:cf:c4:6f:21:ac:a8:a6:f4:ab:69: + 2a:2e:00:5d:f7:67:06:b1:4f:97:58:88:55:d8:6e:eb:a5:98: + 50:36:21:70:3d:b0:a4:f5:3b:21:b3:1c:f5:a9:dd:c6:4a:c2: + 89:b8:5a:b3:bc:1f:21:ce:4c:68:5f:98:d8:39:70:d2:7e:a0: + 90:df:ad:a3:13:eb:3c:93:f6:b8:f4:d9:a7:51:b3:0d:ea:ee: + d4:57:aa:db:ca:7c:8a:a0:08:c3:98:9a:3a:b7:ba:2a:50:92: + 26:c2:e3:11:ba:12:60:24:b9:59:df:62:a8:d7:4d:a3:cb:ea: + 46:e8:39:f9:83:14:a8:5c:44:75:71:6b:7f:99:bd:68:58:d9: + 6b:d1:cd:c7:45:95:9e:44:1e:85:35:c0:30:2b:18:aa:eb:2f: + 93:d5:be:66:5d:70:ed:1d:04:f2:c1:1e:b5:ec:45:0c:04:f6: + 9d:88:d3:0c:20:5e:5b:23:df:34:a1:f5:ea:b4:a1:44:c0:da: + d5:ea:89:e8:b5:cb:dc:f8:92:ee:ac:8d:61:ed:bf:74:2b:28: + 79:1f:f4:9a:ff:63:bd:e6:aa:79:1d:2c:26:4a:b2:26:53:57: + ba:88:0e:eb:19:57:c0:10:a0:1e:81:2a:c0:56:2e:c3:2a:81: + bf:c1:5a:e7:48:ce:c1:6a:b9:6c:41:cc:44:a6:b8:70:e2:57: + 0e:6d:41:d6:61:da:bf:ac:20:2c:a7:2a:67:23:98:00:ba:ce: + 8b:a8:c2:45:66:a7:08:eb:7f:0a:b5:e7:9b:d6:f4:07:d5:b3: + 43:cd:27:d4:fa:c9:40:8f:af:b2:36:1c:e7:44:b4:4e:cc:5a: + 2b:73:ad:8f:c4:d9:47:a6:fb:2c:7d:1a:80:2a:55:b3:80:34: + 6f:8e:17:27:93:05:21:40:e9:8f:bf:47:6a:52:f5:2e:b5:18: + d1:8c:1d:83:04:80:55:fd:21:28:dc:7c:be:c8:c1:5f:e4:40: + d3:13:e4:66:bf:ad:92:4e:9b:db:c1:be:a3:42:74:da:c3:2c: + 0a:da:3f:94:14:ad:7e:de:81:c6:01:6a:f7:7a:b4:25:51:b0: + ab:cd:b3:3a:77:bf:c3:6b:04:44:30:73:41:ad:93:49:67:ee: + 43:d1:96:8e:36:83:2b:1b:6c:e7:cc:3e:d6:16:b9:88:4a:ab: + 56:c0:76:00:f6:9a:6a:8a:e3:e0:41:75:9d:3b:47:0f:c9:0a: + 8e:9f:9c:00:92:bb:ae:d8:42:56:35:64:eb:59:13:da:2c:63: + 83:c3:ec:68:91:b5:f3:71:85:48:54:c3:9d:a1:c8:63:f3:de: + 5d:a5:34:a9:1e:85:2c:2c:b5:d8:a9:62:8d:26:1f:b2:9e:a7: + 83:4d:df:69:63:b5:b7:e5:dd:e7:3b:18:e5:b3:77:df:c5:47: + b3:f7:8c:e7:5e:87:2e:46:e3:8f:b1:2b:9b:c6:26:2d:1a:28: + 30:13:10:86:5b:46:87:b1:2d:12:ce:b6:fe:1c:4e:44 +-----BEGIN CERTIFICATE----- +MIIJ9DCCBdygAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MjVaFw0zNjAzMTEyMzI5MjVaMIG4MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSUwIwYDVQQDDBxhZGRjLmFkZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNv +bUBzYW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAKbEqb916kyNO/2KD7CitseoH+QOPkHv1hBId3tOTFnhv23HGHuoAafV0iwh +PtAa2lgD6ELxUw6nkbksued6yd5e7UyTa8zdF9DH0fF8PQ1v311TWrEfo3tbQWUM +fOpT37vaQRXaSeO5Lbu1r++MuIR00BgWjlzkwuehh4/jh4sLu5Aw6ODz68BQX7V/ +VJobNEP9vlqAbg9jorN5QkqFyAfHglUjiNROAy/xlb3tFS0+Fs3/x5sDKTamXcka +HomlumaDD5aoB58kuRuPApq4UCmLvmNF+kXDOCOgmDq0a0KZEzZLhO8niTk0efhn +FnucKgNBFWNG5Nsv8j5t/nwgHp8CSKS8FUKm+DiG3Gt8TmejMYGOtjAa6z0IJRlf +Qtw57HkdMAr7Fo89GRTM9a/XxnXPs5aispvZAwGjyogdcu1v0b9XVo65B5u5BBMe +C1oGaytDotzVt/S6066drf3TinwvhzL6iYhYAK4WK5wdWIJN5SHa1Wz3qECLxwLV +NjDvPwmbptIxo78g1KKeJsS0ww8LbADRLBaxKusG2dWYw83LIGitCiyhLydBXJHe +SWLt2DrvaBxt/pTDKGgyYAhlzQKfl5YvD4cnPbkPhWLoK5q09NPXwZOWJyMpiLE5 +mVM6IKqIRDtKJCqL4LSN3WYw36Zut/whQxaePhIgyHowwT2rAgMBAAGjggH3MIIB +8zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEu +ZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEG +CWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwSQYJYIZIAYb4QgENBDwWOkRv +bWFpbiBDb250cm9sbGVyIENlcnRpZmljYXRlIGFkZGMuYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20wHQYDVR0OBBYEFD28cAx01LiFSR0IhMQbJ/KvcjfTMB8GA1UdIwQY +MBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MEAGA1UdEQQ5MDeCHGFkZGMuYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcD +AgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAJ6Luwp63MCU +M7wYpeZKH/+OIbGPM/A+i2xyVcRHcV/O5zHvW2IEt1ePqCef7WnS7KgN4nYzjUE6 +Z2FcU2DHU+3XmXIpHa7T7sl2HG0YR+mU3S6XP5mvtfShfJL2TbXBegw4utG2GZqf +4gKE1FQBOHtVhkruPYVIAdo0CWlDJX5uBnPguXy1nE6ctVKFMmJiJTn6AktRLt+O +UhcCUPSZKb9+l1OREoWaaWJFWcRbP68Y5nvkhl3xnlorPhRuftRHJO/ZqOzZpsu4 +TxqG2UMgQRYVX4EN/msxU8H2hEzzA2TS5kQ9emB51zdvM97AqLlu/rJ5rLRTkrgK +WSvMazfEb8ZEAvd8xcamb8Kt3ngeSJbM/lkuU8401ujwVkMwMpBv+Ud2q5lj4+ij +84OY6QUr6vn5nWZwxywAwp5XPjFDUFDI26gtIU5vOcK979hHmScNSLJY8b5Fvf7E +olb8BgLcGTOFU+04WQEWvKrF00s3VIMb5cFL3TRr5dg1hpXmn9IihLHiT6cuTeac +69vfQuG0ZuZY0ygQNJfznGtfBSxHLON16290CuzXHTCAVkQSJvZOX/+S9GICNpxi +6zmYU2holfuUaGm4PGYaznjEz8RvIayopvSraSouAF33ZwaxT5dYiFXYbuulmFA2 +IXA9sKT1OyGzHPWp3cZKwom4WrO8HyHOTGhfmNg5cNJ+oJDfraMT6zyT9rj02adR +sw3q7tRXqtvKfIqgCMOYmjq3uipQkibC4xG6EmAkuVnfYqjXTaPL6kboOfmDFKhc +RHVxa3+ZvWhY2WvRzcdFlZ5EHoU1wDArGKrrL5PVvmZdcO0dBPLBHrXsRQwE9p2I +0wwgXlsj3zSh9eq0oUTA2tXqiei1y9z4ku6sjWHtv3QrKHkf9Jr/Y73mqnkdLCZK +siZTV7qIDusZV8AQoB6BKsBWLsMqgb/BWudIzsFquWxBzESmuHDiVw5tQdZh2r+s +ICynKmcjmAC6zouowkVmpwjrfwq155vW9AfVs0PNJ9T6yUCPr7I2HOdEtE7MWitz +rY/E2Uem+yx9GoAqVbOANG+OFyeTBSFA6Y+/R2pS9S61GNGMHYMEgFX9ISjcfL7I +wV/kQNMT5Ga/rZJOm9vBvqNCdNrDLAraP5QUrX7egcYBavd6tCVRsKvNszp3v8Nr +BEQwc0Gtk0ln7kPRlo42gysbbOfMPtYWuYhKq1bAdgD2mmqK4+BBdZ07Rw/JCo6f +nACSu67YQlY1ZOtZE9osY4PD7GiRtfNxhUhUw52hyGPz3l2lNKkehSwstdipYo0m +H7Kep4NN32ljtbfl3ec7GOWzd9/FR7P3jOdehy5G44+xK5vGJi0aKDATEIZbRoex +LRLOtv4cTkQ= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem new file mode 100644 index 0000000..6f11ced --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIpUlK4cdzu/UCAggA +MBQGCCqGSIb3DQMHBAju3WkqK++BQgSCCUit3hNjGErKHafSn7CLnhKlNTzvtaAv +PwTStReWMNULMJ6Z1Rhm0jO8x5BBStEHy3A4h1GmWNSyIzOhZqGi3K2SqpBa9+TP +SSYzeNKCsv/06QeQ3GTJJF2GTKLw8I2tZOJnNy5wYprGDuz92AAncj645C8xBYb/ +RgN1YyHh3B2tkPlOVZZU8z8hH9iaDwKiXfY0+EgVDSCj1pHWKEzGzhx4UtyKhCc5 +1J4fyPA+8SzJ0tRAohLHdrm9KIn/tawbbS6Ce8iwLBad6A4k73WgYW4ZawMA+n1X +OIhyCR/dfIlPRPcojyN4c2O5uPmGCDErt6awUY7LyctZPRAUBbk83i69HbRvK/kq +JuyhTIWUbhVpvt6HZxCC0cFBy7tlSeOL3LXlu1JoWAEqCVm8vHQPs3WTwTTrShHP +kauortTdLstddxqPwWKmUcSLcviK+IfD54y3fJGYMr5goLdXCGfb7XZQoXANIYKP +di/jXOn6PTjKdC7/J8G0UZmRmjEvxp5CBPiNqr07YJUfu7IN4KxEKRf/aDyJ1npw +JEaMFiBvFx0Vr5nm7trQ43TdkuHbn7MY6nkPMbzC8a8KcKFGbnU/n6TIyeGYo2o5 +2ICW3QmXjzhrWiDzU+cEbSEs77UAQJNrSxRVuKKuwLEnuy6/pRhlxex6Hp6nNCOd +dTZKDeqHsntRa6zTuOleh+XOMHeSuHjhJdThxEszHPFsYzH/EtE8TaKiBQE9kecy +M+nbxfMqRTYitsl8wTPiuoTgrzDjUJcAAsS/jDNYUA63NCG2BT9Gq9qY48DwfWGM +YPMYj6CfRwsyAPSeC7hV31olnGAp15kBhM2TpxE6KqUnGuxL0ET9LJsHjaRsP+r1 +KMjNmibQSy948LIvHhEtdfg5/Jn5jv6JHmmSBktma4C+MUfQKBinzy6MM1IAaZlZ +hUdL14VnERFh9OGLjZGBOBlk/9FU2Yf4lfAtLgT95GezlYQIOqpG/Pkm04wH71+W +bfW+53gBQqcaSexM5QFsqRspq7yyLX0mElG6z5gOmEJN3rV+DZ2d+84dxKQ5rX++ ++mLYlfQKe1K/1F8HVXH/1ZMeAkzvxk1Odlm6fhwcTHciX3CSESAtJeLSD3PNgSE1 +f0Lep/CteZecOnM63T454jC4V49qXYgQBD32WuOHIbFhHd/lQ5Zj+3T5LgKlE5H3 +5oTUU/+DFgqFrwHlM5f1Ha9G8rjuHucjHyQ7ix7jNjEIoG82It8ESisIOoOwb3bc +Jjkfj3v7f5Axi0wyD94KLFntBCI64uhyTk+JuvagA2KnLQ5uWEFRgqhMXRNg3kbI +STOAopjoB2bnIvQZxQ8hxOT67EjKd7iJJXh2zfBAQ7dvnVKznvdSamTcB/Uh3IQR +RjOZE3ej3lEb4XCM2NCyqZvFgoU+Og4yg+4yainCE+6Jt1jYNvms2iabxC+ZQZ3t +/vCgVDvnULX5FJvphGK/Idua5FFIeSNLOoK9qjfrBNL9kdFVMWCyMyK0cIdsZFRp +2at32a9n8OU1rRYgFn8kaWK4JQqKelm1qVCixcHLUtI/cyp+t7vvjOGRnDrbfoK0 +ae+pt0De0aBsOMKmUetn3CXFXIyQa/FJ3W8X7yl82ctS3ZZmWcND0Lqhoa1JADdj +vbxxGzh1rJPsuPePwIXAVqtbVJD84i+dP0+i1oR/e5jNgRKj0tJcfZnnsvmSIldY +FvxDpIX2h/tDrTKfwQzFHBBuPA00ZuGfftGc4LD7SOVjVb6CF2GMX/0+zmKlPf56 +FvxvGl+GwLPz/BaSGlT/4DApF0HJEZ1AeSvzHGhdgWecbk4s/lMAnv17vH2YWql1 +uJ54FgDAT0ufzAb0aHAl3YO8pYDOOXGqHaqWRMJvtuh15FB52HYvt+Ojo2mzPu4j +lvUcOBRMzgPl8zcs0L/WgE0SggC6DpXGU+rK1/J91qlNRBJ664R6j0iyskPvdzYN +aJ8ZZSJ+yQPralfSD/Sd+RcRviP2draINoyVbFHSH2zvvhcZc0ETL24tNI/tSXpR +Cw86CajiN7T691pC3eZyQLSQJnMSY/0F0i12KU3J+1kq6eeMSoPc5EKItfH5wxjw +RPnJAU84HGIQEAhEn6Ht1XaZcMfo9xyr9WMpmyH4OoTLt1+gFGgSCfbjsusl9aNl +EDhcYmav8OFHE48qvEoYyHD7S3fwsxKFSCJpYTRweBRQaEzpq1z90tVxzhLZFpJe +A7sw/HpiOuty0hDHQ5JaiRBsQ+CiOsVdWZXzaI/H0aoaPbLbpursuTPPPG5OFqvL +WIIDfFYZ9rhy8t/YaAeTyFoLx1VU7m88ZZndyaVXhnqp7iaU14NXlelPeyKJ3ZXc +pd6gZ4l1XAJHbeyiBx+6khtZb6JTLbYpwfbjTqPmDtNw2PVb5rwF0ZSeP6LXKOEM ++WntayDMbWK67yUCBlkPTpY4k+8nV8pJ+th9sR8LlL7d9rZgbSjmxG8XgjC7HHg+ +4I2O7poGQMVgtMeIsGZRIS0cTpm1dpCRfFQPR0DOB6+wjDRPIRNNiTZQYdkpfHQ1 +QSpCskaWG9HzJQGSu+meN4LdaKEoXwNMMz77fCTWhXXkvy6Ujm44EpOOfaHXpg7T +AQagXzyII0xXj+rAFkqmnyygWgxpou6f3MkoWxIC/qYocC4Ci3oWMAZVssWfnhoP +T/ZormTZN3uQCZYtfwTjbjh5efFQc4I9THxkHV6eyhGE7MQO/D/5zjBzkwmNsU6b +GttZyyHto+oKlXMF9dNKxLkQbtVO8ZDIDuNP+sb/m7wj3GG2MNoklp6Cd7lckimv +PqkQP7PQa8h6EeFXmTKqi7vfgsQAEIzTfOLJDvfHhLC54pjbFPR8vY0T5Y2Dwe8w +rMPwFenW1ae6DjeGDHij3+QbQmTYZeu8Hblhs5DNhy7wtZX05IUsioVfJLC9QngN +Y5u7OuMGQLPdcPjWHBuZsl/lMdii1lOB/PrExrEIsybSGPQonDfK6x1pOeyIJsbr +fDnevcamxLpG6BU8U7AqE1QHa/sJGNO/lgsHGLrb5A2id1J+VttSxSG09sML49uw +T+vmgdVbVjsYRvMSjMfwRrVp4NARlXph5FUA2DxAKXvr1reicAleVgQDcokAHhLi +vGZ34XFIZHB+YZvHxd3tZxLcKvAMZQJTPlO6RdD9cx+84DEfevaJilUjyu6Ga4ty +HjA= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf new file mode 100644 index 0000000..bdd0364 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.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 = addc.addom.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 addc.addom.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=addc.addom.samba.example.com +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:0123456789ABCDEF diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem new file mode 100644 index 0000000..eec21e4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEApsSpv3XqTI07/YoPsKK2x6gf5A4+Qe/WEEh3e05MWeG/bccY +e6gBp9XSLCE+0BraWAPoQvFTDqeRuSy553rJ3l7tTJNrzN0X0MfR8Xw9DW/fXVNa +sR+je1tBZQx86lPfu9pBFdpJ47ktu7Wv74y4hHTQGBaOXOTC56GHj+OHiwu7kDDo +4PPrwFBftX9Umhs0Q/2+WoBuD2Ois3lCSoXIB8eCVSOI1E4DL/GVve0VLT4Wzf/H +mwMpNqZdyRoeiaW6ZoMPlqgHnyS5G48CmrhQKYu+Y0X6RcM4I6CYOrRrQpkTNkuE +7yeJOTR5+GcWe5wqA0EVY0bk2y/yPm3+fCAenwJIpLwVQqb4OIbca3xOZ6MxgY62 +MBrrPQglGV9C3DnseR0wCvsWjz0ZFMz1r9fGdc+zlqKym9kDAaPKiB1y7W/Rv1dW +jrkHm7kEEx4LWgZrK0Oi3NW39LrTrp2t/dOKfC+HMvqJiFgArhYrnB1Ygk3lIdrV +bPeoQIvHAtU2MO8/CZum0jGjvyDUop4mxLTDDwtsANEsFrEq6wbZ1ZjDzcsgaK0K +LKEvJ0Fckd5JYu3YOu9oHG3+lMMoaDJgCGXNAp+Xli8Phyc9uQ+FYugrmrT009fB +k5YnIymIsTmZUzogqohEO0okKovgtI3dZjDfpm63/CFDFp4+EiDIejDBPasCAwEA +AQKCAgAloAU0PyRHdS3tu/JiRbO7RAE98MC3G6dOMStT1IyBUt9foyWw8Gy/Mwyi +DDYhuY09glQqlkvI6KGGB8NBqIBW/U/IkRInPFKdNhf1xbP4jh707VNu1taJhEMy +yyh7rcSym0FH7uHw0NyylwFEqJkQuVIhvSUNbEdU/yqYmhsAkfsVQxOnfSDZWMjf +KAUsZ6rZFCyYOpWaPz58A4WjTp+csbSEBOpgC+HINVc1bIH0nSeD/otIO+RWgh5y +usPdBlkRu8wOj4Z4r05cG13ZDnB3jyG7QBSBHNRTpW3zALWaZvLgsxUg5+ib0W0b +UBbQeKE57rsmlN4ZXa3ny+U4l/6QQDSMtrWPNBCMrkt1Q/52gQk1IGeONUAQdLQT +uBx0Vdn5ZvIFRBnkQl2KWOBWTdD2v0qxIHhXlsWX7tGVU7eh3GIAPoFzQZFHpPhA +RObE8fNg/3HMVGDUwXnd4k+6c1t+Ioa17FuLJE4lr5c55Klq2lJ4Oq2Jd6AfoGjv +anA45ChI6lrg2Kt7OhUEHIIHyZmm7eNmBHoGA3r+YJyiQQIGSiNjH+Up54KWa88z +p+ZY1u3VdOiNuKVlRn79q85Th4HyMlx7wuY+t8HAj42Vt03Uy7iDaaTfuPxehMyS +MqcRWR5MhavR5ShTtsIXwvUgWj/YcqaOb9Zfe2Y1RgFURKN3YQKCAQEA0I1hTnGs +KE5l9dGowKm2io6pZr8J2B8ITjp8pdAaY46Ws1tfcTkbbpBUvyrflCIgLIP9KTP3 +6cc4HrK11mf8rPD1pHNWJd7CjPTLQFMYu+h8YlBqKwrgA8owLzUWG4omS0vehCnG +6OIPi8ceUc2u6XW+TGKP4n8GXJrrKaw9hw83u6h9YQCpgfwF4QpwX8LzTMKnI7te +HxUQFlhKX3vci+dP4n29c6yGl57830E7LeQGRfjo/NAV3pAAcHk79cEzOJQCN1Wy +bNU2kcoOA3tGTI8tCfBdwpN11Sz2/tu4ytJE2weP5S7r9xOTq8t+iKQ9+NLhAvJU +8S2mIkyFAi8tWQKCAQEAzLWsJ3qxyaLHv4tOFTqenSj0CbB25OIzDQNLT++L4fYn +YAqL6/G83bRVbdYvfJ3ZdZdnseluGrR8ZcxdqioLCws66+O1vC8GkHI5aBKZt4MD +Um+SzD6ZnARYcTbtRmPUJHxIdny2dbYLe5dDlqTFIV+olWDR+1YMSzXt/VW+jx9I +tHhw8LJAxhMhDt0Gh+CxNFHQYdkdK/OuNTBufT/rxeT3E5t3TbSG29pU/F2Rce1G +CCy0nbFsTMjPusSzwFJILWHdvBAYJceOajvqZhlaTV11u/qrj9gb+nJkH+rKvJnA +pK2YyFWqomnGCZB61Y5LOfjk2b1BfVGCdqpRrBCOowKCAQBun3/NB1jlbGiDEvor +cBpmtrO+z3jeTd+u9zElFxTYWEsxyjb/LOaTKDX7zTcZMVzVoBGKaImJVOY8yljP +6QrLhWkXGSLKJbYW5MZnUWyeR/yqfbNDL5qSCA61C7i1VPtpF05p1msvHrJWV4GK +rMqqBY2yoNlnsC9ksbwpt7ZPTNAoV4BiEuLXEyLfMxVWhmdeASZ9Oqb7X8XPxHd2 +3JGpGEJ0hnQWxp4CERBbMBO/DOQS+6xCZfIjw0ioYHZgrmGIEmJ2jZt+RT6T6JS0 +XhB1DcE7M2fYjTWEpTxDBbOoyg5CDGnUjKYXwiejieaNfmls8hbu5DIQWEF2khY/ +iVzJAoIBAENOiGgCo2oUp3CHMQkx2Oz7hiGZb74Z0Yc5yg1iSa/l61Rco1zUgrCy +llQi1EI49EMBoQqSIa2OIkimRTWp1S+wZZMhr6NMIvBjXhSl6Py5iuIT5URaYM83 +bozq7mDyedH1Oy4aGzPgwy3DsmlZi6dJeHiE+QWWaTxhYvqksp8EPjd4UkoRkdKO +f5QPgBI1Ao6dR9KkPD8zQ9ghMHLmDXNnsQU1XKij7qNiygagDS5UQW52pHwk1eL5 +M7PI8QEPDMQ/JVSsRgRF9MFhKdSgCVzemdNQvA/zkl9qNRl5bWdNdlWu7kkQQaZc ++Mw0QO7udjV9bGFbJKk7n5W8slXMq9kCggEAJ2yzyZKdQZtuXpf6WN6sNqRJ6CHo +k9en+acEg9Y+5lVt2CRblprQxhdUV2KyN7G8GxV0hMwmHtMTeB4j6jhdZrAAZGVW +upqCfY2vSYQ/svCeB0Fs5DMEI4iCS5Drn8gKKi/zWAbox9sb+zaYT/Ot5p2Ki/HH +YIh+p8EE6IFWE3jChabPQieXVOC7tg/qaxWVHTv7Qe2fdZTY3XifTcN7hVghf/bH +Vn+VdU2u/7hE7X3y9YNETNSin5U3F0BSm1tUQimUzU50+9Nl2UGPBI39e+15qRz7 +JHocpq9h9+k3T7qWwJxX74YhcTqdb1pGsKUEmo7r6rPR4L5h5nCF3OgR9g== +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem new file mode 100644 index 0000000..5b356fa --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFEjCCAvoCAQAwgcwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +GzAZBgNVBAsMEkRvbWFpbiBDb250cm9sbGVyczElMCMGA1UEAwwcYWRkYy5hZGRv +bS5zYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Etc2FtYmEuZXhh +bXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCmxKm/depMjTv9ig+worbHqB/kDj5B79YQSHd7TkxZ4b9txxh7 +qAGn1dIsIT7QGtpYA+hC8VMOp5G5LLnnesneXu1Mk2vM3RfQx9HxfD0Nb99dU1qx +H6N7W0FlDHzqU9+72kEV2knjuS27ta/vjLiEdNAYFo5c5MLnoYeP44eLC7uQMOjg +8+vAUF+1f1SaGzRD/b5agG4PY6KzeUJKhcgHx4JVI4jUTgMv8ZW97RUtPhbN/8eb +Ayk2pl3JGh6Jpbpmgw+WqAefJLkbjwKauFApi75jRfpFwzgjoJg6tGtCmRM2S4Tv +J4k5NHn4ZxZ7nCoDQRVjRuTbL/I+bf58IB6fAkikvBVCpvg4htxrfE5nozGBjrYw +Gus9CCUZX0LcOex5HTAK+xaPPRkUzPWv18Z1z7OWorKb2QMBo8qIHXLtb9G/V1aO +uQebuQQTHgtaBmsrQ6Lc1bf0utOuna3904p8L4cy+omIWACuFiucHViCTeUh2tVs +96hAi8cC1TYw7z8Jm6bSMaO/INSinibEtMMPC2wA0SwWsSrrBtnVmMPNyyBorQos +oS8nQVyR3kli7dg672gcbf6UwyhoMmAIZc0Cn5eWLw+HJz25D4Vi6CuatPTT18GT +licjKYixOZlTOiCqiEQ7SiQqi+C0jd1mMN+mbrf8IUMWnj4SIMh6MME9qwIDAQAB +oAAwDQYJKoZIhvcNAQELBQADggIBADLgdZz1gvzpnZPwd5KCxjwKgiotlUGBh6t6 +cLhyomCN02adMr0PPJP/n3r1Zsaq2db/zktP8J5fUYqA9vJZzYukzkKRHbl+rdHS +JVEvHmbsG3729V9cy40kuL0EAM0weBbfQZaeFxfcLxl5v14QOxvldrmYSK5GaLh8 +WSEz4uljrI8ee3q8Cn08xlZ2Dr3MoHI9unEcLJFXkpCwVBALFhw5dG8od3jl8AyS +WeMVbdD9fm4jnHE/RDSPDqUqMCGIYmrB5amGO5rSLDTWxDxrcHFRM7sa359nW2IA +GoZd+r8Vf2AZ8i/KRgH7uIFB2BJm4L0QiVlajy3odW3zhQIVXNh9p58aGzOFQGkq +Gsld4WI3gZZeSvGgGIjoB2+AYRjxTzUn5qSFVev5sFLK3cNdPZo66xltuPBhfXB/ +v/+/TQC80oZ8oZGdgYvBBT1IEg4pwB5Myqeps9J7kbJVmtxR2EGlq/aGN0yE/fy9 +S8ners0iXBJP18suSwbjj2unZQMBYLIgHLkzztxAMGYBlfEljSAvDfFCsK5Rkmya +soxd1qHHMG8Ap+WZagpkK9tv42HwmbYKVeDArGAHr53aC4ripgrSBnzpmkiSyi4p +mb3L5K/ZSOxo3xrS0wERq3p6FalF8/AhctgzWOgMvikVoTUy0xPsG/hulXPyk2UG +rYn+WPQz +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem new file mode 120000 index 0000000..43b4b51 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem @@ -0,0 +1 @@ +DC-addc.addom.samba.example.com-S02-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem new file mode 120000 index 0000000..3170fe7 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +DC-addc.addom.samba.example.com-S02-private-key.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-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..7b1b6a1 --- /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 16 23:28:44 2016 GMT + Not After : Mar 11 23:28:44 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:a4:76:ce:e8:63:fe:57:f9:a3:ae:e0:ad:4d: + e2:15:8e:d8:27:c8:7d:7f:2b:b1:e8:aa:50:8f:94: + f9:c7:71:3f:52:32:91:d1:6d:52:22:5f:cd:8d:cc: + 62:16:7a:8b:58:65:ed:07:f7:ea:24:d3:88:d8:26: + ca:eb:ec:16:a7:84:1c:7e:15:46:64:09:22:46:b9: + dd:5c:07:84:50:a7:4e:31:3f:01:23:d1:f8:36:04: + 1a:bb:d4:e5:b6:d4:1b:5c:16:c9:9e:37:8a:3e:a9: + 7d:30:24:40:b2:b5:44:40:fa:5c:6f:d5:3e:ff:32: + c2:e7:24:0a:e4:e4:aa:9f:ff:4c:ac:be:37:58:22: + 08:16:0e:f6:a7:2f:b5:6c:4f:ac:7b:a4:82:a8:9f: + 38:64:17:6e:72:b6:7c:4c:c5:44:2a:0a:b4:25:0d: + b0:0c:ab:98:4a:f9:1a:1a:c9:a6:59:f4:00:a5:0a: + 6f:0a:d0:a5:34:ca:0f:f4:0e:fb:ba:d7:bb:3e:2c: + 7c:0c:68:6b:26:ff:1c:29:fe:77:f9:30:85:0d:44: + 8c:af:90:8a:70:93:5d:3a:b6:18:8b:a5:85:11:5c: + a3:5d:57:16:dd:c7:c8:00:f1:05:71:c2:6e:07:3c: + 37:69:36:7c:12:c5:9e:1b:69:11:45:44:1e:eb:b9: + b2:96:b1:89:cd:4d:fa:89:eb:92:49:f2:46:35:f3: + 9d:87:3c:be:e4:f8:b7:31:a7:36:4b:81:76:9b:b2: + 04:d5:80:7d:4f:e6:02:ed:24:4c:a0:03:c4:9d:00: + 9f:9d:71:93:0d:a5:b8:37:62:2b:03:c3:bd:24:25: + 2c:c3:43:d4:c8:27:b0:6d:05:d4:c6:c5:d8:5b:09: + 94:e8:27:6b:d9:6d:b7:bc:de:76:bf:d5:9c:36:26: + 04:b9:97:1d:f0:c9:8d:91:93:82:32:0d:b7:16:97: + 41:31:9a:22:0b:2e:ba:99:51:28:6b:f5:04:ba:c9: + 3d:57:0c:72:e8:e1:24:1a:d4:2a:6a:e7:e3:b6:b9: + 94:61:e3:4e:42:81:e5:43:e4:1e:ef:6d:c4:5d:a4: + f9:b4:ec:3a:8a:34:fe:b5:c7:a8:fe:19:8d:cf:7d: + 1b:60:21:ba:25:6f:35:cd:4f:72:28:42:7d:87:08: + aa:da:33:7e:63:e6:5b:5f:e7:01:a8:e3:0b:d3:08: + 5a:a6:df:ea:e7:2b:13:48:a7:83:32:96:c4:ba:d1: + ff:15:66:52:33:86:46:5f:c2:9f:59:4a:00:98:b7: + 1b:a1:87:25:df:ad:68:5b:f7:26:17:2b:eb:84:62: + 9d:c3:bd:99:67:6a:02:5d:70:72:3e:18:92:99:8c: + bd:d9:4f + 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: + E1:DF:73:0B:F1:3E:86:43:A4:B3:E9:8D:44:7D:3C:B2:19:C1:BC:F2 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + 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 + 89:2c:57:98:17:c1:73:a6:10:02:6f:a6:ac:47:1c:37:2d:1d: + a1:3c:c5:29:b6:3a:e6:e8:14:ec:3b:74:ee:da:db:2d:97:3e: + d3:8c:9d:42:7e:b0:46:e9:54:74:4f:34:df:9e:34:7f:9e:8a: + 9d:4d:b2:cf:fb:71:3f:cb:32:e6:45:e7:b4:d3:9e:e8:ca:a5: + cf:16:7b:76:b5:4e:e0:b9:bb:79:b1:82:a7:d3:23:cb:3c:46: + 63:63:96:b3:5b:62:9e:99:dc:02:17:f9:07:63:86:76:06:1a: + 02:1b:9a:df:1d:cd:e7:46:fe:9a:13:87:47:dd:e2:77:58:50: + a2:6c:c9:a0:f8:14:1f:3b:d7:59:9c:89:bd:2e:2d:ce:60:f4: + c6:2c:e3:63:cf:34:84:61:d9:90:2e:90:fc:5b:4f:a2:00:87: + e7:40:e0:fc:d1:24:8b:d0:28:01:d3:53:ac:b1:58:7f:87:29: + 38:56:93:dd:a2:14:4a:9a:94:b9:f8:94:b2:04:47:db:b8:38: + e6:85:2b:cf:d4:72:88:8b:0d:8e:a0:69:f9:9f:10:22:82:9c: + c5:ec:01:e3:07:a1:69:37:94:25:3a:cd:17:29:37:8d:24:d3: + 27:0f:4d:bf:b0:31:36:b8:c6:a8:69:0b:df:28:f8:e2:dc:da: + 95:3e:7f:d7:3f:a5:8f:92:6a:7d:ad:3a:ac:af:73:2b:5f:f1: + b3:22:92:ef:da:71:84:9e:4b:23:7b:69:b7:29:fc:c5:05:84: + 4b:ff:06:92:ee:f5:9b:14:2a:af:be:ef:02:e1:e7:d0:e8:d0: + 29:7c:48:40:f1:95:bb:08:b2:30:c5:81:80:a8:91:5b:2e:08: + 3b:30:44:07:b5:c4:0b:07:74:ca:5d:37:3d:75:f9:bc:6d:21: + a6:e0:91:d8:f9:27:88:05:58:a7:f4:36:eb:ba:40:63:36:15: + 42:98:0b:e2:d1:c9:11:0b:29:81:e1:c7:02:7e:fa:05:65:51: + 7b:d6:1a:33:46:fc:a5:d4:fd:64:e8:c8:11:d4:d1:41:d9:39: + 18:08:a3:ed:15:70:d9:14:f5:ba:c9:bb:3e:96:8d:5d:cc:c3: + 5c:b6:c8:79:02:2e:e2:a1:06:ba:a5:21:1c:bf:16:7f:2d:d9: + 93:07:92:b1:fa:ee:3f:e3:56:35:f3:30:aa:11:54:d3:71:cb: + 29:d4:60:e1:6c:ae:c4:24:e3:00:4f:5f:52:b0:3f:f4:76:f3: + 6d:db:bc:d8:65:c4:37:be:1a:87:9b:65:c4:20:dd:da:a9:4c: + 9f:86:33:2b:49:a6:f7:aa:ce:da:98:3b:e3:5f:ac:b8:1b:45: + 0e:56:59:fb:49:38:0f:b7:d4:49:f8:7b:ac:fa:d8:b8:1d:16: + db:b2:4c:15:d8:e7:eb:6b:38:ff:d2:69:26:a6:f6:50:15:45: + 2f:12:b2:05:d4:bf:6f:53:79:64:9b:d5:8b:a1:08:3e:43:ee: + 08:fe:9b:ea:83:89:8a:6a:53:98:1e:c5:91:4c:7a:99:2b:6d: + 97:dc:96:1b:de:27:c5:af:0f:dd:42:5c:23:7d:bc:6b:5b:ab: + 47:29:98:35:8f:9e:e6:e1:5f:96:6a:bd:cf:3c:47:89:8b:ad: + 21:de:20:da:99:82:c1:0e:9b:7c:38:21:d8:b1:1c:34:c5:4e: + f7:fe:7d:5e:a4:2f:f8:7d:5c:30:2c:9e:e6:5a:4f:d3:15:90: + e6:6f:69:ea:51:93:8f:2c:dd:a7:c3:3c:50:a8:d1:ba:0b:5c: + cc:2e:4e:57:71:21:08:a1:2c:bd:a7:20:4b:ae:5c:02:7a:cd: + 9a:fe:1e:db:ec:ce:3b:12:37:cb:96:20:7b:3b:b1:5a:2e:84: + 03:f9:0b:32:43:c0:4e:e3:ea:79:e7:9a:13:54:e5:a8:1a:17: + c4:79:78:25:63:ab:67:39:39:a0:6c:c4:c5:94:ac:16:92:3d: + f0:1a:1a:9e:ca:7a:84:1b:c1:5a:5f:4c:65:8a:30:a6:5e:6c: + 0e:ae:bf:ac:09:97:0f:83:5c:92:ce:e4:43:de:06:4b:96:f5: + 46:3b:7d:a8:e3:0f:d3:fe:00:c7:d4:79:4e:5f:bd:ec:59:12: + f9:65:23:fa:e7:97:a2:a6:39:3b:a3:1e:da:47:c5:18:5b:8d: + a7:7b:29:1c:5a:7a:06:c6:92:9e:b7:3b:f0:c5:56:e8:cf:84: + cd:dd:61:0f:21:25:f4:1e:2b:40:b6:74:28:8d:41:f6:2c:1d: + ce:b4:39:d1:e1:be:15:78:c9:d7:99:a1:9d:50:43:da:ec:40: + 69:6a:3b:17:af:28:22:09:e0:7d:38:9e:a7:ca:b7:f7:94:8a: + 2a:1b:32:4e:28:6d:18:95:ca:42:67:c8:bb:13:24:31:43:84: + 3e:95:66:08:5c:15:7f:6b:93:cc:8f:b8:76:7a:fd:74:4a:d6: + 6f:64:74:df:72:f7:34:a3:50:f0:db:bf:0a:2b:1b:48:b7:c9: + c0:97:23:27:b1:56:5b:9e:10:12:5a:bf:ff:38:61:da:41:75: + 15:c5:03:c2:20:fd:7f:84:c0:94:8e:11:ed:01:ba:f1:19:b5: + 05:1d:bf:89:ea:c9:38:4e:d2:cf:5b:24:c6:37:a1:8e:60:89: + 5c:52:ff:7d:5e:2d:c9:f8:b1:79:07:4c:2f:18:85:e8:ba:bf: + 3e:da:59:43:df:29:79:7e:00:38:d2:fc:a9:8e:3b:9d +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI4NDRaFw0zNjAzMTEyMzI4NDRaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOakds7oY/5X+aOu4K1N4hWO2CfIfX8rseiqUI+U+cdxP1IykdFtUiJfzY3MYhZ6 +i1hl7Qf36iTTiNgmyuvsFqeEHH4VRmQJIka53VwHhFCnTjE/ASPR+DYEGrvU5bbU +G1wWyZ43ij6pfTAkQLK1RED6XG/VPv8ywuckCuTkqp//TKy+N1giCBYO9qcvtWxP +rHukgqifOGQXbnK2fEzFRCoKtCUNsAyrmEr5GhrJpln0AKUKbwrQpTTKD/QO+7rX +uz4sfAxoayb/HCn+d/kwhQ1EjK+QinCTXTq2GIulhRFco11XFt3HyADxBXHCbgc8 +N2k2fBLFnhtpEUVEHuu5spaxic1N+onrkknyRjXznYc8vuT4tzGnNkuBdpuyBNWA +fU/mAu0kTKADxJ0An51xkw2luDdiKwPDvSQlLMND1MgnsG0F1MbF2FsJlOgna9lt +t7zedr/VnDYmBLmXHfDJjZGTgjINtxaXQTGaIgsuuplRKGv1BLrJPVcMcujhJBrU +Kmrn47a5lGHjTkKB5UPkHu9txF2k+bTsOoo0/rXHqP4Zjc99G2AhuiVvNc1PcihC +fYcIqtozfmPmW1/nAajjC9MIWqbf6ucrE0ingzKWxLrR/xVmUjOGRl/Cn1lKAJi3 +G6GHJd+taFv3Jhcr64RincO9mWdqAl1wcj4YkpmMvdlPAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFOHfcwvxPoZDpLPpjUR9PLIZwbzyMB8GA1UdIwQYMBaAFKI+ +Aiqjp005tAhNmcwMdTbqJ8M+MD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAIksV5gXwXOmEAJvpqxHHDct +HaE8xSm2OuboFOw7dO7a2y2XPtOMnUJ+sEbpVHRPNN+eNH+eip1Nss/7cT/LMuZF +57TTnujKpc8We3a1TuC5u3mxgqfTI8s8RmNjlrNbYp6Z3AIX+QdjhnYGGgIbmt8d +zedG/poTh0fd4ndYUKJsyaD4FB8711mcib0uLc5g9MYs42PPNIRh2ZAukPxbT6IA +h+dA4PzRJIvQKAHTU6yxWH+HKThWk92iFEqalLn4lLIER9u4OOaFK8/UcoiLDY6g +afmfECKCnMXsAeMHoWk3lCU6zRcpN40k0ycPTb+wMTa4xqhpC98o+OLc2pU+f9c/ +pY+San2tOqyvcytf8bMiku/acYSeSyN7abcp/MUFhEv/BpLu9ZsUKq++7wLh59Do +0Cl8SEDxlbsIsjDFgYCokVsuCDswRAe1xAsHdMpdNz11+bxtIabgkdj5J4gFWKf0 +Nuu6QGM2FUKYC+LRyRELKYHhxwJ++gVlUXvWGjNG/KXU/WToyBHU0UHZORgIo+0V +cNkU9brJuz6WjV3Mw1y2yHkCLuKhBrqlIRy/Fn8t2ZMHkrH67j/jVjXzMKoRVNNx +yynUYOFsrsQk4wBPX1KwP/R2823bvNhlxDe+GoebZcQg3dqpTJ+GMytJpveqztqY +O+NfrLgbRQ5WWftJOA+31En4e6z62LgdFtuyTBXY5+trOP/SaSam9lAVRS8SsgXU +v29TeWSb1YuhCD5D7gj+m+qDiYpqU5gexZFMepkrbZfclhveJ8WvD91CXCN9vGtb +q0cpmDWPnubhX5Zqvc88R4mLrSHeINqZgsEOm3w4IdixHDTFTvf+fV6kL/h9XDAs +nuZaT9MVkOZvaepRk48s3afDPFCo0boLXMwuTldxIQihLL2nIEuuXAJ6zZr+Htvs +zjsSN8uWIHs7sVouhAP5CzJDwE7j6nnnmhNU5agaF8R5eCVjq2c5OaBsxMWUrBaS +PfAaGp7KeoQbwVpfTGWKMKZebA6uv6wJlw+DXJLO5EPeBkuW9UY7fajjD9P+AMfU +eU5fvexZEvllI/rnl6KmOTujHtpHxRhbjad7KRxaegbGkp63O/DFVujPhM3dYQ8h +JfQeK0C2dCiNQfYsHc60OdHhvhV4ydeZoZ1QQ9rsQGlqOxevKCIJ4H04nqfKt/eU +iiobMk4obRiVykJnyLsTJDFDhD6VZghcFX9rk8yPuHZ6/XRK1m9kdN9y9zSjUPDb +vworG0i3ycCXIyexVlueEBJav/84YdpBdRXFA8Ig/X+EwJSOEe0BuvEZtQUdv4nq +yThO0s9bJMY3oY5giVxS/31eLcn4sXkHTC8Yhei6vz7aWUPfKXl+ADjS/KmOO50= +-----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..3443a501 --- /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----- +MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIc8U9D3UAcEQCAggA +MBQGCCqGSIb3DQMHBAiv8rBzGS//TQSCCUieV5YQyWsn3FFhKYI425pOXfnTsSUb +VEe7wO2H7D/S0RFfT5gILYv57TTH8Z9uAeX/wU5msKA4PZt16aMutNl2NWell8hy +IX5R4n6IzSP6IobZKsyFR5u/h683Eli1pBd4BbLJuYu94sxelB4HQdRp0QJIvIvO +TWqTyD7UmqqG/IVhTMQpzcepY/S4SGI6GODJtDLPRgv3x5/Z0/NsxiMKrXMi7HKc +Rzg8jm2mausukN+sSyPcvlEufQjRJgJXtCIX98FMLp0pkOq1rsVUSNg8Qza6tbyE +XhweHWbV9YZCVfmnhUalLt7CIoA7QeOQZbwTNpTo/4mSEA7lv1knvFSdMc9JvR6J +bZQOk5rPzuX2W84UQ3CkIwaRB2iFUv0gJy5Z2xbhWgAR5KZIhGTKupHBYOmD29QU +whgjXq4McdYWKquxELzSW5jXVPNwvREhEuKR1mt6g0NqXCbCeQHw7DWH1OGPz7jM +HXsCGVWpXqeWvRHhdF+NRfHa41hqGS3Onq29UJtgcMpNYpGQYY6Exq6hVVsmddwt +QU4COPfozJzeAlkUEem5AKnuh1JUxo/RieNP99sv1/8g8icc+oPXOIu/6HI3JGYB +4WTVBp1OccEcNlnUYhxcL3ODYXcLUhiLZh2DS+IDLS3Pbp0v1qz/JuzDxiYBnEYt +4Q5NWdhPF/TSS7wQHRl35LAyHHhBIu1kuDhnXjdq87h7ioNiffZ0DgSW4HFUzslk +4UZGFTKaDpepBfIp1qnYGPKCMv+MLaMWU3LOfVGT3ecntkMxUtntNMZ6qGaXhzda +65LD9xYJUrbo+qQSBiTNAhMOy6lHlwIulmML0j1YEcVc2EwgqdfbBeT9v9gh6If4 +85ba1Wvy4W/FN/xo/ECflLAvozjyYND8LMcZ73eJs4ncZkMZAkjfP3sg/qvTAtbf +D6c+SRQbxRJv0ZUb9NN7wx4flsyypscKNqk78mytUN7gGf2xJIOvMS/zH/Zf9EpD +bEY+lOY2llYtXhoEj95tnRPFhKaQeGZdkISsmoU5olLsw/tRkquGdAokh+fl+NtZ +WxgJF8Ft8NT4iXhEBRfgFO5ubGq565c66ayA6R6K00pg/IvS8OXPuxT+/e8EKqUO +R9RyWR5n+W8hWw5+pQWGNvwhLFLJFfCxHw2ucSyNCvtcb6ijV5yvi4cI+UuVnh3s +WW3mMaMOYIcbh/thp8wBs/dpAOGUWX7XBfaGsQ0D+ff0ufcUobhXVZgtC0LhgfrN +ZeHQF4bUXycyaAGWvstNb6Xj2QFVDG98eNDGmYDTD+0XwpPc/6/Ge4BLPAVcBpQw +DMCKUqSkPPWCqfipbQmpBxswhYmzx+DjdfRxHExWeGk1pwyfH4GBhO5fkcpYVtU+ +RyruFu0YNnQ+2Y4eg8+3IyJndxkUHmwsB1DB0P8XvJ0n/NnAnZ0sIpE0x3dOFhb+ +SK0dj8fo2aEHOimrTHc2EJ2ZscpSCVNQ1BsScM36FCWxRWbTr8rBFsdUJ5CMZ2hN +qHBtf38SgNkD3qBUmiPetsYt6qTKY9Rv25D4zL5IR2ZnV99oW6MTDhc49cxYn8Dy +MKlyzV3upykqGBMSKBKbafDI3sO8gB3upUetnogi1TMaNyu4qNzq8oNRfdf+RD1R +Rg4++U14UbYNvWRQnCqjJGUXDnVc8Gp9K8Z6p5eXihsFfpol1OGu0td1e0FRi3AH +INW9UEpfRbmbEPHhYQRNAyRlcQXJ1FBnxUCk6qgfkD0ziJk2VD4oFoaSlqy7l21z +zoH0Vp6PZGZEIs/mAODvtH5jsTEMUE8uuRmPqgnFqbi/gfQ5FJLR6dfCb8MJ2iJM +Hw4791wi7tS1aCYoHneDtxNFeWuuEmw1uMoA+C5euGNv86XAH5AV2OrTIt8SLFPN +mLBLQ3J9Kkitsy1JFz9IdJ5uY3K2CvpOaP+sx3l1Q4YVuSza8r7zRfTC1wPfbsvk +64zZQzA57WvRvpaZU49HbMV9/zDOlQfLtL7TdAbqLYjlVRpO5pHHEqLRR9eGQ2UY +zhfMFfcJahH4lDbgHf6EVjHnEuoW9fU8hLRVzUcQCVDsf36Et+g5G1JMhFnlVzdv +MaKiN9tzKeIqxUSlXMHYm+oIb849pshNo+KRzZ0K+r+wExnpIfCfVOjAvSQU+6y9 +1uIIQlJfk6uPFVriaooyUDrW9/83AgzJDrkpSMTnVmo/MTS8cAe8Ox5cr+mHqJko +cnHzBNI9Q0z59SpJdXucPVyk5MYPUdfyI2ouicm+nKidNvlp36O7UHMw0pJdeqDg +03vhaVif5uN8FNjBLp6xIipX6lor6XCOnkGR/zkis602sTAkE4nemOw9zy3rIBr+ +hYnSY7vMFCVYIERjqSOLE0k0d5RyOsGjSYr8yQMvpTGusla34qVPjrrpJ+OuczK/ +6KJeHV+WUw42g8JSs67j8YJ2ejc9gr9AVSRiES99QL+tlFnOTY28N40OjXqFJjYK +A0x0By1O6h4PMKtYchTuJAoEOB2KOP1Ta+NlL80zM4nWwv7NdO0AR/ATfUfix1GS +NiMC10C7eurYdAfxly3p9NgjQq+vaKsnSy0TbXPCgW8YTegnxKTUWJm+BEiYaE4M +A0c1CySusV+JO1catlXSeCB6ajddi/SKXsW26lJ3Q+8QqhA3EMivCE3Zh2Q5c1yp +gCV7IXtdryPdK16qmirO9LKkm6sCfBdhgBgi+IcyUhqxwHCwxrPqzEs75Sa3U/6k +kV3AqFwhHYtUj2fBNlfJ1efV8fW+WLboJkHbi2LXmL4NBvHTNjK3NprffFrQ/QJU +oYsMQdeWQZD+3p8w1fPb0sXEDL6LQgjAjyDaqOiX8XrQ8nr3n4FpTI38/OIIfS69 +IHtgo5yv0CMfN+C6LAHOE0aDHRoY6+TVVgr1Z/X2VqJQJONii0dQ5ttDHYnUpzu0 +vWsdvVjsyhkLa2yhUB7UyWusZo0HZRSAcf1pNlpp5rCtJad9to7OvOL3qb5GluAK +/5eZE6RzgyGOjtOx0IgQ+l4ThQCTbkoVEtB59IEeP/+Sq2RmFfdGiGgC3Wnrga8b +gkuXXbjZboptSku6N1ZO1r99wd0qIHzrtVCONGLGfVBy7X6nDO2pC9IUOXycMji7 +B5J0toyDWt6UzlLQasmz8Be7NZJCkDd2jlSKorZtdynsXbRkX1H4by9kI8kEcgK7 +ICE= +-----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..546b292 --- /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----- +MIIJJwIBAAKCAgEA5qR2zuhj/lf5o67grU3iFY7YJ8h9fyux6KpQj5T5x3E/UjKR +0W1SIl/NjcxiFnqLWGXtB/fqJNOI2CbK6+wWp4QcfhVGZAkiRrndXAeEUKdOMT8B +I9H4NgQau9TlttQbXBbJnjeKPql9MCRAsrVEQPpcb9U+/zLC5yQK5OSqn/9MrL43 +WCIIFg72py+1bE+se6SCqJ84ZBducrZ8TMVEKgq0JQ2wDKuYSvkaGsmmWfQApQpv +CtClNMoP9A77ute7Pix8DGhrJv8cKf53+TCFDUSMr5CKcJNdOrYYi6WFEVyjXVcW +3cfIAPEFccJuBzw3aTZ8EsWeG2kRRUQe67mylrGJzU36ieuSSfJGNfOdhzy+5Pi3 +Mac2S4F2m7IE1YB9T+YC7SRMoAPEnQCfnXGTDaW4N2IrA8O9JCUsw0PUyCewbQXU +xsXYWwmU6Cdr2W23vN52v9WcNiYEuZcd8MmNkZOCMg23FpdBMZoiCy66mVEoa/UE +usk9Vwxy6OEkGtQqaufjtrmUYeNOQoHlQ+Qe723EXaT5tOw6ijT+tceo/hmNz30b +YCG6JW81zU9yKEJ9hwiq2jN+Y+ZbX+cBqOML0whapt/q5ysTSKeDMpbEutH/FWZS +M4ZGX8KfWUoAmLcboYcl361oW/cmFyvrhGKdw72ZZ2oCXXByPhiSmYy92U8CAwEA +AQKCAgBqVMxJW64t5lU69zax70QZ+D8DKFVjObvNridx6pa1MiqlNJcxXBsPqedU +RjO6dUikumjq0Yrq63MdY9UNq0xOcoPIRPqsx+E7hhjdgsGnhVpxLcDSyMyL6pyA +mAhHn8X1ULQm8ygS94S1myEQwqzy3/mZvVBLyxU8BsvW9u0K0mKBCTjustHTiZaB +QWd8xcaZQiDSqIUQ8BSFYkgwBIoGb+TZaFQPo1SUy/8S9oBw3CMn84V6EPL5QWbV +d8rqOuciJNQTzFgKJHbRjXW2Nn5Avae2kQaiG+5RUP5D801D0denAq2SFbbJaFTA +O4kKYOKS6QGOjfj0Xh4ONveiaXxBSPpIJSvbjAV+Nq92NVkZ35jiPqGZzebhzzoD +mU6mMvRoL/FHs9PKNZF1Cd4EP1SdLhiImj+1eajfYvHAlz6kIJxTue0BFkh13uwp +amx48wB7e/W8t8lqixICf1HlCv+EQGN6aka5dHMqJobXhkt9npz53+AYdpc8Sjs9 +QlFplYoOgkaHvzLv9yeZPOT5Xr32weE6KpM+SwvpVxfttbkvqrWoOoEcDARuVqiS +TRzS/ZDiEn+Kcgm7pJ3i2nTAIBzwC4z91HJbeVXNpptkZJEgjXM8XjSArHjDrkl1 +EGKARlkTn576XMGWSkF/bmEBiG0KIhTu+DmwsQvR+564tjV98QKCAQEA+aS7ygjL +aRj5JZKMt3VWZRntK20m04iY0wGDNs+p+nFRJjCDAUhTTOl9++vlJYe8HO9iXzUv +O51tGnzrck9+gUVlFghrw0dJ+mY0+1bSt2aLNUmlfvv1uRpm9Pd3xbQ6e3Kpf/r1 +ew6IpG8I6pvpVJXJ3FQZpSOlTP9dyRxMNzdILGzzPrb+2r0j6Oc/y3+adBiXB3Yg +QPfFJRJZA4k2Wk/qSi9NR/yWHaY0krO68l8l2zn1AKaIoVVqtxVTQ7qUBWNXzVMe +ULtAvO1Bonh+C+zYcNJjSBeYWeJ7pbp/ozDe6M2DuJMv4aW6oV6tGcMF9NOd1pFx +qiC8vIVPZ3rJ9QKCAQEA7IPf9CAaDUScu2/Ry9z1RaISU4BMi/30poc80Zy2hC18 +vP8aiHVlQdkdzdKYGweaYNQpszGeBcHK51y6V11vwCNQRrCoUp9VbICp7ok2O4y8 +w9r+q4GcYthHeMhEnHDo4R/uHKEJCYS012RLlLSXMa0Dfl1sOv8mVuIEaZoRJrAq +Xzxz9KX7MFv5Zb8TvVL6fHEXmdMmmoiZnyNplH+3LMj6duoNaxjtsoixCkuRTXE7 +Cav118q+QWae+yhIonF+HRIa/G0doqHa+P9rl18FUnxfAf91Z70SSJ2oOtuWjd1J +37eG4d7skpAoWWdXNpCqpJnsPLlSlBqKmYrN5CM3swKCAQBAfV/Np0v00HC8Vgln +8zXoVDRCfaYEC0t/ZuqgpDDC87cE6I9PK4HpYoAbLis58MCVsPl2ouSav+ZJa2/f +Tc3eUzDz6iT8g1QHDZQuQZWZrzHTCD1qemhV8w4Zxjv4pMBe15YV65yyt2RxJgXl +pXU3VqKY+ljNolG3fFib9WVy9iL85wBHeTqJA0ddiS+fwE0EJL4PPWLDpb4V/5Fj +KnUSC4b4txN9vzCAZEk8hJWMuyuqYGR8UIkHNGum9ClYW8CVS76I2ioArP7iT2Af +OoVFS1/2dUMUgpPm1G0guPb0D1HmTgDzE4LRBeEagryw5QKK5oflwBje3ColgUKr +9rppAoIBAH9t9gXkHeU0KHXco16BaCziS5ltsNBkPaJTjvMoyjWhBGoX0EXhanL1 +9dblNkqp6AVviiAgBZH4fcf17/gOQZ116VSM7cPGURIqqGP6zZt8EmA756akKIwh +FzD+Rek79F0HBRWrteDI/V5njUlLm4KKQy2cTCnlOtTo5ZO4DLGZjNrPCXKw0wuV +ImQtdQc2Y/sUO7EHUO9F1e8l90apIRoiFsBnDl+7iKX+e9SeLmVZMoPdgJGJjMRT +9ChB5hCPsXEcRinm6GataftqMp/V9Foi5FWBO9JuziENwIwlr5Izvg+pJCUiJLg6 +r2KsCRM/EpGo1N1KxDFDs5VScegPCX0CggEAWCJ0+KmHbA4F+vDjYW1wNE1MBKee +4Q+nnX45oEHDM+J5da2Ov2IhblzVX/vJaVtI2rwSXCkM3x7ByAXwewNa4BA/eGG/ +v2MPs21f9GcLkpLv0xz+pILkeeNk+e0yIYE4jWQGFMlYh7cNLStDSw6XNU/9IKeO +r2gQjAqS/pMGBMS3FOcd2S+/gMjJom2GaWLhGdJAGdmtGh2EbFku5+WDL76pyAaN +BHEGD91PSER5nEGS9ho81IPDrIm0LVcp6xMRD6PWput/0gcC3Zun1ZDo9oJA1AsS +NMnm6c14ASh/1KQUx9XkC1hUmBVhb4UA4EshT4oXffTHpDMlA6yWqlkReg== +-----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..d2647cc --- /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 +ggIKAoICAQDmpHbO6GP+V/mjruCtTeIVjtgnyH1/K7HoqlCPlPnHcT9SMpHRbVIi +X82NzGIWeotYZe0H9+ok04jYJsrr7BanhBx+FUZkCSJGud1cB4RQp04xPwEj0fg2 +BBq71OW21BtcFsmeN4o+qX0wJECytURA+lxv1T7/MsLnJArk5Kqf/0ysvjdYIggW +DvanL7VsT6x7pIKonzhkF25ytnxMxUQqCrQlDbAMq5hK+RoayaZZ9AClCm8K0KU0 +yg/0Dvu617s+LHwMaGsm/xwp/nf5MIUNRIyvkIpwk106thiLpYURXKNdVxbdx8gA +8QVxwm4HPDdpNnwSxZ4baRFFRB7rubKWsYnNTfqJ65JJ8kY1852HPL7k+LcxpzZL +gXabsgTVgH1P5gLtJEygA8SdAJ+dcZMNpbg3YisDw70kJSzDQ9TIJ7BtBdTGxdhb +CZToJ2vZbbe83na/1Zw2JgS5lx3wyY2Rk4IyDbcWl0ExmiILLrqZUShr9QS6yT1X +DHLo4SQa1Cpq5+O2uZRh405CgeVD5B7vbcRdpPm07DqKNP61x6j+GY3PfRtgIbol +bzXNT3IoQn2HCKraM35j5ltf5wGo4wvTCFqm3+rnKxNIp4MylsS60f8VZlIzhkZf +wp9ZSgCYtxuhhyXfrWhb9yYXK+uEYp3DvZlnagJdcHI+GJKZjL3ZTwIDAQABoAAw +DQYJKoZIhvcNAQELBQADggIBAFRI0PRZO7XlWIpWUC0wc3KjVvTGxieaalJdPC/j +dxT7lBkSTHGjbeLIkqjVAuhONziKT2RP9QxzK2sa9jxIi5zR1byZv500suTez+96 +KkqSnFTgM4nwJdv2S8x0uBPmlREL4K1I0FGZX29wd0bqFhBQqSzVQvQqGSiqSJfU +KkIys1tAIrC7DfNvfhogIrupuN8clluLe0T25qxGeaqXN+EYB7U/O+4FZccpGoeP +dHO2zYeRib0oGTlnk1noRmlqgXPEKfzoWMJ2cUkexlRy1ajW0r1rvcIgc1rPnB8h +6c6YhFGwbYW54/I6tLxJc5pyWCQNH/uYEeFnGs/w85lPKvLM0RXsQ7rfnDRv3LOj +Mex+3whmIs5dAVdQQMy0ngsbPpaR+5Ry8eWAPmwnRXwVaysGgmTysVCzFGqSO3ul +7FgbKEEM1cNe4+Gvl2LEl+aJ5CB1DBslDjXMQVwLMpAU2sthJurhujx3/j598IUp +why48F4056Uf33CncLSEriykIEFXUionXUxtDsCaS13+CfKw+gUJJRsg4ZWqrY6M +b0KHAtzq4g7lFZ+XaXpGdxntqGOrgxfcgWBRhJnp35ILoMFNV2OHjySnF6SWDJvP +AY9IQsUDiMruNjCS9s5zaH7KqmJJ+pgcjVSholozUEI2J3hUpq3KFsE20Cyi+YbO +kTlo +-----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/NewCerts/00.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem new file mode 100644 index 0000000..7b1b6a1 --- /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 16 23:28:44 2016 GMT + Not After : Mar 11 23:28:44 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:a4:76:ce:e8:63:fe:57:f9:a3:ae:e0:ad:4d: + e2:15:8e:d8:27:c8:7d:7f:2b:b1:e8:aa:50:8f:94: + f9:c7:71:3f:52:32:91:d1:6d:52:22:5f:cd:8d:cc: + 62:16:7a:8b:58:65:ed:07:f7:ea:24:d3:88:d8:26: + ca:eb:ec:16:a7:84:1c:7e:15:46:64:09:22:46:b9: + dd:5c:07:84:50:a7:4e:31:3f:01:23:d1:f8:36:04: + 1a:bb:d4:e5:b6:d4:1b:5c:16:c9:9e:37:8a:3e:a9: + 7d:30:24:40:b2:b5:44:40:fa:5c:6f:d5:3e:ff:32: + c2:e7:24:0a:e4:e4:aa:9f:ff:4c:ac:be:37:58:22: + 08:16:0e:f6:a7:2f:b5:6c:4f:ac:7b:a4:82:a8:9f: + 38:64:17:6e:72:b6:7c:4c:c5:44:2a:0a:b4:25:0d: + b0:0c:ab:98:4a:f9:1a:1a:c9:a6:59:f4:00:a5:0a: + 6f:0a:d0:a5:34:ca:0f:f4:0e:fb:ba:d7:bb:3e:2c: + 7c:0c:68:6b:26:ff:1c:29:fe:77:f9:30:85:0d:44: + 8c:af:90:8a:70:93:5d:3a:b6:18:8b:a5:85:11:5c: + a3:5d:57:16:dd:c7:c8:00:f1:05:71:c2:6e:07:3c: + 37:69:36:7c:12:c5:9e:1b:69:11:45:44:1e:eb:b9: + b2:96:b1:89:cd:4d:fa:89:eb:92:49:f2:46:35:f3: + 9d:87:3c:be:e4:f8:b7:31:a7:36:4b:81:76:9b:b2: + 04:d5:80:7d:4f:e6:02:ed:24:4c:a0:03:c4:9d:00: + 9f:9d:71:93:0d:a5:b8:37:62:2b:03:c3:bd:24:25: + 2c:c3:43:d4:c8:27:b0:6d:05:d4:c6:c5:d8:5b:09: + 94:e8:27:6b:d9:6d:b7:bc:de:76:bf:d5:9c:36:26: + 04:b9:97:1d:f0:c9:8d:91:93:82:32:0d:b7:16:97: + 41:31:9a:22:0b:2e:ba:99:51:28:6b:f5:04:ba:c9: + 3d:57:0c:72:e8:e1:24:1a:d4:2a:6a:e7:e3:b6:b9: + 94:61:e3:4e:42:81:e5:43:e4:1e:ef:6d:c4:5d:a4: + f9:b4:ec:3a:8a:34:fe:b5:c7:a8:fe:19:8d:cf:7d: + 1b:60:21:ba:25:6f:35:cd:4f:72:28:42:7d:87:08: + aa:da:33:7e:63:e6:5b:5f:e7:01:a8:e3:0b:d3:08: + 5a:a6:df:ea:e7:2b:13:48:a7:83:32:96:c4:ba:d1: + ff:15:66:52:33:86:46:5f:c2:9f:59:4a:00:98:b7: + 1b:a1:87:25:df:ad:68:5b:f7:26:17:2b:eb:84:62: + 9d:c3:bd:99:67:6a:02:5d:70:72:3e:18:92:99:8c: + bd:d9:4f + 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: + E1:DF:73:0B:F1:3E:86:43:A4:B3:E9:8D:44:7D:3C:B2:19:C1:BC:F2 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + 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 + 89:2c:57:98:17:c1:73:a6:10:02:6f:a6:ac:47:1c:37:2d:1d: + a1:3c:c5:29:b6:3a:e6:e8:14:ec:3b:74:ee:da:db:2d:97:3e: + d3:8c:9d:42:7e:b0:46:e9:54:74:4f:34:df:9e:34:7f:9e:8a: + 9d:4d:b2:cf:fb:71:3f:cb:32:e6:45:e7:b4:d3:9e:e8:ca:a5: + cf:16:7b:76:b5:4e:e0:b9:bb:79:b1:82:a7:d3:23:cb:3c:46: + 63:63:96:b3:5b:62:9e:99:dc:02:17:f9:07:63:86:76:06:1a: + 02:1b:9a:df:1d:cd:e7:46:fe:9a:13:87:47:dd:e2:77:58:50: + a2:6c:c9:a0:f8:14:1f:3b:d7:59:9c:89:bd:2e:2d:ce:60:f4: + c6:2c:e3:63:cf:34:84:61:d9:90:2e:90:fc:5b:4f:a2:00:87: + e7:40:e0:fc:d1:24:8b:d0:28:01:d3:53:ac:b1:58:7f:87:29: + 38:56:93:dd:a2:14:4a:9a:94:b9:f8:94:b2:04:47:db:b8:38: + e6:85:2b:cf:d4:72:88:8b:0d:8e:a0:69:f9:9f:10:22:82:9c: + c5:ec:01:e3:07:a1:69:37:94:25:3a:cd:17:29:37:8d:24:d3: + 27:0f:4d:bf:b0:31:36:b8:c6:a8:69:0b:df:28:f8:e2:dc:da: + 95:3e:7f:d7:3f:a5:8f:92:6a:7d:ad:3a:ac:af:73:2b:5f:f1: + b3:22:92:ef:da:71:84:9e:4b:23:7b:69:b7:29:fc:c5:05:84: + 4b:ff:06:92:ee:f5:9b:14:2a:af:be:ef:02:e1:e7:d0:e8:d0: + 29:7c:48:40:f1:95:bb:08:b2:30:c5:81:80:a8:91:5b:2e:08: + 3b:30:44:07:b5:c4:0b:07:74:ca:5d:37:3d:75:f9:bc:6d:21: + a6:e0:91:d8:f9:27:88:05:58:a7:f4:36:eb:ba:40:63:36:15: + 42:98:0b:e2:d1:c9:11:0b:29:81:e1:c7:02:7e:fa:05:65:51: + 7b:d6:1a:33:46:fc:a5:d4:fd:64:e8:c8:11:d4:d1:41:d9:39: + 18:08:a3:ed:15:70:d9:14:f5:ba:c9:bb:3e:96:8d:5d:cc:c3: + 5c:b6:c8:79:02:2e:e2:a1:06:ba:a5:21:1c:bf:16:7f:2d:d9: + 93:07:92:b1:fa:ee:3f:e3:56:35:f3:30:aa:11:54:d3:71:cb: + 29:d4:60:e1:6c:ae:c4:24:e3:00:4f:5f:52:b0:3f:f4:76:f3: + 6d:db:bc:d8:65:c4:37:be:1a:87:9b:65:c4:20:dd:da:a9:4c: + 9f:86:33:2b:49:a6:f7:aa:ce:da:98:3b:e3:5f:ac:b8:1b:45: + 0e:56:59:fb:49:38:0f:b7:d4:49:f8:7b:ac:fa:d8:b8:1d:16: + db:b2:4c:15:d8:e7:eb:6b:38:ff:d2:69:26:a6:f6:50:15:45: + 2f:12:b2:05:d4:bf:6f:53:79:64:9b:d5:8b:a1:08:3e:43:ee: + 08:fe:9b:ea:83:89:8a:6a:53:98:1e:c5:91:4c:7a:99:2b:6d: + 97:dc:96:1b:de:27:c5:af:0f:dd:42:5c:23:7d:bc:6b:5b:ab: + 47:29:98:35:8f:9e:e6:e1:5f:96:6a:bd:cf:3c:47:89:8b:ad: + 21:de:20:da:99:82:c1:0e:9b:7c:38:21:d8:b1:1c:34:c5:4e: + f7:fe:7d:5e:a4:2f:f8:7d:5c:30:2c:9e:e6:5a:4f:d3:15:90: + e6:6f:69:ea:51:93:8f:2c:dd:a7:c3:3c:50:a8:d1:ba:0b:5c: + cc:2e:4e:57:71:21:08:a1:2c:bd:a7:20:4b:ae:5c:02:7a:cd: + 9a:fe:1e:db:ec:ce:3b:12:37:cb:96:20:7b:3b:b1:5a:2e:84: + 03:f9:0b:32:43:c0:4e:e3:ea:79:e7:9a:13:54:e5:a8:1a:17: + c4:79:78:25:63:ab:67:39:39:a0:6c:c4:c5:94:ac:16:92:3d: + f0:1a:1a:9e:ca:7a:84:1b:c1:5a:5f:4c:65:8a:30:a6:5e:6c: + 0e:ae:bf:ac:09:97:0f:83:5c:92:ce:e4:43:de:06:4b:96:f5: + 46:3b:7d:a8:e3:0f:d3:fe:00:c7:d4:79:4e:5f:bd:ec:59:12: + f9:65:23:fa:e7:97:a2:a6:39:3b:a3:1e:da:47:c5:18:5b:8d: + a7:7b:29:1c:5a:7a:06:c6:92:9e:b7:3b:f0:c5:56:e8:cf:84: + cd:dd:61:0f:21:25:f4:1e:2b:40:b6:74:28:8d:41:f6:2c:1d: + ce:b4:39:d1:e1:be:15:78:c9:d7:99:a1:9d:50:43:da:ec:40: + 69:6a:3b:17:af:28:22:09:e0:7d:38:9e:a7:ca:b7:f7:94:8a: + 2a:1b:32:4e:28:6d:18:95:ca:42:67:c8:bb:13:24:31:43:84: + 3e:95:66:08:5c:15:7f:6b:93:cc:8f:b8:76:7a:fd:74:4a:d6: + 6f:64:74:df:72:f7:34:a3:50:f0:db:bf:0a:2b:1b:48:b7:c9: + c0:97:23:27:b1:56:5b:9e:10:12:5a:bf:ff:38:61:da:41:75: + 15:c5:03:c2:20:fd:7f:84:c0:94:8e:11:ed:01:ba:f1:19:b5: + 05:1d:bf:89:ea:c9:38:4e:d2:cf:5b:24:c6:37:a1:8e:60:89: + 5c:52:ff:7d:5e:2d:c9:f8:b1:79:07:4c:2f:18:85:e8:ba:bf: + 3e:da:59:43:df:29:79:7e:00:38:d2:fc:a9:8e:3b:9d +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI4NDRaFw0zNjAzMTEyMzI4NDRaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOakds7oY/5X+aOu4K1N4hWO2CfIfX8rseiqUI+U+cdxP1IykdFtUiJfzY3MYhZ6 +i1hl7Qf36iTTiNgmyuvsFqeEHH4VRmQJIka53VwHhFCnTjE/ASPR+DYEGrvU5bbU +G1wWyZ43ij6pfTAkQLK1RED6XG/VPv8ywuckCuTkqp//TKy+N1giCBYO9qcvtWxP +rHukgqifOGQXbnK2fEzFRCoKtCUNsAyrmEr5GhrJpln0AKUKbwrQpTTKD/QO+7rX +uz4sfAxoayb/HCn+d/kwhQ1EjK+QinCTXTq2GIulhRFco11XFt3HyADxBXHCbgc8 +N2k2fBLFnhtpEUVEHuu5spaxic1N+onrkknyRjXznYc8vuT4tzGnNkuBdpuyBNWA +fU/mAu0kTKADxJ0An51xkw2luDdiKwPDvSQlLMND1MgnsG0F1MbF2FsJlOgna9lt +t7zedr/VnDYmBLmXHfDJjZGTgjINtxaXQTGaIgsuuplRKGv1BLrJPVcMcujhJBrU +Kmrn47a5lGHjTkKB5UPkHu9txF2k+bTsOoo0/rXHqP4Zjc99G2AhuiVvNc1PcihC +fYcIqtozfmPmW1/nAajjC9MIWqbf6ucrE0ingzKWxLrR/xVmUjOGRl/Cn1lKAJi3 +G6GHJd+taFv3Jhcr64RincO9mWdqAl1wcj4YkpmMvdlPAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFOHfcwvxPoZDpLPpjUR9PLIZwbzyMB8GA1UdIwQYMBaAFKI+ +Aiqjp005tAhNmcwMdTbqJ8M+MD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAIksV5gXwXOmEAJvpqxHHDct +HaE8xSm2OuboFOw7dO7a2y2XPtOMnUJ+sEbpVHRPNN+eNH+eip1Nss/7cT/LMuZF +57TTnujKpc8We3a1TuC5u3mxgqfTI8s8RmNjlrNbYp6Z3AIX+QdjhnYGGgIbmt8d +zedG/poTh0fd4ndYUKJsyaD4FB8711mcib0uLc5g9MYs42PPNIRh2ZAukPxbT6IA +h+dA4PzRJIvQKAHTU6yxWH+HKThWk92iFEqalLn4lLIER9u4OOaFK8/UcoiLDY6g +afmfECKCnMXsAeMHoWk3lCU6zRcpN40k0ycPTb+wMTa4xqhpC98o+OLc2pU+f9c/ +pY+San2tOqyvcytf8bMiku/acYSeSyN7abcp/MUFhEv/BpLu9ZsUKq++7wLh59Do +0Cl8SEDxlbsIsjDFgYCokVsuCDswRAe1xAsHdMpdNz11+bxtIabgkdj5J4gFWKf0 +Nuu6QGM2FUKYC+LRyRELKYHhxwJ++gVlUXvWGjNG/KXU/WToyBHU0UHZORgIo+0V +cNkU9brJuz6WjV3Mw1y2yHkCLuKhBrqlIRy/Fn8t2ZMHkrH67j/jVjXzMKoRVNNx +yynUYOFsrsQk4wBPX1KwP/R2823bvNhlxDe+GoebZcQg3dqpTJ+GMytJpveqztqY +O+NfrLgbRQ5WWftJOA+31En4e6z62LgdFtuyTBXY5+trOP/SaSam9lAVRS8SsgXU +v29TeWSb1YuhCD5D7gj+m+qDiYpqU5gexZFMepkrbZfclhveJ8WvD91CXCN9vGtb +q0cpmDWPnubhX5Zqvc88R4mLrSHeINqZgsEOm3w4IdixHDTFTvf+fV6kL/h9XDAs +nuZaT9MVkOZvaepRk48s3afDPFCo0boLXMwuTldxIQihLL2nIEuuXAJ6zZr+Htvs +zjsSN8uWIHs7sVouhAP5CzJDwE7j6nnnmhNU5agaF8R5eCVjq2c5OaBsxMWUrBaS +PfAaGp7KeoQbwVpfTGWKMKZebA6uv6wJlw+DXJLO5EPeBkuW9UY7fajjD9P+AMfU +eU5fvexZEvllI/rnl6KmOTujHtpHxRhbjad7KRxaegbGkp63O/DFVujPhM3dYQ8h +JfQeK0C2dCiNQfYsHc60OdHhvhV4ydeZoZ1QQ9rsQGlqOxevKCIJ4H04nqfKt/eU +iiobMk4obRiVykJnyLsTJDFDhD6VZghcFX9rk8yPuHZ6/XRK1m9kdN9y9zSjUPDb +vworG0i3ycCXIyexVlueEBJav/84YdpBdRXFA8Ig/X+EwJSOEe0BuvEZtQUdv4nq +yThO0s9bJMY3oY5giVxS/31eLcn4sXkHTC8Yhei6vz7aWUPfKXl+ADjS/KmOO50= +-----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..4ab5d5a --- /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 16 23:29:04 2016 GMT + Not After : Mar 11 23:29:04 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:af:87:9e:1e:7f:c0:ab:da:47:22:74:d0:df:01: + f1:67:6c:ac:c4:b7:d9:18:97:e5:7a:62:76:33:b6: + 52:f2:92:90:75:ac:a3:94:7e:0c:29:75:c9:83:2f: + 19:66:60:84:45:ff:d5:a9:bd:c5:3a:a2:d8:25:cf: + 15:8a:23:3e:09:73:2f:99:1d:24:1f:e6:96:7e:7b: + c4:1e:8d:55:5b:c1:18:69:cd:1d:b4:22:d5:7b:db: + 5e:7c:91:f2:8e:c1:03:30:ee:63:46:5a:54:d5:40: + ac:79:55:00:71:07:8d:3e:0e:ed:ff:93:6c:f1:2d: + 84:c1:51:a3:7c:49:cf:ff:85:7b:c0:64:c1:ba:c8: + 66:7a:ff:17:2a:74:ea:16:6a:1d:97:c0:27:57:10: + be:76:f5:9a:63:56:c7:25:c6:fc:a7:5e:00:a6:1a: + 3d:21:bd:7a:f9:e3:03:60:ce:df:16:06:fc:05:bc: + d1:c8:5d:e7:33:ed:52:8b:60:5b:60:c5:70:13:1d: + c1:b3:08:13:09:3b:05:e8:02:40:12:45:89:af:87: + 1f:6a:8f:62:ce:1e:17:13:34:82:81:86:e9:bb:85: + 5b:75:1d:f4:3a:02:b4:a6:58:23:fe:c3:3a:35:09: + 95:bb:f7:79:bc:e3:97:e6:6d:77:24:aa:2d:51:50: + 37:69 + 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: + 45:DA:4B:8D:05:9C:62:4E:62:C3:D7:5C:5F:D3:D9:85:B4:9B:F2:2C + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + 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 + a2:bb:e6:97:67:3c:b6:6e:6e:dd:34:99:16:c6:80:91:08:bf: + 91:ba:51:62:5d:76:2f:e5:53:91:3d:99:03:18:a9:84:69:73: + 76:66:c3:eb:56:d7:c5:40:91:15:da:de:b2:76:48:7d:8a:8c: + 80:79:3c:e6:da:0e:a6:c3:53:d6:74:ee:5f:29:b7:03:46:de: + 89:32:14:22:03:30:68:2e:7e:06:d4:ac:9e:82:c0:02:16:7f: + 81:ba:ee:7a:e7:8b:f7:fb:99:7f:8c:eb:78:54:97:4e:28:44: + da:f4:e2:1b:f8:3e:ac:ca:cc:e3:e3:71:90:91:47:9c:78:ed: + 6f:bc:b7:98:12:ea:75:e5:15:f7:26:56:a7:5c:d6:74:a8:13: + 7b:23:35:4e:6a:01:f6:a9:f5:5b:9b:d0:ea:ba:0f:c3:c4:1a: + e0:b9:a3:ed:5d:28:cb:7f:1d:3e:8a:9a:af:4c:88:00:3c:10: + f0:49:85:24:60:e6:cb:d6:9e:00:46:78:4d:90:22:68:4f:10: + 39:84:3b:e2:7c:3d:ed:23:41:19:7e:6f:45:59:89:a9:9f:26: + c1:f9:7d:4d:0a:b4:10:f9:31:7d:cc:87:d0:4b:62:14:70:86: + c8:7d:14:ff:e4:68:e2:de:42:ca:01:c7:aa:2d:5a:a5:72:64: + f1:4c:fa:6e:60:15:22:08:68:e6:c6:6a:75:63:24:b5:54:76: + d1:97:4f:e0:e8:bc:eb:d0:62:84:4a:b4:3a:07:38:5f:b9:a6: + 6a:31:14:47:33:81:bd:d0:a4:a2:da:2b:92:0d:dc:42:c4:0f: + 28:0d:b6:1b:33:b5:88:df:1b:a8:d8:90:9a:11:ce:df:d4:14: + e9:ac:94:94:95:bb:bc:6e:f1:be:85:29:3f:17:ab:41:14:d8: + 20:ba:e0:a2:a3:d3:d4:8b:1e:4b:32:22:8d:0d:c1:e6:39:1a: + ce:cd:f3:1d:f1:82:85:d5:e7:80:34:90:a4:0e:d4:af:32:c8: + 79:4e:25:32:b6:1e:06:3a:26:42:38:47:1a:32:96:71:5b:fe: + 5b:b0:ef:7d:fe:58:ca:eb:b5:c9:4b:2f:12:cb:89:36:22:7c: + a6:39:ab:20:c1:2d:cd:6b:34:e1:cd:bc:ed:45:45:12:4a:65: + 4b:ab:45:f2:6d:7a:9d:f8:b5:52:78:1b:da:2f:e0:ce:f7:e2: + b0:fa:6f:40:3d:dd:e9:39:c3:63:68:ab:77:53:be:3b:dd:9a: + bc:d7:d7:fa:6a:bf:bf:74:f7:11:80:87:f9:d3:45:eb:1e:8e: + d1:a9:a0:2e:66:e7:20:67:1c:4c:22:43:77:85:ff:1a:23:37: + cc:49:de:51:ee:f2:04:2f:a8:98:88:0f:b6:18:53:eb:e2:49: + 15:5e:02:8b:1e:7b:e6:c5:d1:0c:df:84:4e:d9:bd:fe:21:48: + d4:a4:11:01:27:57:51:d6:c1:b2:a1:1c:11:9a:a7:d1:ab:f0: + 99:16:b2:c8:3f:74:25:68:0b:1a:cf:58:0d:cd:cc:1a:6d:8b: + ec:1f:70:82:02:40:97:0f:75:2c:53:87:c1:42:5c:d1:7e:19: + 78:2c:2c:88:73:33:81:63:38:84:07:0f:16:bb:7c:54:59:03: + 94:e7:b8:85:d7:f8:5e:53:35:65:2e:e5:27:65:be:f0:89:65: + f6:ab:3f:6e:a5:bd:c1:1a:9e:31:30:68:6e:50:af:54:4c:33: + f8:73:2f:41:60:4f:4c:85:1b:ad:7d:db:62:42:dc:87:96:b4: + cf:ce:12:50:ed:6c:01:5f:e2:f9:03:f5:f7:4c:6c:8f:2b:5b: + 7a:64:7d:19:e8:20:f2:e9:10:58:f3:71:0e:1e:58:68:f2:59: + 3c:06:53:7a:f3:60:62:5b:c7:b7:83:58:1d:3d:a6:17:db:33: + cc:91:14:af:d6:b9:08:bf:60:af:ac:3e:fe:8b:74:71:20:c7: + e7:31:5e:26:6c:28:52:67:12:1e:c3:9b:89:23:5d:88:ee:b0: + 6b:db:cc:94:8b:9b:1b:40:b7:66:bc:7d:1d:e1:08:00:20:ba: + 41:cd:17:d6:4c:7b:c4:5a:fd:cf:6b:20:e2:b8:86:9c:31:17: + c2:d7:7f:1c:3a:d0:fc:1d:f5:7f:c9:96:04:27:de:b8:ef:8d: + 38:9a:b3:56:60:ac:c2:07:38:64:19:39:9e:73:6f:ba:59:15: + ac:45:42:4d:bb:79:60:7f:ae:c3:8d:63:4a:27:16:0a:ca:92: + 7f:f7:a2:02:76:f5:e6:7c:ec:ba:ea:18:cd:9c:3b:ee:37:2c: + 9d:78:4e:c9:40:6d:94:cc:ce:ca:f4:33:fc:a4:dd:05:62:d6: + 0f:1e:19:63:af:10:c3:ff:02:1a:0a:48:fd:af:f2:a4:0e:64: + dd:90:f4:4f:14:1b:90:1f:9e:29:b0:0b:94:a4:d1:2a:87:b9: + 3a:76:c2:b6:af:c3:d4:84:6e:85:1c:64:73:46:d0:df:72:c0: + 3c:42:91:c4:30:10:11:18:36:bc:e5:17:36:22:5f:c2:3f:ac: + 1d:2e:9d:87:11:be:a7:ac:b2:62:35:74:b9:27:27:95:bc:c1: + 11:44:f8:64:36:60:74:06:a2:e7:e9:76:be:a7:86:5e:18:1e: + bd:dc:b0:aa:ae:92:d6:dd:d6:25:80:d6:c1:be:c1:21:1c:01: + 6f:83:20:ae:b7:54:4f:3d:2d:12:fc:a2:cc:49:fd:59 +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MDRaFw0zNjAzMTEyMzI5MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvh54ef8Cr2kcidNDf +AfFnbKzEt9kYl+V6YnYztlLykpB1rKOUfgwpdcmDLxlmYIRF/9WpvcU6otglzxWK +Iz4Jcy+ZHSQf5pZ+e8QejVVbwRhpzR20ItV72158kfKOwQMw7mNGWlTVQKx5VQBx +B40+Du3/k2zxLYTBUaN8Sc//hXvAZMG6yGZ6/xcqdOoWah2XwCdXEL529ZpjVscl +xvynXgCmGj0hvXr54wNgzt8WBvwFvNHIXecz7VKLYFtgxXATHcGzCBMJOwXoAkAS +RYmvhx9qj2LOHhcTNIKBhum7hVt1HfQ6ArSmWCP+wzo1CZW793m845fmbXckqi1R +UDdpAgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFEXaS40FnGJO +YsPXXF/T2YW0m/IsMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAorvml2c8tm5u3TSZFsaA +kQi/kbpRYl12L+VTkT2ZAxiphGlzdmbD61bXxUCRFdresnZIfYqMgHk85toOpsNT +1nTuXym3A0beiTIUIgMwaC5+BtSsnoLAAhZ/gbrueueL9/uZf4zreFSXTihE2vTi +G/g+rMrM4+NxkJFHnHjtb7y3mBLqdeUV9yZWp1zWdKgTeyM1TmoB9qn1W5vQ6roP +w8Qa4Lmj7V0oy38dPoqar0yIADwQ8EmFJGDmy9aeAEZ4TZAiaE8QOYQ74nw97SNB +GX5vRVmJqZ8mwfl9TQq0EPkxfcyH0EtiFHCGyH0U/+Ro4t5CygHHqi1apXJk8Uz6 +bmAVIgho5sZqdWMktVR20ZdP4Oi869BihEq0Ogc4X7mmajEURzOBvdCkotorkg3c +QsQPKA22GzO1iN8bqNiQmhHO39QU6ayUlJW7vG7xvoUpPxerQRTYILrgoqPT1Ise +SzIijQ3B5jkazs3zHfGChdXngDSQpA7UrzLIeU4lMrYeBjomQjhHGjKWcVv+W7Dv +ff5Yyuu1yUsvEsuJNiJ8pjmrIMEtzWs04c287UVFEkplS6tF8m16nfi1Ungb2i/g +zvfisPpvQD3d6TnDY2ird1O+O92avNfX+mq/v3T3EYCH+dNF6x6O0amgLmbnIGcc +TCJDd4X/GiM3zEneUe7yBC+omIgPthhT6+JJFV4Cix575sXRDN+ETtm9/iFI1KQR +ASdXUdbBsqEcEZqn0avwmRayyD90JWgLGs9YDc3MGm2L7B9wggJAlw91LFOHwUJc +0X4ZeCwsiHMzgWM4hAcPFrt8VFkDlOe4hdf4XlM1ZS7lJ2W+8Ill9qs/bqW9wRqe +MTBoblCvVEwz+HMvQWBPTIUbrX3bYkLch5a0z84SUO1sAV/i+QP190xsjytbemR9 +Gegg8ukQWPNxDh5YaPJZPAZTevNgYlvHt4NYHT2mF9szzJEUr9a5CL9gr6w+/ot0 +cSDH5zFeJmwoUmcSHsObiSNdiO6wa9vMlIubG0C3Zrx9HeEIACC6Qc0X1kx7xFr9 +z2sg4riGnDEXwtd/HDrQ/B31f8mWBCfeuO+NOJqzVmCswgc4ZBk5nnNvulkVrEVC +Tbt5YH+uw41jSicWCsqSf/eiAnb15nzsuuoYzZw77jcsnXhOyUBtlMzOyvQz/KTd +BWLWDx4ZY68Qw/8CGgpI/a/ypA5k3ZD0TxQbkB+eKbALlKTRKoe5OnbCtq/D1IRu +hRxkc0bQ33LAPEKRxDAQERg2vOUXNiJfwj+sHS6dhxG+p6yyYjV0uScnlbzBEUT4 +ZDZgdAai5+l2vqeGXhgevdywqq6S1t3WJYDWwb7BIRwBb4MgrrdUTz0tEvyizEn9 +WQ== +-----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..2e2a8b9 --- /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 16 23:29:25 2016 GMT + Not After : Mar 11 23:29:25 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=addc.addom.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:a6:c4:a9:bf:75:ea:4c:8d:3b:fd:8a:0f:b0:a2: + b6:c7:a8:1f:e4:0e:3e:41:ef:d6:10:48:77:7b:4e: + 4c:59:e1:bf:6d:c7:18:7b:a8:01:a7:d5:d2:2c:21: + 3e:d0:1a:da:58:03:e8:42:f1:53:0e:a7:91:b9:2c: + b9:e7:7a:c9:de:5e:ed:4c:93:6b:cc:dd:17:d0:c7: + d1:f1:7c:3d:0d:6f:df:5d:53:5a:b1:1f:a3:7b:5b: + 41:65:0c:7c:ea:53:df:bb:da:41:15:da:49:e3:b9: + 2d:bb:b5:af:ef:8c:b8:84:74:d0:18:16:8e:5c:e4: + c2:e7:a1:87:8f:e3:87:8b:0b:bb:90:30:e8:e0:f3: + eb:c0:50:5f:b5:7f:54:9a:1b:34:43:fd:be:5a:80: + 6e:0f:63:a2:b3:79:42:4a:85:c8:07:c7:82:55:23: + 88:d4:4e:03:2f:f1:95:bd:ed:15:2d:3e:16:cd:ff: + c7:9b:03:29:36:a6:5d:c9:1a:1e:89:a5:ba:66:83: + 0f:96:a8:07:9f:24:b9:1b:8f:02:9a:b8:50:29:8b: + be:63:45:fa:45:c3:38:23:a0:98:3a:b4:6b:42:99: + 13:36:4b:84:ef:27:89:39:34:79:f8:67:16:7b:9c: + 2a:03:41:15:63:46:e4:db:2f:f2:3e:6d:fe:7c:20: + 1e:9f:02:48:a4:bc:15:42:a6:f8:38:86:dc:6b:7c: + 4e:67:a3:31:81:8e:b6:30:1a:eb:3d:08:25:19:5f: + 42:dc:39:ec:79:1d:30:0a:fb:16:8f:3d:19:14:cc: + f5:af:d7:c6:75:cf:b3:96:a2:b2:9b:d9:03:01:a3: + ca:88:1d:72:ed:6f:d1:bf:57:56:8e:b9:07:9b:b9: + 04:13:1e:0b:5a:06:6b:2b:43:a2:dc:d5:b7:f4:ba: + d3:ae:9d:ad:fd:d3:8a:7c:2f:87:32:fa:89:88:58: + 00:ae:16:2b:9c:1d:58:82:4d:e5:21:da:d5:6c:f7: + a8:40:8b:c7:02:d5:36:30:ef:3f:09:9b:a6:d2:31: + a3:bf:20:d4:a2:9e:26:c4:b4:c3:0f:0b:6c:00:d1: + 2c:16:b1:2a:eb:06:d9:d5:98:c3:cd:cb:20:68:ad: + 0a:2c:a1:2f:27:41:5c:91:de:49:62:ed:d8:3a:ef: + 68:1c:6d:fe:94:c3:28:68:32:60:08:65:cd:02:9f: + 97:96:2f:0f:87:27:3d:b9:0f:85:62:e8:2b:9a:b4: + f4:d3:d7:c1:93:96:27:23:29:88:b1:39:99:53:3a: + 20:aa:88:44:3b:4a:24:2a:8b:e0:b4:8d:dd:66:30: + df:a6:6e:b7:fc:21:43:16:9e:3e:12:20:c8:7a:30: + c1:3d:ab + 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 addc.addom.samba.example.com + X509v3 Subject Key Identifier: + 3D:BC:70:0C:74:D4:B8:85:49:1D:08:84:C4:1B:27:F2:AF:72:37:D3 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:addc.addom.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 + 9e:8b:bb:0a:7a:dc:c0:94:33:bc:18:a5:e6:4a:1f:ff:8e:21: + b1:8f:33:f0:3e:8b:6c:72:55:c4:47:71:5f:ce:e7:31:ef:5b: + 62:04:b7:57:8f:a8:27:9f:ed:69:d2:ec:a8:0d:e2:76:33:8d: + 41:3a:67:61:5c:53:60:c7:53:ed:d7:99:72:29:1d:ae:d3:ee: + c9:76:1c:6d:18:47:e9:94:dd:2e:97:3f:99:af:b5:f4:a1:7c: + 92:f6:4d:b5:c1:7a:0c:38:ba:d1:b6:19:9a:9f:e2:02:84:d4: + 54:01:38:7b:55:86:4a:ee:3d:85:48:01:da:34:09:69:43:25: + 7e:6e:06:73:e0:b9:7c:b5:9c:4e:9c:b5:52:85:32:62:62:25: + 39:fa:02:4b:51:2e:df:8e:52:17:02:50:f4:99:29:bf:7e:97: + 53:91:12:85:9a:69:62:45:59:c4:5b:3f:af:18:e6:7b:e4:86: + 5d:f1:9e:5a:2b:3e:14:6e:7e:d4:47:24:ef:d9:a8:ec:d9:a6: + cb:b8:4f:1a:86:d9:43:20:41:16:15:5f:81:0d:fe:6b:31:53: + c1:f6:84:4c:f3:03:64:d2:e6:44:3d:7a:60:79:d7:37:6f:33: + de:c0:a8:b9:6e:fe:b2:79:ac:b4:53:92:b8:0a:59:2b:cc:6b: + 37:c4:6f:c6:44:02:f7:7c:c5:c6:a6:6f:c2:ad:de:78:1e:48: + 96:cc:fe:59:2e:53:ce:34:d6:e8:f0:56:43:30:32:90:6f:f9: + 47:76:ab:99:63:e3:e8:a3:f3:83:98:e9:05:2b:ea:f9:f9:9d: + 66:70:c7:2c:00:c2:9e:57:3e:31:43:50:50:c8:db:a8:2d:21: + 4e:6f:39:c2:bd:ef:d8:47:99:27:0d:48:b2:58:f1:be:45:bd: + fe:c4:a2:56:fc:06:02:dc:19:33:85:53:ed:38:59:01:16:bc: + aa:c5:d3:4b:37:54:83:1b:e5:c1:4b:dd:34:6b:e5:d8:35:86: + 95:e6:9f:d2:22:84:b1:e2:4f:a7:2e:4d:e6:9c:eb:db:df:42: + e1:b4:66:e6:58:d3:28:10:34:97:f3:9c:6b:5f:05:2c:47:2c: + e3:75:eb:6f:74:0a:ec:d7:1d:30:80:56:44:12:26:f6:4e:5f: + ff:92:f4:62:02:36:9c:62:eb:39:98:53:68:68:95:fb:94:68: + 69:b8:3c:66:1a:ce:78:c4:cf:c4:6f:21:ac:a8:a6:f4:ab:69: + 2a:2e:00:5d:f7:67:06:b1:4f:97:58:88:55:d8:6e:eb:a5:98: + 50:36:21:70:3d:b0:a4:f5:3b:21:b3:1c:f5:a9:dd:c6:4a:c2: + 89:b8:5a:b3:bc:1f:21:ce:4c:68:5f:98:d8:39:70:d2:7e:a0: + 90:df:ad:a3:13:eb:3c:93:f6:b8:f4:d9:a7:51:b3:0d:ea:ee: + d4:57:aa:db:ca:7c:8a:a0:08:c3:98:9a:3a:b7:ba:2a:50:92: + 26:c2:e3:11:ba:12:60:24:b9:59:df:62:a8:d7:4d:a3:cb:ea: + 46:e8:39:f9:83:14:a8:5c:44:75:71:6b:7f:99:bd:68:58:d9: + 6b:d1:cd:c7:45:95:9e:44:1e:85:35:c0:30:2b:18:aa:eb:2f: + 93:d5:be:66:5d:70:ed:1d:04:f2:c1:1e:b5:ec:45:0c:04:f6: + 9d:88:d3:0c:20:5e:5b:23:df:34:a1:f5:ea:b4:a1:44:c0:da: + d5:ea:89:e8:b5:cb:dc:f8:92:ee:ac:8d:61:ed:bf:74:2b:28: + 79:1f:f4:9a:ff:63:bd:e6:aa:79:1d:2c:26:4a:b2:26:53:57: + ba:88:0e:eb:19:57:c0:10:a0:1e:81:2a:c0:56:2e:c3:2a:81: + bf:c1:5a:e7:48:ce:c1:6a:b9:6c:41:cc:44:a6:b8:70:e2:57: + 0e:6d:41:d6:61:da:bf:ac:20:2c:a7:2a:67:23:98:00:ba:ce: + 8b:a8:c2:45:66:a7:08:eb:7f:0a:b5:e7:9b:d6:f4:07:d5:b3: + 43:cd:27:d4:fa:c9:40:8f:af:b2:36:1c:e7:44:b4:4e:cc:5a: + 2b:73:ad:8f:c4:d9:47:a6:fb:2c:7d:1a:80:2a:55:b3:80:34: + 6f:8e:17:27:93:05:21:40:e9:8f:bf:47:6a:52:f5:2e:b5:18: + d1:8c:1d:83:04:80:55:fd:21:28:dc:7c:be:c8:c1:5f:e4:40: + d3:13:e4:66:bf:ad:92:4e:9b:db:c1:be:a3:42:74:da:c3:2c: + 0a:da:3f:94:14:ad:7e:de:81:c6:01:6a:f7:7a:b4:25:51:b0: + ab:cd:b3:3a:77:bf:c3:6b:04:44:30:73:41:ad:93:49:67:ee: + 43:d1:96:8e:36:83:2b:1b:6c:e7:cc:3e:d6:16:b9:88:4a:ab: + 56:c0:76:00:f6:9a:6a:8a:e3:e0:41:75:9d:3b:47:0f:c9:0a: + 8e:9f:9c:00:92:bb:ae:d8:42:56:35:64:eb:59:13:da:2c:63: + 83:c3:ec:68:91:b5:f3:71:85:48:54:c3:9d:a1:c8:63:f3:de: + 5d:a5:34:a9:1e:85:2c:2c:b5:d8:a9:62:8d:26:1f:b2:9e:a7: + 83:4d:df:69:63:b5:b7:e5:dd:e7:3b:18:e5:b3:77:df:c5:47: + b3:f7:8c:e7:5e:87:2e:46:e3:8f:b1:2b:9b:c6:26:2d:1a:28: + 30:13:10:86:5b:46:87:b1:2d:12:ce:b6:fe:1c:4e:44 +-----BEGIN CERTIFICATE----- +MIIJ9DCCBdygAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MjVaFw0zNjAzMTEyMzI5MjVaMIG4MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSUwIwYDVQQDDBxhZGRjLmFkZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNv +bUBzYW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAKbEqb916kyNO/2KD7CitseoH+QOPkHv1hBId3tOTFnhv23HGHuoAafV0iwh +PtAa2lgD6ELxUw6nkbksued6yd5e7UyTa8zdF9DH0fF8PQ1v311TWrEfo3tbQWUM +fOpT37vaQRXaSeO5Lbu1r++MuIR00BgWjlzkwuehh4/jh4sLu5Aw6ODz68BQX7V/ +VJobNEP9vlqAbg9jorN5QkqFyAfHglUjiNROAy/xlb3tFS0+Fs3/x5sDKTamXcka +HomlumaDD5aoB58kuRuPApq4UCmLvmNF+kXDOCOgmDq0a0KZEzZLhO8niTk0efhn +FnucKgNBFWNG5Nsv8j5t/nwgHp8CSKS8FUKm+DiG3Gt8TmejMYGOtjAa6z0IJRlf +Qtw57HkdMAr7Fo89GRTM9a/XxnXPs5aispvZAwGjyogdcu1v0b9XVo65B5u5BBMe +C1oGaytDotzVt/S6066drf3TinwvhzL6iYhYAK4WK5wdWIJN5SHa1Wz3qECLxwLV +NjDvPwmbptIxo78g1KKeJsS0ww8LbADRLBaxKusG2dWYw83LIGitCiyhLydBXJHe +SWLt2DrvaBxt/pTDKGgyYAhlzQKfl5YvD4cnPbkPhWLoK5q09NPXwZOWJyMpiLE5 +mVM6IKqIRDtKJCqL4LSN3WYw36Zut/whQxaePhIgyHowwT2rAgMBAAGjggH3MIIB +8zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEu +ZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEG +CWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwSQYJYIZIAYb4QgENBDwWOkRv +bWFpbiBDb250cm9sbGVyIENlcnRpZmljYXRlIGFkZGMuYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20wHQYDVR0OBBYEFD28cAx01LiFSR0IhMQbJ/KvcjfTMB8GA1UdIwQY +MBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MEAGA1UdEQQ5MDeCHGFkZGMuYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcD +AgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAJ6Luwp63MCU +M7wYpeZKH/+OIbGPM/A+i2xyVcRHcV/O5zHvW2IEt1ePqCef7WnS7KgN4nYzjUE6 +Z2FcU2DHU+3XmXIpHa7T7sl2HG0YR+mU3S6XP5mvtfShfJL2TbXBegw4utG2GZqf +4gKE1FQBOHtVhkruPYVIAdo0CWlDJX5uBnPguXy1nE6ctVKFMmJiJTn6AktRLt+O +UhcCUPSZKb9+l1OREoWaaWJFWcRbP68Y5nvkhl3xnlorPhRuftRHJO/ZqOzZpsu4 +TxqG2UMgQRYVX4EN/msxU8H2hEzzA2TS5kQ9emB51zdvM97AqLlu/rJ5rLRTkrgK +WSvMazfEb8ZEAvd8xcamb8Kt3ngeSJbM/lkuU8401ujwVkMwMpBv+Ud2q5lj4+ij +84OY6QUr6vn5nWZwxywAwp5XPjFDUFDI26gtIU5vOcK979hHmScNSLJY8b5Fvf7E +olb8BgLcGTOFU+04WQEWvKrF00s3VIMb5cFL3TRr5dg1hpXmn9IihLHiT6cuTeac +69vfQuG0ZuZY0ygQNJfznGtfBSxHLON16290CuzXHTCAVkQSJvZOX/+S9GICNpxi +6zmYU2holfuUaGm4PGYaznjEz8RvIayopvSraSouAF33ZwaxT5dYiFXYbuulmFA2 +IXA9sKT1OyGzHPWp3cZKwom4WrO8HyHOTGhfmNg5cNJ+oJDfraMT6zyT9rj02adR +sw3q7tRXqtvKfIqgCMOYmjq3uipQkibC4xG6EmAkuVnfYqjXTaPL6kboOfmDFKhc +RHVxa3+ZvWhY2WvRzcdFlZ5EHoU1wDArGKrrL5PVvmZdcO0dBPLBHrXsRQwE9p2I +0wwgXlsj3zSh9eq0oUTA2tXqiei1y9z4ku6sjWHtv3QrKHkf9Jr/Y73mqnkdLCZK +siZTV7qIDusZV8AQoB6BKsBWLsMqgb/BWudIzsFquWxBzESmuHDiVw5tQdZh2r+s +ICynKmcjmAC6zouowkVmpwjrfwq155vW9AfVs0PNJ9T6yUCPr7I2HOdEtE7MWitz +rY/E2Uem+yx9GoAqVbOANG+OFyeTBSFA6Y+/R2pS9S61GNGMHYMEgFX9ISjcfL7I +wV/kQNMT5Ga/rZJOm9vBvqNCdNrDLAraP5QUrX7egcYBavd6tCVRsKvNszp3v8Nr +BEQwc0Gtk0ln7kPRlo42gysbbOfMPtYWuYhKq1bAdgD2mmqK4+BBdZ07Rw/JCo6f +nACSu67YQlY1ZOtZE9osY4PD7GiRtfNxhUhUw52hyGPz3l2lNKkehSwstdipYo0m +H7Kep4NN32ljtbfl3ec7GOWzd9/FR7P3jOdehy5G44+xK5vGJi0aKDATEIZbRoex +LRLOtv4cTkQ= +-----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..7486a63 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem @@ -0,0 +1,169 @@ +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 16 23:29:41 2016 GMT + Not After : Mar 11 23:29:41 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:91:64:f2:1b:2b:ed:9b:40:bc:0d:46:23:49: + 77:32:74:fe:cb:9a:46:86:33:1e:56:bd:c8:da:dd: + e6:2a:07:34:61:1c:f0:b8:71:29:24:2b:90:f3:43: + 99:6f:69:f6:ff:8d:b9:b7:3f:f3:36:6a:99:90:90: + d6:95:63:4e:88:5a:d7:41:89:7f:73:13:64:49:c7: + de:42:65:08:5d:ca:04:b2:68:3a:40:7f:6a:05:df: + 56:30:2f:ac:1b:8b:0f:c3:15:3c:38:0f:90:50:44: + 00:bb:59:40:f6:d2:e8:5b:73:03:0d:f6:7d:38:5d: + 2f:99:c3:0d:13:0f:74:d0:9e:ef:1e:92:42:c4:46: + 7c:dc:85:7e:e9:af:91:4e:9d:5f:82:af:58:60:18: + a5:ac:91:6e:dd:cf:a7:32:3c:d2:f4:e9:81:be:80: + 9e:0c:ca:1f:1a:be:98:c4:fe:e6:25:c1:89:fe:16: + 0a:30:90:d3:d4:e5:af:89:24:64:12:d0:4f:19:e2: + 1b:86:fb:06:a9:63:d1:47:10:89:dc:2b:52:24:dc: + 66:a9:56:c2:cb:f4:ec:35:12:f4:ad:5e:fc:ff:86: + e9:b1:f9:1f:b3:ce:44:fb:be:04:af:8d:42:9b:56: + a5:02:7f:c5:cf:5f:23:41:1c:69:ee:33:97:7a:81: + 50:8b + 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@addom.samba.example.com + X509v3 Subject Key Identifier: + 30:10:6E:1F:7E:52:33:8C:C8:85:E5:92:74:5D:76:7E:E9:33:5B:36 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@addom.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 + 53:3e:51:d2:5d:2c:69:23:5b:dd:05:1a:23:ff:39:5d:54:63: + e5:da:e1:4b:60:8c:09:7c:4e:8e:da:8a:bb:63:5d:bc:2d:a0: + d4:ce:9e:d2:ce:38:d7:32:67:ba:4a:a6:d1:1d:c4:c7:50:e8: + 9a:9e:44:56:1a:9c:f4:8f:b9:8e:39:84:21:db:0f:60:8a:60: + b4:0f:4f:3c:35:a0:d2:37:3d:88:e8:0a:18:a7:a7:2d:19:e3: + aa:d3:8e:18:8f:35:ef:3e:4a:95:c4:d3:9b:f4:cf:89:c2:70: + b9:8c:5c:ef:8a:9e:7a:56:73:13:eb:8b:b7:d9:e1:88:5b:c4: + 62:47:42:45:8d:7b:2d:cf:71:83:1b:48:9d:84:8f:65:66:97: + 61:fc:f6:30:34:e8:88:2a:34:91:48:dc:7a:b7:65:bc:9c:98: + 00:4c:e7:49:fe:4d:a9:56:ea:87:d6:6c:46:39:f2:98:5b:56: + 14:82:f2:9e:b8:ad:fd:89:36:48:87:4e:5c:ef:3f:e0:35:ff: + 72:5f:5b:e1:c2:fd:d9:6e:40:2b:35:ad:50:08:74:94:87:89: + c4:cd:c7:ab:a7:19:4e:ba:f2:1d:83:0f:b0:cf:9c:e6:df:73: + 36:88:cf:42:9c:a3:72:27:0f:f7:bf:5b:cc:6b:e5:20:03:b5: + 4a:1c:f3:7d:ae:92:43:aa:bb:13:07:a4:3a:77:3d:34:01:00: + f1:89:aa:e8:1b:09:7b:b8:b0:e1:54:03:ff:3d:8d:be:35:b9: + 13:b2:59:58:32:48:93:f8:e7:d7:3d:49:70:01:44:e6:2b:21: + b3:75:49:ae:44:7a:50:15:b8:65:f3:c3:48:96:df:c8:d9:2a: + f7:c5:2a:7e:2c:68:77:af:2d:78:1b:fc:1a:d8:f4:8b:a6:86: + 35:d2:f0:87:e9:d6:30:0a:76:65:f8:71:e9:80:0d:1f:16:86: + 89:92:81:34:d9:be:9b:41:25:ec:65:a9:0a:56:b2:03:91:54: + 02:21:97:99:74:61:8c:4a:2e:f4:d0:b1:8b:f1:e6:26:52:bc: + f6:f2:e0:bd:96:66:22:c3:4e:51:2f:c3:c4:65:65:c7:97:b5: + 1b:29:23:7a:c0:7b:fb:49:33:a0:a9:6a:b7:2f:f3:44:6b:5b: + 0c:2c:0d:75:f2:50:d5:82:ba:9a:ab:e0:89:0a:b6:b5:8a:5e: + 1a:67:ab:d9:a7:21:22:75:61:1e:d7:21:36:15:6a:da:a8:39: + 4d:95:50:2b:e6:ac:c4:f6:38:74:c9:c5:ac:ce:2f:b3:c8:d4: + ad:18:a7:93:d4:1a:be:c2:be:9e:39:e6:a7:b1:0e:93:d0:9e: + cf:b0:ac:53:7d:08:1f:9d:a5:98:2b:4e:f6:80:e4:df:ea:43: + a2:f9:64:bf:84:b2:ff:1c:93:36:60:74:08:4e:5b:d6:24:9a: + f8:ac:c7:81:f9:2a:a9:00:28:44:15:6a:31:b9:b5:08:89:c8: + 31:15:1e:8f:9d:2c:d0:e3:a8:32:2c:68:42:41:19:6c:43:8e: + 69:c0:44:01:ba:1c:c4:ea:f4:ff:c8:57:03:ba:df:3f:5e:a5: + 03:da:75:31:2e:07:67:a7:5c:02:55:c3:6f:8f:11:f5:8c:56: + a1:f7:4b:bb:46:d0:e5:ff:68:c1:77:3d:0d:35:12:f5:40:af: + cd:05:5c:53:74:ff:54:e0:c0:c6:10:5c:e8:33:06:0a:50:47: + 7e:71:3a:36:66:aa:f8:de:97:2a:ae:bf:8d:6d:d4:39:c4:fd: + b3:03:1d:a5:9c:47:39:8c:c0:b3:73:f8:3a:d6:34:ac:49:4f: + b3:87:74:11:20:8f:c0:aa:24:a7:30:20:0c:c0:d9:1c:44:ee: + ae:c8:b8:13:63:e5:f8:5e:8f:b0:5a:46:c5:83:3d:41:62:06: + e4:62:a6:0a:40:cc:8e:59:ad:8a:36:4e:20:e6:f2:32:04:6e: + ee:4e:7d:97:88:dc:ea:74:90:c4:ab:a8:b5:bc:6c:81:b1:64: + 77:a6:93:34:44:e4:60:38:b1:0c:2b:29:3a:4a:f7:17:d7:3a: + c8:42:7e:db:4d:5f:09:92:ae:6c:90:e1:7d:9f:96:9c:1a:82: + bd:45:02:76:29:62:e5:b9:14:53:01:53:c0:5a:d5:34:53:7a: + 25:49:3e:3d:db:19:7e:29:57:80:78:67:ea:21:3e:3d:59:36: + e0:8b:da:75:57:9b:c8:9d:a1:18:18:e2:5c:35:35:9e:62:2c: + f5:0f:c0:8f:55:16:a5:d4:9e:cd:0e:78:87:9d:53:d3:01:e1: + 18:61:36:1c:06:c3:3a:43:f3:8a:13:e6:4e:52:32:fd:46:21: + cd:62:18:1f:ae:f5:f2:1a:ea:7a:01:3b:a1:3f:1d:16:00:91: + 5e:94:78:f4:60:33:54:a9:fc:1c:0a:75:f9:17:aa:dd:12:91: + 66:4b:f0:d1:60:25:d4:06:d1:99:9c:c5:64:01:4b:ba:d9:66: + ba:9c:f7:68:75:fd:11:3a:eb:6e:fb:8f:a6:17:8a:cd:bc:1a: + 59:f9:a9:cd:33:db:7d:71:26:7d:c7:be:de:eb:2e:c0:7e:db: + 29:08:0e:82:63:1e:8c:8f:e6:21:1c:b1:49:13:9e:df:78:3b: + 68:01:17:0f:df:97:96:58:32:48:1e:5c:ff:fa:db:90:b5:05: + 84:68:fd:7c:c0:a5:35:d9:75:1e:ea:cc:25:25:3f:6e +-----BEGIN CERTIFICATE----- +MIIJGzCCBQOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5NDFaFw0zNjAzMTEyMzI5NDFaMIGzMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxLjAsBgNVBAMMJWFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20xNDAyBgkqhkiG9w0BCQEWJWFkbWluaXN0cmF0b3JAYWRkb20uc2Ft +YmEuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+ +kWTyGyvtm0C8DUYjSXcydP7LmkaGMx5Wvcja3eYqBzRhHPC4cSkkK5DzQ5lvafb/ +jbm3P/M2apmQkNaVY06IWtdBiX9zE2RJx95CZQhdygSyaDpAf2oF31YwL6wbiw/D +FTw4D5BQRAC7WUD20uhbcwMN9n04XS+Zww0TD3TQnu8ekkLERnzchX7pr5FOnV+C +r1hgGKWskW7dz6cyPNL06YG+gJ4Myh8avpjE/uYlwYn+FgowkNPU5a+JJGQS0E8Z +4huG+wapY9FHEIncK1Ik3GapVsLL9Ow1EvStXvz/humx+R+zzkT7vgSvjUKbVqUC +f8XPXyNBHGnuM5d6gVCLAgMBAAGjggIjMIICHzAJBgNVHRMEAjAAME8GA1UdHwRI +MEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1z +YW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNV +HQ8EBAMCBeAwVQYJYIZIAYb4QgENBEgWRlNtYXJ0IENhcmQgTG9naW4gQ2VydGlm +aWNhdGUgZm9yIGFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhhbXBsZS5jb20w +HQYDVR0OBBYEFDAQbh9+UjOMyIXlknRddn7pM1s2MB8GA1UdIwQYMBaAFKI+Aiqj +p005tAhNmcwMdTbqJ8M+MGcGA1UdEQRgMF6BJWFkbWluaXN0cmF0b3JAYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gNQYKKwYBBAGCNxQCA6AnDCVhZG1pbmlzdHJhdG9y +QGFkZG9tLnNhbWJhLmV4YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRw +Oi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5j +b20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcDAgYKKwYBBAGCNxQCAjANBgkq +hkiG9w0BAQsFAAOCBAEAUz5R0l0saSNb3QUaI/85XVRj5drhS2CMCXxOjtqKu2Nd +vC2g1M6e0s441zJnukqm0R3Ex1Domp5EVhqc9I+5jjmEIdsPYIpgtA9PPDWg0jc9 +iOgKGKenLRnjqtOOGI817z5KlcTTm/TPicJwuYxc74qeelZzE+uLt9nhiFvEYkdC +RY17Lc9xgxtInYSPZWaXYfz2MDToiCo0kUjcerdlvJyYAEznSf5NqVbqh9ZsRjny +mFtWFILynrit/Yk2SIdOXO8/4DX/cl9b4cL92W5AKzWtUAh0lIeJxM3Hq6cZTrry +HYMPsM+c5t9zNojPQpyjcicP979bzGvlIAO1Shzzfa6SQ6q7EwekOnc9NAEA8Ymq +6BsJe7iw4VQD/z2NvjW5E7JZWDJIk/jn1z1JcAFE5ishs3VJrkR6UBW4ZfPDSJbf +yNkq98Uqfixod68teBv8Gtj0i6aGNdLwh+nWMAp2Zfhx6YANHxaGiZKBNNm+m0El +7GWpClayA5FUAiGXmXRhjEou9NCxi/HmJlK89vLgvZZmIsNOUS/DxGVlx5e1Gykj +esB7+0kzoKlqty/zRGtbDCwNdfJQ1YK6mqvgiQq2tYpeGmer2achInVhHtchNhVq +2qg5TZVQK+asxPY4dMnFrM4vs8jUrRink9QavsK+njnmp7EOk9Cez7CsU30IH52l +mCtO9oDk3+pDovlkv4Sy/xyTNmB0CE5b1iSa+KzHgfkqqQAoRBVqMbm1CInIMRUe +j50s0OOoMixoQkEZbEOOacBEAbocxOr0/8hXA7rfP16lA9p1MS4HZ6dcAlXDb48R +9YxWofdLu0bQ5f9owXc9DTUS9UCvzQVcU3T/VODAxhBc6DMGClBHfnE6Nmaq+N6X +Kq6/jW3UOcT9swMdpZxHOYzAs3P4OtY0rElPs4d0ESCPwKokpzAgDMDZHETursi4 +E2Pl+F6PsFpGxYM9QWIG5GKmCkDMjlmtijZOIObyMgRu7k59l4jc6nSQxKuotbxs +gbFkd6aTNETkYDixDCspOkr3F9c6yEJ+201fCZKubJDhfZ+WnBqCvUUCdili5bkU +UwFTwFrVNFN6JUk+PdsZfilXgHhn6iE+PVk24IvadVebyJ2hGBjiXDU1nmIs9Q/A +j1UWpdSezQ54h51T0wHhGGE2HAbDOkPzihPmTlIy/UYhzWIYH6718hrqegE7oT8d +FgCRXpR49GAzVKn8HAp1+Req3RKRZkvw0WAl1AbRmZzFZAFLutlmupz3aHX9ETrr +bvuPpheKzbwaWfmpzTPbfXEmfce+3usuwH7bKQgOgmMejI/mIRyxSROe33g7aAEX +D9+XllgySB5c//rbkLUFhGj9fMClNdl1HurMJSU/bg== +-----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..fb3c34a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt @@ -0,0 +1,4 @@ +V 360311232844Z 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 360311232904Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360311232925Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=addc.addom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360311232941Z 03 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.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..9b973d4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old @@ -0,0 +1,3 @@ +V 360311232844Z 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 360311232904Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360311232925Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=addc.addom.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..930b870 --- /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----- +MIISljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI8gnWGjK+GVYCAggA +MBQGCCqGSIb3DQMHBAjV6Im8e0V05wSCElCDz2WaJB4sMLy3WQI/JoMnq+DDjyNC +7+9th9jeu0Nzcax9NqQ2pKWav2eIwhjS61AM7Zw4+SIqV6mJmuv1IVohHgxAx+nN +1Poq6bAbgbxk0uwS4nSYXQWOA6xhmjLuZcQcl8bZ6c50Vvc1GLkKiJ7T2x0xr2qt +pkw86WzbBtrUDbg5IHR3AsgTpyg1Lhs/E1ZCJ3Kd5qXpJwoejvjMCeCqroEzEfo0 +TzIRQS3R/hbnsAzwP03p4HyNs7rY8qGY0K+xv6fTHHiiw+0KbJK0w8KLi7ru0pp8 +YPTTSWBLd96ws0nlhY0aVQzDhlbXSXtqMSQNgZYln7CcH2R8dycwcjDhX0JsPAql +tIzvkl2goYU7jNI5QnpGPA9VH2U2ipMaEhiaY4yfDolnRaueo3YdmigFz7I4Tanx +kB3BaF0WrUkIk9oXXH2yIbRm6UAgYhGvNkTcifu6Iv+xfxn2JPulNGWcsJlVsRof +Hrdy3ZzcDp3bYDoA7gVWQgQKoz3ngIhrgH98zSiNCpKvjWXYx+oWYKHtxVFtFwij +Pc6+AUdTTjVfQsfNBkE9B2sjmvif6lnKWaMS349zodVCjWQrjsUITJV9Hbqv/8lw +GrCTFS4R1Wt+ABQDZXZDj4qXQ3Y8NhNI4Z/rkGN9rdaNJuDoyDYzm0tGvoRBP2uV +GJrAWKt6amx0oSI18L1cqm2hoY7wiZSYFqdXbZm5fbhoELfeak0tMPkHEXx1HtCu +cVQjcbHTakHcc1cW5TFRlmWZwar4RC//6YO5PENhMacPuW1ld0qF5AbwH303Gw1/ +k4+sYBe0IxiFQWnIFyfCoZI9swTojuUU/p+wxHjwCoxLoiYDN8EOCkHvgcgu7ddQ +WVHpWyhcNeKcYH71PvyPXjJufbaBouMHrGAodAQXYuRZCwpXvfRG6rqs3yPYkFYn +dBRdUKDIj2KBLg5n2ssy7ENpRcygUwfgK4H7Qn1yHmDMuq9VjgWNSn1ufCQa+M2L +CAOMrzX6uRuzw04K2vvv9xhC/Vrr+ISbOL9CDJyvyD4Xzk09JXV9CL8zTDzlJf6s +DnGhd4F/ejKn8MiOTOYuKugqoFDIw0D3WtbiAHYkXyB1Q13JXjc+N5E74xtGPVUW +IezrC9yEnQWrrtCBFbAtAKehphfZrvseAB4tBSyToio9wXBVKupa/ghoKEuBIQtE +OAsBY5Vd8JwZyaLFLBzkPfDqZE6mNSQuSm/x4HjciToQBYicNoGApRH0qneHXdUU +YUA5QeRp/HRL+yawNPq47HgvmbJh1cpyOsBOGjwqo0Tf0Q6WcqhrZmceHJbpxFeR +ySDEsuqdSp0prk5CCJ6HO3gsrE6DFLmLNNkZACycIndKO/I98ORY4dmR+zGUoMTS +Y5Gqpxhuh2LleiquFv3c/mrXVRA4Vl6F43H8isv+7/avhoSkBdoVi17wCR3pdk9F +naPHRqv6O+VT82S8BqYLR0xk3or+0wzFuaGkh6zPjlYr+DGrTr9qSW34+hJAUsSh +pcmePlS4A08sM2aZ/z4NSBzGrtSAI0KaeZOZMEyHL7MwZGHvQYz4WbekZJMZR33L +51ia/VkA2rMw6fgV/HYA3Zwd3NSTQ9jvwP8oAYmjrIbkApQTZQdbGQIh+8kcA4QE +3seLJAQQ3/reJvkc4jzwbF+A6K53iu23s/FhP89fK93xz+2zxt4bfMb0RQYWSb4u +aMsTHMC+Aenx93KrVYHvBi/O3PRxPUZQaPPQ+GQVerpmqhnrAtPh8xMjtxRpF3mI +Hff9RJTCi9jAQWDYAuuWNo1nFi4q6tQU8vCX2T5o+AsvwIrRDxz9E3ELqwPD1Zl8 +YRSBVgQPpy9xS/eHCgBOa7Lch2/gmew0pE6JgHmGSAZbZGVa7QxIsWvrgvNwuDmQ +pV9xVWttK5dup1un9Z9fiuozO+Iu6a8x0ECCxsUEO2C9bh+Qt1EzjirVy+1WWnKc +fW2XrFHwQMqIMTjM8JOuWgL2R+YjhFFge0h8CGiXk4f6mnuuGfHhP858Mmxuw0rZ +bdwwyBq1eiXPrkxm88yo8FYmLXCQExlyFsLbFZ+kJVhZbxeP9siedP14Tgqy2FC0 +2A+tcmypVLu5Vthu66I3wUvmgi9hucwe/s8qCRQwYciN1wzHH6f+uDz//kQIgA75 +AuNAHJYV3uWCKUESpnDL/9W2O6FvWY/j24QG0AkXsl+peovo8CucGUZxphLfsua6 +4x2WrTLehObG+G54CHdOLTrFQDIDRL9Kvmrw8/TGkXEles+WNnB8HxiUQKokA3ld +fhXy+e/yjaGzwoNY84CV1WXowWJ2vA1Z9gdr1mFpl2uJm1s+RRquuyRI/yXBvGQ4 +x0pPSe8vbQ2OlCzuVMjFpG4dx4oqBwXUR69YigpsVi1A3n23qAPUSjJBflgPLWdG +x/T+NiQ9TVhFKHqkgiL7e5s5VWaYREXjfDeiVowst/7vJdX3RugJTlVfnmPJ/pJZ +JnObpWxm7jmJu72fek0bmNaOMvMf4YVB5G/z2gQ0bpwSbl91kxJvTJ6DG9Kb10h9 +ekfffdFdiZHD5V7BUibmt3aYAZSPRG3Scurrv/kKzkH1/cEMnMDb2ppxsfT+LrLu +92P/7sCxqGJtk6JNiV9MhY3c9gBHsWTIbcJG/wZHzXhwZphoPyFf21I3x11jzQ86 +D3WTC4UQ8ez+PgMvl1ifP0wC0e7ANs8GsDZg9GEI+tBxx4GsAP1dcpr8c+v/wEDF +/a2fXqtymxWUDc4qCcrE5Az/U7k4tMSIvOiH/QVBsYOybcuvHd4E+Yrx7bXapk0V +KIgFQm8kVftR32h7KDx55Vcv5a11dEp4TUF1k1MH36GVxMzfqQnnTnwDs67Q2FCs +YAGt9jF0imAU3KZUwHbJvPYpjNEV9g3pkd4shyB7ZqNXjOFG+rU7F6xOVcf33lBu +yP653eMJjLR7hKrQ1UiWhgosc9zSUhl+Er6EqV0OoNtXzDI0uHsCzJ4BuLeKzOga +wXS8JjzHR9Qb+Nf0OljkNgmfCUBk7BDGuvt6ZQwP4pift9+YKJQ9dTLz0QZxeEoA +Ky9BOkhF4Q9cYACZiSnZGWq5Y+5I+zIPr1LxGfu8gOqhkvne5wAHmC97YbSXaHXI +rHvFhAzbwdsX2Crgvgd+feIP3LU5T7YhGW3nZMbigaDsBOTUQQW0f8tXygc1QjzT +dV/mbpoIDz/39PIYKC0BlQQ2S3clfr8SoRWR0bKEypPd7CZXAH4zAdPjKJih3yV/ +SqWxvMKuZFpSu3BJTcrXvN7nvKBzW17VGI0eSE9+SwrsMHZVUjXUolarSYczdC6v +QKkNV7+Uu04GCNivnE6sYs3M0n5ZSvvBha1/8kUDIi1k6QhvtEauA3WuoMp8/iU2 +mlvT5Kev96glUo1SdCQRLZFh1HXtvKgYiqEZ8FVW3kHMrvDF3Nxh4XDGvuQ6nO8O +w8TfE56kZVot8KTcYkOBDiyVX/qGLYNNvW2WHm+zygHKVQRkxnL5Y1/GOU10Wr2i +7ynFFYyjHwj5vkKsqLytQmuIxig2L8eW2WSx74WyWJPLbeHUSVweHjO9DTh9TgUZ +QEqPRuhTJMXq6VYpMWq9CUYAF/nal1vTab3Q7BbKcDFma89d4m+yv6FTnOnswS5q +r22NvQwl+09grdVYaL14a+BtkkCYH+SL30B54Vws5W7JS+34OSkMzDZtwwuGUqC3 +P61oG3jsGyJt6knWTgnp83GHKo1jsrP6IooatP4BaPf7PmKcftPuzies10G7MGHm +h7gAAYVrAW9lDvKKYc7UC/rgf4kJpkqcM6d3eU+9+ccVfmCIbHN4dEE/+VGKMHAA +qKQS9j5dyoCZH14PXAotyHCmvst08pkKG9Oj7VPG/+rX6tBD3y1LOlMbMKet9Owy +WA0yTBYXHxr22zcJD6k/7AgkBKbdkJPMR+X9IyINQojpvXJZIKZkVhoSCa4d9DYF +2xLKo3W3Mqoi3U7sQ42mQsdaozlql+CBYqd3wq1bkGyyqZ4zgm+D9VI+mZ6hZGt/ +77Qlp2j8JeCdsPDy+igzCpz6fkVaQum5fZlg1II5uYR+4EOvn33LbCT+kcqp+YC8 +m32umo2Eg1In2xgfqCpPTEDIjLSxgvC+NtJ/CmGVo6gYebyFLXZlnDbzAhxaOIDO +p59Tm9K3+wL31FnQOlXtkO9VihN9k5W1qR/MjPH3LaWCFSgMjed3LlOPEFBYmzeV +oz1oBZcJGVA0aEMA/Oh8hqMjVjz3vaIQfCuJ6eTLob7RDfmnhVaCPHMT9sJDCqKU +j4r1P0SRj+SRt+tO3kPD3dz8ejXRUb/lTLTSx3fQK0sB7XWu/LJpP3jGgoES6W/t +Fj6Eai8LXjqr+1rMnc0NKCLlWZakYp8snikOI5b/+t4WsOwhKVFiMbMdtkf5u7J8 +yKLPpkUS/YBxk4Uhv7srkITCzGpE9keV9umQImwPKAtb25DcAXPp5IXuJViHtu6Y +rKYYlmWgjobgCDvP7NFGKv+7hszZpWmSg/AS13QtPUZ9Fn9mM/Af8Swu5pp2HGUp +Zme8CjltYjtAk5ChNL+9C5AlVEZoD0x1ag16Gp09ODzEjQ0JebojJuw1X4+q3syD +BodCMFhwiO2nsnHrr5PALdoAy4YYmQop31HwjhsDShCuSc+8kWnvWRlzyVSI8/vV +jD8TV68QBeKyU8PDhC2Bmogy/xVYAJthgfK9LYD619Xz8+0h0cTFSwK/WAO4C38l +WV9SASyAj0O+JMUWheq/Qh4gP2NRDL2fyMFpf8uflwTjmg3Mu39oqcI3SQYk6ViI +Mq+ClfbU1hYZrakAN8pt8HUM1XbXJRDXnE3hmrTiU+jdNucuunHDjkf9ZaRNgBWW +yV309Ua9O91EEG0iGjkQ9Sy3ChscBolfvMpayzGtQRFDYWDX6UZnV5zI4ir21ikQ +A04zphPlCdOWelU8Qs8GuYX8HeXCzc1hUKffARtY2DQqiQ6lmh4YXHM0ILK/kDYo +ftmcBWpAZEntVRlnrCbPz29cwltn6DHQC6HWKGQyRxafp8fINUOINNMui+W4UR5f +tNn9IederuOpDvgYDMAzEt59BT8QgRggJl+hlXjRxOXANLTOHWqWKejk8+LAAH3+ +DjBFTX84cfrbbLgrK57E9afEN84KM2EJCCGFXYvc5qBPgrS9oYQwIErvpy89k8fW +bR7pU41CrHYZG2am774H80FCfofzzAFoJ2pZdPF2Lo95cLxNENy8RjYfePJR2tcf +vlqNynUvBjabCW6XhtmRK8/fsakfqfaQkZfpHqtA+qAweLh1bcirz3rBeNvwsO3G +JBxUgNkMel2F78Lg/EfMQL/hxeajDV+LilJkeZeRbHNL18M8dzzJaZkBm2oGylc5 +AS5r4r1EvSINjf1uXDA9CMBNydf6n62VPnDKrk1WK2R+pzFeeVvRayx7PVWacP3N +JnKPY+t2eIq5JlNCfIHcL8MDHaau4ck/f2lnUJm1OfqhdfAf6wsf+XuEhfkzqsV/ +gRjrumWsuMs7B15eIZNoyP+x9XPfTXvKXtNpWaUbq2iC/rxgMzqzDN0XvHSr8eTL +I5sg9nlAiezZYcDsGcjpK5EUY3/3zmZtO+OvXg2kA0dQx8QWg51B8MI/f9EprAAp +O4ypSjvH+Hthnq4Cr1dXtJzOJru3wz0N37Hy/EhMrDYP3XJUjkYJqTrxM8dsT7TD +RwvRjbJaZYi1mmIakXbHAhEAcIg/Z7hueIYHrOzYaW6akPdxy0yS252mZ83KtUC9 +oxNzYQdMi43bxbWgcTu5RxGPZ99IYUdKziBJiJlOpWFSzPwKcD0bkHeDAbWZ4Aex +msyzLubI3nPnuszVWgG8cUP1w1HbCC5KAWIOSoRYS6SzcirAZAXuqvoBGGSCiKdJ +kMIXRjSHgTfNPE0zSkuoYognqtPBQB+tCmEYUwmIidzp7iVe3muLJj1qHRcUNx1g +XzbpRMOGRUSgMJJlcba5BRNmFnSEjgnFx+v/NEiMhjacOiDDypi58eYPvgLZ0v8I +UlI0napiKxX1XS9XZE7SI8xXn5zte2de36xAfZTm1gMEYG/sOUndKUUrmsG4ag+u +ttyW6veD/LMXzYX/vP6zBe8l2RkZp15xMPMSTovij4ELLOAsWmAB8MAQ7p2TThOa +gmFx0AnWZ55GAXcM6/2dK54ZQjm12KgRz2uZD6RpHgxDlErzHBVY8VFWPHx4b60M ++BVqk94uAsprvWczcuowZwF41MsJ7wm3a1Jtd104mx1/0GokF6EG+NjpSFvHiDN8 +JVlZ24lBIBv/7Q== +-----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..d6a1577 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIILPDCCBySgAwIBAgIJAM6BrnFPnFmXMA0GCSqGSIb3DQEBCwUAMIHGMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKU2FtYmFTdGF0ZTESMBAGA1UEBwwJU2FtYmFDaXR5 +MRkwFwYDVQQKDBBTYW1iYVNlbGZUZXN0aW5nMRowGAYDVQQLDBFDQSBBZG1pbmlz +dHJhdGlvbjEgMB4GA1UEAwwXQ0Egb2Ygc2FtYmEuZXhhbXBsZS5jb20xNTAzBgkq +hkiG9w0BCQEWJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29t +MB4XDTE2MDMxNjIzMjgzMVoXDTM2MDMxMTIzMjgzMVowgcYxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApTYW1iYVN0YXRlMRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNV +BAoMEFNhbWJhU2VsZlRlc3RpbmcxGjAYBgNVBAsMEUNBIEFkbWluaXN0cmF0aW9u +MSAwHgYDVQQDDBdDQSBvZiBzYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJ +ARYmY2Etc2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggQiMA0G +CSqGSIb3DQEBAQUAA4IEDwAwggQKAoIEAQC3qPlXMRW0bS5QonEW4MMRiZlgWRc3 +DLtA1hSg0a0POKXIBTTb26kVWwJkdLdLPf9POdAWa+PtEDcgiTKeNeh3hdCaKQiR +LGtmR2Ncy5jcLyAaJPHL3ZrYCzKPyfhVLtZqrS+5CmJRs1Ar1zEpRPIcT0Qdb6Jp +gu43msIQnULTZPatF4Oi847jb/JIXnTYxto7cuk1I/2VFJ8OD2cYypNbCkthwAga +ftJ0GNsM2Ii0q5aFnrHpCh/UhvQ1XGZfGVgBRrFjQQ75GlSCFXuwLLiyXwpj6c/p +QPTQuWLe+21rnizpxmXBvP6d2LaX2Vsq/XP9iVN/jVigY4swgk61Z6XFkmsVJErB ++JEOrjdcO0kkkqlSY0aqqpoXgtV8lNxTeKrNllRmW/i/Wz174PPdvR6QQFMG0X/W +NOtqwBGZqiafHlu1xrtC/RnzC2S3ygKssP9463bO8IDvhv2I3QnbsuQdKhQSE5rr +VDJcSI1DHe+tGsko4QA2RBFvgO8+877K9qnBXpnVdYrnEk4UlZVk8L7TIngbA7RR +bZ7j1mE28PIzcGN2ps1IY80CbO6V+60YegT2F7smjRAS9YJyfqM0fs4yoRuT5Day +BHN9asy//gEVfebXytzfvZvh0Y+XTlxsXbZ24IsaW1IhsLNvny9BX2Ygrv5wnf7i +zvEGf4rnO4v+d4mn2HrkkYLfIJe/iQAY3c8uABbEZgzrTHqC+oyRE4MQUtjQR+10 +8IOvbVeU716Q3SxyiGlq0Dici84J2izArVuZBGVoS2pytwbNFU7eL5SeirL1Xy/E +3siV+y6Oxr3sigrAmMQbzr0YQT7yDjVaP61ct8krc5N4Z95SciIlvmEIzKkV8kql +Uiom+XWP8aRnZmiuvfGnvEyB67MmggEkG1LGIhsp+ZsnTfo4nU716Djlq5pOZHY2 +VTiOLET7Omo/a+RmHwrog4hRm2BYifyt3RGmzoWF77klbow13ov0UrsTF7Sw6Uft +EnaklsZU9cfFyNLsDjEwRTWQ4QMdq3dI6WSOYN9EWFtxLGY8FypH2QkTOOPsqgXY +/SxZUBqa3r+MrGRJ2NCF6kr1/yanLicVzNSR4tymEFDfF2FJVOtQqbO370JGIrJE +3kq89zUUMH9xNP6IJu+N11Xe63028KlJomWq6my8AUk7a0sk8z75FIa5PvUSYhQ8 +gbTYXM2AyYLTYxkLt+OzLLyvQI1l6KX3PWLaa94lqxkjGQWIt/ViL1OTineiTbYJ +YR2SB4R3S3Y6N3AAT6l7D1/lxThrqzmWAAkbElBTZZrXGybjL3I9q8lzVt98X9HY +LrVClydpw42drOIX5PQ68+s8lYNBA1/uYim3IgTjDPIqsNIkBOjreYnPAgMBAAGj +ggEpMIIBJTAdBgNVHQ4EFgQUoj4CKqOnTTm0CE2ZzAx1Nuonwz4wHwYDVR0jBBgw +FoAUoj4CKqOnTTm0CE2ZzAx1Nuonwz4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3dy5zYW1iYS5leGFtcGxlLmNv +bS9jcmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNybC5jcmwwEQYJYIZIAYb4QgEB +BAQDAgEGMDEGA1UdEQQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4 +YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJh +LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IEAQCa8zKgFnArq4GM+OJfiK95 +fYuTgbO+PaH19GWCyNkNCrtasxt6BIdxKYW+rC6VxXBRXSvaPLbiRCDhD9hL03IR +daQ+R9JanYzoloN7m5q+mSdJpfsIfdlvqKr4hyti6sfC3jnQC1Tp696KrW1P1Ymi +kOOxksmngZzTYr2q+JhydYsNAdpxeAIAILDZI0F4VzOVPXRy2+Gop+lwWYvtRjjn +Z8HemYJ8jIGUlldMVInd5+XmS4/+kFLB6Ly+JAoqC9PBUfWiwXIFIPOIM5ia4sNH +ZeViTG5Kw7MO/esPs7J8VKB6La4v+CYCT4ngT0ekRLXhRi/Dwa8Ok+hFmRtrikvU +TEqZPOQT3sRqGdlongAZ1kmCkU4n4RhwbMh6WitDKJf7YToMsyrm6LQvGo4Bf1Ns +mqnY93OSTyOblNGYwq45BMQbGhW21uW93SQg938ojuw4366KeGnHCD3zvyfWh6Yh +duAWNQb8TNDqhik0lLNVMyrEPpk0f24XrVC2LBia3Z4hQvep/pI8tg1656XbI6/J +GubM9KW6o0ndZLnMzFFga3JqztzL/Ooqu+yVaA9q89GlN2zv3hafXaC/AChG1b8k +Esx37mA68jVaTh/1hX8T2hz14EV3LUB2N21W228HuUhZ33PEcR10XMJNJsOOwHUn +5I902kznpUs3VTVvbWBsEfhZAD9uns07Z5b0b8UN3fZyNmXeE7gObt10obSFzoPt +yhnTCULNJ0K3cwuQDAC4Y6HQK5hvLBazdvnYT5rZqGneG9ALdQqr9if2gZFeUPQv +a63VZFwfyx5wQlFwLVbaH3tTl1dweJkZYjUC3BL1rngHNNvD1t//ERXqL2ngOe4C +1xNNOBAC2Q4upBYAuH+zoT8KMRCxEh22SPNGrlmN+9MwY+ceP1Dxa97vY9FtSMIB +dYEvoI8TyFhAjC6t4HOUxT4lvpc7Hma+1AlG5x/aSCY2A9ONdLLo5DyXSuLFHgtc +gh0dJygZ85sd90k8hl+73muHHofG6HuzMNaQhN8sFoaiedhIHa5+Lv6FVyd7Y0dy +QVHiPVcf5KG3o0y6OnXdfsGNUsak01fqQhIewVghdTU9liGW8PH1UVWO310q1K46 +U46Hp/JBamvvW5B2ZSg8Dj4arS7/TxxNqbIPAtNxtN7Hwg1dubGWMatCv2A8Cx29 +oWIeUG2HKY4XvbdOnpWvCGx+sUqBiK6Sf5zvJF+UigmZPKrZgbrFWSC1tf0RYn9d +IyH4JGo4uP5OCxBWFvtj2d51qJJvdnlegKkPd9E0vzIZRHJsSoAx54MmqRZQkPzV +56iQXA4iTfhv2sF7Uer379OV//ML5xIjsV+IkJepTUtAgimqkKKRktCPfFT6mOtw +-----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..73b10cb --- /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 +c2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20XDTE2MDMxNjIzMjgz +NFoXDTM2MDMxMTIzMjgzNFqgYjBgMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1w +bGUuY29tQHNhbWJhLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhN +mcwMdTbqJ8M+MAoGA1UdFAQDAgEAMA0GCSqGSIb3DQEBCwUAA4IEAQA13bwPRi4+ +CaG7MSTVA4Z4JZIU1CQagBJCah0XPXl+xIs/aWCxS3jdFnCUNLOxrKk5Onrsv0z7 +YWQJHsH2Lu0I38SPyWhftmhrqn74QQyfbGMGblDufbfJsHNyeME2z0ZtCoHUgaz2 +kMatR7ys6uvOY4Moghr/xNK2QYSzCFsetF/5ua2h547GK+VMqb4wH14WIx0ljVO0 +knpqT+uX5b+3KX2QcUFDIzRJZWBj0gDWzNxL5PSbZbcxtpUpUIgbFHD8HGRAu3R3 +MCJE3mKuKyaRKqLaF/qOWnskkHnIV3gObeKIgWFNLiyQKUAvu0m3QO7b5zqUeOep +JMy/3dwixIoDU5QU1O7TAvJQhVscjt0baQaklqlI7jKwdd1xk6brIXKqLa55ALd2 +RIs7I01X/ZyukrY+NbvQOGh/Weqnxe2IM91DkVQGYNxaa52Fqlrop3U4qdZRgtuL +Ye8RP3IPcVEoH/t/fW6IBTEN1uG9vVvyUUW2H4lI44yeNt2Pd+6qXXFyKZ9pfctx +7zCOdo9/ikSzCddLFKL6bgJ4vxNuSt+4csq79BytK+69SrsGP/R87154uqA8nMPm +TXpFhL3YBqOklphc1JVCccTp/824vkrgrEOSB7uIZOtdTpTuRabo6R5yv2pjC5GR +om3sI8c7xKeUUsfxDF2jt4vJHlKgYEx8YgbAdKq3As0fkpsY0IcMSNR1KMq8H4ia +0eNWy1YmkvcZzZTL1GBtL1XNPHkvmuBHV2rglBg7PAklr/9WX7IM6AZh2WKP0Spe +ih1C7YlVzCgQgOaGEe28jegtgkr3I84j34GJmK5WO5fa7/au8wzUDEyGTJE1wZxv +k1s4TKiNuCSiH26qVUKfwpzrqhiW/ElAeKsXxjg/V7anhPbQsd+sz4RNFi9RldlY +tdXkPmKBTvupJkVa3ZUxl8gyXNW8t8bSpW2kYFOorxnEkvhwIxMhwSC9pyEyNFXa +sxsMZ/BcvFBcJYORhxMYVNksCriyWRuYsNORC8s9wnygbQ2n3TuoloZ9rR8mc6XK +3EgLwhOyENWToRurBdN7Vq6BuNtnl5P/Rd2WBTy62EcXkrnJCCUK4ouP3o0MRt/V +LdQiCVf9nnHdkiWMQMH4pkgrEJb70IvS/MAAee3SFuMNa72zgD9Pgk4NX6upqt8s +3+wo0gqmg1gJ9RQUyk/TuYMgdBVg68B6G1C8RifxffhZMj/rOm1xdXXwRfmDyrHZ +aaNZv3VHTEIJjSCHMkDV7SD9d36gdX0F1lLP5HIu0QTWJeyE/fFTD+hQMY5Ryk+c +nzW2ZYuTp14xWD3NTQzq/NS+BPpOcAtL3hSpyvP4UkIFGZc7OUPPBBwR2xTVLQfZ +YqKrAHJKgPXZ +-----END X509 CRL----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem new file mode 100644 index 0000000..7486a63 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem @@ -0,0 +1,169 @@ +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 16 23:29:41 2016 GMT + Not After : Mar 11 23:29:41 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:91:64:f2:1b:2b:ed:9b:40:bc:0d:46:23:49: + 77:32:74:fe:cb:9a:46:86:33:1e:56:bd:c8:da:dd: + e6:2a:07:34:61:1c:f0:b8:71:29:24:2b:90:f3:43: + 99:6f:69:f6:ff:8d:b9:b7:3f:f3:36:6a:99:90:90: + d6:95:63:4e:88:5a:d7:41:89:7f:73:13:64:49:c7: + de:42:65:08:5d:ca:04:b2:68:3a:40:7f:6a:05:df: + 56:30:2f:ac:1b:8b:0f:c3:15:3c:38:0f:90:50:44: + 00:bb:59:40:f6:d2:e8:5b:73:03:0d:f6:7d:38:5d: + 2f:99:c3:0d:13:0f:74:d0:9e:ef:1e:92:42:c4:46: + 7c:dc:85:7e:e9:af:91:4e:9d:5f:82:af:58:60:18: + a5:ac:91:6e:dd:cf:a7:32:3c:d2:f4:e9:81:be:80: + 9e:0c:ca:1f:1a:be:98:c4:fe:e6:25:c1:89:fe:16: + 0a:30:90:d3:d4:e5:af:89:24:64:12:d0:4f:19:e2: + 1b:86:fb:06:a9:63:d1:47:10:89:dc:2b:52:24:dc: + 66:a9:56:c2:cb:f4:ec:35:12:f4:ad:5e:fc:ff:86: + e9:b1:f9:1f:b3:ce:44:fb:be:04:af:8d:42:9b:56: + a5:02:7f:c5:cf:5f:23:41:1c:69:ee:33:97:7a:81: + 50:8b + 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@addom.samba.example.com + X509v3 Subject Key Identifier: + 30:10:6E:1F:7E:52:33:8C:C8:85:E5:92:74:5D:76:7E:E9:33:5B:36 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@addom.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 + 53:3e:51:d2:5d:2c:69:23:5b:dd:05:1a:23:ff:39:5d:54:63: + e5:da:e1:4b:60:8c:09:7c:4e:8e:da:8a:bb:63:5d:bc:2d:a0: + d4:ce:9e:d2:ce:38:d7:32:67:ba:4a:a6:d1:1d:c4:c7:50:e8: + 9a:9e:44:56:1a:9c:f4:8f:b9:8e:39:84:21:db:0f:60:8a:60: + b4:0f:4f:3c:35:a0:d2:37:3d:88:e8:0a:18:a7:a7:2d:19:e3: + aa:d3:8e:18:8f:35:ef:3e:4a:95:c4:d3:9b:f4:cf:89:c2:70: + b9:8c:5c:ef:8a:9e:7a:56:73:13:eb:8b:b7:d9:e1:88:5b:c4: + 62:47:42:45:8d:7b:2d:cf:71:83:1b:48:9d:84:8f:65:66:97: + 61:fc:f6:30:34:e8:88:2a:34:91:48:dc:7a:b7:65:bc:9c:98: + 00:4c:e7:49:fe:4d:a9:56:ea:87:d6:6c:46:39:f2:98:5b:56: + 14:82:f2:9e:b8:ad:fd:89:36:48:87:4e:5c:ef:3f:e0:35:ff: + 72:5f:5b:e1:c2:fd:d9:6e:40:2b:35:ad:50:08:74:94:87:89: + c4:cd:c7:ab:a7:19:4e:ba:f2:1d:83:0f:b0:cf:9c:e6:df:73: + 36:88:cf:42:9c:a3:72:27:0f:f7:bf:5b:cc:6b:e5:20:03:b5: + 4a:1c:f3:7d:ae:92:43:aa:bb:13:07:a4:3a:77:3d:34:01:00: + f1:89:aa:e8:1b:09:7b:b8:b0:e1:54:03:ff:3d:8d:be:35:b9: + 13:b2:59:58:32:48:93:f8:e7:d7:3d:49:70:01:44:e6:2b:21: + b3:75:49:ae:44:7a:50:15:b8:65:f3:c3:48:96:df:c8:d9:2a: + f7:c5:2a:7e:2c:68:77:af:2d:78:1b:fc:1a:d8:f4:8b:a6:86: + 35:d2:f0:87:e9:d6:30:0a:76:65:f8:71:e9:80:0d:1f:16:86: + 89:92:81:34:d9:be:9b:41:25:ec:65:a9:0a:56:b2:03:91:54: + 02:21:97:99:74:61:8c:4a:2e:f4:d0:b1:8b:f1:e6:26:52:bc: + f6:f2:e0:bd:96:66:22:c3:4e:51:2f:c3:c4:65:65:c7:97:b5: + 1b:29:23:7a:c0:7b:fb:49:33:a0:a9:6a:b7:2f:f3:44:6b:5b: + 0c:2c:0d:75:f2:50:d5:82:ba:9a:ab:e0:89:0a:b6:b5:8a:5e: + 1a:67:ab:d9:a7:21:22:75:61:1e:d7:21:36:15:6a:da:a8:39: + 4d:95:50:2b:e6:ac:c4:f6:38:74:c9:c5:ac:ce:2f:b3:c8:d4: + ad:18:a7:93:d4:1a:be:c2:be:9e:39:e6:a7:b1:0e:93:d0:9e: + cf:b0:ac:53:7d:08:1f:9d:a5:98:2b:4e:f6:80:e4:df:ea:43: + a2:f9:64:bf:84:b2:ff:1c:93:36:60:74:08:4e:5b:d6:24:9a: + f8:ac:c7:81:f9:2a:a9:00:28:44:15:6a:31:b9:b5:08:89:c8: + 31:15:1e:8f:9d:2c:d0:e3:a8:32:2c:68:42:41:19:6c:43:8e: + 69:c0:44:01:ba:1c:c4:ea:f4:ff:c8:57:03:ba:df:3f:5e:a5: + 03:da:75:31:2e:07:67:a7:5c:02:55:c3:6f:8f:11:f5:8c:56: + a1:f7:4b:bb:46:d0:e5:ff:68:c1:77:3d:0d:35:12:f5:40:af: + cd:05:5c:53:74:ff:54:e0:c0:c6:10:5c:e8:33:06:0a:50:47: + 7e:71:3a:36:66:aa:f8:de:97:2a:ae:bf:8d:6d:d4:39:c4:fd: + b3:03:1d:a5:9c:47:39:8c:c0:b3:73:f8:3a:d6:34:ac:49:4f: + b3:87:74:11:20:8f:c0:aa:24:a7:30:20:0c:c0:d9:1c:44:ee: + ae:c8:b8:13:63:e5:f8:5e:8f:b0:5a:46:c5:83:3d:41:62:06: + e4:62:a6:0a:40:cc:8e:59:ad:8a:36:4e:20:e6:f2:32:04:6e: + ee:4e:7d:97:88:dc:ea:74:90:c4:ab:a8:b5:bc:6c:81:b1:64: + 77:a6:93:34:44:e4:60:38:b1:0c:2b:29:3a:4a:f7:17:d7:3a: + c8:42:7e:db:4d:5f:09:92:ae:6c:90:e1:7d:9f:96:9c:1a:82: + bd:45:02:76:29:62:e5:b9:14:53:01:53:c0:5a:d5:34:53:7a: + 25:49:3e:3d:db:19:7e:29:57:80:78:67:ea:21:3e:3d:59:36: + e0:8b:da:75:57:9b:c8:9d:a1:18:18:e2:5c:35:35:9e:62:2c: + f5:0f:c0:8f:55:16:a5:d4:9e:cd:0e:78:87:9d:53:d3:01:e1: + 18:61:36:1c:06:c3:3a:43:f3:8a:13:e6:4e:52:32:fd:46:21: + cd:62:18:1f:ae:f5:f2:1a:ea:7a:01:3b:a1:3f:1d:16:00:91: + 5e:94:78:f4:60:33:54:a9:fc:1c:0a:75:f9:17:aa:dd:12:91: + 66:4b:f0:d1:60:25:d4:06:d1:99:9c:c5:64:01:4b:ba:d9:66: + ba:9c:f7:68:75:fd:11:3a:eb:6e:fb:8f:a6:17:8a:cd:bc:1a: + 59:f9:a9:cd:33:db:7d:71:26:7d:c7:be:de:eb:2e:c0:7e:db: + 29:08:0e:82:63:1e:8c:8f:e6:21:1c:b1:49:13:9e:df:78:3b: + 68:01:17:0f:df:97:96:58:32:48:1e:5c:ff:fa:db:90:b5:05: + 84:68:fd:7c:c0:a5:35:d9:75:1e:ea:cc:25:25:3f:6e +-----BEGIN CERTIFICATE----- +MIIJGzCCBQOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5NDFaFw0zNjAzMTEyMzI5NDFaMIGzMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxLjAsBgNVBAMMJWFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20xNDAyBgkqhkiG9w0BCQEWJWFkbWluaXN0cmF0b3JAYWRkb20uc2Ft +YmEuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+ +kWTyGyvtm0C8DUYjSXcydP7LmkaGMx5Wvcja3eYqBzRhHPC4cSkkK5DzQ5lvafb/ +jbm3P/M2apmQkNaVY06IWtdBiX9zE2RJx95CZQhdygSyaDpAf2oF31YwL6wbiw/D +FTw4D5BQRAC7WUD20uhbcwMN9n04XS+Zww0TD3TQnu8ekkLERnzchX7pr5FOnV+C +r1hgGKWskW7dz6cyPNL06YG+gJ4Myh8avpjE/uYlwYn+FgowkNPU5a+JJGQS0E8Z +4huG+wapY9FHEIncK1Ik3GapVsLL9Ow1EvStXvz/humx+R+zzkT7vgSvjUKbVqUC +f8XPXyNBHGnuM5d6gVCLAgMBAAGjggIjMIICHzAJBgNVHRMEAjAAME8GA1UdHwRI +MEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1z +YW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNV +HQ8EBAMCBeAwVQYJYIZIAYb4QgENBEgWRlNtYXJ0IENhcmQgTG9naW4gQ2VydGlm +aWNhdGUgZm9yIGFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhhbXBsZS5jb20w +HQYDVR0OBBYEFDAQbh9+UjOMyIXlknRddn7pM1s2MB8GA1UdIwQYMBaAFKI+Aiqj +p005tAhNmcwMdTbqJ8M+MGcGA1UdEQRgMF6BJWFkbWluaXN0cmF0b3JAYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gNQYKKwYBBAGCNxQCA6AnDCVhZG1pbmlzdHJhdG9y +QGFkZG9tLnNhbWJhLmV4YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRw +Oi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5j +b20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcDAgYKKwYBBAGCNxQCAjANBgkq +hkiG9w0BAQsFAAOCBAEAUz5R0l0saSNb3QUaI/85XVRj5drhS2CMCXxOjtqKu2Nd +vC2g1M6e0s441zJnukqm0R3Ex1Domp5EVhqc9I+5jjmEIdsPYIpgtA9PPDWg0jc9 +iOgKGKenLRnjqtOOGI817z5KlcTTm/TPicJwuYxc74qeelZzE+uLt9nhiFvEYkdC +RY17Lc9xgxtInYSPZWaXYfz2MDToiCo0kUjcerdlvJyYAEznSf5NqVbqh9ZsRjny +mFtWFILynrit/Yk2SIdOXO8/4DX/cl9b4cL92W5AKzWtUAh0lIeJxM3Hq6cZTrry +HYMPsM+c5t9zNojPQpyjcicP979bzGvlIAO1Shzzfa6SQ6q7EwekOnc9NAEA8Ymq +6BsJe7iw4VQD/z2NvjW5E7JZWDJIk/jn1z1JcAFE5ishs3VJrkR6UBW4ZfPDSJbf +yNkq98Uqfixod68teBv8Gtj0i6aGNdLwh+nWMAp2Zfhx6YANHxaGiZKBNNm+m0El +7GWpClayA5FUAiGXmXRhjEou9NCxi/HmJlK89vLgvZZmIsNOUS/DxGVlx5e1Gykj +esB7+0kzoKlqty/zRGtbDCwNdfJQ1YK6mqvgiQq2tYpeGmer2achInVhHtchNhVq +2qg5TZVQK+asxPY4dMnFrM4vs8jUrRink9QavsK+njnmp7EOk9Cez7CsU30IH52l +mCtO9oDk3+pDovlkv4Sy/xyTNmB0CE5b1iSa+KzHgfkqqQAoRBVqMbm1CInIMRUe +j50s0OOoMixoQkEZbEOOacBEAbocxOr0/8hXA7rfP16lA9p1MS4HZ6dcAlXDb48R +9YxWofdLu0bQ5f9owXc9DTUS9UCvzQVcU3T/VODAxhBc6DMGClBHfnE6Nmaq+N6X +Kq6/jW3UOcT9swMdpZxHOYzAs3P4OtY0rElPs4d0ESCPwKokpzAgDMDZHETursi4 +E2Pl+F6PsFpGxYM9QWIG5GKmCkDMjlmtijZOIObyMgRu7k59l4jc6nSQxKuotbxs +gbFkd6aTNETkYDixDCspOkr3F9c6yEJ+201fCZKubJDhfZ+WnBqCvUUCdili5bkU +UwFTwFrVNFN6JUk+PdsZfilXgHhn6iE+PVk24IvadVebyJ2hGBjiXDU1nmIs9Q/A +j1UWpdSezQ54h51T0wHhGGE2HAbDOkPzihPmTlIy/UYhzWIYH6718hrqegE7oT8d +FgCRXpR49GAzVKn8HAp1+Req3RKRZkvw0WAl1AbRmZzFZAFLutlmupz3aHX9ETrr +bvuPpheKzbwaWfmpzTPbfXEmfce+3usuwH7bKQgOgmMejI/mIRyxSROe33g7aAEX +D9+XllgySB5c//rbkLUFhGj9fMClNdl1HurMJSU/bg== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem new file mode 100644 index 0000000..0d33211 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI06+E0Qn55PYCAggA +MBQGCCqGSIb3DQMHBAgRIdE1BfEflgSCBMgjWcKNk0gmS+OepxYA2tMjMir2YwFb +ht/PFx0llj4Zt2U2TgvSFhm7JcsNPXqqqElIvEeNrY5BTB6Jbkd5pt1EpKcBlgHQ +cPtjslAxo5C5FgvLuzaFd1tRhHm7UWygTRcI+79zRmypOm0v57ZdS6Z218sJc0gk +re7tBT+lF+S5uCRAUmWBgdVjEFjW+1r0dhVJWYftB8JoE4zW+B0wEz6PIv0cTt7K +cnjHVMFKWPJStAbJ98RWchF0KWeu+cuWAWt/rJ2QrM+q1bBP4Mgn6XfRnKbcJofk +BG5v4oo8B/TSe3woBMtf2BheaeXDa96D7lxF7gELTkdodNfJd9s66GLSRKCk6amk +eJKO8fLZbXpiT0/TGeFvrihWa/ZpVG4I94KDn2a+U8Agq+B1WA6MqCt6txK6GFIN +okCRyRUYb6TFDI2JA+jeEX+0tStVGp+qNyk4PT4tZOG2BJ2dq5F6+KF0VzE8I7V0 +zIFWQvvwO8N+osvmJgQgxI6JOq0ubiHEEiSrd4lKVO7NJ223I9GXao/z+0l5ywYn +SL0LEsw2adblRDgzBnsLCqWEeC3Oczg790AaNkqWPolGKBEpOXlCPCjILJfG/7Ii +GGvuAQaXOOM3fnxb2oTOpFMn6BQDmX77hiCKGTB4VCgTIhwBOpwLDeDxjyUjCp2C +PPtped8Dne+kK9iGuHyu45sXrVtxfigfKh9+ncCsFVQfpmcYXDiUhn/RUP4qezco +jkKeC+S4lM9mG/KzWeDUtMlYkEqFA6yxs05VzpxR3h7sizV0YAE2evSxn3w4aYWY +GGKtVG4h30f7YbxI1N9+2iBTToAejF5gF5/WDPn8N+voohQCIQ6iAZ48vUDuQGme +mzi73xu774u7M/BnmgtTr1ZG9gvT+F6q6rnJFAqj3k8j+mv2w4XCqytZJ4OGTijo +j/s/eZDWmo4t/WXUMjePDzXl96hjBq4bZOpqNwKDLsqbVwQrhFzXTkGLhGQAyKb4 +wZywUkYfTdWa9f+A2NmWqry9Ef5KcOJTSHt6FeY5kwcY56iZT+cD4V2pgxTqQBGt +YUy/j0V35l41OTKZ6x5P3ZSk45w6RPY3/BqcnfvhSFxON3jFivg1DKIcB8WaWjss +40vP+TthOR2X4FQ/OHKwjs+tC6JpwDuSNCVwj9VBGSgjeXK/aV9BG1A0m4R7qxTV +aT4tjSSfPfkOf16hTW2ncHTr9rvY3XcYm8eC5E/IEQ7gxpG/JI0+xK2tel0bochs +aSBP+qGP85Sib3pcnepG6Zhkx4KgTvhbWRAfNS5rB1jLGSpeWQkMZmun91tTuVLK +fRyfQZ2gkr2ixX/zlPb1bhIXHUBgnoUyUHwZ2lNCDp/dm+nGYqXeeg9lZfD3dYpQ +Yd1zdR7Faj8aOsC9T4DRUDzgUIUCdvd2wdmnXF1YB43VgXjsAkfZkEVve1ltv4iG +OAtp0n9aUz+4yS4kBLWEQfNsK7Tz5zjN2BJmm5qQWARxVbR/shhYKqXuY9HbmB95 +sGc1d37pK+n4HvXqQ701zEuvtwyP/P4gg7HjBI2pauuKfT+eVK+xpTBx4W8imY7j +8IhJ4IBBUWzoMoADD132fVW7f3vpp1XGjvbq5fgDlU6beVsWS9KXBD2Wsl7FDkJ5 +49U= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf new file mode 100644 index 0000000..da136b8c --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.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@addom.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = administrator@addom.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@addom.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@addom.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@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem new file mode 100644 index 0000000..1510760 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAvpFk8hsr7ZtAvA1GI0l3MnT+y5pGhjMeVr3I2t3mKgc0YRzw +uHEpJCuQ80OZb2n2/425tz/zNmqZkJDWlWNOiFrXQYl/cxNkScfeQmUIXcoEsmg6 +QH9qBd9WMC+sG4sPwxU8OA+QUEQAu1lA9tLoW3MDDfZ9OF0vmcMNEw900J7vHpJC +xEZ83IV+6a+RTp1fgq9YYBilrJFu3c+nMjzS9OmBvoCeDMofGr6YxP7mJcGJ/hYK +MJDT1OWviSRkEtBPGeIbhvsGqWPRRxCJ3CtSJNxmqVbCy/TsNRL0rV78/4bpsfkf +s85E+74Er41Cm1alAn/Fz18jQRxp7jOXeoFQiwIDAQABAoIBADkGUvmrrdJ1IcLk +CffnNPbxUYllifMAevSj5+WufwBWlZL10QawPgpnywEwWkqfn9zK8SbnyQSgk4FS +BhQ/2jEtVbpzxaKOy/TUDSs7BmziVdN5Iu1H81b8hNL4gPzg+P98bD+uUJXkM3/c +bnctl4A+A0z7VG84W1Ucq93nQyJl18E64i57JMb3tI+423FM3sJBk2FUj64Mwg8r +0p88gccSieB3GusffHazlJDKrlHdFyClLBnW3OQHegv42JOKZErIMHwlaV8fhF21 +GAARx/pDgnvIYUaGhLrf2pCyIkOZIdUedA84rLwAZT9akOtxpNCAxlVUn4xcpAC1 +EAKzGbECgYEA99Hzh3vDNGINYJjqsw01E71DelNTeUmBOuJKqdOG0YLHiG0tERcx +9KLv+7Uo/qtuRzpkMHao7+zC4spQBk1yYkjVtPkXhWdgVUOztkkza72jlwtVu0eK +VYfB7eubOMnSsPtVeYyyM6DFKBRUxo0VKsvvjD/84WdCGsgy+jDRDUkCgYEAxNur +XMStYOnxdebOGFs5U8jc+/HNNuaCpSkk98uQ0/VfWp8TXA508FYnT6/BcoH+3hHy +7W/7aMv//0IWgNQk8m1w33svDdq7jRJXrIpyb7QaX2OW8IfTfIMKVXOgxPvD/4IK +lvmvf8T7K0W7rDYdcfy9bsDb0RQcH0Z3cp4lUzMCgYEAmLjmX6RB1FJo9BLI8Lc+ +8n88ynH3i1NlNKioYqhc+VijJsxBbbrhqmWPh4tJTEjRmUu+2q8FxXYfVCxhzMCF +sVQ5f2HSwP/IOkOSyM+rxMYFvtvZZaTc94DGXp1H92NJWJBLSLEQUQjO97gv1nyz +gsBTTBdS/IXqEx81a0ISUyECgYA80saClj4fmIjDbfm1qtHuojwtGAvY76XkE+9Z +JKtt4f2BSW843TqiW2wwAdTaZXHy+Ua+t//M5GMHYksDqQh1Yv0h/7SNKk0SjF1M +cUZkXxha6rFjRgRBD1ftCRneYw+u7WYKOcFQz/Lu7s/KqLm2U2nQQ4RneDgsLaCQ +aG6N4wKBgArI0d3MlNFXLU7bT+q/2BaZ5VBwaF/6DlI4m1hDT8dKtOTja+y6vAm/ +aH82uJyoom8R/w2H/ICe3NuwYgTo/7Vy6xMt1TnskGOc0yjTZBMMU1nN8zrxlgD1 +1Xr8TzGOf//mK4H54B/POSq6WZ0PSXDVGToVWMdif+2Rq16+CcKp +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem new file mode 100644 index 0000000..fbaf0fc --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDDTCCAfUCAQAwgccxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +DjAMBgNVBAsMBVVzZXJzMS4wLAYDVQQDDCVhZG1pbmlzdHJhdG9yQGFkZG9tLnNh +bWJhLmV4YW1wbGUuY29tMTQwMgYJKoZIhvcNAQkBFiVhZG1pbmlzdHJhdG9yQGFk +ZG9tLnNhbWJhLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvpFk8hsr7ZtAvA1GI0l3MnT+y5pGhjMeVr3I2t3mKgc0YRzwuHEpJCuQ +80OZb2n2/425tz/zNmqZkJDWlWNOiFrXQYl/cxNkScfeQmUIXcoEsmg6QH9qBd9W +MC+sG4sPwxU8OA+QUEQAu1lA9tLoW3MDDfZ9OF0vmcMNEw900J7vHpJCxEZ83IV+ +6a+RTp1fgq9YYBilrJFu3c+nMjzS9OmBvoCeDMofGr6YxP7mJcGJ/hYKMJDT1OWv +iSRkEtBPGeIbhvsGqWPRRxCJ3CtSJNxmqVbCy/TsNRL0rV78/4bpsfkfs85E+74E +r41Cm1alAn/Fz18jQRxp7jOXeoFQiwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB +ALQr9rGYIkhd/AXeVoFHs/66rwaq3GccdnJpi023/5LhOlRmMa2BWTuQm3jW/3Oc +HgQOx9G0GTDpaBtAjOCGDCygw/k23oekVTQtDPiGigMnpuY2vnrjAeUFJo3us5pA +9eVPzKTzJf5ftc/aoVC39t/1Uks103M8t5vJCcexBTYQONe56XC1krY50PHZNI/u +stjOmleHZclLBU/BplId43nRlvvdkXihPiEbdV4XvhHRs/6w52DkQst6NH6jzeWk +anYEP2Oo1ROX5v201414ZaWm7oDxtNuL8NzDt+DUGISwC/9ZcqadzlaoI9XVhOb2 +AfbQMY1Q/3OeR8uRROpnHjE= +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem new file mode 120000 index 0000000..a2eb210 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem @@ -0,0 +1 @@ +USER-administrator@addom.samba.example.com-S03-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem new file mode 120000 index 0000000..afbf12e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +USER-administrator@addom.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..4ab5d5a --- /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 16 23:29:04 2016 GMT + Not After : Mar 11 23:29:04 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:af:87:9e:1e:7f:c0:ab:da:47:22:74:d0:df:01: + f1:67:6c:ac:c4:b7:d9:18:97:e5:7a:62:76:33:b6: + 52:f2:92:90:75:ac:a3:94:7e:0c:29:75:c9:83:2f: + 19:66:60:84:45:ff:d5:a9:bd:c5:3a:a2:d8:25:cf: + 15:8a:23:3e:09:73:2f:99:1d:24:1f:e6:96:7e:7b: + c4:1e:8d:55:5b:c1:18:69:cd:1d:b4:22:d5:7b:db: + 5e:7c:91:f2:8e:c1:03:30:ee:63:46:5a:54:d5:40: + ac:79:55:00:71:07:8d:3e:0e:ed:ff:93:6c:f1:2d: + 84:c1:51:a3:7c:49:cf:ff:85:7b:c0:64:c1:ba:c8: + 66:7a:ff:17:2a:74:ea:16:6a:1d:97:c0:27:57:10: + be:76:f5:9a:63:56:c7:25:c6:fc:a7:5e:00:a6:1a: + 3d:21:bd:7a:f9:e3:03:60:ce:df:16:06:fc:05:bc: + d1:c8:5d:e7:33:ed:52:8b:60:5b:60:c5:70:13:1d: + c1:b3:08:13:09:3b:05:e8:02:40:12:45:89:af:87: + 1f:6a:8f:62:ce:1e:17:13:34:82:81:86:e9:bb:85: + 5b:75:1d:f4:3a:02:b4:a6:58:23:fe:c3:3a:35:09: + 95:bb:f7:79:bc:e3:97:e6:6d:77:24:aa:2d:51:50: + 37:69 + 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: + 45:DA:4B:8D:05:9C:62:4E:62:C3:D7:5C:5F:D3:D9:85:B4:9B:F2:2C + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + 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 + a2:bb:e6:97:67:3c:b6:6e:6e:dd:34:99:16:c6:80:91:08:bf: + 91:ba:51:62:5d:76:2f:e5:53:91:3d:99:03:18:a9:84:69:73: + 76:66:c3:eb:56:d7:c5:40:91:15:da:de:b2:76:48:7d:8a:8c: + 80:79:3c:e6:da:0e:a6:c3:53:d6:74:ee:5f:29:b7:03:46:de: + 89:32:14:22:03:30:68:2e:7e:06:d4:ac:9e:82:c0:02:16:7f: + 81:ba:ee:7a:e7:8b:f7:fb:99:7f:8c:eb:78:54:97:4e:28:44: + da:f4:e2:1b:f8:3e:ac:ca:cc:e3:e3:71:90:91:47:9c:78:ed: + 6f:bc:b7:98:12:ea:75:e5:15:f7:26:56:a7:5c:d6:74:a8:13: + 7b:23:35:4e:6a:01:f6:a9:f5:5b:9b:d0:ea:ba:0f:c3:c4:1a: + e0:b9:a3:ed:5d:28:cb:7f:1d:3e:8a:9a:af:4c:88:00:3c:10: + f0:49:85:24:60:e6:cb:d6:9e:00:46:78:4d:90:22:68:4f:10: + 39:84:3b:e2:7c:3d:ed:23:41:19:7e:6f:45:59:89:a9:9f:26: + c1:f9:7d:4d:0a:b4:10:f9:31:7d:cc:87:d0:4b:62:14:70:86: + c8:7d:14:ff:e4:68:e2:de:42:ca:01:c7:aa:2d:5a:a5:72:64: + f1:4c:fa:6e:60:15:22:08:68:e6:c6:6a:75:63:24:b5:54:76: + d1:97:4f:e0:e8:bc:eb:d0:62:84:4a:b4:3a:07:38:5f:b9:a6: + 6a:31:14:47:33:81:bd:d0:a4:a2:da:2b:92:0d:dc:42:c4:0f: + 28:0d:b6:1b:33:b5:88:df:1b:a8:d8:90:9a:11:ce:df:d4:14: + e9:ac:94:94:95:bb:bc:6e:f1:be:85:29:3f:17:ab:41:14:d8: + 20:ba:e0:a2:a3:d3:d4:8b:1e:4b:32:22:8d:0d:c1:e6:39:1a: + ce:cd:f3:1d:f1:82:85:d5:e7:80:34:90:a4:0e:d4:af:32:c8: + 79:4e:25:32:b6:1e:06:3a:26:42:38:47:1a:32:96:71:5b:fe: + 5b:b0:ef:7d:fe:58:ca:eb:b5:c9:4b:2f:12:cb:89:36:22:7c: + a6:39:ab:20:c1:2d:cd:6b:34:e1:cd:bc:ed:45:45:12:4a:65: + 4b:ab:45:f2:6d:7a:9d:f8:b5:52:78:1b:da:2f:e0:ce:f7:e2: + b0:fa:6f:40:3d:dd:e9:39:c3:63:68:ab:77:53:be:3b:dd:9a: + bc:d7:d7:fa:6a:bf:bf:74:f7:11:80:87:f9:d3:45:eb:1e:8e: + d1:a9:a0:2e:66:e7:20:67:1c:4c:22:43:77:85:ff:1a:23:37: + cc:49:de:51:ee:f2:04:2f:a8:98:88:0f:b6:18:53:eb:e2:49: + 15:5e:02:8b:1e:7b:e6:c5:d1:0c:df:84:4e:d9:bd:fe:21:48: + d4:a4:11:01:27:57:51:d6:c1:b2:a1:1c:11:9a:a7:d1:ab:f0: + 99:16:b2:c8:3f:74:25:68:0b:1a:cf:58:0d:cd:cc:1a:6d:8b: + ec:1f:70:82:02:40:97:0f:75:2c:53:87:c1:42:5c:d1:7e:19: + 78:2c:2c:88:73:33:81:63:38:84:07:0f:16:bb:7c:54:59:03: + 94:e7:b8:85:d7:f8:5e:53:35:65:2e:e5:27:65:be:f0:89:65: + f6:ab:3f:6e:a5:bd:c1:1a:9e:31:30:68:6e:50:af:54:4c:33: + f8:73:2f:41:60:4f:4c:85:1b:ad:7d:db:62:42:dc:87:96:b4: + cf:ce:12:50:ed:6c:01:5f:e2:f9:03:f5:f7:4c:6c:8f:2b:5b: + 7a:64:7d:19:e8:20:f2:e9:10:58:f3:71:0e:1e:58:68:f2:59: + 3c:06:53:7a:f3:60:62:5b:c7:b7:83:58:1d:3d:a6:17:db:33: + cc:91:14:af:d6:b9:08:bf:60:af:ac:3e:fe:8b:74:71:20:c7: + e7:31:5e:26:6c:28:52:67:12:1e:c3:9b:89:23:5d:88:ee:b0: + 6b:db:cc:94:8b:9b:1b:40:b7:66:bc:7d:1d:e1:08:00:20:ba: + 41:cd:17:d6:4c:7b:c4:5a:fd:cf:6b:20:e2:b8:86:9c:31:17: + c2:d7:7f:1c:3a:d0:fc:1d:f5:7f:c9:96:04:27:de:b8:ef:8d: + 38:9a:b3:56:60:ac:c2:07:38:64:19:39:9e:73:6f:ba:59:15: + ac:45:42:4d:bb:79:60:7f:ae:c3:8d:63:4a:27:16:0a:ca:92: + 7f:f7:a2:02:76:f5:e6:7c:ec:ba:ea:18:cd:9c:3b:ee:37:2c: + 9d:78:4e:c9:40:6d:94:cc:ce:ca:f4:33:fc:a4:dd:05:62:d6: + 0f:1e:19:63:af:10:c3:ff:02:1a:0a:48:fd:af:f2:a4:0e:64: + dd:90:f4:4f:14:1b:90:1f:9e:29:b0:0b:94:a4:d1:2a:87:b9: + 3a:76:c2:b6:af:c3:d4:84:6e:85:1c:64:73:46:d0:df:72:c0: + 3c:42:91:c4:30:10:11:18:36:bc:e5:17:36:22:5f:c2:3f:ac: + 1d:2e:9d:87:11:be:a7:ac:b2:62:35:74:b9:27:27:95:bc:c1: + 11:44:f8:64:36:60:74:06:a2:e7:e9:76:be:a7:86:5e:18:1e: + bd:dc:b0:aa:ae:92:d6:dd:d6:25:80:d6:c1:be:c1:21:1c:01: + 6f:83:20:ae:b7:54:4f:3d:2d:12:fc:a2:cc:49:fd:59 +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MDRaFw0zNjAzMTEyMzI5MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvh54ef8Cr2kcidNDf +AfFnbKzEt9kYl+V6YnYztlLykpB1rKOUfgwpdcmDLxlmYIRF/9WpvcU6otglzxWK +Iz4Jcy+ZHSQf5pZ+e8QejVVbwRhpzR20ItV72158kfKOwQMw7mNGWlTVQKx5VQBx +B40+Du3/k2zxLYTBUaN8Sc//hXvAZMG6yGZ6/xcqdOoWah2XwCdXEL529ZpjVscl +xvynXgCmGj0hvXr54wNgzt8WBvwFvNHIXecz7VKLYFtgxXATHcGzCBMJOwXoAkAS +RYmvhx9qj2LOHhcTNIKBhum7hVt1HfQ6ArSmWCP+wzo1CZW793m845fmbXckqi1R +UDdpAgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFEXaS40FnGJO +YsPXXF/T2YW0m/IsMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAorvml2c8tm5u3TSZFsaA +kQi/kbpRYl12L+VTkT2ZAxiphGlzdmbD61bXxUCRFdresnZIfYqMgHk85toOpsNT +1nTuXym3A0beiTIUIgMwaC5+BtSsnoLAAhZ/gbrueueL9/uZf4zreFSXTihE2vTi +G/g+rMrM4+NxkJFHnHjtb7y3mBLqdeUV9yZWp1zWdKgTeyM1TmoB9qn1W5vQ6roP +w8Qa4Lmj7V0oy38dPoqar0yIADwQ8EmFJGDmy9aeAEZ4TZAiaE8QOYQ74nw97SNB +GX5vRVmJqZ8mwfl9TQq0EPkxfcyH0EtiFHCGyH0U/+Ro4t5CygHHqi1apXJk8Uz6 +bmAVIgho5sZqdWMktVR20ZdP4Oi869BihEq0Ogc4X7mmajEURzOBvdCkotorkg3c +QsQPKA22GzO1iN8bqNiQmhHO39QU6ayUlJW7vG7xvoUpPxerQRTYILrgoqPT1Ise +SzIijQ3B5jkazs3zHfGChdXngDSQpA7UrzLIeU4lMrYeBjomQjhHGjKWcVv+W7Dv +ff5Yyuu1yUsvEsuJNiJ8pjmrIMEtzWs04c287UVFEkplS6tF8m16nfi1Ungb2i/g +zvfisPpvQD3d6TnDY2ird1O+O92avNfX+mq/v3T3EYCH+dNF6x6O0amgLmbnIGcc +TCJDd4X/GiM3zEneUe7yBC+omIgPthhT6+JJFV4Cix575sXRDN+ETtm9/iFI1KQR +ASdXUdbBsqEcEZqn0avwmRayyD90JWgLGs9YDc3MGm2L7B9wggJAlw91LFOHwUJc +0X4ZeCwsiHMzgWM4hAcPFrt8VFkDlOe4hdf4XlM1ZS7lJ2W+8Ill9qs/bqW9wRqe +MTBoblCvVEwz+HMvQWBPTIUbrX3bYkLch5a0z84SUO1sAV/i+QP190xsjytbemR9 +Gegg8ukQWPNxDh5YaPJZPAZTevNgYlvHt4NYHT2mF9szzJEUr9a5CL9gr6w+/ot0 +cSDH5zFeJmwoUmcSHsObiSNdiO6wa9vMlIubG0C3Zrx9HeEIACC6Qc0X1kx7xFr9 +z2sg4riGnDEXwtd/HDrQ/B31f8mWBCfeuO+NOJqzVmCswgc4ZBk5nnNvulkVrEVC +Tbt5YH+uw41jSicWCsqSf/eiAnb15nzsuuoYzZw77jcsnXhOyUBtlMzOyvQz/KTd +BWLWDx4ZY68Qw/8CGgpI/a/ypA5k3ZD0TxQbkB+eKbALlKTRKoe5OnbCtq/D1IRu +hRxkc0bQ33LAPEKRxDAQERg2vOUXNiJfwj+sHS6dhxG+p6yyYjV0uScnlbzBEUT4 +ZDZgdAai5+l2vqeGXhgevdywqq6S1t3WJYDWwb7BIRwBb4MgrrdUTz0tEvyizEn9 +WQ== +-----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..652e3bd --- /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----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI7Afo/WihRO4CAggA +MBQGCCqGSIb3DQMHBAiyzMez8ikVKgSCBMikJkx4Qhm0cLRQXJfIPsHX0YQfinoJ +qLGWMQ5KWTpwFZHoeqarmCVLJwReF75E8nD5tJdKt5J+lN0gBQMbppAzlSOJvMne +1E5sDoBHY3jYUViF3p+ZZt4YoDxaGFYxcGL9M6Uo/Yb1791riMisQjgn7inpRe0i +JuHngJH9Dblg0+vGM3JkMKdizWHSW4RyeYXa8d3rh62Y5RD7exUHKkz3pPucSsyy +dnkhvbhdXSYzPxcUarrjx3pNMzWhamLWP3V6UwupCB8dygLm4QV+Fc3Jw7wR3Efj +cewWjmXHuHzAGfDhr1r6yeWaAQCYezSp18UwMRv9AWgiTAayxDI+IroBigvU3PfA +KE0RlWBnvoy2ggNEsCvk2QXYpQiIJMTS9u1oi2aOdvXaaVxuKBPJGgzAFGSnM44k +gE1Pe+snVxzRuzHCNXnWoCxSa9xAvRt/dnQ9n1p2m3lwlt+kP0kO4ieMhT+SnBNh +QY/WRfJ8E5ldYyfJ0y2eRd1hCu+42tj72rAuQkhPEUJzWuU6N1xzChXPwXVnhIh4 +HS4bpd9uL1wA5sNw2zfXdanagmSrXC5EFVdj4rJzHWzkalg0GTMhYd4QsbqI5d8O +lO5ECnZUJwIcYa5Hy7OVDymRh3BxPMDGYqiO1+6QHUrqRm/XiSDUSaBfLat9ckHY +0JT5nbBMg0TJ3VIhUbsZaQ4fwZNr9zgeS+yoFuLcPYPCHBz2fDNq6MFb0BqbHcYY +qmf++nxF/jW21UKTryBeiLdkq1TjExOEXdmjSL4vwmUjyx+ycM4w8GvdU4xkdkQl +1jNlx20WSocZ0hzreCMXglUb1q7tzZvaVJrSS9TX2PV38Fcz6jpmOeKtnkRBMUis +Ge20QO7D8zCJM0jL+mNAnuZCA7zHc8aenbR6hK8i3Kd8G0XhWLNVWI5KfFtgrRaW +UCM8mSdEIvWZfPrdvxo/kYEXBBA8i+3oO0nSUTyHpqmsIH3nYvaWnVmibnKMigO3 ++3d+6Db5R117EbXDdRWm85jiN7PQ1SdNVxtKN4Wu188r/KfchXAeBQcBy9Kh1vVY +qYTqP4Mp7dbm864iiZQZwTLJeq346+xUze5NY7nFHWl0ps7ujk+i9WA9I+M2TAj9 +Zmywy4Xvjwpj7PO5zA9O5TRxnnBbz7VrTcxBLK+6T/2yZZceJ29Bv7wy61eK9LNk +AYy+MFXlY64L6HauTk9Ne/VnNnTvYYqrqPNy6CehQc0+LKvmYLCHUZabhWi7P1rj +gUkkypfBH0j8k1lDnjnYu5bml32GK7eBix9C+5kNDadnvCEVDiYFT59SDyKCUHMZ +19EKywqkWVPu5ez+60zSEJACpvIqDxlamusN3O9tQZD/t2c2lJiBeBPszXgj8Gin +++tuCwkz/3KNy+u3SCZg9SUk5+XVZDOQOMh9EmUT5oqoPUTm9pblU2B8lRZaw/wl +B97E4q4TUOtXZXHJdCkU8Sxr8/l8fOFYqIeiFx8PhSHaFgpEKgs89G9AefIb+l1u +Z36bqMs0y4rIiSHR++0ZO5NJIi33zhPHvifmPzBTDXRn9cWdfqwetq1ts9ZD27oE +4UhJyRU0gprmtpQWoVnd6ghiM1zk7lZmRQEDDXy4+puztzgZNLKJbSeXbufe49nX +DcU= +-----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..cc8f150 --- /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----- +MIIEowIBAAKCAQEAr4eeHn/Aq9pHInTQ3wHxZ2ysxLfZGJflemJ2M7ZS8pKQdayj +lH4MKXXJgy8ZZmCERf/Vqb3FOqLYJc8ViiM+CXMvmR0kH+aWfnvEHo1VW8EYac0d +tCLVe9tefJHyjsEDMO5jRlpU1UCseVUAcQeNPg7t/5Ns8S2EwVGjfEnP/4V7wGTB +ushmev8XKnTqFmodl8AnVxC+dvWaY1bHJcb8p14Apho9Ib16+eMDYM7fFgb8BbzR +yF3nM+1Si2BbYMVwEx3BswgTCTsF6AJAEkWJr4cfao9izh4XEzSCgYbpu4VbdR30 +OgK0plgj/sM6NQmVu/d5vOOX5m13JKotUVA3aQIDAQABAoIBAQCEj7E0a1rA7ooG +VZ5grQD5ELOxpP7Jef2OXcnS6ADgvRtoI0cun7rjnNbgwbM3A/EhRELCfFT1IYKH +m0szFcaGMH1j7wQXK3fAcgv83tP2BXBAhu3F2wDLFzLWdQpwEQgt7fr/aLzkiIE4 +6J76va9HjNLkzxvZUH0P2m3TMZNp7s2NLjxNQwivNXSgKXcT9fPX7IaBd063W41I +iYQZ7M8Q3C1vk34uC9V1LxjFxOAe42G/ITkjt3CJbg0CjMXG3P3TKIXG94ufpFQO +mkEzUSGxTCkwlqHKcxsa+7f72TocuhLuwpFBSeRmiIsa5ZHxJiC6XOkz2CAboNkI +UMSVjoxZAoGBAOlOGjiF7ChheDLhtj3/VcxfyHkcNoUFAtKuoT/FD8JMQiEUTifr +V7eA8pfAQubVVRNLmZEA40gsJsTPbCRQymwcYDFRATlTd6nZ1s53z99E/v/1QjIa +ZpQXRD+Nt1xmID/MuX34qpIA6ZEE2zTFoMo1STeNf4eC9mESW9DkA05rAoGBAMCa +wrvLa5whtXbhdoWfCMYKtSQuGTEKslb4Ec97sKIdZXloGnH0eyiwnynCDhX2wPJt +gnQtVxNXb9+MFxh+6bnX5rMyB+myXszpPNBCbLO0FU3+vfIEmOoULqU1Xn7Eu97m +LGoR6G9cN7p8RuX7zp5ROKGfDg77oW8XhVah2x57AoGAY1BmBQ2tW/sx6ab/pyCc +a2WSt0t1QebCLuE7ryO586H2vJIiOwgJzQnNOyAS2qSRlKcn9fwExGJXFoydok/p ++1+Q6y1qcfbAB8O9lyKVkJuUWW0UArQOWpgU62DuXxzyOXZyt9c09PYCd0Mz9SDz +s2A/jLBlS1BKhUQFZcTKS4UCgYBaT7cD66x3t26pYar7mMi6ZAbwAhWZ41QgZ42i +ZnM6cOJF/UR5LpQZTkgzgmSsc9mhUywaYbA0x4kTn1KtD8V0eQIaAFmpgRPmrW7w +kFT8JnLe8ZYLR5CUIgaFPPMkKgeVywQEcIU2wlz3OpLcACiwH5GYZ0ZmTCM0Pikt +qBNgxQKBgEVgpIHZi2xdfvwtCrEfomnlImj94HySKIFenCRoc/d34+KO4jKho1zN +dqbSDqz/lB/7GWFjRszTMZMVJkl8TbE050UEe8EDPt93BSeGHNCUXUesZQVddGhn +iH8OLIkoW3xIlNgflwi4+7gLjWrAHHPwEG3Iys83DVCA5D/4C02m +-----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..72cd979 --- /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 +YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4eeHn/A +q9pHInTQ3wHxZ2ysxLfZGJflemJ2M7ZS8pKQdayjlH4MKXXJgy8ZZmCERf/Vqb3F +OqLYJc8ViiM+CXMvmR0kH+aWfnvEHo1VW8EYac0dtCLVe9tefJHyjsEDMO5jRlpU +1UCseVUAcQeNPg7t/5Ns8S2EwVGjfEnP/4V7wGTBushmev8XKnTqFmodl8AnVxC+ +dvWaY1bHJcb8p14Apho9Ib16+eMDYM7fFgb8BbzRyF3nM+1Si2BbYMVwEx3BswgT +CTsF6AJAEkWJr4cfao9izh4XEzSCgYbpu4VbdR30OgK0plgj/sM6NQmVu/d5vOOX +5m13JKotUVA3aQIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAGrgBV0TkeQ3fHEJ +vTabQG/aKSgzkkzaiBdY5GBX3FGtmKl0E9DNImc3bcw4QBC8GDObGoqct31QpHnT +H51MN/Vix3YAUsKbGtvopGygn22sLtm21Iy1lOS2QsEikPxrDedmKjGzsyi8fWFF +fWOEW1+mhS7L6oiNDm18MbAaYN6wdgkPVW0Uc+P/ftRZ1y2T2mli+99IgNQQW9Rb +7ZrHBTyCq9IK73UniVCA3yEN2ibHxaZQsvl3DpUfkKdPV1FOsvj33nTMtcubY7/P +c4n3w2M0HVSu6Ch+cJj0dy3FzYU76eInzT6B+hs2lGCIm6H4pUH8Vjx9dNMjcC4d +vctx/Mw= +-----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 d7c0abbe95ae225a77e504ff2f74680aa708d394 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 120/352] 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 (cherry picked from 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 86956aa..187ea4b 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 addc.addom.samba.example.com 0123456789ABCDEF -./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.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 addc.addom.samba.example.com 0123456789ABCDEF +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.samba.example.com -- 1.9.1 From 77d54d829d39c6cfaa00a014671b53e8849380f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 121/352] 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 9937203..e87acd3 100644 --- a/selftest/target/Samba.pm +++ b/selftest/target/Samba.pm @@ -71,6 +71,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 122/352] 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 (cherry picked from 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 8ac3286..3fc31e0 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -257,219 +257,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} @@ -767,8 +557,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 d3e1e4dc329876b8abbcf54edae3c04418583323 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 123/352] 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 3fc31e0..9105b2d 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -501,6 +501,8 @@ sub provision_raw_step1($$) } Samba::prepare_keyblobs($ctx); + my $crlfile = "$ctx->{tlsdir}/crl.pem"; + $crlfile = "" unless -e ${crlfile}; print CONFFILE " [global] @@ -520,6 +522,7 @@ sub provision_raw_step1($$) winbind separator = / 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 d33c94f176e94bdb2692c5ef763708c38d57cac8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 124/352] 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 db5da05..11d661d 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; @@ -516,6 +517,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"; @@ -547,6 +584,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 399f22da5db45b4aae621ab41f4fa86c69b8d2d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 07:10:06 +0100 Subject: [PATCH 125/352] 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 (cherry picked from 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 2dfdb1e..35e81fc 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -349,8 +349,8 @@ for t in tests: plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ') plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "rpc.samr.passwords.validate": - plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') - plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "ad_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, "nt4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') -- 1.9.1 From 16287af41bc9c0a88890ac97ba323708842b59fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 09:13:46 +0100 Subject: [PATCH 126/352] 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 be52fc06b7021ab412970a33e6fe1f3d48f37cb2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 12:10:12 +0100 Subject: [PATCH 127/352] 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 (cherry picked from commit 1a7d8b8602a687ff6eef45f15f597694e94e14b1) --- source4/torture/rpc/forest_trust.c | 12 +++-- source4/torture/rpc/lsa.c | 14 ++++-- source4/torture/rpc/netlogon.c | 98 +++++++++++++++++++++++++++++++------- source4/torture/rpc/netlogon.h | 7 +++ source4/torture/rpc/remote_pac.c | 34 ++++++++----- 5 files changed, 132 insertions(+), 33 deletions(-) diff --git a/source4/torture/rpc/forest_trust.c b/source4/torture/rpc/forest_trust.c index ccb19ed..aae745f 100644 --- a/source4/torture/rpc/forest_trust.c +++ b/source4/torture/rpc/forest_trust.c @@ -516,7 +516,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; @@ -547,7 +548,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); @@ -559,11 +560,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/lsa.c b/source4/torture/rpc/lsa.c index 44cdbdc..bff0926 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -4134,7 +4134,8 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p, struct netr_Authenticator req_auth; struct netr_Authenticator rep_auth; struct netr_ServerPasswordSet2 s; - struct dcerpc_pipe *p2; + struct dcerpc_pipe *p1 = NULL; + struct dcerpc_pipe *p2 = NULL; NTSTATUS status; bool ok; int rc; @@ -4223,18 +4224,25 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p, status = dcerpc_parse_binding(tctx, binding, &b2); torture_assert_ntstatus_ok(tctx, status, "Bad binding string"); - status = dcerpc_pipe_connect_b(tctx, &p2, b2, + status = dcerpc_pipe_connect_b(tctx, &p1, b2, &ndr_table_netlogon, cli_credentials_init_anon(tctx), tctx->ev, tctx->lp_ctx); torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b"); - ok = check_pw_with_ServerAuthenticate3(p2, tctx, + ok = check_pw_with_ServerAuthenticate3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, server_name, incoming_creds, &creds); torture_assert_int_equal(tctx, ok, expected_result, "check_pw_with_ServerAuthenticate3"); + if (expected_result == true) { + ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p2); + torture_assert_int_equal(tctx, ok, true, + "test_SetupCredentialsPipe"); + } + TALLOC_FREE(p1); if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { #ifdef SAMBA4_USES_HEIMDAL diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 9f8e8f1..a9e64cf 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); @@ -2507,7 +2550,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; @@ -2515,12 +2558,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); @@ -3343,7 +3392,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) { @@ -3356,14 +3405,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); @@ -3413,7 +3468,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; @@ -3436,14 +3491,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)) { @@ -3868,7 +3929,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; @@ -3882,6 +3943,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); @@ -3889,6 +3951,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 196d9f8f..dd44796 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 bef4e14ff4ae9c5b3e9ee62c3a8c4383efee037f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:24:03 +0100 Subject: [PATCH 128/352] 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 78947a2cc5c2ca0d88d523bbe63e671b52ddcacc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 01:56:07 +0100 Subject: [PATCH 129/352] 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 9000fe9..4465698 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -1755,7 +1755,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 1539c698cb7ad2d6faf55ebd592e8e0a79e7fb83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 18:09:26 +0100 Subject: [PATCH 130/352] 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 a9e64cf..01bba97 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -4028,7 +4028,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 14f60d1ae6acdc802ce865ab82104e8a91fea213 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 02:55:30 +0100 Subject: [PATCH 131/352] 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 a72dd31..57a97f3 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 = NULL; 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 9b5f19cbacf5930aaa1083878cbc8d25cb2ef332 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:01:47 +0200 Subject: [PATCH 132/352] 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 bb9cd18..4c43519 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -234,7 +234,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 cd1c5b7b884bca4f31faf14e21d4d92a76a40597 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:08:43 +0100 Subject: [PATCH 133/352] 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 9fd5f25..e3b1352 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 56ea9092a630edd3baaa646b6639e8d5c9d77c86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 134/352] 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 be90de16b2a93a1a864d382e8d09ac3b8d0804ea 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 135/352] 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 fe8da85e8ddfa2a7af57af5c294e4f65a5601eb6 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 136/352] 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 94bcddd66395e997204ecb8134e1b7a9889473f9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 21:00:30 +0100 Subject: [PATCH 137/352] 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 97d0352..50d1a0c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1361,6 +1361,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 0b3ef98ccfefbf48904269ec9b87d2127ed10abe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 20:34:27 +0100 Subject: [PATCH 138/352] 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 3c0a2cc0f0dae6d9d93780835b66842160e32df7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 15:30:00 +0100 Subject: [PATCH 139/352] 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 322d4d5..f78f83e 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 bfd5e103e76239af1d2dcdec8cca6eaaed4677a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 23:32:50 +0100 Subject: [PATCH 140/352] 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 4b4b77a..7eb06cf 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 03942988baab48b6e76d7b5a474829cf9f1d7f83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 19:41:53 +0100 Subject: [PATCH 141/352] 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 077c97b..1ac6881 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 35b31a5493522c20951d8957b91669e9d1577ce1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 08:46:45 +0100 Subject: [PATCH 142/352] 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 67104ce13c6980906fc64937b6b7ce9082dfc6bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 143/352] 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 66e27367e1bcce0dc90d48b924b40874b8a01bcc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:58:19 +0100 Subject: [PATCH 144/352] 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 b83753a3bfa7f1d2c593499302f00e4cc9b5d7d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:01:09 +0100 Subject: [PATCH 145/352] 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 6dbea3d409042100f4e25595fc12c9fe0be5d75e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:06:09 +0100 Subject: [PATCH 146/352] 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 a2ce8bd5c3940ebab7a4e3f9c965ee577dcee787 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 147/352] 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 f7c0be618ed2df4fa671ceb65975d7391c61828c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 148/352] 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 d63e84ddbb20e369c3474e43a6703aa6fe8dff67 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 14:06:18 +0100 Subject: [PATCH 149/352] 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 672cf37..0d1b90c 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -1286,7 +1286,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; @@ -1384,6 +1394,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 ddedf6a..039e653 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 0438c42170b87227828cf1477970b4302914e45e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:06 +0100 Subject: [PATCH 150/352] 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 2a5341969c2b4ffc900451762859530db07eb0fc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:35 +0100 Subject: [PATCH 151/352] 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 74a6a0cab2d7baf7be19a6f49fd38698cc717e99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 152/352] 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 2ab2f3e8dbdce2bbc3d4dd9ba87d6046c1f0f549 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 153/352] 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 e40d9f9dd241a8107af2f18abaa8b000d8fdfbdb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 20:13:24 +0100 Subject: [PATCH 154/352] 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 b62d9588b18de56fbee1f88a8220dd96a28ee676 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 155/352] 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 e3b1352..2a8bba8 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 6ed376e41804af15e865fd09061f393383c1ef89 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Dec 2013 11:27:27 +0100 Subject: [PATCH 156/352] 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 a43dca89694d3d2c6b170835f65066ef8889f86c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 157/352] 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 e01e45c4388f0be4ac913fc1be68956723a1ec85 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 21:24:47 +0100 Subject: [PATCH 158/352] 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 4e12277..3711b1e 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 0ccb25062b13312b403543993f44f79c5a11f164 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:29:11 +0100 Subject: [PATCH 159/352] 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 fdedd63..78dd59d 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 3711b1e..a69add0 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 01bba97..c8e864d 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -882,6 +882,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 dd44796..2b72f38 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 5f3f3d5..c454257 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1192,7 +1192,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 57a97f3..829c969 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); @@ -853,6 +854,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 c99077266aefcedcbba471531ee81342cd783105 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:31:35 +0100 Subject: [PATCH 160/352] 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 78dd59d..3779ec0 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 a69add0..0abbb5c 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 c58a23f..acf39e1 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 e9eaadf..7ad4654 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 e5499e06d02a88f5975c2916927d81f765900a9c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 30 Nov 2015 09:13:14 +0100 Subject: [PATCH 161/352] 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 15c700e..f041e32 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -244,9 +244,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 */ @@ -275,7 +278,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 995b3ec5f3cfc2c6672c85a25c724b09f2347538 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:02:58 +0100 Subject: [PATCH 162/352] 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 fb7e94b29a4a3a82393e56ee2f5480d3c9cc549e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:26:49 +0100 Subject: [PATCH 163/352] 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 17ec2d459aef73556fb6ade3e83148733061ebe9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:11:32 +0100 Subject: [PATCH 164/352] 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 9b28c45..be2e94e 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 3f00720abf93dad76b551e5d078f34c8f4e104f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:10:20 +0100 Subject: [PATCH 165/352] 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 be2e94e..8baf803 100644 --- a/auth/gensec/schannel.c +++ b/auth/gensec/schannel.c @@ -672,9 +672,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 995dc35936a94839fe6cc2a80c499a071bbc90a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Mar 2016 15:31:23 +0100 Subject: [PATCH 166/352] 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 49b5b2f..2f63aaeb 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -128,6 +128,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; @@ -200,6 +202,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; } @@ -236,6 +242,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: @@ -551,7 +565,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 20a6eaaafbc1c8cc61b477ced3cc809494b11a96 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 167/352] 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 e0c1b85..d5fd745 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -2468,22 +2468,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; } @@ -2570,22 +2564,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 7637512d2a35610de8ed69334e44c9987be3b8c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 168/352] 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 2f63aaeb..778f62b 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -993,6 +993,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 4042a4259fe171773bac81fec1bc7a56a223f3dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 169/352] 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 d5fd745..aec0d89 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1719,6 +1719,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 94891e6a03edbc7af4318832bb653db12e95d7d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 170/352] 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 c454257..9e521cd 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1189,8 +1189,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 c76c2a5b281b9f0f139d766d31bb0d91764ed88d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 171/352] 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 2b72f38..e880f80 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 bcb13eb0998a502b8bfb07d3b7141464ee2a73f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Feb 2016 19:08:31 +0100 Subject: [PATCH 172/352] 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 acf39e1..cc9ae33 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 7ad4654..ebf6812 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 1f981ba3e12af955f5d0c803a720f87fb82905bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 173/352] 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 778f62b..527718d 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -828,6 +828,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; @@ -898,6 +900,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 ec296245a13ffcf10d8bfc2fd87bb63cb0c5ec66 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 174/352] 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 aec0d89..176769f 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1585,6 +1585,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); @@ -1611,6 +1612,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 fbfb1f7a2993f0450c978c53ba11d048baf91e16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 175/352] 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 f40a4f1..dc460b9 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 def0c4a87adbc25dec7eafdbf7329e7e97b6647b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 176/352] 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 47c0a4f35b617c0ea078c0b5bc543011d0ee5b69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 177/352] 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 5ea9921e6d886125d091f13a62db9c0149ba3a81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 178/352] 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 b7e0a2f2c5dc5138ec7304a5cd4c753a28dc5e0b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 179/352] 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 424e5827bc61b3c1be77d416069106e439f8951b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 180/352] 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 50d1a0c..d1848a2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2119,6 +2119,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 190e6b1e68b6043e651c7f438a4affbf99702610 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 27 Mar 2016 01:09:05 +0100 Subject: [PATCH 181/352] 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 b95ad0e..7f415b5 100644 --- a/docs-xml/smbdotconf/protocol/clientusespnego.xml +++ b/docs-xml/smbdotconf/protocol/clientusespnego.xml @@ -8,6 +8,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 d0f0a37..8c9a333 100644 --- a/docs-xml/smbdotconf/security/clientntlmv2auth.xml +++ b/docs-xml/smbdotconf/security/clientntlmv2auth.xml @@ -27,6 +27,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 c93cf634d7fb068f2572395e17dcd9107dea3668 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:02:34 +0100 Subject: [PATCH 182/352] 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 7b75f13..e79a292 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2529,6 +2529,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 c576b22..0c68baf 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -691,6 +691,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 ceec09315bb85e9b753a0deb763ccc3ca8de5222 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:02:34 +0100 Subject: [PATCH 183/352] 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 3a0247c..60532f9 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -676,6 +676,14 @@ struct parm_struct parm_table[] = { .enum_list = NULL, }, { + .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 5ebf5e3c029fa81e9e9154c851c639cf922e24ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 184/352] 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 b079d04..c23de7e 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 42e3860c662d5d6996aef0a63c08d63e7ae1c86b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 185/352] 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 406bd0d21af48e479cac30788da07c7a47b088c7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:08:38 +0100 Subject: [PATCH 186/352] 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 d16c440..24a9e24 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -213,6 +213,7 @@ sub setup_nt4_dc($$) 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 ed2c349a1f26245213d67da32116c41267796e21 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:59:42 +0100 Subject: [PATCH 187/352] 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 e79a292..bc588e4 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2529,7 +2529,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 0c68baf..a31cea6 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -691,7 +691,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 fd89cb2099936ca17f52b15c32ad84904c3f910c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Mar 2016 15:50:49 +0100 Subject: [PATCH 188/352] 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 8fcc7341a104e26b995c4b6c1dd67023e187c08f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 189/352] 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 d2f4ca7..db8de4e 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 db4ae82538dd4d2d783da65d6cf4d50ab95f7b5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 190/352] 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 db8de4e..79478e7 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 467a6ba3ab0119cd3ab2f3f285c8e0bfd4dcdf5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 191/352] 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 79478e7..c5d8219 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 8c1ab97d60a13c4f15fca2cfa1f4eca5dd517091 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:56:29 +0100 Subject: [PATCH 192/352] 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 f78f83e..0bcf817 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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) -- 1.9.1 From d7eba528509c76daa0645375e371e6557dff6281 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 12:45:56 +0100 Subject: [PATCH 193/352] 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 dc4555e467cb714eee4ff6a8d5726e67b14b55f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 12:03:56 +0100 Subject: [PATCH 194/352] 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 bc588e4..ac6b1d1 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2710,6 +2710,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 c762259..cc6f13d 100644 --- a/lib/param/loadparm.h +++ b/lib/param/loadparm.h @@ -193,6 +193,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 60532f9..90eb12d 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -222,6 +222,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 a31cea6..a037c6e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -742,6 +742,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 08ec7ea63665b092fdcc67a59a6785f2b27b34fb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:09:46 +0100 Subject: [PATCH 195/352] 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 90eb12d..b3b654f 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -1564,6 +1564,14 @@ struct parm_struct parm_table[] = { .enum_list = enum_ldap_sasl_wrapping, }, { + .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 fde7dc79d641bc38addeca8eb7b2d581ad6d371c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Aug 2015 12:19:37 +0200 Subject: [PATCH 196/352] 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 189a59041f007327c73db8c8b18e904b46f68342 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:07:02 +0100 Subject: [PATCH 197/352] 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 0bcf817..5ce4140 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -522,7 +522,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(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_spn.sh"), '$PREFIX/ad_dc_ntvfs']) -plantestsuite_loadlist("samba4.ldap.bind(ad_dc_ntvfs)", "ad_dc_ntvfs", [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 87dfe4bd72da2e543f34eb38816687d3d4bfdabb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:27:33 +0100 Subject: [PATCH 198/352] 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 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 9105b2d..4272159 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -530,6 +530,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 @@ -1319,7 +1320,9 @@ sub provision_ad_dc_ntvfs($$) print "PROVISIONING AD DC (NTVFS)..."; 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", @@ -1437,6 +1440,7 @@ sub provision_fl2008r2dc($$$) my ($self, $prefix, $dcvars) = @_; print "PROVISIONING DC WITH FOREST LEVEL 2008r2..."; + my $extra_conf_options = "ldap server require strong auth = no"; my $ret = $self->provision($prefix, "domain controller", "dc7", @@ -1446,7 +1450,7 @@ sub provision_fl2008r2dc($$$) "locDCpass7", undef, undef, - "", + $extra_conf_options, "", undef); -- 1.9.1 From 7ef87e1337f106fe332bcfe8c52b39400c32ec68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:04:48 +0100 Subject: [PATCH 199/352] 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 09a0f79..3f2ba71 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -316,3 +316,9 @@ # we can watch for set methods on. # ^samba.tests.dcerpc.integer.samba.tests.dcerpc.integer.IntegerTests.test_.*_into_uint8_list +# +## 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 5ce4140..e73ba27 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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%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(ad_dc_ntvfs:local)" % options, "ad_dc_ntvfs:local", "%s/test_ldb.sh ldapi $PREFIX_ABS/ad_dc_ntvfs/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 200/352] 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 ac6b1d1..90e980f 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2710,7 +2710,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 a037c6e..8e76e265 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -743,7 +743,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 a0e880fc772a8b6ab92ccfb2c2a28f3f754375f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 15:39:48 +0100 Subject: [PATCH 201/352] 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 e565e79822cd90298e1ae8eb44efbd246d12127f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 202/352] 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 5c3e9f1..5045e88 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); @@ -1362,6 +1447,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 83520a7..6584e36 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 94367a1..eb7f213 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 48b584cd974cf83e09777bc856a7e6b386c21839 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 22:12:56 +0100 Subject: [PATCH 203/352] 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 90e980f..4392172 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2574,6 +2574,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 b3b654f..db58733 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 @@ -124,6 +125,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 8e76e265..1a080d4 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -70,6 +70,7 @@ #include "dbwrap/dbwrap_rbt.h" #include "../lib/util/bitmap.h" #include "librpc/gen_ndr/nbt.h" +#include "source4/lib/tls/tls.h" #ifdef HAVE_SYS_SYSCTL_H #include @@ -867,6 +868,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = str_list_make_v3_const(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 c35c8aeda7dedb64a9eea849820ac6e83769b92e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:37:06 +0100 Subject: [PATCH 204/352] 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 db58733..815482b 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4048,6 +4048,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 425c3fb714b7ef996b6803fafea34459cb7ada31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 03:56:22 +0100 Subject: [PATCH 205/352] 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 e73ba27..4b7b97c 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 4a48ed09ad22ae5f5b55fcfe587fed0510f42977 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 206/352] 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 eb7f213..bcd6979 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 a8b82c48678854cae4d958146b06a85f21bb4698 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 207/352] 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 a09008088f4d36562af71625c0de5d54b6033731 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 15:07:36 +0100 Subject: [PATCH 208/352] 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 3f2ba71..b730e6f 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -322,3 +322,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 4b7b97c..9810196 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(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%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 e9089e860f82ecb29d787b8d396c5f4b8da53409 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:38:46 +0100 Subject: [PATCH 209/352] 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 11d661d..f7b7f95 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -586,6 +586,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 4272159..f8db618 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -523,6 +523,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 de45527c85d737071c5ba634c0f6ac7717434daa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 13:03:08 +0100 Subject: [PATCH 210/352] 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 4392172..72a9892 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2574,7 +2574,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 1a080d4..401eae4 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -868,7 +868,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = str_list_make_v3_const(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 d8c3f9ebc89cc7d03885f6456813abfeb0d83853 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 04:45:16 +0200 Subject: [PATCH 211/352] 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 d4b8de6..5e261a2 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 b19deb2ffd635d6fdee71cff0d2ddb063ac2acce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 212/352] 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 fe942c1..4e40758 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 18382a9..41b55eb 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -25,6 +25,7 @@ #include "../libcli/smb/smb2_negotiate_context.h" #include "../lib/tsocket/tsocket.h" #include "../librpc/ndr/libndr.h" +#include "../libcli/smb/smb_signing.h" extern fstring remote_proto; @@ -160,6 +161,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)) { @@ -287,7 +289,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 11d381f..fe64df0 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -258,7 +258,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, } 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 7d20be505792c5327bc20be69a45b0ad754989e5 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:25:32 +0100 Subject: [PATCH 213/352] 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 93a4f7ec019ed1c9736cb6c9165b6907186bd1aa Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:30:42 +0100 Subject: [PATCH 214/352] 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 d68bcb6..25b2ed6 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. @@ -599,7 +600,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 9cd478e3af612dc9c6cac82fe9acb8f4358f2966 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 215/352] 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 9fdb833..8bd7fda 100644 --- a/docs-xml/smbdotconf/security/serversigning.xml +++ b/docs-xml/smbdotconf/security/serversigning.xml @@ -10,7 +10,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 079123e6a7bcfa9e67650d08f6ee4effb8e04612 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:45:43 +0100 Subject: [PATCH 216/352] 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 e68226f..252c47e 100644 --- a/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml @@ -78,13 +78,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 c906a15..441f0ca 100644 --- a/docs-xml/smbdotconf/protocol/clientminprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientminprotocol.xml @@ -12,10 +12,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 72a9892..2e6fe86 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, "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"); @@ -3216,6 +3218,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 ecab853..bae10ef 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -941,6 +941,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 401eae4..b92e015 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -640,6 +640,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; @@ -4442,6 +4444,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 008c2952ada2e975f74758764b8c8672582be839 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 08:58:32 +0100 Subject: [PATCH 217/352] 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 815482b..01c1f3c 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4056,6 +4056,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 0f9a5d2faaaae0a3078f4daff988fac5e7a292e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:43:58 +0100 Subject: [PATCH 218/352] 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 60b8ffe..0e72674 100644 --- a/docs-xml/smbdotconf/security/clientsigning.xml +++ b/docs-xml/smbdotconf/security/clientsigning.xml @@ -8,14 +8,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 2e6fe86..4005bdb 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, "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"); @@ -3242,6 +3243,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 bae10ef..594456c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -943,6 +943,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 b92e015..c054002 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -823,6 +823,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; @@ -4468,6 +4469,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 067c38b429cb4223d26252ef51bc2082c3b8cfbb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 09:04:37 +0100 Subject: [PATCH 219/352] 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 01c1f3c..72d3189 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4072,6 +4072,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 70dece6cfbfaf2f9f0e6b8705c15c8458d6642f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:13:11 +0100 Subject: [PATCH 220/352] 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 57f92de40803817edaa54b3a3ec70fb6eef400e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:14:39 +0100 Subject: [PATCH 221/352] 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 c93120a66bd7ec7189293728a4b23b3e763d5526 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 222/352] 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 0eca08b7d520558ca4cb9470c3e8b8b791818c83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 223/352] 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 2f709650fc61c42dc579c936182b9b7b032885a4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Mar 2014 13:44:29 +0100 Subject: [PATCH 224/352] 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 20abf524e5db439596e2668a1f4fff8c99ac1486 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:23:58 +0100 Subject: [PATCH 225/352] 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 594456c..88be15a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -940,7 +940,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 c054002..52aa4b8 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4436,15 +4436,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 1964fcff..b6ed2de 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1049,8 +1049,8 @@ static NTSTATUS cm_prepare_connection(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 eb0ae2a2ad2668477e926b99a4a2e2853e8ede77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 13:22:16 +0100 Subject: [PATCH 226/352] 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 b6ed2de..075a818 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -996,7 +996,7 @@ static NTSTATUS cm_prepare_connection(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 955825feb86c5cd410ef96347beebe73800ec723 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 09:55:37 +0100 Subject: [PATCH 227/352] 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 4005bdb..8df1812 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3290,10 +3290,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 505d40d..14b5992 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -382,6 +382,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 c4cca15..04c9001 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -95,6 +95,7 @@ enum protocol_types { #define PROTOCOL_LATEST PROTOCOL_SMB3_11 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 6f28dfa..cfb3b16 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -170,6 +170,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 1b34a1797a945f7e23dada4f6cd546d18af9ad43 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 17:16:04 +0100 Subject: [PATCH 228/352] 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 d1848a2..2c351dd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3152,6 +3152,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); @@ -3181,6 +3183,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)) { @@ -3206,8 +3216,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 c6063437e60c38532d46a5d02ba86436ee63271d Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:00:09 +0100 Subject: [PATCH 229/352] 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 28553fc..5ed3129 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1933,7 +1933,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 1de08c4..93caf04 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -7396,7 +7396,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 b7c7628a565f523c8f8d05eba219c7ae38fa954f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:01:59 +0100 Subject: [PATCH 230/352] 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 0e05af8..37632af 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 31c1fb362f061637c73df09d3d26d5b80ade7254 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:13 +0100 Subject: [PATCH 231/352] 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 0dc6657..1a8cd91 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -89,7 +89,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 c6625cbcf8f5e525c3835b43ece02cc0c164373e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:52 +0100 Subject: [PATCH 232/352] 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 3e58b18..aab2d29 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -857,7 +857,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc, domain, pass, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); } /**************************************************************** @@ -1412,7 +1412,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, machine_domain, machine_password, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(status)) { status = cli_full_connection(&cli, NULL, @@ -1423,7 +1423,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 bf0e3b5b6a3c70dd38fe9ed9349fa099d2267e04 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:04:35 +0100 Subject: [PATCH 233/352] 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 4676b72..49b9ad6 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 b13769c7da99b1525dece60f3b17bb0a9cbbb3db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 23:52:30 +0100 Subject: [PATCH 234/352] 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 8df1812..f134fb0 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3247,11 +3247,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 52aa4b8..38def82 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4464,11 +4464,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 f3cf788ce06a6a84dc01516d0dc351e574be3a93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:12:18 +0200 Subject: [PATCH 235/352] 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 7c1e2d3..47c72c2 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 9a697ce..d65e75e 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; }; @@ -414,5 +419,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 8ece0ddb905ba45352ec8a29c289af925eaa9697 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 236/352] 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 b730e6f..2b5df61 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -97,6 +97,8 @@ ^samba4.rpc.netlogon.*.NetrEnumerateTrustedDomainsEx ^samba4.rpc.netlogon.*.GetPassword ^samba4.rpc.netlogon.*.DatabaseRedo +^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 d331313..3fe6c13 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 9810196..26552da 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 e4a2e80d031326456c0b9603a5934e32b8137e7c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 237/352] 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 3edd1b6..5e29ac7 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, @@ -1805,11 +1813,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 d01682e80f251ea3d3122903da91bc4e99dfad83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 22:15:00 +0100 Subject: [PATCH 238/352] 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 81db1875db1f15913f6d02cc4b6242491eb336fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 04:06:04 +0100 Subject: [PATCH 239/352] 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 14e473bda6a2692f827ffeb02c2acfca3c7b1fda Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 240/352] 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 b4108d9..c32fbc7 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1071,10 +1071,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 7a0b7ef53a736f8795a615f2f8bcd273cd842b60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 241/352] 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 f131d00..8e251ef 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 f1d4fa485a873a3cc1a32a464e9da7730f3e4ab8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 16:02:25 +0100 Subject: [PATCH 242/352] 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 9adaa61..e2e4a64 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -678,15 +678,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 ff68aa0523fccad702faa6ad278b1b6f8d05465e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 243/352] 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 f134fb0..5b90853 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2534,6 +2534,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 38def82..638579e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -698,6 +698,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 291f294c28a8b47fca6e5e18c1d70033e8450a84 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 18 Mar 2016 08:45:11 +0100 Subject: [PATCH 244/352] 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 72d3189..5f699cf 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4080,6 +4080,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 33568ca080bd2af47a69e683b9e4c53da40e23e9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 02:46:59 +0100 Subject: [PATCH 245/352] 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 47c72c2..aeed386 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 d65e75e..66cb1f4 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; }; @@ -423,5 +424,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 755baa77b9309faa90b47caa2f19c7c00ad52341 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 246/352] 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 c40322f..8a0f66b 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -34,6 +34,14 @@ #include "libcli/lsarpc/util_lsarpc.h" #include "lib/messaging/irpc.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 3474b34695d4cb93422bcc02f1297e44dad5f7a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 247/352] 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 2b5df61..01e9f36 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -99,6 +99,8 @@ ^samba4.rpc.netlogon.*.DatabaseRedo ^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 9f3bd10..c4ed1de 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 83b8738c95b7ecf8ebd29de234a113887eda2ec0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:52:48 +0200 Subject: [PATCH 248/352] 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 527718d..fd86c36 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -44,6 +44,14 @@ #include "librpc/gen_ndr/ndr_winbind_c.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 d8090473ecc11fcab6db03c9365abb3e697a4ca2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:17:40 +0100 Subject: [PATCH 249/352] 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 fc8477903a12a2e00ca55426ec7a4b5e1663cc86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:18:42 +0100 Subject: [PATCH 250/352] 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 61658b0a143aa7a15e14c40a6a2555dddf37dd84 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:19:04 +0100 Subject: [PATCH 251/352] 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 44cd559310f773b1bcccbb9d685637c6492f5208 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Mar 2016 04:40:30 +0100 Subject: [PATCH 252/352] 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 e55a1f36593a5429b2f82c7aa5a586494fb5d188 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 253/352] 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 01e9f36..0973e06 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -336,3 +336,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 c27a2e3fb670c226fa482cfe4904c134e356369b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:47:42 +0100 Subject: [PATCH 254/352] 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 4f9e203633e9b2e83e407ab7ae1d92a8c9d1ee4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 255/352] 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 5b90853..dac0f00 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2534,7 +2534,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 638579e..f357eb5 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -698,7 +698,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 049f128e69a67328d08b29fb71bce5b003644ed8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 256/352] 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 c4ed1de..69d48b8 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 ade42c8510bc4e718f8ad65811eff5bc0c550077 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 257/352] 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 7eb06cf..2f6f020 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 7814debbcc8b91717466647a34a6c5b33d139e64 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 22:46:05 +0200 Subject: [PATCH 258/352] 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 ce002a5e82dff130ec40d210b6fb996c29f4b166 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 259/352] 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 28600c9..f179f7a 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -186,9 +186,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 e9551a728f1d4240d64b85c18490805e6d8bff14 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 10:24:45 +0200 Subject: [PATCH 260/352] 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 c462561db7dbcd711d26745f3d84b11a6ae407c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 16:25:48 +0200 Subject: [PATCH 261/352] 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 47bf3d0..1b4c9a3 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 *); @@ -1547,6 +1549,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 { @@ -1571,6 +1580,8 @@ req_done: } } +static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req); + /* perform the send side of a async dcerpc request */ @@ -1581,6 +1592,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) { @@ -1603,6 +1615,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); @@ -1617,6 +1635,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 6385dd0..707e4cc 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 5a308599d35d043b3e660c225942f78f30136cf0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 262/352] 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 1b4c9a3..443b929 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 707e4cc..c7299fe 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 e93f21e308bad6fe70cb3db178acf1855eccebee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 263/352] 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 2d73a5d17d12a6668af4f69632de64c094d610be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 264/352] 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 443b929..68051ee 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -837,13 +837,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) { @@ -890,21 +890,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); } @@ -922,7 +919,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, @@ -962,7 +959,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 6067a4f798f2b07f7ee2b461d82e5f832977aa26 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 265/352] 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 68051ee..a4b40f6 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 8d52966830dd24c63f725c9e92cb8d0bbd736e42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 266/352] 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 a4b40f6..b7c5e6c 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -744,12 +744,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; @@ -769,6 +764,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); @@ -777,7 +780,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 aafe838f03fddae547746ba816a9adb8dd2bba25 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 267/352] 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 b7c5e6c..0ae15a6 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1464,8 +1464,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 67cb5c213e08cb131ca81fc78e8ddd19334ecfc6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 268/352] 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 0ae15a6..ae9c79d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1641,11 +1641,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 9ffde5752f6c02064604c206bbddbd357737408b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 269/352] 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 ae9c79d..ae3eb68 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1776,25 +1776,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) { @@ -1814,8 +1798,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 abde4f80546acd4dc434fd5b8c257544a1df8488 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 270/352] 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 0973e06..fb23524 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 ae3eb68..451a249 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; @@ -1226,7 +1225,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); } @@ -1299,6 +1298,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; @@ -1372,11 +1372,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; } @@ -1426,9 +1428,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; } @@ -2234,7 +2235,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); } @@ -2307,6 +2308,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; /* @@ -2365,12 +2367,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 c7299fe..39d28a6 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 1b7fac5acb4e4f099c54b2a4bfc84de8a5b17e9f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 271/352] 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 451a249..4ed86a1 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -778,6 +778,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 a3ad92502131132acfe4832a5f54ef2358131fdc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 272/352] 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 f179f7a..e3c9c0f 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -192,6 +192,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 720aa39131ef9c5867257b84605e734cfb701610 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 273/352] 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 f642d30..f31a330 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 3a8947a64335cf229ce3561000e07625749e75c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 274/352] 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 f31a330..6e0a7ea 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 1798958160d47d0da03d49fb7f1adfdfc026363e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 275/352] 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 4ed86a1..73c9f4d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1345,13 +1345,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 0d8da7b0e68d88e2636f258652d39cbd11b0f5a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 276/352] 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 73c9f4d..7c900d2 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2350,17 +2350,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))); @@ -2378,6 +2367,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 a27366d99e63a795dac01aa9c583ce014a6bc081 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 277/352] 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 7c900d2..fde0eb1 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -743,6 +743,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: @@ -1344,8 +1353,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; @@ -2367,25 +2388,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 e2980b5dc559fe021d0b5e6e1cc5858c54fae6e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:08:46 +0200 Subject: [PATCH 278/352] 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 fde0eb1..97acbef 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1569,6 +1569,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 58df2a722ff4a78005d14d9c5913ddb3a2c06387 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 279/352] 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 aeed386..b79c748 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->initial_euid = geteuid(); dce_ctx->endpoint_list = NULL; @@ -1609,7 +1609,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; @@ -1884,7 +1884,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 */ @@ -1940,7 +1940,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 */ @@ -1974,7 +1974,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 */ @@ -2012,7 +2012,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 671e3c83358f6b4585b8338054a0c6ad9918335b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 280/352] 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 fb23524..0973e06 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 587940ea2ac3f568e112fdb1f54f98b4e58ffe73 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 281/352] 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 9413b7f2b443c66e45198e071e70b815187a9a27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 11:03:58 +0200 Subject: [PATCH 282/352] 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 66cb1f4..c525c31 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 1bd8704fcd94e513aa83ce9c21991771ec5789a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 16:02:31 +0100 Subject: [PATCH 283/352] 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 b79c748..e62a3dc 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 18f1865d9863d570fcee9afea1093eb4fe11f8b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 284/352] 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 9a8fdfb..f4da0b48 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); } @@ -946,7 +946,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; @@ -959,8 +959,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 1821282704671d203b2d97a7048335d7dda1550f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 285/352] 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 69d48b8..423fcf0 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 3e3f506170d97d3f1b3cdd6a0d78442603a15916 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 286/352] 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 fd86c36..7a92a6d 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -536,7 +536,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) { @@ -572,12 +572,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)) { @@ -1010,13 +1009,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; } @@ -1076,8 +1069,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 dc947aee77d27df373a4afe29ded649f36bc37dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 287/352] 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 e62a3dc..91a7855 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 c525c31..603a55d 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 712375ba57eac3cb729919b3cf9cbad1ed709f42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 288/352] 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 a4a57ed87ae180f85f18303c97e308e7b684a4db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 289/352] 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 085a643c0f6ae7479a02e6c036891fa1dae0ca20 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 290/352] 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 fa101859279e7c6ae70ea9feb71c23beb3da7483 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 291/352] 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 de812b509be2f925ebc6c19f913c6f7fb592778d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 292/352] 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 91a7855..6a353d5 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 4ce8a8822f70ded09e92bbcb72ff1648b0a973b8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 293/352] 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 6a353d5..5be3fd9 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 285d6c2c91ecadd8a8f58bd9197afdd5b2fe216c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 294/352] 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 5be3fd9..be65203 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 2beecdb8116862293b00d40e532823221460e14c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 295/352] 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 be65203..6b629e0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1629,6 +1629,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) { @@ -1655,7 +1656,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; } @@ -1675,6 +1676,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; } @@ -1702,8 +1717,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 603a55d..6c52cb0 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 c6c0c8b90200e7cb89776e7986692b5c0f2994cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 296/352] 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 6b629e0..60b5b83 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 fe5425f483c32938c625783756735ce4c586bea8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 297/352] 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 60b5b83..2618ca8 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; } @@ -1666,6 +1698,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 6c52cb0..2627f75 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 a38d92a7468040825d1bdde9fc6a129d824d902d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 298/352] 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 2618ca8..d3e6618 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 2627f75..cd0b0e4 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 540eaaca02162071fbf6bc560c62854ccfa960dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 299/352] 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 190cfa69e88ff3a4bbbc0003754c636eeefe69ca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 300/352] 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 d3e6618..d0729f2 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 669dc0f3f6d8e3f39e92daa9ef4559f7cb2661b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 301/352] 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 d0729f2..cd464e7 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 2ad7b05ed83a12bb734a723b5280a6fa8b1c9a8b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 302/352] 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 cd464e7..9199d9b 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 b90be16c75a9e09c2cb86ea7f175f8a8c737960d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 303/352] 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 9199d9b..7307871 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 3592fddc64e2a350c03afc982a463aae5a5e4a24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 304/352] 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 7307871..e014b17 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 0fbffa85edb919571c9d7e2c88f78f69991d299c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 305/352] 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 e014b17..c1bc5c7 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 1b278527dce109b06e6f9b406af4e1edf2ce4b54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 306/352] 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 c1bc5c7..d537c66 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 cd0b0e4..595fad6 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 c1dc766ced57f07fe346f4a5276ca3798d56e905 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 307/352] 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 d537c66..fa2849f 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 6a9bcdacb9c75f2fa1a573c4037124f4f8cc6f99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:55:27 +0200 Subject: [PATCH 308/352] 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 fa2849f..0103f4f 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 38085c88a15a11ef932b868882762d9bab80ee24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 17:21:05 +0200 Subject: [PATCH 309/352] 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 0103f4f..951e028 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 ea186ba67e55898b5088ec0622883cb79e540577 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 14:18:09 +0200 Subject: [PATCH 310/352] 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 951e028..d8b7c77 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 99a8c5f50393d51347386691304bfd83ce3c4e89 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 05:01:26 +0200 Subject: [PATCH 311/352] 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 d8b7c77..957d22c 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 db27056716ed678fb4618b3e95974ce581a69e2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 312/352] 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 957d22c..7b17f9f 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 595fad6..7e8b18a 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 ded21874c55f429640d187ad99762ac6d18aee40 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 313/352] 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 7b17f9f..a303d3c 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 36eb0b9b4c558eb6a14cb9d87f862dba8dfa849b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 314/352] 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 14a94b4a75f0b855c6d2b585bbde9aa45df52867 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 315/352] 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 6e0a7ea..0fb848f 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 5e27277f849d1204f6ef90f6379d6aa53c9b56ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 316/352] 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 5480ae72baa04d505e27d03896af3a6127c0a8f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 317/352] 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 0fb848f..9269f24 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 eedb715ce6259f50c2fbf19790b35e3bcf660c38 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 318/352] 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 9269f24..56e5d17 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 d0d3de26b274b3299a00e8686ace20d1042692fc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:48:38 +0200 Subject: [PATCH 319/352] 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 56e5d17..26f709d 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 18b8d0db77dfee28bba262e4f379a14b4497f74a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 320/352] 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 26f709d..1d1ccad 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 28f2b07a3f11f5f7f0c421d0e53e3f982a1fd83e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 321/352] 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 c23df593512a51a6fa42c06846b195cdacdc6996 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 322/352] 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 0d0ae6fcf35c2ae2ac5cdbe1f61b305335eab348 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 323/352] 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 a5ceef000ad23da0f8afc41cd98ee2db5d809080 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 324/352] 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 372ab6ce15a5c3adb0f1dd2eede3c3942d7fb533 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 325/352] 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 e60abf67e0a3c3d6bdb61e27194d51692dafb69b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 326/352] 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 1ddf445aa1e26bc0fc21dc80612b57a84b160be1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 327/352] 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 8ac315eb8b8daa5d1cddad0e48bfb2af756166b5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Jul 2015 09:15:39 +0200 Subject: [PATCH 328/352] 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 ff7fbf345a4a6a921619a1ed89e58ae665ff0bf7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 329/352] 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 52c86da568cd44b9e177cef78c91fa5fd04d2da0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 330/352] 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 97862dc48744eb800f621e6cbfe7abcfb6bca6b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 331/352] 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 1ff30626dcde09e41e40b2654befb9046055068d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:40:58 +0100 Subject: [PATCH 332/352] 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 b0b0e4f245daeeaa1f42d7d7d765147cadffb461 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 333/352] 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 c46422d0999bffbfd7e66cf96bb5be890ee225e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 334/352] 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 f73bf9ef9fd374a04b996599fb02a4750c0dc33c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Jul 2015 10:58:07 +0200 Subject: [PATCH 335/352] 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 9f823050e25cfa94c58c74645d52fab32cb85f43 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 336/352] 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 3b0441fd9e2609304d0e939be6d098af726e5026 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 337/352] 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 db85c440094dfb2d7019d1b780ceb4c6d0547a3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 338/352] 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 1d1ccad..6402637 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 7eff7c7b1fedaa8437754ca45df17638575e1543 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 339/352] 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 1b26e9bfbf353146aebda9c71a40283f94b3f648 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 340/352] 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 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6402637..3015cbb 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)) { @@ -2369,6 +2369,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); @@ -2429,6 +2430,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); @@ -2499,6 +2501,7 @@ static NTSTATUS rpccli_generic_bind_data_from_creds(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 b333a0f91994c06f737de670e2c8669f5693fa38 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 341/352] 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 d53da4b1c2faf12cd3eb46ad57f046f9bcc8dce6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 342/352] 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 c959b8ea3331fadd04e667f81cb24cd6fece1e10 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 343/352] 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 11d79eef6f5421cfc5926a7b8c2576e05dd59a03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 344/352] 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 3015cbb..00ff530 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 baa92e257f743e3a03c9cc09dd0a35eefd667c5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 345/352] 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 2b87d970c502501d4a9f093fea42da0059cc67e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:05:45 +0100 Subject: [PATCH 346/352] 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 a5e025c5e3ba57dfa06f950f7e00421ab786a349 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:23:14 +0100 Subject: [PATCH 347/352] 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 00ff530..97f4944 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; } @@ -2275,8 +2335,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 878a1c2b5ef6eeea6e2c95ea68b7df38d706a880 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:13:41 +0100 Subject: [PATCH 348/352] 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 97acbef..ade742c 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1546,7 +1546,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; @@ -1555,16 +1564,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; @@ -1573,9 +1581,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 2f050fe5eddd973d116c123561da065d4dacd4f1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 349/352] 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 3fa6f93cb815c046b03f0db419e8e1542b4d3bca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 350/352] 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 351/352] CVE-2015-5370: s4:selftest: run samba.tests.dcerpc.raw_protocol against ad_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 26552da..6de8527 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -540,6 +540,7 @@ planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.rpcecho") planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.registry", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) plantestsuite_loadlist("samba4.ldap.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite("samba4.sam.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) -- 1.9.1 From 88ce9d04783ebb8701c5bb25f351f9c36bee994b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Apr 2016 10:05:38 +0200 Subject: [PATCH 352/352] 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