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"
32 #define DBGC_CLASS DBGC_RPC_SRV
34 /****************************************************************************
35 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
36 ****************************************************************************/
38 static ssize_t fill_rpc_header(struct pipes_struct *p, char *data, size_t data_to_copy)
40 size_t len_needed_to_complete_hdr =
41 MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu.length);
43 DEBUG(10, ("fill_rpc_header: data_to_copy = %u, "
44 "len_needed_to_complete_hdr = %u, "
46 (unsigned int)data_to_copy,
47 (unsigned int)len_needed_to_complete_hdr,
48 (unsigned int)p->in_data.pdu.length ));
50 if (p->in_data.pdu.data == NULL) {
51 p->in_data.pdu.data = talloc_array(p, uint8_t, RPC_HEADER_LEN);
53 if (p->in_data.pdu.data == NULL) {
54 DEBUG(0, ("talloc failed\n"));
58 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
59 data, len_needed_to_complete_hdr);
60 p->in_data.pdu.length += len_needed_to_complete_hdr;
62 return (ssize_t)len_needed_to_complete_hdr;
65 static bool get_pdu_size(struct pipes_struct *p)
68 /* the fill_rpc_header() call insures we copy only
69 * RPC_HEADER_LEN bytes. If this doesn't match then
70 * somethign is very wrong and we can only abort */
71 if (p->in_data.pdu.length != RPC_HEADER_LEN) {
72 DEBUG(0, ("Unexpected RPC Header size! "
73 "got %d, expected %d)\n",
74 (int)p->in_data.pdu.length,
76 set_incoming_fault(p);
80 frag_len = dcerpc_get_frag_length(&p->in_data.pdu);
82 /* verify it is a reasonable value */
83 if ((frag_len < RPC_HEADER_LEN) ||
84 (frag_len > RPC_MAX_PDU_FRAG_LEN)) {
85 DEBUG(0, ("Unexpected RPC Fragment size! (%d)\n",
87 set_incoming_fault(p);
91 p->in_data.pdu_needed_len = frag_len - RPC_HEADER_LEN;
93 /* allocate the space needed to fill the pdu */
94 p->in_data.pdu.data = talloc_realloc(p, p->in_data.pdu.data,
96 if (p->in_data.pdu.data == NULL) {
97 DEBUG(0, ("talloc_realloc failed\n"));
98 set_incoming_fault(p);
105 /****************************************************************************
106 Call this to free any talloc'ed memory. Do this after processing
107 a complete incoming and outgoing request (multiple incoming/outgoing
109 ****************************************************************************/
111 static void free_pipe_context(struct pipes_struct *p)
113 data_blob_free(&p->out_data.frag);
114 data_blob_free(&p->out_data.rdata);
115 data_blob_free(&p->in_data.data);
117 DEBUG(3, ("free_pipe_context: "
118 "destroying talloc pool of size %lu\n",
119 (unsigned long)talloc_total_size(p->mem_ctx)));
120 talloc_free_children(p->mem_ctx);
123 /****************************************************************************
124 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
125 ****************************************************************************/
127 ssize_t process_incoming_data(struct pipes_struct *p, char *data, size_t n)
129 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN
130 - p->in_data.pdu.length);
132 DEBUG(10, ("process_incoming_data: Start: pdu.length = %u, "
133 "pdu_needed_len = %u, incoming data = %u\n",
134 (unsigned int)p->in_data.pdu.length,
135 (unsigned int)p->in_data.pdu_needed_len,
138 if(data_to_copy == 0) {
140 * This is an error - data is being received and there is no
141 * space in the PDU. Free the received data and go into the
144 DEBUG(0, ("process_incoming_data: "
145 "No space in incoming pdu buffer. "
146 "Current size = %u incoming data size = %u\n",
147 (unsigned int)p->in_data.pdu.length,
149 set_incoming_fault(p);
154 * If we have no data already, wait until we get at least
155 * a RPC_HEADER_LEN * number of bytes before we can do anything.
158 if ((p->in_data.pdu_needed_len == 0) &&
159 (p->in_data.pdu.length < RPC_HEADER_LEN)) {
161 * Always return here. If we have more data then the RPC_HEADER
162 * will be processed the next time around the loop.
164 return fill_rpc_header(p, data, data_to_copy);
168 * At this point we know we have at least an RPC_HEADER_LEN amount of
169 * data stored in p->in_data.pdu.
173 * If pdu_needed_len is zero this is a new pdu.
174 * Check how much more data we need, then loop again.
176 if (p->in_data.pdu_needed_len == 0) {
178 bool ok = get_pdu_size(p);
182 if (p->in_data.pdu_needed_len > 0) {
186 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU
187 * that consists of an RPC_HEADER only. This is a
188 * DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or
189 * DCERPC_PKT_ORPHANED pdu type.
190 * Deal with this in process_complete_pdu(). */
194 * Ok - at this point we have a valid RPC_HEADER.
195 * Keep reading until we have a full pdu.
198 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
201 * Copy as much of the data as we need into the p->in_data.pdu buffer.
202 * pdu_needed_len becomes zero when we have a complete pdu.
205 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
207 p->in_data.pdu.length += data_to_copy;
208 p->in_data.pdu_needed_len -= data_to_copy;
211 * Do we have a complete PDU ?
212 * (return the number of bytes handled in the call)
215 if(p->in_data.pdu_needed_len == 0) {
216 process_complete_pdu(p);
220 DEBUG(10, ("process_incoming_data: not a complete PDU yet. "
221 "pdu.length = %u, pdu_needed_len = %u\n",
222 (unsigned int)p->in_data.pdu.length,
223 (unsigned int)p->in_data.pdu_needed_len));
225 return (ssize_t)data_to_copy;
228 /****************************************************************************
229 Accepts incoming data on an internal rpc pipe.
230 ****************************************************************************/
232 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
234 size_t data_left = n;
239 DEBUG(10, ("write_to_pipe: data_left = %u\n",
240 (unsigned int)data_left));
242 data_used = process_incoming_data(p, data, data_left);
244 DEBUG(10, ("write_to_pipe: data_used = %d\n",
251 data_left -= data_used;
258 /****************************************************************************
259 Replies to a request to read data from a pipe.
261 Headers are interspersed with the data at PDU intervals. By the time
262 this function is called, the start of the data could possibly have been
263 read by an SMBtrans (file_offset != 0).
265 Calling create_rpc_reply() here is a hack. The data should already
266 have been prepared into arrays of headers + data stream sections.
267 ****************************************************************************/
269 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
270 size_t n, bool *is_data_outstanding)
272 uint32 pdu_remaining = 0;
273 ssize_t data_returned = 0;
276 DEBUG(0,("read_from_pipe: pipe not open\n"));
280 DEBUG(6,(" name: %s len: %u\n",
281 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
285 * We cannot return more than one PDU length per
290 * This condition should result in the connection being closed.
291 * Netapp filers seem to set it to 0xffff which results in domain
292 * authentications failing. Just ignore it so things work.
295 if(n > RPC_MAX_PDU_FRAG_LEN) {
296 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
297 "pipe %s. We can only service %d sized reads.\n",
299 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
300 RPC_MAX_PDU_FRAG_LEN ));
301 n = RPC_MAX_PDU_FRAG_LEN;
305 * Determine if there is still data to send in the
306 * pipe PDU buffer. Always send this first. Never
307 * send more than is left in the current PDU. The
308 * client should send a new read request for a new
312 pdu_remaining = p->out_data.frag.length
313 - p->out_data.current_pdu_sent;
315 if (pdu_remaining > 0) {
316 data_returned = (ssize_t)MIN(n, pdu_remaining);
318 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
319 "current_pdu_sent = %u returning %d bytes.\n",
320 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
321 (unsigned int)p->out_data.frag.length,
322 (unsigned int)p->out_data.current_pdu_sent,
323 (int)data_returned));
326 p->out_data.frag.data
327 + p->out_data.current_pdu_sent,
330 p->out_data.current_pdu_sent += (uint32)data_returned;
335 * At this point p->current_pdu_len == p->current_pdu_sent (which
336 * may of course be zero if this is the first return fragment.
339 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
340 "= %u, p->out_data.rdata.length = %u.\n",
341 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
343 (unsigned int)p->out_data.data_sent_length,
344 (unsigned int)p->out_data.rdata.length));
346 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
348 * We have sent all possible data, return 0.
355 * We need to create a new PDU from the data left in p->rdata.
356 * Create the header/data/footers. This also sets up the fields
357 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
358 * and stores the outgoing PDU in p->current_pdu.
361 if(!create_next_pdu(p)) {
362 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
363 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
367 data_returned = MIN(n, p->out_data.frag.length);
369 memcpy(data, p->out_data.frag.data, (size_t)data_returned);
370 p->out_data.current_pdu_sent += (uint32)data_returned;
373 (*is_data_outstanding) = p->out_data.frag.length > n;
375 if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
376 /* We've returned everything in the out_data.frag
377 * so we're done with this pdu. Free it and reset
378 * current_pdu_sent. */
379 p->out_data.current_pdu_sent = 0;
380 data_blob_free(&p->out_data.frag);
382 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
384 * We're completely finished with both outgoing and
385 * incoming data streams. It's safe to free all
386 * temporary data from this request.
388 free_pipe_context(p);
392 return data_returned;
395 bool fsp_is_np(struct files_struct *fsp)
397 enum FAKE_FILE_TYPE type;
399 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
403 type = fsp->fake_file_handle->type;
405 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
406 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
409 struct np_proxy_state {
411 uint16_t device_state;
412 uint64_t allocation_size;
413 struct tstream_context *npipe;
414 struct tevent_queue *read_queue;
415 struct tevent_queue *write_queue;
418 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
419 const char *pipe_name,
420 const struct tsocket_address *local_address,
421 const struct tsocket_address *remote_address,
422 struct auth_serversupplied_info *server_info)
424 struct np_proxy_state *result;
426 const char *socket_dir;
427 struct tevent_context *ev;
428 struct tevent_req *subreq;
429 struct netr_SamInfo3 *info3;
435 result = talloc(mem_ctx, struct np_proxy_state);
436 if (result == NULL) {
437 DEBUG(0, ("talloc failed\n"));
441 result->read_queue = tevent_queue_create(result, "np_read");
442 if (result->read_queue == NULL) {
443 DEBUG(0, ("tevent_queue_create failed\n"));
447 result->write_queue = tevent_queue_create(result, "np_write");
448 if (result->write_queue == NULL) {
449 DEBUG(0, ("tevent_queue_create failed\n"));
453 ev = s3_tevent_context_init(talloc_tos());
455 DEBUG(0, ("s3_tevent_context_init failed\n"));
459 socket_dir = lp_parm_const_string(
460 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
462 if (socket_dir == NULL) {
463 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
466 socket_np_dir = talloc_asprintf(talloc_tos(), "%s/np", socket_dir);
467 if (socket_np_dir == NULL) {
468 DEBUG(0, ("talloc_asprintf failed\n"));
472 info3 = talloc_zero(talloc_tos(), struct netr_SamInfo3);
474 DEBUG(0, ("talloc failed\n"));
478 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
479 if (!NT_STATUS_IS_OK(status)) {
481 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
487 subreq = tstream_npa_connect_send(talloc_tos(), ev,
490 remote_address, /* client_addr */
491 NULL, /* client_name */
492 local_address, /* server_addr */
493 NULL, /* server_name */
495 server_info->user_session_key,
496 data_blob_null /* delegated_creds */);
497 if (subreq == NULL) {
499 DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and "
500 "user %s\\%s failed\n",
501 socket_np_dir, pipe_name, info3->base.domain.string,
502 info3->base.account_name.string));
505 ok = tevent_req_poll(subreq, ev);
508 DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s "
509 "failed for tstream_npa_connect: %s\n",
510 socket_np_dir, pipe_name, info3->base.domain.string,
511 info3->base.account_name.string,
516 ret = tstream_npa_connect_recv(subreq, &sys_errno,
520 &result->device_state,
521 &result->allocation_size);
524 DEBUG(0, ("tstream_npa_connect_recv to %s for pipe %s and "
525 "user %s\\%s failed: %s\n",
526 socket_np_dir, pipe_name, info3->base.domain.string,
527 info3->base.account_name.string,
528 strerror(sys_errno)));
539 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
540 const struct tsocket_address *local_address,
541 const struct tsocket_address *remote_address,
542 struct client_address *client_id,
543 struct auth_serversupplied_info *server_info,
544 struct messaging_context *msg_ctx,
545 struct fake_file_handle **phandle)
547 const char *rpcsrv_type;
548 const char **proxy_list;
549 struct fake_file_handle *handle;
550 bool external = false;
552 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
554 handle = talloc(mem_ctx, struct fake_file_handle);
555 if (handle == NULL) {
556 return NT_STATUS_NO_MEMORY;
559 /* Check what is the server type for this pipe.
560 Defaults to "embedded" */
561 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
564 if (StrCaseCmp(rpcsrv_type, "embedded") != 0) {
568 /* Still support the old method for defining external servers */
569 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
574 struct np_proxy_state *p;
576 p = make_external_rpc_pipe_p(handle, name,
581 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
582 handle->private_data = p;
584 struct pipes_struct *p;
585 struct ndr_syntax_id syntax;
587 if (!is_known_pipename(name, &syntax)) {
589 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
592 p = make_internal_rpc_pipe_p(handle, &syntax, client_id,
593 server_info, msg_ctx);
595 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
596 handle->private_data = p;
599 if (handle->private_data == NULL) {
601 return NT_STATUS_PIPE_NOT_AVAILABLE;
609 bool np_read_in_progress(struct fake_file_handle *handle)
611 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
615 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
616 struct np_proxy_state *p = talloc_get_type_abort(
617 handle->private_data, struct np_proxy_state);
620 read_count = tevent_queue_length(p->read_queue);
621 if (read_count > 0) {
631 struct np_write_state {
632 struct event_context *ev;
633 struct np_proxy_state *p;
638 static void np_write_done(struct tevent_req *subreq);
640 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
641 struct fake_file_handle *handle,
642 const uint8_t *data, size_t len)
644 struct tevent_req *req;
645 struct np_write_state *state;
648 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
649 dump_data(50, data, len);
651 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
658 status = NT_STATUS_OK;
662 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
663 struct pipes_struct *p = talloc_get_type_abort(
664 handle->private_data, struct pipes_struct);
666 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
668 status = (state->nwritten >= 0)
669 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
673 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
674 struct np_proxy_state *p = talloc_get_type_abort(
675 handle->private_data, struct np_proxy_state);
676 struct tevent_req *subreq;
680 state->iov.iov_base = CONST_DISCARD(void *, data);
681 state->iov.iov_len = len;
683 subreq = tstream_writev_queue_send(state, ev,
687 if (subreq == NULL) {
690 tevent_req_set_callback(subreq, np_write_done, req);
694 status = NT_STATUS_INVALID_HANDLE;
696 if (NT_STATUS_IS_OK(status)) {
697 tevent_req_done(req);
699 tevent_req_nterror(req, status);
701 return tevent_req_post(req, ev);
707 static void np_write_done(struct tevent_req *subreq)
709 struct tevent_req *req = tevent_req_callback_data(
710 subreq, struct tevent_req);
711 struct np_write_state *state = tevent_req_data(
712 req, struct np_write_state);
716 received = tstream_writev_queue_recv(subreq, &err);
718 tevent_req_nterror(req, map_nt_error_from_unix(err));
721 state->nwritten = received;
722 tevent_req_done(req);
725 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
727 struct np_write_state *state = tevent_req_data(
728 req, struct np_write_state);
731 if (tevent_req_is_nterror(req, &status)) {
734 *pnwritten = state->nwritten;
738 struct np_ipc_readv_next_vector_state {
745 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
746 uint8_t *buf, size_t len)
751 s->len = MIN(len, UINT16_MAX);
754 static int np_ipc_readv_next_vector(struct tstream_context *stream,
757 struct iovec **_vector,
760 struct np_ipc_readv_next_vector_state *state =
761 (struct np_ipc_readv_next_vector_state *)private_data;
762 struct iovec *vector;
766 if (state->ofs == state->len) {
772 pending = tstream_pending_bytes(stream);
777 if (pending == 0 && state->ofs != 0) {
778 /* return a short read */
785 /* we want at least one byte and recheck again */
788 size_t missing = state->len - state->ofs;
789 if (pending > missing) {
790 /* there's more available */
791 state->remaining = pending - missing;
794 /* read what we can get and recheck in the next cycle */
799 vector = talloc_array(mem_ctx, struct iovec, 1);
804 vector[0].iov_base = state->buf + state->ofs;
805 vector[0].iov_len = wanted;
807 state->ofs += wanted;
814 struct np_read_state {
815 struct np_proxy_state *p;
816 struct np_ipc_readv_next_vector_state next_vector;
819 bool is_data_outstanding;
822 static void np_read_done(struct tevent_req *subreq);
824 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
825 struct fake_file_handle *handle,
826 uint8_t *data, size_t len)
828 struct tevent_req *req;
829 struct np_read_state *state;
832 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
837 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
838 struct pipes_struct *p = talloc_get_type_abort(
839 handle->private_data, struct pipes_struct);
841 state->nread = read_from_internal_pipe(
842 p, (char *)data, len, &state->is_data_outstanding);
844 status = (state->nread >= 0)
845 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
849 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
850 struct np_proxy_state *p = talloc_get_type_abort(
851 handle->private_data, struct np_proxy_state);
852 struct tevent_req *subreq;
854 np_ipc_readv_next_vector_init(&state->next_vector,
857 subreq = tstream_readv_pdu_queue_send(state,
861 np_ipc_readv_next_vector,
862 &state->next_vector);
863 if (subreq == NULL) {
864 status = NT_STATUS_NO_MEMORY;
867 tevent_req_set_callback(subreq, np_read_done, req);
871 status = NT_STATUS_INVALID_HANDLE;
873 if (NT_STATUS_IS_OK(status)) {
874 tevent_req_done(req);
876 tevent_req_nterror(req, status);
878 return tevent_req_post(req, ev);
881 static void np_read_done(struct tevent_req *subreq)
883 struct tevent_req *req = tevent_req_callback_data(
884 subreq, struct tevent_req);
885 struct np_read_state *state = tevent_req_data(
886 req, struct np_read_state);
890 ret = tstream_readv_pdu_queue_recv(subreq, &err);
893 tevent_req_nterror(req, map_nt_error_from_unix(err));
898 state->is_data_outstanding = (state->next_vector.remaining > 0);
900 tevent_req_done(req);
904 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
905 bool *is_data_outstanding)
907 struct np_read_state *state = tevent_req_data(
908 req, struct np_read_state);
911 if (tevent_req_is_nterror(req, &status)) {
915 DEBUG(10, ("Received %d bytes. There is %smore data outstanding\n",
916 (int)state->nread, state->is_data_outstanding?"":"no "));
918 *nread = state->nread;
919 *is_data_outstanding = state->is_data_outstanding;
924 static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx,
925 const char *pipe_name,
926 const struct ndr_syntax_id *abstract_syntax,
927 struct auth_serversupplied_info *server_info,
928 struct rpc_pipe_client **_result)
930 struct tsocket_address *local, *remote;
931 struct rpc_pipe_client *result = NULL;
932 struct np_proxy_state *proxy_state = NULL;
933 struct pipe_auth_data *auth;
937 /* this is an internal connection, fake up ip addresses */
938 ret = tsocket_address_inet_from_strings(talloc_tos(), "ip",
941 return NT_STATUS_NO_MEMORY;
943 ret = tsocket_address_inet_from_strings(talloc_tos(), "ip",
946 return NT_STATUS_NO_MEMORY;
949 proxy_state = make_external_rpc_pipe_p(mem_ctx, pipe_name,
950 local, remote, server_info);
952 return NT_STATUS_UNSUCCESSFUL;
955 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
956 if (result == NULL) {
957 status = NT_STATUS_NO_MEMORY;
961 result->abstract_syntax = *abstract_syntax;
962 result->transfer_syntax = ndr_transfer_syntax;
964 result->desthost = get_myname(result);
965 result->srv_name_slash = talloc_asprintf_strupper_m(
966 result, "\\\\%s", result->desthost);
967 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
968 status = NT_STATUS_NO_MEMORY;
972 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
973 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
975 status = rpc_transport_tstream_init(result,
977 proxy_state->read_queue,
978 proxy_state->write_queue,
980 if (!NT_STATUS_IS_OK(status)) {
984 result->auth = talloc_zero(result, struct pipe_auth_data);
986 status = NT_STATUS_NO_MEMORY;
989 result->auth->auth_type = DCERPC_AUTH_TYPE_NONE;
990 result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
992 status = rpccli_anon_bind_data(result, &auth);
993 if (!NT_STATUS_IS_OK(status)) {
994 DEBUG(0, ("Failed to initialize anonymous bind.\n"));
998 status = rpc_pipe_bind(result, auth);
999 if (!NT_STATUS_IS_OK(status)) {
1000 DEBUG(0, ("Failed to bind spoolss pipe.\n"));
1004 if (!NT_STATUS_IS_OK(status)) {
1005 TALLOC_FREE(result);
1007 TALLOC_FREE(proxy_state);
1013 * @brief Create a new RPC client context which uses a local dispatch function.
1015 * @param mem_ctx The memory context on which thje pipe will ultimately
1017 * @param name The pipe name to connect to.
1018 * @param server_info Credentials to use for the connection.
1019 * @param pipe [in|out] Checks if a pipe is connected, and connects it
1022 * @return NT_STATUS_OK on success, a corresponding NT status if
1026 NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx,
1027 const struct ndr_syntax_id *syntax,
1028 struct auth_serversupplied_info *server_info,
1029 struct client_address *client_id,
1030 struct messaging_context *msg_ctx,
1031 struct rpc_pipe_client **cli_pipe)
1034 const char *server_type;
1035 const char *pipe_name;
1038 if (rpccli_is_connected(*cli_pipe)) {
1039 return NT_STATUS_OK;
1041 TALLOC_FREE(*cli_pipe);
1044 tmpctx = talloc_new(mem_ctx);
1046 return NT_STATUS_NO_MEMORY;
1049 pipe_name = get_pipe_name_from_syntax(tmpctx, syntax);
1051 TALLOC_FREE(tmpctx);
1052 return NT_STATUS_INVALID_PARAMETER;
1055 DEBUG(10, ("Connecting to %s pipe.\n", pipe_name));
1057 server_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1058 "rpc_server", pipe_name,
1060 if (StrCaseCmp(server_type, "embedded") == 0) {
1061 status = rpc_pipe_open_internal(tmpctx,
1062 syntax, server_info,
1065 if (!NT_STATUS_IS_OK(status)) {
1069 /* It would be nice to just use rpc_pipe_open_ncalrpc() but
1070 * for now we need to use the special proxy setup to connect
1073 status = rpc_pipe_open_external(tmpctx,
1077 if (!NT_STATUS_IS_OK(status)) {
1082 status = NT_STATUS_OK;
1084 if (NT_STATUS_IS_OK(status)) {
1085 talloc_steal(mem_ctx, *cli_pipe);
1087 TALLOC_FREE(tmpctx);