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

📄 oplock.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   basic raw test suite for oplocks   Copyright (C) Andrew Tridgell 2003      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 "torture/torture.h"#include "librpc/gen_ndr/security.h"#include "libcli/raw/libcliraw.h"#include "libcli/raw/raw_proto.h"#include "libcli/libcli.h"#include "torture/util.h"#include "lib/events/events.h"#include "param/param.h"#include "lib/cmdline/popt_common.h"#include "libcli/resolve/resolve.h"#define CHECK_VAL(v, correct) do { \	if ((v) != (correct)) { \		torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \				__location__, #v, (int)v, (int)correct); \		ret = false; \	}} while (0)#define CHECK_RANGE(v, min, max) do { \	if ((v) < (min) || (v) > (max)) { \		torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \				__location__, #v, (int)v, (int)min, (int)max); \		ret = false; \	}} while (0)#define CHECK_STRMATCH(v, correct) do { \	if (!v || strstr((v),(correct)) == NULL) { \		torture_result(tctx, TORTURE_FAIL,  "(%s): wrong value for %s got '%s' - should be '%s'\n", \				__location__, #v, v?v:"NULL", correct); \		ret = false; \	} \} while (0)#define CHECK_STATUS(tctx, status, correct) do { \	if (!NT_STATUS_EQUAL(status, correct)) { \		torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \		       nt_errstr(status), nt_errstr(correct)); \		ret = false; \		goto done; \	}} while (0)static struct {	int fnum;	uint8_t level;	int count;	int failures;} break_info;#define BASEDIR "\\test_oplock"/*  a handler function for oplock break requests. Ack it as a break to level II if possible*/static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,					uint16_t tid, uint16_t fnum,					uint8_t level, void *private){	struct smbcli_tree *tree = (struct smbcli_tree *)private;	const char *name;	break_info.fnum = fnum;	break_info.level = level;	break_info.count++;	switch (level) {	case OPLOCK_BREAK_TO_LEVEL_II:		name = "level II";		break;	case OPLOCK_BREAK_TO_NONE:		name = "none";		break;	default:		name = "unknown";		break_info.failures++;	}	printf("Acking to %s [0x%02X] in oplock handler\n",		name, level);	return smbcli_oplock_ack(tree, fnum, level);}/*  a handler function for oplock break requests. Ack it as a break to none*/static bool oplock_handler_ack_to_none(struct smbcli_transport *transport, 				       uint16_t tid, uint16_t fnum, 				       uint8_t level, void *private){	struct smbcli_tree *tree = (struct smbcli_tree *)private;	break_info.fnum = fnum;	break_info.level = level;	break_info.count++;	printf("Acking to none in oplock handler\n");	return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);}/*  a handler function for oplock break requests. Let it timeout*/static bool oplock_handler_timeout(struct smbcli_transport *transport,				   uint16_t tid, uint16_t fnum,				   uint8_t level, void *private){	break_info.fnum = fnum;	break_info.level = level;	break_info.count++;	printf("Let oplock break timeout\n");	return true;}static void oplock_handler_close_recv(struct smbcli_request *req){	NTSTATUS status;	status = smbcli_request_simple_recv(req);	if (!NT_STATUS_IS_OK(status)) {		printf("close failed in oplock_handler_close\n");		break_info.failures++;	}}/*  a handler function for oplock break requests - close the file*/static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid, 				 uint16_t fnum, uint8_t level, void *private){	union smb_close io;	struct smbcli_tree *tree = (struct smbcli_tree *)private;	struct smbcli_request *req;	break_info.fnum = fnum;	break_info.level = level;	break_info.count++;	io.close.level = RAW_CLOSE_CLOSE;	io.close.in.file.fnum = fnum;	io.close.in.write_time = 0;	req = smb_raw_close_send(tree, &io);	if (req == NULL) {		printf("failed to send close in oplock_handler_close\n");		return false;	}	req->async.fn = oplock_handler_close_recv;	req->async.private = NULL;	return true;}static bool open_connection_no_level2_oplocks(struct torture_context *tctx,					      struct smbcli_state **c){	NTSTATUS status;	struct smbcli_options options;	lp_smbcli_options(tctx->lp_ctx, &options);	options.use_level2_oplocks = false;	status = smbcli_full_connection(tctx, c,					torture_setting_string(tctx, "host", NULL),					lp_smb_ports(tctx->lp_ctx),					torture_setting_string(tctx, "share", NULL),					NULL, cmdline_credentials,					lp_resolve_context(tctx->lp_ctx),					tctx->ev, &options);	if (!NT_STATUS_IS_OK(status)) {		printf("Failed to open connection - %s\n", nt_errstr(status));		return false;	}	return true;}static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2){	const char *fname = BASEDIR "\\test_exclusive1.dat";	NTSTATUS status;	bool ret = true;	union smb_open io;	union smb_unlink unl;	uint16_t fnum=0;	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	/* cleanup */	smbcli_unlink(cli1->tree, fname);	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);	/*	  base ntcreatex parms	*/	io.generic.level = RAW_OPEN_NTCREATEX;	io.ntcreatex.in.root_fid = 0;	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;	io.ntcreatex.in.alloc_size = 0;	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;	io.ntcreatex.in.create_options = 0;	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;	io.ntcreatex.in.security_flags = 0;	io.ntcreatex.in.fname = fname;	torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");	ZERO_STRUCT(break_info);	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;	status = smb_raw_open(cli1->tree, tctx, &io);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	fnum = io.ntcreatex.out.file.fnum;	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);	torture_comment(tctx, "a 2nd open should not cause a break\n");	status = smb_raw_open(cli2->tree, tctx, &io);	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);	CHECK_VAL(break_info.count, 0);	CHECK_VAL(break_info.failures, 0);	torture_comment(tctx, "unlink it - should also be no break\n");	unl.unlink.in.pattern = fname;	unl.unlink.in.attrib = 0;	status = smb_raw_unlink(cli2->tree, &unl);	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);	CHECK_VAL(break_info.count, 0);	CHECK_VAL(break_info.failures, 0);	smbcli_close(cli1->tree, fnum);done:	smb_raw_exit(cli1->session);	smb_raw_exit(cli2->session);	smbcli_deltree(cli1->tree, BASEDIR);	return ret;}static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2){	const char *fname = BASEDIR "\\test_exclusive2.dat";	NTSTATUS status;	bool ret = true;	union smb_open io;	union smb_unlink unl;	uint16_t fnum=0, fnum2=0;	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	/* cleanup */	smbcli_unlink(cli1->tree, fname);	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);	/*	  base ntcreatex parms	*/	io.generic.level = RAW_OPEN_NTCREATEX;	io.ntcreatex.in.root_fid = 0;	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;	io.ntcreatex.in.alloc_size = 0;	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;	io.ntcreatex.in.create_options = 0;	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;	io.ntcreatex.in.security_flags = 0;	io.ntcreatex.in.fname = fname;	torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");	ZERO_STRUCT(break_info);	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|		NTCREATEX_SHARE_ACCESS_WRITE|		NTCREATEX_SHARE_ACCESS_DELETE;	status = smb_raw_open(cli1->tree, tctx, &io);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	fnum = io.ntcreatex.out.file.fnum;	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);	torture_comment(tctx, "a 2nd open should cause a break to level 2\n");	status = smb_raw_open(cli2->tree, tctx, &io);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	fnum2 = io.ntcreatex.out.file.fnum;	CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);	CHECK_VAL(break_info.count, 1);	CHECK_VAL(break_info.fnum, fnum);	CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);	CHECK_VAL(break_info.failures, 0);	ZERO_STRUCT(break_info);	/* now we have 2 level II oplocks... */	torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");	unl.unlink.in.pattern = fname;	unl.unlink.in.attrib = 0;	status = smb_raw_unlink(cli2->tree, &unl);	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);	CHECK_VAL(break_info.count, 0);	CHECK_VAL(break_info.failures, 0);	torture_comment(tctx, "close 1st handle\n");	smbcli_close(cli1->tree, fnum);	torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");	unl.unlink.in.pattern = fname;	unl.unlink.in.attrib = 0;	status = smb_raw_unlink(cli2->tree, &unl);	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);	CHECK_VAL(break_info.count, 0);	CHECK_VAL(break_info.failures, 0);	torture_comment(tctx, "close 1st handle\n");	smbcli_close(cli2->tree, fnum2);	torture_comment(tctx, "unlink it\n");	unl.unlink.in.pattern = fname;	unl.unlink.in.attrib = 0;	status = smb_raw_unlink(cli2->tree, &unl);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	CHECK_VAL(break_info.count, 0);	CHECK_VAL(break_info.failures, 0);done:	smb_raw_exit(cli1->session);	smb_raw_exit(cli2->session);	smbcli_deltree(cli1->tree, BASEDIR);	return ret;}static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2){	const char *fname = BASEDIR "\\test_exclusive3.dat";	NTSTATUS status;	bool ret = true;	union smb_open io;	union smb_setfileinfo sfi;	uint16_t fnum=0;	if (!torture_setup_dir(cli1, BASEDIR)) {		return false;	}	/* cleanup */	smbcli_unlink(cli1->tree, fname);	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);	/*	  base ntcreatex parms	*/	io.generic.level = RAW_OPEN_NTCREATEX;	io.ntcreatex.in.root_fid = 0;	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;	io.ntcreatex.in.alloc_size = 0;	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;	io.ntcreatex.in.create_options = 0;	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;	io.ntcreatex.in.security_flags = 0;	io.ntcreatex.in.fname = fname;	torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");	ZERO_STRUCT(break_info);	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;	status = smb_raw_open(cli1->tree, tctx, &io);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	fnum = io.ntcreatex.out.file.fnum;	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);	torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");	ZERO_STRUCT(sfi);	sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;	sfi.generic.in.file.path = fname;	sfi.end_of_file_info.in.size = 100;	status = smb_raw_setpathinfo(cli2->tree, &sfi);

⌨️ 快捷键说明

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