コード例 #1
0
ファイル: rpc.c プロジェクト: DavidMulder/samba
static bool torture_rpc_setup_machine_bdc(struct torture_context *tctx,
					  void **data)
{
	NTSTATUS status;
	struct dcerpc_binding *binding;
	struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase, 
						struct torture_rpc_tcase);
	struct torture_rpc_tcase_data *tcase_data;

	status = torture_rpc_binding(tctx, &binding);
	if (NT_STATUS_IS_ERR(status))
		return false;

	*data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
	tcase_data->credentials = popt_get_cmdline_credentials();
	tcase_data->join_ctx = torture_join_domain(tctx, tcase->machine_name,
						   ACB_SVRTRUST, 
						   &tcase_data->credentials);
	if (tcase_data->join_ctx == NULL)
	    torture_fail(tctx, "Failed to join as BDC");

	status = dcerpc_pipe_connect_b(tctx, 
				&(tcase_data->pipe),
				binding,
				tcase->table,
				tcase_data->credentials, tctx->ev, tctx->lp_ctx);

	torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");

	return NT_STATUS_IS_OK(status);
}
コード例 #2
0
ファイル: schannel.c プロジェクト: DanilKorotenko/samba
/*
  test two schannel connections
 */
bool torture_rpc_schannel2(struct torture_context *torture)
{
	struct test_join *join_ctx;
	NTSTATUS status;
	const char *binding = torture_setting_string(torture, "binding", NULL);
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p1 = NULL, *p2 = NULL;
	struct cli_credentials *credentials1, *credentials2;
	uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN;

	join_ctx = torture_join_domain(torture, talloc_asprintf(torture, "%s2", TEST_MACHINE_NAME),
				       ACB_WSTRUST, &credentials1);
	torture_assert(torture, join_ctx != NULL,
		       "Failed to join domain with acct_flags=ACB_WSTRUST");

	credentials2 = cli_credentials_shallow_copy(torture, credentials1);
	cli_credentials_set_netlogon_creds(credentials1, NULL);
	cli_credentials_set_netlogon_creds(credentials2, NULL);

	status = dcerpc_parse_binding(torture, binding, &b);
	torture_assert_ntstatus_ok(torture, status, "Bad binding string");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(torture, status, "set flags");

	torture_comment(torture, "Opening first connection\n");
	status = dcerpc_pipe_connect_b(torture, &p1, b, &ndr_table_netlogon,
				       credentials1, torture->ev, torture->lp_ctx);
	torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");

	torture_comment(torture, "Opening second connection\n");
	status = dcerpc_pipe_connect_b(torture, &p2, b, &ndr_table_netlogon,
				       credentials2, torture->ev, torture->lp_ctx);
	torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");

	cli_credentials_set_netlogon_creds(credentials1, NULL);
	cli_credentials_set_netlogon_creds(credentials2, NULL);

	torture_comment(torture, "Testing logon on pipe1\n");
	if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
		return false;

	torture_comment(torture, "Testing logon on pipe2\n");
	if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
		return false;

	torture_comment(torture, "Again on pipe1\n");
	if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
		return false;

	torture_comment(torture, "Again on pipe2\n");
	if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
		return false;

	torture_leave_domain(torture, join_ctx);
	return true;
}
コード例 #3
0
ファイル: schannel.c プロジェクト: DanilKorotenko/samba
/*
  test a schannel connection with the given flags
 */
static bool test_schannel(struct torture_context *tctx,
			  uint16_t acct_flags, uint32_t dcerpc_flags,
			  int i)
{
	struct test_join *join_ctx;
	NTSTATUS status;
	const char *binding = torture_setting_string(tctx, "binding", NULL);
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p = NULL;
	struct dcerpc_pipe *p_netlogon = NULL;
	struct dcerpc_pipe *p_netlogon2 = NULL;
	struct dcerpc_pipe *p_netlogon3 = NULL;
	struct dcerpc_pipe *p_samr2 = NULL;
	struct dcerpc_pipe *p_lsa = NULL;
	struct netlogon_creds_CredentialState *creds;
	struct cli_credentials *credentials;
	enum dcerpc_transport_t transport;

	join_ctx = torture_join_domain(tctx,
				       talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i),
				       acct_flags, &credentials);
	torture_assert(tctx, join_ctx != NULL, "Failed to join domain");

	status = dcerpc_parse_binding(tctx, binding, &b);
	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_pipe_connect_b(tctx, &p, b, &ndr_table_samr,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status,
		"Failed to connect to samr with schannel");

	torture_assert(tctx, test_samr_ops(tctx, p->binding_handle),
		       "Failed to process schannel secured SAMR ops");

	/* Also test that when we connect to the netlogon pipe, that
	 * the credentials we setup on the first pipe are valid for
	 * the second */

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm map");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_secondary_auth_connection(p, b, &ndr_table_netlogon,
						  credentials, tctx->lp_ctx,
						  tctx, &p_netlogon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");

	creds = cli_credentials_get_netlogon_creds(credentials);
	torture_assert(tctx, (creds != NULL), "schannel creds");

	/* checks the capabilities */
	torture_assert(tctx, test_netlogon_capabilities(p_netlogon, tctx, credentials, creds),
		       "Failed to process schannel secured capability ops (on fresh connection)");

	/* do a couple of logins */
	torture_assert(tctx, test_netlogon_ops(p_netlogon, tctx, credentials, creds),
		"Failed to process schannel secured NETLOGON ops");

	torture_assert(tctx, test_netlogon_ex_ops(p_netlogon, tctx, credentials, creds),
		"Failed to process schannel secured NETLOGON EX ops");

	/* we *MUST* use ncacn_np for openpolicy etc. */
	transport = dcerpc_binding_get_transport(b);
	status = dcerpc_binding_set_transport(b, NCACN_NP);
	torture_assert_ntstatus_ok(tctx, status, "set transport");

	/* Swap the binding details from SAMR to LSARPC */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm map");

	torture_assert_ntstatus_ok(tctx,
		dcerpc_pipe_connect_b(tctx, &p_lsa, b, &ndr_table_lsarpc,
				      credentials, tctx->ev, tctx->lp_ctx),
		"failed to connect lsarpc with schannel");

	torture_assert(tctx, test_lsa_ops(tctx, p_lsa),
		"Failed to process schannel secured LSA ops");

	talloc_free(p_lsa);
	p_lsa = NULL;

	/* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
	status = dcerpc_binding_set_transport(b, NCACN_IP_TCP);
	torture_assert_ntstatus_ok(tctx, status, "set transport");

	torture_assert_ntstatus_ok(tctx,
		dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx),
		"failed to call epm map");

	torture_assert_ntstatus_ok(tctx,
		dcerpc_pipe_connect_b(tctx, &p_lsa, b, &ndr_table_lsarpc,
				      credentials, tctx->ev, tctx->lp_ctx),
		"failed to connect lsarpc with schannel");

	torture_assert(tctx,
		test_many_LookupSids(p_lsa, tctx, NULL),
		"LsaLookupSids3 failed!\n");

	status = dcerpc_binding_set_transport(b, transport);
	torture_assert_ntstatus_ok(tctx, status, "set transport");


	/* Drop the socket, we want to start from scratch */
	talloc_free(p);
	p = NULL;

	/* Now see what we are still allowed to do */

	status = dcerpc_parse_binding(tctx, binding, &b);
	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_pipe_connect_b(tctx, &p_samr2, b, &ndr_table_samr,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status,
		"Failed to connect with schannel");

	/* do a some SAMR operations.  We have *not* done a new serverauthenticate */
	torture_assert (tctx, test_samr_ops(tctx, p_samr2->binding_handle),
			"Failed to process schannel secured SAMR ops (on fresh connection)");

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_secondary_auth_connection(p_samr2, b, &ndr_table_netlogon,
						  credentials, tctx->lp_ctx,
						  tctx, &p_netlogon2);
	torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");

	/* checks the capabilities */
	torture_assert(tctx, test_netlogon_capabilities(p_netlogon2, tctx, credentials, creds),
		       "Failed to process schannel secured capability ops (on fresh connection)");

	/* Try the schannel-only SamLogonEx operation */
	torture_assert(tctx, test_netlogon_ex_ops(p_netlogon2, tctx, credentials, creds),
		       "Failed to process schannel secured NETLOGON EX ops (on fresh connection)");


	/* And the more traditional style, proving that the
	 * credentials chaining state is fully present */
	torture_assert(tctx, test_netlogon_ops(p_netlogon2, tctx, credentials, creds),
			     "Failed to process schannel secured NETLOGON ops (on fresh connection)");

	/* Drop the socket, we want to start from scratch (again) */
	talloc_free(p_samr2);

	/* We don't want schannel for this test */
	status = dcerpc_binding_set_flags(b, 0, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_pipe_connect_b(tctx, &p_netlogon3, b, &ndr_table_netlogon,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");

	torture_assert(tctx, !test_netlogon_ex_ops(p_netlogon3, tctx, credentials, creds),
			"Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)");

	/* Required because the previous call will mark the current context as having failed */
	tctx->last_result = TORTURE_OK;
	tctx->last_reason = NULL;

	torture_assert(tctx, test_netlogon_ops(p_netlogon3, tctx, credentials, creds),
			"Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth");

	torture_leave_domain(tctx, join_ctx);
	return true;
}
コード例 #4
0
ファイル: dgram.c プロジェクト: 0x24bin/winexe-1
/* test UDP/138 ntlogon requests */
static bool nbt_test_ntlogon(struct torture_context *tctx)
{
	struct dgram_mailslot_handler *dgmslot;
	struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev,
								 lp_iconv_convenience(tctx->lp_ctx));
	struct socket_address *dest;
	struct test_join *join_ctx;
	const struct dom_sid *dom_sid;
	struct cli_credentials *machine_credentials;

	const char *myaddress;
	struct nbt_netlogon_packet logon;
	struct nbt_netlogon_response *response;
	struct nbt_name myname;
	NTSTATUS status;
	struct timeval tv = timeval_current();

	struct socket_address *socket_address;
	const char *address;
	struct nbt_name name;

	struct interface *ifaces;
	
	name.name = lp_workgroup(tctx->lp_ctx);
	name.type = NBT_NAME_LOGON;
	name.scope = NULL;

	/* do an initial name resolution to find its IP */
	torture_assert_ntstatus_ok(tctx, 
				   resolve_name(lp_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev),
				   talloc_asprintf(tctx, "Failed to resolve %s", name.name));

	load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
	myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));

	socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
						     myaddress, lp_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, socket_address != NULL, "Error getting address");

	/* try receiving replies on port 138 first, which will only
	   work if we are root and smbd/nmbd are not running - fall
	   back to listening on any port, which means replies from
	   most windows versions won't be seen */
	status = socket_listen(dgmsock->sock, socket_address, 0, 0);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(socket_address);
		socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
							     myaddress, 0);
		torture_assert(tctx, socket_address != NULL, "Error getting address");

		socket_listen(dgmsock->sock, socket_address, 0, 0);
	}

	join_ctx = torture_join_domain(tctx, TEST_NAME, 
				       ACB_WSTRUST, &machine_credentials);
	dom_sid = torture_join_sid(join_ctx);

	torture_assert(tctx, join_ctx != NULL,
		       talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
		       		       lp_workgroup(tctx->lp_ctx), TEST_NAME));

	/* setup a temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	

	ZERO_STRUCT(logon);
	logon.command = LOGON_SAM_LOGON_REQUEST;
	logon.req.logon.request_count = 0;
	logon.req.logon.computer_name = TEST_NAME;
	logon.req.logon.user_name     = TEST_NAME"$";
	logon.req.logon.mailslot_name = dgmslot->mailslot_name;
	logon.req.logon.acct_control  = ACB_WSTRUST;
	/* Try with a SID this time */
	logon.req.logon.sid           = *dom_sid;
	logon.req.logon.nt_version    = 1;
	logon.req.logon.lmnt_token    = 0xFFFF;
	logon.req.logon.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lp_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
		event_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
	map_netlogon_samlogon_response(&response->data.samlogon);

	torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");

	torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");


	/* setup a temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	

	ZERO_STRUCT(logon);
	logon.command = LOGON_SAM_LOGON_REQUEST;
	logon.req.logon.request_count = 0;
	logon.req.logon.computer_name = TEST_NAME;
	logon.req.logon.user_name     = TEST_NAME"$";
	logon.req.logon.mailslot_name = dgmslot->mailslot_name;
	logon.req.logon.acct_control  = ACB_WSTRUST;
	/* Leave sid as all zero */
	logon.req.logon.nt_version    = 1;
	logon.req.logon.lmnt_token    = 0xFFFF;
	logon.req.logon.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lp_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
		event_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
	map_netlogon_samlogon_response(&response->data.samlogon);

	torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");

	torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");


	/* setup (another) temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	
	ZERO_STRUCT(logon);
	logon.command = LOGON_PRIMARY_QUERY;
	logon.req.pdc.computer_name = TEST_NAME;
	logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
	logon.req.pdc.unicode_name  = TEST_NAME;
	logon.req.pdc.nt_version    = 1;
	logon.req.pdc.lmnt_token    = 0xFFFF;
	logon.req.pdc.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lp_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
		event_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
	torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");

	torture_leave_domain(tctx, join_ctx);

	/* setup (another) temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	
	ZERO_STRUCT(logon);
	logon.command = LOGON_PRIMARY_QUERY;
	logon.req.pdc.computer_name = TEST_NAME;
	logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
	logon.req.pdc.unicode_name  = TEST_NAME;
	logon.req.pdc.nt_version    = 1;
	logon.req.pdc.lmnt_token    = 0xFFFF;
	logon.req.pdc.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lp_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
		event_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
	torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");


	return true;
}
コード例 #5
0
ファイル: schannel.c プロジェクト: Alexandr-Galko/samba
/*
  test a schannel connection with the given flags
 */
static bool test_schannel(struct torture_context *tctx,
			  uint16_t acct_flags, uint32_t dcerpc_flags,
			  int i)
{
	struct test_join *join_ctx;
	NTSTATUS status;
	const char *binding = torture_setting_string(tctx, "binding", NULL);
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p = NULL;
	struct dcerpc_pipe *p_netlogon = NULL;
	struct dcerpc_pipe *p_netlogon2 = NULL;
	struct dcerpc_pipe *p_netlogon3 = NULL;
	struct dcerpc_pipe *p_samr2 = NULL;
	struct dcerpc_pipe *p_lsa = NULL;
	struct netlogon_creds_CredentialState *creds;
	struct cli_credentials *credentials;

	join_ctx = torture_join_domain(tctx, 
				       talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i), 
				       acct_flags, &credentials);
	torture_assert(tctx, join_ctx != NULL, "Failed to join domain");

	status = dcerpc_parse_binding(tctx, binding, &b);
	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(tctx, &p, b, &ndr_table_samr,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, 
		"Failed to connect with schannel");

	torture_assert(tctx, test_samr_ops(tctx, p->binding_handle),
		       "Failed to process schannel secured SAMR ops");

	/* Also test that when we connect to the netlogon pipe, that
	 * the credentials we setup on the first pipe are valid for
	 * the second */

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm map");

	status = dcerpc_secondary_connection(p, &p_netlogon, 
					     b);
	torture_assert_ntstatus_ok(tctx, status, "seconday connection");

	status = dcerpc_bind_auth(p_netlogon, &ndr_table_netlogon, 
				  credentials, lpcfg_gensec_settings(tctx, tctx->lp_ctx),
				  DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	torture_assert_ntstatus_ok(tctx, status, "bind auth");

	status = dcerpc_schannel_creds(p_netlogon->conn->security_state.generic_state, tctx, &creds);
	torture_assert_ntstatus_ok(tctx, status, "schannel creds");

	/* do a couple of logins */
	torture_assert(tctx, test_netlogon_ops(p_netlogon, tctx, credentials, creds),
		"Failed to process schannel secured NETLOGON ops");

	torture_assert(tctx, test_netlogon_ex_ops(p_netlogon, tctx, credentials, creds),
		"Failed to process schannel secured NETLOGON EX ops");

	/* Swap the binding details from SAMR to LSARPC */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm map");

	status = dcerpc_secondary_connection(p, &p_lsa, 
					     b);

	torture_assert_ntstatus_ok(tctx, status, "seconday connection");

	status = dcerpc_bind_auth(p_lsa, &ndr_table_lsarpc,
				  credentials, lpcfg_gensec_settings(tctx, tctx->lp_ctx),
				  DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	torture_assert_ntstatus_ok(tctx, status, "bind auth");

	torture_assert(tctx, test_lsa_ops(tctx, p_lsa), 
		"Failed to process schannel secured LSA ops");

	/* Drop the socket, we want to start from scratch */
	talloc_free(p);
	p = NULL;

	/* Now see what we are still allowed to do */
	
	status = dcerpc_parse_binding(tctx, binding, &b);
	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(tctx, &p_samr2, b, &ndr_table_samr,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, 
		"Failed to connect with schannel");

	/* do a some SAMR operations.  We have *not* done a new serverauthenticate */
	torture_assert (tctx, test_samr_ops(tctx, p_samr2->binding_handle),
			"Failed to process schannel secured SAMR ops (on fresh connection)");

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "epm");

	status = dcerpc_secondary_connection(p_samr2, &p_netlogon2, 
					     b);
	torture_assert_ntstatus_ok(tctx, status, "seconday connection");

	/* and now setup an SCHANNEL bind on netlogon */
	status = dcerpc_bind_auth(p_netlogon2, &ndr_table_netlogon,
				  credentials, lpcfg_gensec_settings(tctx, tctx->lp_ctx),
				  DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p_samr2->conn),
				  NULL);

	torture_assert_ntstatus_ok(tctx, status, "auth failed");
	
	/* Try the schannel-only SamLogonEx operation */
	torture_assert(tctx, test_netlogon_ex_ops(p_netlogon2, tctx, credentials, creds), 
		       "Failed to process schannel secured NETLOGON EX ops (on fresh connection)");
		

	/* And the more traditional style, proving that the
	 * credentials chaining state is fully present */
	torture_assert(tctx, test_netlogon_ops(p_netlogon2, tctx, credentials, creds),
			     "Failed to process schannel secured NETLOGON ops (on fresh connection)");

	/* Drop the socket, we want to start from scratch (again) */
	talloc_free(p_samr2);

	/* We don't want schannel for this test */
	b->flags &= ~DCERPC_AUTH_OPTIONS;

	status = dcerpc_pipe_connect_b(tctx, &p_netlogon3, b, &ndr_table_netlogon,
				       credentials, tctx->ev, tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");

	torture_assert(tctx, !test_netlogon_ex_ops(p_netlogon3, tctx, credentials, creds),
			"Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)");

	/* Required because the previous call will mark the current context as having failed */
	tctx->last_result = TORTURE_OK;
	tctx->last_reason = NULL;

	torture_assert(tctx, test_netlogon_ops(p_netlogon3, tctx, credentials, creds),
			"Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth");

	torture_leave_domain(tctx, join_ctx);
	return true;
}
コード例 #6
0
ファイル: libnet_BecomeDC.c プロジェクト: AIdrifter/samba
bool torture_net_become_dc(struct torture_context *torture)
{
	bool ret = true;
	NTSTATUS status;
	struct libnet_BecomeDC b;
	struct libnet_UnbecomeDC u;
	struct libnet_vampire_cb_state *s;
	struct ldb_message *msg;
	int ldb_ret;
	uint32_t i;
	char *private_dir;
	const char *address;
	struct nbt_name name;
	const char *netbios_name;
	struct cli_credentials *machine_account;
	struct test_join *tj;
	struct loadparm_context *lp_ctx;
	struct ldb_context *ldb;
	struct libnet_context *ctx;
	struct dsdb_schema *schema;

	char *location = NULL;
	torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
				   "torture_temp_dir should return NT_STATUS_OK" );

	netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
	if (!netbios_name || !netbios_name[0]) {
		netbios_name = "smbtorturedc";
	}

	make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));

	/* do an initial name resolution to find its IP */
	status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
				 0, 0,
				 &name, torture, &address, torture->ev);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "Failed to resolve %s - %s\n",
				   name.name, nt_errstr(status)));


	/* Join domain as a member server. */
	tj = torture_join_domain(torture, netbios_name,
				 ACB_WSTRUST,
				 &machine_account);
	torture_assert(torture, tj, talloc_asprintf(torture,
						    "%s failed to join domain as workstation\n",
						    netbios_name));

	s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
			       netbios_name,
			       torture_join_dom_netbios_name(tj),
			       torture_join_dom_dns_name(tj),
			       location);
	torture_assert(torture, s, "libnet_vampire_cb_state_init");

	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
	ctx->cred = cmdline_credentials;

	ZERO_STRUCT(b);
	b.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	b.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	b.in.domain_sid			= torture_join_sid(tj);
	b.in.source_dsa_address		= address;
	b.in.dest_dsa_netbios_name	= netbios_name;

	b.in.callbacks.private_data	= s;
	b.in.callbacks.check_options	= libnet_vampire_cb_check_options;
	b.in.callbacks.prepare_db       = libnet_vampire_cb_prepare_db;
	b.in.callbacks.schema_chunk	= libnet_vampire_cb_schema_chunk;
	b.in.callbacks.config_chunk	= libnet_vampire_cb_store_chunk;
	b.in.callbacks.domain_chunk	= libnet_vampire_cb_store_chunk;

	status = libnet_BecomeDC(ctx, s, &b);
	torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
				   "libnet_BecomeDC() failed - %s %s\n",
				   nt_errstr(status), b.out.error_string));
	ldb = libnet_vampire_cb_ldb(s);

	msg = ldb_msg_new(s);
	torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
				      "ldb_msg_new() failed\n");
	msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
	torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
				      "ldb_msg_new(@ROOTDSE) failed\n");

	ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");

	for (i=0; i < msg->num_elements; i++) {
		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
	}

	torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
	ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_modify() failed\n");
	
	/* commit the transaction now we know the secrets were written
	 * out properly
	*/
	ldb_ret = ldb_transaction_commit(ldb);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_transaction_commit() failed\n");

	/* reopen the ldb */
	talloc_unlink(s, ldb);

	lp_ctx = libnet_vampire_cb_lp_ctx(s);
	private_dir = talloc_asprintf(s, "%s/%s", location, "private");
	lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
	torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
	ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0);
	torture_assert_goto(torture, ldb != NULL, ret, cleanup,
				      talloc_asprintf(torture,
				      "Failed to open '%s/sam.ldb'\n", private_dir));

	torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
						"Uses global schema");

	schema = dsdb_get_schema(ldb, s);
	torture_assert_goto(torture, schema != NULL, ret, cleanup,
				      "Failed to get loaded dsdb_schema\n");

	/* Make sure we get this from the command line */
	if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
		talloc_free(s);
		return ret;
	}

cleanup:
	ZERO_STRUCT(u);
	u.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	u.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	u.in.source_dsa_address		= address;
	u.in.dest_dsa_netbios_name	= netbios_name;

	status = libnet_UnbecomeDC(ctx, s, &u);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "libnet_UnbecomeDC() failed - %s %s\n",
				   nt_errstr(status), u.out.error_string));

	/* Leave domain. */
	torture_leave_domain(torture, tj);

	talloc_free(s);
	return ret;
}
コード例 #7
0
ファイル: schannel.c プロジェクト: Marvin-Lee/libwmiclient
/*
  test a schannel connection with the given flags
 */
static BOOL test_schannel(TALLOC_CTX *mem_ctx, 
			  uint16_t acct_flags, uint32_t dcerpc_flags,
			  int i)
{
	BOOL ret = True;

	struct test_join *join_ctx;
	NTSTATUS status;
	const char *binding = lp_parm_string(-1, "torture", "binding");
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p = NULL;
	struct dcerpc_pipe *p_netlogon = NULL;
	struct dcerpc_pipe *p_netlogon2 = NULL;
	struct dcerpc_pipe *p_netlogon3 = NULL;
	struct dcerpc_pipe *p_samr2 = NULL;
	struct dcerpc_pipe *p_lsa = NULL;
	struct creds_CredentialState *creds;
	struct cli_credentials *credentials;

	TALLOC_CTX *test_ctx = talloc_named(mem_ctx, 0, "test_schannel context");

	join_ctx = torture_join_domain(talloc_asprintf(mem_ctx, "%s%d", TEST_MACHINE_NAME, i), 
				       acct_flags, &credentials);
	if (!join_ctx) {
		printf("Failed to join domain with acct_flags=0x%x\n", acct_flags);
		talloc_free(test_ctx);
		return False;
	}

	status = dcerpc_parse_binding(test_ctx, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Bad binding string %s\n", binding);
		goto failed;
	}

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(test_ctx, &p, b, &dcerpc_table_samr,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect with schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	if (!test_samr_ops(p, test_ctx)) {
		printf("Failed to process schannel secured SAMR ops\n");
		ret = False;
	}

	/* Also test that when we connect to the netlogon pipe, that
	 * the credentials we setup on the first pipe are valid for
	 * the second */

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_netlogon, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p, &p_netlogon, 
					     b);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_bind_auth(p_netlogon, &dcerpc_table_netlogon,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_schannel_creds(p_netlogon->conn->security_state.generic_state, test_ctx, &creds);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	/* do a couple of logins */
	if (!test_netlogon_ops(p_netlogon, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON ops\n");
		ret = False;
	}

	if (!test_netlogon_ex_ops(p_netlogon, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON EX ops\n");
		ret = False;
	}

	/* Swap the binding details from SAMR to LSARPC */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_lsarpc, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p, &p_lsa, 
					     b);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_bind_auth(p_lsa, &dcerpc_table_lsarpc,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	if (!test_lsa_ops(p_lsa, test_ctx)) {
		printf("Failed to process schannel secured LSA ops\n");
		ret = False;
	}

	/* Drop the socket, we want to start from scratch */
	talloc_free(p);
	p = NULL;

	/* Now see what we are still allowed to do */
	
	status = dcerpc_parse_binding(test_ctx, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Bad binding string %s\n", binding);
		goto failed;
	}

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(test_ctx, &p_samr2, b, &dcerpc_table_samr,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect with schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	/* do a some SAMR operations.  We have *not* done a new serverauthenticate */
	if (!test_samr_ops(p_samr2, test_ctx)) {
		printf("Failed to process schannel secured SAMR ops (on fresh connection)\n");
		goto failed;
	}

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_netlogon, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p_samr2, &p_netlogon2, 
					     b);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	/* and now setup an SCHANNEL bind on netlogon */
	status = dcerpc_bind_auth(p_netlogon2, &dcerpc_table_netlogon,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p_samr2->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}
	
	/* Try the schannel-only SamLogonEx operation */
	if (!test_netlogon_ex_ops(p_netlogon2, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON EX ops (on fresh connection)\n");
		ret = False;
	}

	/* And the more traditional style, proving that the
	 * credentials chaining state is fully present */
	if (!test_netlogon_ops(p_netlogon2, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON ops (on fresh connection)\n");
		ret = False;
	}

	/* Drop the socket, we want to start from scratch (again) */
	talloc_free(p_samr2);

	/* We don't want schannel for this test */
	b->flags &= ~DCERPC_AUTH_OPTIONS;

	status = dcerpc_pipe_connect_b(test_ctx, &p_netlogon3, b, &dcerpc_table_netlogon,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect without schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	if (test_netlogon_ex_ops(p_netlogon3, test_ctx, credentials, creds)) {
		printf("Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)\n");
		ret = False;
	}

	if (!test_netlogon_ops(p_netlogon3, test_ctx, credentials, creds)) {
		printf("Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth\n");
		ret = False;
	}

	torture_leave_domain(join_ctx);
	talloc_free(test_ctx);
	return ret;

failed:
	torture_leave_domain(join_ctx);
	talloc_free(test_ctx);
	return False;	
}