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

📄 gentest.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   generic testing tool - version with both SMB and SMB2 support   Copyright (C) Andrew Tridgell 2003-2008      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 "lib/cmdline/popt_common.h"#include "lib/events/events.h"#include "system/time.h"#include "system/filesys.h"#include "libcli/raw/request.h"#include "libcli/libcli.h"#include "libcli/raw/libcliraw.h"#include "libcli/smb2/smb2.h"#include "libcli/smb2/smb2_calls.h"#include "librpc/gen_ndr/security.h"#include "librpc/gen_ndr/ndr_security.h"#include "auth/credentials/credentials.h"#include "libcli/resolve/resolve.h"#include "auth/gensec/gensec.h"#include "param/param.h"#include "dynconfig/dynconfig.h"#include "libcli/security/security.h"#include "libcli/raw/raw_proto.h"#define NSERVERS 2#define NINSTANCES 2/* global options */static struct gentest_options {	int showall;	int analyze;	int analyze_always;	int analyze_continuous;	uint_t max_open_handles;	uint_t seed;	uint_t numops;	int use_oplocks;	char **ignore_patterns;	const char *seeds_file;	int use_preset_seeds;	int fast_reconnect;	int mask_indexing;	int no_eas;	int no_acls;	int skip_cleanup;	int valid;	int smb2;} options;/* mapping between open handles on the server and local handles */static struct {	bool active;	uint_t instance;	struct smb2_handle smb2_handle[NSERVERS]; /* SMB2 */	uint16_t smb_handle[NSERVERS];            /* SMB */	const char *name;} *open_handles;static uint_t num_open_handles;/* state information for the servers. We open NINSTANCES connections to   each server */static struct {	struct smb2_tree *smb2_tree[NINSTANCES];	struct smbcli_tree *smb_tree[NINSTANCES];	char *server_name;	char *share_name;	struct cli_credentials *credentials;} servers[NSERVERS];/* the seeds and flags for each operation */static struct {	uint_t seed;	bool disabled;} *op_parms;/* oplock break info */static struct {	bool got_break;	struct smb2_handle smb2_handle;	uint16_t smb_handle;	uint16_t handle;	uint8_t level;	bool do_close;} oplocks[NSERVERS][NINSTANCES];/* change notify reply info */static struct {	int notify_count;	NTSTATUS status;	union smb_notify notify;} notifies[NSERVERS][NINSTANCES];/* info relevant to the current operation */static struct {	const char *name;	uint_t seed;	NTSTATUS status;	uint_t opnum;	TALLOC_CTX *mem_ctx;	const char *mismatch;} current_op;static struct smb2_handle bad_smb2_handle;#define BAD_HANDLE 0xFFFEstatic bool oplock_handler_smb2(struct smb2_transport *transport, const struct smb2_handle *handle,				uint8_t level, void *private_data);static void idle_func_smb2(struct smb2_transport *transport, void *private);static bool oplock_handler_smb(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private);static void idle_func_smb(struct smbcli_transport *transport, void *private);/*  check if a string should be ignored. This is used as the basis  for all error ignore settings*/static bool ignore_pattern(const char *str){	int i;	if (!options.ignore_patterns) return false;	for (i=0;options.ignore_patterns[i];i++) {		if (strcmp(options.ignore_patterns[i], str) == 0 ||		    gen_fnmatch(options.ignore_patterns[i], str) == 0) {			DEBUG(2,("Ignoring '%s'\n", str));			return true;		}	}	return false;}/***************************************************** connect to the servers*******************************************************/static bool connect_servers_fast(void){	int h, i;	/* close all open files */	for (h=0;h<options.max_open_handles;h++) {		if (!open_handles[h].active) continue;		for (i=0;i<NSERVERS;i++) {			NTSTATUS status;			if (options.smb2) {				status = smb2_util_close(servers[i].smb2_tree[open_handles[h].instance],							 open_handles[h].smb2_handle[i]);			} else {				status = smbcli_close(servers[i].smb_tree[open_handles[h].instance],						      open_handles[h].smb_handle[i]);			}			if (NT_STATUS_IS_ERR(status)) {				return false;			}			open_handles[h].active = false;		}	}	return true;}/***************************************************** connect to the servers*******************************************************/static bool connect_servers(struct event_context *ev,			    struct loadparm_context *lp_ctx){	int i, j;	if (options.fast_reconnect && servers[0].smb2_tree[0]) {		if (connect_servers_fast()) {			return true;		}	}	/* close any existing connections */	for (i=0;i<NSERVERS;i++) {		for (j=0;j<NINSTANCES;j++) {			if (servers[i].smb2_tree[j]) {				smb2_tdis(servers[i].smb2_tree[j]);				talloc_free(servers[i].smb2_tree[j]);				servers[i].smb2_tree[j] = NULL;			}			if (servers[i].smb_tree[j]) {				smb_tree_disconnect(servers[i].smb_tree[j]);				talloc_free(servers[i].smb_tree[j]);				servers[i].smb_tree[j] = NULL;			}		}	}	for (i=0;i<NSERVERS;i++) {		for (j=0;j<NINSTANCES;j++) {			NTSTATUS status;			struct smbcli_options smb_options;			lp_smbcli_options(lp_ctx, &smb_options);			printf("Connecting to \\\\%s\\%s as %s - instance %d\n",			       servers[i].server_name, servers[i].share_name, 			       servers[i].credentials->username, j);			cli_credentials_set_workstation(servers[i].credentials, 							"gentest", CRED_SPECIFIED);			if (options.smb2) {				status = smb2_connect(NULL, servers[i].server_name, 						      servers[i].share_name,						      lp_resolve_context(lp_ctx),						      servers[i].credentials,						      &servers[i].smb2_tree[j],						      ev, &smb_options);			} else {				status = smbcli_tree_full_connection(NULL,								     &servers[i].smb_tree[j], 								     servers[i].server_name, 								     lp_smb_ports(lp_ctx),								     servers[i].share_name, "A:",								     servers[i].credentials,								     lp_resolve_context(lp_ctx), ev,								     &smb_options);			}			if (!NT_STATUS_IS_OK(status)) {				printf("Failed to connect to \\\\%s\\%s - %s\n",				       servers[i].server_name, servers[i].share_name,				       nt_errstr(status));				return false;			}			if (options.smb2) {				servers[i].smb2_tree[j]->session->transport->oplock.handler = oplock_handler_smb2;				servers[i].smb2_tree[j]->session->transport->oplock.private_data = (void *)(uintptr_t)((i<<8)|j);				smb2_transport_idle_handler(servers[i].smb2_tree[j]->session->transport, 							    idle_func_smb2, 50000, NULL);			} else {				smbcli_oplock_handler(servers[i].smb_tree[j]->session->transport, oplock_handler_smb, 						      (void *)(uintptr_t)((i<<8)|j));				smbcli_transport_idle_handler(servers[i].smb_tree[j]->session->transport, idle_func_smb, 							      50000, (void *)(uintptr_t)((i<<8)|j));			}		}	}	return true;}/*  work out the time skew between the servers - be conservative*/static uint_t time_skew(void){	uint_t ret;	if (options.smb2) {		ret = labs(servers[0].smb2_tree[0]->session->transport->negotiate.system_time -			   servers[1].smb2_tree[0]->session->transport->negotiate.system_time);	} else {		ret = labs(servers[0].smb_tree[0]->session->transport->negotiate.server_time -			   servers[1].smb_tree[0]->session->transport->negotiate.server_time);	}	return ret + 300;}static bool smb2_handle_equal(const struct smb2_handle *h1, const struct smb2_handle *h2){	return memcmp(h1, h2, sizeof(struct smb2_handle)) == 0;}/*  turn a server handle into a local handle*/static uint_t fnum_to_handle_smb2(int server, int instance, struct smb2_handle server_handle){	uint_t i;	for (i=0;i<options.max_open_handles;i++) {		if (!open_handles[i].active ||		    instance != open_handles[i].instance) continue;		if (smb2_handle_equal(&open_handles[i].smb2_handle[server], &server_handle)) {			return i;		}	}	printf("Invalid server handle in fnum_to_handle on server %d instance %d\n", 	       server, instance);	return BAD_HANDLE;}/*  turn a server handle into a local handle*/static uint_t fnum_to_handle_smb(int server, int instance, uint16_t server_handle){	uint_t i;	for (i=0;i<options.max_open_handles;i++) {		if (!open_handles[i].active ||		    instance != open_handles[i].instance) continue;		if (open_handles[i].smb_handle[server] == server_handle) {			return i;		}	}	printf("Invalid server handle in fnum_to_handle on server %d instance %d\n", 	       server, instance);	return BAD_HANDLE;}/*  add some newly opened handles*/static void gen_add_handle_smb2(int instance, const char *name, struct smb2_handle handles[NSERVERS]){	int i, h;	for (h=0;h<options.max_open_handles;h++) {		if (!open_handles[h].active) break;	}	if (h == options.max_open_handles) {		/* we have to force close a random handle */		h = random() % options.max_open_handles;		for (i=0;i<NSERVERS;i++) {			NTSTATUS status;			status = smb2_util_close(servers[i].smb2_tree[open_handles[h].instance], 						 open_handles[h].smb2_handle[i]);			if (NT_STATUS_IS_ERR(status)) {				printf("INTERNAL ERROR: Close failed when recovering handle! - %s\n",				       nt_errstr(status));			}		}		printf("Recovered handle %d\n", h);		num_open_handles--;	}	for (i=0;i<NSERVERS;i++) {		open_handles[h].smb2_handle[i] = handles[i];		open_handles[h].instance = instance;		open_handles[h].active = true;		open_handles[h].name = name;	}	num_open_handles++;	printf("OPEN num_open_handles=%d h=%d (%s)\n", 	       num_open_handles, h, name);}/*  add some newly opened handles*/static void gen_add_handle_smb(int instance, const char *name, uint16_t handles[NSERVERS]){	int i, h;	for (h=0;h<options.max_open_handles;h++) {		if (!open_handles[h].active) break;	}	if (h == options.max_open_handles) {		/* we have to force close a random handle */		h = random() % options.max_open_handles;		for (i=0;i<NSERVERS;i++) {			NTSTATUS status;			status = smbcli_close(servers[i].smb_tree[open_handles[h].instance], 					      open_handles[h].smb_handle[i]);			if (NT_STATUS_IS_ERR(status)) {				printf("INTERNAL ERROR: Close failed when recovering handle! - %s\n",				       nt_errstr(status));			}		}		printf("Recovered handle %d\n", h);		num_open_handles--;	}	for (i=0;i<NSERVERS;i++) {		open_handles[h].smb_handle[i] = handles[i];		open_handles[h].instance = instance;		open_handles[h].active = true;		open_handles[h].name = name;	}	num_open_handles++;	printf("OPEN num_open_handles=%d h=%d (%s)\n", 	       num_open_handles, h, name);}/*  remove a closed handle*/static void gen_remove_handle_smb2(int instance, struct smb2_handle handles[NSERVERS]){	int h;	for (h=0;h<options.max_open_handles;h++) {		if (instance == open_handles[h].instance &&		    smb2_handle_equal(&open_handles[h].smb2_handle[0], &handles[0])) {			open_handles[h].active = false;						num_open_handles--;			printf("CLOSE num_open_handles=%d h=%d (%s)\n", 			       num_open_handles, h, 			       open_handles[h].name);			return;		}	}	printf("Removing invalid handle!?\n");	exit(1);}/*  remove a closed handle*/static void gen_remove_handle_smb(int instance, uint16_t handles[NSERVERS]){	int h;	for (h=0;h<options.max_open_handles;h++) {		if (instance == open_handles[h].instance &&		    open_handles[h].smb_handle[0] == handles[0]) {			open_handles[h].active = false;						num_open_handles--;			printf("CLOSE num_open_handles=%d h=%d (%s)\n", 			       num_open_handles, h, 			       open_handles[h].name);			return;		}	}	printf("Removing invalid handle!?\n");	exit(1);}/*  return true with 'chance' probability as a percentage*/static bool gen_chance(uint_t chance){	return ((random() % 100) <= chance);}/*  map an internal handle number to a server handle*/static struct smb2_handle gen_lookup_handle_smb2(int server, uint16_t handle){	if (handle == BAD_HANDLE) return bad_smb2_handle;	return open_handles[handle].smb2_handle[server];}/*  map an internal handle number to a server handle*/static uint16_t gen_lookup_handle_smb(int server, uint16_t handle){	if (handle == BAD_HANDLE) return BAD_HANDLE;	return open_handles[handle].smb_handle[server];}/*  return a file handle*/static uint16_t gen_fnum(int instance){	uint16_t h;	int count = 0;	if (gen_chance(20)) return BAD_HANDLE;	while (num_open_handles > 0 && count++ < 10*options.max_open_handles) {		h = random() % options.max_open_handles;		if (open_handles[h].active && 		    open_handles[h].instance == instance) {			return h;		}	}	return BAD_HANDLE;}/*  return a file handle, but skewed so we don't close the last  couple of handles too readily*/static uint16_t gen_fnum_close(int instance){	if (num_open_handles < 5) {		if (gen_chance(90)) return BAD_HANDLE;	}	return gen_fnum(instance);}/*  generate an integer in a specified range*/

⌨️ 快捷键说明

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