s4:"dns_update_list" file: install it properly into the private directory
[Samba/cd1.git] / source3 / rpc_server / srv_pipe_hnd.c
blob8d4e26bcab550d6dbd5765eb070dd8fa6a5772a0
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
7 *
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/ndr_named_pipe_auth.h"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
28 static int pipes_open;
30 static pipes_struct *InternalPipes;
32 /* TODO
33 * the following prototypes are declared here to avoid
34 * code being moved about too much for a patch to be
35 * disrupted / less obvious.
37 * these functions, and associated functions that they
38 * call, should be moved behind a .so module-loading
39 * system _anyway_. so that's the next step...
42 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p);
44 /****************************************************************************
45 Internal Pipe iterator functions.
46 ****************************************************************************/
48 pipes_struct *get_first_internal_pipe(void)
50 return InternalPipes;
53 pipes_struct *get_next_internal_pipe(pipes_struct *p)
55 return p->next;
58 /****************************************************************************
59 Initialise an outgoing packet.
60 ****************************************************************************/
62 static bool pipe_init_outgoing_data(pipes_struct *p)
64 output_data *o_data = &p->out_data;
66 /* Reset the offset counters. */
67 o_data->data_sent_length = 0;
68 o_data->current_pdu_sent = 0;
70 prs_mem_free(&o_data->frag);
72 /* Free any memory in the current return data buffer. */
73 prs_mem_free(&o_data->rdata);
76 * Initialize the outgoing RPC data buffer.
77 * we will use this as the raw data area for replying to rpc requests.
78 */
79 if(!prs_init(&o_data->rdata, 128, p->mem_ctx, MARSHALL)) {
80 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
81 return False;
84 return True;
87 /****************************************************************************
88 Make an internal namedpipes structure
89 ****************************************************************************/
91 static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
92 const struct ndr_syntax_id *syntax,
93 const char *client_address,
94 struct auth_serversupplied_info *server_info)
96 pipes_struct *p;
98 DEBUG(4,("Create pipe requested %s\n",
99 get_pipe_name_from_syntax(talloc_tos(), syntax)));
101 p = TALLOC_ZERO_P(mem_ctx, struct pipes_struct);
103 if (!p) {
104 DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
105 return NULL;
108 p->mem_ctx = talloc_named(p, 0, "pipe %s %p",
109 get_pipe_name_from_syntax(talloc_tos(),
110 syntax), p);
111 if (p->mem_ctx == NULL) {
112 DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
113 TALLOC_FREE(p);
114 return NULL;
117 if (!init_pipe_handle_list(p, syntax)) {
118 DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
119 TALLOC_FREE(p);
120 return NULL;
124 * Initialize the incoming RPC data buffer with one PDU worth of memory.
125 * We cheat here and say we're marshalling, as we intend to add incoming
126 * data directly into the prs_struct and we want it to auto grow. We will
127 * change the type to UNMARSALLING before processing the stream.
130 if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
131 DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
132 close_policy_by_pipe(p);
133 TALLOC_FREE(p);
134 return NULL;
137 p->server_info = copy_serverinfo(p, server_info);
138 if (p->server_info == NULL) {
139 DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
140 close_policy_by_pipe(p);
141 TALLOC_FREE(p);
142 return NULL;
145 DLIST_ADD(InternalPipes, p);
147 memcpy(p->client_address, client_address, sizeof(p->client_address));
149 p->endian = RPC_LITTLE_ENDIAN;
152 * Initialize the outgoing RPC data buffer with no memory.
154 prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);
156 p->syntax = *syntax;
158 DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
159 get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open));
161 talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
163 return p;
166 /****************************************************************************
167 Sets the fault state on incoming packets.
168 ****************************************************************************/
170 static void set_incoming_fault(pipes_struct *p)
172 prs_mem_free(&p->in_data.data);
173 p->in_data.pdu_needed_len = 0;
174 p->in_data.pdu_received_len = 0;
175 p->fault_state = True;
176 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
177 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
180 /****************************************************************************
181 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
182 ****************************************************************************/
184 static ssize_t fill_rpc_header(pipes_struct *p, char *data, size_t data_to_copy)
186 size_t len_needed_to_complete_hdr = MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu_received_len);
188 DEBUG(10,("fill_rpc_header: data_to_copy = %u, len_needed_to_complete_hdr = %u, receive_len = %u\n",
189 (unsigned int)data_to_copy, (unsigned int)len_needed_to_complete_hdr,
190 (unsigned int)p->in_data.pdu_received_len ));
192 if (p->in_data.current_in_pdu == NULL) {
193 p->in_data.current_in_pdu = talloc_array(p, uint8_t,
194 RPC_HEADER_LEN);
196 if (p->in_data.current_in_pdu == NULL) {
197 DEBUG(0, ("talloc failed\n"));
198 return -1;
201 memcpy((char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, len_needed_to_complete_hdr);
202 p->in_data.pdu_received_len += len_needed_to_complete_hdr;
204 return (ssize_t)len_needed_to_complete_hdr;
207 /****************************************************************************
208 Unmarshalls a new PDU header. Assumes the raw header data is in current_in_pdu.
209 ****************************************************************************/
211 static ssize_t unmarshall_rpc_header(pipes_struct *p)
214 * Unmarshall the header to determine the needed length.
217 prs_struct rpc_in;
219 if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
220 DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
221 set_incoming_fault(p);
222 return -1;
225 prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
226 prs_set_endian_data( &rpc_in, p->endian);
228 prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
229 p->in_data.pdu_received_len, False);
232 * Unmarshall the header as this will tell us how much
233 * data we need to read to get the complete pdu.
234 * This also sets the endian flag in rpc_in.
237 if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
238 DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
239 set_incoming_fault(p);
240 prs_mem_free(&rpc_in);
241 return -1;
245 * Validate the RPC header.
248 if(p->hdr.major != 5 && p->hdr.minor != 0) {
249 DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
250 set_incoming_fault(p);
251 prs_mem_free(&rpc_in);
252 return -1;
256 * If there's not data in the incoming buffer this should be the start of a new RPC.
259 if(prs_offset(&p->in_data.data) == 0) {
262 * AS/U doesn't set FIRST flag in a BIND packet it seems.
265 if ((p->hdr.pkt_type == DCERPC_PKT_REQUEST) && !(p->hdr.flags & DCERPC_PFC_FLAG_FIRST)) {
267 * Ensure that the FIRST flag is set. If not then we have
268 * a stream missmatch.
271 DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
272 set_incoming_fault(p);
273 prs_mem_free(&rpc_in);
274 return -1;
278 * If this is the first PDU then set the endianness
279 * flag in the pipe. We will need this when parsing all
280 * data in this RPC.
283 p->endian = rpc_in.bigendian_data;
285 DEBUG(5,("unmarshall_rpc_header: using %sendian RPC\n",
286 p->endian == RPC_LITTLE_ENDIAN ? "little-" : "big-" ));
288 } else {
291 * If this is *NOT* the first PDU then check the endianness
292 * flag in the pipe is the same as that in the PDU.
295 if (p->endian != rpc_in.bigendian_data) {
296 DEBUG(0,("unmarshall_rpc_header: FIRST endianness flag (%d) different in next PDU !\n", (int)p->endian));
297 set_incoming_fault(p);
298 prs_mem_free(&rpc_in);
299 return -1;
304 * Ensure that the pdu length is sane.
307 if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > RPC_MAX_PDU_FRAG_LEN)) {
308 DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
309 set_incoming_fault(p);
310 prs_mem_free(&rpc_in);
311 return -1;
314 DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
315 (unsigned int)p->hdr.flags ));
317 p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;
319 prs_mem_free(&rpc_in);
321 p->in_data.current_in_pdu = TALLOC_REALLOC_ARRAY(
322 p, p->in_data.current_in_pdu, uint8_t, p->hdr.frag_len);
323 if (p->in_data.current_in_pdu == NULL) {
324 DEBUG(0, ("talloc failed\n"));
325 set_incoming_fault(p);
326 return -1;
329 return 0; /* No extra data processed. */
332 /****************************************************************************
333 Call this to free any talloc'ed memory. Do this before and after processing
334 a complete PDU.
335 ****************************************************************************/
337 static void free_pipe_context(pipes_struct *p)
339 if (p->mem_ctx) {
340 DEBUG(3,("free_pipe_context: destroying talloc pool of size "
341 "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
342 talloc_free_children(p->mem_ctx);
343 } else {
344 p->mem_ctx = talloc_named(p, 0, "pipe %s %p",
345 get_pipe_name_from_syntax(talloc_tos(),
346 &p->syntax), p);
347 if (p->mem_ctx == NULL) {
348 p->fault_state = True;
353 /****************************************************************************
354 Processes a request pdu. This will do auth processing if needed, and
355 appends the data into the complete stream if the LAST flag is not set.
356 ****************************************************************************/
358 static bool process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
360 uint32 ss_padding_len = 0;
361 size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
362 (p->hdr.auth_len ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
364 if(!p->pipe_bound) {
365 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
366 set_incoming_fault(p);
367 return False;
371 * Check if we need to do authentication processing.
372 * This is only done on requests, not binds.
376 * Read the RPC request header.
379 if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) {
380 DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n"));
381 set_incoming_fault(p);
382 return False;
385 switch(p->auth.auth_type) {
386 case PIPE_AUTH_TYPE_NONE:
387 break;
389 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
390 case PIPE_AUTH_TYPE_NTLMSSP:
392 NTSTATUS status;
393 if(!api_pipe_ntlmssp_auth_process(p, rpc_in_p, &ss_padding_len, &status)) {
394 DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
395 DEBUG(0,("process_request_pdu: error was %s.\n", nt_errstr(status) ));
396 set_incoming_fault(p);
397 return False;
399 break;
402 case PIPE_AUTH_TYPE_SCHANNEL:
403 if (!api_pipe_schannel_process(p, rpc_in_p, &ss_padding_len)) {
404 DEBUG(3,("process_request_pdu: failed to do schannel processing.\n"));
405 set_incoming_fault(p);
406 return False;
408 break;
410 default:
411 DEBUG(0,("process_request_pdu: unknown auth type %u set.\n", (unsigned int)p->auth.auth_type ));
412 set_incoming_fault(p);
413 return False;
416 /* Now we've done the sign/seal we can remove any padding data. */
417 if (data_len > ss_padding_len) {
418 data_len -= ss_padding_len;
422 * Check the data length doesn't go over the 15Mb limit.
423 * increased after observing a bug in the Windows NT 4.0 SP6a
424 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
425 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
428 if(prs_offset(&p->in_data.data) + data_len > MAX_RPC_DATA_SIZE) {
429 DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
430 (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
431 set_incoming_fault(p);
432 return False;
436 * Append the data portion into the buffer and return.
439 if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) {
440 DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
441 (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
442 set_incoming_fault(p);
443 return False;
446 if(p->hdr.flags & DCERPC_PFC_FLAG_LAST) {
447 bool ret = False;
449 * Ok - we finally have a complete RPC stream.
450 * Call the rpc command to process it.
454 * Ensure the internal prs buffer size is *exactly* the same
455 * size as the current offset.
458 if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
459 DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n"));
460 set_incoming_fault(p);
461 return False;
465 * Set the parse offset to the start of the data and set the
466 * prs_struct to UNMARSHALL.
469 prs_set_offset(&p->in_data.data, 0);
470 prs_switch_type(&p->in_data.data, UNMARSHALL);
473 * Process the complete data stream here.
476 free_pipe_context(p);
478 if(pipe_init_outgoing_data(p)) {
479 ret = api_pipe_request(p);
482 free_pipe_context(p);
485 * We have consumed the whole data stream. Set back to
486 * marshalling and set the offset back to the start of
487 * the buffer to re-use it (we could also do a prs_mem_free()
488 * and then re_init on the next start of PDU. Not sure which
489 * is best here.... JRA.
492 prs_switch_type(&p->in_data.data, MARSHALL);
493 prs_set_offset(&p->in_data.data, 0);
494 return ret;
497 return True;
500 /****************************************************************************
501 Processes a finished PDU stored in current_in_pdu. The RPC_HEADER has
502 already been parsed and stored in p->hdr.
503 ****************************************************************************/
505 static void process_complete_pdu(pipes_struct *p)
507 prs_struct rpc_in;
508 size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
509 char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
510 bool reply = False;
512 if(p->fault_state) {
513 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
514 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
515 set_incoming_fault(p);
516 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
517 return;
520 prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
523 * Ensure we're using the corrent endianness for both the
524 * RPC header flags and the raw data we will be reading from.
527 prs_set_endian_data( &rpc_in, p->endian);
528 prs_set_endian_data( &p->in_data.data, p->endian);
530 prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
532 DEBUG(10,("process_complete_pdu: processing packet type %u\n",
533 (unsigned int)p->hdr.pkt_type ));
535 switch (p->hdr.pkt_type) {
536 case DCERPC_PKT_REQUEST:
537 reply = process_request_pdu(p, &rpc_in);
538 break;
540 case DCERPC_PKT_PING: /* CL request - ignore... */
541 DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
542 (unsigned int)p->hdr.pkt_type,
543 get_pipe_name_from_syntax(talloc_tos(),
544 &p->syntax)));
545 break;
547 case DCERPC_PKT_RESPONSE: /* No responses here. */
548 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_RESPONSE received from client on pipe %s.\n",
549 get_pipe_name_from_syntax(talloc_tos(),
550 &p->syntax)));
551 break;
553 case DCERPC_PKT_FAULT:
554 case DCERPC_PKT_WORKING: /* CL request - reply to a ping when a call in process. */
555 case DCERPC_PKT_NOCALL: /* CL - server reply to a ping call. */
556 case DCERPC_PKT_REJECT:
557 case DCERPC_PKT_ACK:
558 case DCERPC_PKT_CL_CANCEL:
559 case DCERPC_PKT_FACK:
560 case DCERPC_PKT_CANCEL_ACK:
561 DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
562 (unsigned int)p->hdr.pkt_type,
563 get_pipe_name_from_syntax(talloc_tos(),
564 &p->syntax)));
565 break;
567 case DCERPC_PKT_BIND:
569 * We assume that a pipe bind is only in one pdu.
571 if(pipe_init_outgoing_data(p)) {
572 reply = api_pipe_bind_req(p, &rpc_in);
574 break;
576 case DCERPC_PKT_BIND_ACK:
577 case DCERPC_PKT_BIND_NAK:
578 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK packet type %u received on pipe %s.\n",
579 (unsigned int)p->hdr.pkt_type,
580 get_pipe_name_from_syntax(talloc_tos(),
581 &p->syntax)));
582 break;
585 case DCERPC_PKT_ALTER:
587 * We assume that a pipe bind is only in one pdu.
589 if(pipe_init_outgoing_data(p)) {
590 reply = api_pipe_alter_context(p, &rpc_in);
592 break;
594 case DCERPC_PKT_ALTER_RESP:
595 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_ALTER_RESP on pipe %s: Should only be server -> client.\n",
596 get_pipe_name_from_syntax(talloc_tos(),
597 &p->syntax)));
598 break;
600 case DCERPC_PKT_AUTH3:
602 * The third packet in an NTLMSSP auth exchange.
604 if(pipe_init_outgoing_data(p)) {
605 reply = api_pipe_bind_auth3(p, &rpc_in);
607 break;
609 case DCERPC_PKT_SHUTDOWN:
610 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_SHUTDOWN on pipe %s: Should only be server -> client.\n",
611 get_pipe_name_from_syntax(talloc_tos(),
612 &p->syntax)));
613 break;
615 case DCERPC_PKT_CO_CANCEL:
616 /* For now just free all client data and continue processing. */
617 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL. Abandoning rpc call.\n"));
618 /* As we never do asynchronous RPC serving, we can never cancel a
619 call (as far as I know). If we ever did we'd have to send a cancel_ack
620 reply. For now, just free all client data and continue processing. */
621 reply = True;
622 break;
623 #if 0
624 /* Enable this if we're doing async rpc. */
625 /* We must check the call-id matches the outstanding callid. */
626 if(pipe_init_outgoing_data(p)) {
627 /* Send a cancel_ack PDU reply. */
628 /* We should probably check the auth-verifier here. */
629 reply = setup_cancel_ack_reply(p, &rpc_in);
631 break;
632 #endif
634 case DCERPC_PKT_ORPHANED:
635 /* We should probably check the auth-verifier here.
636 For now just free all client data and continue processing. */
637 DEBUG(3,("process_complete_pdu: DCERPC_PKT_ORPHANED. Abandoning rpc call.\n"));
638 reply = True;
639 break;
641 default:
642 DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
643 break;
646 /* Reset to little endian. Probably don't need this but it won't hurt. */
647 prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);
649 if (!reply) {
650 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
651 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
652 &p->syntax)));
653 set_incoming_fault(p);
654 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
655 prs_mem_free(&rpc_in);
656 } else {
658 * Reset the lengths. We're ready for a new pdu.
660 TALLOC_FREE(p->in_data.current_in_pdu);
661 p->in_data.pdu_needed_len = 0;
662 p->in_data.pdu_received_len = 0;
665 prs_mem_free(&rpc_in);
668 /****************************************************************************
669 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
670 ****************************************************************************/
672 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
674 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
676 DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
677 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
678 (unsigned int)n ));
680 if(data_to_copy == 0) {
682 * This is an error - data is being received and there is no
683 * space in the PDU. Free the received data and go into the fault state.
685 DEBUG(0,("process_incoming_data: No space in incoming pdu buffer. Current size = %u \
686 incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)n ));
687 set_incoming_fault(p);
688 return -1;
692 * If we have no data already, wait until we get at least a RPC_HEADER_LEN
693 * number of bytes before we can do anything.
696 if((p->in_data.pdu_needed_len == 0) && (p->in_data.pdu_received_len < RPC_HEADER_LEN)) {
698 * Always return here. If we have more data then the RPC_HEADER
699 * will be processed the next time around the loop.
701 return fill_rpc_header(p, data, data_to_copy);
705 * At this point we know we have at least an RPC_HEADER_LEN amount of data
706 * stored in current_in_pdu.
710 * If pdu_needed_len is zero this is a new pdu.
711 * Unmarshall the header so we know how much more
712 * data we need, then loop again.
715 if(p->in_data.pdu_needed_len == 0) {
716 ssize_t rret = unmarshall_rpc_header(p);
717 if (rret == -1 || p->in_data.pdu_needed_len > 0) {
718 return rret;
720 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists
721 of an RPC_HEADER only. This is a DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or DCERPC_PKT_ORPHANED
722 pdu type. Deal with this in process_complete_pdu(). */
726 * Ok - at this point we have a valid RPC_HEADER in p->hdr.
727 * Keep reading until we have a full pdu.
730 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
733 * Copy as much of the data as we need into the current_in_pdu buffer.
734 * pdu_needed_len becomes zero when we have a complete pdu.
737 memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);
738 p->in_data.pdu_received_len += data_to_copy;
739 p->in_data.pdu_needed_len -= data_to_copy;
742 * Do we have a complete PDU ?
743 * (return the number of bytes handled in the call)
746 if(p->in_data.pdu_needed_len == 0) {
747 process_complete_pdu(p);
748 return data_to_copy;
751 DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
752 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
754 return (ssize_t)data_to_copy;
757 /****************************************************************************
758 Accepts incoming data on an internal rpc pipe.
759 ****************************************************************************/
761 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
763 size_t data_left = n;
765 while(data_left) {
766 ssize_t data_used;
768 DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));
770 data_used = process_incoming_data(p, data, data_left);
772 DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
774 if(data_used < 0) {
775 return -1;
778 data_left -= data_used;
779 data += data_used;
782 return n;
785 /****************************************************************************
786 Replies to a request to read data from a pipe.
788 Headers are interspersed with the data at PDU intervals. By the time
789 this function is called, the start of the data could possibly have been
790 read by an SMBtrans (file_offset != 0).
792 Calling create_rpc_reply() here is a hack. The data should already
793 have been prepared into arrays of headers + data stream sections.
794 ****************************************************************************/
796 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_t n,
797 bool *is_data_outstanding)
799 uint32 pdu_remaining = 0;
800 ssize_t data_returned = 0;
802 if (!p) {
803 DEBUG(0,("read_from_pipe: pipe not open\n"));
804 return -1;
807 DEBUG(6,(" name: %s len: %u\n",
808 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
809 (unsigned int)n));
812 * We cannot return more than one PDU length per
813 * read request.
817 * This condition should result in the connection being closed.
818 * Netapp filers seem to set it to 0xffff which results in domain
819 * authentications failing. Just ignore it so things work.
822 if(n > RPC_MAX_PDU_FRAG_LEN) {
823 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
824 "pipe %s. We can only service %d sized reads.\n",
825 (unsigned int)n,
826 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
827 RPC_MAX_PDU_FRAG_LEN ));
828 n = RPC_MAX_PDU_FRAG_LEN;
832 * Determine if there is still data to send in the
833 * pipe PDU buffer. Always send this first. Never
834 * send more than is left in the current PDU. The
835 * client should send a new read request for a new
836 * PDU.
839 pdu_remaining = prs_offset(&p->out_data.frag)
840 - p->out_data.current_pdu_sent;
842 if (pdu_remaining > 0) {
843 data_returned = (ssize_t)MIN(n, pdu_remaining);
845 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
846 "current_pdu_sent = %u returning %d bytes.\n",
847 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
848 (unsigned int)prs_offset(&p->out_data.frag),
849 (unsigned int)p->out_data.current_pdu_sent,
850 (int)data_returned));
852 memcpy(data,
853 prs_data_p(&p->out_data.frag)
854 + p->out_data.current_pdu_sent,
855 data_returned);
857 p->out_data.current_pdu_sent += (uint32)data_returned;
858 goto out;
862 * At this point p->current_pdu_len == p->current_pdu_sent (which
863 * may of course be zero if this is the first return fragment.
866 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
867 "= %u, prs_offset(&p->out_data.rdata) = %u.\n",
868 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
869 (int)p->fault_state,
870 (unsigned int)p->out_data.data_sent_length,
871 (unsigned int)prs_offset(&p->out_data.rdata) ));
873 if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
875 * We have sent all possible data, return 0.
877 data_returned = 0;
878 goto out;
882 * We need to create a new PDU from the data left in p->rdata.
883 * Create the header/data/footers. This also sets up the fields
884 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
885 * and stores the outgoing PDU in p->current_pdu.
888 if(!create_next_pdu(p)) {
889 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
890 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
891 return -1;
894 data_returned = MIN(n, prs_offset(&p->out_data.frag));
896 memcpy( data, prs_data_p(&p->out_data.frag), (size_t)data_returned);
897 p->out_data.current_pdu_sent += (uint32)data_returned;
899 out:
900 (*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
902 if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
903 /* We've returned everything in the out_data.frag
904 * so we're done with this pdu. Free it and reset
905 * current_pdu_sent. */
906 p->out_data.current_pdu_sent = 0;
907 prs_mem_free(&p->out_data.frag);
909 return data_returned;
912 /****************************************************************************
913 Close an rpc pipe.
914 ****************************************************************************/
916 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
918 if (!p) {
919 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
920 return False;
923 prs_mem_free(&p->out_data.frag);
924 prs_mem_free(&p->out_data.rdata);
925 prs_mem_free(&p->in_data.data);
927 if (p->auth.auth_data_free_func) {
928 (*p->auth.auth_data_free_func)(&p->auth);
931 free_pipe_rpc_context( p->contexts );
933 /* Free the handles database. */
934 close_policy_by_pipe(p);
936 DLIST_REMOVE(InternalPipes, p);
938 ZERO_STRUCTP(p);
940 return 0;
943 bool fsp_is_np(struct files_struct *fsp)
945 enum FAKE_FILE_TYPE type;
947 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
948 return false;
951 type = fsp->fake_file_handle->type;
953 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
954 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
957 struct np_proxy_state {
958 struct tevent_queue *read_queue;
959 struct tevent_queue *write_queue;
960 int fd;
962 uint8_t *msg;
963 size_t sent;
966 static int np_proxy_state_destructor(struct np_proxy_state *state)
968 if (state->fd != -1) {
969 close(state->fd);
971 return 0;
974 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
975 const char *pipe_name,
976 struct auth_serversupplied_info *server_info)
978 struct np_proxy_state *result;
979 struct sockaddr_un addr;
980 char *socket_path;
981 const char *socket_dir;
983 DATA_BLOB req_blob;
984 struct netr_SamInfo3 *info3;
985 struct named_pipe_auth_req req;
986 DATA_BLOB rep_blob;
987 uint8 rep_buf[20];
988 struct named_pipe_auth_rep rep;
989 enum ndr_err_code ndr_err;
990 NTSTATUS status;
991 ssize_t written;
993 result = talloc(mem_ctx, struct np_proxy_state);
994 if (result == NULL) {
995 DEBUG(0, ("talloc failed\n"));
996 return NULL;
999 result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
1000 if (result->fd == -1) {
1001 DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
1002 goto fail;
1004 talloc_set_destructor(result, np_proxy_state_destructor);
1006 ZERO_STRUCT(addr);
1007 addr.sun_family = AF_UNIX;
1009 socket_dir = lp_parm_const_string(
1010 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
1011 get_dyn_NCALRPCDIR());
1012 if (socket_dir == NULL) {
1013 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
1014 goto fail;
1017 socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s",
1018 socket_dir, pipe_name);
1019 if (socket_path == NULL) {
1020 DEBUG(0, ("talloc_asprintf failed\n"));
1021 goto fail;
1023 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
1024 TALLOC_FREE(socket_path);
1026 become_root();
1027 if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
1028 unbecome_root();
1029 DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
1030 strerror(errno)));
1031 goto fail;
1033 unbecome_root();
1035 info3 = talloc(talloc_tos(), struct netr_SamInfo3);
1036 if (info3 == NULL) {
1037 DEBUG(0, ("talloc failed\n"));
1038 goto fail;
1041 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
1042 if (!NT_STATUS_IS_OK(status)) {
1043 TALLOC_FREE(info3);
1044 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
1045 nt_errstr(status)));
1046 goto fail;
1049 req.level = 1;
1050 req.info.info1 = *info3;
1052 ndr_err = ndr_push_struct_blob(
1053 &req_blob, talloc_tos(), NULL, &req,
1054 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
1056 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1057 DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n",
1058 ndr_errstr(ndr_err)));
1059 goto fail;
1062 DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length));
1063 dump_data(10, req_blob.data, req_blob.length);
1065 written = write_data(result->fd, (char *)req_blob.data,
1066 req_blob.length);
1067 if (written == -1) {
1068 DEBUG(3, ("Could not write auth req data to RPC server\n"));
1069 goto fail;
1072 status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf));
1073 if (!NT_STATUS_IS_OK(status)) {
1074 DEBUG(3, ("Could not read auth result\n"));
1075 goto fail;
1078 rep_blob = data_blob_const(rep_buf, sizeof(rep_buf));
1080 DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length));
1081 dump_data(10, rep_blob.data, rep_blob.length);
1083 ndr_err = ndr_pull_struct_blob(
1084 &rep_blob, talloc_tos(), NULL, &rep,
1085 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
1087 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1088 DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
1089 ndr_errstr(ndr_err)));
1090 goto fail;
1093 if (rep.length != 16) {
1094 DEBUG(0, ("req invalid length: %u != 16\n",
1095 rep.length));
1096 goto fail;
1099 if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) {
1100 DEBUG(0, ("req invalid magic: %s != %s\n",
1101 rep.magic, NAMED_PIPE_AUTH_MAGIC));
1102 goto fail;
1105 if (!NT_STATUS_IS_OK(rep.status)) {
1106 DEBUG(0, ("req failed: %s\n",
1107 nt_errstr(rep.status)));
1108 goto fail;
1111 if (rep.level != 1) {
1112 DEBUG(0, ("req invalid level: %u != 1\n",
1113 rep.level));
1114 goto fail;
1117 result->msg = NULL;
1119 result->read_queue = tevent_queue_create(result, "np_read");
1120 if (result->read_queue == NULL) {
1121 goto fail;
1123 result->write_queue = tevent_queue_create(result, "np_write");
1124 if (result->write_queue == NULL) {
1125 goto fail;
1128 return result;
1130 fail:
1131 TALLOC_FREE(result);
1132 return NULL;
1135 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1136 const char *client_address,
1137 struct auth_serversupplied_info *server_info,
1138 struct fake_file_handle **phandle)
1140 const char **proxy_list;
1141 struct fake_file_handle *handle;
1143 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1145 handle = talloc(mem_ctx, struct fake_file_handle);
1146 if (handle == NULL) {
1147 return NT_STATUS_NO_MEMORY;
1150 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1151 struct np_proxy_state *p;
1153 p = make_external_rpc_pipe_p(handle, name, server_info);
1155 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1156 handle->private_data = p;
1157 } else {
1158 struct pipes_struct *p;
1159 struct ndr_syntax_id syntax;
1161 if (!is_known_pipename(name, &syntax)) {
1162 TALLOC_FREE(handle);
1163 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1166 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1167 server_info);
1169 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1170 handle->private_data = p;
1173 if (handle->private_data == NULL) {
1174 TALLOC_FREE(handle);
1175 return NT_STATUS_PIPE_NOT_AVAILABLE;
1178 *phandle = handle;
1180 return NT_STATUS_OK;
1183 struct np_write_state {
1184 struct event_context *ev;
1185 struct np_proxy_state *p;
1186 struct iovec iov;
1187 ssize_t nwritten;
1190 static void np_write_done(struct tevent_req *subreq);
1192 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1193 struct fake_file_handle *handle,
1194 const uint8_t *data, size_t len)
1196 struct tevent_req *req;
1197 struct np_write_state *state;
1198 NTSTATUS status;
1200 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1201 dump_data(50, data, len);
1203 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1204 if (req == NULL) {
1205 return NULL;
1208 if (len == 0) {
1209 state->nwritten = 0;
1210 status = NT_STATUS_OK;
1211 goto post_status;
1214 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1215 struct pipes_struct *p = talloc_get_type_abort(
1216 handle->private_data, struct pipes_struct);
1218 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1220 status = (state->nwritten >= 0)
1221 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1222 goto post_status;
1225 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1226 struct np_proxy_state *p = talloc_get_type_abort(
1227 handle->private_data, struct np_proxy_state);
1228 struct tevent_req *subreq;
1230 state->ev = ev;
1231 state->p = p;
1232 state->iov.iov_base = CONST_DISCARD(void *, data);
1233 state->iov.iov_len = len;
1235 subreq = writev_send(state, ev, p->write_queue, p->fd,
1236 false, &state->iov, 1);
1237 if (subreq == NULL) {
1238 goto fail;
1240 tevent_req_set_callback(subreq, np_write_done, req);
1241 return req;
1244 status = NT_STATUS_INVALID_HANDLE;
1245 post_status:
1246 if (NT_STATUS_IS_OK(status)) {
1247 tevent_req_done(req);
1248 } else {
1249 tevent_req_nterror(req, status);
1251 return tevent_req_post(req, ev);
1252 fail:
1253 TALLOC_FREE(req);
1254 return NULL;
1257 static void np_write_done(struct tevent_req *subreq)
1259 struct tevent_req *req = tevent_req_callback_data(
1260 subreq, struct tevent_req);
1261 struct np_write_state *state = tevent_req_data(
1262 req, struct np_write_state);
1263 ssize_t received;
1264 int err;
1266 received = writev_recv(subreq, &err);
1267 if (received < 0) {
1268 tevent_req_nterror(req, map_nt_error_from_unix(err));
1269 return;
1271 state->nwritten = received;
1272 tevent_req_done(req);
1275 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1277 struct np_write_state *state = tevent_req_data(
1278 req, struct np_write_state);
1279 NTSTATUS status;
1281 if (tevent_req_is_nterror(req, &status)) {
1282 return status;
1284 *pnwritten = state->nwritten;
1285 return NT_STATUS_OK;
1288 static ssize_t rpc_frag_more_fn(uint8_t *buf, size_t buflen, void *priv)
1290 prs_struct hdr_prs;
1291 struct rpc_hdr_info hdr;
1292 bool ret;
1294 if (buflen > RPC_HEADER_LEN) {
1295 return 0;
1297 prs_init_empty(&hdr_prs, talloc_tos(), UNMARSHALL);
1298 prs_give_memory(&hdr_prs, (char *)buf, RPC_HEADER_LEN, false);
1299 ret = smb_io_rpc_hdr("", &hdr, &hdr_prs, 0);
1300 prs_mem_free(&hdr_prs);
1302 if (!ret) {
1303 return -1;
1306 return (hdr.frag_len - RPC_HEADER_LEN);
1309 struct np_read_state {
1310 struct event_context *ev;
1311 struct np_proxy_state *p;
1312 uint8_t *data;
1313 size_t len;
1315 size_t nread;
1316 bool is_data_outstanding;
1319 static void np_read_trigger(struct tevent_req *req, void *private_data);
1320 static void np_read_done(struct tevent_req *subreq);
1322 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1323 struct fake_file_handle *handle,
1324 uint8_t *data, size_t len)
1326 struct tevent_req *req;
1327 struct np_read_state *state;
1328 NTSTATUS status;
1330 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1331 if (req == NULL) {
1332 return NULL;
1335 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1336 struct pipes_struct *p = talloc_get_type_abort(
1337 handle->private_data, struct pipes_struct);
1339 state->nread = read_from_internal_pipe(
1340 p, (char *)data, len, &state->is_data_outstanding);
1342 status = (state->nread >= 0)
1343 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1344 goto post_status;
1347 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1348 struct np_proxy_state *p = talloc_get_type_abort(
1349 handle->private_data, struct np_proxy_state);
1351 if (p->msg != NULL) {
1352 size_t thistime;
1354 thistime = MIN(talloc_get_size(p->msg) - p->sent,
1355 len);
1357 memcpy(data, p->msg+p->sent, thistime);
1358 state->nread = thistime;
1359 p->sent += thistime;
1361 if (p->sent < talloc_get_size(p->msg)) {
1362 state->is_data_outstanding = true;
1363 } else {
1364 state->is_data_outstanding = false;
1365 TALLOC_FREE(p->msg);
1367 status = NT_STATUS_OK;
1368 goto post_status;
1371 state->ev = ev;
1372 state->p = p;
1373 state->data = data;
1374 state->len = len;
1376 if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
1377 NULL)) {
1378 goto fail;
1380 return req;
1383 status = NT_STATUS_INVALID_HANDLE;
1384 post_status:
1385 if (NT_STATUS_IS_OK(status)) {
1386 tevent_req_done(req);
1387 } else {
1388 tevent_req_nterror(req, status);
1390 return tevent_req_post(req, ev);
1391 fail:
1392 TALLOC_FREE(req);
1393 return NULL;
1396 static void np_read_trigger(struct tevent_req *req, void *private_data)
1398 struct np_read_state *state = tevent_req_data(
1399 req, struct np_read_state);
1400 struct tevent_req *subreq;
1402 subreq = read_packet_send(state, state->ev, state->p->fd,
1403 RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
1404 if (tevent_req_nomem(subreq, req)) {
1405 return;
1407 tevent_req_set_callback(subreq, np_read_done, req);
1410 static void np_read_done(struct tevent_req *subreq)
1412 struct tevent_req *req = tevent_req_callback_data(
1413 subreq, struct tevent_req);
1414 struct np_read_state *state = tevent_req_data(
1415 req, struct np_read_state);
1416 ssize_t received;
1417 size_t thistime;
1418 int err;
1420 received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
1421 TALLOC_FREE(subreq);
1422 if (received == -1) {
1423 tevent_req_nterror(req, map_nt_error_from_unix(err));
1424 return;
1427 thistime = MIN(received, state->len);
1429 memcpy(state->data, state->p->msg, thistime);
1430 state->p->sent = thistime;
1431 state->nread = thistime;
1433 if (state->p->sent < received) {
1434 state->is_data_outstanding = true;
1435 } else {
1436 TALLOC_FREE(state->p->msg);
1437 state->is_data_outstanding = false;
1440 tevent_req_done(req);
1441 return;
1444 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1445 bool *is_data_outstanding)
1447 struct np_read_state *state = tevent_req_data(
1448 req, struct np_read_state);
1449 NTSTATUS status;
1451 if (tevent_req_is_nterror(req, &status)) {
1452 return status;
1454 *nread = state->nread;
1455 *is_data_outstanding = state->is_data_outstanding;
1456 return NT_STATUS_OK;
1460 * @brief Create a new RPC client context which uses a local dispatch function.
1462 * @param[in] mem_ctx The memory context to use.
1464 * @param[in] abstract_syntax Normally the syntax_id of the autogenerated
1465 * ndr_table_<name>.
1467 * @param[in] dispatch The corresponding autogenerated dispatch function
1468 * rpc_<name>_dispatch.
1470 * @param[in] serversupplied_info The server supplied authentication function.
1472 * @param[out] presult A pointer to store the connected rpc client pipe.
1474 * @return NT_STATUS_OK on success, a corresponding NT status if an
1475 * error occured.
1477 * @code
1478 * struct rpc_pipe_client *winreg_pipe;
1479 * NTSTATUS status;
1481 * status = rpc_pipe_open_internal(tmp_ctx,
1482 * &ndr_table_winreg.syntax_id,
1483 * rpc_winreg_dispatch,
1484 * p->server_info,
1485 * &winreg_pipe);
1486 * @endcode
1488 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
1489 const struct ndr_syntax_id *abstract_syntax,
1490 NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
1491 TALLOC_CTX *mem_ctx,
1492 const struct ndr_interface_table *table,
1493 uint32_t opnum, void *r),
1494 struct auth_serversupplied_info *serversupplied_info,
1495 struct rpc_pipe_client **presult)
1497 struct rpc_pipe_client *result;
1499 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
1500 if (result == NULL) {
1501 return NT_STATUS_NO_MEMORY;
1504 result->abstract_syntax = *abstract_syntax;
1505 result->transfer_syntax = ndr_transfer_syntax;
1506 result->dispatch = dispatch;
1508 result->pipes_struct = make_internal_rpc_pipe_p(
1509 result, abstract_syntax, "", serversupplied_info);
1510 if (result->pipes_struct == NULL) {
1511 TALLOC_FREE(result);
1512 return NT_STATUS_NO_MEMORY;
1515 result->max_xmit_frag = -1;
1516 result->max_recv_frag = -1;
1518 *presult = result;
1519 return NT_STATUS_OK;
1522 /*******************************************************************
1523 gets a domain user's groups from their already-calculated NT_USER_TOKEN
1524 ********************************************************************/
1526 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
1527 const DOM_SID *domain_sid,
1528 size_t num_sids,
1529 const DOM_SID *sids,
1530 int *numgroups,
1531 struct samr_RidWithAttribute **pgids)
1533 int i;
1535 *numgroups=0;
1536 *pgids = NULL;
1538 for (i=0; i<num_sids; i++) {
1539 struct samr_RidWithAttribute gid;
1540 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
1541 continue;
1543 gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
1544 SE_GROUP_ENABLED);
1545 ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
1546 gid, pgids, numgroups);
1547 if (*pgids == NULL) {
1548 return NT_STATUS_NO_MEMORY;
1551 return NT_STATUS_OK;
1554 /****************************************************************************
1555 inits a netr_SamBaseInfo structure from an auth_serversupplied_info.
1556 *****************************************************************************/
1558 static NTSTATUS serverinfo_to_SamInfo_base(TALLOC_CTX *mem_ctx,
1559 struct auth_serversupplied_info *server_info,
1560 uint8_t *pipe_session_key,
1561 size_t pipe_session_key_len,
1562 struct netr_SamBaseInfo *base)
1564 struct samu *sampw;
1565 struct samr_RidWithAttribute *gids = NULL;
1566 const DOM_SID *user_sid = NULL;
1567 const DOM_SID *group_sid = NULL;
1568 DOM_SID domain_sid;
1569 uint32 user_rid, group_rid;
1570 NTSTATUS status;
1572 int num_gids = 0;
1573 const char *my_name;
1575 struct netr_UserSessionKey user_session_key;
1576 struct netr_LMSessionKey lm_session_key;
1578 NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
1579 NTTIME allow_password_change, force_password_change;
1580 struct samr_RidWithAttributeArray groups;
1581 int i;
1582 struct dom_sid2 *sid = NULL;
1584 ZERO_STRUCT(user_session_key);
1585 ZERO_STRUCT(lm_session_key);
1587 sampw = server_info->sam_account;
1589 user_sid = pdb_get_user_sid(sampw);
1590 group_sid = pdb_get_group_sid(sampw);
1592 if (pipe_session_key && pipe_session_key_len != 16) {
1593 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
1594 "pipe_session_key_len[%zu] != 16\n",
1595 pipe_session_key_len));
1596 return NT_STATUS_INTERNAL_ERROR;
1599 if ((user_sid == NULL) || (group_sid == NULL)) {
1600 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
1601 return NT_STATUS_UNSUCCESSFUL;
1604 sid_copy(&domain_sid, user_sid);
1605 sid_split_rid(&domain_sid, &user_rid);
1607 sid = sid_dup_talloc(mem_ctx, &domain_sid);
1608 if (!sid) {
1609 return NT_STATUS_NO_MEMORY;
1612 if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
1613 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
1614 "%s\n but group sid %s.\n"
1615 "The conflicting domain portions are not "
1616 "supported for NETLOGON calls\n",
1617 pdb_get_domain(sampw),
1618 pdb_get_username(sampw),
1619 sid_string_dbg(user_sid),
1620 sid_string_dbg(group_sid)));
1621 return NT_STATUS_UNSUCCESSFUL;
1624 if(server_info->login_server) {
1625 my_name = server_info->login_server;
1626 } else {
1627 my_name = global_myname();
1630 status = nt_token_to_group_list(mem_ctx, &domain_sid,
1631 server_info->num_sids,
1632 server_info->sids,
1633 &num_gids, &gids);
1635 if (!NT_STATUS_IS_OK(status)) {
1636 return status;
1639 if (server_info->user_session_key.length) {
1640 memcpy(user_session_key.key,
1641 server_info->user_session_key.data,
1642 MIN(sizeof(user_session_key.key),
1643 server_info->user_session_key.length));
1644 if (pipe_session_key) {
1645 arcfour_crypt(user_session_key.key, pipe_session_key, 16);
1648 if (server_info->lm_session_key.length) {
1649 memcpy(lm_session_key.key,
1650 server_info->lm_session_key.data,
1651 MIN(sizeof(lm_session_key.key),
1652 server_info->lm_session_key.length));
1653 if (pipe_session_key) {
1654 arcfour_crypt(lm_session_key.key, pipe_session_key, 8);
1658 groups.count = num_gids;
1659 groups.rids = TALLOC_ARRAY(mem_ctx, struct samr_RidWithAttribute, groups.count);
1660 if (!groups.rids) {
1661 return NT_STATUS_NO_MEMORY;
1664 for (i=0; i < groups.count; i++) {
1665 groups.rids[i].rid = gids[i].rid;
1666 groups.rids[i].attributes = gids[i].attributes;
1669 unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
1670 unix_to_nt_time(&last_logoff, get_time_t_max());
1671 unix_to_nt_time(&acct_expiry, get_time_t_max());
1672 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
1673 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
1674 unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
1676 base->last_logon = last_logon;
1677 base->last_logoff = last_logoff;
1678 base->acct_expiry = acct_expiry;
1679 base->last_password_change = last_password_change;
1680 base->allow_password_change = allow_password_change;
1681 base->force_password_change = force_password_change;
1682 base->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(sampw));
1683 base->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(sampw));
1684 base->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(sampw));
1685 base->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(sampw));
1686 base->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(sampw));
1687 base->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(sampw));
1688 base->logon_count = 0; /* ?? */
1689 base->bad_password_count = 0; /* ?? */
1690 base->rid = user_rid;
1691 base->primary_gid = group_rid;
1692 base->groups = groups;
1693 base->user_flags = NETLOGON_EXTRA_SIDS;
1694 base->key = user_session_key;
1695 base->logon_server.string = talloc_strdup(mem_ctx, my_name);
1696 base->domain.string = talloc_strdup(mem_ctx, pdb_get_domain(sampw));
1697 base->domain_sid = sid;
1698 base->LMSessKey = lm_session_key;
1699 base->acct_flags = pdb_get_acct_ctrl(sampw);
1701 ZERO_STRUCT(user_session_key);
1702 ZERO_STRUCT(lm_session_key);
1704 return NT_STATUS_OK;
1707 /****************************************************************************
1708 inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
1709 already be initialized and is used as the talloc parent for its members.
1710 *****************************************************************************/
1712 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
1713 uint8_t *pipe_session_key,
1714 size_t pipe_session_key_len,
1715 struct netr_SamInfo2 *sam2)
1717 NTSTATUS status;
1719 status = serverinfo_to_SamInfo_base(sam2,
1720 server_info,
1721 pipe_session_key,
1722 pipe_session_key_len,
1723 &sam2->base);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 return status;
1728 return NT_STATUS_OK;
1731 /****************************************************************************
1732 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
1733 already be initialized and is used as the talloc parent for its members.
1734 *****************************************************************************/
1736 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
1737 uint8_t *pipe_session_key,
1738 size_t pipe_session_key_len,
1739 struct netr_SamInfo3 *sam3)
1741 NTSTATUS status;
1743 status = serverinfo_to_SamInfo_base(sam3,
1744 server_info,
1745 pipe_session_key,
1746 pipe_session_key_len,
1747 &sam3->base);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 return status;
1752 sam3->sidcount = 0;
1753 sam3->sids = NULL;
1755 return NT_STATUS_OK;
1758 /****************************************************************************
1759 inits a netr_SamInfo6 structure from an auth_serversupplied_info. sam6 must
1760 already be initialized and is used as the talloc parent for its members.
1761 *****************************************************************************/
1763 NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
1764 uint8_t *pipe_session_key,
1765 size_t pipe_session_key_len,
1766 struct netr_SamInfo6 *sam6)
1768 NTSTATUS status;
1769 struct pdb_domain_info *dominfo;
1771 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1772 DEBUG(10,("Not adding validation info level 6 "
1773 "without ADS passdb backend\n"));
1774 return NT_STATUS_INVALID_INFO_CLASS;
1777 dominfo = pdb_get_domain_info(sam6);
1778 if (dominfo == NULL) {
1779 return NT_STATUS_NO_MEMORY;
1782 status = serverinfo_to_SamInfo_base(sam6,
1783 server_info,
1784 pipe_session_key,
1785 pipe_session_key_len,
1786 &sam6->base);
1787 if (!NT_STATUS_IS_OK(status)) {
1788 return status;
1791 sam6->sidcount = 0;
1792 sam6->sids = NULL;
1794 sam6->forest.string = talloc_strdup(sam6, dominfo->dns_forest);
1795 if (sam6->forest.string == NULL) {
1796 return NT_STATUS_NO_MEMORY;
1799 sam6->principle.string = talloc_asprintf(sam6, "%s@%s",
1800 pdb_get_username(server_info->sam_account),
1801 dominfo->dns_domain);
1802 if (sam6->principle.string == NULL) {
1803 return NT_STATUS_NO_MEMORY;
1806 return NT_STATUS_OK;