📄 lock.c
字号:
struct smb_composite_sesssetup setup; struct smbcli_tree *tree; union smb_tcon tcon; const char *host, *share; union smb_lock io; struct smb_lock_entry lock[2]; NTSTATUS status; bool ret = true; int fnum; const char *fname = BASEDIR "\\test.txt"; time_t t; struct smbcli_request *req; if (!torture_setup_dir(cli, BASEDIR)) { return false; } printf("Testing LOCKING_ANDX_CANCEL_LOCK\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_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); printf("testing cancel by CANCEL_LOCK\n"); /* 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; } /* 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_DOS(ERRDOS, ERRcancelviolation)); /* 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_DOS(ERRDOS, ERRcancelviolation)); /* 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; } printf("testing cancel by unlock\n"); io.lockx.in.ulock_cnt = 0; io.lockx.in.lock_cnt = 1; io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = 0; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); io.lockx.in.timeout = 5000; 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.ulock_cnt = 1; io.lockx.in.lock_cnt = 0; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); t = time(NULL); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_OK); if (time(NULL) > t+2) { printf("lock cancel by unlock was not immediate (%s) - took %d secs\n", __location__, (int)(time(NULL)-t)); ret = false; goto done; } printf("testing cancel by close\n"); io.lockx.in.ulock_cnt = 0; io.lockx.in.lock_cnt = 1; io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = 0; status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); t = time(NULL); 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; } status = smbcli_close(cli->tree, fnum); CHECK_STATUS(status, NT_STATUS_OK); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); if (time(NULL) > t+2) { printf("lock cancel by close was not immediate (%s)\n", __location__); ret = false; goto done; } printf("create a new sessions\n"); session = smbcli_session_init(cli->transport, tctx, false); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; status = smb_composite_sesssetup(session, &setup); CHECK_STATUS(status, NT_STATUS_OK); session->vuid = setup.out.vuid; printf("create new tree context\n"); share = torture_setting_string(tctx, "share", NULL); host = torture_setting_string(tctx, "host", NULL); tree = smbcli_tree_init(session, tctx, false); tcon.generic.level = RAW_TCON_TCONX; tcon.tconx.in.flags = 0; tcon.tconx.in.password = data_blob(NULL, 0); tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); tcon.tconx.in.device = "A:"; status = smb_raw_tcon(tree, tctx, &tcon); CHECK_STATUS(status, NT_STATUS_OK); tree->tid = tcon.tconx.out.tid; printf("testing cancel by exit\n"); fname = BASEDIR "\\test_exit.txt"; fnum = smbcli_open(tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(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 = session->pid; lock[0].offset = 100; lock[0].count = 10; io.lockx.in.locks = &lock[0]; status = smb_raw_lock(tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.ulock_cnt = 0; io.lockx.in.lock_cnt = 1; io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = 0; status = smb_raw_lock(tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); io.lockx.in.timeout = 10000; t = time(NULL); req = smb_raw_lock_send(tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } status = smb_raw_exit(session); CHECK_STATUS(status, NT_STATUS_OK); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); if (time(NULL) > t+2) { printf("lock cancel by exit was not immediate (%s)\n", __location__); ret = false; goto done; } printf("testing cancel by ulogoff\n"); fname = BASEDIR "\\test_ulogoff.txt"; fnum = smbcli_open(tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(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 = session->pid; lock[0].offset = 100; lock[0].count = 10; io.lockx.in.locks = &lock[0]; status = smb_raw_lock(tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.ulock_cnt = 0; io.lockx.in.lock_cnt = 1; io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = 0; status = smb_raw_lock(tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); io.lockx.in.timeout = 10000; t = time(NULL); req = smb_raw_lock_send(tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } status = smb_raw_ulogoff(session); CHECK_STATUS(status, NT_STATUS_OK); status = smbcli_request_simple_recv(req); if (NT_STATUS_EQUAL(NT_STATUS_FILE_LOCK_CONFLICT, status)) { printf("lock not canceled by ulogoff - %s (ignored because of vfs_vifs fails it)\n", nt_errstr(status)); smb_tree_disconnect(tree); smb_raw_exit(session); goto done; } CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); if (time(NULL) > t+2) { printf("lock cancel by ulogoff was not immediate (%s)\n", __location__); ret = false; goto done; } printf("testing cancel by tdis\n"); tree->session = cli->session; fname = BASEDIR "\\test_tdis.txt"; fnum = smbcli_open(tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(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(tree, &io); CHECK_STATUS(status, NT_STATUS_OK); status = smb_raw_lock(tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); io.lockx.in.timeout = 10000; t = time(NULL); req = smb_raw_lock_send(tree, &io); if (req == NULL) { printf("Failed to setup timed lock (%s)\n", __location__); ret = false; goto done; } status = smb_tree_disconnect(tree); CHECK_STATUS(status, NT_STATUS_OK); status = smbcli_request_simple_recv(req); CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); if (time(NULL) > t+2) { printf("lock cancel by tdis was not immediate (%s)\n", __location__); ret = false; goto done; }done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}/* test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT*/static bool test_errorcode(struct torture_context *tctx, struct smbcli_state *cli){ union smb_lock io; union smb_open op; struct smb_lock_entry lock[2]; NTSTATUS status; bool ret = true; int fnum, fnum2; const char *fname; struct smbcli_request *req; time_t start; int t; if (!torture_setup_dir(cli, BASEDIR)) { return false; } printf("Testing LOCK_NOT_GRANTED vs. FILE_LOCK_CONFLICT\n"); printf("testing with timeout = 0\n"); fname = BASEDIR "\\test0.txt"; t = 0; /* * the first run is with t = 0, * the second with t > 0 (=1) */next_run: /* * use the DENY_DOS mode, that creates two fnum's of one low-level file handle, * this demonstrates that the cache is per fnum */ op.openx.level = RAW_OPEN_OPENX; op.openx.in.fname = fname; op.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO; op.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_DOS; op.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE; op.openx.in.search_attrs = 0; op.openx.in.file_attrs = 0; op.openx.in.write_time = 0; op.openx.in.size = 0; op.openx.in.timeout = 0; status = smb_raw_open(cli->tree, tctx, &op); CHECK_STATUS(status, NT_STATUS_OK); fnum = op.openx.out.file.fnum; status = smb_raw_open(cli->tree, tctx, &op); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = op.openx.out.file.fnum; io.lockx.level = RAW_LOCK_LOCKX; io.lockx.in.file.fnum = fnum; io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = t; 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); /* * demonstrate that the first conflicting lock on each handle give LOCK_NOT_GRANTED * this also demonstrates that the error code cache is per file handle * (LOCK_NOT_GRANTED is only be used when timeout is 0!) */ 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)); 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)); /* demonstrate that each following conflict gives FILE_LOCK_CONFLICT */ 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); 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 the smbpid doesn't matter */ lock[0].pid++; 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].pid--; /* * demonstrate the a successful lock with count = 0 and the same offset, * doesn't reset the error cache */ lock[0].offset = 100; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -