[PR PATCH] [Updated] samba-tool domain trust: fix trust compatibility to Windows Server 1709 and FreeIPA
Stefan Metzmacher
metze at samba.org
Thu Jul 19 08:06:53 UTC 2018
Hi Alexander,
I've implemented the autodetection of smb1 and smb2 for our dcerpc
client side.
Please review patches 1-13 from the attached patchset and push it.
Here's the related pending pipeline:
https://gitlab.com/samba-team/devel/samba/pipelines/26062213
>> Can you split the last patch and demonstrate the the test passes with
>> a temporary file in selftest/knownfail.d/ and then gets fixed with the
>> changes. From reading the test I guess it won't fail as the bug happens
>> in two places.
> Thing is, it will not fail for wrong salt too because we are running
> against the same code that uses the same method to generate salt
> principal. So before the patch we've got 'EXAMPLE.COMFOO$' as a salt,
> after the patch we'd get 'EXAMPLE.COMkrbtgtFOO' but in both cases both
> client and KDC would be operating with the same salt because we retrieve
> this keytab from the same KDC.
>
> I wonder if we can retrieve it from a different KDC and store under
> the proper principal but current code for keytab retrieval in libnet
> doesn't handle that because it has no way to specify a different
> principal name when writing keys to a keytab (we want to retrieve
> FOO$@EXAMPLE.COM as EXAMPLE$@FOO.COM and then try to auth against
> FOO.COM KDC).
>
> With my parallel patches (in works) to FreeIPA and SSSD, I get Samba AD
> DC properly trusted by FreeIPA and FreeIPA properly trusted by Samba AD
> DC when trust is driven from FreeIPA side. So salt fixes helped, for
> cases when TDA is used for authentication by both sides. There
> is a remaining need to fix cross-realm TGT on FreeIPA side to allow
> FreeIPA -> Samba AD leg to work with cross-realm referral issuance.
> Samba AD -> FreeIPA leg works already.
I ported the patch to master (some defines are different...)
The pipeline with the complete set is:
https://gitlab.com/samba-team/devel/samba/pipelines/26062727
In the commit message of path 14 I added some TODOs:
TODO: unit tests: loop over all account types with, loop over names with
and without upn, with and without '$'. Use 'eXaMpLe.COM' and similar
names to check the correct upper/lower case result.
TODO: Also verify this against windows...
A test can create objects via ldap and/or lsa (for trusts)
then get the object including supplementalCredentials
via drsuapi (as admin) and check the stored salt.
We should have similar tests already.
I think we need at least some test that can't fail because
of a symmetric fix.
Would you have time to work on such tests?
metze
-------------- next part --------------
From 5835a998fe39571ab062a3f730a620eec5ce7e8e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 15:36:31 +0200
Subject: [PATCH 01/15] s4:libcli: split out smb_raw_negotiate_fill_transport()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/raw/rawnegotiate.c | 74 ++++++++++++++++++-------------
1 file changed, 44 insertions(+), 30 deletions(-)
diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c
index 73c9123411d6..cec081c364a4 100644
--- a/source4/libcli/raw/rawnegotiate.c
+++ b/source4/libcli/raw/rawnegotiate.c
@@ -28,6 +28,47 @@
#include "../libcli/smb/smbXcli_base.h"
#include "../lib/util/tevent_ntstatus.h"
+NTSTATUS smb_raw_negotiate_fill_transport(struct smbcli_transport *transport)
+{
+ struct smbcli_negotiate *n = &transport->negotiate;
+ struct smbXcli_conn *c = transport->conn;
+ NTTIME ntt;
+
+ n->protocol = smbXcli_conn_protocol(c);
+ if (n->protocol > PROTOCOL_NT1) {
+ return NT_STATUS_REVISION_MISMATCH;
+ }
+
+ n->sec_mode = smb1cli_conn_server_security_mode(c);
+ n->max_mux = smbXcli_conn_max_requests(c);
+ n->max_xmit = smb1cli_conn_max_xmit(c);
+ n->sesskey = smb1cli_conn_server_session_key(c);
+ n->capabilities = smb1cli_conn_capabilities(c);;
+
+ /* this time arrives in real GMT */
+ ntt = smbXcli_conn_server_system_time(c);
+ n->server_time = nt_time_to_unix(ntt);
+ n->server_zone = smb1cli_conn_server_time_zone(c);
+
+ if (n->capabilities & CAP_EXTENDED_SECURITY) {
+ const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c);
+ if (b) {
+ n->secblob = *b;
+ }
+ } else {
+ const uint8_t *p = smb1cli_conn_server_challenge(c);
+ if (p) {
+ n->secblob = data_blob_const(p, 8);
+ }
+ }
+
+ n->readbraw_supported = smb1cli_conn_server_readbraw(c);
+ n->readbraw_supported = smb1cli_conn_server_writebraw(c);
+ n->lockread_supported = smb1cli_conn_server_lockread(c);
+
+ return NT_STATUS_OK;
+}
+
struct smb_raw_negotiate_state {
struct smbcli_transport *transport;
};
@@ -82,10 +123,7 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq)
struct smb_raw_negotiate_state *state =
tevent_req_data(req,
struct smb_raw_negotiate_state);
- struct smbcli_negotiate *n = &state->transport->negotiate;
- struct smbXcli_conn *c = state->transport->conn;
NTSTATUS status;
- NTTIME ntt;
status = smbXcli_negprot_recv(subreq);
TALLOC_FREE(subreq);
@@ -93,35 +131,11 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq)
return;
}
- n->protocol = smbXcli_conn_protocol(c);
-
- n->sec_mode = smb1cli_conn_server_security_mode(c);
- n->max_mux = smbXcli_conn_max_requests(c);
- n->max_xmit = smb1cli_conn_max_xmit(c);
- n->sesskey = smb1cli_conn_server_session_key(c);
- n->capabilities = smb1cli_conn_capabilities(c);;
-
- /* this time arrives in real GMT */
- ntt = smbXcli_conn_server_system_time(c);
- n->server_time = nt_time_to_unix(ntt);
- n->server_zone = smb1cli_conn_server_time_zone(c);
-
- if (n->capabilities & CAP_EXTENDED_SECURITY) {
- const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c);
- if (b) {
- n->secblob = *b;
- }
- } else {
- const uint8_t *p = smb1cli_conn_server_challenge(c);
- if (p) {
- n->secblob = data_blob_const(p, 8);
- }
+ status = smb_raw_negotiate_fill_transport(state->transport);
+ if (tevent_req_nterror(req, status)) {
+ return;
}
- n->readbraw_supported = smb1cli_conn_server_readbraw(c);
- n->readbraw_supported = smb1cli_conn_server_writebraw(c);
- n->lockread_supported = smb1cli_conn_server_lockread(c);
-
tevent_req_done(req);
}
--
2.17.1
From 79d799005ac5d4c901c2aed35adc2082b0d4bc99 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 15:36:52 +0200
Subject: [PATCH 02/15] s4:libcli: add smbcli_transport_raw_init()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/raw/clitransport.c | 44 +++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index d0dd1f9dee6a..47b8dbf3ae7f 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -113,6 +113,50 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
return transport;
}
+/*
+ create a transport structure based on an established socket
+*/
+NTSTATUS smbcli_transport_raw_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbXcli_conn **_conn,
+ const struct smbcli_options *options,
+ struct smbcli_transport **_transport)
+{
+ struct smbcli_transport *transport = NULL;
+ NTSTATUS status;
+
+ if (*_conn == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ transport = talloc_zero(mem_ctx, struct smbcli_transport);
+ if (transport == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ transport->ev = ev;
+ transport->options = *options;
+
+ /*
+ * First only set the pointer without move.
+ */
+ transport->conn = *_conn;
+ status = smb_raw_negotiate_fill_transport(transport);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(transport);
+ return status;
+ }
+
+ talloc_set_destructor(transport, transport_destructor);
+
+ /*
+ * Now move it away from the caller...
+ */
+ transport->conn = talloc_move(transport, _conn);
+ *_transport = transport;
+ return NT_STATUS_OK;
+}
+
/*
mark the transport as dead
*/
--
2.17.1
From 639cf055204db0480e23f401a58f3b59f792d6eb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 15:01:50 +0200
Subject: [PATCH 03/15] s4:libcli: use talloc_zero() for struct
smb_composite_connect in fetchfile.c
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb_composite/fetchfile.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c
index d19c86a8d05b..dc6f71b452e2 100644
--- a/source4/libcli/smb_composite/fetchfile.c
+++ b/source4/libcli/smb_composite/fetchfile.c
@@ -131,7 +131,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc
state = talloc(c, struct fetchfile_state);
if (state == NULL) goto failed;
- state->connect = talloc(state, struct smb_composite_connect);
+ state->connect = talloc_zero(state, struct smb_composite_connect);
if (state->connect == NULL) goto failed;
state->io = io;
--
2.17.1
From 606d623554b9e6b6a47fe0ebd232e2cf898d6200 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 15:34:55 +0200
Subject: [PATCH 04/15] s4:libcli: allow passing an already negotiated
connection to smb_composite_connect()
It will just do the session setup and tree connect steps.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/raw/clitree.c | 1 +
source4/libcli/smb_composite/connect.c | 48 ++++++++++++++++----
source4/libcli/smb_composite/smb_composite.h | 1 +
source4/ntvfs/cifs/vfs_cifs.c | 1 +
4 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c
index 11be5485f261..b1b6159e7508 100644
--- a/source4/libcli/raw/clitree.c
+++ b/source4/libcli/raw/clitree.c
@@ -207,6 +207,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
io.in.called_name = strupper_talloc(tmp_ctx, dest_host);
io.in.service = service;
io.in.service_type = service_type;
+ io.in.existing_conn = NULL;
io.in.credentials = credentials;
io.in.gensec_settings = gensec_settings;
io.in.fallback_to_anonymous = false;
diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c
index fffa768ac977..582d43ef1730 100644
--- a/source4/libcli/smb_composite/connect.c
+++ b/source4/libcli/smb_composite/connect.c
@@ -228,18 +228,10 @@ static NTSTATUS connect_session_setup(struct composite_context *c,
return NT_STATUS_OK;
}
-/*
- a negprot request has completed
-*/
-static NTSTATUS connect_negprot(struct composite_context *c,
- struct smb_composite_connect *io)
+static NTSTATUS connect_send_session(struct composite_context *c,
+ struct smb_composite_connect *io)
{
struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
- NTSTATUS status;
-
- status = smb_raw_negotiate_recv(state->subreq);
- TALLOC_FREE(state->subreq);
- NT_STATUS_NOT_OK_RETURN(status);
/* next step is a session setup */
state->session = smbcli_session_init(state->transport, state, true, io->in.session_options);
@@ -281,6 +273,22 @@ static NTSTATUS connect_negprot(struct composite_context *c,
return NT_STATUS_OK;
}
+/*
+ a negprot request has completed
+*/
+static NTSTATUS connect_negprot(struct composite_context *c,
+ struct smb_composite_connect *io)
+{
+ struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
+ NTSTATUS status;
+
+ status = smb_raw_negotiate_recv(state->subreq);
+ TALLOC_FREE(state->subreq);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ return connect_send_session(c, io);
+}
+
/*
setup a negprot send
*/
@@ -432,6 +440,26 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
nbt_choose_called_name(state, &state->called,
io->in.called_name, NBT_NAME_SERVER);
+ if (io->in.existing_conn != NULL) {
+ NTSTATUS status;
+
+ status = smbcli_transport_raw_init(state,
+ c->event_ctx,
+ &io->in.existing_conn,
+ &io->in.options,
+ &state->transport);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ status = connect_send_session(c, io);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ return c;
+ }
+
state->creq = smbcli_sock_connect_send(state,
NULL,
io->in.dest_ports,
diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h
index a92c9612c6ac..383946f1307a 100644
--- a/source4/libcli/smb_composite/smb_composite.h
+++ b/source4/libcli/smb_composite/smb_composite.h
@@ -118,6 +118,7 @@ struct smb_composite_connect {
const char *called_name;
const char *service;
const char *service_type;
+ struct smbXcli_conn *existing_conn; /* optional */
struct cli_credentials *credentials;
bool fallback_to_anonymous;
const char *workgroup;
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 478428e32465..d88c034c6f2a 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -296,6 +296,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
io.in.dest_ports = lpcfg_smb_ports(ntvfs->ctx->lp_ctx);
io.in.socket_options = lpcfg_socket_options(ntvfs->ctx->lp_ctx);
io.in.called_name = host;
+ io.in.existing_conn = NULL;
io.in.credentials = credentials;
io.in.fallback_to_anonymous = false;
io.in.workgroup = lpcfg_workgroup(ntvfs->ctx->lp_ctx);
--
2.17.1
From af9ed03a678cc5a894e8fbebd137c4f35125a054 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 16:43:04 +0200
Subject: [PATCH 05/15] s4:libcli: add smb2_transport_raw_init()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb2/transport.c | 35 +++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 166f34b82569..1d08289341ba 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -85,6 +85,41 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
return transport;
}
+/*
+ create a transport structure based on an established socket
+*/
+NTSTATUS smb2_transport_raw_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbXcli_conn **_conn,
+ const struct smbcli_options *options,
+ struct smb2_transport **_transport)
+{
+ struct smb2_transport *transport = NULL;
+ enum protocol_types protocol;
+
+ if (*_conn == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ protocol = smbXcli_conn_protocol(*_conn);
+ if (protocol < PROTOCOL_SMB2_02) {
+ return NT_STATUS_REVISION_MISMATCH;
+ }
+
+ transport = talloc_zero(mem_ctx, struct smb2_transport);
+ if (transport == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ transport->ev = ev;
+ transport->options = *options;
+ transport->conn = talloc_move(transport, _conn);
+
+ talloc_set_destructor(transport, transport_destructor);
+ *_transport = transport;
+ return NT_STATUS_OK;
+}
+
/*
mark the transport as dead
*/
--
2.17.1
From c39fca2f9007509bfadd39bf5e7f2c2bfe80fc91 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 16:43:32 +0200
Subject: [PATCH 06/15] s4:libcli: split out smb2_connect_session_start()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb2/connect.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 8ff56c9ca8f8..ac37eae6aa89 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -50,6 +50,7 @@ struct smb2_connect_state {
struct smb2_tree *tree;
};
+static void smb2_connect_session_start(struct tevent_req *req);
static void smb2_connect_socket_done(struct composite_context *creq);
/*
@@ -170,10 +171,6 @@ static void smb2_connect_negprot_done(struct tevent_req *subreq)
struct tevent_req *req =
tevent_req_callback_data(subreq,
struct tevent_req);
- struct smb2_connect_state *state =
- tevent_req_data(req,
- struct smb2_connect_state);
- struct smb2_transport *transport = state->transport;
NTSTATUS status;
status = smbXcli_negprot_recv(subreq);
@@ -182,6 +179,17 @@ static void smb2_connect_negprot_done(struct tevent_req *subreq)
return;
}
+ smb2_connect_session_start(req);
+}
+
+static void smb2_connect_session_start(struct tevent_req *req)
+{
+ struct smb2_connect_state *state =
+ tevent_req_data(req,
+ struct smb2_connect_state);
+ struct smb2_transport *transport = state->transport;
+ struct tevent_req *subreq = NULL;
+
state->session = smb2_session_init(transport, state->gensec_settings, state);
if (tevent_req_nomem(state->session, req)) {
return;
--
2.17.1
From dde3c6103d48035e950633cc3c3bfd7961bef5eb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 16:44:16 +0200
Subject: [PATCH 07/15] s4:libcli: allow passing an already negotiated
connection to smb2_connect_send()
It will just do the session setup and tree connect steps.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb2/connect.c | 21 +++++++++++++++++++++
source4/librpc/rpc/dcerpc_connect.c | 1 +
2 files changed, 22 insertions(+)
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index ac37eae6aa89..2dee50218694 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -64,6 +64,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
const char *share,
struct resolve_context *resolve_ctx,
struct cli_credentials *credentials,
+ struct smbXcli_conn **existing_conn,
uint64_t previous_session_id,
const struct smbcli_options *options,
const char *socket_options,
@@ -107,6 +108,25 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ if (existing_conn != NULL) {
+ NTSTATUS status;
+
+ status = smb2_transport_raw_init(state, ev,
+ existing_conn,
+ options,
+ &state->transport);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ smb2_connect_session_start(req);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+ }
+
creq = smbcli_sock_connect_send(state, NULL, state->ports,
state->host, state->resolve_ctx,
state->ev, state->socket_options,
@@ -311,6 +331,7 @@ NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx,
share,
resolve_ctx,
credentials,
+ NULL, /* existing_conn */
previous_session_id,
options,
socket_options,
diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c
index 1252e74b5a9d..a3f25efc0b47 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -301,6 +301,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send(
"IPC$",
s->io.resolve_ctx,
s->io.creds,
+ NULL, /* existing_conn */
0, /* previous_session_id */
&options,
lpcfg_socket_options(lp_ctx),
--
2.17.1
From 5529fc17ec3f59103d6da17a5b11546334a46e5f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 23:52:30 +0200
Subject: [PATCH 08/15] s4:libcli: add fallback_to_anonymous to
smb2_connect_send()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb2/connect.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 2dee50218694..e4cbf8c5c419 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -35,6 +35,7 @@
struct smb2_connect_state {
struct tevent_context *ev;
struct cli_credentials *credentials;
+ bool fallback_to_anonymous;
uint64_t previous_session_id;
struct resolve_context *resolve_ctx;
const char *host;
@@ -64,6 +65,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
const char *share,
struct resolve_context *resolve_ctx,
struct cli_credentials *credentials,
+ bool fallback_to_anonymous,
struct smbXcli_conn **existing_conn,
uint64_t previous_session_id,
const struct smbcli_options *options,
@@ -83,6 +85,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->credentials = credentials;
+ state->fallback_to_anonymous = fallback_to_anonymous;
state->previous_session_id = previous_session_id;
state->options = *options;
state->host = host;
@@ -240,6 +243,34 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
status = smb2_session_setup_spnego_recv(subreq);
TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status) &&
+ !cli_credentials_is_anonymous(state->credentials) &&
+ state->fallback_to_anonymous) {
+ struct cli_credentials *anon_creds = NULL;
+
+ /*
+ * The transport was moved to session,
+ * we need to revert that before removing
+ * the old broken session.
+ */
+ state->transport = talloc_move(state, &state->session->transport);
+ TALLOC_FREE(state->session);
+
+ anon_creds = cli_credentials_init_anon(state);
+ if (tevent_req_nomem(anon_creds, req)) {
+ return;
+ }
+ cli_credentials_set_workstation(anon_creds,
+ cli_credentials_get_workstation(state->credentials),
+ CRED_SPECIFIED);
+
+ /*
+ * retry with anonymous credentials
+ */
+ state->credentials = anon_creds;
+ smb2_connect_session_start(req);
+ return;
+ }
if (tevent_req_nterror(req, status)) {
return;
}
@@ -331,6 +362,7 @@ NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx,
share,
resolve_ctx,
credentials,
+ false, /* fallback_to_anonymous */
NULL, /* existing_conn */
previous_session_id,
options,
--
2.17.1
From c5ac6f40c6fe93e273c7b4208bbf2405d0db8dad Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 14:52:43 +0200
Subject: [PATCH 09/15] s4:libcli: add smb_connect_nego_{send,recv}()
This can be used to create a connection up to a negotiated
smbXcli_conn.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/libcli/smb_composite/connect_nego.c | 206 +++++++++++++++++++
source4/libcli/smb_composite/smb_composite.h | 21 ++
source4/libcli/wscript_build | 20 +-
3 files changed, 242 insertions(+), 5 deletions(-)
create mode 100644 source4/libcli/smb_composite/connect_nego.c
diff --git a/source4/libcli/smb_composite/connect_nego.c b/source4/libcli/smb_composite/connect_nego.c
new file mode 100644
index 000000000000..14538c76afcb
--- /dev/null
+++ b/source4/libcli/smb_composite/connect_nego.c
@@ -0,0 +1,206 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Stefan Metzmacher 2018
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "libcli/composite/composite.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "lib/socket/socket.h"
+#include "libcli/resolve/resolve.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "libcli/smb/smbXcli_base.h"
+
+struct smb_connect_nego_state {
+ struct tevent_context *ev;
+ struct resolve_context *resolve_ctx;
+ const char *socket_options;
+ struct smbcli_options options;
+ const char *dest_hostname;
+ const char *dest_address;
+ const char **dest_ports;
+ struct nbt_name calling, called;
+ struct smbXcli_conn *conn;
+};
+
+static void smb_connect_nego_connect_done(struct composite_context *creq);
+static void smb_connect_nego_nego_done(struct tevent_req *subreq);
+
+struct tevent_req *smb_connect_nego_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resolve_context *resolve_ctx,
+ const struct smbcli_options *options,
+ const char *socket_options,
+ const char *dest_hostname,
+ const char *dest_address, /* optional */
+ const char **dest_ports,
+ const char *called_name,
+ const char *calling_name)
+{
+ struct tevent_req *req = NULL;
+ struct smb_connect_nego_state *state = NULL;
+ struct composite_context *creq = NULL;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct smb_connect_nego_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->resolve_ctx= resolve_ctx;
+ state->options = *options;
+ state->socket_options = socket_options;
+ state->dest_hostname = dest_hostname;
+ state->dest_address = dest_address;
+ state->dest_ports = dest_ports;
+
+ make_nbt_name_client(&state->calling, calling_name);
+
+ nbt_choose_called_name(state, &state->called,
+ called_name, NBT_NAME_SERVER);
+ if (tevent_req_nomem(state->called.name, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ creq = smbcli_sock_connect_send(state,
+ state->dest_address,
+ state->dest_ports,
+ state->dest_hostname,
+ state->resolve_ctx,
+ state->ev,
+ state->socket_options,
+ &state->calling,
+ &state->called);
+ if (tevent_req_nomem(creq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ creq->async.private_data = req;
+ creq->async.fn = smb_connect_nego_connect_done;
+
+ return req;
+}
+
+static void smb_connect_nego_connect_done(struct composite_context *creq)
+{
+ struct tevent_req *req =
+ talloc_get_type_abort(creq->async.private_data,
+ struct tevent_req);
+ struct smb_connect_nego_state *state =
+ tevent_req_data(req,
+ struct smb_connect_nego_state);
+ struct tevent_req *subreq = NULL;
+ struct smbcli_socket *sock = NULL;
+ uint32_t smb1_capabilities;
+ uint32_t timeout_msec = state->options.request_timeout * 1000;
+ NTSTATUS status;
+
+ status = smbcli_sock_connect_recv(creq, state, &sock);
+ creq = NULL;
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+
+ TALLOC_FREE(sock->event.fde);
+ TALLOC_FREE(sock->event.te);
+
+ smb1_capabilities = 0;
+ smb1_capabilities |= CAP_LARGE_FILES;
+ smb1_capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
+ smb1_capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND;
+ smb1_capabilities |= CAP_DFS | CAP_W2K_SMBS;
+ smb1_capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX;
+ smb1_capabilities |= CAP_LWIO;
+
+ if (state->options.ntstatus_support) {
+ smb1_capabilities |= CAP_STATUS32;
+ }
+
+ if (state->options.unicode) {
+ smb1_capabilities |= CAP_UNICODE;
+ }
+
+ if (state->options.use_spnego) {
+ smb1_capabilities |= CAP_EXTENDED_SECURITY;
+ }
+
+ if (state->options.use_level2_oplocks) {
+ smb1_capabilities |= CAP_LEVEL_II_OPLOCKS;
+ }
+
+ state->conn = smbXcli_conn_create(state,
+ sock->sock->fd,
+ state->dest_hostname,
+ state->options.signing,
+ smb1_capabilities,
+ &state->options.client_guid,
+ state->options.smb2_capabilities);
+ if (tevent_req_nomem(state->conn, req)) {
+ return;
+ }
+ sock->sock->fd = -1;
+ TALLOC_FREE(sock);
+
+ subreq = smbXcli_negprot_send(state,
+ state->ev,
+ state->conn,
+ timeout_msec,
+ state->options.min_protocol,
+ state->options.max_protocol,
+ state->options.max_credits);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq, smb_connect_nego_nego_done, req);
+}
+
+static void smb_connect_nego_nego_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq,
+ struct tevent_req);
+ NTSTATUS status;
+
+ status = smbXcli_negprot_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+NTSTATUS smb_connect_nego_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct smbXcli_conn **_conn)
+{
+ struct smb_connect_nego_state *state =
+ tevent_req_data(req,
+ struct smb_connect_nego_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ *_conn = talloc_move(mem_ctx, &state->conn);
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h
index 383946f1307a..72c9bc7507e6 100644
--- a/source4/libcli/smb_composite/smb_composite.h
+++ b/source4/libcli/smb_composite/smb_composite.h
@@ -101,6 +101,27 @@ NTSTATUS smb_composite_savefile_recv(struct composite_context *c);
NTSTATUS smb_composite_savefile(struct smbcli_tree *tree,
struct smb_composite_savefile *io);
+/*
+ a composite request for a low level connection to a remote server. Includes
+
+ - socket establishment
+ - session request
+ - negprot
+*/
+struct tevent_req *smb_connect_nego_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resolve_context *resolve_ctx,
+ const struct smbcli_options *options,
+ const char *socket_options,
+ const char *dest_hostname,
+ const char *dest_address, /* optional */
+ const char **dest_ports,
+ const char *called_name,
+ const char *calling_name);
+NTSTATUS smb_connect_nego_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct smbXcli_conn **_conn);
+
/*
a composite request for a full connection to a remote server. Includes
diff --git a/source4/libcli/wscript_build b/source4/libcli/wscript_build
index 220b028cb368..d3641f538af3 100644
--- a/source4/libcli/wscript_build
+++ b/source4/libcli/wscript_build
@@ -25,11 +25,21 @@ bld.SAMBA_SUBSYSTEM('cli_composite',
bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE',
- source='smb_composite/loadfile.c smb_composite/savefile.c smb_composite/connect.c smb_composite/sesssetup.c smb_composite/fetchfile.c smb_composite/appendacl.c smb_composite/fsinfo.c smb_composite/smb2.c',
- deps='LIBCLI_SMB2 tevent-util',
- public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent',
- private_headers='smb_composite/smb_composite.h',
- )
+ source='''
+ smb_composite/loadfile.c
+ smb_composite/savefile.c
+ smb_composite/connect_nego.c
+ smb_composite/connect.c
+ smb_composite/sesssetup.c
+ smb_composite/fetchfile.c
+ smb_composite/appendacl.c
+ smb_composite/fsinfo.c
+ smb_composite/smb2.c
+ ''',
+ deps='LIBCLI_SMB2 tevent-util',
+ public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent',
+ private_headers='smb_composite/smb_composite.h',
+ )
for env in bld.gen_python_environments():
--
2.17.1
From 1852d9d898e51f78e24b86e11e233565328d689c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 19 Jul 2018 07:32:08 +0200
Subject: [PATCH 10/15] librpc: add binding handle support for [smb1]
This will be used to force smb1.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
librpc/rpc/binding.c | 1 +
librpc/rpc/rpc_common.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index 63ba682a577e..aa8cc6b46c6f 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -103,6 +103,7 @@ static const struct ncacn_option {
{"print", DCERPC_DEBUG_PRINT_BOTH},
{"padcheck", DCERPC_DEBUG_PAD_CHECK},
{"bigendian", DCERPC_PUSH_BIGENDIAN},
+ {"smb1", DCERPC_SMB1},
{"smb2", DCERPC_SMB2},
{"ndr64", DCERPC_NDR64},
{"packet", DCERPC_PACKET},
diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index d6b2d5dbc055..cdc9fe8ac882 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -108,6 +108,8 @@ struct dcerpc_binding;
#define DCERPC_PACKET (1<<26)
+#define DCERPC_SMB1 (1<<27)
+
/* The following definitions come from ../librpc/rpc/dcerpc_error.c */
const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
--
2.17.1
From afc70b6ee590e9e295aca01c0d3bf210e06afada Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Jul 2018 16:55:33 +0200
Subject: [PATCH 11/15] s4:librpc: autonegotiate SMB1/2/3
Windows Server 1709 defaults to SMB2 and does not have SMB1 enabled.
When establishing trust, samba-tool does not specify SMB protocol
version and fail by default.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/librpc/rpc/dcerpc_connect.c | 238 ++++++++++++----------------
1 file changed, 102 insertions(+), 136 deletions(-)
diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c
index a3f25efc0b47..93619c6a54fb 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -76,6 +76,8 @@ static void continue_pipe_open_smb(struct composite_context *ctx)
}
static void continue_smb_open(struct composite_context *c);
+static void continue_smb2_connect(struct tevent_req *subreq);
+static void continue_smbXcli_connect(struct tevent_req *subreq);
/*
Stage 2 of ncacn_np_smb: Open a named pipe after successful smb connection
@@ -132,9 +134,10 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT
{
struct composite_context *c;
struct pipe_np_smb_state *s;
- struct composite_context *conn_req;
+ struct tevent_req *subreq = NULL;
struct smb_composite_connect *conn;
uint32_t flags;
+ const char *calling_name = NULL;
/* composite context allocation and setup */
c = composite_create(mem_ctx, io->conn->event_ctx);
@@ -152,6 +155,11 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT
return c;
}
+ if (s->io.creds == NULL) {
+ composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
+ return c;
+ }
+
/* prepare smb connection parameters: we're connecting to IPC$ share on
remote rpc server */
conn->in.dest_host = dcerpc_binding_get_string_option(s->io.binding, "host");
@@ -184,21 +192,100 @@ 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.min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx);
+ conn->in.options.max_protocol = lpcfg_client_ipc_max_protocol(lp_ctx);
+ if ((flags & DCERPC_SMB1) && (flags & DCERPC_SMB2)) {
+ /* auto */
+ } else if (flags & DCERPC_SMB2) {
+ if (conn->in.options.min_protocol < PROTOCOL_SMB2_02) {
+ conn->in.options.min_protocol = PROTOCOL_SMB2_02;
+ }
+ if (conn->in.options.max_protocol < PROTOCOL_SMB2_02) {
+ conn->in.options.max_protocol = PROTOCOL_LATEST;
+ }
+ } else if (flags & DCERPC_SMB1) {
+ conn->in.options.min_protocol = PROTOCOL_NT1;
+ conn->in.options.max_protocol = PROTOCOL_NT1;
+ } else {
+ /* auto */
+ }
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,
- c->event_ctx);
- if (composite_nomem(conn_req, c)) return c;
+ if (s->conn.in.credentials != NULL) {
+ calling_name = cli_credentials_get_workstation(s->conn.in.credentials);
+ }
+ if (calling_name == NULL) {
+ calling_name = "SMBCLIENT";
+ }
+
+ subreq = smb_connect_nego_send(s,
+ c->event_ctx,
+ s->io.resolve_ctx,
+ &conn->in.options,
+ conn->in.socket_options,
+ conn->in.dest_host,
+ NULL, /* dest_address */
+ conn->in.dest_ports,
+ conn->in.called_name,
+ calling_name);
+ if (composite_nomem(subreq, c)) return c;
+ tevent_req_set_callback(subreq,
+ continue_smbXcli_connect,
+ c);
- composite_continue(c, conn_req, continue_smb_connect, c);
return c;
}
+static void continue_smbXcli_connect(struct tevent_req *subreq)
+{
+ struct composite_context *c =
+ tevent_req_callback_data(subreq,
+ struct composite_context);
+ struct pipe_np_smb_state *s =
+ talloc_get_type_abort(c->private_data,
+ struct pipe_np_smb_state);
+ struct smb_composite_connect *conn = &s->conn;
+ struct composite_context *creq = NULL;
+ enum protocol_types protocol;
+
+ c->status = smb_connect_nego_recv(subreq, s,
+ &conn->in.existing_conn);
+ TALLOC_FREE(subreq);
+ if (!composite_is_ok(c)) return;
+
+ protocol = smbXcli_conn_protocol(conn->in.existing_conn);
+ if (protocol >= PROTOCOL_SMB2_02) {
+ // TODO add [smb2] to binding
+
+ /* send smb2 connect request */
+ subreq = smb2_connect_send(s, c->event_ctx,
+ conn->in.dest_host,
+ conn->in.dest_ports,
+ conn->in.service,
+ s->io.resolve_ctx,
+ conn->in.credentials,
+ conn->in.fallback_to_anonymous,
+ &conn->in.existing_conn,
+ 0, /* previous_session_id */
+ &conn->in.options,
+ conn->in.socket_options,
+ conn->in.gensec_settings);
+ if (composite_nomem(subreq, c)) return;
+ tevent_req_set_callback(subreq, continue_smb2_connect, c);
+ return;
+ }
+
+ /* send smb connect request */
+ creq = smb_composite_connect_send(conn, s->io.conn,
+ s->io.resolve_ctx,
+ c->event_ctx);
+ if (composite_nomem(creq, c)) return;
+
+ composite_continue(c, creq, continue_smb_connect, c);
+ return;
+}
+
/*
Receive result of a rpc connection to a rpc pipe on SMB
@@ -238,92 +325,6 @@ static void continue_smb2_connect(struct tevent_req *subreq)
}
-/*
- Initiate async open of a rpc connection request on SMB2 using
- the binding structure to determine the endpoint and options
-*/
-static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send(
- TALLOC_CTX *mem_ctx,
- struct dcerpc_pipe_connect *io,
- struct loadparm_context *lp_ctx)
-{
- struct composite_context *c;
- struct pipe_np_smb_state *s;
- struct tevent_req *subreq;
- struct smbcli_options options;
- const char *host;
- uint32_t flags;
-
- /* composite context allocation and setup */
- c = composite_create(mem_ctx, io->conn->event_ctx);
- if (c == NULL) return NULL;
-
- s = talloc_zero(c, struct pipe_np_smb_state);
- if (composite_nomem(s, c)) return c;
- c->private_data = s;
-
- s->io = *io;
-
- if (smbXcli_conn_is_connected(s->io.smb.conn)) {
- continue_smb_open(c);
- return c;
- }
-
- host = dcerpc_binding_get_string_option(s->io.binding, "host");
- flags = dcerpc_binding_get_flags(s->io.binding);
-
- /*
- * provide proper credentials - user supplied or anonymous in case this is
- * schannel connection
- */
- if (flags & DCERPC_SCHANNEL) {
- s->io.creds = cli_credentials_init_anon(mem_ctx);
- if (composite_nomem(s->io.creds, c)) return c;
- }
-
- 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,
- lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "smb2", "ports", NULL),
- "IPC$",
- s->io.resolve_ctx,
- s->io.creds,
- NULL, /* existing_conn */
- 0, /* previous_session_id */
- &options,
- lpcfg_socket_options(lp_ctx),
- lpcfg_gensec_settings(mem_ctx, lp_ctx));
- if (composite_nomem(subreq, c)) return c;
- tevent_req_set_callback(subreq, continue_smb2_connect, c);
- return c;
-}
-
-
-/*
- Receive result of a rpc connection to a rpc pipe on SMB2
-*/
-static NTSTATUS dcerpc_pipe_connect_ncacn_np_smb2_recv(struct composite_context *c)
-{
- NTSTATUS status = composite_wait(c);
-
- talloc_free(c);
- return status;
-}
-
-
struct pipe_ip_tcp_state {
struct dcerpc_pipe_connect io;
const char *localaddr;
@@ -752,7 +753,6 @@ struct pipe_connect_state {
static void continue_map_binding(struct composite_context *ctx);
static void continue_connect(struct composite_context *c, struct pipe_connect_state *s);
-static void continue_pipe_connect_ncacn_np_smb2(struct composite_context *ctx);
static void continue_pipe_connect_ncacn_np_smb(struct composite_context *ctx);
static void continue_pipe_connect_ncacn_ip_tcp(struct composite_context *ctx);
static void continue_pipe_connect_ncacn_http(struct composite_context *ctx);
@@ -791,15 +791,12 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
struct dcerpc_pipe_connect pc;
/* potential exits to another stage by sending an async request */
- struct composite_context *ncacn_np_smb2_req;
struct composite_context *ncacn_np_smb_req;
struct composite_context *ncacn_ip_tcp_req;
struct composite_context *ncacn_http_req;
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 */
ZERO_STRUCT(pc);
@@ -810,29 +807,16 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
pc.resolve_ctx = lpcfg_resolve_context(s->lp_ctx);
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:
- if (flags & DCERPC_SMB2) {
- /* new varient of SMB a.k.a. SMB2 */
- ncacn_np_smb2_req = dcerpc_pipe_connect_ncacn_np_smb2_send(c, &pc, s->lp_ctx);
- composite_continue(c, ncacn_np_smb2_req, continue_pipe_connect_ncacn_np_smb2, c);
- return;
-
- } else {
- /* good old ordinary SMB */
- ncacn_np_smb_req = dcerpc_pipe_connect_ncacn_np_smb_send(c, &pc, s->lp_ctx);
- composite_continue(c, ncacn_np_smb_req, continue_pipe_connect_ncacn_np_smb, c);
- return;
- }
- break;
+ /*
+ * SMB1/2/3...
+ */
+ ncacn_np_smb_req = dcerpc_pipe_connect_ncacn_np_smb_send(c, &pc, s->lp_ctx);
+ composite_continue(c, ncacn_np_smb_req, continue_pipe_connect_ncacn_np_smb, c);
+ return;
case NCACN_IP_TCP:
ncacn_ip_tcp_req = dcerpc_pipe_connect_ncacn_ip_tcp_send(c, &pc);
@@ -865,24 +849,6 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
}
-/*
- Stage 3 of pipe_connect_b: Receive result of pipe connect request on
- named pipe on smb2
-*/
-static void continue_pipe_connect_ncacn_np_smb2(struct composite_context *ctx)
-{
- struct composite_context *c = talloc_get_type(ctx->async.private_data,
- struct composite_context);
- struct pipe_connect_state *s = talloc_get_type(c->private_data,
- struct pipe_connect_state);
-
- c->status = dcerpc_pipe_connect_ncacn_np_smb2_recv(ctx);
- if (!composite_is_ok(c)) return;
-
- continue_pipe_connect(c, s);
-}
-
-
/*
Stage 3 of pipe_connect_b: Receive result of pipe connect request on
named pipe on smb
--
2.17.1
From 4b946dc79050564c70f59a86aedfc6cb40bd2350 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 19 Jul 2018 07:34:11 +0200
Subject: [PATCH 12/15] s3:selftest: run rpc.lsa.lookupsids also with explicit
[smb1] and [smb2]
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/selftest/tests.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a061483c5f5f..bf0ba2a44546 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -581,7 +581,7 @@ for t in tests:
test = 'rpc.lsa.lookupsids'
-auth_options = ["", "ntlm", "spnego", "spnego,ntlm" ]
+auth_options = ["", "ntlm", "spnego", "spnego,ntlm", "spnego,smb1", "spnego,smb2"]
signseal_options = ["", ",connect", ",packet", ",sign", ",seal"]
endianness_options = ["", ",bigendian"]
for s in signseal_options:
--
2.17.1
From 778fa18127b5ae07bb61862fbf8b0756fb1175c4 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Sat, 24 Feb 2018 14:34:44 +0200
Subject: [PATCH 13/15] samba-tool trust: support discovery via netr_GetDcName
In case a remote DC does not support netr_DsRGetDCNameEx2(),
use netr_GetDcName() instead.
This should help with FreeIPA where embedded smbd runs as a domain
controller but does not implement full Active Directory compatibility.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13538
Signed-off-by: Alexander Bokovoy <ab at samba.org>
---
python/samba/netcmd/domain.py | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index 555462c9615c..becbc498b9e8 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -1876,6 +1876,15 @@ class DomainTrustCommand(Command):
return (policy, info)
+ def get_netlogon_dc_unc(self, conn, server, domain):
+ try:
+ info = conn.netr_DsRGetDCNameEx2(server,
+ None, 0, None, None, None,
+ netlogon.DS_RETURN_DNS_NAME)
+ return info.dc_unc
+ except RuntimeError:
+ return conn.netr_GetDcName(server, domain)
+
def get_netlogon_dc_info(self, conn, server):
info = conn.netr_DsRGetDCNameEx2(server,
None, 0, None, None, None,
@@ -2509,7 +2518,8 @@ class cmd_domain_trust_create(DomainTrustCommand):
raise self.RemoteRuntimeError(self, error, "failed to connect netlogon server")
try:
- remote_netlogon_info = self.get_netlogon_dc_info(remote_netlogon, remote_server)
+ remote_netlogon_dc_unc = self.get_netlogon_dc_unc(remote_netlogon,
+ remote_server, domain)
except RuntimeError as error:
raise self.RemoteRuntimeError(self, error, "failed to get netlogon dc info")
@@ -2659,9 +2669,9 @@ class cmd_domain_trust_create(DomainTrustCommand):
# this triggers netr_GetForestTrustInformation to our domain.
# and lsaRSetForestTrustInformation() remotely, but new top level
# names are disabled by default.
- remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_info.dc_unc,
- local_lsa_info.dns_domain.string,
- netlogon.DS_GFTI_UPDATE_TDO)
+ remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_dc_unc,
+ local_lsa_info.dns_domain.string,
+ netlogon.DS_GFTI_UPDATE_TDO)
except RuntimeError as error:
raise self.RemoteRuntimeError(self, error, "netr_DsRGetForestTrustInformation() failed")
@@ -2712,10 +2722,10 @@ class cmd_domain_trust_create(DomainTrustCommand):
if remote_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_OUTBOUND:
self.outf.write("Validating incoming trust...\n")
try:
- remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_info.dc_unc,
- netlogon.NETLOGON_CONTROL_TC_VERIFY,
- 2,
- local_lsa_info.dns_domain.string)
+ remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_dc_unc,
+ netlogon.NETLOGON_CONTROL_TC_VERIFY,
+ 2,
+ local_lsa_info.dns_domain.string)
except RuntimeError as error:
raise self.RemoteRuntimeError(self, error, "NETLOGON_CONTROL_TC_VERIFY failed")
--
2.17.1
From fee54c664684b46f6079d157b5b43c78364f4b48 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Fri, 16 Feb 2018 18:15:28 +0200
Subject: [PATCH 14/15] TODO: krb5-samba: interdomain trust uses different salt
principal
Salt principal for the interdomain trust is krbtgt/DOMAIN at REALM where
DOMAIN is the sAMAccountName without the dollar sign ($)
The salt principal for the BLA$ user object was generated wrong.
dn: CN=bla.base,CN=System,DC=w4edom-l4,DC=base
securityIdentifier: S-1-5-21-4053568372-2049667917-3384589010
trustDirection: 3
trustPartner: bla.base
trustPosixOffset: -2147483648
trustType: 2
trustAttributes: 8
flatName: BLA
dn: CN=BLA$,CN=Users,DC=w4edom-l4,DC=base
userAccountControl: 2080
primaryGroupID: 513
objectSid: S-1-5-21-278041429-3399921908-1452754838-1597
accountExpires: 9223372036854775807
sAMAccountName: BLA$
sAMAccountType: 805306370
pwdLastSet: 131485652467995000
The salt stored by Windows in the package_PrimaryKerberosBlob
(within supplementalCredentials) seems to be
'W4EDOM-L4.BASEkrbtgtBLA' for the above trust
and Samba stores 'W4EDOM-L4.BASEBLA$'.
While the salt used when building the keys from
trustAuthOutgoing/trustAuthIncoming is
'W4EDOM-L4.BASEkrbtgtBLA.BASE', which we handle correct.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13539
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
TODO: Signed-off-by: Alexander Bokovoy <ab at samba.org>
TODO: Signed-off-by: Stefan Metzmacher <metze at samba.org>
TODO: unit tests: loop over all account types with, loop over names with
and without upn, with and without '$'. Use 'eXaMpLe.COM' and similar
names to check the correct upper/lower case result.
TODO: Also verify this against windows...
A test can create objects via ldap and/or lsa (for trusts)
then get the object including supplementalCredentials
via drsuapi (as admin) and check the stored salt.
We should have similar tests already.
---
auth/credentials/credentials_krb5.c | 16 +++--
lib/krb5_wrap/krb5_samba.c | 61 ++++++++++++++-----
lib/krb5_wrap/krb5_samba.h | 2 +-
source3/passdb/machine_account_secrets.c | 3 +-
.../dsdb/samdb/ldb_modules/password_hash.c | 6 +-
5 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 9da1aa09250d..d36797bf0f37 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -34,6 +34,7 @@
#include "auth/kerberos/kerberos_util.h"
#include "auth/kerberos/pac_utils.h"
#include "param/param.h"
+#include "../libds/common/flags.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
@@ -974,7 +975,7 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
const char *upn = NULL;
const char *realm = cli_credentials_get_realm(cred);
char *salt_principal = NULL;
- bool is_computer = false;
+ uint32_t uac_flags = 0;
if (cred->keytab_obtained >= (MAX(cred->principal_obtained,
cred->username_obtained))) {
@@ -999,9 +1000,15 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
switch (cred->secure_channel_type) {
case SEC_CHAN_WKSTA:
- case SEC_CHAN_BDC:
case SEC_CHAN_RODC:
- is_computer = true;
+ uac_flags = UF_WORKSTATION_TRUST_ACCOUNT;
+ break;
+ case SEC_CHAN_BDC:
+ uac_flags = UF_SERVER_TRUST_ACCOUNT;
+ break;
+ case SEC_CHAN_DOMAIN:
+ case SEC_CHAN_DNS_DOMAIN:
+ uac_flags = UF_INTERDOMAIN_TRUST_ACCOUNT;
break;
default:
upn = cli_credentials_get_principal(cred, mem_ctx);
@@ -1009,13 +1016,14 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
TALLOC_FREE(mem_ctx);
return ENOMEM;
}
+ uac_flags = UF_NORMAL_ACCOUNT;
break;
}
ret = smb_krb5_salt_principal(realm,
username, /* sAMAccountName */
upn, /* userPrincipalName */
- is_computer,
+ uac_flags,
mem_ctx,
&salt_principal);
if (ret) {
diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index 7e90913beb0f..a6ff97640cae 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -24,6 +24,7 @@
#include "system/filesys.h"
#include "krb5_samba.h"
#include "lib/crypto/crypto.h"
+#include "../libds/common/flags.h"
#ifdef HAVE_COM_ERR_H
#include <com_err.h>
@@ -445,8 +446,7 @@ int smb_krb5_get_pw_salt(krb5_context context,
* @param[in] userPrincipalName The userPrincipalName attribute of the object
* or NULL is not available.
*
- * @param[in] is_computer The indication of the object includes
- * objectClass=computer.
+ * @param[in] uac_flags UF_ACCOUNT_TYPE_MASKed userAccountControl field
*
* @param[in] mem_ctx The TALLOC_CTX to allocate _salt_principal.
*
@@ -459,7 +459,7 @@ int smb_krb5_get_pw_salt(krb5_context context,
int smb_krb5_salt_principal(const char *realm,
const char *sAMAccountName,
const char *userPrincipalName,
- bool is_computer,
+ uint32_t uac_flags,
TALLOC_CTX *mem_ctx,
char **_salt_principal)
{
@@ -480,6 +480,23 @@ int smb_krb5_salt_principal(const char *realm,
return EINVAL;
}
+ if (uac_flags & ~UF_ACCOUNT_TYPE_MASK) {
+ /*
+ * catch callers which still
+ * pass 'true'.
+ */
+ TALLOC_FREE(frame);
+ return EINVAL;
+ }
+ if (uac_flags == 0) {
+ /*
+ * catch callers which still
+ * pass 'false'.
+ */
+ TALLOC_FREE(frame);
+ return EINVAL;
+ }
+
upper_realm = strupper_talloc(frame, realm);
if (upper_realm == NULL) {
TALLOC_FREE(frame);
@@ -493,7 +510,7 @@ int smb_krb5_salt_principal(const char *realm,
/*
* Determine a salting principal
*/
- if (is_computer) {
+ if (uac_flags & UF_TRUST_ACCOUNT_MASK) {
int computer_len = 0;
char *tmp = NULL;
@@ -502,20 +519,32 @@ int smb_krb5_salt_principal(const char *realm,
computer_len -= 1;
}
- tmp = talloc_asprintf(frame, "host/%*.*s.%s",
- computer_len, computer_len,
- sAMAccountName, realm);
- if (tmp == NULL) {
- TALLOC_FREE(frame);
- return ENOMEM;
- }
+ if (uac_flags & UF_INTERDOMAIN_TRUST_ACCOUNT) {
+ principal = talloc_asprintf(frame, "krbtgt/%*.*s",
+ computer_len, computer_len,
+ sAMAccountName);
+ if (principal == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
+ } else {
- principal = strlower_talloc(frame, tmp);
- TALLOC_FREE(tmp);
- if (principal == NULL) {
- TALLOC_FREE(frame);
- return ENOMEM;
+ tmp = talloc_asprintf(frame, "host/%*.*s.%s",
+ computer_len, computer_len,
+ sAMAccountName, realm);
+ if (tmp == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
+
+ principal = strlower_talloc(frame, tmp);
+ TALLOC_FREE(tmp);
+ if (principal == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
}
+
principal_len = strlen(principal);
} else if (userPrincipalName != NULL) {
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 315d3c3492e6..8305c1f77af0 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -353,7 +353,7 @@ int smb_krb5_get_pw_salt(krb5_context context,
int smb_krb5_salt_principal(const char *realm,
const char *sAMAccountName,
const char *userPrincipalName,
- bool is_computer,
+ uint32_t uac_flags,
TALLOC_CTX *mem_ctx,
char **_salt_principal);
int smb_krb5_salt_principal2data(krb5_context context,
diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
index 94a7e21c8098..a96bf1c0b6ac 100644
--- a/source3/passdb/machine_account_secrets.c
+++ b/source3/passdb/machine_account_secrets.c
@@ -36,6 +36,7 @@
#include "lib/crypto/crypto.h"
#include "lib/krb5_wrap/krb5_samba.h"
#include "lib/util/time_basic.h"
+#include "../libds/common/flags.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
@@ -1601,7 +1602,7 @@ NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string,
info->account_name,
NULL /* userPrincipalName */,
- true /* is_computer */,
+ UF_WORKSTATION_TRUST_ACCOUNT,
info, &p);
if (ret != 0) {
status = krb5_to_nt_status(ret);
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 58ae64537eb6..5f5710330044 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -130,7 +130,6 @@ struct setup_password_fields_io {
NTTIME pwdLastSet;
const char *sAMAccountName;
const char *user_principal_name;
- bool is_computer;
bool is_krbtgt;
uint32_t restrictions;
struct dom_sid *account_sid;
@@ -678,15 +677,17 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io)
krb5_data salt;
krb5_keyblock key;
krb5_data cleartext_data;
+ uint32_t uac_flags = 0;
ldb = ldb_module_get_ctx(io->ac->module);
cleartext_data.data = (char *)io->n.cleartext_utf8->data;
cleartext_data.length = io->n.cleartext_utf8->length;
+ uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK;
krb5_ret = smb_krb5_salt_principal(io->ac->status->domain_data.realm,
io->u.sAMAccountName,
io->u.user_principal_name,
- io->u.is_computer,
+ uac_flags,
io->ac,
&salt_principal);
if (krb5_ret) {
@@ -3190,7 +3191,6 @@ static int setup_io(struct ph_context *ac,
"sAMAccountName", NULL);
io->u.user_principal_name = ldb_msg_find_attr_as_string(info_msg,
"userPrincipalName", NULL);
- io->u.is_computer = ldb_msg_check_string_attribute(info_msg, "objectClass", "computer");
/* Ensure it has an objectSID too */
io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
--
2.17.1
From 80f157adf683f18e0eba0343a3af0f9aee6a72b0 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Fri, 16 Feb 2018 18:15:28 +0200
Subject: [PATCH 15/15] TODO s4:selftest: test interdomain trust uses different
salt principal
To test it, add a blackbox test that ensures we pass a keytab-based
authentication with a TDO account from a trusted domain.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13539
Signed-off-by: Alexander Bokovoy <ab at samba.org>
TODO: move before fix and add selftest/knownfail.d/ entry
---
source4/selftest/tests.py | 1 +
testprogs/blackbox/test_tdo.sh | 44 ++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
create mode 100755 testprogs/blackbox/test_tdo.sh
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 978a52000552..d1fca008d0a0 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -428,6 +428,7 @@ plantestsuite("samba4.blackbox.trust_token", "fl2008r2dc", [os.path.join(bbdir,
plantestsuite("samba4.blackbox.trust_token", "fl2003dc", [os.path.join(bbdir, "test_trust_token.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$DOMSID', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$TRUST_DOMSID', 'external'])
plantestsuite("samba4.blackbox.ktpass(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(bbdir, "test_ktpass.sh"), '$PREFIX/ad_dc_ntvfs'])
plantestsuite("samba4.blackbox.password_settings(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_password_settings.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"])
+plantestsuite("samba4.blackbox.kinit_trust_tdo(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_tdo.sh"), '$PREFIX', '$REALM', '$DOMAIN', '$TRUST_REALM', '$TRUST_DOMAIN'])
plantestsuite("samba4.blackbox.cifsdd(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "client/tests/test_cifsdd.sh"), '$SERVER', '$USERNAME', '$PASSWORD', "$DOMAIN"])
plantestsuite("samba4.blackbox.nmblookup(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "utils/tests/test_nmblookup.sh"), '$NETBIOSNAME', '$NETBIOSALIAS', '$SERVER', '$SERVER_IP', nmblookup4])
plantestsuite("samba4.blackbox.locktest(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "torture/tests/test_locktest.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$DOMAIN', '$PREFIX'])
diff --git a/testprogs/blackbox/test_tdo.sh b/testprogs/blackbox/test_tdo.sh
new file mode 100755
index 000000000000..bcbdbdfdada1
--- /dev/null
+++ b/testprogs/blackbox/test_tdo.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF
+Usage: test_tdo.sh PREFIX OUR_REALM OUR_FLAT REMOTE_REALM REMOTE_FLAT
+EOF
+exit 1;
+fi
+
+PREFIX="$1"
+OUR_REALM="$2"
+OUR_FLAT="$3"
+REMOTE_REALM="$4"
+REMOTE_FLAT="$5"
+shift 5
+
+. `dirname $0`/subunit.sh
+
+
+samba_tool="$BINDIR/samba-tool"
+samba4bindir="$BINDIR"
+samba4srcdir="$SRCDIR/source4"
+samba4kinit="kinit -k"
+if test -x $BINDIR/samba4kinit; then
+ samba4kinit="$BINDIR/samba4kinit --use-keytab"
+fi
+
+KEYTAB="$PREFIX/tmptdo.keytab"
+
+KRB5_TRACE=/dev/stderr
+export KRB5_TRACE
+
+testit "retrieve keytab for TDO of $REMOTE_REALM" $samba_tool domain exportkeytab $KEYTAB $CONFIGURATION --principal "$REMOTE_FLAT\$@$OUR_REALM" || failed=`expr $failed + 1`
+
+KRB5CCNAME="$PREFIX/tmptdo.ccache"
+export KRB5CCNAME
+
+rm -f $KRB5CCNAME
+
+testit "kinit with keytab for TDO of $REMOTE_REALM" $samba4kinit -t $KEYTAB "$REMOTE_FLAT\$@$OUR_REALM" || failed=`expr $failed + 1`
+
+rm -f $KRB5CCNAME $KEYTAB
+
+exit $failed
--
2.17.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180719/98c06a1d/signature-0001.sig>
More information about the samba-technical
mailing list