diff options
Diffstat (limited to 'source4/libcli/smb2')
-rw-r--r-- | source4/libcli/smb2/config.mk | 3 | ||||
-rw-r--r-- | source4/libcli/smb2/negprot.c | 53 | ||||
-rw-r--r-- | source4/libcli/smb2/request.c | 16 | ||||
-rw-r--r-- | source4/libcli/smb2/session.c | 47 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2.h | 8 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2_calls.h | 63 | ||||
-rw-r--r-- | source4/libcli/smb2/transport.c | 2 |
7 files changed, 153 insertions, 39 deletions
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 */ |