r11666: filled in the basic session setup. Vista happily accepts the first
authorAndrew Tridgell <tridge@samba.org>
Fri, 11 Nov 2005 06:26:42 +0000 (06:26 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:09 +0000 (13:46 -0500)
stage of the session setup, and waits for more.
(This used to be commit 804c229c3ba7f866a7f3d66684e268d5ddc820ce)

source4/include/structs.h
source4/libcli/smb2/session.c
source4/libcli/smb2/smb2.h
source4/torture/smb2/connect.c

index b6bc1cc742fd5370eace5fd1c87c25d58eee1844..eb04436ea36418b00208ab67a3cd9da7cd8a62ce 100644 (file)
@@ -337,3 +337,4 @@ struct _krb5_krb_auth_data;
 struct smb2_request;
 struct smb2_transport;
 struct smb2_negprot;
+struct smb2_session_setup;
index 23fed70e17995e06b23e0ab0a8b54881728b2892..2f9a979feae06393c828d83787280a3970208489 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
 
 /*
   initialise a smb2_session structure
@@ -31,6 +32,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport,
                                       TALLOC_CTX *parent_ctx, BOOL primary)
 {
        struct smb2_session *session;
+       NTSTATUS status;
 
        session = talloc_zero(parent_ctx, struct smb2_session);
        if (!session) {
@@ -42,6 +44,74 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport,
                session->transport = talloc_reference(session, transport);
        }
 
+       /* prepare a gensec context for later use */
+       status = gensec_client_start(session, &session->gensec, 
+                                    session->transport->socket->event.ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(session);
+               return NULL;
+       }
+
        return session;
 }
 
+/*
+  send a session setup request
+*/
+struct smb2_request *smb2_session_setup_send(struct smb2_session *session, 
+                                            struct smb2_session_setup *io)
+{
+       struct smb2_request *req;
+       
+       req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 
+                               0x10 + io->in.secblob.length);
+       if (req == NULL) return NULL;
+
+       SIVAL(req->out.body, 0x00, io->in.unknown1);
+       SIVAL(req->out.body, 0x04, io->in.unknown2);
+       SIVAL(req->out.body, 0x08, io->in.unknown3);
+       SSVAL(req->out.body, 0x0C, io->in.unknown4);
+       SSVAL(req->out.body, 0x0E, io->in.secblob.length);
+       memcpy(req->out.body+0x10, io->in.secblob.data, io->in.secblob.length);
+
+       smb2_transport_send(req);
+
+       return req;
+}
+
+
+/*
+  recv a session setup reply
+*/
+NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 
+                                struct smb2_session_setup *io)
+{
+       uint16_t blobsize;
+
+       if (!smb2_request_receive(req) || 
+           smb2_request_is_error(req)) {
+               return smb2_request_destroy(req);
+       }
+
+       if (req->in.body_size < 0x08) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+
+       io->out.unknown1     = IVAL(req->in.body, 0x00);
+       io->out.unknown2     = SVAL(req->in.body, 0x04);
+       blobsize             = SVAL(req->in.body, 0x06);
+       io->out.secblob      = smb2_pull_blob(req, req->in.body+0x08, blobsize);
+       talloc_steal(mem_ctx, io->out.secblob.data);
+
+       return smb2_request_destroy(req);
+}
+
+/*
+  sync session setup request
+*/
+NTSTATUS smb2_session_setup(struct smb2_session *session, 
+                           TALLOC_CTX *mem_ctx, struct smb2_session_setup *io)
+{
+       struct smb2_request *req = smb2_session_setup_send(session, io);
+       return smb2_session_setup_recv(req, mem_ctx, io);
+}
index 79b983206a3daa05622c90aaa6f982c48798e8b7..2262040b51227e48c46d016a3b42c9fa27de38f7 100644 (file)
@@ -56,6 +56,7 @@ struct smb2_transport {
 */
 struct smb2_session {
        struct smb2_transport *transport;
+       struct gensec_security *gensec;
 };
 
 struct smb2_request_buffer {
index 7237bb704a0aef3a7c50c0c730879263ad5b1d93..43029dd04dbe7d5b1d91e8336206856cbfc543b1 100644 (file)
@@ -27,6 +27,7 @@
 #include "librpc/gen_ndr/ndr_security.h"
 #include "lib/cmdline/popt_common.h"
 #include "lib/events/events.h"
+#include "auth/gensec/gensec.h"
 
 #define BASEDIR "\\testsmb2"
 
@@ -78,7 +79,6 @@ static struct smb2_transport *torture_smb2_negprot(TALLOC_CTX *mem_ctx, const ch
        return transport;
 }
 
-#if 0
 /*
   send a session setup
 */
@@ -86,11 +86,56 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor
                                                 struct cli_credentials *credentials)
 {
        struct smb2_session *session;
+       struct smb2_session_setup io;
        NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(transport);
 
-       session = smb2_session_init(transport);
+       ZERO_STRUCT(io);
+       io.in.unknown1 = 0x11;
+       io.in.unknown2 = 0xF;
+       io.in.unknown3 = 0x00;
+       io.in.unknown4 = 0x50;
+
+       session = smb2_session_init(transport, transport, True);
+
+       status = gensec_set_credentials(session->gensec, credentials);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", 
+                         nt_errstr(status)));
+               return NULL;
+       }
+
+       status = gensec_set_target_hostname(session->gensec, transport->socket->hostname);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", 
+                         nt_errstr(status)));
+               return NULL;
+       }
+
+       status = gensec_set_target_service(session->gensec, "cifs");
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start set GENSEC target service: %s\n", 
+                         nt_errstr(status)));
+               return NULL;
+       }
+
+       status = gensec_start_mech_by_oid(session->gensec, GENSEC_OID_SPNEGO);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start set GENSEC client - %s\n",
+                         nt_errstr(status)));
+               return NULL;
+       }
+
+       status = gensec_update(session->gensec, tmp_ctx,
+                              session->transport->negotiate.secblob,
+                              &io.in.secblob);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && 
+           !NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed initial gensec_update : %s\n", nt_errstr(status)));
+               return NULL;
+       }
 
-       status = smb2_session_setup(session, credentials)
+       status = smb2_session_setup(session, tmp_ctx, &io);
        if (!NT_STATUS_IS_OK(status)) {
                printf("session setup failed - %s\n", nt_errstr(status));
                return NULL;
@@ -98,7 +143,6 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor
 
        return session;
 }
-#endif
 
 /* 
    basic testing of SMB2 connection calls
@@ -112,9 +156,7 @@ BOOL torture_smb2_connect(void)
        struct cli_credentials *credentials = cmdline_credentials;
 
        transport = torture_smb2_negprot(mem_ctx, host);
-#if 0
        session = torture_smb2_session(transport, credentials);
-#endif
 
        talloc_free(mem_ctx);