summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/include/structs.h1
-rw-r--r--source4/libcli/smb2/config.mk3
-rw-r--r--source4/libcli/smb2/negprot.c53
-rw-r--r--source4/libcli/smb2/request.c16
-rw-r--r--source4/libcli/smb2/session.c47
-rw-r--r--source4/libcli/smb2/smb2.h8
-rw-r--r--source4/libcli/smb2/smb2_calls.h63
-rw-r--r--source4/libcli/smb2/transport.c2
-rw-r--r--source4/torture/smb2/connect.c70
9 files changed, 213 insertions, 50 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h
index 7a31b943fd..b6bc1cc742 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -336,3 +336,4 @@ struct _krb5_krb_auth_data;
struct smb2_request;
struct smb2_transport;
+struct smb2_negprot;
diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk
index 9840876c2f..4879dfb5df 100644
--- a/source4/libcli/smb2/config.mk
+++ b/source4/libcli/smb2/config.mk
@@ -2,5 +2,6 @@
OBJ_FILES = \
transport.o \
request.o \
- negprot.o
+ negprot.o \
+ session.o
REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET
diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c
index 6b35373807..ffddf8a2f0 100644
--- a/source4/libcli/smb2/negprot.c
+++ b/source4/libcli/smb2/negprot.c
@@ -23,19 +23,23 @@
#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);
}
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index 1b2dc5e64c..e71fc84471 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -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
index 0000000000..23fed70e17
--- /dev/null
+++ b/source4/libcli/smb2/session.c
@@ -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;
+}
+
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 2e01159355..79b983206a 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -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
index 0000000000..ef0abc3e45
--- /dev/null
+++ b/source4/libcli/smb2/smb2_calls.h
@@ -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;
+};
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index a178b35f93..dd05eed1dd 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -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 */
diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c
index 00a9b35c17..7237bb704a 100644
--- a/source4/torture/smb2/connect.c
+++ b/source4/torture/smb2/connect.c
@@ -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"
@@ -37,17 +38,16 @@
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;
}