Ejemplo n.º 1
0
Archivo: cm.c Proyecto: ekohl/samba
static NTSTATUS pipe_cm_find(struct client_ipc_connection *ipc,
			     const struct ndr_syntax_id *interface,
			     struct rpc_pipe_client **presult)
{
	struct client_pipe_connection *p;

	for (p = ipc->pipe_connections; p; p = p->next) {
		const char *ipc_remote_name;

		if (!rpc_pipe_np_smb_conn(p->pipe)) {
			return NT_STATUS_PIPE_EMPTY;
		}

		ipc_remote_name = cli_state_remote_name(ipc->cli);

		if (strequal(ipc_remote_name, p->pipe->desthost)
		    && ndr_syntax_id_equal(&p->pipe->abstract_syntax,
					   interface)) {
			*presult = p->pipe;
			return NT_STATUS_OK;
		}
	}

	return NT_STATUS_PIPE_NOT_AVAILABLE;
}
Ejemplo n.º 2
0
bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
{
    pipes_struct *plist;
    struct handle_list *hl;

    for (plist = get_first_internal_pipe();
            plist;
            plist = get_next_internal_pipe(plist)) {
        if (ndr_syntax_id_equal(syntax, &plist->syntax)) {
            break;
        }
        if (is_samr_lsa_pipe(&plist->syntax)
                && is_samr_lsa_pipe(syntax)) {
            /*
             * samr and lsa share a handle space (same process
             * under Windows?)
             */
            break;
        }
    }

    if (plist != NULL) {
        hl = plist->pipe_handles;
        if (hl == NULL) {
            return false;
        }
    } else {
        /*
         * First open, we have to create the handle list
         */
        hl = SMB_MALLOC_P(struct handle_list);
        if (hl == NULL) {
            return false;
        }
        ZERO_STRUCTP(hl);

        DEBUG(10,("init_pipe_handles: created handle list for "
                  "pipe %s\n",
                  get_pipe_name_from_syntax(talloc_tos(), syntax)));
    }

    /*
     * One more pipe is using this list.
     */

    hl->pipe_ref_count++;

    /*
     * Point this pipe at this list.
     */

    p->pipe_handles = hl;

    DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
              (unsigned long)p->pipe_handles->pipe_ref_count,
              get_pipe_name_from_syntax(talloc_tos(), syntax)));

    return True;
}
Ejemplo n.º 3
0
static bool check_bind_req(struct pipes_struct *p,
			   struct ndr_syntax_id* abstract,
			   struct ndr_syntax_id* transfer,
			   uint32_t context_id)
{
	struct pipe_rpc_fns *context_fns;
	bool ok;

	DEBUG(3,("check_bind_req for %s\n",
		 ndr_interface_name(&abstract->uuid,
				    abstract->if_version)));

	/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
	if (rpc_srv_pipe_exists_by_id(abstract) &&
	   ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
		DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
			  rpc_srv_get_pipe_cli_name(abstract),
			  rpc_srv_get_pipe_srv_name(abstract)));
	} else {
		return false;
	}

	ok = init_pipe_handles(p, abstract);
	if (!ok) {
		DEBUG(1, ("Failed to init pipe handles!\n"));
		return false;
	}

	context_fns = talloc(p, struct pipe_rpc_fns);
	if (context_fns == NULL) {
		DEBUG(0,("check_bind_req: talloc() failed!\n"));
		return false;
	}

	context_fns->next = context_fns->prev = NULL;
	context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
	context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
	context_fns->context_id = context_id;
	context_fns->syntax = *abstract;

	/* add to the list of open contexts */

	DLIST_ADD( p->contexts, context_fns );

	return True;
}
Ejemplo n.º 4
0
static NTSTATUS pipe_cm_find(struct cli_state *cli,
			     const struct ndr_syntax_id *interface,
			     struct rpc_pipe_client **presult)
{
	struct client_pipe_connection *p;

	for (p = pipe_connections; p; p = p->next) {

		if (!rpc_pipe_np_smb_conn(p->pipe)) {
			return NT_STATUS_PIPE_EMPTY;
		}

		if (strequal(cli->desthost, p->pipe->desthost)
		    && ndr_syntax_id_equal(&p->pipe->abstract_syntax,
					   interface)) {
			*presult = p->pipe;
			return NT_STATUS_OK;
		}
	}

	return NT_STATUS_PIPE_NOT_AVAILABLE;
}
Ejemplo n.º 5
0
_PUBLIC_ NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b,
						     const struct ndr_syntax_id *syntax)
{
	NTSTATUS status;
	char *s = NULL;

	if (syntax == NULL) {
		status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		return NT_STATUS_OK;
	}

	if (ndr_syntax_id_equal(&ndr_syntax_id_null, syntax)) {
		status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		return NT_STATUS_OK;
	}

	s = ndr_syntax_id_to_string(b, syntax);
	if (s == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = dcerpc_binding_set_string_option(b, "abstract_syntax", s);
	TALLOC_FREE(s);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	return NT_STATUS_OK;
}
Ejemplo n.º 6
0
static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
{
	return (ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id)
		|| ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
}
Ejemplo n.º 7
0
bool init_pipe_handles(struct pipes_struct *p, const struct ndr_syntax_id *syntax)
{
	struct pipes_struct *plist;
	struct handle_list *hl;

	for (plist = InternalPipes; plist; plist = plist->next) {
		struct pipe_rpc_fns *p_ctx;
		bool stop = false;

		for (p_ctx = plist->contexts;
		     p_ctx != NULL;
		     p_ctx = p_ctx->next) {
			if (ndr_syntax_id_equal(syntax, &p_ctx->syntax)) {
				stop = true;
				break;
			}
			if (is_samr_lsa_pipe(&p_ctx->syntax)
			    && is_samr_lsa_pipe(syntax)) {
				/*
				 * samr and lsa share a handle space (same process
				 * under Windows?)
				 */
				stop = true;
				break;
			}
		}

		if (stop) {
			break;
		}
	}

	if (plist != NULL) {
		hl = plist->pipe_handles;
		if (hl == NULL) {
			return false;
		}
	} else {
		/*
		 * First open, we have to create the handle list
		 */
		hl = talloc_zero(NULL, struct handle_list);
		if (hl == NULL) {
			return false;
		}

		DEBUG(10,("init_pipe_handle_list: created handle list for "
			  "pipe %s\n",
			  get_pipe_name_from_syntax(talloc_tos(), syntax)));
	}

	/*
	 * One more pipe is using this list.
	 */

	hl->pipe_ref_count++;

	/*
	 * Point this pipe at this list.
	 */

	p->pipe_handles = hl;

	DEBUG(10,("init_pipe_handle_list: pipe_handles ref count = %lu for "
		  "pipe %s\n", (unsigned long)p->pipe_handles->pipe_ref_count,
		  get_pipe_name_from_syntax(talloc_tos(), syntax)));

	return True;
}
NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
				     const char *server_name,
				     const char *domain,
				     const char *clnt_name,
				     const char *machine_account,
				     const unsigned char machine_pwd[16],
				     enum netr_SchannelType sec_chan_type,
				     uint32_t *neg_flags_inout)
{
	NTSTATUS status;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	struct netr_Credential clnt_chal_send;
	struct netr_Credential srv_chal_recv;
	struct samr_Password password;
	bool retried = false;
	fstring mach_acct;
	uint32_t neg_flags = *neg_flags_inout;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	if (!ndr_syntax_id_equal(&cli->abstract_syntax,
				 &ndr_table_netlogon.syntax_id)) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	TALLOC_FREE(cli->dc);

	/* Store the machine account password we're going to use. */
	memcpy(password.hash, machine_pwd, 16);

	fstr_sprintf( mach_acct, "%s$", machine_account);

 again:
	/* Create the client challenge. */
	generate_random_buffer(clnt_chal_send.data, 8);

	/* Get the server challenge. */
	status = dcerpc_netr_ServerReqChallenge(b, talloc_tos(),
						cli->srv_name_slash,
						clnt_name,
						&clnt_chal_send,
						&srv_chal_recv,
						&result);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	if (!NT_STATUS_IS_OK(result)) {
		return result;
	}

	/* Calculate the session key and client credentials */

	cli->dc = netlogon_creds_client_init(cli,
				    mach_acct,
				    clnt_name,
				    &clnt_chal_send,
				    &srv_chal_recv,
				    &password,
				    &clnt_chal_send,
				    neg_flags);

	if (!cli->dc) {
		return NT_STATUS_NO_MEMORY;
	}

	/*
	 * Send client auth-2 challenge and receive server repy.
	 */

	status = dcerpc_netr_ServerAuthenticate2(b, talloc_tos(),
						 cli->srv_name_slash,
						 cli->dc->account_name,
						 sec_chan_type,
						 cli->dc->computer_name,
						 &clnt_chal_send, /* input. */
						 &srv_chal_recv, /* output. */
						 &neg_flags,
						 &result);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	/* we might be talking to NT4, so let's downgrade in that case and retry
	 * with the returned neg_flags - gd */

	if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) {
		retried = true;
		TALLOC_FREE(cli->dc);
		goto again;
	}

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

	/*
	 * Check the returned value using the initial
	 * server received challenge.
	 */

	if (!netlogon_creds_client_check(cli->dc, &srv_chal_recv)) {
		/*
		 * Server replied with bad credential. Fail.
		 */
		DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
			"replied with bad credential\n",
			cli->desthost ));
		return NT_STATUS_ACCESS_DENIED;
	}

	DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
		"chain established.\n",
		cli->desthost ));

	cli->dc->negotiate_flags = neg_flags;
	*neg_flags_inout = neg_flags;

	return NT_STATUS_OK;
}
Ejemplo n.º 9
0
static bool test_Map_tcpip(struct torture_context *tctx,
			   struct dcerpc_binding_handle *h,
			   struct ndr_syntax_id map_syntax)
{
	struct epm_Map r;
	struct GUID uuid;
	struct policy_handle entry_handle;
	struct ndr_syntax_id syntax;
	struct dcerpc_binding map_binding;
	struct epm_twr_t map_tower;
	struct epm_twr_p_t towers[20];
	struct epm_tower t;
	uint32_t num_towers;
	uint32_t port;
	uint32_t i;
	long int p;
	const char *tmp;
	const char *ip;
	char *ptr;
	NTSTATUS status;

	torture_comment(tctx, "Testing epm_Map\n");

	ZERO_STRUCT(uuid);
	ZERO_STRUCT(entry_handle);

	r.in.object = &uuid;
	r.in.map_tower = &map_tower;
	r.in.entry_handle = &entry_handle;
	r.out.entry_handle = &entry_handle;
	r.in.max_towers = 10;
	r.out.towers = towers;
	r.out.num_towers = &num_towers;

	/* Create map tower */
	map_binding.transport = NCACN_IP_TCP;
	map_binding.object = map_syntax;
	map_binding.host = "0.0.0.0";
	map_binding.endpoint = "135";

	status = dcerpc_binding_build_tower(tctx, &map_binding,
					    &map_tower.tower);
	torture_assert_ntstatus_ok(tctx, status,
				   "epm_Map_tcpip failed: can't create map_tower");

	torture_comment(tctx,
			"epm_Map request for '%s':\n",
			ndr_interface_name(&map_syntax.uuid, map_syntax.if_version));
	display_tower(tctx, &r.in.map_tower->tower);

	status = dcerpc_epm_Map_r(h, tctx, &r);

	torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed");
	torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK,
		       "epm_Map_tcpip failed: result is not EPMAPPER_STATUS_OK");

	/* Check the result */
	t = r.out.towers[0].twr->tower;

	/* Check if we got the correct RPC interface identifier */
	dcerpc_floor_get_lhs_data(&t.floors[0], &syntax);
	torture_assert(tctx, ndr_syntax_id_equal(&syntax, &map_syntax),
		       "epm_Map_tcpip failed: Interface identifier mismatch");

	torture_comment(tctx,
			"epm_Map_tcpip response for '%s':\n",
			ndr_interface_name(&syntax.uuid, syntax.if_version));

	dcerpc_floor_get_lhs_data(&t.floors[1], &syntax);
	torture_assert(tctx, ndr_syntax_id_equal(&syntax, &ndr_transfer_syntax_ndr),
		       "epm_Map_tcpip failed: floor 2 is not NDR encoded");

	torture_assert(tctx, t.floors[2].lhs.protocol == EPM_PROTOCOL_NCACN,
		       "epm_Map_tcpip failed: floor 3 is not NCACN_IP_TCP");

	tmp = dcerpc_floor_get_rhs_data(tctx, &t.floors[3]);
	p = strtol(tmp, &ptr, 10);
	port = p & 0xffff;
	torture_assert(tctx, port > 1024 && port < 65535, "epm_Map_tcpip failed");

	ip = dcerpc_floor_get_rhs_data(tctx, &t.floors[4]);
	torture_assert(tctx, is_ipaddress(ip), "epm_Map_tcpip failed");

	for (i = 0; i < *r.out.num_towers; i++) {
		if (r.out.towers[i].twr) {
			display_tower(tctx, &t);
		}
	}

	return true;
}
Ejemplo n.º 10
0
NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
			TALLOC_CTX *mem_ctx,
			const struct ndr_interface_table *table,
			uint32 opnum, void *r)
{
#ifdef AVM_SMALL
	return NT_STATUS_NO_MEMORY;
#else
	prs_struct q_ps, r_ps;
	const struct ndr_interface_call *call;
	struct ndr_pull *pull;
	DATA_BLOB blob;
	struct ndr_push *push;
	NTSTATUS status;
	enum ndr_err_code ndr_err;

	SMB_ASSERT(ndr_syntax_id_equal(&table->syntax_id,
				       &cli->abstract_syntax));
	SMB_ASSERT(table->num_calls > opnum);

	call = &table->calls[opnum];

	push = ndr_push_init_ctx(mem_ctx);
	if (!push) {
		return NT_STATUS_NO_MEMORY;
	}

	ndr_err = call->ndr_push(push, NDR_IN, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		return ndr_map_error2ntstatus(ndr_err);
	}

	blob = ndr_push_blob(push);

	if (!prs_init_data_blob(&q_ps, &blob, mem_ctx)) {
		return NT_STATUS_NO_MEMORY;
	}

	talloc_free(push);

	prs_init_empty( &r_ps, mem_ctx, UNMARSHALL );
	
	status = rpc_api_pipe_req(cli, opnum, &q_ps, &r_ps); 

	prs_mem_free( &q_ps );

	if (!NT_STATUS_IS_OK(status)) {
		prs_mem_free( &r_ps );
		return status;
	}

	if (!prs_data_blob(&r_ps, &blob, mem_ctx)) {
		prs_mem_free( &r_ps );
		return NT_STATUS_NO_MEMORY;
	}

	prs_mem_free( &r_ps );

	pull = ndr_pull_init_blob(&blob, mem_ctx);
	if (pull == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* have the ndr parser alloc memory for us */
	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	ndr_err = call->ndr_pull(pull, NDR_OUT, r);
	talloc_free(pull);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		return ndr_map_error2ntstatus(ndr_err);
	}

	return NT_STATUS_OK;
#endif
}