r11665: started to put some meat on the structure used for the SMB2 library
authorAndrew Tridgell <tridge@samba.org>
Fri, 11 Nov 2005 05:53:54 +0000 (05:53 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:09 +0000 (13:46 -0500)
the call definitions will be in smb2_calls.h, which will play a
similar role that smb_interfaces.h plays for the old SMB protocol
(This used to be commit 4ef3902a8a99a0b8caa81a07ba07830d7cbbc32c)

source4/include/structs.h
source4/libcli/smb2/config.mk
source4/libcli/smb2/negprot.c
source4/libcli/smb2/request.c
source4/libcli/smb2/session.c [new file with mode: 0644]
source4/libcli/smb2/smb2.h
source4/libcli/smb2/smb2_calls.h [new file with mode: 0644]
source4/libcli/smb2/transport.c
source4/torture/smb2/connect.c

index 7a31b943fdc15b42824c748427bc0236ab060d46..b6bc1cc742fd5370eace5fd1c87c25d58eee1844 100644 (file)
@@ -336,3 +336,4 @@ struct _krb5_krb_auth_data;
 
 struct smb2_request;
 struct smb2_transport;
+struct smb2_negprot;
index 9840876c2fe39e839d92ea8a249379ad17512e7a..4879dfb5df84e73666d78b0d89510b09c9e97cfe 100644 (file)
@@ -2,5 +2,6 @@
 OBJ_FILES = \
        transport.o \
        request.o \
-       negprot.o
+       negprot.o \
+       session.o
 REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET
index 6b35373807e9b7cc1161a81c2db99abe7629746e..ffddf8a2f01b29080fba6a10603d482aaa2fb7f8 100644 (file)
 #include "includes.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
 
 /*
   send a negprot request
 */
-struct smb2_request *smb2_negprot_send(struct smb2_transport *transport)
+struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, 
+                                      struct smb2_negprot *io)
 {
        struct smb2_request *req;
+       
 
        req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26);
        if (req == NULL) return NULL;
 
-       memset(req->out.body, 0, 0x26);
-       SIVAL(req->out.body, 0, 0x00010024); /* unknown */
+       SIVAL(req->out.body, 0x00, io->in.unknown1);
+       SSVAL(req->out.body, 0x04, io->in.unknown2);
+       memcpy(req->out.body+0x06, io->in.unknown3, 32);
 
        smb2_transport_send(req);
 
@@ -45,29 +49,35 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport)
 /*
   recv a negprot reply
 */
-NTSTATUS smb2_negprot_recv(struct smb2_request *req)
+NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 
+                          struct smb2_negprot *io)
 {
-       NTTIME t1, t2;
-       DATA_BLOB secblob;
-       struct GUID guid;
-       NTSTATUS status;
+       uint16_t blobsize;
 
        if (!smb2_request_receive(req) || 
            smb2_request_is_error(req)) {
                return smb2_request_destroy(req);
        }
 
-       t1 = smbcli_pull_nttime(req->in.body, 0x28);
-       t2 = smbcli_pull_nttime(req->in.body, 0x30);
-
-       secblob = smb2_pull_blob(req, req->in.body+0x40, req->in.body_size - 0x40);
-       status  = smb2_pull_guid(req, req->in.body+0x08, &guid);
-       NT_STATUS_NOT_OK_RETURN(status);
+       if (req->in.body_size < 0x40) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
 
-       printf("Negprot reply:\n");
-       printf("t1  =%s\n", nt_time_string(req, t1));
-       printf("t2  =%s\n", nt_time_string(req, t2));
-       printf("guid=%s\n", GUID_string(req, &guid));
+       io->out.unknown1     = IVAL(req->in.body, 0x00);
+       io->out.unknown2     = IVAL(req->in.body, 0x04);
+       memcpy(io->out.sessid, req->in.body + 0x08, 16);
+       io->out.unknown3     = IVAL(req->in.body, 0x18);
+       io->out.unknown4     = SVAL(req->in.body, 0x1C);
+       io->out.unknown5     = IVAL(req->in.body, 0x1E);
+       io->out.unknown6     = IVAL(req->in.body, 0x22);
+       io->out.unknown7     = SVAL(req->in.body, 0x26);
+       io->out.current_time = smbcli_pull_nttime(req->in.body, 0x28);
+       io->out.boot_time    = smbcli_pull_nttime(req->in.body, 0x30);
+       io->out.unknown8     = SVAL(req->in.body, 0x38);
+       blobsize             = SVAL(req->in.body, 0x3A);
+       io->out.unknown9     = IVAL(req->in.body, 0x3C);
+       io->out.secblob      = smb2_pull_blob(req, req->in.body+0x40, blobsize);
+       talloc_steal(mem_ctx, io->out.secblob.data);
 
        return smb2_request_destroy(req);
 }
@@ -75,8 +85,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req)
 /*
   sync negprot request
 */
-NTSTATUS smb2_negprot(struct smb2_transport *transport)
+NTSTATUS smb2_negprot(struct smb2_transport *transport, 
+                     TALLOC_CTX *mem_ctx, struct smb2_negprot *io)
 {
-       struct smb2_request *req = smb2_negprot_send(transport);
-       return smb2_negprot_recv(req);
+       struct smb2_request *req = smb2_negprot_send(transport, io);
+       return smb2_negprot_recv(req, mem_ctx, io);
 }
index 1b2dc5e64cf20404ebb26e4ca6512aee044aef98..e71fc844711c3ac8290eebb9c6eabdaaab18b9c3 100644 (file)
@@ -25,7 +25,6 @@
 #include "libcli/smb2/smb2.h"
 #include "include/dlinklist.h"
 #include "lib/events/events.h"
-#include "librpc/gen_ndr/ndr_misc.h"
 
 /*
   initialise a smb2 request
@@ -154,18 +153,3 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size)
        return data_blob_talloc(req, ptr, size);
 }
 
-/*
-  pull a guid from the reply body
-*/
-NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid)
-{
-       NTSTATUS status;
-       DATA_BLOB blob = smb2_pull_blob(req, ptr, 16);
-       if (blob.data == NULL) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-       status = ndr_pull_struct_blob(&blob, req, guid, 
-                                     (ndr_pull_flags_fn_t)ndr_pull_GUID);
-       data_blob_free(&blob);
-       return status;
-}
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
new file mode 100644 (file)
index 0000000..23fed70
--- /dev/null
@@ -0,0 +1,47 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   SMB2 client session handling
+
+   Copyright (C) Andrew Tridgell 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 2 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/smb2/smb2.h"
+
+/*
+  initialise a smb2_session structure
+ */
+struct smb2_session *smb2_session_init(struct smb2_transport *transport,
+                                      TALLOC_CTX *parent_ctx, BOOL primary)
+{
+       struct smb2_session *session;
+
+       session = talloc_zero(parent_ctx, struct smb2_session);
+       if (!session) {
+               return NULL;
+       }
+       if (primary) {
+               session->transport = talloc_steal(session, transport);
+       } else {
+               session->transport = talloc_reference(session, transport);
+       }
+
+       return session;
+}
+
index 2e01159355f171ca01062acedf42e009e61911e2..79b983206a3daa05622c90aaa6f982c48798e8b7 100644 (file)
@@ -29,7 +29,6 @@ struct smb2_options {
 */
 struct smb2_negotiate {
        DATA_BLOB secblob;
-       
 };
 
 /* this is the context for the smb2 transport layer */
@@ -52,6 +51,13 @@ struct smb2_transport {
 };
 
 
+/*
+  SMB2 session context
+*/
+struct smb2_session {
+       struct smb2_transport *transport;
+};
+
 struct smb2_request_buffer {
        /* the raw SMB2 buffer, including the 4 byte length header */
        uint8_t *buffer;
diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h
new file mode 100644 (file)
index 0000000..ef0abc3
--- /dev/null
@@ -0,0 +1,63 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   SMB2 client calls 
+
+   Copyright (C) Andrew Tridgell 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 2 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+struct smb2_negprot {
+       struct {
+               uint32_t unknown1;    /* 0x00010024 */
+               uint16_t unknown2;    /* 0x00 */
+               uint8_t  unknown3[32]; /* all zero */
+       } in;
+       struct {
+               uint32_t unknown1; /* 0x41 */
+               uint32_t unknown2; /* 0x06 */
+               uint8_t  sessid[16];
+               uint32_t unknown3; /* 0x0d */
+               uint16_t unknown4; /* 0x00 */
+               uint32_t unknown5; /* 0x01 */
+               uint32_t unknown6; /* 0x01 */
+               uint16_t unknown7; /* 0x01 */
+               NTTIME   current_time;
+               NTTIME   boot_time;
+               uint16_t unknown8; /* 0x80 */
+               /* uint16_t secblob size here */
+               uint32_t unknown9; /* 0x204d4c20 */
+               DATA_BLOB secblob;
+       } out;
+};
+
+struct smb2_session_setup {
+       struct {
+               uint32_t unknown1; /* 0x11 */
+               uint32_t unknown2; /* 0xF */
+               uint32_t unknown3; /* 0x00 */
+               uint16_t unknown4; /* 0x50 */
+               /* uint16_t secblob size here */
+               DATA_BLOB secblob;
+       } in;
+       struct {
+               uint32_t unknown1; /* 0x09 */
+               uint16_t unknown2; /* 0x48 */
+               /* uint16_t secblob size here */
+               DATA_BLOB secblob;
+       } out;
+};
index a178b35f9325bee16603d6475598811757146991..dd05eed1dd4e97899c3636e523e8d3aefdc2e0bc 100644 (file)
@@ -183,6 +183,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
        req->in.ptr       = req->in.body;
        req->status       = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
 
+       dump_data(0, req->in.body, req->in.body_size);
+
        /* if this request has an async handler then call that to
           notify that the reply has been received. This might destroy
           the request so it must happen last */
index 00a9b35c17ec1b662333c4fa885321389bea41ee..7237bb704a0aef3a7c50c0c730879263ad5b1d93 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"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "lib/cmdline/popt_common.h"
 #include "lib/events/events.h"
                goto done; \
        }} while (0)
 
-/* 
-   basic testing of SMB2 connection calls
-*/
-BOOL torture_smb2_connect(void)
+
+/*
+  send a negotiate
+ */
+static struct smb2_transport *torture_smb2_negprot(TALLOC_CTX *mem_ctx, const char *host)
 {
-       TALLOC_CTX *mem_ctx = talloc_new(NULL);
        struct smbcli_socket *socket;
        struct smb2_transport *transport;
-       const char *host = lp_parm_string(-1, "torture", "host");
-       BOOL ret = True;
        NTSTATUS status;
+       struct smb2_negprot io;
 
        socket = smbcli_sock_connect_byname(host, 445, mem_ctx, NULL);
        if (socket == NULL) {
@@ -56,19 +56,67 @@ BOOL torture_smb2_connect(void)
        }
 
        transport = smb2_transport_init(socket, mem_ctx);
-       if (socket == NULL) {
+       if (transport == NULL) {
                printf("Failed to setup smb2 transport\n");
                return False;
        }
 
+       ZERO_STRUCT(io);
+       io.in.unknown1 = 0x010024;
+
        /* send a negprot */
-       status = smb2_negprot(transport);
+       status = smb2_negprot(transport, mem_ctx, &io);
        if (!NT_STATUS_IS_OK(status)) {
                printf("negprot failed - %s\n", nt_errstr(status));
-               return False;
+               return NULL;
        }
 
+       printf("Negprot reply:\n");
+       printf("current_time  = %s\n", nt_time_string(mem_ctx, io.out.current_time));
+       printf("boot_time     = %s\n", nt_time_string(mem_ctx, io.out.boot_time));
+
+       return transport;
+}
+
+#if 0
+/*
+  send a session setup
+*/
+static struct smb2_session *torture_smb2_session(struct smb2_transport *transport, 
+                                                struct cli_credentials *credentials)
+{
+       struct smb2_session *session;
+       NTSTATUS status;
+
+       session = smb2_session_init(transport);
+
+       status = smb2_session_setup(session, credentials)
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("session setup failed - %s\n", nt_errstr(status));
+               return NULL;
+       }
+
+       return session;
+}
+#endif
+
+/* 
+   basic testing of SMB2 connection calls
+*/
+BOOL torture_smb2_connect(void)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+       struct smb2_transport *transport;
+       struct smb2_session *session;
+       const char *host = lp_parm_string(-1, "torture", "host");
+       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);
 
-       return ret;
+       return True;
 }