static bool test_BindingString(struct torture_context *tctx,
							   const void *test_data)
{
	const char *binding = test_data;
	struct dcerpc_binding *b, *b2;
	const char *s, *s2;
	struct epm_tower tower;
	TALLOC_CTX *mem_ctx = tctx;

	/* Parse */
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(mem_ctx, binding, &b),
		"Error parsing binding string");

	s = dcerpc_binding_string(mem_ctx, b);
	torture_assert(tctx, s != NULL, "Error converting binding back to string");

	torture_assert_casestr_equal(tctx, binding, s, 
		"Mismatch while comparing original and regenerated binding strings");

	/* Generate protocol towers */
	torture_assert_ntstatus_ok(tctx, dcerpc_binding_build_tower(mem_ctx, b, &tower),
		"Error generating protocol tower");

	/* Convert back to binding and then back to string and compare */

	torture_assert_ntstatus_ok(tctx, dcerpc_binding_from_tower(mem_ctx, &tower, &b2),
			    "Error generating binding from tower for original binding");

	/* Compare to a stripped down version of the binding string because 
	 * the protocol tower doesn't contain the extra option data */
	b->options = NULL;

	b->flags = 0;
	
	s = dcerpc_binding_string(mem_ctx, b);
	torture_assert(tctx, s != NULL, "Error converting binding back to string for (stripped down)"); 

	s2 = dcerpc_binding_string(mem_ctx, b2);
	torture_assert(tctx, s != NULL, "Error converting binding back to string"); 

	if (is_ipaddress(b->host))
		torture_assert_casestr_equal(tctx, s, s2, "Mismatch while comparing original and from protocol tower generated binding strings");

	return true;
}
Beispiel #2
0
bool torture_rpc_connect_binding(struct torture_context *torture)
{
	const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_BINDING;
	NTSTATUS status;
	struct dcerpc_binding *binding;
	const char *bindstr;

	status = torture_rpc_binding(torture, &binding);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	bindstr = dcerpc_binding_string(torture, binding);

	return torture_rpc_connect(torture, level, bindstr, NULL);
}
Beispiel #3
0
static bool test_no_transport(struct torture_context *tctx)
{
	const char *binding = "somehost";
	struct dcerpc_binding *b;
	const char *s;

	/* Parse */
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, binding, &b),
		"Error parsing binding string");

	torture_assert(tctx, b->transport == NCA_UNKNOWN, "invalid transport");

	s = dcerpc_binding_string(tctx, b);
	torture_assert(tctx, s != NULL, "Error converting binding back to string");

	torture_assert_casestr_equal(tctx, binding, s, 
		"Mismatch while comparing original and regenerated binding strings");

	return true;
}
Beispiel #4
0
/**
 * open a rpc connection to the chosen binding string
 */
_PUBLIC_ NTSTATUS torture_rpc_connection_with_binding(struct torture_context *tctx,
						      struct dcerpc_binding *binding,
						      struct dcerpc_pipe **p,
						      const struct ndr_interface_table *table)
{
	NTSTATUS status;

	dcerpc_init();

	status = dcerpc_pipe_connect_b(tctx,
				     p, binding, table,
				     popt_get_cmdline_credentials(),
					tctx->ev, tctx->lp_ctx);

	if (NT_STATUS_IS_ERR(status)) {
		torture_warning(tctx, "Failed to connect to remote server: %s %s\n",
			   dcerpc_binding_string(tctx, binding), nt_errstr(status));
	}

	return status;
}
Beispiel #5
0
static bool test_parse_check_results(struct torture_context *tctx)
{
	struct dcerpc_binding *b;
	struct GUID uuid;

	torture_assert_ntstatus_ok(tctx, 
				   GUID_from_string("308FB580-1EB2-11CA-923B-08002B1075A7", &uuid),
				   "parsing uuid");

	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_NP, "ncacn_np expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[rpcecho]", &b), "parse");
	torture_assert_str_equal(tctx, b->endpoint, "rpcecho", "endpoint");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho]", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho,sign,seal]", &b), "parse");
	torture_assert(tctx, b->flags == DCERPC_SIGN+DCERPC_SEAL, "sign+seal flags");
	torture_assert_str_equal(tctx, b->endpoint, "/pipe/rpcecho", "endpoint");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[,sign]", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign]", &b), "parse");
	torture_assert(tctx, b->endpoint == NULL, "endpoint");
	torture_assert(tctx, b->flags == DCERPC_SIGN, "sign flag");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncalrpc:", &b), "parse");
	torture_assert(tctx, b->transport == NCALRPC, "ncalrpc expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 
		"308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_np:$SERVER", &b), "parse");
	torture_assert(tctx, GUID_equal(&b->object.uuid, &uuid), "object uuid");
	torture_assert_int_equal(tctx, b->object.if_version, 0, "object version");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 
		"308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:$SERVER", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
	torture_assert(tctx, b->flags == (DCERPC_SIGN | DCERPC_LOCALADDRESS), "sign flag");
	torture_assert_str_equal(tctx, b->localaddress, "192.168.1.1", "localaddress");
	torture_assert_str_equal(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]",
				 dcerpc_binding_string(tctx, b), "back to string");

	return true;
}
Beispiel #6
0
BOOL torture_rpc_scanner(struct torture_context *torture)
{
        NTSTATUS status;
        struct dcerpc_pipe *p;
	TALLOC_CTX *mem_ctx, *loop_ctx;
	BOOL ret = True;
	const struct dcerpc_interface_list *l;
	const char *binding = torture_setting_string(torture, "binding", NULL);
	struct dcerpc_binding *b;

	mem_ctx = talloc_init("torture_rpc_scanner");

	if (!binding) {
		talloc_free(mem_ctx);
		printf("You must supply a ncacn binding string\n");
		return False;
	}
	
	status = dcerpc_parse_binding(mem_ctx, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		printf("Failed to parse binding '%s'\n", binding);
		return False;
	}

	for (l=librpc_dcerpc_pipes();l;l=l->next) {		
		loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_scanner loop context");
		/* some interfaces are not mappable */
		if (l->table->num_calls == 0 ||
		    strcmp(l->table->name, "mgmt") == 0) {
			talloc_free(loop_ctx);
			continue;
		}

		printf("\nTesting pipe '%s'\n", l->table->name);

		if (b->transport == NCACN_IP_TCP) {
			status = dcerpc_epm_map_binding(mem_ctx, b, l->table, NULL);
			if (!NT_STATUS_IS_OK(status)) {
				printf("Failed to map port for uuid %s\n", 
					   GUID_string(loop_ctx, &l->table->syntax_id.uuid));
				talloc_free(loop_ctx);
				continue;
			}
		} else {
			b->endpoint = talloc_strdup(b, l->table->name);
		}

		lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, b));

		status = torture_rpc_connection(loop_ctx, &p, &dcerpc_table_mgmt);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(loop_ctx);
			ret = False;
			continue;
		}
	
		if (!test_inq_if_ids(p, mem_ctx, l->table)) {
			ret = False;
		}
	}

	return ret;
}
Beispiel #7
0
static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
{
        NTSTATUS status;
	const struct ndr_interface_table *table;
	struct dcesrv_remote_private *priv;
	const char *binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding");
	const char *user, *pass, *domain;
	struct cli_credentials *credentials;
	bool must_free_credentials = true;
	bool machine_account;
	struct dcerpc_binding		*b;
	struct composite_context	*pipe_conn_req;

	machine_account = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "use_machine_account", false);

	priv = talloc(dce_call->conn, struct dcesrv_remote_private);
	if (!priv) {
		return NT_STATUS_NO_MEMORY;	
	}
	
	priv->c_pipe = NULL;
	dce_call->context->private_data = priv;

	if (!binding) {
		DEBUG(0,("You must specify a DCE/RPC binding string\n"));
		return NT_STATUS_INVALID_PARAMETER;
	}

	user = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "user");
	pass = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "password");
	domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain");

	table = ndr_table_by_syntax(&iface->syntax_id);
	if (!table) {
		dce_call->fault_code = DCERPC_FAULT_UNK_IF;
		return NT_STATUS_NET_WRITE_FAULT;
	}

	if (user && pass) {
		DEBUG(5, ("dcerpc_remote: RPC Proxy: Using specified account\n"));
		credentials = cli_credentials_init(priv);
		if (!credentials) {
			return NT_STATUS_NO_MEMORY;
		}
		cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx);
		cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
		if (domain) {
			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
		}
		cli_credentials_set_password(credentials, pass, CRED_SPECIFIED);
	} else if (machine_account) {
		DEBUG(5, ("dcerpc_remote: RPC Proxy: Using machine account\n"));
		credentials = cli_credentials_init(priv);
		cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx);
		if (domain) {
			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
		}
		status = cli_credentials_set_machine_account(credentials, dce_call->conn->dce_ctx->lp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
	} else if (dce_call->conn->auth_state.session_info->credentials) {
		DEBUG(5, ("dcerpc_remote: RPC Proxy: Using delegated credentials\n"));
		credentials = dce_call->conn->auth_state.session_info->credentials;
		must_free_credentials = false;
	} else {
		DEBUG(1,("dcerpc_remote: RPC Proxy: You must supply binding, user and password or have delegated credentials\n"));
		return NT_STATUS_INVALID_PARAMETER;
	}

	/* parse binding string to the structure */
	status = dcerpc_parse_binding(dce_call->context, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding));
		return status;
	}

	/* If we already have a remote association group ID, then use that */
	if (dce_call->context->assoc_group->proxied_id != 0) {
		status = dcerpc_binding_set_assoc_group_id(b,
			dce_call->context->assoc_group->proxied_id);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("dcerpc_binding_set_assoc_group_id() - %s'\n",
				  nt_errstr(status)));
			return status;
		}
	}

	status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dcerpc_binding_set_abstract_syntax() - %s'\n",
			  nt_errstr(status)));
		return status;
	}

	DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b)));

	pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
						   credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
	status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(priv->c_pipe));
	
	if (must_free_credentials) {
		talloc_free(credentials);
	}

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

	if (dce_call->context->assoc_group->proxied_id == 0) {
		dce_call->context->assoc_group->proxied_id =
			dcerpc_binding_get_assoc_group_id(priv->c_pipe->binding);
	}

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

	return NT_STATUS_OK;	
}
Beispiel #8
0
_PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx,
					       const char *machine_name, 
				      uint32_t acct_flags,
				      struct cli_credentials **machine_credentials)
{
	NTSTATUS status;
	struct libnet_context *libnet_ctx;
	struct libnet_JoinDomain *libnet_r;
	struct test_join *tj;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	const char *binding_str = NULL;
	struct dcerpc_binding *binding = NULL;
	enum dcerpc_transport_t transport;

	tj = talloc_zero(tctx, struct test_join);
	if (!tj) return NULL;

	binding_str = torture_setting_string(tctx, "binding", NULL);
	if (binding_str == NULL) {
		const char *host = torture_setting_string(tctx, "host", NULL);
		binding_str = talloc_asprintf(tj, "ncacn_np:%s", host);
	}
	status = dcerpc_parse_binding(tj, binding_str, &binding);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dcerpc_parse_binding(%s) failed - %s\n",
			  binding_str, nt_errstr(status)));
		talloc_free(tj);
		return NULL;
	}
	transport = dcerpc_binding_get_transport(binding);
	switch (transport) {
	case NCALRPC:
	case NCACN_UNIX_STREAM:
		break;
	default:
		dcerpc_binding_set_transport(binding, NCACN_NP);
		dcerpc_binding_set_flags(binding, 0, DCERPC_AUTH_OPTIONS);
		break;
	}

	libnet_r = talloc_zero(tj, struct libnet_JoinDomain);
	if (!libnet_r) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx);
	if (!libnet_ctx) {
		talloc_free(tj);
		return NULL;
	}
	
	tj->libnet_r = libnet_r;
		
	libnet_ctx->cred = cmdline_credentials;
	libnet_r->in.binding = dcerpc_binding_string(libnet_r, binding);
	if (libnet_r->in.binding == NULL) {
		talloc_free(tj);
		return NULL;
	}
	libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED;
	libnet_r->in.netbios_name = machine_name;
	libnet_r->in.account_name = talloc_asprintf(libnet_r, "%s$", machine_name);
	if (!libnet_r->in.account_name) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_r->in.acct_type = acct_flags;
	libnet_r->in.recreate_account = true;

	status = libnet_JoinDomain(libnet_ctx, libnet_r, libnet_r);
	if (!NT_STATUS_IS_OK(status)) {
		if (libnet_r->out.error_string) {
			DEBUG(0, ("Domain join failed - %s\n", libnet_r->out.error_string));
		} else {
			DEBUG(0, ("Domain join failed - %s\n", nt_errstr(status)));
		}
		talloc_free(tj);
                return NULL;
	}
	tj->p = libnet_r->out.samr_pipe;
	tj->user_handle = *libnet_r->out.user_handle;
	tj->dom_sid = libnet_r->out.domain_sid;
	talloc_steal(tj, libnet_r->out.domain_sid);
	tj->dom_netbios_name	= libnet_r->out.domain_name;
	talloc_steal(tj, libnet_r->out.domain_name);
	tj->dom_dns_name	= libnet_r->out.realm;
	talloc_steal(tj, libnet_r->out.realm);
	tj->user_guid = libnet_r->out.account_guid;
	tj->netbios_name = talloc_strdup(tj, machine_name);
	if (!tj->netbios_name) {
		talloc_free(tj);
		return NULL;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &tj->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.fields_present = SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
	u.info21.comment.string = talloc_asprintf(tj, 
						  "Tortured by Samba4: %s", 
						  timestring(tj, time(NULL)));
	u.info21.full_name.string = talloc_asprintf(tj, 
						    "Torture account for Samba4: %s", 
						    timestring(tj, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(tj, 
						      "Samba4 torture account created by host %s: %s", 
						      lpcfg_netbios_name(tctx->lp_ctx), timestring(tj, time(NULL)));

	status = dcerpc_samr_SetUserInfo_r(tj->p->binding_handle, tj, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(status));
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(s.out.result));
	}

	*machine_credentials = cli_credentials_init(tj);
	cli_credentials_set_conf(*machine_credentials, tctx->lp_ctx);
	cli_credentials_set_workstation(*machine_credentials, machine_name, CRED_SPECIFIED);
	cli_credentials_set_domain(*machine_credentials, libnet_r->out.domain_name, CRED_SPECIFIED);
	if (libnet_r->out.realm) {
		cli_credentials_set_realm(*machine_credentials, libnet_r->out.realm, CRED_SPECIFIED);
	}
	cli_credentials_set_username(*machine_credentials, libnet_r->in.account_name, CRED_SPECIFIED);
	cli_credentials_set_password(*machine_credentials, libnet_r->out.join_password, CRED_SPECIFIED);
	cli_credentials_set_kvno(*machine_credentials, libnet_r->out.kvno);
	if (acct_flags & ACB_SVRTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_BDC);
	} else if (acct_flags & ACB_WSTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_WKSTA);
	} else {
		DEBUG(0, ("Invalid account type specificed to torture_join_domain\n"));
		talloc_free(*machine_credentials);
		return NULL;
	}

	return tj;
}
Beispiel #9
0
bool torture_rpc_mgmt(struct torture_context *torture)
{
        NTSTATUS status;
        struct dcerpc_pipe *p;
	TALLOC_CTX *mem_ctx, *loop_ctx;
	bool ret = true;
	const struct ndr_interface_list *l;
	struct dcerpc_binding *b;

	mem_ctx = talloc_init("torture_rpc_mgmt");

	status = torture_rpc_binding(torture, &b);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return false;
	}

	for (l=ndr_table_list();l;l=l->next) {		
		loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_mgmt loop context");
		
		/* some interfaces are not mappable */
		if (l->table->num_calls == 0 ||
		    strcmp(l->table->name, "mgmt") == 0) {
			talloc_free(loop_ctx);
			continue;
		}

		printf("\nTesting pipe '%s'\n", l->table->name);

		status = dcerpc_epm_map_binding(loop_ctx, b, l->table, NULL, torture->lp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to map port for uuid %s\n", 
				   GUID_string(loop_ctx, &l->table->syntax_id.uuid));
			talloc_free(loop_ctx);
			continue;
		}

		lp_set_cmdline(torture->lp_ctx, "torture:binding", dcerpc_binding_string(loop_ctx, b));

		status = torture_rpc_connection(torture, &p, &ndr_table_mgmt);
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
			printf("Interface not available - skipping\n");
			talloc_free(loop_ctx);
			continue;
		}

		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(loop_ctx);
			ret = false;
			continue;
		}

		if (!test_is_server_listening(p, loop_ctx)) {
			ret = false;
		}

		if (!test_stop_server_listening(p, loop_ctx)) {
			ret = false;
		}

		if (!test_inq_stats(p, loop_ctx)) {
			ret = false;
		}

		if (!test_inq_princ_name(p, loop_ctx)) {
			ret = false;
		}

		if (!test_inq_if_ids(torture, p, loop_ctx, NULL, NULL)) {
			ret = false;
		}

	}

	return ret;
}