⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locking.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   basic locking tests   Copyright (C) Andrew Tridgell 2000-2004   Copyright (C) Jeremy Allison 2000-2004      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "libcli/raw/libcliraw.h"#include "libcli/libcli.h"#include "torture/smbtorture.h"#include "torture/util.h"#include "system/time.h"#include "system/filesys.h"#define BASEDIR "\\locktest"/*  This test checks for two things:  1) correct support for retaining locks over a close (ie. the server     must not use posix semantics)  2) support for lock timeouts */static bool torture_locktest1(struct torture_context *tctx, 			      struct smbcli_state *cli1,			      struct smbcli_state *cli2){	const char *fname = BASEDIR "\\lockt1.lck";	int fnum1, fnum2, fnum3;	time_t t1, t2;	uint_t lock_timeout;	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);	torture_assert(tctx, fnum1 != -1,				   talloc_asprintf(tctx, 		"open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));	fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);	torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, 		"open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));	fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);	torture_assert(tctx, fnum3 != -1, talloc_asprintf(tctx, 		"open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree)));	torture_assert_ntstatus_ok(tctx, 		smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK),		talloc_asprintf(tctx, "lock1 failed (%s)", smbcli_errstr(cli1->tree)));	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock2 succeeded! This is a locking bug\n");	if (!check_error(__location__, cli2, ERRDOS, ERRlock, 			 NT_STATUS_LOCK_NOT_GRANTED)) return false;	torture_assert(tctx,		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock2 succeeded! This is a locking bug\n");	if (!check_error(__location__, cli2, ERRDOS, ERRlock, 				 NT_STATUS_FILE_LOCK_CONFLICT)) return false;	torture_assert_ntstatus_ok(tctx, 		smbcli_lock(cli1->tree, fnum1, 5, 9, 0, WRITE_LOCK),		talloc_asprintf(tctx, 		"lock1 failed (%s)", smbcli_errstr(cli1->tree)));	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 5, 9, 0, WRITE_LOCK)),		"lock2 succeeded! This is a locking bug");		if (!check_error(__location__, cli2, ERRDOS, ERRlock, 				 NT_STATUS_LOCK_NOT_GRANTED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock2 succeeded! This is a locking bug");		if (!check_error(__location__, cli2, ERRDOS, ERRlock, 				 NT_STATUS_LOCK_NOT_GRANTED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock2 succeeded! This is a locking bug");	if (!check_error(__location__, cli2, ERRDOS, ERRlock, 			 NT_STATUS_FILE_LOCK_CONFLICT)) return false;	lock_timeout = (6 + (random() % 20));	torture_comment(tctx, "Testing lock timeout with timeout=%u\n", 					lock_timeout);	t1 = time(NULL);	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)),		"lock3 succeeded! This is a locking bug\n");	if (!check_error(__location__, cli2, ERRDOS, ERRlock, 				 NT_STATUS_FILE_LOCK_CONFLICT)) return false;	t2 = time(NULL);	if (t2 - t1 < 5) {		torture_fail(tctx, 			"error: This server appears not to support timed lock requests");	}	torture_comment(tctx, "server slept for %u seconds for a %u second timeout\n",	       (uint_t)(t2-t1), lock_timeout);	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum2),		talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock4 succeeded! This is a locking bug");			if (!check_error(__location__, cli2, ERRDOS, ERRlock, 			 NT_STATUS_FILE_LOCK_CONFLICT)) return false;	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),		talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli1->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum3),		talloc_asprintf(tctx, "close3 failed (%s)", smbcli_errstr(cli2->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),		talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));	return true;}/*  This test checks that   1) the server supports multiple locking contexts on the one SMB  connection, distinguished by PID.    2) the server correctly fails overlapping locks made by the same PID (this     goes against POSIX behaviour, which is why it is tricky to implement)  3) the server denies unlock requests by an incorrect client PID*/static bool torture_locktest2(struct torture_context *tctx,			      struct smbcli_state *cli){	const char *fname = BASEDIR "\\lockt2.lck";	int fnum1, fnum2, fnum3;	if (!torture_setup_dir(cli, BASEDIR)) {		return false;	}	torture_comment(tctx, "Testing pid context\n");		cli->session->pid = 1;	fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);	torture_assert(tctx, fnum1 != -1, 		talloc_asprintf(tctx, 		"open of %s failed (%s)", fname, smbcli_errstr(cli->tree)));	fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);	torture_assert(tctx, fnum2 != -1,		talloc_asprintf(tctx, "open2 of %s failed (%s)", 		       fname, smbcli_errstr(cli->tree)));	cli->session->pid = 2;	fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);	torture_assert(tctx, fnum3 != -1,		talloc_asprintf(tctx, 		"open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)));	cli->session->pid = 1;	torture_assert_ntstatus_ok(tctx, 		smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK),		talloc_asprintf(tctx, 		"lock1 failed (%s)", smbcli_errstr(cli->tree)));	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK)),		"WRITE lock1 succeeded! This is a locking bug");			if (!check_error(__location__, cli, ERRDOS, ERRlock, 			 NT_STATUS_LOCK_NOT_GRANTED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK)),		"WRITE lock2 succeeded! This is a locking bug");	if (!check_error(__location__, cli, ERRDOS, ERRlock, 			 NT_STATUS_LOCK_NOT_GRANTED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK)),		"READ lock2 succeeded! This is a locking bug");	if (!check_error(__location__, cli, ERRDOS, ERRlock, 			 NT_STATUS_FILE_LOCK_CONFLICT)) return false;	torture_assert_ntstatus_ok(tctx, 		smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK),		talloc_asprintf(tctx, 		"lock at 100 failed (%s)", smbcli_errstr(cli->tree)));	cli->session->pid = 2;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4)),		"unlock at 100 succeeded! This is a locking bug");	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4)),		"unlock1 succeeded! This is a locking bug");	if (!check_error(__location__, cli, 				 ERRDOS, ERRnotlocked, 				 NT_STATUS_RANGE_NOT_LOCKED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8)),		"unlock2 succeeded! This is a locking bug");	if (!check_error(__location__, cli, 			 ERRDOS, ERRnotlocked, 			 NT_STATUS_RANGE_NOT_LOCKED)) return false;	torture_assert(tctx, 		!NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK)),		"lock3 succeeded! This is a locking bug");	if (!check_error(__location__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return false;	cli->session->pid = 1;	torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum1), 		talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum2),		talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum3),		talloc_asprintf(tctx, "close3 failed (%s)", smbcli_errstr(cli->tree)));	return true;}/*  This test checks that   1) the server supports the full offset range in lock requests*/static bool torture_locktest3(struct torture_context *tctx, 			      struct smbcli_state *cli1,			      struct smbcli_state *cli2){	const char *fname = BASEDIR "\\lockt3.lck";	int fnum1, fnum2, i;	uint32_t offset;	extern int torture_numops;#define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops	torture_comment(tctx, "Testing 32 bit offset ranges");	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);	torture_assert(tctx, fnum1 != -1, 		talloc_asprintf(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));	fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);	torture_assert(tctx, fnum2 != -1,		talloc_asprintf(tctx, "open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree)));	torture_comment(tctx, "Establishing %d locks\n", torture_numops);	for (offset=i=0;i<torture_numops;i++) {		NEXT_OFFSET;		torture_assert_ntstatus_ok(tctx, 			smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK),			talloc_asprintf(tctx, "lock1 %d failed (%s)", i, smbcli_errstr(cli1->tree)));		torture_assert_ntstatus_ok(tctx, 			smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK),			talloc_asprintf(tctx, "lock2 %d failed (%s)", 			       i, smbcli_errstr(cli1->tree)));	}	torture_comment(tctx, "Testing %d locks\n", torture_numops);	for (offset=i=0;i<torture_numops;i++) {		NEXT_OFFSET;		torture_assert(tctx, 			!NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK)),			talloc_asprintf(tctx, "error: lock1 %d succeeded!", i));		torture_assert(tctx, 			!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK)),			talloc_asprintf(tctx, "error: lock2 %d succeeded!", i));		torture_assert(tctx, 			!NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK)),			talloc_asprintf(tctx, "error: lock3 %d succeeded!", i));		torture_assert(tctx, 			!NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK)),			talloc_asprintf(tctx, "error: lock4 %d succeeded!", i));	}	torture_comment(tctx, "Removing %d locks\n", torture_numops);	for (offset=i=0;i<torture_numops;i++) {		NEXT_OFFSET;		torture_assert_ntstatus_ok(tctx, 					smbcli_unlock(cli1->tree, fnum1, offset-1, 1),					talloc_asprintf(tctx, "unlock1 %d failed (%s)", 			       i,			       smbcli_errstr(cli1->tree)));		torture_assert_ntstatus_ok(tctx, 			smbcli_unlock(cli2->tree, fnum2, offset-2, 1),			talloc_asprintf(tctx, "unlock2 %d failed (%s)", 			       i,			       smbcli_errstr(cli1->tree)));	}	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),		talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),		talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));	torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),		talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));	return true;}#define EXPECTED(ret, v) if ((ret) != (v)) { \        torture_comment(tctx, "** "); correct = false; \        }/*  looks at overlapping locks*/static bool torture_locktest4(struct torture_context *tctx, 			      struct smbcli_state *cli1,			      struct smbcli_state *cli2){	const char *fname = BASEDIR "\\lockt4.lck";	int fnum1, fnum2, f;	bool ret;	uint8_t buf[1000];	bool correct = true;	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);	fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);	memset(buf, 0, sizeof(buf));	if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {		torture_comment(tctx, "Failed to create file\n");		correct = false;		goto fail;	}	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));	EXPECTED(ret, false);	torture_comment(tctx, "the same process %s set overlapping write locks\n", ret?"can":"cannot");	    	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));	EXPECTED(ret, true);	torture_comment(tctx, "the same process %s set overlapping read locks\n", ret?"can":"cannot");	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -