summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-05-21 22:12:20 +1000
committerAndrew Tridgell <tridge@samba.org>2008-05-21 22:12:20 +1000
commit4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2 (patch)
treeed2ef4b86ae4b1629d91a7605a262e64703e3859
parentaf61219f365ae94f3c797b7450d0ea0e00ad0b11 (diff)
downloadsamba-4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2.tar.gz
samba-4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2.tar.bz2
samba-4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2.zip
fixed SMB2 locking
- SMB2 locking is different in several ways from SMB locking. To fix it properly we will need a new generic mapping structure for locking, but for now do a best effort mapping - added locking to gentest_smb2 (This used to be commit ea6d9cf602302adafe0f9d5f5f90a9b26d1ead6f)
-rw-r--r--source4/libcli/raw/interfaces.h28
-rw-r--r--source4/libcli/smb2/lock.c24
-rw-r--r--source4/ntvfs/ntvfs_generic.c62
-rw-r--r--source4/smb_server/smb2/fileio.c30
-rw-r--r--source4/smb_server/smb2/smb2_server.h2
-rw-r--r--source4/torture/gentest_smb2.c57
-rw-r--r--source4/torture/smb2/lock.c148
7 files changed, 199 insertions, 152 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 871bab01db..149b91916a 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -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;
diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c
index d71a337d56..62c6e5dba7 100644
--- a/source4/libcli/smb2/lock.c
+++ b/source4/libcli/smb2/lock.c
@@ -29,17 +29,25 @@
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);
}
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index 3653ad82c1..a706e621c9 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -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;
diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c
index b6b35d3d89..0feb259038 100644
--- a/source4/smb_server/smb2/fileio.c
+++ b/source4/smb_server/smb2/fileio.c
@@ -247,7 +247,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 +255,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));
diff --git a/source4/smb_server/smb2/smb2_server.h b/source4/smb_server/smb2/smb2_server.h
index 2f347d3876..fc40a92efc 100644
--- a/source4/smb_server/smb2/smb2_server.h
+++ b/source4/smb_server/smb2/smb2_server.h
@@ -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); \
diff --git a/source4/torture/gentest_smb2.c b/source4/torture/gentest_smb2.c
index 9c4be90b3c..68e9e2c20b 100644
--- a/source4/torture/gentest_smb2.c
+++ b/source4/torture/gentest_smb2.c
@@ -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);
}
/*
@@ -1135,46 +1138,41 @@ 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;
}
+#if 0
+
/*
generate a fileinfo query structure
*/
@@ -1583,6 +1581,7 @@ static struct {
{"CLOSE", handler_close},
{"READ", handler_read},
{"WRITE", handler_write},
+ {"LOCK", handler_lock},
};
diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c
index 3cf2e93ee0..e81647b497 100644
--- a/source4/torture/smb2/lock.c
+++ b/source4/torture/smb2/lock.c
@@ -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,