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 "../librpc/gen_ndr/srv_spoolss.h"
24 #include "librpc/gen_ndr/ndr_named_pipe_auth.h"
25 #include "../libcli/named_pipe_auth/npa_tstream.h"
26 #include "rpc_server.h"
27 #include "smbd/globals.h"
28 #include "fake_file.h"
31 #define DBGC_CLASS DBGC_RPC_SRV
33 /****************************************************************************
34 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
35 ****************************************************************************/
37 static ssize_t fill_rpc_header(struct pipes_struct *p, char *data, size_t data_to_copy)
39 size_t len_needed_to_complete_hdr =
40 MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu.length);
42 DEBUG(10, ("fill_rpc_header: data_to_copy = %u, "
43 "len_needed_to_complete_hdr = %u, "
45 (unsigned int)data_to_copy,
46 (unsigned int)len_needed_to_complete_hdr,
47 (unsigned int)p->in_data.pdu.length ));
49 if (p->in_data.pdu.data == NULL) {
50 p->in_data.pdu.data = talloc_array(p, uint8_t, RPC_HEADER_LEN);
52 if (p->in_data.pdu.data == NULL) {
53 DEBUG(0, ("talloc failed\n"));
57 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
58 data, len_needed_to_complete_hdr);
59 p->in_data.pdu.length += len_needed_to_complete_hdr;
61 return (ssize_t)len_needed_to_complete_hdr;
64 static bool get_pdu_size(struct pipes_struct *p)
67 /* the fill_rpc_header() call insures we copy only
68 * RPC_HEADER_LEN bytes. If this doesn't match then
69 * somethign is very wrong and we can only abort */
70 if (p->in_data.pdu.length != RPC_HEADER_LEN) {
71 DEBUG(0, ("Unexpected RPC Header size! "
72 "got %d, expected %d)\n",
73 (int)p->in_data.pdu.length,
75 set_incoming_fault(p);
79 frag_len = dcerpc_get_frag_length(&p->in_data.pdu);
81 /* verify it is a reasonable value */
82 if ((frag_len < RPC_HEADER_LEN) ||
83 (frag_len > RPC_MAX_PDU_FRAG_LEN)) {
84 DEBUG(0, ("Unexpected RPC Fragment size! (%d)\n",
86 set_incoming_fault(p);
90 p->in_data.pdu_needed_len = frag_len - RPC_HEADER_LEN;
92 /* allocate the space needed to fill the pdu */
93 p->in_data.pdu.data = talloc_realloc(p, p->in_data.pdu.data,
95 if (p->in_data.pdu.data == NULL) {
96 DEBUG(0, ("talloc_realloc failed\n"));
97 set_incoming_fault(p);
104 /****************************************************************************
105 Call this to free any talloc'ed memory. Do this after processing
106 a complete incoming and outgoing request (multiple incoming/outgoing
108 ****************************************************************************/
110 static void free_pipe_context(struct pipes_struct *p)
112 data_blob_free(&p->out_data.frag);
113 data_blob_free(&p->out_data.rdata);
114 data_blob_free(&p->in_data.data);
116 DEBUG(3, ("free_pipe_context: "
117 "destroying talloc pool of size %lu\n",
118 (unsigned long)talloc_total_size(p->mem_ctx)));
119 talloc_free_children(p->mem_ctx);
122 /****************************************************************************
123 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
124 ****************************************************************************/
126 static ssize_t process_incoming_data(struct pipes_struct *p, char *data, size_t n)
128 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN
129 - p->in_data.pdu.length);
131 DEBUG(10, ("process_incoming_data: Start: pdu.length = %u, "
132 "pdu_needed_len = %u, incoming data = %u\n",
133 (unsigned int)p->in_data.pdu.length,
134 (unsigned int)p->in_data.pdu_needed_len,
137 if(data_to_copy == 0) {
139 * This is an error - data is being received and there is no
140 * space in the PDU. Free the received data and go into the
143 DEBUG(0, ("process_incoming_data: "
144 "No space in incoming pdu buffer. "
145 "Current size = %u incoming data size = %u\n",
146 (unsigned int)p->in_data.pdu.length,
148 set_incoming_fault(p);
153 * If we have no data already, wait until we get at least
154 * a RPC_HEADER_LEN * number of bytes before we can do anything.
157 if ((p->in_data.pdu_needed_len == 0) &&
158 (p->in_data.pdu.length < RPC_HEADER_LEN)) {
160 * Always return here. If we have more data then the RPC_HEADER
161 * will be processed the next time around the loop.
163 return fill_rpc_header(p, data, data_to_copy);
167 * At this point we know we have at least an RPC_HEADER_LEN amount of
168 * data stored in p->in_data.pdu.
172 * If pdu_needed_len is zero this is a new pdu.
173 * Check how much more data we need, then loop again.
175 if (p->in_data.pdu_needed_len == 0) {
177 bool ok = get_pdu_size(p);
181 if (p->in_data.pdu_needed_len > 0) {
185 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU
186 * that consists of an RPC_HEADER only. This is a
187 * DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or
188 * DCERPC_PKT_ORPHANED pdu type.
189 * Deal with this in process_complete_pdu(). */
193 * Ok - at this point we have a valid RPC_HEADER.
194 * Keep reading until we have a full pdu.
197 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
200 * Copy as much of the data as we need into the p->in_data.pdu buffer.
201 * pdu_needed_len becomes zero when we have a complete pdu.
204 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
206 p->in_data.pdu.length += data_to_copy;
207 p->in_data.pdu_needed_len -= data_to_copy;
210 * Do we have a complete PDU ?
211 * (return the number of bytes handled in the call)
214 if(p->in_data.pdu_needed_len == 0) {
215 process_complete_pdu(p);
219 DEBUG(10, ("process_incoming_data: not a complete PDU yet. "
220 "pdu.length = %u, pdu_needed_len = %u\n",
221 (unsigned int)p->in_data.pdu.length,
222 (unsigned int)p->in_data.pdu_needed_len));
224 return (ssize_t)data_to_copy;
227 /****************************************************************************
228 Accepts incoming data on an internal rpc pipe.
229 ****************************************************************************/
231 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
233 size_t data_left = n;
238 DEBUG(10, ("write_to_pipe: data_left = %u\n",
239 (unsigned int)data_left));
241 data_used = process_incoming_data(p, data, data_left);
243 DEBUG(10, ("write_to_pipe: data_used = %d\n",
250 data_left -= data_used;
257 /****************************************************************************
258 Replies to a request to read data from a pipe.
260 Headers are interspersed with the data at PDU intervals. By the time
261 this function is called, the start of the data could possibly have been
262 read by an SMBtrans (file_offset != 0).
264 Calling create_rpc_reply() here is a hack. The data should already
265 have been prepared into arrays of headers + data stream sections.
266 ****************************************************************************/
268 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
269 size_t n, bool *is_data_outstanding)
271 uint32 pdu_remaining = 0;
272 ssize_t data_returned = 0;
275 DEBUG(0,("read_from_pipe: pipe not open\n"));
279 DEBUG(6,(" name: %s len: %u\n",
280 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
284 * We cannot return more than one PDU length per
289 * This condition should result in the connection being closed.
290 * Netapp filers seem to set it to 0xffff which results in domain
291 * authentications failing. Just ignore it so things work.
294 if(n > RPC_MAX_PDU_FRAG_LEN) {
295 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
296 "pipe %s. We can only service %d sized reads.\n",
298 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
299 RPC_MAX_PDU_FRAG_LEN ));
300 n = RPC_MAX_PDU_FRAG_LEN;
304 * Determine if there is still data to send in the
305 * pipe PDU buffer. Always send this first. Never
306 * send more than is left in the current PDU. The
307 * client should send a new read request for a new
311 pdu_remaining = p->out_data.frag.length
312 - p->out_data.current_pdu_sent;
314 if (pdu_remaining > 0) {
315 data_returned = (ssize_t)MIN(n, pdu_remaining);
317 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
318 "current_pdu_sent = %u returning %d bytes.\n",
319 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
320 (unsigned int)p->out_data.frag.length,
321 (unsigned int)p->out_data.current_pdu_sent,
322 (int)data_returned));
325 p->out_data.frag.data
326 + p->out_data.current_pdu_sent,
329 p->out_data.current_pdu_sent += (uint32)data_returned;
334 * At this point p->current_pdu_len == p->current_pdu_sent (which
335 * may of course be zero if this is the first return fragment.
338 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
339 "= %u, p->out_data.rdata.length = %u.\n",
340 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
342 (unsigned int)p->out_data.data_sent_length,
343 (unsigned int)p->out_data.rdata.length));
345 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
347 * We have sent all possible data, return 0.
354 * We need to create a new PDU from the data left in p->rdata.
355 * Create the header/data/footers. This also sets up the fields
356 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
357 * and stores the outgoing PDU in p->current_pdu.
360 if(!create_next_pdu(p)) {
361 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
362 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
366 data_returned = MIN(n, p->out_data.frag.length);
368 memcpy(data, p->out_data.frag.data, (size_t)data_returned);
369 p->out_data.current_pdu_sent += (uint32)data_returned;
372 (*is_data_outstanding) = p->out_data.frag.length > n;
374 if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
375 /* We've returned everything in the out_data.frag
376 * so we're done with this pdu. Free it and reset
377 * current_pdu_sent. */
378 p->out_data.current_pdu_sent = 0;
379 data_blob_free(&p->out_data.frag);
381 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
383 * We're completely finished with both outgoing and
384 * incoming data streams. It's safe to free all
385 * temporary data from this request.
387 free_pipe_context(p);
391 return data_returned;
394 bool fsp_is_np(struct files_struct *fsp)
396 enum FAKE_FILE_TYPE type;
398 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
402 type = fsp->fake_file_handle->type;
404 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
405 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
408 struct np_proxy_state {
410 uint16_t device_state;
411 uint64_t allocation_size;
412 struct tstream_context *npipe;
413 struct tevent_queue *read_queue;
414 struct tevent_queue *write_queue;
417 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
418 const char *pipe_name,
419 const struct tsocket_address *local_address,
420 const struct tsocket_address *remote_address,
421 struct auth_serversupplied_info *server_info)
423 struct np_proxy_state *result;
425 const char *socket_dir;
426 struct tevent_context *ev;
427 struct tevent_req *subreq;
428 struct netr_SamInfo3 *info3;
434 result = talloc(mem_ctx, struct np_proxy_state);
435 if (result == NULL) {
436 DEBUG(0, ("talloc failed\n"));
440 result->read_queue = tevent_queue_create(result, "np_read");
441 if (result->read_queue == NULL) {
442 DEBUG(0, ("tevent_queue_create failed\n"));
446 result->write_queue = tevent_queue_create(result, "np_write");
447 if (result->write_queue == NULL) {
448 DEBUG(0, ("tevent_queue_create failed\n"));
452 ev = s3_tevent_context_init(talloc_tos());
454 DEBUG(0, ("s3_tevent_context_init failed\n"));
458 socket_dir = lp_parm_const_string(
459 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
460 get_dyn_NCALRPCDIR());
461 if (socket_dir == NULL) {
462 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
465 socket_np_dir = talloc_asprintf(talloc_tos(), "%s/np", socket_dir);
466 if (socket_np_dir == NULL) {
467 DEBUG(0, ("talloc_asprintf failed\n"));
471 info3 = talloc_zero(talloc_tos(), struct netr_SamInfo3);
473 DEBUG(0, ("talloc failed\n"));
477 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
478 if (!NT_STATUS_IS_OK(status)) {
480 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
486 subreq = tstream_npa_connect_send(talloc_tos(), ev,
489 remote_address, /* client_addr */
490 NULL, /* client_name */
491 local_address, /* server_addr */
492 NULL, /* server_name */
494 server_info->user_session_key,
495 data_blob_null /* delegated_creds */);
496 if (subreq == NULL) {
498 DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and "
499 "user %s\\%s failed\n",
500 socket_np_dir, pipe_name, info3->base.domain.string,
501 info3->base.account_name.string));
504 ok = tevent_req_poll(subreq, ev);
507 DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s "
508 "failed for tstream_npa_connect: %s\n",
509 socket_np_dir, pipe_name, info3->base.domain.string,
510 info3->base.account_name.string,
515 ret = tstream_npa_connect_recv(subreq, &sys_errno,
519 &result->device_state,
520 &result->allocation_size);
523 DEBUG(0, ("tstream_npa_connect_recv to %s for pipe %s and "
524 "user %s\\%s failed: %s\n",
525 socket_np_dir, pipe_name, info3->base.domain.string,
526 info3->base.account_name.string,
527 strerror(sys_errno)));
538 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
539 const struct tsocket_address *local_address,
540 const struct tsocket_address *remote_address,
541 struct client_address *client_id,
542 struct auth_serversupplied_info *server_info,
543 struct messaging_context *msg_ctx,
544 struct fake_file_handle **phandle)
546 const char **proxy_list;
547 struct fake_file_handle *handle;
549 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
551 handle = talloc(mem_ctx, struct fake_file_handle);
552 if (handle == NULL) {
553 return NT_STATUS_NO_MEMORY;
556 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
557 struct np_proxy_state *p;
559 p = make_external_rpc_pipe_p(handle, name,
564 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
565 handle->private_data = p;
567 struct pipes_struct *p;
568 struct ndr_syntax_id syntax;
570 if (!is_known_pipename(name, &syntax)) {
572 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
575 p = make_internal_rpc_pipe_p(handle, &syntax, client_id,
576 server_info, msg_ctx);
578 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
579 handle->private_data = p;
582 if (handle->private_data == NULL) {
584 return NT_STATUS_PIPE_NOT_AVAILABLE;
592 bool np_read_in_progress(struct fake_file_handle *handle)
594 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
598 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
599 struct np_proxy_state *p = talloc_get_type_abort(
600 handle->private_data, struct np_proxy_state);
603 read_count = tevent_queue_length(p->read_queue);
604 if (read_count > 0) {
614 struct np_write_state {
615 struct event_context *ev;
616 struct np_proxy_state *p;
621 static void np_write_done(struct tevent_req *subreq);
623 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
624 struct fake_file_handle *handle,
625 const uint8_t *data, size_t len)
627 struct tevent_req *req;
628 struct np_write_state *state;
631 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
632 dump_data(50, data, len);
634 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
641 status = NT_STATUS_OK;
645 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
646 struct pipes_struct *p = talloc_get_type_abort(
647 handle->private_data, struct pipes_struct);
649 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
651 status = (state->nwritten >= 0)
652 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
656 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
657 struct np_proxy_state *p = talloc_get_type_abort(
658 handle->private_data, struct np_proxy_state);
659 struct tevent_req *subreq;
663 state->iov.iov_base = CONST_DISCARD(void *, data);
664 state->iov.iov_len = len;
666 subreq = tstream_writev_queue_send(state, ev,
670 if (subreq == NULL) {
673 tevent_req_set_callback(subreq, np_write_done, req);
677 status = NT_STATUS_INVALID_HANDLE;
679 if (NT_STATUS_IS_OK(status)) {
680 tevent_req_done(req);
682 tevent_req_nterror(req, status);
684 return tevent_req_post(req, ev);
690 static void np_write_done(struct tevent_req *subreq)
692 struct tevent_req *req = tevent_req_callback_data(
693 subreq, struct tevent_req);
694 struct np_write_state *state = tevent_req_data(
695 req, struct np_write_state);
699 received = tstream_writev_queue_recv(subreq, &err);
701 tevent_req_nterror(req, map_nt_error_from_unix(err));
704 state->nwritten = received;
705 tevent_req_done(req);
708 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
710 struct np_write_state *state = tevent_req_data(
711 req, struct np_write_state);
714 if (tevent_req_is_nterror(req, &status)) {
717 *pnwritten = state->nwritten;
721 struct np_ipc_readv_next_vector_state {
728 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
729 uint8_t *buf, size_t len)
734 s->len = MIN(len, UINT16_MAX);
737 static int np_ipc_readv_next_vector(struct tstream_context *stream,
740 struct iovec **_vector,
743 struct np_ipc_readv_next_vector_state *state =
744 (struct np_ipc_readv_next_vector_state *)private_data;
745 struct iovec *vector;
749 if (state->ofs == state->len) {
755 pending = tstream_pending_bytes(stream);
760 if (pending == 0 && state->ofs != 0) {
761 /* return a short read */
768 /* we want at least one byte and recheck again */
771 size_t missing = state->len - state->ofs;
772 if (pending > missing) {
773 /* there's more available */
774 state->remaining = pending - missing;
777 /* read what we can get and recheck in the next cycle */
782 vector = talloc_array(mem_ctx, struct iovec, 1);
787 vector[0].iov_base = state->buf + state->ofs;
788 vector[0].iov_len = wanted;
790 state->ofs += wanted;
797 struct np_read_state {
798 struct np_proxy_state *p;
799 struct np_ipc_readv_next_vector_state next_vector;
802 bool is_data_outstanding;
805 static void np_read_done(struct tevent_req *subreq);
807 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
808 struct fake_file_handle *handle,
809 uint8_t *data, size_t len)
811 struct tevent_req *req;
812 struct np_read_state *state;
815 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
820 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
821 struct pipes_struct *p = talloc_get_type_abort(
822 handle->private_data, struct pipes_struct);
824 state->nread = read_from_internal_pipe(
825 p, (char *)data, len, &state->is_data_outstanding);
827 status = (state->nread >= 0)
828 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
832 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
833 struct np_proxy_state *p = talloc_get_type_abort(
834 handle->private_data, struct np_proxy_state);
835 struct tevent_req *subreq;
837 np_ipc_readv_next_vector_init(&state->next_vector,
840 subreq = tstream_readv_pdu_queue_send(state,
844 np_ipc_readv_next_vector,
845 &state->next_vector);
846 if (subreq == NULL) {
849 tevent_req_set_callback(subreq, np_read_done, req);
853 status = NT_STATUS_INVALID_HANDLE;
855 if (NT_STATUS_IS_OK(status)) {
856 tevent_req_done(req);
858 tevent_req_nterror(req, status);
860 return tevent_req_post(req, ev);
863 static void np_read_done(struct tevent_req *subreq)
865 struct tevent_req *req = tevent_req_callback_data(
866 subreq, struct tevent_req);
867 struct np_read_state *state = tevent_req_data(
868 req, struct np_read_state);
872 ret = tstream_readv_pdu_queue_recv(subreq, &err);
875 tevent_req_nterror(req, map_nt_error_from_unix(err));
880 state->is_data_outstanding = (state->next_vector.remaining > 0);
882 tevent_req_done(req);
886 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
887 bool *is_data_outstanding)
889 struct np_read_state *state = tevent_req_data(
890 req, struct np_read_state);
893 if (tevent_req_is_nterror(req, &status)) {
896 *nread = state->nread;
897 *is_data_outstanding = state->is_data_outstanding;
902 * @brief Create a new RPC client context which uses a local dispatch function.
904 * @param[in] conn The connection struct that will hold the pipe
906 * @param[out] spoolss_pipe A pointer to the connected rpc client pipe.
908 * @return NT_STATUS_OK on success, a corresponding NT status if an
911 NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
912 struct rpc_pipe_client **spoolss_pipe)
916 /* TODO: check and handle disconnections */
918 if (!conn->spoolss_pipe) {
919 status = rpc_pipe_open_internal(conn,
920 &ndr_table_spoolss.syntax_id,
922 &conn->sconn->client_id,
923 conn->sconn->msg_ctx,
924 &conn->spoolss_pipe);
925 if (!NT_STATUS_IS_OK(status)) {
930 *spoolss_pipe = conn->spoolss_pipe;