Example #1
0
/** 
 * The challenge from the target server, when operating in security=server
 **/
static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
{
	struct smb_composite_connect io;
	struct smbcli_options smb_options;
	const char **host_list;
	NTSTATUS status;

	/* Make a connection to the target server, found by 'password server' in smb.conf */
	
	lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);

	/* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */
	io.in.options.use_spnego = false;

	/* Hope we don't get * (the default), as this won't work... */
	host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx); 
	if (!host_list) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	io.in.dest_host = host_list[0];
	if (strequal(io.in.dest_host, "*")) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx); 
	io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx);
	io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);

	io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host);

	/* We don't want to get as far as the session setup */
	io.in.credentials = cli_credentials_init_anon(mem_ctx);
	cli_credentials_set_workstation(io.in.credentials,
					lp_netbios_name(ctx->auth_ctx->lp_ctx),
					CRED_SPECIFIED);

	io.in.service = NULL;

	io.in.workgroup = ""; /* only used with SPNEGO, disabled above */

	io.in.options = smb_options;
	
	io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx);
	lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);

	status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx),
				       ctx->auth_ctx->event_ctx);
	NT_STATUS_NOT_OK_RETURN(status);

	if (io.out.tree->session->transport->negotiate.secblob.length != 8) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8);
	ctx->private_data = talloc_steal(ctx, io.out.tree->session);
	return NT_STATUS_OK;
}
Example #2
0
NTSTATUS svc_UploadService(const char *hostname,
			   struct cli_credentials * credentials, int flags)
{
	struct smb_composite_savefile *io;
	struct smbcli_state *cli;
	NTSTATUS status;
	struct smbcli_options options;
	struct smbcli_session_options session_options;

	lp_smbcli_options(cmdline_lp_ctx, &options);
	lp_smbcli_session_options(cmdline_lp_ctx, &session_options);

	status =
	    smbcli_full_connection(NULL, &cli, hostname, lp_smb_ports(cmdline_lp_ctx), "ADMIN$", NULL,
				   lp_socket_options(cmdline_lp_ctx), credentials, lp_resolve_context(cmdline_lp_ctx), ev_ctx, &options, &session_options, lp_iconv_convenience(cmdline_lp_ctx), lp_gensec_settings(NULL, cmdline_lp_ctx));
	NT_ERR(status, 1, "Failed to open ADMIN$ share");
	if (flags & SVC_FORCE_UPLOAD) {
		smbcli_unlink(cli->tree, "winexesvc.exe");
	} else {
		int fd = smbcli_open(cli->tree, "winexesvc.exe", O_RDONLY, DENY_NONE);
		if (fd >= 0) {
			smbcli_close(cli->tree, fd);
			return status;
		}
	}
	io = talloc_zero(cli->tree, struct smb_composite_savefile);
	io->in.fname = "winexesvc.exe";
	if (flags & SVC_OSCHOOSE) {
	    status = smbcli_chkpath(cli->tree, "SysWoW64");
	}
	if ((flags & SVC_OSCHOOSE && NT_STATUS_IS_OK(status)) || (flags & SVC_OS64BIT)) {
		DEBUG(1, ("svc_UploadService: Installing 64bit winexesvc.exe\n"));
		io->in.data = winexesvc64_exe;
		io->in.size = winexesvc64_exe_len;
	} else {
		DEBUG(1, ("svc_UploadService: Installing 32bit winexesvc.exe\n"));
		io->in.data = winexesvc32_exe;
		io->in.size = winexesvc32_exe_len;
	}
	status = smb_composite_savefile(cli->tree, io);
	NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname);
	talloc_free(io);
	smbcli_tdis(cli);
	return status;
}
Example #3
0
/***************************************************** 
return a connection to a server
*******************************************************/
static struct smbcli_state *connect_one(struct tevent_context *ev,
					struct loadparm_context *lp_ctx,
					TALLOC_CTX *mem_ctx,
					char *share, int snum, int conn)
{
	struct smbcli_state *c;
	char *server, *myname;
	NTSTATUS status;
	int retries = 10;
	struct smbcli_options options;
	struct smbcli_session_options session_options;

	lp_smbcli_options(lp_ctx, &options);
	lp_smbcli_session_options(lp_ctx, &session_options);

	printf("connect_one(%s, %d, %d)\n", share, snum, conn);

	server = talloc_strdup(mem_ctx, share+2);
	share = strchr_m(server,'\\');
	if (!share) return NULL;
	*share = 0;
	share++;

	if (snum == 0) {
		char **unc_list = NULL;
		int num_unc_names;
		const char *p;
		p = lp_parm_string(lp_ctx, NULL, "torture", "unclist");
		if (p) {
			char *h, *s;
			unc_list = file_lines_load(p, &num_unc_names, 0, NULL);
			if (!unc_list || num_unc_names <= 0) {
				printf("Failed to load unc names list from '%s'\n", p);
				exit(1);
			}

			if (!smbcli_parse_unc(unc_list[conn % num_unc_names],
					      NULL, &h, &s)) {
				printf("Failed to parse UNC name %s\n",
				       unc_list[conn % num_unc_names]);
				exit(1);
			}
			server = talloc_strdup(mem_ctx, h);
			share = talloc_strdup(mem_ctx, s);
		}
	}


	myname = talloc_asprintf(mem_ctx, "lock-%u-%u", getpid(), snum);
	cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED);

	do {
		printf("\\\\%s\\%s\n", server, share);
		status = smbcli_full_connection(NULL, &c, 
						server, 
						lp_smb_ports(lp_ctx),
						share, NULL,
						lp_socket_options(lp_ctx),
						servers[snum], 
						lp_resolve_context(lp_ctx),
						ev, &options, &session_options,
						lp_iconv_convenience(lp_ctx),
						lp_gensec_settings(mem_ctx, lp_ctx));
		if (!NT_STATUS_IS_OK(status)) {
			sleep(2);
		}
	} while (!NT_STATUS_IS_OK(status) && retries--);

	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}

	return c;
}
Example #4
0
static int copy_files(struct tevent_context *ev, struct loadparm_context *lp_ctx)
{
	uint8_t *	iobuf;	/* IO buffer. */
	uint64_t	iomax;	/* Size of the IO buffer. */
	uint64_t	data_size; /* Amount of data in the IO buffer. */

	uint64_t	ibs;
	uint64_t	obs;
	uint64_t	count;

	struct dd_iohandle *	ifile;
	struct dd_iohandle *	ofile;

	struct smbcli_options options;
	struct smbcli_session_options session_options;

	ibs = check_arg_numeric("ibs");
	obs = check_arg_numeric("obs");
	count = check_arg_numeric("count");

	lp_smbcli_options(lp_ctx, &options);
	lp_smbcli_session_options(lp_ctx, &session_options);

	/* Allocate IO buffer. We need more than the max IO size because we
	 * could accumulate a remainder if ibs and obs don't match.
	 */
	iomax = 2 * MAX(ibs, obs);
	if ((iobuf = malloc_array_p(uint8_t, iomax)) == NULL) {
		fprintf(stderr,
			"%s: failed to allocate IO buffer of %llu bytes\n",
			PROGNAME, (unsigned long long)iomax);
		return(EOM_EXIT_CODE);
	}

	options.max_xmit = MAX(ibs, obs);

	DEBUG(4, ("IO buffer size is %llu, max xmit is %d\n",
			(unsigned long long)iomax, options.max_xmit));

	if (!(ifile = open_file(lp_resolve_context(lp_ctx), ev, "if",
				lp_smb_ports(lp_ctx), &options,
				lp_socket_options(lp_ctx),
				&session_options, lp_iconv_convenience(lp_ctx),
				lp_gensec_settings(lp_ctx, lp_ctx)))) {
		return(FILESYS_EXIT_CODE);
	}

	if (!(ofile = open_file(lp_resolve_context(lp_ctx), ev, "of",
				lp_smb_ports(lp_ctx), &options,
				lp_socket_options(lp_ctx),
				&session_options,
				lp_iconv_convenience(lp_ctx),
				lp_gensec_settings(lp_ctx, lp_ctx)))) {
		return(FILESYS_EXIT_CODE);
	}

	/* Seek the files to their respective starting points. */
	ifile->io_seek(ifile, check_arg_numeric("skip") * ibs);
	ofile->io_seek(ofile, check_arg_numeric("seek") * obs);

	DEBUG(4, ("max xmit was negotiated to be %d\n", options.max_xmit));

	for (data_size = 0;;) {

		/* Handle signals. We are somewhat compatible with GNU dd.
		 * SIGINT makes us stop, but still print transfer statistics.
		 * SIGUSR1 makes us print transfer statistics but we continue
		 * copying.
		 */
		if (dd_sigint) {
			break;
		}

		if (dd_sigusr1) {
			print_transfer_stats();
			dd_sigusr1 = 0;
		}

		if (ifile->io_flags & DD_END_OF_FILE) {
			DEBUG(4, ("flushing %llu bytes at EOF\n",
					(unsigned long long)data_size));
			while (data_size > 0) {
				if (!dd_flush_block(ofile, iobuf,
							&data_size, obs)) {
					return(IOERROR_EXIT_CODE);
				}
			}
			goto done;
		}

		/* Try and read enough blocks of ibs bytes to be able write
		 * out one of obs bytes.
		 */
		if (!dd_fill_block(ifile, iobuf, &data_size, obs, ibs)) {
			return(IOERROR_EXIT_CODE);
		}

		if (data_size == 0) {
			/* Done. */
			SMB_ASSERT(ifile->io_flags & DD_END_OF_FILE);
		}

		/* Stop reading when we hit the block count. */
		if (dd_stats.in.bytes >= (ibs * count)) {
			ifile->io_flags |= DD_END_OF_FILE;
		}

		/* If we wanted to be a legitimate dd, we would do character
		 * conversions and other shenanigans here.
		 */

		/* Flush what we read in units of obs bytes. We want to have
		 * at least obs bytes in the IO buffer but might not if the
		 * file is too small.
		 */
		if (data_size && 
		    !dd_flush_block(ofile, iobuf, &data_size, obs)) {
			return(IOERROR_EXIT_CODE);
		}
	}

done:
	print_transfer_stats();
	return(0);
}
Example #5
0
static int fork_tcon_client(struct torture_context *tctx,
		int *tcon_count, unsigned tcon_timelimit,
		const char *host, const char *share)
{
	pid_t child;
	struct smbcli_state *cli;
	struct timeval end;
	struct timeval now;
	struct smbcli_options options;
	struct smbcli_session_options session_options;

	lp_smbcli_options(tctx->lp_ctx, &options);
	lp_smbcli_session_options(tctx->lp_ctx, &session_options);

	child = fork();
	if (child == -1) {
		printf("failed to fork child: %s\n,", strerror(errno));
		return -1;
	} else if (child != 0) {
		/* Parent, just return. */
		return 0;
	}

	/* Child. Just make as many connections as possible within the
	 * time limit. Don't bother synchronising the child start times
	 * because it's probably not work the effort, and a bit of startup
	 * jitter is probably a more realistic test.
	 */


	end = timeval_current();
	now = timeval_current();
	end.tv_sec += tcon_timelimit;
	*tcon_count = 0;

	while (timeval_compare(&now, &end) == -1) {
		NTSTATUS status;

		status = smbcli_full_connection(NULL, &cli,
				host, lp_smb_ports(tctx->lp_ctx), share,
				NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials,
				lp_resolve_context(tctx->lp_ctx),
				tctx->ev, &options, &session_options,
				lp_iconv_convenience(tctx->lp_ctx),
				lp_gensec_settings(tctx, tctx->lp_ctx));

		if (!NT_STATUS_IS_OK(status)) {
			printf("failed to connect to //%s/%s: %s\n",
				host, share, nt_errstr(status));
			goto done;
		}

		smbcli_tdis(cli);
		talloc_free(cli);

		*tcon_count = *tcon_count + 1;
		now = timeval_current();
	}

done:
	exit(0);
}
Example #6
0
NTSTATUS svc_uninstall(const char *hostname,
		       struct cli_credentials * credentials)
{
	NTSTATUS status;
	struct dcerpc_pipe *svc_pipe;
	struct policy_handle scm_handle;
	struct policy_handle svc_handle;
	struct SERVICE_STATUS svc_status;
	struct smbcli_options options;
	struct smbcli_session_options session_options;

	lp_smbcli_options(cmdline_lp_ctx, &options);
	lp_smbcli_session_options(cmdline_lp_ctx, &session_options);

	status = svc_pipe_connect(&svc_pipe, hostname, credentials);
	NT_ERR(status, 1, "Cannot connect to svcctl pipe");
	status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle);
	NT_ERR(status, 1, "OpenSCManager failed");
	status =
	    svc_OpenService(svc_pipe, &scm_handle, "winexesvc",
			    &svc_handle);
	NT_ERR(status, 1, "OpenService failed");
	DEBUG(1, ("OpenService - %s\n", nt_errstr(status)));
	if (NT_STATUS_IS_OK(status)) {
		status =
		    svc_ControlService(svc_pipe, &svc_handle,
				       SERVICE_CONTROL_STOP, &svc_status);
		{
			struct SERVICE_STATUS s;
			do {
				msleep(100);
				status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s);
				NT_ERR(status, 1, "QueryServiceStatus failed");
			} while (s.state == SVCCTL_STOP_PENDING);
			if (s.state != SVCCTL_STOPPED) {
				DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state));
				return NT_STATUS_UNSUCCESSFUL;
			}
		}
		DEBUG(1, ("StopService - %s\n", nt_errstr(status)));
		status = svc_DeleteService(svc_pipe, &svc_handle);
		DEBUG(1, ("DeleteService - %s\n", nt_errstr(status)));
		status = svc_CloseServiceHandle(svc_pipe, &svc_handle);
		DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status)));
	}
	svc_CloseServiceHandle(svc_pipe, &scm_handle);
	DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status)));

	struct smbcli_state *cli;
	status =
	    smbcli_full_connection(NULL, &cli, hostname, lp_smb_ports(cmdline_lp_ctx), "ADMIN$", NULL,
				   lp_socket_options(cmdline_lp_ctx), credentials, lp_resolve_context(cmdline_lp_ctx), ev_ctx, &options, &session_options, lp_iconv_convenience(cmdline_lp_ctx), lp_gensec_settings(NULL, cmdline_lp_ctx));
	NT_ERR(status, 1, "Failed to open ADMIN$ share");
	/* Give winexesvc some time to exit */
	msleep(300);
	status = smbcli_unlink(cli->tree, "winexesvc.exe");
	DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status)));
	status = smbcli_tdis(cli);
	DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status)));
	return status;
}
Example #7
0
/*
  test a simple savefile/loadfile combination
*/
static bool test_fetchfile(struct smbcli_state *cli, struct torture_context *tctx)
{
	const char *fname = BASEDIR "\\test.txt";
	NTSTATUS status;
	struct smb_composite_savefile io1;
	struct smb_composite_fetchfile io2;
	struct composite_context **c;
	uint8_t *data;
	int i;
	size_t len = random() % 10000;
	extern int torture_numops;
	struct tevent_context *event_ctx;
	int *count = talloc_zero(tctx, int);
	bool ret = true;

	data = talloc_array(tctx, uint8_t, len);

	generate_random_buffer(data, len);

	io1.in.fname = fname;
	io1.in.data  = data;
	io1.in.size  = len;

	printf("testing savefile\n");

	status = smb_composite_savefile(cli->tree, &io1);
	if (!NT_STATUS_IS_OK(status)) {
		printf("(%s) savefile failed: %s\n",__location__, nt_errstr(status));
		return false;
	}

	io2.in.dest_host = torture_setting_string(tctx, "host", NULL);
	io2.in.ports = lp_smb_ports(tctx->lp_ctx);
	io2.in.called_name = torture_setting_string(tctx, "host", NULL);
	io2.in.service = torture_setting_string(tctx, "share", NULL);
	io2.in.service_type = "A:";

	io2.in.credentials = cmdline_credentials;
	io2.in.workgroup  = lp_workgroup(tctx->lp_ctx);
	io2.in.filename = fname;
	io2.in.resolve_ctx = lp_resolve_context(tctx->lp_ctx);
	io2.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
	io2.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
	lp_smbcli_options(tctx->lp_ctx, &io2.in.options);
	lp_smbcli_session_options(tctx->lp_ctx, &io2.in.session_options);

	printf("testing parallel fetchfile with %d ops\n", torture_numops);

	event_ctx = cli->transport->socket->event.ctx;
	c = talloc_array(tctx, struct composite_context *, torture_numops);

	for (i=0; i<torture_numops; i++) {
		c[i] = smb_composite_fetchfile_send(&io2, event_ctx);
		c[i]->async.fn = loadfile_complete;
		c[i]->async.private_data = count;
	}

	printf("waiting for completion\n");

	while (*count != torture_numops) {
		event_loop_once(event_ctx);
		if (torture_setting_bool(tctx, "progress", true)) {
			printf("(%s) count=%d\r", __location__, *count);
			fflush(stdout);
		}
	}
	printf("count=%d\n", *count);

	for (i=0;i<torture_numops;i++) {
		status = smb_composite_fetchfile_recv(c[i], tctx);
		if (!NT_STATUS_IS_OK(status)) {
			printf("(%s) loadfile[%d] failed - %s\n", __location__, i,
			       nt_errstr(status));
			ret = false;
			continue;
		}

		if (io2.out.size != len) {
			printf("(%s) wrong length in returned data - %d "
			       "should be %d\n", __location__,
			       io2.out.size, (int)len);
			ret = false;
			continue;
		}
		
		if (memcmp(io2.out.data, data, len) != 0) {
			printf("(%s) wrong data in loadfile!\n", __location__);
			ret = false;
			continue;
		}
	}

	return ret;
}