📄 lock.c
字号:
status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* * demonstrate the a successful lock with count = 0 and outside the locked range, * doesn't reset the error cache */ lock[0].offset = 110; lock[0].count = 0; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 99; lock[0].count = 0; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* demonstrate that a changing count doesn't reset the error cache */ lock[0].offset = 100; lock[0].count = 5; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 100; lock[0].count = 15; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* * demonstrate the a lock with count = 0 and inside the locked range, * fails and resets the error cache */ lock[0].offset = 101; lock[0].count = 0; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* demonstrate the a changing offset, resets the error cache */ lock[0].offset = 105; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 95; lock[0].count = 9; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* * demonstrate the a successful lock in a different range, * doesn't reset the cache, the failing lock on the 2nd handle * resets the resets the cache */ lock[0].offset = 120; lock[0].count = 15; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); lock[0].offset = 100; lock[0].count = 10; io.lockx.in.file.fnum = fnum; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.file.fnum = fnum2; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, (t?NT_STATUS_FILE_LOCK_CONFLICT:NT_STATUS_LOCK_NOT_GRANTED)); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); /* end of the loop */ if (t == 0) { smb_raw_exit(cli->session); printf("testing with timeout > 0 (=1)\n"); fname = BASEDIR "\\test1.txt"; t = 1; goto next_run; } /* * the following 3 test sections demonstrate that * the cache is only set when the error is reported * to the client (after the timeout went by) */ smb_raw_exit(cli->session); printf("testing a conflict while a lock is pending\n"); fname = BASEDIR "\\test2.txt"; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = false; goto done; } io.lockx.level = RAW_LOCK_LOCKX; io.lockx.in.file.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); start = time(NULL); io.lockx.in.timeout = 1000; req = smb_raw_lock_send(cli->tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } io.lockx.in.timeout = 0; lock[0].offset = 105; lock[0].count = 10; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); if (time(NULL) < start+1) { printf("lock comes back to early (%s)\n", __location__); ret = false; goto done; } smbcli_close(cli->tree, fnum); fname = BASEDIR "\\test3.txt"; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = false; goto done; } io.lockx.level = RAW_LOCK_LOCKX; io.lockx.in.file.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); start = time(NULL); io.lockx.in.timeout = 1000; req = smb_raw_lock_send(cli->tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } io.lockx.in.timeout = 0; lock[0].offset = 105; lock[0].count = 10; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); lock[0].offset = 100; lock[0].count = 10; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); if (time(NULL) < start+1) { printf("lock comes back to early (%s)\n", __location__); ret = false; goto done; } smbcli_close(cli->tree, fnum); fname = BASEDIR "\\test4.txt"; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = false; goto done; } io.lockx.level = RAW_LOCK_LOCKX; io.lockx.in.file.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); start = time(NULL); io.lockx.in.timeout = 1000; req = smb_raw_lock_send(cli->tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } io.lockx.in.timeout = 0; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); if (time(NULL) < start+1) { printf("lock comes back to early (%s)\n", __location__); ret = false; goto done; }done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}/* test LOCKING_ANDX_CHANGE_LOCKTYPE*/static bool test_changetype(struct torture_context *tctx, struct smbcli_state *cli){ union smb_lock io; struct smb_lock_entry lock[2]; NTSTATUS status; bool ret = true; int fnum; uint8_t c = 0; const char *fname = BASEDIR "\\test.txt"; if (!torture_setup_dir(cli, BASEDIR)) { return false; } printf("Testing LOCKING_ANDX_CHANGE_LOCKTYPE\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; } io.lockx.level = RAW_LOCK_LOCKX; io.lockx.in.file.fnum = fnum; io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; 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); if (smbcli_write(cli->tree, fnum, 0, &c, 100, 1) == 1) { printf("allowed write on read locked region (%s)\n", __location__); ret = false; goto done; } /* windows server don't seem to support this */ io.lockx.in.mode = LOCKING_ANDX_CHANGE_LOCKTYPE; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); if (smbcli_write(cli->tree, fnum, 0, &c, 100, 1) == 1) { printf("allowed write after lock change (%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*/struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx){ struct torture_suite *suite = torture_suite_create(mem_ctx, "LOCK"); torture_suite_add_1smb_test(suite, "lockx", test_lockx); torture_suite_add_1smb_test(suite, "lock", test_lock); torture_suite_add_1smb_test(suite, "pidhigh", test_pidhigh); torture_suite_add_1smb_test(suite, "async", test_async); torture_suite_add_1smb_test(suite, "errorcode", test_errorcode); torture_suite_add_1smb_test(suite, "changetype", test_changetype); return suite;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -