From c4219fd8030494986c5fa418c46defb1a9c05c7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Apr 2008 15:08:52 +0100 Subject: Make the composite 'connect to server' code useful for security=server The ability to short-circuit the connection code to only do a negprot allows us to do the rest once we have the user's password. We return the 8 byte challenge so we can pass it to the client. Andrew Bartlett (This used to be commit 40fe386b0374df8b390b995c332d048dbbc08f1b) --- source4/libcli/smb_composite/connect.c | 42 ++++++++++++++++++++-------- source4/libcli/smb_composite/sesssetup.c | 2 +- source4/libcli/smb_composite/smb_composite.h | 5 ++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index c4abfa5e37..4400c61a81 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -38,7 +38,9 @@ enum connect_stage {CONNECT_RESOLVE, CONNECT_NEGPROT, CONNECT_SESSION_SETUP, CONNECT_SESSION_SETUP_ANON, - CONNECT_TCON}; + CONNECT_TCON, + CONNECT_DONE +}; struct connect_state { enum connect_stage stage; @@ -97,8 +99,7 @@ static NTSTATUS connect_tcon(struct composite_context *c, state->io_tcon->tconx.out.fs_type); } - /* all done! */ - c->state = COMPOSITE_STATE_DONE; + state->stage = CONNECT_DONE; return NT_STATUS_OK; } @@ -203,6 +204,13 @@ static NTSTATUS connect_session_setup(struct composite_context *c, state->session->vuid = state->io_setup->out.vuid; + /* If we don't have a remote share name then this indicates that + * we don't want to do a tree connect */ + if (!io->in.service) { + state->stage = CONNECT_DONE; + return NT_STATUS_OK; + } + /* setup for a tconx */ io->out.tree = smbcli_tree_init(state->session, state, true); NT_STATUS_HAVE_NO_MEMORY(io->out.tree); @@ -251,10 +259,23 @@ static NTSTATUS connect_negprot(struct composite_context *c, status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); + if (!(state->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY)) { + io->out.negprot_challenge = state->transport->negotiate.secblob; + } else { + io->out.negprot_challenge = data_blob(NULL, 0); + } + + /* If we don't have any credentials then this indicates that + * we don't want to do a session setup */ + if (!io->in.credentials) { + state->stage = CONNECT_DONE; + return NT_STATUS_OK; + } + /* next step is a session setup */ state->session = smbcli_session_init(state->transport, state, true); NT_STATUS_HAVE_NO_MEMORY(state->session); - + state->io_setup = talloc(c, struct smb_composite_sesssetup); NT_STATUS_HAVE_NO_MEMORY(state->io_setup); @@ -272,6 +293,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, state->creq->async.fn = composite_handler; state->creq->async.private_data = c; + state->stage = CONNECT_SESSION_SETUP; return NT_STATUS_OK; @@ -405,13 +427,11 @@ static void state_handler(struct composite_context *c) break; } - if (!NT_STATUS_IS_OK(c->status)) { - c->state = COMPOSITE_STATE_ERROR; - } - - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); + if (state->stage == CONNECT_DONE) { + /* all done! */ + composite_done(c); + } else { + composite_is_ok(c); } } diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 1427fe525b..11ac37e257 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -224,7 +224,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, { NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); - const char *password = cli_credentials_get_password(io->in.credentials); DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); DATA_BLOB session_key; int flags = CLI_CRED_NTLM_AUTH; @@ -266,6 +265,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, data_blob_free(&session_key); } else if (session->options.plaintext_auth) { + const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index e7e131869c..80746f2732 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -83,8 +83,8 @@ struct smb_composite_savefile { - socket establishment - session request - negprot - - session setup - - tree connect + - session setup (if credentials are not NULL) + - tree connect (if service is not NULL) */ struct smb_composite_connect { struct { @@ -101,6 +101,7 @@ struct smb_composite_connect { struct { struct smbcli_tree *tree; bool anonymous_fallback_done; + DATA_BLOB negprot_challenge; } out; }; -- cgit