Ejemplo n.º 1
0
static bool try_failed_login(struct torture_context *tctx, struct smbcli_state *cli)
{
	NTSTATUS status;
	struct smb_composite_sesssetup setup;
	struct smbcli_session *session;
	struct smbcli_session_options options;

	lp_smbcli_session_options(tctx->lp_ctx, &options);

	session = smbcli_session_init(cli->transport, cli, false, options);
	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities;
	setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
	setup.in.credentials = cli_credentials_init(session);
	setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);

	cli_credentials_set_conf(setup.in.credentials, tctx->lp_ctx);
	cli_credentials_set_domain(setup.in.credentials, "INVALID-DOMAIN", CRED_SPECIFIED);
	cli_credentials_set_username(setup.in.credentials, "INVALID-USERNAME", CRED_SPECIFIED);
	cli_credentials_set_password(setup.in.credentials, "INVALID-PASSWORD", CRED_SPECIFIED);

	status = smb_composite_sesssetup(session, &setup);
	talloc_free(session);
	if (NT_STATUS_IS_OK(status)) {
		printf("Allowed session setup with invalid credentials?!\n");
		return false;
	}

	return true;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 6
0
static NTSTATUS server_check_password(struct auth_method_context *ctx,
				      TALLOC_CTX *mem_ctx,
				      const struct auth_usersupplied_info *user_info, 
				      struct auth_serversupplied_info **_server_info)
{
	NTSTATUS nt_status;
	struct auth_serversupplied_info *server_info;
	struct cli_credentials *creds;
	struct smb_composite_sesssetup session_setup;

	struct smbcli_session *session = talloc_get_type(ctx->private_data, struct smbcli_session);

	creds = cli_credentials_init(mem_ctx);

	NT_STATUS_HAVE_NO_MEMORY(creds);
	
	cli_credentials_set_username(creds, user_info->client.account_name, CRED_SPECIFIED);
	cli_credentials_set_domain(creds, user_info->client.domain_name, CRED_SPECIFIED);

	switch (user_info->password_state) {
	case AUTH_PASSWORD_PLAIN:
		cli_credentials_set_password(creds, user_info->password.plaintext, 
					     CRED_SPECIFIED);
		break;
	case AUTH_PASSWORD_HASH:
		cli_credentials_set_nt_hash(creds, user_info->password.hash.nt,
					    CRED_SPECIFIED);
		break;
		
	case AUTH_PASSWORD_RESPONSE:
		cli_credentials_set_ntlm_response(creds, &user_info->password.response.lanman, &user_info->password.response.nt, CRED_SPECIFIED);
		break;
	}

	session_setup.in.sesskey = session->transport->negotiate.sesskey;
	session_setup.in.capabilities = session->transport->negotiate.capabilities;

	session_setup.in.credentials = creds;
	session_setup.in.workgroup = ""; /* Only used with SPNEGO, which we are not doing */
	session_setup.in.gensec_settings = lp_gensec_settings(session, ctx->auth_ctx->lp_ctx);

	/* Check password with remove server - this should be async some day */
	nt_status = smb_composite_sesssetup(session, &session_setup);

	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	server_info = talloc(mem_ctx, struct auth_serversupplied_info);
	NT_STATUS_HAVE_NO_MEMORY(server_info);

	server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
	NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);

	/* is this correct? */
	server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
	NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);

	server_info->n_domain_groups = 0;
	server_info->domain_groups = NULL;

	/* annoying, but the Anonymous really does have a session key, 
	   and it is all zeros! */
	server_info->user_session_key = data_blob(NULL, 0);
	server_info->lm_session_key = data_blob(NULL, 0);

	server_info->account_name = talloc_strdup(server_info, user_info->client.account_name);
	NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);

	server_info->domain_name = talloc_strdup(server_info, user_info->client.domain_name);
	NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);

	server_info->full_name = NULL;

	server_info->logon_script = talloc_strdup(server_info, "");
	NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);

	server_info->profile_path = talloc_strdup(server_info, "");
	NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);

	server_info->home_directory = talloc_strdup(server_info, "");
	NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);

	server_info->home_drive = talloc_strdup(server_info, "");
	NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);

	server_info->last_logon = 0;
	server_info->last_logoff = 0;
	server_info->acct_expiry = 0;
	server_info->last_password_change = 0;
	server_info->allow_password_change = 0;
	server_info->force_password_change = 0;

	server_info->logon_count = 0;
	server_info->bad_password_count = 0;

	server_info->acct_flags = ACB_NORMAL;

	server_info->authenticated = false;

	*_server_info = server_info;

	return nt_status;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
static bool torture_ntlmssp_self_check(struct torture_context *tctx)
{
	struct gensec_security *gensec_security;
	struct gensec_ntlmssp_state *gensec_ntlmssp_state;
	DATA_BLOB data;
	DATA_BLOB sig, expected_sig;
	TALLOC_CTX *mem_ctx = tctx;

	torture_assert_ntstatus_ok(tctx, 
		gensec_client_start(mem_ctx, &gensec_security,
				    tctx->ev, lp_gensec_settings(tctx, tctx->lp_ctx)),
		"gensec client start");

	gensec_set_credentials(gensec_security, cmdline_credentials);

	gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
	gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);

	torture_assert_ntstatus_ok(tctx, 
			gensec_start_mech_by_oid(gensec_security, GENSEC_OID_NTLMSSP),
			"Failed to start GENSEC for NTLMSSP");

	gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;

	gensec_ntlmssp_state->session_key = strhex_to_data_blob(tctx, "0102030405060708090a0b0c0d0e0f00");
	dump_data_pw("NTLMSSP session key: \n", 
		     gensec_ntlmssp_state->session_key.data,  
		     gensec_ntlmssp_state->session_key.length);

	gensec_ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_NEGOTIATE_NTLM2;

	torture_assert_ntstatus_ok(tctx,  
		ntlmssp_sign_init(gensec_ntlmssp_state),
		"Failed to sign_init");

	data = strhex_to_data_blob(tctx, "6a43494653");
	gensec_ntlmssp_sign_packet(gensec_security, gensec_security,
				   data.data, data.length, data.data, data.length, &sig);

	expected_sig = strhex_to_data_blob(tctx, "01000000e37f97f2544f4d7e00000000");

	dump_data_pw("NTLMSSP calc sig:     ", sig.data, sig.length);
	dump_data_pw("NTLMSSP expected sig: ", expected_sig.data, expected_sig.length);

	torture_assert_int_equal(tctx, sig.length, expected_sig.length, "Wrong sig length");

	torture_assert_mem_equal(tctx, sig.data, expected_sig.data, sig.length,
				   "data mismatch");

	torture_assert_ntstatus_equal(tctx, 
				      gensec_ntlmssp_check_packet(gensec_security, gensec_security,
								  data.data, data.length, data.data, data.length, &sig),
				      NT_STATUS_ACCESS_DENIED, "Check of just signed packet (should fail, wrong end)");

	gensec_ntlmssp_state->session_key = data_blob(NULL, 0);

	torture_assert_ntstatus_equal(tctx, 
				      gensec_ntlmssp_check_packet(gensec_security, gensec_security,
								  data.data, data.length, data.data, data.length, &sig),
				      NT_STATUS_NO_USER_SESSION_KEY, "Check of just signed packet without a session key should fail");

	talloc_free(gensec_security);

	torture_assert_ntstatus_ok(tctx, 
		gensec_client_start(mem_ctx, &gensec_security,
				    tctx->ev, lp_gensec_settings(tctx, tctx->lp_ctx)),
		"Failed to start GENSEC for NTLMSSP");

	gensec_set_credentials(gensec_security, cmdline_credentials);

	gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
	gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);

	torture_assert_ntstatus_ok(tctx, 
		gensec_start_mech_by_oid(gensec_security, GENSEC_OID_NTLMSSP),
		"GENSEC start mech by oid");

	gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;

	gensec_ntlmssp_state->session_key = strhex_to_data_blob(tctx, "0102030405e538b0");
	dump_data_pw("NTLMSSP session key: \n", 
		     gensec_ntlmssp_state->session_key.data,  
		     gensec_ntlmssp_state->session_key.length);

	gensec_ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_KEY_EXCH;

	torture_assert_ntstatus_ok(tctx,  
		ntlmssp_sign_init(gensec_ntlmssp_state),
		"Failed to sign_init");

	data = strhex_to_data_blob(tctx, "6a43494653");
	gensec_ntlmssp_sign_packet(gensec_security, gensec_security,
			    data.data, data.length, data.data, data.length, &sig);

	expected_sig = strhex_to_data_blob(tctx, "0100000078010900397420fe0e5a0f89");

	dump_data_pw("NTLMSSP calc sig:     ", sig.data, sig.length);
	dump_data_pw("NTLMSSP expected sig: ", expected_sig.data, expected_sig.length);

	torture_assert_int_equal(tctx, sig.length, expected_sig.length, "Wrong sig length");

	torture_assert_mem_equal(tctx, sig.data+8, expected_sig.data+8, sig.length-8,
				   "data mismatch");

	torture_assert_ntstatus_equal(tctx, 
				      gensec_ntlmssp_check_packet(gensec_security, gensec_security,
								  data.data, data.length, data.data, data.length, &sig),
				      NT_STATUS_ACCESS_DENIED, "Check of just signed packet (should fail, wrong end)");

	sig.length /= 2;

	torture_assert_ntstatus_equal(tctx, 
				      gensec_ntlmssp_check_packet(gensec_security, gensec_security,
								  data.data, data.length, data.data, data.length, &sig),
				      NT_STATUS_ACCESS_DENIED, "Check of just signed packet with short sig");

	talloc_free(gensec_security);
	return true;
}
Ejemplo n.º 10
0
static bool test_PACVerify(struct torture_context *tctx,
                           struct dcerpc_pipe *p,
                           struct cli_credentials *credentials)
{
    NTSTATUS status;

    struct netr_LogonSamLogon r;

    union netr_LogonLevel logon;
    union netr_Validation validation;
    uint8_t authoritative;
    struct netr_Authenticator return_authenticator;

    struct netr_GenericInfo generic;
    struct netr_Authenticator auth, auth2;


    struct netlogon_creds_CredentialState *creds;
    struct gensec_security *gensec_client_context;
    struct gensec_security *gensec_server_context;

    DATA_BLOB client_to_server, server_to_client, pac_wrapped, payload;
    struct PAC_Validate pac_wrapped_struct;

    enum ndr_err_code ndr_err;

    struct auth_session_info *session_info;

    char *tmp_dir;

    TALLOC_CTX *tmp_ctx = talloc_new(tctx);

    torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed");

    if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
                                credentials, SEC_CHAN_BDC,
                                &creds)) {
        return false;
    }

    status = torture_temp_dir(tctx, "PACVerify", &tmp_dir);
    torture_assert_ntstatus_ok(tctx, status, "torture_temp_dir failed");

    status = gensec_client_start(tctx, &gensec_client_context, tctx->ev,
                                 lp_gensec_settings(tctx, tctx->lp_ctx));
    torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");

    status = gensec_set_target_hostname(gensec_client_context, TEST_MACHINE_NAME);

    status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
    torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");

    status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI");
    torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");

    status = gensec_server_start(tctx, tctx->ev,
                                 lp_gensec_settings(tctx, tctx->lp_ctx),
                                 NULL, &gensec_server_context);
    torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed");

    status = gensec_set_credentials(gensec_server_context, credentials);
    torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed");

    status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI");
    torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed");

    server_to_client = data_blob(NULL, 0);

    do {
        /* Do a client-server update dance */
        status = gensec_update(gensec_client_context, tmp_ctx, server_to_client, &client_to_server);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
            ;
            torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
        }

        status = gensec_update(gensec_server_context, tmp_ctx, client_to_server, &server_to_client);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
            ;
            torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
        }

        if (NT_STATUS_IS_OK(status)) {
            break;
        }
    } while (1);

    /* Extract the PAC using Samba's code */

    status = gensec_session_info(gensec_server_context, &session_info);
    torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");

    pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
    pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
    pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;
    pac_wrapped_struct.ChecksumAndSignature = payload
            = data_blob_talloc(tmp_ctx, NULL,
                               pac_wrapped_struct.ChecksumLength
                               + pac_wrapped_struct.SignatureLength);
    memcpy(&payload.data[0],
           session_info->server_info->pac_srv_sig.signature.data,
           pac_wrapped_struct.ChecksumLength);
    memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
           session_info->server_info->pac_kdc_sig.signature.data,
           pac_wrapped_struct.SignatureLength);

    ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_wrapped_struct,
                                   (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
    torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");

    torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
    netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);

    generic.length = pac_wrapped.length;
    generic.data = pac_wrapped.data;

    /* Validate it over the netlogon pipe */

    generic.identity_info.parameter_control = 0;
    generic.identity_info.logon_id_high = 0;
    generic.identity_info.logon_id_low = 0;
    generic.identity_info.domain_name.string = session_info->server_info->domain_name;
    generic.identity_info.account_name.string = session_info->server_info->account_name;
    generic.identity_info.workstation.string = TEST_MACHINE_NAME;

    generic.package_name.string = "Kerberos";

    logon.generic = &generic;

    ZERO_STRUCT(auth2);
    netlogon_creds_client_authenticator(creds, &auth);
    r.in.credential = &auth;
    r.in.return_authenticator = &auth2;
    r.in.logon = &logon;
    r.in.logon_level = NetlogonGenericInformation;
    r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    r.in.computer_name = cli_credentials_get_workstation(credentials);
    r.in.validation_level = NetlogonValidationGenericInfo2;
    r.out.validation = &validation;
    r.out.authoritative = &authoritative;
    r.out.return_authenticator = &return_authenticator;

    status = dcerpc_netr_LogonSamLogon(p, tctx, &r);

    torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");

    /* This will break the signature nicely (even in the crypto wrapping), check we get a logon failure */
    generic.data[generic.length-1]++;

    logon.generic = &generic;

    ZERO_STRUCT(auth2);
    netlogon_creds_client_authenticator(creds, &auth);
    r.in.credential = &auth;
    r.in.return_authenticator = &auth2;
    r.in.logon_level = NetlogonGenericInformation;
    r.in.logon = &logon;
    r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    r.in.computer_name = cli_credentials_get_workstation(credentials);
    r.in.validation_level = NetlogonValidationGenericInfo2;

    status = dcerpc_netr_LogonSamLogon(p, tctx, &r);

    torture_assert_ntstatus_equal(tctx, status, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed");

    torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
                   "Credential chaining failed");

    /* This will break the parsing nicely (even in the crypto wrapping), check we get INVALID_PARAMETER */
    generic.length--;

    logon.generic = &generic;

    ZERO_STRUCT(auth2);
    netlogon_creds_client_authenticator(creds, &auth);
    r.in.credential = &auth;
    r.in.return_authenticator = &auth2;
    r.in.logon_level = NetlogonGenericInformation;
    r.in.logon = &logon;
    r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    r.in.computer_name = cli_credentials_get_workstation(credentials);
    r.in.validation_level = NetlogonValidationGenericInfo2;

    status = dcerpc_netr_LogonSamLogon(p, tctx, &r);

    torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed");

    torture_assert(tctx, netlogon_creds_client_check(creds,
                   &r.out.return_authenticator->cred),
                   "Credential chaining failed");

    pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
    pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;

    /* Break the SignatureType */
    pac_wrapped_struct.SignatureType++;

    pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;
    pac_wrapped_struct.ChecksumAndSignature = payload
            = data_blob_talloc(tmp_ctx, NULL,
                               pac_wrapped_struct.ChecksumLength
                               + pac_wrapped_struct.SignatureLength);
    memcpy(&payload.data[0],
           session_info->server_info->pac_srv_sig.signature.data,
           pac_wrapped_struct.ChecksumLength);
    memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
           session_info->server_info->pac_kdc_sig.signature.data,
           pac_wrapped_struct.SignatureLength);

    ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_wrapped_struct,
                                   (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
    torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");

    torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
    netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);

    generic.length = pac_wrapped.length;
    generic.data = pac_wrapped.data;

    logon.generic = &generic;

    ZERO_STRUCT(auth2);
    netlogon_creds_client_authenticator(creds, &auth);
    r.in.credential = &auth;
    r.in.return_authenticator = &auth2;
    r.in.logon_level = NetlogonGenericInformation;
    r.in.logon = &logon;
    r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    r.in.computer_name = cli_credentials_get_workstation(credentials);
    r.in.validation_level = NetlogonValidationGenericInfo2;

    status = dcerpc_netr_LogonSamLogon(p, tctx, &r);

    torture_assert_ntstatus_equal(tctx, status, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed");

    torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
                   "Credential chaining failed");

    pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
    pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
    pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;

    pac_wrapped_struct.ChecksumAndSignature = payload
            = data_blob_talloc(tmp_ctx, NULL,
                               pac_wrapped_struct.ChecksumLength
                               + pac_wrapped_struct.SignatureLength);
    memcpy(&payload.data[0],
           session_info->server_info->pac_srv_sig.signature.data,
           pac_wrapped_struct.ChecksumLength);
    memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
           session_info->server_info->pac_kdc_sig.signature.data,
           pac_wrapped_struct.SignatureLength);

    /* Break the signature length */
    pac_wrapped_struct.SignatureLength++;

    ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_wrapped_struct,
                                   (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
    torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");

    torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
    netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);

    generic.length = pac_wrapped.length;
    generic.data = pac_wrapped.data;

    logon.generic = &generic;

    ZERO_STRUCT(auth2);
    netlogon_creds_client_authenticator(creds, &auth);
    r.in.credential = &auth;
    r.in.return_authenticator = &auth2;
    r.in.logon_level = NetlogonGenericInformation;
    r.in.logon = &logon;
    r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    r.in.computer_name = cli_credentials_get_workstation(credentials);
    r.in.validation_level = NetlogonValidationGenericInfo2;

    status = dcerpc_netr_LogonSamLogon(p, tctx, &r);

    torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed");

    torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
                   "Credential chaining failed");
    return true;
}
Ejemplo n.º 11
0
/* test a query FS info by asking for share's GUID */
static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx)
{
	char *guid = NULL;
	NTSTATUS status;
	struct smb_composite_fsinfo io1;
	struct composite_context **c;

	int i;
	extern int torture_numops;
	struct tevent_context *event_ctx;
	int *count = talloc_zero(tctx, int);
	bool ret = true;

	io1.in.dest_host = torture_setting_string(tctx, "host", NULL);
	io1.in.dest_ports = lp_smb_ports(tctx->lp_ctx);
	io1.in.socket_options = lp_socket_options(tctx->lp_ctx);
	io1.in.called_name = torture_setting_string(tctx, "host", NULL);
	io1.in.service = torture_setting_string(tctx, "share", NULL);
	io1.in.service_type = "A:";
	io1.in.credentials = cmdline_credentials;
	io1.in.workgroup = lp_workgroup(tctx->lp_ctx);
	io1.in.level = RAW_QFS_OBJECTID_INFORMATION;
	io1.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
	io1.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);

	printf("testing parallel queryfsinfo [Object ID] with %d ops\n", torture_numops);

	event_ctx = tctx->ev;
	c = talloc_array(tctx, struct composite_context *, torture_numops);

	for (i=0; i<torture_numops; i++) {
		c[i] = smb_composite_fsinfo_send(cli->tree, &io1, lp_resolve_context(tctx->lp_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_fsinfo_recv(c[i], tctx);
		if (!NT_STATUS_IS_OK(status)) {
			printf("(%s) fsinfo[%d] failed - %s\n", __location__, i, nt_errstr(status));
			ret = false;
			continue;
		}

		if (io1.out.fsinfo->generic.level != RAW_QFS_OBJECTID_INFORMATION) {
			printf("(%s) wrong level in returned info - %d "
			       "should be %d\n", __location__,
			       io1.out.fsinfo->generic.level, RAW_QFS_OBJECTID_INFORMATION);
			ret = false;
			continue;
		}

		guid=GUID_string(tctx, &io1.out.fsinfo->objectid_information.out.guid);
		printf("[%d] GUID: %s\n", i, guid);

		
	}

	return ret;
}
Ejemplo n.º 12
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;
}