mirror of
https://github.com/samba-team/samba.git
synced 2025-11-30 20:23:49 +03:00
fixed up the .in side of SMB2 negprot
fixed the input side of the SMB2 negprot structure and parsers according to the documentation
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -31,16 +31,33 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport,
|
||||
struct smb2_negprot *io)
|
||||
{
|
||||
struct smb2_request *req;
|
||||
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, 0x26, false, 0);
|
||||
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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user