mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
r11668: yay! we get a successful session setup with SMB2, and get back a 64bit uid
(This used to be commit 72b34a7c1b66af6be02f66639efc55a19c73e387)
This commit is contained in:
parent
86c1370cb0
commit
7a78d2d6b0
@ -33,7 +33,6 @@ struct smb2_request *smb2_negprot_send(struct smb2_transport *transport,
|
||||
{
|
||||
struct smb2_request *req;
|
||||
|
||||
|
||||
req = smb2_request_init(transport, SMB2_OP_NEGPROT, 0x26);
|
||||
if (req == NULL) return NULL;
|
||||
|
||||
|
@ -130,7 +130,7 @@ BOOL smb2_request_is_error(struct smb2_request *req)
|
||||
/*
|
||||
check if a range in the reply body is out of bounds
|
||||
*/
|
||||
BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size)
|
||||
BOOL smb2_oob_in(struct smb2_request *req, const uint8_t *ptr, uint_t size)
|
||||
{
|
||||
/* be careful with wraparound! */
|
||||
if (ptr < req->in.body ||
|
||||
@ -142,14 +142,66 @@ BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size)
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
check if a range in the outgoing body is out of bounds
|
||||
*/
|
||||
BOOL smb2_oob_out(struct smb2_request *req, const uint8_t *ptr, uint_t size)
|
||||
{
|
||||
/* be careful with wraparound! */
|
||||
if (ptr < req->out.body ||
|
||||
ptr >= req->out.body + req->out.body_size ||
|
||||
size > req->out.body_size ||
|
||||
ptr + size > req->out.body + req->out.body_size) {
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
pull a data blob from the body of a reply
|
||||
*/
|
||||
DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size)
|
||||
{
|
||||
if (smb2_oob(req, ptr, size)) {
|
||||
if (smb2_oob_in(req, ptr, size)) {
|
||||
return data_blob(NULL, 0);
|
||||
}
|
||||
return data_blob_talloc(req, ptr, size);
|
||||
}
|
||||
|
||||
/*
|
||||
pull a ofs/length/blob triple into a data blob
|
||||
the ptr points to the start of the offset/length pair
|
||||
*/
|
||||
NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob)
|
||||
{
|
||||
uint16_t ofs, size;
|
||||
if (smb2_oob_in(req, ptr, 4)) {
|
||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
ofs = SVAL(ptr, 0);
|
||||
size = SVAL(ptr, 2);
|
||||
if (smb2_oob_in(req, req->in.hdr + ofs, size)) {
|
||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*blob = data_blob_talloc(req, req->in.hdr+ofs, size);
|
||||
NT_STATUS_HAVE_NO_MEMORY(blob->data);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
push a ofs/length/blob triple into a data blob
|
||||
the ptr points to the start of the offset/length pair
|
||||
|
||||
NOTE: assumes blob goes immediately after the offset/length pair. Needs
|
||||
to be generalised
|
||||
*/
|
||||
NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB blob)
|
||||
{
|
||||
if (smb2_oob_out(req, ptr, 4+blob.length)) {
|
||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
SSVAL(ptr, 0, 4 + (ptr - req->out.hdr));
|
||||
SSVAL(ptr, 2, blob.length);
|
||||
memcpy(ptr+4, blob.data, blob.length);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -62,17 +62,22 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session,
|
||||
struct smb2_session_setup *io)
|
||||
{
|
||||
struct smb2_request *req;
|
||||
NTSTATUS status;
|
||||
|
||||
req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP,
|
||||
0x10 + io->in.secblob.length);
|
||||
if (req == NULL) return NULL;
|
||||
|
||||
SBVAL(req->out.hdr, SMB2_HDR_UID, session->uid);
|
||||
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);
|
||||
|
||||
status = smb2_push_ofs_blob(req, req->out.body+0x0C, io->in.secblob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smb2_transport_send(req);
|
||||
|
||||
@ -86,10 +91,11 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session,
|
||||
NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
|
||||
struct smb2_session_setup *io)
|
||||
{
|
||||
uint16_t blobsize;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!smb2_request_receive(req) ||
|
||||
smb2_request_is_error(req)) {
|
||||
(smb2_request_is_error(req) &&
|
||||
!NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
|
||||
return smb2_request_destroy(req);
|
||||
}
|
||||
|
||||
@ -97,10 +103,14 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
|
||||
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);
|
||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
||||
io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID);
|
||||
|
||||
status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
smb2_request_destroy(req);
|
||||
return status;
|
||||
}
|
||||
talloc_steal(mem_ctx, io->out.secblob.data);
|
||||
|
||||
return smb2_request_destroy(req);
|
||||
|
@ -57,6 +57,7 @@ struct smb2_transport {
|
||||
struct smb2_session {
|
||||
struct smb2_transport *transport;
|
||||
struct gensec_security *gensec;
|
||||
uint64_t uid;
|
||||
};
|
||||
|
||||
struct smb2_request_buffer {
|
||||
@ -141,8 +142,7 @@ struct smb2_request {
|
||||
#define SMB2_HDR_SEQNUM 0x18
|
||||
#define SMB2_HDR_PID 0x20
|
||||
#define SMB2_HDR_TID 0x24
|
||||
#define SMB2_HDR_UID 0x28
|
||||
#define SMB2_HDR_UID2 0x2c /* whats this? */
|
||||
#define SMB2_HDR_UID 0x28 /* 64 bit */
|
||||
#define SMB2_HDR_SIG 0x30 /* guess ... */
|
||||
#define SMB2_HDR_BODY 0x40
|
||||
|
||||
|
@ -50,14 +50,13 @@ struct smb2_session_setup {
|
||||
uint32_t unknown1; /* 0x11 */
|
||||
uint32_t unknown2; /* 0xF */
|
||||
uint32_t unknown3; /* 0x00 */
|
||||
uint16_t unknown4; /* 0x50 */
|
||||
/* uint16_t secblob size here */
|
||||
/* uint16_t secblob ofs/size here */
|
||||
DATA_BLOB secblob;
|
||||
} in;
|
||||
struct {
|
||||
uint32_t unknown1; /* 0x09 */
|
||||
uint16_t unknown2; /* 0x48 */
|
||||
/* uint16_t secblob size here */
|
||||
/* uint16_t secblob ofs/size here */
|
||||
DATA_BLOB secblob;
|
||||
uint64_t uid; /* returned in header */
|
||||
} out;
|
||||
};
|
||||
|
@ -183,7 +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);
|
||||
DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", req->seqnum));
|
||||
dump_data(2, 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
|
||||
@ -200,7 +201,7 @@ error:
|
||||
DLIST_REMOVE(transport->pending_recv, req);
|
||||
req->state = SMB2_REQUEST_ERROR;
|
||||
}
|
||||
dump_data(0, blob.data, blob.length);
|
||||
dump_data(2, blob.data, blob.length);
|
||||
data_blob_free(&blob);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
@ -247,6 +248,9 @@ void smb2_transport_send(struct smb2_request *req)
|
||||
|
||||
_smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
|
||||
|
||||
DEBUG(2, ("SMB2 send seqnum=0x%llx\n", req->seqnum));
|
||||
dump_data(2, req->out.body, req->out.body_size);
|
||||
|
||||
/* check if the transport is dead */
|
||||
if (req->transport->socket->sock == NULL) {
|
||||
req->state = SMB2_REQUEST_ERROR;
|
||||
|
@ -76,6 +76,8 @@ static struct smb2_transport *torture_smb2_negprot(TALLOC_CTX *mem_ctx, const ch
|
||||
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));
|
||||
|
||||
transport->negotiate.secblob = io.out.secblob;
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
@ -89,12 +91,12 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor
|
||||
struct smb2_session_setup io;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(transport);
|
||||
DATA_BLOB secblob;
|
||||
|
||||
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);
|
||||
|
||||
@ -126,21 +128,39 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor
|
||||
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;
|
||||
}
|
||||
secblob = session->transport->negotiate.secblob;
|
||||
|
||||
do {
|
||||
NTSTATUS status1;
|
||||
|
||||
status1 = gensec_update(session->gensec, tmp_ctx, secblob, &io.in.secblob);
|
||||
if (!NT_STATUS_EQUAL(status1, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
|
||||
!NT_STATUS_IS_OK(status1)) {
|
||||
DEBUG(1, ("Failed initial gensec_update : %s\n",
|
||||
nt_errstr(status1)));
|
||||
status = status1;
|
||||
break;
|
||||
}
|
||||
|
||||
status = smb2_session_setup(session, tmp_ctx, &io);
|
||||
secblob = io.out.secblob;
|
||||
|
||||
session->uid = io.out.uid;
|
||||
|
||||
if (NT_STATUS_IS_OK(status) &&
|
||||
NT_STATUS_EQUAL(status1, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
status = gensec_update(session->gensec, tmp_ctx, secblob,
|
||||
&io.in.secblob);
|
||||
}
|
||||
} while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
printf("Session setup gave UID 0x%llx\n", session->uid);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user