added smb2_close(). This also demonstrates that file handles are 16
authortridge <tridge@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Fri, 11 Nov 2005 13:08:31 +0000 (13:08 +0000)
committertridge <tridge@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Fri, 11 Nov 2005 13:08:31 +0000 (13:08 +0000)
bytes, not 20 bytes (metze, you were right!)

git-svn-id: svn+ssh://svn.samba.org/data/svn/samba/branches/SAMBA_4_0@11680 0c0555d6-39d7-0310-84fc-f1cc0bd64818

source/include/structs.h
source/libcli/smb2/close.c [new file with mode: 0644]
source/libcli/smb2/config.mk
source/libcli/smb2/create.c
source/libcli/smb2/smb2_calls.h
source/torture/smb2/connect.c

index e104eac1ab1573559c2bf46cb5374191afcc7a69..059466bc59867dbdb1e180de13dbb355f8c69396 100644 (file)
@@ -342,5 +342,4 @@ struct smb2_session_setup;
 struct smb2_tree;
 struct smb2_tree_connect;
 struct smb2_create;
-
-
+struct smb2_close;
diff --git a/source/libcli/smb2/close.c b/source/libcli/smb2/close.c
new file mode 100644 (file)
index 0000000..87220a4
--- /dev/null
@@ -0,0 +1,85 @@
+/* 
+   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 close request
+*/
+struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close *io)
+{
+       struct smb2_request *req;
+
+       req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18);
+       if (req == NULL) return NULL;
+
+       SIVAL(req->out.body, 0x00, io->in.unknown1);
+       SIVAL(req->out.body, 0x04, io->in.unknown2);
+       SBVAL(req->out.body, 0x08, io->in.handle.data[0]);
+       SBVAL(req->out.body, 0x10, io->in.handle.data[1]);
+
+       smb2_transport_send(req);
+
+       return req;
+}
+
+
+/*
+  recv a close reply
+*/
+NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io)
+{
+       if (!smb2_request_receive(req) || 
+           smb2_request_is_error(req)) {
+               return smb2_request_destroy(req);
+       }
+
+       if (req->in.body_size < 0x3C) {
+               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);
+
+       return smb2_request_destroy(req);
+}
+
+/*
+  sync close request
+*/
+NTSTATUS smb2_close(struct smb2_tree *tree, struct smb2_close *io)
+{
+       struct smb2_request *req = smb2_close_send(tree, io);
+       return smb2_close_recv(req, io);
+}
index f3acd069556fcc0d8e3992532ae6709d23410285..a1807686944b816b3c9590884a35b6cb13c38b90 100644 (file)
@@ -5,5 +5,6 @@ OBJ_FILES = \
        negprot.o \
        session.o \
        tcon.o \
-       create.o
+       create.o \
+       close.o
 REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET
index dbb4d4b9742bef05c08c890c10ce90a8ddce0e58..dc602ca71c1a2298cc5e6e8881312d41e351dc2b 100644 (file)
@@ -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);
 }
index 8b68751df30223cb4736702827d746691fccd0c8..7d41a0615314a94e76da778a62d719adc698e156 100644 (file)
@@ -76,10 +76,10 @@ struct smb2_tree_connect {
 };
 
 /*
-  file handles in SMB2 are 20 bytes, like RPC handles
+  file handles in SMB2 are 16 bytes
 */
 struct smb2_handle {
-       uint8_t data[20];
+       uint64_t data[2];
 };
 
 struct smb2_create {
@@ -114,8 +114,33 @@ struct smb2_create {
                uint32_t unknown5;
                uint32_t unknown6;
                uint32_t unknown7;
+               uint32_t unknown8;
+               uint32_t unknown9;
                struct smb2_handle handle;
-               uint32_t unknown8[2];
+               uint32_t unknown10;
+       } out;
+};
+
+
+struct smb2_close {
+       struct {
+               uint32_t unknown1;
+               uint32_t unknown2;
+               struct smb2_handle handle;
+       } in;
+
+       struct {
+               uint32_t unknown1;
+               uint32_t unknown2;
+               NTTIME   create_time;
+               NTTIME   access_time;
+               NTTIME   write_time;
+               NTTIME   change_time;
+               uint32_t unknown3;
+               uint32_t unknown4;
+               uint32_t unknown5;
+               uint32_t unknown6;
+               uint32_t unknown7;
        } out;
 };
 
index 955df4c890bb90d3f60740b0ed4794fd792ede6e..ee323a8b3a0778f843311a12d2ed280283790c31 100644 (file)
@@ -203,6 +203,7 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree,
 {
        struct smb2_create io;
        NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
 
        ZERO_STRUCT(io);
        io.in.unknown1 = 0x09000039;
@@ -216,12 +217,49 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree,
                return io.out.handle;
        }
 
-       printf("Open gave handle:\n");
-       dump_data(0, io.out.handle.data, 20);
+       printf("Open gave:\n");
+       printf("create_time     = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
+       printf("access_time     = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
+       printf("write_time      = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
+       printf("change_time     = %s\n", nt_time_string(tmp_ctx, io.out.change_time));
+       printf("handle          = %016llx%016llx\n", 
+              io.out.handle.data[0], 
+              io.out.handle.data[1]);
+
+       talloc_free(tmp_ctx);
        
        return io.out.handle;
 }
 
+/*
+  send a close
+*/
+static NTSTATUS torture_smb2_close(struct smb2_tree *tree, struct smb2_handle handle)
+{
+       struct smb2_close io;
+       NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
+
+       ZERO_STRUCT(io);
+       io.in.unknown1 = 0x10018;
+       io.in.handle   = handle;
+       status = smb2_close(tree, &io);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed - %s\n", nt_errstr(status));
+               return status;
+       }
+
+       printf("Close gave:\n");
+       printf("create_time     = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
+       printf("access_time     = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
+       printf("write_time      = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
+       printf("change_time     = %s\n", nt_time_string(tmp_ctx, io.out.change_time));
+
+       talloc_free(tmp_ctx);
+       
+       return status;
+}
+
 /* 
    basic testing of SMB2 connection calls
 */
@@ -234,15 +272,15 @@ BOOL torture_smb2_connect(void)
        const char *host = lp_parm_string(-1, "torture", "host");
        const char *share = lp_parm_string(-1, "torture", "share");
        struct cli_credentials *credentials = cmdline_credentials;
-       struct smb2_handle h;
+       struct smb2_handle h1, h2;
 
        transport = torture_smb2_negprot(mem_ctx, host);
        session   = torture_smb2_session(transport, credentials);
        tree      = torture_smb2_tree(session, share);
-       h         = torture_smb2_create(tree, "test2.dat");
-       h         = torture_smb2_create(tree, "test3.dat");
-       h         = torture_smb2_create(tree, "test4.dat");
-       h         = torture_smb2_create(tree, "test5.dat");
+       h1        = torture_smb2_create(tree, "test1.dat");
+       h2        = torture_smb2_create(tree, "test2.dat");
+       torture_smb2_close(tree, h1);
+       torture_smb2_close(tree, h2);
 
        talloc_free(mem_ctx);