From 2e753f851885930000eadbd4b69660d85124c716 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 12:37:16 +0000 Subject: r11679: opening/creating files in SMB2 now works. Lots of unknown parameters in the call tho. (This used to be commit 548fbd86b3b114493943b50669bdcba2f4ed87f2) --- source4/libcli/smb2/create.c | 124 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 source4/libcli/smb2/create.c (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c new file mode 100644 index 0000000000..dbb4d4b974 --- /dev/null +++ b/source4/libcli/smb2/create.c @@ -0,0 +1,124 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client tree 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" +#include "libcli/smb2/smb2_calls.h" + +/* + send a create request +*/ +struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create *io) +{ + struct smb2_request *req; + NTSTATUS status; + DATA_BLOB path; + uint8_t *ptr; + + status = smb2_string_blob(tree, io->in.fname, &path); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); + if (req == NULL) return NULL; + + SIVAL(req->out.body, 0x00, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x08, io->in.unknown3[0]); + SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); + SIVAL(req->out.body, 0x10, io->in.unknown3[2]); + SIVAL(req->out.body, 0x14, io->in.unknown3[3]); + SIVAL(req->out.body, 0x18, io->in.access_mask); + SIVAL(req->out.body, 0x1C, io->in.file_attr); + SIVAL(req->out.body, 0x20, io->in.unknown4); + SIVAL(req->out.body, 0x24, io->in.open_disposition); + SIVAL(req->out.body, 0x28, io->in.unknown5); + + SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ + SSVAL(req->out.body, 0x2E, path.length); + SIVAL(req->out.body, 0x30, 0x40+0x38+path.length); /* offset to 2nd buffer? */ + + SIVAL(req->out.body, 0x34, io->in.unknown6); + + memcpy(req->out.body+0x38, path.data, path.length); + + ptr = req->out.body+0x38+path.length; + + SIVAL(ptr, 0x00, io->in.unknown7); + SIVAL(ptr, 0x04, io->in.unknown8); + SIVAL(ptr, 0x08, io->in.unknown9); + SIVAL(ptr, 0x0C, io->in.unknown10); + SIVAL(ptr, 0x10, io->in.unknown11); + + data_blob_free(&path); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a create reply +*/ +NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) +{ + int i; + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x54) { + printf("body size %d\n", req->in.body_size); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.unknown3 = IVAL(req->in.body, 0x24); + io->out.unknown4 = IVAL(req->in.body, 0x28); + io->out.unknown5 = IVAL(req->in.body, 0x2C); + io->out.unknown6 = IVAL(req->in.body, 0x30); + io->out.unknown7 = IVAL(req->in.body, 0x34); + memcpy(io->out.handle.data, req->in.body+0x38, 20); + for (i=0;i<2;i++) { + io->out.unknown8[i] = IVAL(req->in.body, 0x4C + i*4); + } + + return smb2_request_destroy(req); +} + +/* + sync create request +*/ +NTSTATUS smb2_create(struct smb2_tree *tree, struct smb2_create *io) +{ + struct smb2_request *req = smb2_create_send(tree, io); + return smb2_create_recv(req, io); +} -- cgit From 1b2e8caad3fb01ea3b61bda63965d324de61c815 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 13:08:31 +0000 Subject: r11680: added smb2_close(). This also demonstrates that file handles are 16 bytes, not 20 bytes (metze, you were right!) (This used to be commit d3bcc6628cde9ddedf0fd408cbee573f133ce582) --- source4/libcli/smb2/create.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index dbb4d4b974..dc602ca71c 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -84,14 +84,12 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { - int i; if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } if (req->in.body_size < 0x54) { - printf("body size %d\n", req->in.body_size); return NT_STATUS_BUFFER_TOO_SMALL; } @@ -106,10 +104,11 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.unknown5 = IVAL(req->in.body, 0x2C); io->out.unknown6 = IVAL(req->in.body, 0x30); io->out.unknown7 = IVAL(req->in.body, 0x34); - memcpy(io->out.handle.data, req->in.body+0x38, 20); - for (i=0;i<2;i++) { - io->out.unknown8[i] = IVAL(req->in.body, 0x4C + i*4); - } + io->out.unknown8 = IVAL(req->in.body, 0x38); + io->out.unknown9 = IVAL(req->in.body, 0x3C); + io->out.handle.data[0] = BVAL(req->in.body, 0x40); + io->out.handle.data[1] = BVAL(req->in.body, 0x48); + io->out.unknown10 = IVAL(req->in.body, 0x50); return smb2_request_destroy(req); } -- cgit From 461ccc557b7cc4ed8b0a3f9fc9aa5f03eccbc656 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 14:04:46 +0000 Subject: r11681: filled in a few more smb2_create() fields (This used to be commit a95413568f1e45691524dfd8e9159a3bafe358ea) --- source4/libcli/smb2/create.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index dc602ca71c..53476ad056 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -51,9 +51,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x14, io->in.unknown3[3]); SIVAL(req->out.body, 0x18, io->in.access_mask); SIVAL(req->out.body, 0x1C, io->in.file_attr); - SIVAL(req->out.body, 0x20, io->in.unknown4); + SIVAL(req->out.body, 0x20, io->in.share_access); SIVAL(req->out.body, 0x24, io->in.open_disposition); - SIVAL(req->out.body, 0x28, io->in.unknown5); + SIVAL(req->out.body, 0x28, io->in.create_options); SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ SSVAL(req->out.body, 0x2E, path.length); @@ -99,13 +99,10 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.unknown3 = IVAL(req->in.body, 0x24); - io->out.unknown4 = IVAL(req->in.body, 0x28); - io->out.unknown5 = IVAL(req->in.body, 0x2C); - io->out.unknown6 = IVAL(req->in.body, 0x30); - io->out.unknown7 = IVAL(req->in.body, 0x34); - io->out.unknown8 = IVAL(req->in.body, 0x38); - io->out.unknown9 = IVAL(req->in.body, 0x3C); + io->out.alloc_size = BVAL(req->in.body, 0x28); + io->out.size = BVAL(req->in.body, 0x30); + io->out.file_attr = IVAL(req->in.body, 0x38); + io->out.unknown8 = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); io->out.unknown10 = IVAL(req->in.body, 0x50); -- cgit From be77dac05f22b93345aa7b6f8ba42615d74b19a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 14:14:22 +0000 Subject: r11683: fixed create call (This used to be commit 02d733190340fbb611443b0cc484813ba026eafe) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 53476ad056..f234e6cb35 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -102,10 +102,10 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.alloc_size = BVAL(req->in.body, 0x28); io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); - io->out.unknown8 = IVAL(req->in.body, 0x3C); + io->out.unknown3 = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); - io->out.unknown10 = IVAL(req->in.body, 0x50); + io->out.unknown4 = IVAL(req->in.body, 0x50); return smb2_request_destroy(req); } -- cgit From 91e1893741741de04b73a098495c697434105803 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 23:27:47 +0000 Subject: r11691: added reply buffer code checks and oplock flags for create request/reply (This used to be commit 26ed781375c03958241d8c93324e04e948944d01) --- source4/libcli/smb2/create.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index f234e6cb35..e4b0773758 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -43,7 +43,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); if (req == NULL) return NULL; - SIVAL(req->out.body, 0x00, io->in.unknown1); + SSVAL(req->out.body, 0x00, io->in.buffer_code); + SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); @@ -84,6 +85,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { + smb2_request_receive(req); + dump_data(0, req->in.body, req->in.body_size); + if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); @@ -93,16 +97,18 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) return NT_STATUS_BUFFER_TOO_SMALL; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); - io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); - io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); - io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); - io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.alloc_size = BVAL(req->in.body, 0x28); - io->out.size = BVAL(req->in.body, 0x30); - io->out.file_attr = IVAL(req->in.body, 0x38); - io->out.unknown3 = IVAL(req->in.body, 0x3C); + SMB2_CHECK_BUFFER_CODE(req, 0x59); + + io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.create_action = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.alloc_size = BVAL(req->in.body, 0x28); + io->out.size = BVAL(req->in.body, 0x30); + io->out.file_attr = IVAL(req->in.body, 0x38); + io->out._pad = IVAL(req->in.body, 0x3C); io->out.handle.data[0] = BVAL(req->in.body, 0x40); io->out.handle.data[1] = BVAL(req->in.body, 0x48); io->out.unknown4 = IVAL(req->in.body, 0x50); -- cgit From 56712033d59212c8d72c8d60df885a5764601b7e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 02:16:19 +0000 Subject: r11694: fixed 2 valgrind errors (This used to be commit 6381fe72417a5cd231b63a87a6a0ba9c65030ce6) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index e4b0773758..1316626432 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -70,7 +70,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(ptr, 0x04, io->in.unknown8); SIVAL(ptr, 0x08, io->in.unknown9); SIVAL(ptr, 0x0C, io->in.unknown10); - SIVAL(ptr, 0x10, io->in.unknown11); + SBVAL(ptr, 0x10, io->in.unknown11); data_blob_free(&path); -- cgit From 67a85b3f1bca7e0590ae97d07a6ef32c418e64d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 07:48:56 +0000 Subject: r11697: - added a generic SMB2 getinfo call - added a SMB2-SCANGETINFO test for scanning for available info levels - added names for the info levels I recognise to smb2.h (This used to be commit fe5986067e2aaca039d70393ccc8761434f18fe6) --- source4/libcli/smb2/create.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 1316626432..9483f35ca1 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -85,9 +85,6 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create */ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) { - smb2_request_receive(req); - dump_data(0, req->in.body, req->in.body_size); - if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); -- cgit From e9eb56068573d89f8ce45f08220ca870b3daa669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 11:01:15 +0000 Subject: r11741: - the buffer code (first 2 bytes in the SMB2 body) seem to be the length of the fixed body part, and +1 if there's a dynamic part - there're 3 types of dynamic blobs with uint16_t offset/uint16_t size with uint16_t offset/uint32_t size with uint32_t offset/uint32_t size /* aligned to 8 bytes */ - strings are transmitted in UTF-16 with no termination and packet into a uint16/uint16 blob metze (This used to be commit 79103c51e5c752fbdb4d25a0047b65002828df89) --- source4/libcli/smb2/create.c | 59 +++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 9483f35ca1..79d3341bd0 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -32,18 +32,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; - DATA_BLOB path; - uint8_t *ptr; - status = smb2_string_blob(tree, io->in.fname, &path); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x00, io->in.buffer_code); SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.unknown2); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); @@ -56,23 +48,17 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x24, io->in.open_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); - SSVAL(req->out.body, 0x2C, 0x40+0x38); /* offset to fname */ - SSVAL(req->out.body, 0x2E, path.length); - SIVAL(req->out.body, 0x30, 0x40+0x38+path.length); /* offset to 2nd buffer? */ - - SIVAL(req->out.body, 0x34, io->in.unknown6); - - memcpy(req->out.body+0x38, path.data, path.length); - - ptr = req->out.body+0x38+path.length; - - SIVAL(ptr, 0x00, io->in.unknown7); - SIVAL(ptr, 0x04, io->in.unknown8); - SIVAL(ptr, 0x08, io->in.unknown9); - SIVAL(ptr, 0x0C, io->in.unknown10); - SBVAL(ptr, 0x10, io->in.unknown11); + status = smb2_push_o16s16_string(&req->out, req->out.body+0x2C, io->in.fname); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } - data_blob_free(&path); + status = smb2_push_o32s32_blob(&req->out, req->out.body+0x30, io->in.blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } smb2_transport_send(req); @@ -83,18 +69,16 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* recv a create reply */ -NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) +NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io) { + NTSTATUS status; + if (!smb2_request_receive(req) || smb2_request_is_error(req)) { return smb2_request_destroy(req); } - if (req->in.body_size < 0x54) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - SMB2_CHECK_BUFFER_CODE(req, 0x59); + SMB2_CHECK_PACKET_RECV(req, 0x58, True); io->out.oplock_flags = SVAL(req->in.body, 0x02); io->out.create_action = IVAL(req->in.body, 0x04); @@ -106,9 +90,12 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); io->out._pad = IVAL(req->in.body, 0x3C); - io->out.handle.data[0] = BVAL(req->in.body, 0x40); - io->out.handle.data[1] = BVAL(req->in.body, 0x48); - io->out.unknown4 = IVAL(req->in.body, 0x50); + smb2_pull_handle(req->in.body+0x40, &io->out.handle); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } return smb2_request_destroy(req); } @@ -116,8 +103,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io) /* sync create request */ -NTSTATUS smb2_create(struct smb2_tree *tree, struct smb2_create *io) +NTSTATUS smb2_create(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_create *io) { struct smb2_request *req = smb2_create_send(tree, io); - return smb2_create_recv(req, io); + return smb2_create_recv(req, mem_ctx, io); } -- cgit From fe996e8ac687dbf5b5cfdd795f14aed89663f06d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 03:32:38 +0000 Subject: r11754: make the SMB2 blob push routines take offsets, so they fit better with the rest of the packet construction code (This used to be commit 387ec2b17ff30a1c040b460b498c8fa7d8770593) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 79d3341bd0..47fd208643 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -48,13 +48,13 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SIVAL(req->out.body, 0x24, io->in.open_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); - status = smb2_push_o16s16_string(&req->out, req->out.body+0x2C, io->in.fname); + status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } - status = smb2_push_o32s32_blob(&req->out, req->out.body+0x30, io->in.blob); + status = smb2_push_o32s32_blob(&req->out, 0x30, io->in.blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; -- cgit From c8c7fb2492d3f19939df67f98e4ea6ad423274da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 09:25:25 +0000 Subject: r11775: added support for creating files on SMB2 with initial EA lists and an ACL (This used to be commit ff197092988cee64742f83df23c43ae664a196f9) --- source4/libcli/smb2/create.c | 65 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 47fd208643..647b408c68 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -25,6 +25,37 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#define CREATE_TAG_EA 0x41747845 /* "ExtA" */ +#define CREATE_TAG_SD 0x6341784D /* "MxAc" */ + +/* + add a blob to a smb2_create attribute blob +*/ +static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + uint32_t tag, + DATA_BLOB add, BOOL last) +{ + NTSTATUS status; + uint32_t ofs = blob->length; + status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length); + NT_STATUS_NOT_OK_RETURN(status); + + if (last) { + SIVAL(blob->data, ofs+0x00, 0); + } else { + SIVAL(blob->data, ofs+0x00, 0x18 + add.length); + } + SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ + SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ + SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */ + SIVAL(blob->data, ofs+0x0C, add.length); + SIVAL(blob->data, ofs+0x10, tag); + SIVAL(blob->data, ofs+0x14, 0); /* pad? */ + memcpy(blob->data+ofs+0x18, add.data, add.length); + + return NT_STATUS_OK; +} + /* send a create request */ @@ -32,6 +63,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; + DATA_BLOB blob = data_blob(NULL, 0); req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); if (req == NULL) return NULL; @@ -54,7 +86,36 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } - status = smb2_push_o32s32_blob(&req->out, 0x30, io->in.blob); + if (io->in.eas.num_eas != 0) { + DATA_BLOB b = data_blob_talloc(req, NULL, + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EA, b, False); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + data_blob_free(&b); + } + + if (io->in.sd != NULL) { + DATA_BLOB b; + status = ndr_push_struct_blob(&b, req, io->in.sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, b, True); + } else { + status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, data_blob(NULL, 0), True); + } + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + status = smb2_push_o32s32_blob(&req->out, 0x30, blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -74,7 +135,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct NTSTATUS status; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } -- cgit From d5f37ecf94e2b63511102b3fd34c0e7bcd8d7879 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 11:45:24 +0000 Subject: r11780: it turns out that the MxAc tag isn't a security descriptor, its a request that the server return its own MxAc blob which contains the maximum allowed access_mask for the returned file handle (This used to be commit c0288aa8cd46ca384074f89430c226d725c39475) --- source4/libcli/smb2/create.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 647b408c68..564eba7f46 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -25,8 +25,8 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#define CREATE_TAG_EA 0x41747845 /* "ExtA" */ -#define CREATE_TAG_SD 0x6341784D /* "MxAc" */ +#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */ +#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */ /* add a blob to a smb2_create attribute blob @@ -37,13 +37,14 @@ static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, { NTSTATUS status; uint32_t ofs = blob->length; - status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length); + uint8_t pad = smb2_padding_size(add.length, 8); + status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad); NT_STATUS_NOT_OK_RETURN(status); if (last) { SIVAL(blob->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x18 + add.length); + SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad); } SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ @@ -52,6 +53,7 @@ static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, SIVAL(blob->data, ofs+0x10, tag); SIVAL(blob->data, ofs+0x14, 0); /* pad? */ memcpy(blob->data+ofs+0x18, add.data, add.length); + memset(blob->data+ofs+0x18+add.length, 0, pad); return NT_STATUS_OK; } @@ -90,7 +92,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EA, b, False); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, False); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -98,18 +100,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create data_blob_free(&b); } - if (io->in.sd != NULL) { - DATA_BLOB b; - status = ndr_push_struct_blob(&b, req, io->in.sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } - status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, b, True); - } else { - status = smb2_create_blob_add(req, &blob, CREATE_TAG_SD, data_blob(NULL, 0), True); - } + /* an empty MxAc tag seems to be used to ask the server to + return the maximum access mask allowed on the file */ + status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), True); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From 310fa875091a85bb5d7be196906723f14305d406 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 25 Nov 2005 05:23:55 +0000 Subject: r11888: - added SMB2 trans support - added session key to SMB2 - renamed 'unknown2' in create to 'impersonation' (This used to be commit aef915f312a78bf8a4123f7c40fcd14ff293d934) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 564eba7f46..c7bb190559 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -71,7 +71,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); - SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x04, io->in.impersonation); SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); -- cgit From dc86ab3e454d7219608d01879145dec5609acaa3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 May 2006 10:47:37 +0000 Subject: r15532: add a BOOL body_dynamic_present, because the body_dynamic_size can be 0 also if the dynamic flag should be set metze (This used to be commit 7829100e1ee79f4f5d24004af221288e19c09b3e) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index c7bb190559..339258a0df 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -67,7 +67,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, 1); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, True, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); -- cgit From e306c5bf129a981693bd251d45597f1e584ee850 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 10:46:38 +0000 Subject: r15741: move smb2 request structures into the main smb request structs as new levels metze (This used to be commit 91806353174704857dfcc15a730af7232cfde660) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 339258a0df..da21d090fd 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -144,7 +144,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); io->out._pad = IVAL(req->in.body, 0x3C); - smb2_pull_handle(req->in.body+0x40, &io->out.handle); + smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); -- cgit From f6274959ba381b6b5d025cb0cee78665107a72a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 11:16:11 +0000 Subject: r20647: add cluster code (This used to be commit 5870830b99a8d76bda1ff5af3fcf8dda9aba50ec) --- source4/libcli/smb2/create.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index da21d090fd..81c11eebc2 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -72,6 +72,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.impersonation); + /* are these 16 bytes the root_fid (vl) */ SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); -- cgit From 1c211a2e43db46c649a963ec883481cc4321870a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 11:50:33 +0000 Subject: r20650: revert a bunch of code I didn't mean to commit yet (This used to be commit b3e2d4908781781a487eaeb683d22eb967e5597d) --- source4/libcli/smb2/create.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 81c11eebc2..da21d090fd 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -72,7 +72,6 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create SSVAL(req->out.body, 0x02, io->in.oplock_flags); SIVAL(req->out.body, 0x04, io->in.impersonation); - /* are these 16 bytes the root_fid (vl) */ SIVAL(req->out.body, 0x08, io->in.unknown3[0]); SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); SIVAL(req->out.body, 0x10, io->in.unknown3[2]); -- cgit From 4ef7bab6d0dd64fc426508be164b3d3f24762b22 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 May 2007 10:05:13 +0000 Subject: r22791: make it possible to use smb2_create_blob_add() in the server code too metze (This used to be commit c08eeb62ca001cebcb7af2b655269e4b388e69c1) --- source4/libcli/smb2/create.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index da21d090fd..fe91acbf0a 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -31,9 +31,9 @@ /* add a blob to a smb2_create attribute blob */ -static NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - uint32_t tag, - DATA_BLOB add, BOOL last) +NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + uint32_t tag, + DATA_BLOB add, BOOL last) { NTSTATUS status; uint32_t ofs = blob->length; -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libcli/smb2/create.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index fe91acbf0a..58e7a905d9 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" -- cgit From 0b91f3916430d0271eab867675d44c5439de40c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 29 Aug 2007 13:07:03 +0000 Subject: r24780: More work allowing libutil to be used by external users. (This used to be commit 31993cf67b816a184a4a4e92ef8ca2532c797190) --- source4/libcli/smb2/create.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 58e7a905d9..c8ac271f44 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -34,11 +34,10 @@ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint32_t tag, DATA_BLOB add, BOOL last) { - NTSTATUS status; uint32_t ofs = blob->length; uint8_t pad = smb2_padding_size(add.length, 8); - status = data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad); - NT_STATUS_NOT_OK_RETURN(status); + if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad)) + return NT_STATUS_NO_MEMORY; if (last) { SIVAL(blob->data, ofs+0x00, 0); -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libcli/smb2/create.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index c8ac271f44..ba11c22e87 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -32,7 +32,7 @@ */ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint32_t tag, - DATA_BLOB add, BOOL last) + DATA_BLOB add, bool last) { uint32_t ofs = blob->length; uint8_t pad = smb2_padding_size(add.length, 8); @@ -65,7 +65,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); - req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, True, 0); + req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; SSVAL(req->out.body, 0x02, io->in.oplock_flags); @@ -90,7 +90,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, False); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -100,7 +100,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), True); + status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -130,7 +130,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct return smb2_request_destroy(req); } - SMB2_CHECK_PACKET_RECV(req, 0x58, True); + SMB2_CHECK_PACKET_RECV(req, 0x58, true); io->out.oplock_flags = SVAL(req->in.body, 0x02); io->out.create_action = IVAL(req->in.body, 0x04); -- cgit From 88d2e0522737fb8856fb0f52c2af8a2f56130f19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 15:05:44 +1100 Subject: updated SMB2 create operation to match WSPP. Adding some defined for various new create options (This used to be commit d037dc23ced3df6bce98cbf4810fb5f1247336bd) --- source4/libcli/smb2/create.c | 52 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index ba11c22e87..cca83a040c 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -24,34 +24,33 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */ -#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */ - /* add a blob to a smb2_create attribute blob */ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - uint32_t tag, + const char *tag, DATA_BLOB add, bool last) { uint32_t ofs = blob->length; - uint8_t pad = smb2_padding_size(add.length, 8); - if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad)) + size_t tag_length = strlen(tag); + uint8_t pad = smb2_padding_size(add.length+tag_length, 8); + if (!data_blob_realloc(mem_ctx, blob, + blob->length + 0x14 + tag_length + add.length + pad)) return NT_STATUS_NO_MEMORY; if (last) { SIVAL(blob->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad); + SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad); } SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ - SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ - SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */ + SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */ + SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ SIVAL(blob->data, ofs+0x0C, add.length); - SIVAL(blob->data, ofs+0x10, tag); - SIVAL(blob->data, ofs+0x14, 0); /* pad? */ - memcpy(blob->data+ofs+0x18, add.data, add.length); - memset(blob->data+ofs+0x18+add.length, 0, pad); + memcpy(blob->data+ofs+0x10, tag, tag_length); + SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */ + memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length); + memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad); return NT_STATUS_OK; } @@ -68,16 +67,15 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in.oplock_flags); - SIVAL(req->out.body, 0x04, io->in.impersonation); - SIVAL(req->out.body, 0x08, io->in.unknown3[0]); - SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); - SIVAL(req->out.body, 0x10, io->in.unknown3[2]); - SIVAL(req->out.body, 0x14, io->in.unknown3[3]); - SIVAL(req->out.body, 0x18, io->in.access_mask); - SIVAL(req->out.body, 0x1C, io->in.file_attr); + SCVAL(req->out.body, 0x02, io->in.security_flags); + SCVAL(req->out.body, 0x03, io->in.oplock_level); + SIVAL(req->out.body, 0x04, io->in.impersonation_level); + SBVAL(req->out.body, 0x08, io->in.create_flags); + SBVAL(req->out.body, 0x10, io->in.reserved); + SIVAL(req->out.body, 0x18, io->in.desired_access); + SIVAL(req->out.body, 0x1C, io->in.file_attributes); SIVAL(req->out.body, 0x20, io->in.share_access); - SIVAL(req->out.body, 0x24, io->in.open_disposition); + SIVAL(req->out.body, 0x24, io->in.create_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname); @@ -90,7 +88,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -100,7 +98,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC, + data_blob(NULL, 0), true); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -132,7 +131,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct SMB2_CHECK_PACKET_RECV(req, 0x58, true); - io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.oplock_level = CVAL(req->in.body, 0x02); + io->out.reserved = CVAL(req->in.body, 0x03); io->out.create_action = IVAL(req->in.body, 0x04); io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); @@ -141,7 +141,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.alloc_size = BVAL(req->in.body, 0x28); io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); - io->out._pad = IVAL(req->in.body, 0x3C); + io->out.reserved2 = IVAL(req->in.body, 0x3C); smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/libcli/smb2/create.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index cca83a040c..999c10ab08 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -- cgit From 578539216fcb275e5ec013b3ed1c81e4baced80e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Apr 2008 10:03:08 +0200 Subject: libcli/smb2: make it possible to pass additional extra blobs in smb2_create() This also fixes the alignment from 8 to 4 byte bounderies. metze (This used to be commit e0a0d8e36acd735b587cd7870625af52c5dc3431) --- source4/libcli/smb2/create.c | 94 +++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 23 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 999c10ab08..6ac32a494f 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -28,30 +28,59 @@ /* add a blob to a smb2_create attribute blob */ -NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const char *tag, - DATA_BLOB add, bool last) +static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer, + const struct smb2_create_blob *blob, + bool last) { - uint32_t ofs = blob->length; - size_t tag_length = strlen(tag); - uint8_t pad = smb2_padding_size(add.length+tag_length, 8); - if (!data_blob_realloc(mem_ctx, blob, - blob->length + 0x14 + tag_length + add.length + pad)) + uint32_t ofs = buffer->length; + size_t tag_length = strlen(blob->tag); + uint8_t pad = smb2_padding_size(blob->data.length+tag_length, 4); + + if (!data_blob_realloc(mem_ctx, buffer, + buffer->length + 0x14 + tag_length + blob->data.length + pad)) return NT_STATUS_NO_MEMORY; - + if (last) { - SIVAL(blob->data, ofs+0x00, 0); + SIVAL(buffer->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad); + SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad); } - SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ - SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */ - SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ - SIVAL(blob->data, ofs+0x0C, add.length); - memcpy(blob->data+ofs+0x10, tag, tag_length); - SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */ - memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length); - memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad); + SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */ + SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */ + SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ + SIVAL(buffer->data, ofs+0x0C, blob->data.length); + memcpy(buffer->data+ofs+0x10, blob->tag, tag_length); + SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */ + memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length); + memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad); + + return NT_STATUS_OK; +} + +NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b, + const char *tag, DATA_BLOB data) +{ + struct smb2_create_blob *array; + + array = talloc_realloc(mem_ctx, b->blobs, + struct smb2_create_blob, + b->num_blobs + 1); + NT_STATUS_HAVE_NO_MEMORY(array); + b->blobs = array; + + b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag); + NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag); + + if (data.data) { + b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs, + data.data, + data.length); + NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data); + } else { + b->blobs[b->num_blobs].data = data_blob(NULL, 0); + } + + b->num_blobs += 1; return NT_STATUS_OK; } @@ -64,6 +93,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create struct smb2_request *req; NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); + uint32_t i; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -89,7 +119,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false); + status = smb2_create_blob_add(req, &io->in.blobs, + SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -99,13 +130,30 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC, - data_blob(NULL, 0), true); - + status = smb2_create_blob_add(req, &io->in.blobs, + SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } + + for (i=0; i < io->in.blobs.num_blobs; i++) { + bool last = false; + const struct smb2_create_blob *c; + + if ((i + 1) == io->in.blobs.num_blobs) { + last = true; + } + + c = &io->in.blobs.blobs[i]; + status = smb2_create_blob_push_one(req, &blob, + c, last); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + status = smb2_push_o32s32_blob(&req->out, 0x30, blob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From d5def936fe67c1cde2c4ed00834c4ce325dfcb55 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 22:46:29 +1000 Subject: pass in the required alignment to the EA construction routines (This used to be commit af31030e0b78b6b220740529901ec8d2d9f5a3fe) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 6ac32a494f..9d28bbf8c4 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -117,8 +117,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, - ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); - ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 8)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 8); status = smb2_create_blob_add(req, &io->in.blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { -- cgit From ec7a6ee8ab25f4550a68b286d9eba32b955a73a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 May 2008 00:07:12 +1000 Subject: fix make test for EAs again - go back to 4 byte alignment until I work out the rules that Vista wants more exactly - add the zero sized EA handling for SMB2 more generically (This used to be commit 326b69bc8064cbea357864cecd6bd27b50c57184) --- source4/libcli/smb2/create.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 9d28bbf8c4..b1b8b0ccfa 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -117,8 +117,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, - ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 8)); - ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 8); + ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); + ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4); status = smb2_create_blob_add(req, &io->in.blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { -- cgit From 2814868e93116bb967a7438d95b6fd407246acc1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 12:42:19 +1000 Subject: don't alter the in blobs in a SMB2 create, otherwise two calls in a row will fail (This used to be commit 3b811a52fe9a8356337ad149d01a3498c09d900a) --- source4/libcli/smb2/create.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index b1b8b0ccfa..1901cb4977 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -94,6 +94,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS status; DATA_BLOB blob = data_blob(NULL, 0); uint32_t i; + struct smb2_create_blobs blobs = io->in.blobs; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -119,7 +120,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4); - status = smb2_create_blob_add(req, &io->in.blobs, + status = smb2_create_blob_add(req, &blobs, SMB2_CREATE_TAG_EXTA, b); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -130,22 +131,22 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &io->in.blobs, + status = smb2_create_blob_add(req, &blobs, SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } - for (i=0; i < io->in.blobs.num_blobs; i++) { + for (i=0; i < blobs.num_blobs; i++) { bool last = false; const struct smb2_create_blob *c; - if ((i + 1) == io->in.blobs.num_blobs) { + if ((i + 1) == blobs.num_blobs) { last = true; } - c = &io->in.blobs.blobs[i]; + c = &blobs.blobs[i]; status = smb2_create_blob_push_one(req, &blob, c, last); if (!NT_STATUS_IS_OK(status)) { -- cgit From 2173169e191754887acddb669a937b872b7ce017 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 15:27:50 +1000 Subject: added support for all of the known SMB2 create tags in our client library (This used to be commit 597b38e97b01d2137e6ac96ca07cd56fadb2c09e) --- source4/libcli/smb2/create.c | 186 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 7 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 1901cb4977..4a97f8aafb 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -24,6 +24,74 @@ #include "libcli/raw/raw_proto.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "librpc/gen_ndr/ndr_security.h" + + +/* + parse a set of SMB2 create blobs +*/ +NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, + struct smb2_create_blobs *blobs) +{ + const uint8_t *data = buffer.data; + uint32_t remaining = buffer.length; + + while (remaining > 0) { + uint32_t next; + uint32_t name_offset, name_length; + uint32_t reserved, data_offset; + uint32_t data_length; + char *tag; + DATA_BLOB b; + NTSTATUS status; + + if (remaining < 16) { + return NT_STATUS_INVALID_PARAMETER; + } + next = IVAL(data, 0); + name_offset = SVAL(data, 4); + name_length = SVAL(data, 6); + reserved = SVAL(data, 8); + data_offset = SVAL(data, 10); + data_length = IVAL(data, 12); + + if ((next & 0x7) != 0 || + next > remaining || + name_offset < 16 || + name_offset > remaining || + name_offset + name_length > remaining || + data_offset < name_offset + name_length || + data_offset > remaining || + data_offset + (uint64_t)data_length > remaining) { + return NT_STATUS_INVALID_PARAMETER; + } + + tag = talloc_strndup(mem_ctx, (const char *)data + name_offset, name_length); + if (tag == NULL) { + return NT_STATUS_NO_MEMORY; + } + + b = data_blob_const(data+data_offset, data_length); + status = smb2_create_blob_add(mem_ctx, blobs, tag, b); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_free(tag); + + if (next == 0) break; + + remaining -= next; + data += next; + + if (remaining < 16) { + return NT_STATUS_INVALID_PARAMETER; + } + } + + return NT_STATUS_OK; +} + /* add a blob to a smb2_create attribute blob @@ -116,6 +184,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } + /* now add all the optional blobs */ if (io->in.eas.num_eas != 0) { DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4)); @@ -131,13 +200,87 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blobs, - SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; + if (io->in.query_maximal_access) { + /* TODO: MS-SMB2 2.2.13.2.5 says this can contain a timestamp? What to do + with that if it doesn't match? */ + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.alloc_size != 0) { + uint8_t data[8]; + SBVAL(data, 0, io->in.alloc_size); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_ALSI, data_blob_const(data, 8)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.durable_open) { + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_DHNQ, data_blob_talloc_zero(req, 16)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.durable_handle) { + uint8_t data[16]; + smb2_push_handle(data, io->in.durable_handle); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.timewarp) { + uint8_t data[8]; + SBVAL(data, 0, io->in.timewarp); + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_TWRP, data_blob_const(data, 8)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } } + if (io->in.sec_desc) { + enum ndr_err_code ndr_err; + DATA_BLOB sd_blob; + ndr_err = ndr_push_struct_blob(&sd_blob, req, NULL, + io->in.sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(req); + return NULL; + } + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_SECD, sd_blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + if (io->in.query_on_disk_id) { + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_QFID, data_blob(NULL, 0)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + /* and any custom blobs */ for (i=0; i < blobs.num_blobs; i++) { bool last = false; const struct smb2_create_blob *c; @@ -173,6 +316,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io) { NTSTATUS status; + DATA_BLOB blob; + int i; if (!smb2_request_receive(req) || !smb2_request_is_ok(req)) { @@ -180,7 +325,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct } SMB2_CHECK_PACKET_RECV(req, 0x58, true); - + ZERO_STRUCT(io->out); io->out.oplock_level = CVAL(req->in.body, 0x02); io->out.reserved = CVAL(req->in.body, 0x03); io->out.create_action = IVAL(req->in.body, 0x04); @@ -193,12 +338,39 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.file_attr = IVAL(req->in.body, 0x38); io->out.reserved2 = IVAL(req->in.body, 0x3C); smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); - status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); + status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &blob); if (!NT_STATUS_IS_OK(status)) { smb2_request_destroy(req); return status; } + status = smb2_create_blob_parse(mem_ctx, blob, &io->out.blobs); + if (!NT_STATUS_IS_OK(status)) { + smb2_request_destroy(req); + return status; + } + + /* pull out the parsed blobs */ + for (i=0;iout.blobs.num_blobs;i++) { + if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) { + /* why 8 bytes not 4?? */ + if (io->out.blobs.blobs[i].data.length != 8) { + smb2_request_destroy(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0); + } + if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) { + if (io->out.blobs.blobs[i].data.length != 32) { + smb2_request_destroy(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32); + } + } + + data_blob_free(&blob); + return smb2_request_destroy(req); } -- cgit From 773f5cce80322d8674ac0b99b0e0ea641991af1b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 16:27:38 +1000 Subject: expose a function for pushing all SMB2 create blobs (This used to be commit f5985a0490e4105a9b0208f6b7b19e635db324f9) --- source4/libcli/smb2/create.c | 53 ++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 4a97f8aafb..b976b528f1 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -125,6 +125,35 @@ static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer return NT_STATUS_OK; } + +/* + create a buffer of a set of create blobs +*/ +NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer, + const struct smb2_create_blobs blobs) +{ + int i; + NTSTATUS status; + + *buffer = data_blob(NULL, 0); + for (i=0; i < blobs.num_blobs; i++) { + bool last = false; + const struct smb2_create_blob *c; + + if ((i + 1) == blobs.num_blobs) { + last = true; + } + + c = &blobs.blobs[i]; + status = smb2_create_blob_push_one(mem_ctx, buffer, c, last); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + return NT_STATUS_OK; +} + + NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b, const char *tag, DATA_BLOB data) { @@ -160,8 +189,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create { struct smb2_request *req; NTSTATUS status; - DATA_BLOB blob = data_blob(NULL, 0); - uint32_t i; + DATA_BLOB blob; struct smb2_create_blobs blobs = io->in.blobs; req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); @@ -281,21 +309,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create } /* and any custom blobs */ - for (i=0; i < blobs.num_blobs; i++) { - bool last = false; - const struct smb2_create_blob *c; - - if ((i + 1) == blobs.num_blobs) { - last = true; - } - - c = &blobs.blobs[i]; - status = smb2_create_blob_push_one(req, &blob, - c, last); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(req); - return NULL; - } + status = smb2_create_blob_push(req, &blob, blobs); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; } status = smb2_push_o32s32_blob(&req->out, 0x30, blob); @@ -304,6 +321,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create return NULL; } + data_blob_free(&blob); + smb2_transport_send(req); return req; -- cgit From 0be9746e1fc47aff93c1d77d256f4fb7942529d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 16:58:34 +1000 Subject: ensure we don't change the incoming blobs in a SMB2 create (This used to be commit a6cc89fffe8c149b540f2125cea57f31331d5460) --- source4/libcli/smb2/create.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index b976b528f1..bff0a1587d 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -59,6 +59,7 @@ NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, next > remaining || name_offset < 16 || name_offset > remaining || + name_length != 4 || /* windows enforces this */ name_offset + name_length > remaining || data_offset < name_offset + name_length || data_offset > remaining || @@ -190,7 +191,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create struct smb2_request *req; NTSTATUS status; DATA_BLOB blob; - struct smb2_create_blobs blobs = io->in.blobs; + struct smb2_create_blobs blobs; + int i; + + ZERO_STRUCT(blobs); req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; @@ -309,6 +313,17 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create } /* and any custom blobs */ + for (i=0;iin.blobs.num_blobs;i++) { + status = smb2_create_blob_add(req, &blobs, + io->in.blobs.blobs[i].tag, + io->in.blobs.blobs[i].data); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + + status = smb2_create_blob_push(req, &blob, blobs); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); -- cgit From f4077a05cbdb0a7bb0cc9baf120d26e026f86b9b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 21:48:26 +1000 Subject: updated comment based on MS-SMB2 docs (This used to be commit 5754cc13514a0f5fe4c47ce53521c256c9d96487) --- source4/libcli/smb2/create.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index bff0a1587d..342a519376 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -387,7 +387,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct /* pull out the parsed blobs */ for (i=0;iout.blobs.num_blobs;i++) { if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) { - /* why 8 bytes not 4?? */ + /* TODO: this also contains a status field in + first 4 bytes */ if (io->out.blobs.blobs[i].data.length != 8) { smb2_request_destroy(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; -- cgit From f6b678b57e14e23479530b64652efe8c51bb4929 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 18:23:00 +1000 Subject: fixed offset for maximal access response (This used to be commit ddd0bb32510d615c7b943fb4ce4c9c275b98ab89) --- source4/libcli/smb2/create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/create.c') diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 342a519376..8a40e56a00 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -393,7 +393,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_request_destroy(req); return NT_STATUS_INVALID_NETWORK_RESPONSE; } - io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0); + io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4); } if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) { if (io->out.blobs.blobs[i].data.length != 32) { -- cgit