Make the composite 'connect to server' code useful for security=server
authorAndrew Bartlett <abartlet@samba.org>
Fri, 25 Apr 2008 14:08:52 +0000 (15:08 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 25 Apr 2008 14:08:52 +0000 (15:08 +0100)
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
source4/libcli/smb_composite/sesssetup.c
source4/libcli/smb_composite/smb_composite.h

index c4abfa5e370133763d8ee3da765417cbb9456c80..4400c61a812a14d1a695b86aaeef71cad149ba50 100644 (file)
@@ -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);
        }
 }
 
index 1427fe525b4dbe185c9d11f8c3f146a9e4c3f21a..11ac37e257abbb668c539377291dd2a41ab9eae5 100644 (file)
@@ -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 {
index e7e131869c95decb5e59583ea823fca05a282e32..80746f27325d1ad3024fb6c0a03d3164a8f8f109 100644 (file)
@@ -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;
 };