Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into nosmbpython
authorJelmer Vernooij <jelmer@samba.org>
Wed, 21 May 2008 13:45:04 +0000 (15:45 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Wed, 21 May 2008 13:45:04 +0000 (15:45 +0200)
(This used to be commit f29e9009310e4a6d575651dd9ba41ffc90bfb386)

source4/libcli/raw/interfaces.h
source4/libcli/smb2/flush.c
source4/libcli/smb2/lock.c
source4/ntvfs/ntvfs_generic.c
source4/smb_server/smb2/fileio.c
source4/smb_server/smb2/smb2_server.h
source4/torture/gentest_smb2.c
source4/torture/smb2/lock.c

index 871bab01db0d77381a540c396f71addc5d76b2cc..3370021d48e4538f70d9462a2f162f3b5c6baac2 100644 (file)
@@ -1866,13 +1866,12 @@ enum smb_lock_level {
        RAW_LOCK_SMB2_BREAK
 };
 
-/* the generic interface is defined to be equal to the lockingX interface */
-#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX
+#define        RAW_LOCK_GENERIC RAW_LOCK_LOCKX
 
 /* union for lock() backend call 
 */
 union smb_lock {
-       /* SMBlockingX (and generic) interface */
+       /* SMBlockingX and generic interface */
        struct {
                enum smb_lock_level level;
                struct {
@@ -1887,7 +1886,7 @@ union smb_lock {
                                uint64_t count;
                        } *locks; /* unlocks are first in the arrray */
                } in;
-       } lockx, generic;
+       } generic, lockx;
 
        /* SMBlock and SMBunlock interface */
        struct {
@@ -1907,23 +1906,26 @@ union smb_lock {
 
                        /* static body buffer 48 (0x30) bytes */
                        /* uint16_t buffer_code;  0x30 */
-                       uint16_t unknown1; /* must be 0x0001 */
-                       uint32_t unknown2;
+                       uint16_t lock_count;
+                       uint32_t reserved;
                        /* struct smb2_handle handle; */
-                       uint64_t offset;
-                       uint64_t count;
-                       uint32_t unknown5;
+                       struct smb2_lock_element {
+                               uint64_t offset;
+                               uint64_t length;
+/* these flags are the same as the SMB2 lock flags */
 #define SMB2_LOCK_FLAG_NONE            0x00000000
 #define SMB2_LOCK_FLAG_SHARED          0x00000001
-#define SMB2_LOCK_FLAG_EXCLUSIV                0x00000002
+#define SMB2_LOCK_FLAG_EXCLUSIVE       0x00000002
 #define SMB2_LOCK_FLAG_UNLOCK          0x00000004
-#define SMB2_LOCK_FLAG_NO_PENDING      0x00000010
-                       uint32_t flags;
+#define SMB2_LOCK_FLAG_FAIL_IMMEDIATELY        0x00000010
+                               uint32_t flags;
+                               uint32_t reserved;
+                       } *locks;
                } in;
                struct {
                        /* static body buffer 4 (0x04) bytes */
                        /* uint16_t buffer_code;  0x04 */
-                       uint16_t unknown1;
+                       uint16_t reserved;
                } out;
        } smb2;
 
@@ -2154,8 +2156,12 @@ union smb_flush {
                enum smb_flush_level level;
                struct {
                        union smb_handle file;
-                       uint32_t unknown;
+                       uint16_t reserved1;
+                       uint32_t reserved2;
                } in;
+               struct {
+                       uint16_t reserved;
+               } out;
        } smb2;
 };
 
index 116068ed6ebe96747475ed3b8cce8094f2fbc512..577d1ba1ba78845af00efd52ac78d132320bad4e 100644 (file)
@@ -33,8 +33,8 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush *
        req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, false, 0);
        if (req == NULL) return NULL;
 
-       SSVAL(req->out.body, 0x02, 0); /* pad? */
-       SIVAL(req->out.body, 0x04, io->in.unknown);
+       SSVAL(req->out.body, 0x02, io->in.reserved1);
+       SIVAL(req->out.body, 0x04, io->in.reserved2);
        smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
 
        smb2_transport_send(req);
@@ -55,6 +55,8 @@ NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io)
 
        SMB2_CHECK_PACKET_RECV(req, 0x04, false);
 
+       io->out.reserved = SVAL(req->in.body, 0x02);
+
        return smb2_request_destroy(req);
 }
 
index d71a337d5621502d7b4046238a68f33848a3c15d..62c6e5dba7479d5e160127a975b2ba5815fee7ed 100644 (file)
 struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io)
 {
        struct smb2_request *req;
+       int i;
 
-       req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, false, 0);
+       req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 
+                                    24 + io->in.lock_count*24, false, 0);
        if (req == NULL) return NULL;
 
-       SSVAL(req->out.body, 0x02, io->in.unknown1);
-       SIVAL(req->out.body, 0x04, io->in.unknown2);
+       /* this is quite bizarre - the spec says we must lie about the length! */
+       SSVAL(req->out.body, 0, 0x30);
+
+       SSVAL(req->out.body, 0x02, io->in.lock_count);
+       SIVAL(req->out.body, 0x04, io->in.reserved);
        smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
-       SBVAL(req->out.body, 0x18, io->in.offset);
-       SBVAL(req->out.body, 0x20, io->in.count);
-       SIVAL(req->out.body, 0x24, io->in.unknown5);
-       SIVAL(req->out.body, 0x28, io->in.flags);
+
+       for (i=0;i<io->in.lock_count;i++) {
+               SBVAL(req->out.body, 0x18 + i*24, io->in.locks[i].offset);
+               SBVAL(req->out.body, 0x20 + i*24, io->in.locks[i].length);
+               SIVAL(req->out.body, 0x28 + i*24, io->in.locks[i].flags);
+               SIVAL(req->out.body, 0x2C + i*24, io->in.locks[i].reserved);
+       }
 
        smb2_transport_send(req);
 
@@ -59,7 +67,7 @@ NTSTATUS smb2_lock_recv(struct smb2_request *req, struct smb2_lock *io)
 
        SMB2_CHECK_PACKET_RECV(req, 0x04, false);
 
-       io->out.unknown1 = SVAL(req->in.body, 0x02);
+       io->out.reserved = SVAL(req->in.body, 0x02);
 
        return smb2_request_destroy(req);
 }
index 3653ad82c1400db0ae6bca350a589e6d000975ab..a706e621c9083f1cd8be07f125810424f39a2026 100644 (file)
@@ -1011,38 +1011,56 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
                locks->count = lck->unlock.in.count;
                break;
 
-       case RAW_LOCK_SMB2:
-               if (lck->smb2.in.unknown1 != 1) {
+       case RAW_LOCK_SMB2: {
+               /* this is only approximate! We need to change the
+                  generic structure to fix this properly */
+               int i;
+               if (lck->smb2.in.lock_count < 1) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
                lck2->generic.level = RAW_LOCK_GENERIC;
                lck2->generic.in.file.ntvfs= lck->smb2.in.file.ntvfs;
-               if (lck->smb2.in.flags & SMB2_LOCK_FLAG_EXCLUSIV) {
-                       lck2->generic.in.mode = 0;
-               } else {
-                       lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
+               lck2->generic.in.timeout = UINT32_MAX;
+               lck2->generic.in.mode = 0;
+               lck2->generic.in.lock_cnt = 0;
+               lck2->generic.in.ulock_cnt = 0;
+               lck2->generic.in.locks = talloc_zero_array(lck2, struct smb_lock_entry, 
+                                                          lck->smb2.in.lock_count);
+               if (lck2->generic.in.locks == NULL) {
+                       return NT_STATUS_NO_MEMORY;
                }
-               if (lck->smb2.in.flags & SMB2_LOCK_FLAG_NO_PENDING) {
-                       lck2->generic.in.timeout = 0;
-               } else {
-                       lck2->generic.in.timeout = UINT32_MAX;
+               for (i=0;i<lck->smb2.in.lock_count;i++) {
+                       if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
+                               int j = lck2->generic.in.ulock_cnt;
+                               lck2->generic.in.ulock_cnt++;
+                               lck2->generic.in.locks[j].pid = 0;
+                               lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
+                               lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
+                               lck2->generic.in.locks[j].pid = 0;
+                       }
                }
-               if (lck->smb2.in.flags & SMB2_LOCK_FLAG_UNLOCK) {
-                       lck2->generic.in.ulock_cnt = 1;
-                       lck2->generic.in.lock_cnt = 0;
-               } else {
-                       lck2->generic.in.ulock_cnt = 0;
-                       lck2->generic.in.lock_cnt = 1;
+               for (i=0;i<lck->smb2.in.lock_count;i++) {
+                       if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
+                               int j = lck2->generic.in.ulock_cnt + 
+                                       lck2->generic.in.lock_cnt;
+                               lck2->generic.in.lock_cnt++;
+                               lck2->generic.in.locks[j].pid = 0;
+                               lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
+                               lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
+                               lck2->generic.in.locks[j].pid = 0;
+                               if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
+                                       lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
+                               }
+                               if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
+                                       lck2->generic.in.timeout = 0;
+                               }
+                       }
                }
-               lck2->generic.in.locks = locks;
-               locks->pid = 0;
-               locks->offset = lck->smb2.in.offset;
-               locks->count = lck->smb2.in.count;
-
                /* initialize output value */
-               lck->smb2.out.unknown1 = 0;
+               lck->smb2.out.reserved = 0;
                break;
+       }
 
        case RAW_LOCK_SMB2_BREAK:
                lck2->generic.level             = RAW_LOCK_GENERIC;
index b6b35d3d892bcf2e8735c31980ad00a64c1e55f2..5ab217bbfd687b036aa5c994f26099c605c391ac 100644 (file)
@@ -135,7 +135,7 @@ static void smb2srv_flush_send(struct ntvfs_request *ntvfs)
        SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_flush);
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x04, false, 0));
 
-       SSVAL(req->out.body,    0x02,   0);
+       SSVAL(req->out.body,    0x02,   io->smb2.out.reserved);
 
        smb2srv_send_reply(req);
 }
@@ -143,15 +143,14 @@ static void smb2srv_flush_send(struct ntvfs_request *ntvfs)
 void smb2srv_flush_recv(struct smb2srv_request *req)
 {
        union smb_flush *io;
-       uint16_t _pad;
 
        SMB2SRV_CHECK_BODY_SIZE(req, 0x18, false);
        SMB2SRV_TALLOC_IO_PTR(io, union smb_flush);
        SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_flush_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->smb2.level                  = RAW_FLUSH_SMB2;
-       _pad                            = SVAL(req->in.body, 0x02);
-       io->smb2.in.unknown             = IVAL(req->in.body, 0x04);
+       io->smb2.in.reserved1           = SVAL(req->in.body, 0x02);
+       io->smb2.in.reserved2           = IVAL(req->in.body, 0x04);
        io->smb2.in.file.ntvfs          = smb2srv_pull_handle(req, req->in.body, 0x08);
 
        SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
@@ -247,7 +246,7 @@ static void smb2srv_lock_send(struct ntvfs_request *ntvfs)
        SMB2SRV_CHECK_ASYNC_STATUS_ERR(io, union smb_lock);
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x04, false, 0));
 
-       SSVAL(req->out.body,    0x02,   io->smb2.out.unknown1);
+       SSVAL(req->out.body,    0x02,   io->smb2.out.reserved);
 
        smb2srv_send_reply(req);
 }
@@ -255,20 +254,34 @@ static void smb2srv_lock_send(struct ntvfs_request *ntvfs)
 void smb2srv_lock_recv(struct smb2srv_request *req)
 {
        union smb_lock *io;
+       int i;
 
        SMB2SRV_CHECK_BODY_SIZE(req, 0x30, false);
        SMB2SRV_TALLOC_IO_PTR(io, union smb_lock);
        SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_lock_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->smb2.level                  = RAW_LOCK_SMB2;
-
-       io->smb2.in.unknown1            = SVAL(req->in.body, 0x02);
-       io->smb2.in.unknown2            = IVAL(req->in.body, 0x04);
+       io->smb2.in.lock_count          = SVAL(req->in.body, 0x02);
+       io->smb2.in.reserved            = IVAL(req->in.body, 0x04);
        io->smb2.in.file.ntvfs          = smb2srv_pull_handle(req, req->in.body, 0x08);
-       io->smb2.in.offset              = BVAL(req->in.body, 0x18);
-       io->smb2.in.count               = BVAL(req->in.body, 0x20);
-       io->smb2.in.unknown5            = IVAL(req->in.body, 0x24);
-       io->smb2.in.flags               = IVAL(req->in.body, 0x28);
+       if (req->in.body_size < 24 + 24*(uint64_t)io->smb2.in.lock_count) {
+               DEBUG(0,("%s: lock buffer too small\n", __location__));
+               smb2srv_send_error(req,  NT_STATUS_FOOBAR);
+               return;
+       }
+       io->smb2.in.locks = talloc_array(io, struct smb2_lock_element, 
+                                        io->smb2.in.lock_count);
+       if (io->smb2.in.locks == NULL) {
+               smb2srv_send_error(req, NT_STATUS_NO_MEMORY);
+               return;
+       }
+
+       for (i=0;i<io->smb2.in.lock_count;i++) {
+               io->smb2.in.locks[i].offset     = BVAL(req->in.body, 24 + i*24);
+               io->smb2.in.locks[i].length     = BVAL(req->in.body, 32 + i*24);
+               io->smb2.in.locks[i].flags      = IVAL(req->in.body, 40 + i*24);
+               io->smb2.in.locks[i].reserved   = IVAL(req->in.body, 44 + i*24);
+       }
 
        SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
        SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, io));
index 2f347d387618f5e813bb426eaf7a7bc053d99ce7..fc40a92efcfb6f0c25facfb4cb77f820e4649f44 100644 (file)
@@ -70,7 +70,7 @@ struct smbsrv_request;
 
 #include "smb_server/smb2/smb2_proto.h"
 
-/* useful way of catching wct errors with file and line number */
+/* useful way of catching field size errors with file and line number */
 #define SMB2SRV_CHECK_BODY_SIZE(req, size, dynamic) do { \
        size_t is_size = req->in.body_size; \
        uint16_t field_size = SVAL(req->in.body, 0); \
index 9c4be90b3cf07d283f505447d1a42eeedb7ad818..fc6dbcbb9ae0d7339bc6d43d1db6900f1f285b8f 100644 (file)
@@ -349,8 +349,8 @@ static uint16_t gen_fnum(int instance)
 */
 static uint16_t gen_fnum_close(int instance)
 {
-       if (num_open_handles < 3) {
-               if (gen_chance(80)) return BAD_HANDLE;
+       if (num_open_handles < 5) {
+               if (gen_chance(90)) return BAD_HANDLE;
        }
 
        return gen_fnum(instance);
@@ -530,13 +530,16 @@ static uint16_t gen_rename_flags(void)
 
 
 /*
-  return a lockingx lock mode
+  return a set of lock flags
 */
-static uint16_t gen_lock_mode(void)
+static uint16_t gen_lock_flags(void)
 {
        if (gen_chance(5))  return gen_bits_mask(0xFFFF);
        if (gen_chance(20)) return gen_bits_mask(0x1F);
-       return gen_bits_mask(LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES);
+       if (gen_chance(50)) return SMB2_LOCK_FLAG_UNLOCK;
+       return gen_bits_mask(SMB2_LOCK_FLAG_SHARED | 
+                            SMB2_LOCK_FLAG_EXCLUSIVE | 
+                            SMB2_LOCK_FLAG_FAIL_IMMEDIATELY);
 }
 
 /*
@@ -570,8 +573,8 @@ static uint32_t gen_ntcreatex_flags(void)
 */
 static uint32_t gen_access_mask(void)
 {
-       if (gen_chance(50)) return SEC_FLAG_MAXIMUM_ALLOWED;
-       if (gen_chance(20)) return SEC_FILE_ALL;
+       if (gen_chance(70)) return SEC_FLAG_MAXIMUM_ALLOWED;
+       if (gen_chance(70)) return SEC_FILE_ALL;
        return gen_bits_mask(0xFFFFFFFF);
 }
 
@@ -590,6 +593,7 @@ static uint32_t gen_create_options(void)
 */
 static uint32_t gen_open_disp(void)
 {
+       if (gen_chance(50)) return NTCREATEX_DISP_OPEN_IF;
        if (gen_chance(10)) return gen_bits_mask(0xFFFFFFFF);
        return gen_int_range(0, 5);
 }
@@ -999,20 +1003,20 @@ again:
 /*
   generate ntcreatex operations
 */
-static bool handler_ntcreatex(int instance)
+static bool handler_create(int instance)
 {
        struct smb2_create parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
        ZERO_STRUCT(parm[0]);
-       parm[0].in.security_flags             = gen_bits_levels(3, 70, 0x0, 70, 0x3, 100, 0xFF);
-       parm[0].in.oplock_level               = gen_bits_levels(3, 70, 0x0, 70, 0x9, 100, 0xFF);
-       parm[0].in.impersonation_level        = gen_bits_levels(3, 70, 0x0, 70, 0x3, 100, 0xFFFFFFFF);
-       parm[0].in.create_flags               = gen_bits_levels(2, 80, 0x0, 100, 0xFFFFFFFF);
+       parm[0].in.security_flags             = gen_bits_levels(3, 90, 0x0, 70, 0x3, 100, 0xFF);
+       parm[0].in.oplock_level               = gen_bits_levels(3, 90, 0x0, 70, 0x9, 100, 0xFF);
+       parm[0].in.impersonation_level        = gen_bits_levels(3, 90, 0x0, 70, 0x3, 100, 0xFFFFFFFF);
+       parm[0].in.create_flags               = gen_bits_levels(2, 90, 0x0, 100, 0xFFFFFFFF);
        if (gen_chance(2)) {
                parm[0].in.create_flags       |= gen_bits_mask(0xFFFFFFFF);
        }
-       parm[0].in.reserved                   = gen_bits_levels(2, 80, 0x0, 100, 0xFFFFFFFF);
+       parm[0].in.reserved                   = gen_bits_levels(2, 95, 0x0, 100, 0xFFFFFFFF);
        if (gen_chance(2)) {
                parm[0].in.reserved           |= gen_bits_mask(0xFFFFFFFF);
        }
@@ -1135,46 +1139,63 @@ static bool handler_write(int instance)
        return true;
 }
 
-#if 0
 /*
   generate lockingx operations
 */
 static bool handler_lock(int instance)
 {
-       union smb_lock parm[NSERVERS];
+       struct smb2_lock parm[NSERVERS];
        NTSTATUS status[NSERVERS];
-       int n, nlocks;
+       int n;
 
-       parm[0].lockx.level = RAW_LOCK_LOCKX;
-       parm[0].lockx.in.file.fnum = gen_fnum(instance);
-       parm[0].lockx.in.mode = gen_lock_mode();
-       parm[0].lockx.in.timeout = gen_timeout();
-       do {
-               /* make sure we don't accidentially generate an oplock
-                  break ack - otherwise the server can just block forever */
-               parm[0].lockx.in.ulock_cnt = gen_lock_count();
-               parm[0].lockx.in.lock_cnt = gen_lock_count();
-               nlocks = parm[0].lockx.in.ulock_cnt + parm[0].lockx.in.lock_cnt;
-       } while (nlocks == 0);
-
-       if (nlocks > 0) {
-               parm[0].lockx.in.locks = talloc_array(current_op.mem_ctx,
-                                                       struct smb_lock_entry,
-                                                       nlocks);
-               for (n=0;n<nlocks;n++) {
-                       parm[0].lockx.in.locks[n].pid = gen_pid();
-                       parm[0].lockx.in.locks[n].offset = gen_offset();
-                       parm[0].lockx.in.locks[n].count = gen_io_count();
-               }
+       parm[0].level = RAW_LOCK_LOCKX;
+       parm[0].in.file.handle.data[0] = gen_fnum(instance);
+       parm[0].in.lock_count = gen_lock_count();
+       parm[0].in.reserved = gen_bits_mask2(0, 0xFFFFFFFF);
+       
+       parm[0].in.locks = talloc_array(current_op.mem_ctx,
+                                       struct smb2_lock_element,
+                                       parm[0].in.lock_count);
+       for (n=0;n<parm[0].in.lock_count;n++) {
+               parm[0].in.locks[n].offset = gen_offset();
+               parm[0].in.locks[n].length = gen_io_count();
+               /* don't yet cope with async replies */
+               parm[0].in.locks[n].flags  = gen_lock_flags() | 
+                       SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
+               parm[0].in.locks[n].reserved = gen_bits_mask2(0x0, 0xFFFFFFFF);
        }
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(lockx.in.file.fnum);
-       GEN_CALL(smb_raw_lock(tree, &parm[i]));
+       GEN_SET_FNUM(in.file.handle);
+       GEN_CALL(smb2_lock(tree, &parm[i]));
+
+       return true;
+}
+
+/*
+  generate flush operations
+*/
+static bool handler_flush(int instance)
+{
+       struct smb2_flush parm[NSERVERS];
+       NTSTATUS status[NSERVERS];
+
+       ZERO_STRUCT(parm[0]);
+       parm[0].in.file.handle.data[0] = gen_fnum(instance);
+       parm[0].in.reserved1  = gen_bits_mask2(0x0, 0xFFFF);
+       parm[0].in.reserved2  = gen_bits_mask2(0x0, 0xFFFFFFFF);
+
+       GEN_COPY_PARM;
+       GEN_SET_FNUM(in.file.handle);
+       GEN_CALL(smb2_flush(tree, &parm[i]));
+
+       CHECK_EQUAL(out.reserved);
 
        return true;
 }
 
+#if 0
+
 /*
   generate a fileinfo query structure
 */
@@ -1579,10 +1600,12 @@ static struct {
        bool (*handler)(int instance);
        int count, success_count;
 } gen_ops[] = {
-       {"NTCREATEX",  handler_ntcreatex},
+       {"CREATE",     handler_create},
        {"CLOSE",      handler_close},
        {"READ",       handler_read},
        {"WRITE",      handler_write},
+       {"LOCK",       handler_lock},
+       {"FLUSH",      handler_flush},
 };
 
 
index 3cf2e93ee04bb864deda761fd8a5d97810fa6f2a..e81647b497630e7103321569f0a04d2563259ebe 100644 (file)
@@ -51,6 +51,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        struct smb2_handle h;
        uint8_t buf[200];
        struct smb2_lock lck;
+       struct smb2_lock_element el[1];
 
        ZERO_STRUCT(buf);
 
@@ -60,117 +61,119 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       lck.in.unknown1         = 0x0000;
-       lck.in.unknown2         = 0x00000000;
+       lck.in.locks            = el;
+
+       lck.in.lock_count       = 0x0000;
+       lck.in.reserved         = 0x00000000;
        lck.in.file.handle      = h;
-       lck.in.offset           = 0x0000000000000000;
-       lck.in.count            = 0x0000000000000000;
-       lck.in.unknown5         = 0x0000000000000000;
-       lck.in.flags            = 0x00000000;
+       el[0].offset            = 0x0000000000000000;
+       el[0].length            = 0x0000000000000000;
+       el[0].reserved          = 0x0000000000000000;
+       el[0].flags             = 0x00000000;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x00000000;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x00000000;
        lck.in.file.handle      = h;
-       lck.in.offset           = 0;
-       lck.in.count            = 0;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = SMB2_LOCK_FLAG_NONE;
+       el[0].offset            = 0;
+       el[0].length            = 0;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = SMB2_LOCK_FLAG_NONE;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        lck.in.file.handle.data[0] +=1;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
        lck.in.file.handle.data[0] -=1;
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0xFFFFFFFF;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0xFFFFFFFF;
        lck.in.file.handle      = h;
-       lck.in.offset           = UINT64_MAX;
-       lck.in.count            = UINT64_MAX;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = SMB2_LOCK_FLAG_EXCLUSIV|SMB2_LOCK_FLAG_NO_PENDING;
+       el[0].offset            = UINT64_MAX;
+       el[0].length            = UINT64_MAX;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x12345678;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x12345678;
        lck.in.file.handle      = h;
-       lck.in.offset           = UINT32_MAX;
-       lck.in.count            = UINT32_MAX;
-       lck.in.unknown5         = 0x87654321;
-       lck.in.flags            = SMB2_LOCK_FLAG_EXCLUSIV|SMB2_LOCK_FLAG_NO_PENDING;
+       el[0].offset            = UINT32_MAX;
+       el[0].length            = UINT32_MAX;
+       el[0].reserved          = 0x87654321;
+       el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
-       lck.in.flags            = 0x00000000;
+       el[0].flags             = 0x00000000;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
-       lck.in.flags            = 0x00000001;
+       el[0].flags             = 0x00000001;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x87654321;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x87654321;
        lck.in.file.handle      = h;
-       lck.in.offset           = 0x00000000FFFFFFFF;
-       lck.in.count            = 0x00000000FFFFFFFF;
-       lck.in.unknown5         = 0x12345678;
-       lck.in.flags            = SMB2_LOCK_FLAG_UNLOCK;
+       el[0].offset            = 0x00000000FFFFFFFF;
+       el[0].length            = 0x00000000FFFFFFFF;
+       el[0].reserved          = 0x12345678;
+       el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x12345678;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x12345678;
        lck.in.file.handle      = h;
-       lck.in.offset           = 0x00000000FFFFFFFF;
-       lck.in.count            = 0x00000000FFFFFFFF;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = SMB2_LOCK_FLAG_UNLOCK;
+       el[0].offset            = 0x00000000FFFFFFFF;
+       el[0].length            = 0x00000000FFFFFFFF;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 
@@ -206,6 +209,9 @@ static bool test_lock_read_write(struct torture_context *torture,
        struct smb2_create cr;
        struct smb2_write wr;
        struct smb2_read rd;
+       struct smb2_lock_element el[1];
+
+       lck.in.locks            = el;
 
        ZERO_STRUCT(buf);
 
@@ -215,27 +221,27 @@ static bool test_lock_read_write(struct torture_context *torture,
        status = smb2_util_write(tree, h1, buf, 0, ARRAY_SIZE(buf));
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x00000000;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x00000000;
        lck.in.file.handle      = h1;
-       lck.in.offset           = 0;
-       lck.in.count            = ARRAY_SIZE(buf)/2;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = s->lock_flags;
+       el[0].offset            = 0;
+       el[0].length            = ARRAY_SIZE(buf)/2;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = s->lock_flags;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x00000000;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x00000000;
        lck.in.file.handle      = h1;
-       lck.in.offset           = ARRAY_SIZE(buf)/2;
-       lck.in.count            = ARRAY_SIZE(buf)/2;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = s->lock_flags;
+       el[0].offset            = ARRAY_SIZE(buf)/2;
+       el[0].length            = ARRAY_SIZE(buf)/2;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = s->lock_flags;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        ZERO_STRUCT(cr);
        cr.in.oplock_level = 0;
@@ -286,16 +292,16 @@ static bool test_lock_read_write(struct torture_context *torture,
        status = smb2_read(tree, tree, &rd);
        CHECK_STATUS(status, s->read_h2_status);
 
-       lck.in.unknown1         = 0x0001;
-       lck.in.unknown2         = 0x00000000;
+       lck.in.lock_count       = 0x0001;
+       lck.in.reserved         = 0x00000000;
        lck.in.file.handle      = h1;
-       lck.in.offset           = ARRAY_SIZE(buf)/2;
-       lck.in.count            = ARRAY_SIZE(buf)/2;
-       lck.in.unknown5         = 0x00000000;
-       lck.in.flags            = SMB2_LOCK_FLAG_UNLOCK;
+       el[0].offset            = ARRAY_SIZE(buf)/2;
+       el[0].length            = ARRAY_SIZE(buf)/2;
+       el[0].reserved          = 0x00000000;
+       el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
        status = smb2_lock(tree, &lck);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VALUE(lck.out.unknown1, 0);
+       CHECK_VALUE(lck.out.reserved, 0);
 
        ZERO_STRUCT(wr);
        wr.in.file.handle = h2;
@@ -349,7 +355,7 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t
 {
        struct test_lock_read_write_state s = {
                .fname                  = "lock_rw_exclusiv.dat",
-               .lock_flags             = SMB2_LOCK_FLAG_EXCLUSIV,
+               .lock_flags             = SMB2_LOCK_FLAG_EXCLUSIVE,
                .write_h1_status        = NT_STATUS_OK,
                .read_h1_status         = NT_STATUS_OK,
                .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,