2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1998,
5 * Largely re-written : 2005
6 * Copyright (C) Jeremy Allison 1998 - 2005
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "fake_file.h"
26 #include "rpc_server/rpc_ncacn_np.h"
27 #include "rpc_server/srv_pipe_hnd.h"
28 #include "rpc_server/srv_pipe.h"
29 #include "rpc_server/rpc_server.h"
30 #include "rpc_server/rpc_config.h"
31 #include "../lib/tsocket/tsocket.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "librpc/ndr/ndr_table.h"
36 #define DBGC_CLASS DBGC_RPC_SRV
38 /****************************************************************************
39 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
40 ****************************************************************************/
42 static ssize_t fill_rpc_header(struct pipes_struct *p, const char *data, size_t data_to_copy)
44 size_t len_needed_to_complete_hdr =
45 MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu.length);
47 DEBUG(10, ("fill_rpc_header: data_to_copy = %u, "
48 "len_needed_to_complete_hdr = %u, "
50 (unsigned int)data_to_copy,
51 (unsigned int)len_needed_to_complete_hdr,
52 (unsigned int)p->in_data.pdu.length ));
54 if (p->in_data.pdu.data == NULL) {
55 p->in_data.pdu.data = talloc_array(p, uint8_t, RPC_HEADER_LEN);
57 if (p->in_data.pdu.data == NULL) {
58 DEBUG(0, ("talloc failed\n"));
62 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
63 data, len_needed_to_complete_hdr);
64 p->in_data.pdu.length += len_needed_to_complete_hdr;
66 return (ssize_t)len_needed_to_complete_hdr;
69 static bool get_pdu_size(struct pipes_struct *p)
72 /* the fill_rpc_header() call insures we copy only
73 * RPC_HEADER_LEN bytes. If this doesn't match then
74 * somethign is very wrong and we can only abort */
75 if (p->in_data.pdu.length != RPC_HEADER_LEN) {
76 DEBUG(0, ("Unexpected RPC Header size! "
77 "got %d, expected %d)\n",
78 (int)p->in_data.pdu.length,
80 set_incoming_fault(p);
84 frag_len = dcerpc_get_frag_length(&p->in_data.pdu);
86 /* verify it is a reasonable value */
87 if ((frag_len < RPC_HEADER_LEN) ||
88 (frag_len > RPC_MAX_PDU_FRAG_LEN)) {
89 DEBUG(0, ("Unexpected RPC Fragment size! (%d)\n",
91 set_incoming_fault(p);
95 p->in_data.pdu_needed_len = frag_len - RPC_HEADER_LEN;
97 /* allocate the space needed to fill the pdu */
98 p->in_data.pdu.data = talloc_realloc(p, p->in_data.pdu.data,
100 if (p->in_data.pdu.data == NULL) {
101 DEBUG(0, ("talloc_realloc failed\n"));
102 set_incoming_fault(p);
109 /****************************************************************************
110 Call this to free any talloc'ed memory. Do this after processing
111 a complete incoming and outgoing request (multiple incoming/outgoing
113 ****************************************************************************/
115 static void free_pipe_context(struct pipes_struct *p)
117 data_blob_free(&p->out_data.frag);
118 data_blob_free(&p->out_data.rdata);
119 data_blob_free(&p->in_data.data);
121 DEBUG(3, ("free_pipe_context: "
122 "destroying talloc pool of size %lu\n",
123 (unsigned long)talloc_total_size(p->mem_ctx)));
124 talloc_free_children(p->mem_ctx);
127 /****************************************************************************
128 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
129 ****************************************************************************/
131 ssize_t process_incoming_data(struct pipes_struct *p, const char *data, size_t n)
133 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN
134 - p->in_data.pdu.length);
136 DEBUG(10, ("process_incoming_data: Start: pdu.length = %u, "
137 "pdu_needed_len = %u, incoming data = %u\n",
138 (unsigned int)p->in_data.pdu.length,
139 (unsigned int)p->in_data.pdu_needed_len,
142 if(data_to_copy == 0) {
144 * This is an error - data is being received and there is no
145 * space in the PDU. Free the received data and go into the
148 DEBUG(0, ("process_incoming_data: "
149 "No space in incoming pdu buffer. "
150 "Current size = %u incoming data size = %u\n",
151 (unsigned int)p->in_data.pdu.length,
153 set_incoming_fault(p);
158 * If we have no data already, wait until we get at least
159 * a RPC_HEADER_LEN * number of bytes before we can do anything.
162 if ((p->in_data.pdu_needed_len == 0) &&
163 (p->in_data.pdu.length < RPC_HEADER_LEN)) {
165 * Always return here. If we have more data then the RPC_HEADER
166 * will be processed the next time around the loop.
168 return fill_rpc_header(p, data, data_to_copy);
172 * At this point we know we have at least an RPC_HEADER_LEN amount of
173 * data stored in p->in_data.pdu.
177 * If pdu_needed_len is zero this is a new pdu.
178 * Check how much more data we need, then loop again.
180 if (p->in_data.pdu_needed_len == 0) {
182 bool ok = get_pdu_size(p);
186 if (p->in_data.pdu_needed_len > 0) {
190 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU
191 * that consists of an RPC_HEADER only. This is a
192 * DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or
193 * DCERPC_PKT_ORPHANED pdu type.
194 * Deal with this in process_complete_pdu(). */
198 * Ok - at this point we have a valid RPC_HEADER.
199 * Keep reading until we have a full pdu.
202 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
205 * Copy as much of the data as we need into the p->in_data.pdu buffer.
206 * pdu_needed_len becomes zero when we have a complete pdu.
209 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
211 p->in_data.pdu.length += data_to_copy;
212 p->in_data.pdu_needed_len -= data_to_copy;
215 * Do we have a complete PDU ?
216 * (return the number of bytes handled in the call)
219 if(p->in_data.pdu_needed_len == 0) {
220 process_complete_pdu(p);
224 DEBUG(10, ("process_incoming_data: not a complete PDU yet. "
225 "pdu.length = %u, pdu_needed_len = %u\n",
226 (unsigned int)p->in_data.pdu.length,
227 (unsigned int)p->in_data.pdu_needed_len));
229 return (ssize_t)data_to_copy;
232 /****************************************************************************
233 Accepts incoming data on an internal rpc pipe.
234 ****************************************************************************/
236 static ssize_t write_to_internal_pipe(struct pipes_struct *p, const char *data, size_t n)
238 size_t data_left = n;
243 DEBUG(10, ("write_to_pipe: data_left = %u\n",
244 (unsigned int)data_left));
246 data_used = process_incoming_data(p, data, data_left);
248 DEBUG(10, ("write_to_pipe: data_used = %d\n",
255 data_left -= data_used;
262 /****************************************************************************
263 Replies to a request to read data from a pipe.
265 Headers are interspersed with the data at PDU intervals. By the time
266 this function is called, the start of the data could possibly have been
267 read by an SMBtrans (file_offset != 0).
269 Calling create_rpc_reply() here is a hack. The data should already
270 have been prepared into arrays of headers + data stream sections.
271 ****************************************************************************/
273 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
274 size_t n, bool *is_data_outstanding)
276 uint32 pdu_remaining = 0;
277 ssize_t data_returned = 0;
280 DEBUG(0,("read_from_pipe: pipe not open\n"));
284 DEBUG(6,(" name: %s len: %u\n",
285 ndr_interface_name(&p->contexts->syntax.uuid,
286 p->contexts->syntax.if_version),
290 * We cannot return more than one PDU length per
295 * This condition should result in the connection being closed.
296 * Netapp filers seem to set it to 0xffff which results in domain
297 * authentications failing. Just ignore it so things work.
300 if(n > RPC_MAX_PDU_FRAG_LEN) {
301 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
302 "pipe %s. We can only service %d sized reads.\n",
304 ndr_interface_name(&p->contexts->syntax.uuid,
305 p->contexts->syntax.if_version),
306 RPC_MAX_PDU_FRAG_LEN ));
307 n = RPC_MAX_PDU_FRAG_LEN;
311 * Determine if there is still data to send in the
312 * pipe PDU buffer. Always send this first. Never
313 * send more than is left in the current PDU. The
314 * client should send a new read request for a new
318 pdu_remaining = p->out_data.frag.length
319 - p->out_data.current_pdu_sent;
321 if (pdu_remaining > 0) {
322 data_returned = (ssize_t)MIN(n, pdu_remaining);
324 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
325 "current_pdu_sent = %u returning %d bytes.\n",
326 ndr_interface_name(&p->contexts->syntax.uuid,
327 p->contexts->syntax.if_version),
328 (unsigned int)p->out_data.frag.length,
329 (unsigned int)p->out_data.current_pdu_sent,
330 (int)data_returned));
333 p->out_data.frag.data
334 + p->out_data.current_pdu_sent,
337 p->out_data.current_pdu_sent += (uint32)data_returned;
342 * At this point p->current_pdu_len == p->current_pdu_sent (which
343 * may of course be zero if this is the first return fragment.
346 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
347 "= %u, p->out_data.rdata.length = %u.\n",
348 ndr_interface_name(&p->contexts->syntax.uuid,
349 p->contexts->syntax.if_version),
351 (unsigned int)p->out_data.data_sent_length,
352 (unsigned int)p->out_data.rdata.length));
354 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
356 * We have sent all possible data, return 0.
363 * We need to create a new PDU from the data left in p->rdata.
364 * Create the header/data/footers. This also sets up the fields
365 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
366 * and stores the outgoing PDU in p->current_pdu.
369 if(!create_next_pdu(p)) {
370 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
371 ndr_interface_name(&p->contexts->syntax.uuid,
372 p->contexts->syntax.if_version)));
376 data_returned = MIN(n, p->out_data.frag.length);
378 memcpy(data, p->out_data.frag.data, (size_t)data_returned);
379 p->out_data.current_pdu_sent += (uint32)data_returned;
382 (*is_data_outstanding) = p->out_data.frag.length > n;
384 if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
385 /* We've returned everything in the out_data.frag
386 * so we're done with this pdu. Free it and reset
387 * current_pdu_sent. */
388 p->out_data.current_pdu_sent = 0;
389 data_blob_free(&p->out_data.frag);
391 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
393 * We're completely finished with both outgoing and
394 * incoming data streams. It's safe to free all
395 * temporary data from this request.
397 free_pipe_context(p);
401 return data_returned;
404 bool fsp_is_np(struct files_struct *fsp)
406 enum FAKE_FILE_TYPE type;
408 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
412 type = fsp->fake_file_handle->type;
414 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
415 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
418 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
419 const struct tsocket_address *local_address,
420 const struct tsocket_address *remote_address,
421 struct auth_session_info *session_info,
422 struct tevent_context *ev_ctx,
423 struct messaging_context *msg_ctx,
424 struct fake_file_handle **phandle)
426 enum rpc_service_mode_e pipe_mode;
427 const char **proxy_list;
428 struct fake_file_handle *handle;
429 struct ndr_syntax_id syntax;
430 struct npa_state *npa = NULL;
434 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
436 handle = talloc(mem_ctx, struct fake_file_handle);
437 if (handle == NULL) {
438 return NT_STATUS_NO_MEMORY;
441 /* Check what is the server type for this pipe.
442 Defaults to "embedded" */
443 pipe_mode = rpc_service_mode(name);
445 /* Still support the old method for defining external servers */
446 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
447 pipe_mode = RPC_SERVICE_MODE_EXTERNAL;
451 case RPC_SERVICE_MODE_EXTERNAL:
452 status = make_external_rpc_pipe(handle,
458 if (!NT_STATUS_IS_OK(status)) {
463 handle->private_data = (void *)npa;
464 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
467 case RPC_SERVICE_MODE_EMBEDDED:
468 /* Check if we this daemon handles this pipe */
469 ok = is_known_pipename(name, &syntax);
471 DEBUG(0, ("ERROR! '%s' is not a registred pipe!\n",
474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
477 status = make_internal_rpc_pipe_socketpair(handle,
485 if (!NT_STATUS_IS_OK(status)) {
490 handle->private_data = (void *)npa;
491 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
494 case RPC_SERVICE_MODE_DISABLED:
496 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
504 bool np_read_in_progress(struct fake_file_handle *handle)
506 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
510 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
511 struct npa_state *p =
512 talloc_get_type_abort(handle->private_data,
516 read_count = tevent_queue_length(p->read_queue);
517 if (read_count > 0) {
527 struct np_write_state {
528 struct tevent_context *ev;
534 static void np_write_done(struct tevent_req *subreq);
536 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
537 struct fake_file_handle *handle,
538 const uint8_t *data, size_t len)
540 struct tevent_req *req;
541 struct np_write_state *state;
544 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
545 dump_data(50, data, len);
547 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
554 status = NT_STATUS_OK;
558 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
559 struct npa_state *npa =
560 talloc_get_type_abort(handle->private_data,
562 struct pipes_struct *p =
563 talloc_get_type_abort(npa->private_data,
564 struct pipes_struct);
566 state->nwritten = write_to_internal_pipe(p, (const char *)data, len);
568 status = (state->nwritten >= 0)
569 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
573 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
574 struct npa_state *p = talloc_get_type_abort(
575 handle->private_data, struct npa_state);
576 struct tevent_req *subreq;
580 state->iov.iov_base = discard_const_p(void, data);
581 state->iov.iov_len = len;
583 subreq = tstream_writev_queue_send(state, ev,
587 if (subreq == NULL) {
590 tevent_req_set_callback(subreq, np_write_done, req);
594 status = NT_STATUS_INVALID_HANDLE;
596 if (NT_STATUS_IS_OK(status)) {
597 tevent_req_done(req);
599 tevent_req_nterror(req, status);
601 return tevent_req_post(req, ev);
607 static void np_write_done(struct tevent_req *subreq)
609 struct tevent_req *req = tevent_req_callback_data(
610 subreq, struct tevent_req);
611 struct np_write_state *state = tevent_req_data(
612 req, struct np_write_state);
616 received = tstream_writev_queue_recv(subreq, &err);
618 tevent_req_nterror(req, map_nt_error_from_unix(err));
621 state->nwritten = received;
622 tevent_req_done(req);
625 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
627 struct np_write_state *state = tevent_req_data(
628 req, struct np_write_state);
631 if (tevent_req_is_nterror(req, &status)) {
634 *pnwritten = state->nwritten;
638 struct np_ipc_readv_next_vector_state {
645 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
646 uint8_t *buf, size_t len)
651 s->len = MIN(len, UINT16_MAX);
654 static int np_ipc_readv_next_vector(struct tstream_context *stream,
657 struct iovec **_vector,
660 struct np_ipc_readv_next_vector_state *state =
661 (struct np_ipc_readv_next_vector_state *)private_data;
662 struct iovec *vector;
666 if (state->ofs == state->len) {
672 pending = tstream_pending_bytes(stream);
677 if (pending == 0 && state->ofs != 0) {
678 /* return a short read */
685 /* we want at least one byte and recheck again */
688 size_t missing = state->len - state->ofs;
689 if (pending > missing) {
690 /* there's more available */
691 state->remaining = pending - missing;
694 /* read what we can get and recheck in the next cycle */
699 vector = talloc_array(mem_ctx, struct iovec, 1);
704 vector[0].iov_base = state->buf + state->ofs;
705 vector[0].iov_len = wanted;
707 state->ofs += wanted;
714 struct np_read_state {
716 struct np_ipc_readv_next_vector_state next_vector;
719 bool is_data_outstanding;
722 static void np_read_done(struct tevent_req *subreq);
724 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
725 struct fake_file_handle *handle,
726 uint8_t *data, size_t len)
728 struct tevent_req *req;
729 struct np_read_state *state;
732 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
737 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
738 struct npa_state *npa =
739 talloc_get_type_abort(handle->private_data,
741 struct pipes_struct *p =
742 talloc_get_type_abort(npa->private_data,
743 struct pipes_struct);
745 state->nread = read_from_internal_pipe(
746 p, (char *)data, len, &state->is_data_outstanding);
748 status = (state->nread >= 0)
749 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
753 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
754 struct npa_state *p = talloc_get_type_abort(
755 handle->private_data, struct npa_state);
756 struct tevent_req *subreq;
758 np_ipc_readv_next_vector_init(&state->next_vector,
761 subreq = tstream_readv_pdu_queue_send(state,
765 np_ipc_readv_next_vector,
766 &state->next_vector);
767 if (subreq == NULL) {
768 status = NT_STATUS_NO_MEMORY;
771 tevent_req_set_callback(subreq, np_read_done, req);
775 status = NT_STATUS_INVALID_HANDLE;
777 if (NT_STATUS_IS_OK(status)) {
778 tevent_req_done(req);
780 tevent_req_nterror(req, status);
782 return tevent_req_post(req, ev);
785 static void np_read_done(struct tevent_req *subreq)
787 struct tevent_req *req = tevent_req_callback_data(
788 subreq, struct tevent_req);
789 struct np_read_state *state = tevent_req_data(
790 req, struct np_read_state);
794 ret = tstream_readv_pdu_queue_recv(subreq, &err);
797 tevent_req_nterror(req, map_nt_error_from_unix(err));
802 state->is_data_outstanding = (state->next_vector.remaining > 0);
804 tevent_req_done(req);
808 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
809 bool *is_data_outstanding)
811 struct np_read_state *state = tevent_req_data(
812 req, struct np_read_state);
815 if (tevent_req_is_nterror(req, &status)) {
819 DEBUG(10, ("Received %d bytes. There is %smore data outstanding\n",
820 (int)state->nread, state->is_data_outstanding?"":"no "));
822 *nread = state->nread;
823 *is_data_outstanding = state->is_data_outstanding;