summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-02-12 12:54:44 +1100
committerAndrew Tridgell <tridge@samba.org>2008-02-12 12:54:44 +1100
commitccc27e681cbd6283513b929d58f2ebce35e6658b (patch)
tree381348c93cb7bb4fec484768e3b961683c02ff3a /source4
parentecb987c97c98d7374a0e703c56f2a71f8514ece8 (diff)
downloadsamba-ccc27e681cbd6283513b929d58f2ebce35e6658b.tar.gz
samba-ccc27e681cbd6283513b929d58f2ebce35e6658b.tar.bz2
samba-ccc27e681cbd6283513b929d58f2ebce35e6658b.zip
fixed up the .in side of SMB2 negprot
fixed the input side of the SMB2 negprot structure and parsers according to the documentation (This used to be commit 55af8acc7b32c24e4b1187e9d8d1c8f060e914b0)
Diffstat (limited to 'source4')
-rw-r--r--source4/libcli/smb2/connect.c8
-rw-r--r--source4/libcli/smb2/negprot.c31
-rw-r--r--source4/libcli/smb2/smb2_calls.h13
-rw-r--r--source4/smb_server/smb/negprot.c1
-rw-r--r--source4/smb_server/smb2/negprot.c40
-rw-r--r--source4/smb_server/smb_server.h2
6 files changed, 76 insertions, 19 deletions
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 4518203183..a2ae828fa5 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -120,6 +120,7 @@ static void continue_socket(struct composite_context *creq)
struct smbcli_socket *sock;
struct smb2_transport *transport;
struct smb2_request *req;
+ uint16_t dialects[1];
c->status = smbcli_sock_connect_recv(creq, state, &sock);
if (!composite_is_ok(c)) return;
@@ -128,7 +129,12 @@ static void continue_socket(struct composite_context *creq)
if (composite_nomem(transport, c)) return;
ZERO_STRUCT(state->negprot);
- state->negprot.in.unknown1 = 0x0001;
+ state->negprot.in.dialect_count = 1;
+ state->negprot.in.security_mode = 0;
+ state->negprot.in.capabilities = 0;
+ unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
+ dialects[0] = 0;
+ state->negprot.in.dialects = dialects;
req = smb2_negprot_send(transport, &state->negprot);
if (composite_nomem(req, c)) return;
diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c
index 38fe0e7e53..a678ebe229 100644
--- a/source4/libcli/smb2/negprot.c
+++ b/source4/libcli/smb2/negprot.c
@@ -31,16 +31,33 @@ 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, false, 0);
+ uint16_t size = 0x24 + io->in.dialect_count*2;
+ DATA_BLOB guid_blob;
+ enum ndr_err_code ndr_err;
+ int i;
+
+ req = smb2_request_init(transport, SMB2_OP_NEGPROT, size, false, 0);
if (req == NULL) return NULL;
- /* this seems to be a bug, they use 0x24 but the length is 0x26 */
- SSVAL(req->out.body, 0x00, 0x24);
- SSVAL(req->out.body, 0x02, io->in.unknown1);
- memcpy(req->out.body+0x04, io->in.unknown2, 32);
- SSVAL(req->out.body, 0x24, io->in.unknown3);
+ ndr_err = ndr_push_struct_blob(&guid_blob, req, NULL,
+ &io->in.client_guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || guid_blob.length != 16) {
+ talloc_free(req);
+ return NULL;
+ }
+
+ SSVAL(req->out.body, 0x00, 0x24);
+ SSVAL(req->out.body, 0x02, io->in.dialect_count);
+ SSVAL(req->out.body, 0x04, io->in.security_mode);
+ SSVAL(req->out.body, 0x06, io->in.reserved);
+ SIVAL(req->out.body, 0x08, io->in.capabilities);
+ memcpy(req->out.body+0x0C, guid_blob.data, guid_blob.length);
+ smbcli_push_nttime(req->out.body, 0x1C, io->in.start_time);
+ for (i=0;i<io->in.dialect_count;i++) {
+ SSVAL(req->out.body, 0x24 + i*2, io->in.dialects[i]);
+ }
smb2_transport_send(req);
diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h
index 6a551da4ae..41fb35b8f3 100644
--- a/source4/libcli/smb2/smb2_calls.h
+++ b/source4/libcli/smb2/smb2_calls.h
@@ -23,11 +23,14 @@
struct smb2_negprot {
struct {
- /* static body buffer 38 (0x26) bytes */
- /* uint16_t buffer_code; 0x24 (why?) */
- uint16_t unknown1; /* 0x0001 */
- uint8_t unknown2[32]; /* all zero */
- uint16_t unknown3; /* 0x00000 */
+ uint16_t dialect_count; /* size of dialects array */
+ uint16_t security_mode; /* 0==signing disabled
+ 1==signing enabled */
+ uint16_t reserved;
+ uint32_t capabilities;
+ struct GUID client_guid;
+ NTTIME start_time;
+ uint16_t *dialects;
} in;
struct {
/* static body buffer 64 (0x40) bytes */
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index 6d9ff838cb..b57e5e1d64 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -466,6 +466,7 @@ static const struct {
void (*proto_reply_fn)(struct smbsrv_request *req, uint16_t choice);
int protocol_level;
} supported_protocols[] = {
+ {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2},
{"SMB 2.001", "SMB2", reply_smb2, PROTOCOL_SMB2},
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 8e3cfd3547..68509d71c6 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h"
+#include "libcli/raw/libcliraw.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "smb_server/smb_server.h"
@@ -92,6 +93,12 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
struct timeval current_time;
struct timeval boot_time;
+ /* we only do dialect 0 for now */
+ if (io->in.dialect_count < 1 ||
+ io->in.dialects[0] != 0) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
req->smb_conn->negotiate.protocol = PROTOCOL_SMB2;
current_time = timeval_current(); /* TODO: handle timezone?! */
@@ -155,6 +162,9 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro
void smb2srv_negprot_recv(struct smb2srv_request *req)
{
struct smb2_negprot *io;
+ int i;
+ DATA_BLOB guid_blob;
+ enum ndr_err_code ndr_err;
if (req->in.body_size < 0x26) {
smb2srv_send_error(req, NT_STATUS_FOOBAR);
@@ -168,9 +178,30 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
return;
}
- io->in.unknown1 = SVAL(req->in.body, 0x02);
- memcpy(io->in.unknown2, req->in.body + 0x04, 0x20);
- io->in.unknown3 = SVAL(req->in.body, 0x24);
+ io->in.dialect_count = SVAL(req->in.body, 0x02);
+ io->in.security_mode = SVAL(req->in.body, 0x04);
+ io->in.reserved = SVAL(req->in.body, 0x06);
+ io->in.capabilities = IVAL(req->in.body, 0x08);
+ guid_blob.data = req->in.body + 0xC;
+ guid_blob.length = 16;
+ ndr_err = ndr_pull_struct_blob(&guid_blob, req, NULL, &io->in.client_guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR));
+ talloc_free(req);
+ return;
+ }
+ io->in.start_time = smbcli_pull_nttime(req->in.body, 0x1C);
+
+ io->in.dialects = talloc_array(req, uint16_t, io->in.dialect_count);
+ if (io->in.dialects == NULL) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
+ talloc_free(req);
+ return;
+ }
+ for (i=0;i<io->in.dialect_count;i++) {
+ io->in.dialects[i] = SVAL(req->in.body, 0x24+i*2);
+ }
req->status = smb2srv_negprot_backend(req, io);
@@ -182,14 +213,13 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
}
/*
- * reply to a SMB negprot request with dialect "SMB 2.001"
+ * reply to a SMB negprot request with dialect "SMB 2.002"
*/
void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
{
struct smb2srv_request *req;
uint32_t body_fixed_size = 0x26;
- /* create a fake SMB2 negprot request */
req = talloc_zero(smb_req->smb_conn, struct smb2srv_request);
if (!req) goto nomem;
req->smb_conn = smb_req->smb_conn;
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index 5644dfe6fb..bb0673b7d0 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -291,7 +291,7 @@ struct smbsrv_connection {
/* the negotiatiated protocol */
enum protocol_types protocol;
-
+
/* authentication context for multi-part negprot */
struct auth_context *auth_context;