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

📄 misc.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   SMB torture tester   Copyright (C) Andrew Tridgell 1997-2003   Copyright (C) Jelmer Vernooij 2006      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/raw/raw_proto.h"#include "system/time.h"#include "system/wait.h"#include "system/filesys.h"#include "libcli/raw/ioctl.h"#include "libcli/libcli.h"#include "lib/events/events.h"#include "libcli/resolve/resolve.h"#include "auth/credentials/credentials.h"#include "librpc/gen_ndr/ndr_nbt.h"#include "torture/smbtorture.h"#include "torture/util.h"#include "libcli/smb_composite/smb_composite.h"#include "libcli/composite/composite.h"#include "param/param.h"extern struct cli_credentials *cmdline_credentials;	static bool wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len){	while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {		if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return false;	}	return true;}static bool rw_torture(struct torture_context *tctx, struct smbcli_state *c){	const char *lockfname = "\\torture.lck";	char *fname;	int fnum;	int fnum2;	pid_t pid2, pid = getpid();	int i, j;	uint8_t buf[1024];	bool correct = true;	fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL, 			 DENY_NONE);	if (fnum2 == -1)		fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);	if (fnum2 == -1) {		torture_comment(tctx, "open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));		return false;	}	generate_random_buffer(buf, sizeof(buf));	for (i=0;i<torture_numops;i++) {		uint_t n = (uint_t)random()%10;		if (i % 10 == 0) {			if (torture_setting_bool(tctx, "progress", true)) {				torture_comment(tctx, "%d\r", i);				fflush(stdout);			}		}		asprintf(&fname, "\\torture.%u", n);		if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {			return false;		}		fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);		if (fnum == -1) {			torture_comment(tctx, "open failed (%s)\n", smbcli_errstr(c->tree));			correct = false;			break;		}		if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {			torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));			correct = false;		}		for (j=0;j<50;j++) {			if (smbcli_write(c->tree, fnum, 0, buf, 				      sizeof(pid)+(j*sizeof(buf)), 				      sizeof(buf)) != sizeof(buf)) {				torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));				correct = false;			}		}		pid2 = 0;		if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {			torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c->tree));			correct = false;		}		if (pid2 != pid) {			torture_comment(tctx, "data corruption!\n");			correct = false;		}		if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {			torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(c->tree));			correct = false;		}		if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {			torture_comment(tctx, "unlink failed (%s)\n", smbcli_errstr(c->tree));			correct = false;		}		if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {			torture_comment(tctx, "unlock failed (%s)\n", smbcli_errstr(c->tree));			correct = false;		}		free(fname);	}	smbcli_close(c->tree, fnum2);	smbcli_unlink(c->tree, lockfname);	torture_comment(tctx, "%d\n", i);	return correct;}bool run_torture(struct torture_context *tctx, struct smbcli_state *cli, int dummy){	return rw_torture(tctx, cli);}/*  see how many RPC pipes we can open at once*/bool run_pipe_number(struct torture_context *tctx, 					 struct smbcli_state *cli1){	const char *pipe_name = "\\WKSSVC";	int fnum;	int num_pipes = 0;	while(1) {		fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,				   NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);		if (fnum == -1) {			torture_comment(tctx, "Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));			break;		}		num_pipes++;		if (torture_setting_bool(tctx, "progress", true)) {			torture_comment(tctx, "%d\r", num_pipes);			fflush(stdout);		}	}	torture_comment(tctx, "pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );	return true;}/*  open N connections to the server and just hold them open  used for testing performance when there are N idle users  already connected */bool torture_holdcon(struct torture_context *tctx){	int i;	struct smbcli_state **cli;	int num_dead = 0;	torture_comment(tctx, "Opening %d connections\n", torture_numops);		cli = malloc_array_p(struct smbcli_state *, torture_numops);	for (i=0;i<torture_numops;i++) {		if (!torture_open_connection(&cli[i], tctx, i)) {			return false;		}		if (torture_setting_bool(tctx, "progress", true)) {			torture_comment(tctx, "opened %d connections\r", i);			fflush(stdout);		}	}	torture_comment(tctx, "\nStarting pings\n");	while (1) {		for (i=0;i<torture_numops;i++) {			NTSTATUS status;			if (cli[i]) {				status = smbcli_chkpath(cli[i]->tree, "\\");				if (!NT_STATUS_IS_OK(status)) {					torture_comment(tctx, "Connection %d is dead\n", i);					cli[i] = NULL;					num_dead++;				}				usleep(100);			}		}		if (num_dead == torture_numops) {			torture_comment(tctx, "All connections dead - finishing\n");			break;		}		torture_comment(tctx, ".");		fflush(stdout);	}	return true;}/*test how many open files this server supports on the one socket*/bool run_maxfidtest(struct torture_context *tctx, struct smbcli_state *cli, int dummy){#define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"	char *fname;	int fnums[0x11000], i;	int retries=4, maxfid;	bool correct = true;	if (retries <= 0) {		torture_comment(tctx, "failed to connect\n");		return false;	}	if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {		torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",		       smbcli_errstr(cli->tree));		return false;	}	if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {		torture_comment(tctx, "Failed to mkdir \\maxfid, error=%s\n", 		       smbcli_errstr(cli->tree));		return false;	}	torture_comment(tctx, "Testing maximum number of open files\n");	for (i=0; i<0x11000; i++) {		if (i % 1000 == 0) {			asprintf(&fname, "\\maxfid\\fid%d", i/1000);			if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {				torture_comment(tctx, "Failed to mkdir %s, error=%s\n", 				       fname, smbcli_errstr(cli->tree));				return false;			}			free(fname);		}		asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());		if ((fnums[i] = smbcli_open(cli->tree, fname, 					O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==		    -1) {			torture_comment(tctx, "open of %s failed (%s)\n", 			       fname, smbcli_errstr(cli->tree));			torture_comment(tctx, "maximum fnum is %d\n", i);			break;		}		free(fname);		if (torture_setting_bool(tctx, "progress", true)) {			torture_comment(tctx, "%6d\r", i);			fflush(stdout);		}	}	torture_comment(tctx, "%6d\n", i);	i--;	maxfid = i;	torture_comment(tctx, "cleaning up\n");	for (i=0;i<maxfid/2;i++) {		asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());		if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {			torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));		}		if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {			torture_comment(tctx, "unlink of %s failed (%s)\n", 			       fname, smbcli_errstr(cli->tree));			correct = false;		}		free(fname);		asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());		if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {			torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));		}		if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {			torture_comment(tctx, "unlink of %s failed (%s)\n", 			       fname, smbcli_errstr(cli->tree));			correct = false;		}		free(fname);		if (torture_setting_bool(tctx, "progress", true)) {			torture_comment(tctx, "%6d %6d\r", i, maxfid-i);			fflush(stdout);		}	}	torture_comment(tctx, "%6d\n", 0);	if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {		torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",		       smbcli_errstr(cli->tree));		return false;	}	torture_comment(tctx, "maxfid test finished\n");	if (!torture_close_connection(cli)) {		correct = false;	}	return correct;#undef MAXFID_TEMPLATE}/*  sees what IOCTLs are supported */bool torture_ioctl_test(struct torture_context *tctx, 						struct smbcli_state *cli){	uint16_t device, function;	int fnum;	const char *fname = "\\ioctl.dat";	NTSTATUS status;	union smb_ioctl parms;	TALLOC_CTX *mem_ctx;	mem_ctx = talloc_named_const(tctx, 0, "ioctl_test");	smbcli_unlink(cli->tree, fname);	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);	if (fnum == -1) {		torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));		return false;	}	parms.ioctl.level = RAW_IOCTL_IOCTL;	parms.ioctl.in.file.fnum = fnum;	parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;	status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);	torture_comment(tctx, "ioctl job info: %s\n", smbcli_errstr(cli->tree));	for (device=0;device<0x100;device++) {		torture_comment(tctx, "testing device=0x%x\n", device);		for (function=0;function<0x100;function++) {			parms.ioctl.in.request = (device << 16) | function;			status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);			if (NT_STATUS_IS_OK(status)) {				torture_comment(tctx, "ioctl device=0x%x function=0x%x OK : %d bytes\n", 					device, function, (int)parms.ioctl.out.blob.length);			}		}	}	return true;}static void benchrw_callback(struct smbcli_request *req);enum benchrw_stage {	START,	OPEN_CONNECTION,	CLEANUP_TESTDIR,	MK_TESTDIR,	OPEN_FILE,	INITIAL_WRITE,	READ_WRITE_DATA,	MAX_OPS_REACHED,	ERROR,	CLOSE_FILE,	CLEANUP,	FINISHED};struct benchrw_state {	struct torture_context *tctx;	char *dname;	char *fname;	uint16_t fnum;	int nr;	struct smbcli_tree	*cli;			uint8_t *buffer;	int writecnt;	int readcnt;	int completed;	int num_parallel_requests;	void *req_params;	enum benchrw_stage mode;	struct params{		struct unclist{			const char *host;			const char *share;		} **unc;		const char *workgroup;		int retry;		unsigned int writeblocks;		unsigned int blocksize;		unsigned int writeratio;		int num_parallel_requests;	} *lp_params;};/*  	init params using lp_parm_xxx  	return number of unclist entries*/static int init_benchrw_params(struct torture_context *tctx,			       struct params *lpar){	char **unc_list = NULL;	int num_unc_names = 0, conn_index=0, empty_lines=0;	const char *p;	lpar->retry = torture_setting_int(tctx, "retry",3);	lpar->blocksize = torture_setting_int(tctx, "blocksize",65535);	lpar->writeblocks = torture_setting_int(tctx, "writeblocks",15);	lpar->writeratio = torture_setting_int(tctx, "writeratio",5);	lpar->num_parallel_requests = torture_setting_int(		tctx, "parallel_requests", 5);	lpar->workgroup = lp_workgroup(tctx->lp_ctx);		p = torture_setting_string(tctx, "unclist", NULL);	if (p) {		char *h, *s;		unc_list = file_lines_load(p, &num_unc_names, NULL);		if (!unc_list || num_unc_names <= 0) {			torture_comment(tctx, "Failed to load unc names list "					"from '%s'\n", p);			exit(1);		}				lpar->unc = talloc_array(tctx, struct unclist *,					 (num_unc_names-empty_lines));		for(conn_index = 0; conn_index < num_unc_names; conn_index++) {			/* ignore empty lines */			if(strlen(unc_list[conn_index % num_unc_names])==0){				empty_lines++;				continue;			}			if (!smbcli_parse_unc(				    unc_list[conn_index % num_unc_names],				    NULL, &h, &s)) {				torture_comment(					tctx, "Failed to parse UNC "					"name %s\n",					unc_list[conn_index % num_unc_names]);				exit(1);

⌨️ 快捷键说明

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