Exemple #1
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;
}
Exemple #2
0
Fichier : cm.c Projet : ekohl/samba
WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
			   const char *server_name,
			   const struct ndr_syntax_id *interface,
			   struct rpc_pipe_client **presult)
{
	struct rpc_pipe_client *result = NULL;
	NTSTATUS status;
	WERROR werr;
	struct client_ipc_connection *ipc = NULL;

	if (!presult) {
		return WERR_INVALID_PARAM;
	}

	werr = libnetapi_open_ipc_connection(ctx, server_name, &ipc);
	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	status = pipe_cm_open(ctx, ipc, interface, &result);
	if (!NT_STATUS_IS_OK(status)) {
		libnetapi_set_error_string(ctx, "failed to open PIPE %s: %s",
			get_pipe_name_from_syntax(talloc_tos(), interface),
			get_friendly_nt_error_msg(status));
		return WERR_DEST_NOT_FOUND;
	}

	*presult = result;

	return WERR_OK;
}
Exemple #3
0
void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
			    uint32_t access_granted, size_t data_size,
			    const char *type, NTSTATUS *pstatus)
{
	struct dcesrv_handle *rpc_hnd;
	void *data;

	if (p->pipe_handles->count > MAX_OPEN_POLS) {
		DEBUG(0, ("ERROR: Too many handles (%d) for RPC connection %s\n",
			  (int) p->pipe_handles->count,
			  get_pipe_name_from_syntax(talloc_tos(),
						    &p->contexts->syntax)));
		*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
		return NULL;
	}

	data = talloc_size(talloc_tos(), data_size);
	if (data == NULL) {
		*pstatus = NT_STATUS_NO_MEMORY;
		return NULL;
	}
	talloc_set_name_const(data, type);

	rpc_hnd = create_rpc_handle_internal(p, hnd, data);
	if (rpc_hnd == NULL) {
		TALLOC_FREE(data);
		*pstatus = NT_STATUS_NO_MEMORY;
		return NULL;
	}
	rpc_hnd->access_granted = access_granted;
	*pstatus = NT_STATUS_OK;
	return data;
}
Exemple #4
0
void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
                            uint32_t access_granted, size_t data_size,
                            const char *type, NTSTATUS *pstatus)
{
    struct policy *pol;
    void *data;

    if (p->pipe_handles->count > MAX_OPEN_POLS) {
        DEBUG(0, ("policy_handle_create: ERROR: too many handles (%d) "
                  "on pipe %s.\n", (int)p->pipe_handles->count,
                  get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
        *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
        return NULL;
    }

    data = talloc_size(talloc_tos(), data_size);
    if (data == NULL) {
        *pstatus = NT_STATUS_NO_MEMORY;
        return NULL;
    }
    talloc_set_name_const(data, type);

    pol = create_policy_hnd_internal(p, hnd, data);
    if (pol == NULL) {
        TALLOC_FREE(data);
        *pstatus = NT_STATUS_NO_MEMORY;
        return NULL;
    }
    pol->access_granted = access_granted;
    *pstatus = NT_STATUS_OK;
    return data;
}
Exemple #5
0
struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
					      const struct ndr_syntax_id *syntax,
					      const struct tsocket_address *remote_address,
					      const struct auth_session_info *session_info,
					      struct messaging_context *msg_ctx)
{
	struct pipes_struct *p;
	struct pipe_rpc_fns *context_fns;
	const char *pipe_name;
	int ret;

	pipe_name = get_pipe_name_from_syntax(talloc_tos(), syntax);

	DEBUG(4,("Create pipe requested %s\n", pipe_name));

	ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
				     NCALRPC, RPC_LITTLE_ENDIAN, false,
				     remote_address, NULL, &p);
	if (ret) {
		DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
		return NULL;
	}

	if (!init_pipe_handles(p, syntax)) {
		DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	p->session_info = copy_session_info(p, session_info);
	if (p->session_info == NULL) {
		DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
		close_policy_by_pipe(p);
		TALLOC_FREE(p);
		return NULL;
	}

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

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

	/* add to the list of open contexts */
	DLIST_ADD(p->contexts, context_fns);

	DEBUG(4,("Created internal pipe %s\n", pipe_name));

	return p;
}
Exemple #6
0
void close_policy_by_pipe(struct pipes_struct *p)
{
	if (p->pipe_handles == NULL) {
		return;
	}

	p->pipe_handles->pipe_ref_count--;

	if (p->pipe_handles->pipe_ref_count == 0) {
		/*
		 * Last pipe open on this list - free the list.
		 */
		TALLOC_FREE(p->pipe_handles);

		DEBUG(10,("Deleted handle list for RPC connection %s\n",
			  get_pipe_name_from_syntax(talloc_tos(),
						    &p->contexts->syntax)));
	}
}
Exemple #7
0
void close_policy_by_pipe(pipes_struct *p)
{
    p->pipe_handles->pipe_ref_count--;

    if (p->pipe_handles->pipe_ref_count == 0) {
        /*
         * Last pipe open on this list - free the list.
         */
        while (p->pipe_handles->Policy)
            close_policy_hnd(p, &p->pipe_handles->Policy->pol_hnd);

        p->pipe_handles->Policy = NULL;
        p->pipe_handles->count = 0;

        SAFE_FREE(p->pipe_handles);
        DEBUG(10,("close_policy_by_pipe: deleted handle list for "
                  "pipe %s\n",
                  get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
    }
}
Exemple #8
0
struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
					      const struct ndr_syntax_id *syntax,
					      const struct tsocket_address *remote_address,
					      const struct auth_serversupplied_info *session_info,
					      struct messaging_context *msg_ctx)
{
	struct pipes_struct *p;
	struct pipe_rpc_fns *context_fns;

	DEBUG(4,("Create pipe requested %s\n",
		 get_pipe_name_from_syntax(talloc_tos(), syntax)));

	p = talloc_zero(mem_ctx, struct pipes_struct);

	if (!p) {
		DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
		return NULL;
	}

	p->mem_ctx = talloc_named(p, 0, "pipe %s %p",
				 get_pipe_name_from_syntax(talloc_tos(),
							   syntax), p);
	if (p->mem_ctx == NULL) {
		DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	if (!init_pipe_handles(p, syntax)) {
		DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	p->session_info = copy_serverinfo(p, session_info);
	if (p->session_info == NULL) {
		DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
		close_policy_by_pipe(p);
		TALLOC_FREE(p);
		return NULL;
	}

	p->msg_ctx = msg_ctx;

	DLIST_ADD(InternalPipes, p);

	p->remote_address = tsocket_address_copy(remote_address, p);
	if (p->remote_address == NULL) {
		return false;
	}

	p->endian = RPC_LITTLE_ENDIAN;

	p->transport = NCALRPC;

	context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
	if (context_fns == NULL) {
		DEBUG(0,("malloc() failed!\n"));
		return False;
	}

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

	/* add to the list of open contexts */
	DLIST_ADD(p->contexts, context_fns);

	DEBUG(4,("Created internal pipe %s\n",
		 get_pipe_name_from_syntax(talloc_tos(), syntax)));

	talloc_set_destructor(p, close_internal_rpc_pipe_hnd);

	return p;
}
Exemple #9
0
static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
				       size_t n, bool *is_data_outstanding)
{
	uint32 pdu_remaining = 0;
	ssize_t data_returned = 0;

	if (!p) {
		DEBUG(0,("read_from_pipe: pipe not open\n"));
		return -1;
	}

	DEBUG(6,(" name: %s len: %u\n",
		 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
		 (unsigned int)n));

	/*
	 * We cannot return more than one PDU length per
	 * read request.
	 */

	/*
	 * This condition should result in the connection being closed.
	 * Netapp filers seem to set it to 0xffff which results in domain
	 * authentications failing.  Just ignore it so things work.
	 */

	if(n > RPC_MAX_PDU_FRAG_LEN) {
                DEBUG(5,("read_from_pipe: too large read (%u) requested on "
			 "pipe %s. We can only service %d sized reads.\n",
			 (unsigned int)n,
			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
			 RPC_MAX_PDU_FRAG_LEN ));
		n = RPC_MAX_PDU_FRAG_LEN;
	}

	/*
 	 * Determine if there is still data to send in the
	 * pipe PDU buffer. Always send this first. Never
	 * send more than is left in the current PDU. The
	 * client should send a new read request for a new
	 * PDU.
	 */

	pdu_remaining = p->out_data.frag.length
		- p->out_data.current_pdu_sent;

	if (pdu_remaining > 0) {
		data_returned = (ssize_t)MIN(n, pdu_remaining);

		DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
			  "current_pdu_sent = %u returning %d bytes.\n",
			  get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
			  (unsigned int)p->out_data.frag.length,
			  (unsigned int)p->out_data.current_pdu_sent,
			  (int)data_returned));

		memcpy(data,
		       p->out_data.frag.data
		       + p->out_data.current_pdu_sent,
		       data_returned);

		p->out_data.current_pdu_sent += (uint32)data_returned;
		goto out;
	}

	/*
	 * At this point p->current_pdu_len == p->current_pdu_sent (which
	 * may of course be zero if this is the first return fragment.
	 */

	DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
		  "= %u, p->out_data.rdata.length = %u.\n",
		  get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
		  (int)p->fault_state,
		  (unsigned int)p->out_data.data_sent_length,
		  (unsigned int)p->out_data.rdata.length));

	if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
		/*
		 * We have sent all possible data, return 0.
		 */
		data_returned = 0;
		goto out;
	}

	/*
	 * We need to create a new PDU from the data left in p->rdata.
	 * Create the header/data/footers. This also sets up the fields
	 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
	 * and stores the outgoing PDU in p->current_pdu.
	 */

	if(!create_next_pdu(p)) {
		DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
		return -1;
	}

	data_returned = MIN(n, p->out_data.frag.length);

	memcpy(data, p->out_data.frag.data, (size_t)data_returned);
	p->out_data.current_pdu_sent += (uint32)data_returned;

  out:
	(*is_data_outstanding) = p->out_data.frag.length > n;

	if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
		/* We've returned everything in the out_data.frag
		 * so we're done with this pdu. Free it and reset
		 * current_pdu_sent. */
		p->out_data.current_pdu_sent = 0;
		data_blob_free(&p->out_data.frag);

		if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
			/*
			 * We're completely finished with both outgoing and
			 * incoming data streams. It's safe to free all
			 * temporary data from this request.
			 */
			free_pipe_context(p);
		}
	}

	return data_returned;
}
Exemple #10
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;
}