summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/raw/lock.c252
1 files changed, 235 insertions, 17 deletions
diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c
index 36a014e941..0059846180 100644
--- a/source4/torture/raw/lock.c
+++ b/source4/torture/raw/lock.c
@@ -22,16 +22,16 @@
#define CHECK_STATUS(status, correct) do { \
if (!NT_STATUS_EQUAL(status, correct)) { \
- printf("(%d) Incorrect status %s - should be %s\n", \
- __LINE__, nt_errstr(status), nt_errstr(correct)); \
+ printf("(%s) Incorrect status %s - should be %s\n", \
+ __location__, nt_errstr(status), nt_errstr(correct)); \
ret = False; \
goto done; \
}} while (0)
#define CHECK_VALUE(v, correct) do { \
if ((v) != (correct)) { \
- printf("(%d) Incorrect value %s=%d - should be %d\n", \
- __LINE__, #v, v, correct); \
+ printf("(%s) Incorrect value %s=%d - should be %d\n", \
+ __location__, #v, v, correct); \
ret = False; \
goto done; \
}} while (0)
@@ -211,12 +211,144 @@ static BOOL test_lockx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
io.lockx.in.ulock_cnt = 0;
io.lockx.in.lock_cnt = 1;
lock[0].pid = cli->session->pid;
- lock[0].offset = 0;
- lock[0].count = 0xFFFFFFFF;
+ lock[0].offset = 10;
+ lock[0].count = 1;
io.lockx.in.locks = &lock[0];
status = smb_raw_lock(cli->tree, &io);
CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("Trying 0xEEFFFFFF lock\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 4000;
+ lock[0].offset = 0xEEFFFFFF;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying 0xEF000000 lock\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 4000;
+ lock[0].offset = 0xEF000000;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying zero lock\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 0;
+ lock[0].offset = ~0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying max lock\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 0;
+ lock[0].offset = ~0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying 2^63\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 1;
+ lock[0].offset = 1;
+ lock[0].offset <<= 63;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying 2^63 - 1\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 1;
+ lock[0].offset = 1;
+ lock[0].offset <<= 63;
+ lock[0].offset--;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
+ printf("Trying max lock 2\n");
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].count = 1;
+ lock[0].offset = ~0;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid++;
+ lock[0].count = 2;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ lock[0].pid--;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ lock[0].count = 1;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+
done:
smbcli_close(cli->tree, fnum);
smb_raw_exit(cli->session);
@@ -308,33 +440,119 @@ done:
}
-/*
- basic testing of lock calls
+/*
+ test locking&X async operation
*/
-BOOL torture_raw_lock(int dummy)
+static BOOL test_async(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
- struct smbcli_state *cli;
+ union smb_lock io;
+ struct smb_lock_entry lock[2];
+ NTSTATUS status;
BOOL ret = True;
- TALLOC_CTX *mem_ctx;
+ int fnum;
+ const char *fname = BASEDIR "\\test.txt";
+ time_t t;
+ struct smbcli_request *req;
- if (!torture_open_connection(&cli)) {
+ if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
+ NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
+ printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
return False;
}
- mem_ctx = talloc_init("torture_raw_lock");
-
- if (!test_lockx(cli, mem_ctx)) {
+ printf("Testing lock cancel\n");
+ io.generic.level = RAW_LOCK_LOCKX;
+
+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+ if (fnum == -1) {
+ printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
ret = False;
+ goto done;
}
- if (!test_lock(cli, mem_ctx)) {
+ io.lockx.level = RAW_LOCK_LOCKX;
+ io.lockx.in.fnum = fnum;
+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].pid = cli->session->pid;
+ lock[0].offset = 100;
+ lock[0].count = 10;
+ io.lockx.in.locks = &lock[0];
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ t = time(NULL);
+
+ /* setup a timed lock */
+ io.lockx.in.timeout = 10000;
+ req = smb_raw_lock_send(cli->tree, &io);
+ if (req == NULL) {
+ printf("Failed to setup timed lock (%s)\n", __location__);
ret = False;
+ goto done;
}
- if (!test_pidhigh(cli, mem_ctx)) {
+ /* cancel the wrong range */
+ lock[0].offset = 0;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_UNSUCCESSFUL);
+
+ /* cancel with the wrong bits set */
+ lock[0].offset = 100;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_UNSUCCESSFUL);
+
+ /* cancel the right range */
+ lock[0].offset = 100;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* receive the failed lock request */
+ status = smbcli_request_simple_recv(req);
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
+
+ if (time(NULL) > t+2) {
+ printf("lock cancel was not immediate (%s)\n", __location__);
ret = False;
+ goto done;
}
+done:
+ smbcli_close(cli->tree, fnum);
+ smb_raw_exit(cli->session);
+ smbcli_deltree(cli->tree, BASEDIR);
+ return ret;
+}
+
+
+/*
+ basic testing of lock calls
+*/
+BOOL torture_raw_lock(int dummy)
+{
+ struct smbcli_state *cli;
+ BOOL ret = True;
+ TALLOC_CTX *mem_ctx;
+
+ if (!torture_open_connection(&cli)) {
+ return False;
+ }
+
+ mem_ctx = talloc_init("torture_raw_lock");
+
+ ret &= test_lockx(cli, mem_ctx);
+ ret &= test_lock(cli, mem_ctx);
+ ret &= test_pidhigh(cli, mem_ctx);
+ ret &= test_async(cli, mem_ctx);
+
torture_close_connection(cli);
talloc_destroy(mem_ctx);
return ret;