s3-dcerpc: Stop using hand marshalling in create_next_pdu_noauth()
[Samba/vl.git] / source3 / rpc_server / srv_pipe_hnd.c
blobb86a83bf075cdd3236ee28e82e1c1cc8bf16d298
1 /*
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/>.
22 #include "includes.h"
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 "../libcli/auth/schannel.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
33 /****************************************************************************
34 Initialise an outgoing packet.
35 ****************************************************************************/
37 static bool pipe_init_outgoing_data(pipes_struct *p)
39 output_data *o_data = &p->out_data;
41 /* Reset the offset counters. */
42 o_data->data_sent_length = 0;
43 o_data->current_pdu_sent = 0;
45 prs_mem_free(&o_data->frag);
47 /* Free any memory in the current return data buffer. */
48 prs_mem_free(&o_data->rdata);
51 * Initialize the outgoing RPC data buffer.
52 * we will use this as the raw data area for replying to rpc requests.
54 if(!prs_init(&o_data->rdata, 128, p->mem_ctx, MARSHALL)) {
55 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
56 return False;
59 return True;
62 /****************************************************************************
63 Sets the fault state on incoming packets.
64 ****************************************************************************/
66 static void set_incoming_fault(pipes_struct *p)
68 prs_mem_free(&p->in_data.data);
69 p->in_data.pdu_needed_len = 0;
70 p->in_data.pdu.length = 0;
71 p->fault_state = True;
72 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
73 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
76 /****************************************************************************
77 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
78 ****************************************************************************/
80 static ssize_t fill_rpc_header(pipes_struct *p, char *data, size_t data_to_copy)
82 size_t len_needed_to_complete_hdr =
83 MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu.length);
85 DEBUG(10, ("fill_rpc_header: data_to_copy = %u, "
86 "len_needed_to_complete_hdr = %u, "
87 "receive_len = %u\n",
88 (unsigned int)data_to_copy,
89 (unsigned int)len_needed_to_complete_hdr,
90 (unsigned int)p->in_data.pdu.length ));
92 if (p->in_data.pdu.data == NULL) {
93 p->in_data.pdu.data = talloc_array(p, uint8_t, RPC_HEADER_LEN);
95 if (p->in_data.pdu.data == NULL) {
96 DEBUG(0, ("talloc failed\n"));
97 return -1;
100 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
101 data, len_needed_to_complete_hdr);
102 p->in_data.pdu.length += len_needed_to_complete_hdr;
104 return (ssize_t)len_needed_to_complete_hdr;
107 static bool get_pdu_size(pipes_struct *p)
109 uint16_t frag_len;
110 /* the fill_rpc_header() call insures we copy only
111 * RPC_HEADER_LEN bytes. If this doesn't match then
112 * somethign is very wrong and we can only abort */
113 if (p->in_data.pdu.length != RPC_HEADER_LEN) {
114 DEBUG(0, ("Unexpected RPC Header size! "
115 "got %d, expected %d)\n",
116 (int)p->in_data.pdu.length,
117 RPC_HEADER_LEN));
118 set_incoming_fault(p);
119 return false;
122 frag_len = dcerpc_get_frag_length(&p->in_data.pdu);
124 /* verify it is a reasonable value */
125 if ((frag_len < RPC_HEADER_LEN) ||
126 (frag_len > RPC_MAX_PDU_FRAG_LEN)) {
127 DEBUG(0, ("Unexpected RPC Fragment size! (%d)\n",
128 frag_len));
129 set_incoming_fault(p);
130 return false;
133 p->in_data.pdu_needed_len = frag_len - RPC_HEADER_LEN;
135 /* allocate the space needed to fill the pdu */
136 p->in_data.pdu.data = talloc_realloc(p, p->in_data.pdu.data,
137 uint8_t, frag_len);
138 if (p->in_data.pdu.data == NULL) {
139 DEBUG(0, ("talloc_realloc failed\n"));
140 set_incoming_fault(p);
141 return false;
144 return true;
147 /****************************************************************************
148 Call this to free any talloc'ed memory. Do this after processing
149 a complete incoming and outgoing request (multiple incoming/outgoing
150 PDU's).
151 ****************************************************************************/
153 static void free_pipe_context(pipes_struct *p)
155 prs_mem_free(&p->out_data.frag);
156 prs_mem_free(&p->out_data.rdata);
157 prs_mem_free(&p->in_data.data);
159 DEBUG(3, ("free_pipe_context: "
160 "destroying talloc pool of size %lu\n",
161 (unsigned long)talloc_total_size(p->mem_ctx)));
162 talloc_free_children(p->mem_ctx);
164 * Re-initialize to set back to marshalling and set the
165 * offset back to the start of the buffer.
167 if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
168 DEBUG(0, ("free_pipe_context: "
169 "rps_init failed!\n"));
170 p->fault_state = True;
174 /****************************************************************************
175 Processes a request pdu. This will do auth processing if needed, and
176 appends the data into the complete stream if the LAST flag is not set.
177 ****************************************************************************/
179 static bool dcesrv_auth_request(pipes_struct *p, struct ncacn_packet *pkt)
181 NTSTATUS status;
182 size_t hdr_size = DCERPC_REQUEST_LENGTH;
183 struct dcerpc_auth auth;
184 uint32_t auth_length;
185 DATA_BLOB data;
186 DATA_BLOB full_pkt;
188 DEBUG(10, ("Checking request auth.\n"));
190 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
191 hdr_size += 16;
194 switch (p->auth.auth_level) {
195 case DCERPC_AUTH_LEVEL_PRIVACY:
196 DEBUG(10, ("Requested Privacy.\n"));
197 break;
199 case DCERPC_AUTH_LEVEL_INTEGRITY:
200 DEBUG(10, ("Requested Integrity.\n"));
201 break;
203 case DCERPC_AUTH_LEVEL_CONNECT:
204 if (pkt->auth_length != 0) {
205 break;
207 return true;
208 case DCERPC_AUTH_LEVEL_NONE:
209 if (pkt->auth_length != 0) {
210 return false;
212 return true;
214 default:
215 return false;
218 status = dcerpc_pull_auth_trailer(pkt, pkt,
219 &pkt->u.request.stub_and_verifier,
220 &auth, &auth_length, false);
221 if (!NT_STATUS_IS_OK(status)) {
222 return false;
225 pkt->u.request.stub_and_verifier.length -= auth_length;
227 data.data = p->in_data.pdu.data + hdr_size;
228 data.length = pkt->u.request.stub_and_verifier.length;
229 full_pkt.data = p->in_data.pdu.data;
230 full_pkt.length = p->in_data.pdu.length - auth.credentials.length;
232 switch (p->auth.auth_type) {
233 case PIPE_AUTH_TYPE_NONE:
234 return true;
236 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
237 case PIPE_AUTH_TYPE_NTLMSSP:
239 DEBUG(10, ("NTLMSSP auth\n"));
241 if (!p->auth.a_u.auth_ntlmssp_state) {
242 DEBUG(0, ("Invalid auth level, "
243 "failed to process packet auth.\n"));
244 return false;
247 switch (p->auth.auth_level) {
248 case DCERPC_AUTH_LEVEL_PRIVACY:
249 status = auth_ntlmssp_unseal_packet(
250 p->auth.a_u.auth_ntlmssp_state,
251 data.data, data.length,
252 full_pkt.data, full_pkt.length,
253 &auth.credentials);
254 if (!NT_STATUS_IS_OK(status)) {
255 return false;
257 memcpy(pkt->u.request.stub_and_verifier.data,
258 data.data, data.length);
259 break;
261 case DCERPC_AUTH_LEVEL_INTEGRITY:
262 status = auth_ntlmssp_check_packet(
263 p->auth.a_u.auth_ntlmssp_state,
264 data.data, data.length,
265 full_pkt.data, full_pkt.length,
266 &auth.credentials);
267 if (!NT_STATUS_IS_OK(status)) {
268 return false;
270 break;
272 default:
273 DEBUG(0, ("Invalid auth level, "
274 "failed to process packet auth.\n"));
275 return false;
277 break;
279 case PIPE_AUTH_TYPE_SCHANNEL:
281 DEBUG(10, ("SCHANNEL auth\n"));
283 switch (p->auth.auth_level) {
284 case DCERPC_AUTH_LEVEL_PRIVACY:
285 status = netsec_incoming_packet(
286 p->auth.a_u.schannel_auth,
287 pkt, true,
288 data.data, data.length,
289 &auth.credentials);
290 if (!NT_STATUS_IS_OK(status)) {
291 return false;
293 memcpy(pkt->u.request.stub_and_verifier.data,
294 data.data, data.length);
295 break;
297 case DCERPC_AUTH_LEVEL_INTEGRITY:
298 status = netsec_incoming_packet(
299 p->auth.a_u.schannel_auth,
300 pkt, false,
301 data.data, data.length,
302 &auth.credentials);
303 if (!NT_STATUS_IS_OK(status)) {
304 return false;
306 break;
308 default:
309 DEBUG(0, ("Invalid auth level, "
310 "failed to process packet auth.\n"));
311 return false;
313 break;
315 default:
316 DEBUG(0, ("process_request_pdu: "
317 "unknown auth type %u set.\n",
318 (unsigned int)p->auth.auth_type));
319 set_incoming_fault(p);
320 return false;
323 /* remove the indicated amount of padding */
324 if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) {
325 return false;
327 pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length;
329 return true;
332 static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
334 DATA_BLOB data;
336 if (!p->pipe_bound) {
337 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
338 set_incoming_fault(p);
339 return False;
342 /* Store the opnum */
343 p->opnum = pkt->u.request.opnum;
345 if (!dcesrv_auth_request(p, pkt)) {
346 DEBUG(0,("Failed to check packet auth.\n"));
347 set_incoming_fault(p);
348 return false;
351 data = pkt->u.request.stub_and_verifier;
354 * Check the data length doesn't go over the 15Mb limit.
355 * increased after observing a bug in the Windows NT 4.0 SP6a
356 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
357 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
360 if (prs_offset(&p->in_data.data) + data.length > MAX_RPC_DATA_SIZE) {
361 DEBUG(0, ("process_request_pdu: "
362 "rpc data buffer too large (%u) + (%u)\n",
363 (unsigned int)prs_data_size(&p->in_data.data),
364 (unsigned int)data.length));
365 set_incoming_fault(p);
366 return False;
370 * Append the data portion into the buffer and return.
373 if (!prs_copy_data_in(&p->in_data.data,
374 (char *)data.data, data.length)) {
375 DEBUG(0, ("process_request_pdu: Unable to append data size %u "
376 "to parse buffer of size %u.\n",
377 (unsigned int)data.length,
378 (unsigned int)prs_data_size(&p->in_data.data)));
379 set_incoming_fault(p);
380 return False;
383 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
384 bool ret = False;
386 * Ok - we finally have a complete RPC stream.
387 * Call the rpc command to process it.
391 * Ensure the internal prs buffer size is *exactly* the same
392 * size as the current offset.
395 if (!prs_set_buffer_size(&p->in_data.data,
396 prs_offset(&p->in_data.data))) {
397 DEBUG(0, ("process_request_pdu: "
398 "Call to prs_set_buffer_size failed!\n"));
399 set_incoming_fault(p);
400 return False;
404 * Set the parse offset to the start of the data and set the
405 * prs_struct to UNMARSHALL.
408 prs_set_offset(&p->in_data.data, 0);
409 prs_switch_type(&p->in_data.data, UNMARSHALL);
412 * Process the complete data stream here.
415 if (pipe_init_outgoing_data(p)) {
416 ret = api_pipe_request(p, pkt);
419 return ret;
422 return True;
425 /****************************************************************************
426 Processes a finished PDU stored in p->in_data.pdu.
427 ****************************************************************************/
429 static void process_complete_pdu(pipes_struct *p)
431 struct ncacn_packet *pkt = NULL;
432 NTSTATUS status;
433 bool reply = False;
435 if(p->fault_state) {
436 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
437 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
438 goto done;
441 pkt = talloc(p->mem_ctx, struct ncacn_packet);
442 if (!pkt) {
443 DEBUG(0, ("Out of memory!\n"));
444 goto done;
447 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu, pkt);
448 if (!NT_STATUS_IS_OK(status)) {
449 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
450 nt_errstr(status)));
451 goto done;
454 /* Store the call_id */
455 p->call_id = pkt->call_id;
458 * Ensure we're using the corrent endianness for both the
459 * RPC header flags and the raw data we will be reading from.
461 if (pkt->drep[0] == DCERPC_DREP_LE) {
462 p->endian = RPC_LITTLE_ENDIAN;
463 } else {
464 p->endian = RPC_BIG_ENDIAN;
466 prs_set_endian_data(&p->in_data.data, p->endian);
468 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
470 switch (pkt->ptype) {
471 case DCERPC_PKT_REQUEST:
472 reply = process_request_pdu(p, pkt);
473 break;
475 case DCERPC_PKT_PING: /* CL request - ignore... */
476 DEBUG(0, ("process_complete_pdu: Error. "
477 "Connectionless packet type %d received on "
478 "pipe %s.\n", (int)pkt->ptype,
479 get_pipe_name_from_syntax(talloc_tos(),
480 &p->syntax)));
481 break;
483 case DCERPC_PKT_RESPONSE: /* No responses here. */
484 DEBUG(0, ("process_complete_pdu: Error. "
485 "DCERPC_PKT_RESPONSE received from client "
486 "on pipe %s.\n",
487 get_pipe_name_from_syntax(talloc_tos(),
488 &p->syntax)));
489 break;
491 case DCERPC_PKT_FAULT:
492 case DCERPC_PKT_WORKING:
493 /* CL request - reply to a ping when a call in process. */
494 case DCERPC_PKT_NOCALL:
495 /* CL - server reply to a ping call. */
496 case DCERPC_PKT_REJECT:
497 case DCERPC_PKT_ACK:
498 case DCERPC_PKT_CL_CANCEL:
499 case DCERPC_PKT_FACK:
500 case DCERPC_PKT_CANCEL_ACK:
501 DEBUG(0, ("process_complete_pdu: Error. "
502 "Connectionless packet type %u received on "
503 "pipe %s.\n", (unsigned int)pkt->ptype,
504 get_pipe_name_from_syntax(talloc_tos(),
505 &p->syntax)));
506 break;
508 case DCERPC_PKT_BIND:
510 * We assume that a pipe bind is only in one pdu.
512 if (pipe_init_outgoing_data(p)) {
513 reply = api_pipe_bind_req(p, pkt);
515 break;
517 case DCERPC_PKT_BIND_ACK:
518 case DCERPC_PKT_BIND_NAK:
519 DEBUG(0, ("process_complete_pdu: Error. "
520 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
521 "packet type %u received on pipe %s.\n",
522 (unsigned int)pkt->ptype,
523 get_pipe_name_from_syntax(talloc_tos(),
524 &p->syntax)));
525 break;
528 case DCERPC_PKT_ALTER:
530 * We assume that a pipe bind is only in one pdu.
532 if (pipe_init_outgoing_data(p)) {
533 reply = api_pipe_alter_context(p, pkt);
535 break;
537 case DCERPC_PKT_ALTER_RESP:
538 DEBUG(0, ("process_complete_pdu: Error. "
539 "DCERPC_PKT_ALTER_RESP on pipe %s: "
540 "Should only be server -> client.\n",
541 get_pipe_name_from_syntax(talloc_tos(),
542 &p->syntax)));
543 break;
545 case DCERPC_PKT_AUTH3:
547 * The third packet in an NTLMSSP auth exchange.
549 if (pipe_init_outgoing_data(p)) {
550 reply = api_pipe_bind_auth3(p, pkt);
552 break;
554 case DCERPC_PKT_SHUTDOWN:
555 DEBUG(0, ("process_complete_pdu: Error. "
556 "DCERPC_PKT_SHUTDOWN on pipe %s: "
557 "Should only be server -> client.\n",
558 get_pipe_name_from_syntax(talloc_tos(),
559 &p->syntax)));
560 break;
562 case DCERPC_PKT_CO_CANCEL:
563 /* For now just free all client data and continue
564 * processing. */
565 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
566 " Abandoning rpc call.\n"));
567 /* As we never do asynchronous RPC serving, we can
568 * never cancel a call (as far as I know).
569 * If we ever did we'd have to send a cancel_ack reply.
570 * For now, just free all client data and continue
571 * processing. */
572 reply = True;
573 break;
575 #if 0
576 /* Enable this if we're doing async rpc. */
577 /* We must check the outstanding callid matches. */
578 if (pipe_init_outgoing_data(p)) {
579 /* Send a cancel_ack PDU reply. */
580 /* We should probably check the auth-verifier here. */
581 reply = setup_cancel_ack_reply(p, pkt);
583 break;
584 #endif
586 case DCERPC_PKT_ORPHANED:
587 /* We should probably check the auth-verifier here.
588 * For now just free all client data and continue
589 * processing. */
590 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
591 " Abandoning rpc call.\n"));
592 reply = True;
593 break;
595 default:
596 DEBUG(0, ("process_complete_pdu: "
597 "Unknown rpc type = %u received.\n",
598 (unsigned int)pkt->ptype));
599 break;
602 done:
603 /* Reset to little endian.
604 * Probably don't need this but it won't hurt. */
605 prs_set_endian_data(&p->in_data.data, RPC_LITTLE_ENDIAN);
607 if (!reply) {
608 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
609 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
610 &p->syntax)));
611 set_incoming_fault(p);
612 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
613 TALLOC_FREE(pkt);
614 } else {
616 * Reset the lengths. We're ready for a new pdu.
618 TALLOC_FREE(p->in_data.pdu.data);
619 p->in_data.pdu_needed_len = 0;
620 p->in_data.pdu.length = 0;
623 TALLOC_FREE(pkt);
626 /****************************************************************************
627 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
628 ****************************************************************************/
630 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
632 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN
633 - p->in_data.pdu.length);
635 DEBUG(10, ("process_incoming_data: Start: pdu.length = %u, "
636 "pdu_needed_len = %u, incoming data = %u\n",
637 (unsigned int)p->in_data.pdu.length,
638 (unsigned int)p->in_data.pdu_needed_len,
639 (unsigned int)n ));
641 if(data_to_copy == 0) {
643 * This is an error - data is being received and there is no
644 * space in the PDU. Free the received data and go into the
645 * fault state.
647 DEBUG(0, ("process_incoming_data: "
648 "No space in incoming pdu buffer. "
649 "Current size = %u incoming data size = %u\n",
650 (unsigned int)p->in_data.pdu.length,
651 (unsigned int)n));
652 set_incoming_fault(p);
653 return -1;
657 * If we have no data already, wait until we get at least
658 * a RPC_HEADER_LEN * number of bytes before we can do anything.
661 if ((p->in_data.pdu_needed_len == 0) &&
662 (p->in_data.pdu.length < RPC_HEADER_LEN)) {
664 * Always return here. If we have more data then the RPC_HEADER
665 * will be processed the next time around the loop.
667 return fill_rpc_header(p, data, data_to_copy);
671 * At this point we know we have at least an RPC_HEADER_LEN amount of
672 * data stored in p->in_data.pdu.
676 * If pdu_needed_len is zero this is a new pdu.
677 * Check how much more data we need, then loop again.
679 if (p->in_data.pdu_needed_len == 0) {
681 bool ok = get_pdu_size(p);
682 if (!ok) {
683 return -1;
685 if (p->in_data.pdu_needed_len > 0) {
686 return 0;
689 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU
690 * that consists of an RPC_HEADER only. This is a
691 * DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or
692 * DCERPC_PKT_ORPHANED pdu type.
693 * Deal with this in process_complete_pdu(). */
697 * Ok - at this point we have a valid RPC_HEADER.
698 * Keep reading until we have a full pdu.
701 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
704 * Copy as much of the data as we need into the p->in_data.pdu buffer.
705 * pdu_needed_len becomes zero when we have a complete pdu.
708 memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
709 data, data_to_copy);
710 p->in_data.pdu.length += data_to_copy;
711 p->in_data.pdu_needed_len -= data_to_copy;
714 * Do we have a complete PDU ?
715 * (return the number of bytes handled in the call)
718 if(p->in_data.pdu_needed_len == 0) {
719 process_complete_pdu(p);
720 return data_to_copy;
723 DEBUG(10, ("process_incoming_data: not a complete PDU yet. "
724 "pdu.length = %u, pdu_needed_len = %u\n",
725 (unsigned int)p->in_data.pdu.length,
726 (unsigned int)p->in_data.pdu_needed_len));
728 return (ssize_t)data_to_copy;
731 /****************************************************************************
732 Accepts incoming data on an internal rpc pipe.
733 ****************************************************************************/
735 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
737 size_t data_left = n;
739 while(data_left) {
740 ssize_t data_used;
742 DEBUG(10, ("write_to_pipe: data_left = %u\n",
743 (unsigned int)data_left));
745 data_used = process_incoming_data(p, data, data_left);
747 DEBUG(10, ("write_to_pipe: data_used = %d\n",
748 (int)data_used));
750 if(data_used < 0) {
751 return -1;
754 data_left -= data_used;
755 data += data_used;
758 return n;
761 /****************************************************************************
762 Replies to a request to read data from a pipe.
764 Headers are interspersed with the data at PDU intervals. By the time
765 this function is called, the start of the data could possibly have been
766 read by an SMBtrans (file_offset != 0).
768 Calling create_rpc_reply() here is a hack. The data should already
769 have been prepared into arrays of headers + data stream sections.
770 ****************************************************************************/
772 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
773 size_t n, bool *is_data_outstanding)
775 uint32 pdu_remaining = 0;
776 ssize_t data_returned = 0;
778 if (!p) {
779 DEBUG(0,("read_from_pipe: pipe not open\n"));
780 return -1;
783 DEBUG(6,(" name: %s len: %u\n",
784 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
785 (unsigned int)n));
788 * We cannot return more than one PDU length per
789 * read request.
793 * This condition should result in the connection being closed.
794 * Netapp filers seem to set it to 0xffff which results in domain
795 * authentications failing. Just ignore it so things work.
798 if(n > RPC_MAX_PDU_FRAG_LEN) {
799 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
800 "pipe %s. We can only service %d sized reads.\n",
801 (unsigned int)n,
802 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
803 RPC_MAX_PDU_FRAG_LEN ));
804 n = RPC_MAX_PDU_FRAG_LEN;
808 * Determine if there is still data to send in the
809 * pipe PDU buffer. Always send this first. Never
810 * send more than is left in the current PDU. The
811 * client should send a new read request for a new
812 * PDU.
815 pdu_remaining = prs_offset(&p->out_data.frag)
816 - p->out_data.current_pdu_sent;
818 if (pdu_remaining > 0) {
819 data_returned = (ssize_t)MIN(n, pdu_remaining);
821 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
822 "current_pdu_sent = %u returning %d bytes.\n",
823 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
824 (unsigned int)prs_offset(&p->out_data.frag),
825 (unsigned int)p->out_data.current_pdu_sent,
826 (int)data_returned));
828 memcpy(data,
829 prs_data_p(&p->out_data.frag)
830 + p->out_data.current_pdu_sent,
831 data_returned);
833 p->out_data.current_pdu_sent += (uint32)data_returned;
834 goto out;
838 * At this point p->current_pdu_len == p->current_pdu_sent (which
839 * may of course be zero if this is the first return fragment.
842 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
843 "= %u, prs_offset(&p->out_data.rdata) = %u.\n",
844 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
845 (int)p->fault_state,
846 (unsigned int)p->out_data.data_sent_length,
847 (unsigned int)prs_offset(&p->out_data.rdata) ));
849 if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
851 * We have sent all possible data, return 0.
853 data_returned = 0;
854 goto out;
858 * We need to create a new PDU from the data left in p->rdata.
859 * Create the header/data/footers. This also sets up the fields
860 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
861 * and stores the outgoing PDU in p->current_pdu.
864 if(!create_next_pdu(p)) {
865 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
866 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
867 return -1;
870 data_returned = MIN(n, prs_offset(&p->out_data.frag));
872 memcpy( data, prs_data_p(&p->out_data.frag), (size_t)data_returned);
873 p->out_data.current_pdu_sent += (uint32)data_returned;
875 out:
876 (*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
878 if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
879 /* We've returned everything in the out_data.frag
880 * so we're done with this pdu. Free it and reset
881 * current_pdu_sent. */
882 p->out_data.current_pdu_sent = 0;
883 prs_mem_free(&p->out_data.frag);
885 if (p->out_data.data_sent_length
886 >= prs_offset(&p->out_data.rdata)) {
888 * We're completely finished with both outgoing and
889 * incoming data streams. It's safe to free all
890 * temporary data from this request.
892 free_pipe_context(p);
896 return data_returned;
899 bool fsp_is_np(struct files_struct *fsp)
901 enum FAKE_FILE_TYPE type;
903 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
904 return false;
907 type = fsp->fake_file_handle->type;
909 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
910 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
913 struct np_proxy_state {
914 uint16_t file_type;
915 uint16_t device_state;
916 uint64_t allocation_size;
917 struct tstream_context *npipe;
918 struct tevent_queue *read_queue;
919 struct tevent_queue *write_queue;
922 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
923 const char *pipe_name,
924 const struct tsocket_address *local_address,
925 const struct tsocket_address *remote_address,
926 struct auth_serversupplied_info *server_info)
928 struct np_proxy_state *result;
929 char *socket_np_dir;
930 const char *socket_dir;
931 struct tevent_context *ev;
932 struct tevent_req *subreq;
933 struct netr_SamInfo3 *info3;
934 NTSTATUS status;
935 bool ok;
936 int ret;
937 int sys_errno;
939 result = talloc(mem_ctx, struct np_proxy_state);
940 if (result == NULL) {
941 DEBUG(0, ("talloc failed\n"));
942 return NULL;
945 result->read_queue = tevent_queue_create(result, "np_read");
946 if (result->read_queue == NULL) {
947 DEBUG(0, ("tevent_queue_create failed\n"));
948 goto fail;
951 result->write_queue = tevent_queue_create(result, "np_write");
952 if (result->write_queue == NULL) {
953 DEBUG(0, ("tevent_queue_create failed\n"));
954 goto fail;
957 ev = s3_tevent_context_init(talloc_tos());
958 if (ev == NULL) {
959 DEBUG(0, ("s3_tevent_context_init failed\n"));
960 goto fail;
963 socket_dir = lp_parm_const_string(
964 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
965 get_dyn_NCALRPCDIR());
966 if (socket_dir == NULL) {
967 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
968 goto fail;
970 socket_np_dir = talloc_asprintf(talloc_tos(), "%s/np", socket_dir);
971 if (socket_np_dir == NULL) {
972 DEBUG(0, ("talloc_asprintf failed\n"));
973 goto fail;
976 info3 = talloc_zero(talloc_tos(), struct netr_SamInfo3);
977 if (info3 == NULL) {
978 DEBUG(0, ("talloc failed\n"));
979 goto fail;
982 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
983 if (!NT_STATUS_IS_OK(status)) {
984 TALLOC_FREE(info3);
985 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
986 nt_errstr(status)));
987 goto fail;
990 become_root();
991 subreq = tstream_npa_connect_send(talloc_tos(), ev,
992 socket_np_dir,
993 pipe_name,
994 remote_address, /* client_addr */
995 NULL, /* client_name */
996 local_address, /* server_addr */
997 NULL, /* server_name */
998 info3,
999 server_info->user_session_key,
1000 data_blob_null /* delegated_creds */);
1001 if (subreq == NULL) {
1002 unbecome_root();
1003 DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and "
1004 "user %s\\%s failed\n",
1005 socket_np_dir, pipe_name, info3->base.domain.string,
1006 info3->base.account_name.string));
1007 goto fail;
1009 ok = tevent_req_poll(subreq, ev);
1010 unbecome_root();
1011 if (!ok) {
1012 DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s "
1013 "failed for tstream_npa_connect: %s\n",
1014 socket_np_dir, pipe_name, info3->base.domain.string,
1015 info3->base.account_name.string,
1016 strerror(errno)));
1017 goto fail;
1020 ret = tstream_npa_connect_recv(subreq, &sys_errno,
1021 result,
1022 &result->npipe,
1023 &result->file_type,
1024 &result->device_state,
1025 &result->allocation_size);
1026 TALLOC_FREE(subreq);
1027 if (ret != 0) {
1028 DEBUG(0, ("tstream_npa_connect_recv to %s for pipe %s and "
1029 "user %s\\%s failed: %s\n",
1030 socket_np_dir, pipe_name, info3->base.domain.string,
1031 info3->base.account_name.string,
1032 strerror(sys_errno)));
1033 goto fail;
1036 return result;
1038 fail:
1039 TALLOC_FREE(result);
1040 return NULL;
1043 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1044 const struct tsocket_address *local_address,
1045 const struct tsocket_address *remote_address,
1046 struct auth_serversupplied_info *server_info,
1047 struct fake_file_handle **phandle)
1049 const char **proxy_list;
1050 struct fake_file_handle *handle;
1052 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1054 handle = talloc(mem_ctx, struct fake_file_handle);
1055 if (handle == NULL) {
1056 return NT_STATUS_NO_MEMORY;
1059 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1060 struct np_proxy_state *p;
1062 p = make_external_rpc_pipe_p(handle, name,
1063 local_address,
1064 remote_address,
1065 server_info);
1067 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1068 handle->private_data = p;
1069 } else {
1070 struct pipes_struct *p;
1071 struct ndr_syntax_id syntax;
1072 const char *client_address;
1074 if (!is_known_pipename(name, &syntax)) {
1075 TALLOC_FREE(handle);
1076 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1079 if (tsocket_address_is_inet(remote_address, "ip")) {
1080 client_address = tsocket_address_inet_addr_string(
1081 remote_address,
1082 talloc_tos());
1083 if (client_address == NULL) {
1084 TALLOC_FREE(handle);
1085 return NT_STATUS_NO_MEMORY;
1087 } else {
1088 client_address = "";
1091 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1092 server_info);
1094 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1095 handle->private_data = p;
1098 if (handle->private_data == NULL) {
1099 TALLOC_FREE(handle);
1100 return NT_STATUS_PIPE_NOT_AVAILABLE;
1103 *phandle = handle;
1105 return NT_STATUS_OK;
1108 bool np_read_in_progress(struct fake_file_handle *handle)
1110 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1111 return false;
1114 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1115 struct np_proxy_state *p = talloc_get_type_abort(
1116 handle->private_data, struct np_proxy_state);
1117 size_t read_count;
1119 read_count = tevent_queue_length(p->read_queue);
1120 if (read_count > 0) {
1121 return true;
1124 return false;
1127 return false;
1130 struct np_write_state {
1131 struct event_context *ev;
1132 struct np_proxy_state *p;
1133 struct iovec iov;
1134 ssize_t nwritten;
1137 static void np_write_done(struct tevent_req *subreq);
1139 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1140 struct fake_file_handle *handle,
1141 const uint8_t *data, size_t len)
1143 struct tevent_req *req;
1144 struct np_write_state *state;
1145 NTSTATUS status;
1147 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1148 dump_data(50, data, len);
1150 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1151 if (req == NULL) {
1152 return NULL;
1155 if (len == 0) {
1156 state->nwritten = 0;
1157 status = NT_STATUS_OK;
1158 goto post_status;
1161 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1162 struct pipes_struct *p = talloc_get_type_abort(
1163 handle->private_data, struct pipes_struct);
1165 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1167 status = (state->nwritten >= 0)
1168 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1169 goto post_status;
1172 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1173 struct np_proxy_state *p = talloc_get_type_abort(
1174 handle->private_data, struct np_proxy_state);
1175 struct tevent_req *subreq;
1177 state->ev = ev;
1178 state->p = p;
1179 state->iov.iov_base = CONST_DISCARD(void *, data);
1180 state->iov.iov_len = len;
1182 subreq = tstream_writev_queue_send(state, ev,
1183 p->npipe,
1184 p->write_queue,
1185 &state->iov, 1);
1186 if (subreq == NULL) {
1187 goto fail;
1189 tevent_req_set_callback(subreq, np_write_done, req);
1190 return req;
1193 status = NT_STATUS_INVALID_HANDLE;
1194 post_status:
1195 if (NT_STATUS_IS_OK(status)) {
1196 tevent_req_done(req);
1197 } else {
1198 tevent_req_nterror(req, status);
1200 return tevent_req_post(req, ev);
1201 fail:
1202 TALLOC_FREE(req);
1203 return NULL;
1206 static void np_write_done(struct tevent_req *subreq)
1208 struct tevent_req *req = tevent_req_callback_data(
1209 subreq, struct tevent_req);
1210 struct np_write_state *state = tevent_req_data(
1211 req, struct np_write_state);
1212 ssize_t received;
1213 int err;
1215 received = tstream_writev_queue_recv(subreq, &err);
1216 if (received < 0) {
1217 tevent_req_nterror(req, map_nt_error_from_unix(err));
1218 return;
1220 state->nwritten = received;
1221 tevent_req_done(req);
1224 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1226 struct np_write_state *state = tevent_req_data(
1227 req, struct np_write_state);
1228 NTSTATUS status;
1230 if (tevent_req_is_nterror(req, &status)) {
1231 return status;
1233 *pnwritten = state->nwritten;
1234 return NT_STATUS_OK;
1237 struct np_ipc_readv_next_vector_state {
1238 uint8_t *buf;
1239 size_t len;
1240 off_t ofs;
1241 size_t remaining;
1244 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
1245 uint8_t *buf, size_t len)
1247 ZERO_STRUCTP(s);
1249 s->buf = buf;
1250 s->len = MIN(len, UINT16_MAX);
1253 static int np_ipc_readv_next_vector(struct tstream_context *stream,
1254 void *private_data,
1255 TALLOC_CTX *mem_ctx,
1256 struct iovec **_vector,
1257 size_t *count)
1259 struct np_ipc_readv_next_vector_state *state =
1260 (struct np_ipc_readv_next_vector_state *)private_data;
1261 struct iovec *vector;
1262 ssize_t pending;
1263 size_t wanted;
1265 if (state->ofs == state->len) {
1266 *_vector = NULL;
1267 *count = 0;
1268 return 0;
1271 pending = tstream_pending_bytes(stream);
1272 if (pending == -1) {
1273 return -1;
1276 if (pending == 0 && state->ofs != 0) {
1277 /* return a short read */
1278 *_vector = NULL;
1279 *count = 0;
1280 return 0;
1283 if (pending == 0) {
1284 /* we want at least one byte and recheck again */
1285 wanted = 1;
1286 } else {
1287 size_t missing = state->len - state->ofs;
1288 if (pending > missing) {
1289 /* there's more available */
1290 state->remaining = pending - missing;
1291 wanted = missing;
1292 } else {
1293 /* read what we can get and recheck in the next cycle */
1294 wanted = pending;
1298 vector = talloc_array(mem_ctx, struct iovec, 1);
1299 if (!vector) {
1300 return -1;
1303 vector[0].iov_base = state->buf + state->ofs;
1304 vector[0].iov_len = wanted;
1306 state->ofs += wanted;
1308 *_vector = vector;
1309 *count = 1;
1310 return 0;
1313 struct np_read_state {
1314 struct np_proxy_state *p;
1315 struct np_ipc_readv_next_vector_state next_vector;
1317 size_t nread;
1318 bool is_data_outstanding;
1321 static void np_read_done(struct tevent_req *subreq);
1323 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1324 struct fake_file_handle *handle,
1325 uint8_t *data, size_t len)
1327 struct tevent_req *req;
1328 struct np_read_state *state;
1329 NTSTATUS status;
1331 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1332 if (req == NULL) {
1333 return NULL;
1336 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1337 struct pipes_struct *p = talloc_get_type_abort(
1338 handle->private_data, struct pipes_struct);
1340 state->nread = read_from_internal_pipe(
1341 p, (char *)data, len, &state->is_data_outstanding);
1343 status = (state->nread >= 0)
1344 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1345 goto post_status;
1348 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1349 struct np_proxy_state *p = talloc_get_type_abort(
1350 handle->private_data, struct np_proxy_state);
1351 struct tevent_req *subreq;
1353 np_ipc_readv_next_vector_init(&state->next_vector,
1354 data, len);
1356 subreq = tstream_readv_pdu_queue_send(state,
1358 p->npipe,
1359 p->read_queue,
1360 np_ipc_readv_next_vector,
1361 &state->next_vector);
1362 if (subreq == NULL) {
1365 tevent_req_set_callback(subreq, np_read_done, req);
1366 return req;
1369 status = NT_STATUS_INVALID_HANDLE;
1370 post_status:
1371 if (NT_STATUS_IS_OK(status)) {
1372 tevent_req_done(req);
1373 } else {
1374 tevent_req_nterror(req, status);
1376 return tevent_req_post(req, ev);
1379 static void np_read_done(struct tevent_req *subreq)
1381 struct tevent_req *req = tevent_req_callback_data(
1382 subreq, struct tevent_req);
1383 struct np_read_state *state = tevent_req_data(
1384 req, struct np_read_state);
1385 ssize_t ret;
1386 int err;
1388 ret = tstream_readv_pdu_queue_recv(subreq, &err);
1389 TALLOC_FREE(subreq);
1390 if (ret == -1) {
1391 tevent_req_nterror(req, map_nt_error_from_unix(err));
1392 return;
1395 state->nread = ret;
1396 state->is_data_outstanding = (state->next_vector.remaining > 0);
1398 tevent_req_done(req);
1399 return;
1402 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1403 bool *is_data_outstanding)
1405 struct np_read_state *state = tevent_req_data(
1406 req, struct np_read_state);
1407 NTSTATUS status;
1409 if (tevent_req_is_nterror(req, &status)) {
1410 return status;
1412 *nread = state->nread;
1413 *is_data_outstanding = state->is_data_outstanding;
1414 return NT_STATUS_OK;
1418 * @brief Create a new RPC client context which uses a local dispatch function.
1420 * @param[in] conn The connection struct that will hold the pipe
1422 * @param[out] spoolss_pipe A pointer to the connected rpc client pipe.
1424 * @return NT_STATUS_OK on success, a corresponding NT status if an
1425 * error occured.
1427 NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
1428 struct rpc_pipe_client **spoolss_pipe)
1430 NTSTATUS status;
1432 /* TODO: check and handle disconnections */
1434 if (!conn->spoolss_pipe) {
1435 status = rpc_pipe_open_internal(conn,
1436 &ndr_table_spoolss.syntax_id,
1437 conn->server_info,
1438 &conn->spoolss_pipe);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 return status;
1444 *spoolss_pipe = conn->spoolss_pipe;
1445 return NT_STATUS_OK;