tdb: raise version to 1.2.1
[Samba.git] / source3 / rpc_server / srv_pipe_hnd.c
blob83f27fee8e5110b42d434231a2b17e833e817734
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_init("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_destroy(p->mem_ctx);
120 TALLOC_FREE(p);
121 return NULL;
125 * Initialize the incoming RPC data buffer with one PDU worth of memory.
126 * We cheat here and say we're marshalling, as we intend to add incoming
127 * data directly into the prs_struct and we want it to auto grow. We will
128 * change the type to UNMARSALLING before processing the stream.
131 if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
132 DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
133 talloc_destroy(p->mem_ctx);
134 close_policy_by_pipe(p);
135 TALLOC_FREE(p);
136 return NULL;
139 p->server_info = copy_serverinfo(p, server_info);
140 if (p->server_info == NULL) {
141 DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
142 talloc_destroy(p->mem_ctx);
143 close_policy_by_pipe(p);
144 TALLOC_FREE(p);
145 return NULL;
148 DLIST_ADD(InternalPipes, p);
150 memcpy(p->client_address, client_address, sizeof(p->client_address));
152 p->endian = RPC_LITTLE_ENDIAN;
155 * Initialize the outgoing RPC data buffer with no memory.
157 prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);
159 p->syntax = *syntax;
161 DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
162 get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open));
164 talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
166 return p;
169 /****************************************************************************
170 Sets the fault state on incoming packets.
171 ****************************************************************************/
173 static void set_incoming_fault(pipes_struct *p)
175 prs_mem_free(&p->in_data.data);
176 p->in_data.pdu_needed_len = 0;
177 p->in_data.pdu_received_len = 0;
178 p->fault_state = True;
179 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
180 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
183 /****************************************************************************
184 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
185 ****************************************************************************/
187 static ssize_t fill_rpc_header(pipes_struct *p, char *data, size_t data_to_copy)
189 size_t len_needed_to_complete_hdr = MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu_received_len);
191 DEBUG(10,("fill_rpc_header: data_to_copy = %u, len_needed_to_complete_hdr = %u, receive_len = %u\n",
192 (unsigned int)data_to_copy, (unsigned int)len_needed_to_complete_hdr,
193 (unsigned int)p->in_data.pdu_received_len ));
195 if (p->in_data.current_in_pdu == NULL) {
196 p->in_data.current_in_pdu = talloc_array(p, uint8_t,
197 RPC_HEADER_LEN);
199 if (p->in_data.current_in_pdu == NULL) {
200 DEBUG(0, ("talloc failed\n"));
201 return -1;
204 memcpy((char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, len_needed_to_complete_hdr);
205 p->in_data.pdu_received_len += len_needed_to_complete_hdr;
207 return (ssize_t)len_needed_to_complete_hdr;
210 /****************************************************************************
211 Unmarshalls a new PDU header. Assumes the raw header data is in current_in_pdu.
212 ****************************************************************************/
214 static ssize_t unmarshall_rpc_header(pipes_struct *p)
217 * Unmarshall the header to determine the needed length.
220 prs_struct rpc_in;
222 if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
223 DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
224 set_incoming_fault(p);
225 return -1;
228 prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
229 prs_set_endian_data( &rpc_in, p->endian);
231 prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
232 p->in_data.pdu_received_len, False);
235 * Unmarshall the header as this will tell us how much
236 * data we need to read to get the complete pdu.
237 * This also sets the endian flag in rpc_in.
240 if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
241 DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
242 set_incoming_fault(p);
243 prs_mem_free(&rpc_in);
244 return -1;
248 * Validate the RPC header.
251 if(p->hdr.major != 5 && p->hdr.minor != 0) {
252 DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
253 set_incoming_fault(p);
254 prs_mem_free(&rpc_in);
255 return -1;
259 * If there's not data in the incoming buffer this should be the start of a new RPC.
262 if(prs_offset(&p->in_data.data) == 0) {
265 * AS/U doesn't set FIRST flag in a BIND packet it seems.
268 if ((p->hdr.pkt_type == DCERPC_PKT_REQUEST) && !(p->hdr.flags & DCERPC_PFC_FLAG_FIRST)) {
270 * Ensure that the FIRST flag is set. If not then we have
271 * a stream missmatch.
274 DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
275 set_incoming_fault(p);
276 prs_mem_free(&rpc_in);
277 return -1;
281 * If this is the first PDU then set the endianness
282 * flag in the pipe. We will need this when parsing all
283 * data in this RPC.
286 p->endian = rpc_in.bigendian_data;
288 DEBUG(5,("unmarshall_rpc_header: using %sendian RPC\n",
289 p->endian == RPC_LITTLE_ENDIAN ? "little-" : "big-" ));
291 } else {
294 * If this is *NOT* the first PDU then check the endianness
295 * flag in the pipe is the same as that in the PDU.
298 if (p->endian != rpc_in.bigendian_data) {
299 DEBUG(0,("unmarshall_rpc_header: FIRST endianness flag (%d) different in next PDU !\n", (int)p->endian));
300 set_incoming_fault(p);
301 prs_mem_free(&rpc_in);
302 return -1;
307 * Ensure that the pdu length is sane.
310 if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > RPC_MAX_PDU_FRAG_LEN)) {
311 DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
312 set_incoming_fault(p);
313 prs_mem_free(&rpc_in);
314 return -1;
317 DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
318 (unsigned int)p->hdr.flags ));
320 p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;
322 prs_mem_free(&rpc_in);
324 p->in_data.current_in_pdu = TALLOC_REALLOC_ARRAY(
325 p, p->in_data.current_in_pdu, uint8_t, p->hdr.frag_len);
326 if (p->in_data.current_in_pdu == NULL) {
327 DEBUG(0, ("talloc failed\n"));
328 set_incoming_fault(p);
329 return -1;
332 return 0; /* No extra data processed. */
335 /****************************************************************************
336 Call this to free any talloc'ed memory. Do this before and after processing
337 a complete PDU.
338 ****************************************************************************/
340 static void free_pipe_context(pipes_struct *p)
342 if (p->mem_ctx) {
343 DEBUG(3,("free_pipe_context: destroying talloc pool of size "
344 "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
345 talloc_free_children(p->mem_ctx);
346 } else {
347 p->mem_ctx = talloc_init(
348 "pipe %s %p", get_pipe_name_from_syntax(talloc_tos(),
349 &p->syntax),
351 if (p->mem_ctx == NULL) {
352 p->fault_state = True;
357 /****************************************************************************
358 Processes a request pdu. This will do auth processing if needed, and
359 appends the data into the complete stream if the LAST flag is not set.
360 ****************************************************************************/
362 static bool process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
364 uint32 ss_padding_len = 0;
365 size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
366 (p->hdr.auth_len ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
368 if(!p->pipe_bound) {
369 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
370 set_incoming_fault(p);
371 return False;
375 * Check if we need to do authentication processing.
376 * This is only done on requests, not binds.
380 * Read the RPC request header.
383 if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) {
384 DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n"));
385 set_incoming_fault(p);
386 return False;
389 switch(p->auth.auth_type) {
390 case PIPE_AUTH_TYPE_NONE:
391 break;
393 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
394 case PIPE_AUTH_TYPE_NTLMSSP:
396 NTSTATUS status;
397 if(!api_pipe_ntlmssp_auth_process(p, rpc_in_p, &ss_padding_len, &status)) {
398 DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
399 DEBUG(0,("process_request_pdu: error was %s.\n", nt_errstr(status) ));
400 set_incoming_fault(p);
401 return False;
403 break;
406 case PIPE_AUTH_TYPE_SCHANNEL:
407 if (!api_pipe_schannel_process(p, rpc_in_p, &ss_padding_len)) {
408 DEBUG(3,("process_request_pdu: failed to do schannel processing.\n"));
409 set_incoming_fault(p);
410 return False;
412 break;
414 default:
415 DEBUG(0,("process_request_pdu: unknown auth type %u set.\n", (unsigned int)p->auth.auth_type ));
416 set_incoming_fault(p);
417 return False;
420 /* Now we've done the sign/seal we can remove any padding data. */
421 if (data_len > ss_padding_len) {
422 data_len -= ss_padding_len;
426 * Check the data length doesn't go over the 15Mb limit.
427 * increased after observing a bug in the Windows NT 4.0 SP6a
428 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
429 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
432 if(prs_offset(&p->in_data.data) + data_len > MAX_RPC_DATA_SIZE) {
433 DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
434 (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
435 set_incoming_fault(p);
436 return False;
440 * Append the data portion into the buffer and return.
443 if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) {
444 DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
445 (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
446 set_incoming_fault(p);
447 return False;
450 if(p->hdr.flags & DCERPC_PFC_FLAG_LAST) {
451 bool ret = False;
453 * Ok - we finally have a complete RPC stream.
454 * Call the rpc command to process it.
458 * Ensure the internal prs buffer size is *exactly* the same
459 * size as the current offset.
462 if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
463 DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n"));
464 set_incoming_fault(p);
465 return False;
469 * Set the parse offset to the start of the data and set the
470 * prs_struct to UNMARSHALL.
473 prs_set_offset(&p->in_data.data, 0);
474 prs_switch_type(&p->in_data.data, UNMARSHALL);
477 * Process the complete data stream here.
480 free_pipe_context(p);
482 if(pipe_init_outgoing_data(p)) {
483 ret = api_pipe_request(p);
486 free_pipe_context(p);
489 * We have consumed the whole data stream. Set back to
490 * marshalling and set the offset back to the start of
491 * the buffer to re-use it (we could also do a prs_mem_free()
492 * and then re_init on the next start of PDU. Not sure which
493 * is best here.... JRA.
496 prs_switch_type(&p->in_data.data, MARSHALL);
497 prs_set_offset(&p->in_data.data, 0);
498 return ret;
501 return True;
504 /****************************************************************************
505 Processes a finished PDU stored in current_in_pdu. The RPC_HEADER has
506 already been parsed and stored in p->hdr.
507 ****************************************************************************/
509 static void process_complete_pdu(pipes_struct *p)
511 prs_struct rpc_in;
512 size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
513 char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
514 bool reply = False;
516 if(p->fault_state) {
517 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
518 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
519 set_incoming_fault(p);
520 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
521 return;
524 prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
527 * Ensure we're using the corrent endianness for both the
528 * RPC header flags and the raw data we will be reading from.
531 prs_set_endian_data( &rpc_in, p->endian);
532 prs_set_endian_data( &p->in_data.data, p->endian);
534 prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
536 DEBUG(10,("process_complete_pdu: processing packet type %u\n",
537 (unsigned int)p->hdr.pkt_type ));
539 switch (p->hdr.pkt_type) {
540 case DCERPC_PKT_REQUEST:
541 reply = process_request_pdu(p, &rpc_in);
542 break;
544 case DCERPC_PKT_PING: /* CL request - ignore... */
545 DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
546 (unsigned int)p->hdr.pkt_type,
547 get_pipe_name_from_syntax(talloc_tos(),
548 &p->syntax)));
549 break;
551 case DCERPC_PKT_RESPONSE: /* No responses here. */
552 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_RESPONSE received from client on pipe %s.\n",
553 get_pipe_name_from_syntax(talloc_tos(),
554 &p->syntax)));
555 break;
557 case DCERPC_PKT_FAULT:
558 case DCERPC_PKT_WORKING: /* CL request - reply to a ping when a call in process. */
559 case DCERPC_PKT_NOCALL: /* CL - server reply to a ping call. */
560 case DCERPC_PKT_REJECT:
561 case DCERPC_PKT_ACK:
562 case DCERPC_PKT_CL_CANCEL:
563 case DCERPC_PKT_FACK:
564 case DCERPC_PKT_CANCEL_ACK:
565 DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
566 (unsigned int)p->hdr.pkt_type,
567 get_pipe_name_from_syntax(talloc_tos(),
568 &p->syntax)));
569 break;
571 case DCERPC_PKT_BIND:
573 * We assume that a pipe bind is only in one pdu.
575 if(pipe_init_outgoing_data(p)) {
576 reply = api_pipe_bind_req(p, &rpc_in);
578 break;
580 case DCERPC_PKT_BIND_ACK:
581 case DCERPC_PKT_BIND_NAK:
582 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK packet type %u received on pipe %s.\n",
583 (unsigned int)p->hdr.pkt_type,
584 get_pipe_name_from_syntax(talloc_tos(),
585 &p->syntax)));
586 break;
589 case DCERPC_PKT_ALTER:
591 * We assume that a pipe bind is only in one pdu.
593 if(pipe_init_outgoing_data(p)) {
594 reply = api_pipe_alter_context(p, &rpc_in);
596 break;
598 case DCERPC_PKT_ALTER_RESP:
599 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_ALTER_RESP on pipe %s: Should only be server -> client.\n",
600 get_pipe_name_from_syntax(talloc_tos(),
601 &p->syntax)));
602 break;
604 case DCERPC_PKT_AUTH3:
606 * The third packet in an NTLMSSP auth exchange.
608 if(pipe_init_outgoing_data(p)) {
609 reply = api_pipe_bind_auth3(p, &rpc_in);
611 break;
613 case DCERPC_PKT_SHUTDOWN:
614 DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_SHUTDOWN on pipe %s: Should only be server -> client.\n",
615 get_pipe_name_from_syntax(talloc_tos(),
616 &p->syntax)));
617 break;
619 case DCERPC_PKT_CO_CANCEL:
620 /* For now just free all client data and continue processing. */
621 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL. Abandoning rpc call.\n"));
622 /* As we never do asynchronous RPC serving, we can never cancel a
623 call (as far as I know). If we ever did we'd have to send a cancel_ack
624 reply. For now, just free all client data and continue processing. */
625 reply = True;
626 break;
627 #if 0
628 /* Enable this if we're doing async rpc. */
629 /* We must check the call-id matches the outstanding callid. */
630 if(pipe_init_outgoing_data(p)) {
631 /* Send a cancel_ack PDU reply. */
632 /* We should probably check the auth-verifier here. */
633 reply = setup_cancel_ack_reply(p, &rpc_in);
635 break;
636 #endif
638 case DCERPC_PKT_ORPHANED:
639 /* We should probably check the auth-verifier here.
640 For now just free all client data and continue processing. */
641 DEBUG(3,("process_complete_pdu: DCERPC_PKT_ORPHANED. Abandoning rpc call.\n"));
642 reply = True;
643 break;
645 default:
646 DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
647 break;
650 /* Reset to little endian. Probably don't need this but it won't hurt. */
651 prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);
653 if (!reply) {
654 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
655 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
656 &p->syntax)));
657 set_incoming_fault(p);
658 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
659 prs_mem_free(&rpc_in);
660 } else {
662 * Reset the lengths. We're ready for a new pdu.
664 TALLOC_FREE(p->in_data.current_in_pdu);
665 p->in_data.pdu_needed_len = 0;
666 p->in_data.pdu_received_len = 0;
669 prs_mem_free(&rpc_in);
672 /****************************************************************************
673 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
674 ****************************************************************************/
676 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
678 size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
680 DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
681 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
682 (unsigned int)n ));
684 if(data_to_copy == 0) {
686 * This is an error - data is being received and there is no
687 * space in the PDU. Free the received data and go into the fault state.
689 DEBUG(0,("process_incoming_data: No space in incoming pdu buffer. Current size = %u \
690 incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)n ));
691 set_incoming_fault(p);
692 return -1;
696 * If we have no data already, wait until we get at least a RPC_HEADER_LEN
697 * number of bytes before we can do anything.
700 if((p->in_data.pdu_needed_len == 0) && (p->in_data.pdu_received_len < RPC_HEADER_LEN)) {
702 * Always return here. If we have more data then the RPC_HEADER
703 * will be processed the next time around the loop.
705 return fill_rpc_header(p, data, data_to_copy);
709 * At this point we know we have at least an RPC_HEADER_LEN amount of data
710 * stored in current_in_pdu.
714 * If pdu_needed_len is zero this is a new pdu.
715 * Unmarshall the header so we know how much more
716 * data we need, then loop again.
719 if(p->in_data.pdu_needed_len == 0) {
720 ssize_t rret = unmarshall_rpc_header(p);
721 if (rret == -1 || p->in_data.pdu_needed_len > 0) {
722 return rret;
724 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists
725 of an RPC_HEADER only. This is a DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or DCERPC_PKT_ORPHANED
726 pdu type. Deal with this in process_complete_pdu(). */
730 * Ok - at this point we have a valid RPC_HEADER in p->hdr.
731 * Keep reading until we have a full pdu.
734 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
737 * Copy as much of the data as we need into the current_in_pdu buffer.
738 * pdu_needed_len becomes zero when we have a complete pdu.
741 memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);
742 p->in_data.pdu_received_len += data_to_copy;
743 p->in_data.pdu_needed_len -= data_to_copy;
746 * Do we have a complete PDU ?
747 * (return the number of bytes handled in the call)
750 if(p->in_data.pdu_needed_len == 0) {
751 process_complete_pdu(p);
752 return data_to_copy;
755 DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
756 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
758 return (ssize_t)data_to_copy;
761 /****************************************************************************
762 Accepts incoming data on an internal rpc pipe.
763 ****************************************************************************/
765 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
767 size_t data_left = n;
769 while(data_left) {
770 ssize_t data_used;
772 DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));
774 data_used = process_incoming_data(p, data, data_left);
776 DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
778 if(data_used < 0) {
779 return -1;
782 data_left -= data_used;
783 data += data_used;
786 return n;
789 /****************************************************************************
790 Replies to a request to read data from a pipe.
792 Headers are interspersed with the data at PDU intervals. By the time
793 this function is called, the start of the data could possibly have been
794 read by an SMBtrans (file_offset != 0).
796 Calling create_rpc_reply() here is a hack. The data should already
797 have been prepared into arrays of headers + data stream sections.
798 ****************************************************************************/
800 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_t n,
801 bool *is_data_outstanding)
803 uint32 pdu_remaining = 0;
804 ssize_t data_returned = 0;
806 if (!p) {
807 DEBUG(0,("read_from_pipe: pipe not open\n"));
808 return -1;
811 DEBUG(6,(" name: %s len: %u\n",
812 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
813 (unsigned int)n));
816 * We cannot return more than one PDU length per
817 * read request.
821 * This condition should result in the connection being closed.
822 * Netapp filers seem to set it to 0xffff which results in domain
823 * authentications failing. Just ignore it so things work.
826 if(n > RPC_MAX_PDU_FRAG_LEN) {
827 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
828 "pipe %s. We can only service %d sized reads.\n",
829 (unsigned int)n,
830 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
831 RPC_MAX_PDU_FRAG_LEN ));
832 n = RPC_MAX_PDU_FRAG_LEN;
836 * Determine if there is still data to send in the
837 * pipe PDU buffer. Always send this first. Never
838 * send more than is left in the current PDU. The
839 * client should send a new read request for a new
840 * PDU.
843 pdu_remaining = prs_offset(&p->out_data.frag)
844 - p->out_data.current_pdu_sent;
846 if (pdu_remaining > 0) {
847 data_returned = (ssize_t)MIN(n, pdu_remaining);
849 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
850 "current_pdu_sent = %u returning %d bytes.\n",
851 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
852 (unsigned int)prs_offset(&p->out_data.frag),
853 (unsigned int)p->out_data.current_pdu_sent,
854 (int)data_returned));
856 memcpy(data,
857 prs_data_p(&p->out_data.frag)
858 + p->out_data.current_pdu_sent,
859 data_returned);
861 p->out_data.current_pdu_sent += (uint32)data_returned;
862 goto out;
866 * At this point p->current_pdu_len == p->current_pdu_sent (which
867 * may of course be zero if this is the first return fragment.
870 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
871 "= %u, prs_offset(&p->out_data.rdata) = %u.\n",
872 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
873 (int)p->fault_state,
874 (unsigned int)p->out_data.data_sent_length,
875 (unsigned int)prs_offset(&p->out_data.rdata) ));
877 if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
879 * We have sent all possible data, return 0.
881 data_returned = 0;
882 goto out;
886 * We need to create a new PDU from the data left in p->rdata.
887 * Create the header/data/footers. This also sets up the fields
888 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
889 * and stores the outgoing PDU in p->current_pdu.
892 if(!create_next_pdu(p)) {
893 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
894 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
895 return -1;
898 data_returned = MIN(n, prs_offset(&p->out_data.frag));
900 memcpy( data, prs_data_p(&p->out_data.frag), (size_t)data_returned);
901 p->out_data.current_pdu_sent += (uint32)data_returned;
903 out:
904 (*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
906 if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
907 /* We've returned everything in the out_data.frag
908 * so we're done with this pdu. Free it and reset
909 * current_pdu_sent. */
910 p->out_data.current_pdu_sent = 0;
911 prs_mem_free(&p->out_data.frag);
913 return data_returned;
916 /****************************************************************************
917 Close an rpc pipe.
918 ****************************************************************************/
920 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
922 if (!p) {
923 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
924 return False;
927 prs_mem_free(&p->out_data.frag);
928 prs_mem_free(&p->out_data.rdata);
929 prs_mem_free(&p->in_data.data);
931 if (p->auth.auth_data_free_func) {
932 (*p->auth.auth_data_free_func)(&p->auth);
935 TALLOC_FREE(p->mem_ctx);
937 free_pipe_rpc_context( p->contexts );
939 /* Free the handles database. */
940 close_policy_by_pipe(p);
942 DLIST_REMOVE(InternalPipes, p);
944 ZERO_STRUCTP(p);
946 TALLOC_FREE(p);
948 return True;
951 bool fsp_is_np(struct files_struct *fsp)
953 enum FAKE_FILE_TYPE type;
955 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
956 return false;
959 type = fsp->fake_file_handle->type;
961 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
962 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
965 struct np_proxy_state {
966 struct tevent_queue *read_queue;
967 struct tevent_queue *write_queue;
968 int fd;
970 uint8_t *msg;
971 size_t sent;
974 static int np_proxy_state_destructor(struct np_proxy_state *state)
976 if (state->fd != -1) {
977 close(state->fd);
979 return 0;
982 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
983 const char *pipe_name,
984 struct auth_serversupplied_info *server_info)
986 struct np_proxy_state *result;
987 struct sockaddr_un addr;
988 char *socket_path;
989 const char *socket_dir;
991 DATA_BLOB req_blob;
992 struct netr_SamInfo3 *info3;
993 struct named_pipe_auth_req req;
994 DATA_BLOB rep_blob;
995 uint8 rep_buf[20];
996 struct named_pipe_auth_rep rep;
997 enum ndr_err_code ndr_err;
998 NTSTATUS status;
999 ssize_t written;
1001 result = talloc(mem_ctx, struct np_proxy_state);
1002 if (result == NULL) {
1003 DEBUG(0, ("talloc failed\n"));
1004 return NULL;
1007 result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
1008 if (result->fd == -1) {
1009 DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
1010 goto fail;
1012 talloc_set_destructor(result, np_proxy_state_destructor);
1014 ZERO_STRUCT(addr);
1015 addr.sun_family = AF_UNIX;
1017 socket_dir = lp_parm_const_string(
1018 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
1019 get_dyn_NCALRPCDIR());
1020 if (socket_dir == NULL) {
1021 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
1022 goto fail;
1025 socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s",
1026 socket_dir, pipe_name);
1027 if (socket_path == NULL) {
1028 DEBUG(0, ("talloc_asprintf failed\n"));
1029 goto fail;
1031 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
1032 TALLOC_FREE(socket_path);
1034 become_root();
1035 if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
1036 unbecome_root();
1037 DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
1038 strerror(errno)));
1039 goto fail;
1041 unbecome_root();
1043 info3 = talloc(talloc_tos(), struct netr_SamInfo3);
1044 if (info3 == NULL) {
1045 DEBUG(0, ("talloc failed\n"));
1046 goto fail;
1049 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
1050 if (!NT_STATUS_IS_OK(status)) {
1051 TALLOC_FREE(info3);
1052 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
1053 nt_errstr(status)));
1054 goto fail;
1057 req.level = 1;
1058 req.info.info1 = *info3;
1060 ndr_err = ndr_push_struct_blob(
1061 &req_blob, talloc_tos(), NULL, &req,
1062 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
1064 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1065 DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n",
1066 ndr_errstr(ndr_err)));
1067 goto fail;
1070 DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length));
1071 dump_data(10, req_blob.data, req_blob.length);
1073 written = write_data(result->fd, (char *)req_blob.data,
1074 req_blob.length);
1075 if (written == -1) {
1076 DEBUG(3, ("Could not write auth req data to RPC server\n"));
1077 goto fail;
1080 status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf));
1081 if (!NT_STATUS_IS_OK(status)) {
1082 DEBUG(3, ("Could not read auth result\n"));
1083 goto fail;
1086 rep_blob = data_blob_const(rep_buf, sizeof(rep_buf));
1088 DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length));
1089 dump_data(10, rep_blob.data, rep_blob.length);
1091 ndr_err = ndr_pull_struct_blob(
1092 &rep_blob, talloc_tos(), NULL, &rep,
1093 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
1095 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1096 DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
1097 ndr_errstr(ndr_err)));
1098 goto fail;
1101 if (rep.length != 16) {
1102 DEBUG(0, ("req invalid length: %u != 16\n",
1103 rep.length));
1104 goto fail;
1107 if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) {
1108 DEBUG(0, ("req invalid magic: %s != %s\n",
1109 rep.magic, NAMED_PIPE_AUTH_MAGIC));
1110 goto fail;
1113 if (!NT_STATUS_IS_OK(rep.status)) {
1114 DEBUG(0, ("req failed: %s\n",
1115 nt_errstr(rep.status)));
1116 goto fail;
1119 if (rep.level != 1) {
1120 DEBUG(0, ("req invalid level: %u != 1\n",
1121 rep.level));
1122 goto fail;
1125 result->msg = NULL;
1127 result->read_queue = tevent_queue_create(result, "np_read");
1128 if (result->read_queue == NULL) {
1129 goto fail;
1131 result->write_queue = tevent_queue_create(result, "np_write");
1132 if (result->write_queue == NULL) {
1133 goto fail;
1136 return result;
1138 fail:
1139 TALLOC_FREE(result);
1140 return NULL;
1143 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1144 const char *client_address,
1145 struct auth_serversupplied_info *server_info,
1146 struct fake_file_handle **phandle)
1148 const char **proxy_list;
1149 struct fake_file_handle *handle;
1151 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1153 handle = talloc(mem_ctx, struct fake_file_handle);
1154 if (handle == NULL) {
1155 return NT_STATUS_NO_MEMORY;
1158 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1159 struct np_proxy_state *p;
1161 p = make_external_rpc_pipe_p(handle, name, server_info);
1163 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1164 handle->private_data = p;
1165 } else {
1166 struct pipes_struct *p;
1167 struct ndr_syntax_id syntax;
1169 if (!is_known_pipename(name, &syntax)) {
1170 TALLOC_FREE(handle);
1171 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1174 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1175 server_info);
1177 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1178 handle->private_data = p;
1181 if (handle->private_data == NULL) {
1182 TALLOC_FREE(handle);
1183 return NT_STATUS_PIPE_NOT_AVAILABLE;
1186 *phandle = handle;
1188 return NT_STATUS_OK;
1191 struct np_write_state {
1192 struct event_context *ev;
1193 struct np_proxy_state *p;
1194 struct iovec iov;
1195 ssize_t nwritten;
1198 static void np_write_done(struct tevent_req *subreq);
1200 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1201 struct fake_file_handle *handle,
1202 const uint8_t *data, size_t len)
1204 struct tevent_req *req;
1205 struct np_write_state *state;
1206 NTSTATUS status;
1208 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1209 dump_data(50, data, len);
1211 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1212 if (req == NULL) {
1213 return NULL;
1216 if (len == 0) {
1217 state->nwritten = 0;
1218 status = NT_STATUS_OK;
1219 goto post_status;
1222 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1223 struct pipes_struct *p = talloc_get_type_abort(
1224 handle->private_data, struct pipes_struct);
1226 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1228 status = (state->nwritten >= 0)
1229 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1230 goto post_status;
1233 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1234 struct np_proxy_state *p = talloc_get_type_abort(
1235 handle->private_data, struct np_proxy_state);
1236 struct tevent_req *subreq;
1238 state->ev = ev;
1239 state->p = p;
1240 state->iov.iov_base = CONST_DISCARD(void *, data);
1241 state->iov.iov_len = len;
1243 subreq = writev_send(state, ev, p->write_queue, p->fd,
1244 false, &state->iov, 1);
1245 if (subreq == NULL) {
1246 goto fail;
1248 tevent_req_set_callback(subreq, np_write_done, req);
1249 return req;
1252 status = NT_STATUS_INVALID_HANDLE;
1253 post_status:
1254 if (NT_STATUS_IS_OK(status)) {
1255 tevent_req_done(req);
1256 } else {
1257 tevent_req_nterror(req, status);
1259 return tevent_req_post(req, ev);
1260 fail:
1261 TALLOC_FREE(req);
1262 return NULL;
1265 static void np_write_done(struct tevent_req *subreq)
1267 struct tevent_req *req = tevent_req_callback_data(
1268 subreq, struct tevent_req);
1269 struct np_write_state *state = tevent_req_data(
1270 req, struct np_write_state);
1271 ssize_t received;
1272 int err;
1274 received = writev_recv(subreq, &err);
1275 if (received < 0) {
1276 tevent_req_nterror(req, map_nt_error_from_unix(err));
1277 return;
1279 state->nwritten = received;
1280 tevent_req_done(req);
1283 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1285 struct np_write_state *state = tevent_req_data(
1286 req, struct np_write_state);
1287 NTSTATUS status;
1289 if (tevent_req_is_nterror(req, &status)) {
1290 return status;
1292 *pnwritten = state->nwritten;
1293 return NT_STATUS_OK;
1296 static ssize_t rpc_frag_more_fn(uint8_t *buf, size_t buflen, void *priv)
1298 prs_struct hdr_prs;
1299 struct rpc_hdr_info hdr;
1300 bool ret;
1302 if (buflen > RPC_HEADER_LEN) {
1303 return 0;
1305 prs_init_empty(&hdr_prs, talloc_tos(), UNMARSHALL);
1306 prs_give_memory(&hdr_prs, (char *)buf, RPC_HEADER_LEN, false);
1307 ret = smb_io_rpc_hdr("", &hdr, &hdr_prs, 0);
1308 prs_mem_free(&hdr_prs);
1310 if (!ret) {
1311 return -1;
1314 return (hdr.frag_len - RPC_HEADER_LEN);
1317 struct np_read_state {
1318 struct event_context *ev;
1319 struct np_proxy_state *p;
1320 uint8_t *data;
1321 size_t len;
1323 size_t nread;
1324 bool is_data_outstanding;
1327 static void np_read_trigger(struct tevent_req *req, void *private_data);
1328 static void np_read_done(struct tevent_req *subreq);
1330 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1331 struct fake_file_handle *handle,
1332 uint8_t *data, size_t len)
1334 struct tevent_req *req;
1335 struct np_read_state *state;
1336 NTSTATUS status;
1338 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1339 if (req == NULL) {
1340 return NULL;
1343 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1344 struct pipes_struct *p = talloc_get_type_abort(
1345 handle->private_data, struct pipes_struct);
1347 state->nread = read_from_internal_pipe(
1348 p, (char *)data, len, &state->is_data_outstanding);
1350 status = (state->nread >= 0)
1351 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1352 goto post_status;
1355 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1356 struct np_proxy_state *p = talloc_get_type_abort(
1357 handle->private_data, struct np_proxy_state);
1359 if (p->msg != NULL) {
1360 size_t thistime;
1362 thistime = MIN(talloc_get_size(p->msg) - p->sent,
1363 len);
1365 memcpy(data, p->msg+p->sent, thistime);
1366 state->nread = thistime;
1367 p->sent += thistime;
1369 if (p->sent < talloc_get_size(p->msg)) {
1370 state->is_data_outstanding = true;
1371 } else {
1372 state->is_data_outstanding = false;
1373 TALLOC_FREE(p->msg);
1375 status = NT_STATUS_OK;
1376 goto post_status;
1379 state->ev = ev;
1380 state->p = p;
1381 state->data = data;
1382 state->len = len;
1384 if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
1385 NULL)) {
1386 goto fail;
1388 return req;
1391 status = NT_STATUS_INVALID_HANDLE;
1392 post_status:
1393 if (NT_STATUS_IS_OK(status)) {
1394 tevent_req_done(req);
1395 } else {
1396 tevent_req_nterror(req, status);
1398 return tevent_req_post(req, ev);
1399 fail:
1400 TALLOC_FREE(req);
1401 return NULL;
1404 static void np_read_trigger(struct tevent_req *req, void *private_data)
1406 struct np_read_state *state = tevent_req_data(
1407 req, struct np_read_state);
1408 struct tevent_req *subreq;
1410 subreq = read_packet_send(state, state->ev, state->p->fd,
1411 RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
1412 if (tevent_req_nomem(subreq, req)) {
1413 return;
1415 tevent_req_set_callback(subreq, np_read_done, req);
1418 static void np_read_done(struct tevent_req *subreq)
1420 struct tevent_req *req = tevent_req_callback_data(
1421 subreq, struct tevent_req);
1422 struct np_read_state *state = tevent_req_data(
1423 req, struct np_read_state);
1424 ssize_t received;
1425 size_t thistime;
1426 int err;
1428 received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
1429 TALLOC_FREE(subreq);
1430 if (received == -1) {
1431 tevent_req_nterror(req, map_nt_error_from_unix(err));
1432 return;
1435 thistime = MIN(received, state->len);
1437 memcpy(state->data, state->p->msg, thistime);
1438 state->p->sent = thistime;
1439 state->nread = thistime;
1441 if (state->p->sent < received) {
1442 state->is_data_outstanding = true;
1443 } else {
1444 TALLOC_FREE(state->p->msg);
1445 state->is_data_outstanding = false;
1448 tevent_req_done(req);
1449 return;
1452 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1453 bool *is_data_outstanding)
1455 struct np_read_state *state = tevent_req_data(
1456 req, struct np_read_state);
1457 NTSTATUS status;
1459 if (tevent_req_is_nterror(req, &status)) {
1460 return status;
1462 *nread = state->nread;
1463 *is_data_outstanding = state->is_data_outstanding;
1464 return NT_STATUS_OK;
1468 * Create a new RPC client context which uses a local dispatch function.
1470 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
1471 const struct ndr_syntax_id *abstract_syntax,
1472 NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
1473 TALLOC_CTX *mem_ctx,
1474 const struct ndr_interface_table *table,
1475 uint32_t opnum, void *r),
1476 struct auth_serversupplied_info *serversupplied_info,
1477 struct rpc_pipe_client **presult)
1479 struct rpc_pipe_client *result;
1481 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
1482 if (result == NULL) {
1483 return NT_STATUS_NO_MEMORY;
1486 result->abstract_syntax = *abstract_syntax;
1487 result->transfer_syntax = ndr_transfer_syntax;
1488 result->dispatch = dispatch;
1490 result->pipes_struct = make_internal_rpc_pipe_p(
1491 result, abstract_syntax, "", serversupplied_info);
1492 if (result->pipes_struct == NULL) {
1493 TALLOC_FREE(result);
1494 return NT_STATUS_NO_MEMORY;
1497 result->max_xmit_frag = -1;
1498 result->max_recv_frag = -1;
1500 *presult = result;
1501 return NT_STATUS_OK;
1504 /*******************************************************************
1505 gets a domain user's groups from their already-calculated NT_USER_TOKEN
1506 ********************************************************************/
1508 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
1509 const DOM_SID *domain_sid,
1510 size_t num_sids,
1511 const DOM_SID *sids,
1512 int *numgroups,
1513 struct samr_RidWithAttribute **pgids)
1515 int i;
1517 *numgroups=0;
1518 *pgids = NULL;
1520 for (i=0; i<num_sids; i++) {
1521 struct samr_RidWithAttribute gid;
1522 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
1523 continue;
1525 gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
1526 SE_GROUP_ENABLED);
1527 ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
1528 gid, pgids, numgroups);
1529 if (*pgids == NULL) {
1530 return NT_STATUS_NO_MEMORY;
1533 return NT_STATUS_OK;
1536 /****************************************************************************
1537 inits a netr_SamBaseInfo structure from an auth_serversupplied_info.
1538 *****************************************************************************/
1540 static NTSTATUS serverinfo_to_SamInfo_base(TALLOC_CTX *mem_ctx,
1541 struct auth_serversupplied_info *server_info,
1542 uint8_t *pipe_session_key,
1543 size_t pipe_session_key_len,
1544 struct netr_SamBaseInfo *base)
1546 struct samu *sampw;
1547 struct samr_RidWithAttribute *gids = NULL;
1548 const DOM_SID *user_sid = NULL;
1549 const DOM_SID *group_sid = NULL;
1550 DOM_SID domain_sid;
1551 uint32 user_rid, group_rid;
1552 NTSTATUS status;
1554 int num_gids = 0;
1555 const char *my_name;
1557 struct netr_UserSessionKey user_session_key;
1558 struct netr_LMSessionKey lm_session_key;
1560 NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
1561 NTTIME allow_password_change, force_password_change;
1562 struct samr_RidWithAttributeArray groups;
1563 int i;
1564 struct dom_sid2 *sid = NULL;
1566 ZERO_STRUCT(user_session_key);
1567 ZERO_STRUCT(lm_session_key);
1569 sampw = server_info->sam_account;
1571 user_sid = pdb_get_user_sid(sampw);
1572 group_sid = pdb_get_group_sid(sampw);
1574 if (pipe_session_key && pipe_session_key_len != 16) {
1575 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
1576 "pipe_session_key_len[%zu] != 16\n",
1577 pipe_session_key_len));
1578 return NT_STATUS_INTERNAL_ERROR;
1581 if ((user_sid == NULL) || (group_sid == NULL)) {
1582 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
1583 return NT_STATUS_UNSUCCESSFUL;
1586 sid_copy(&domain_sid, user_sid);
1587 sid_split_rid(&domain_sid, &user_rid);
1589 sid = sid_dup_talloc(mem_ctx, &domain_sid);
1590 if (!sid) {
1591 return NT_STATUS_NO_MEMORY;
1594 if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
1595 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
1596 "%s\n but group sid %s.\n"
1597 "The conflicting domain portions are not "
1598 "supported for NETLOGON calls\n",
1599 pdb_get_domain(sampw),
1600 pdb_get_username(sampw),
1601 sid_string_dbg(user_sid),
1602 sid_string_dbg(group_sid)));
1603 return NT_STATUS_UNSUCCESSFUL;
1606 if(server_info->login_server) {
1607 my_name = server_info->login_server;
1608 } else {
1609 my_name = global_myname();
1612 status = nt_token_to_group_list(mem_ctx, &domain_sid,
1613 server_info->num_sids,
1614 server_info->sids,
1615 &num_gids, &gids);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 return status;
1621 if (server_info->user_session_key.length) {
1622 memcpy(user_session_key.key,
1623 server_info->user_session_key.data,
1624 MIN(sizeof(user_session_key.key),
1625 server_info->user_session_key.length));
1626 if (pipe_session_key) {
1627 arcfour_crypt(user_session_key.key, pipe_session_key, 16);
1630 if (server_info->lm_session_key.length) {
1631 memcpy(lm_session_key.key,
1632 server_info->lm_session_key.data,
1633 MIN(sizeof(lm_session_key.key),
1634 server_info->lm_session_key.length));
1635 if (pipe_session_key) {
1636 arcfour_crypt(lm_session_key.key, pipe_session_key, 8);
1640 groups.count = num_gids;
1641 groups.rids = TALLOC_ARRAY(mem_ctx, struct samr_RidWithAttribute, groups.count);
1642 if (!groups.rids) {
1643 return NT_STATUS_NO_MEMORY;
1646 for (i=0; i < groups.count; i++) {
1647 groups.rids[i].rid = gids[i].rid;
1648 groups.rids[i].attributes = gids[i].attributes;
1651 unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
1652 unix_to_nt_time(&last_logoff, get_time_t_max());
1653 unix_to_nt_time(&acct_expiry, get_time_t_max());
1654 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
1655 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
1656 unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
1658 base->last_logon = last_logon;
1659 base->last_logoff = last_logoff;
1660 base->acct_expiry = acct_expiry;
1661 base->last_password_change = last_password_change;
1662 base->allow_password_change = allow_password_change;
1663 base->force_password_change = force_password_change;
1664 base->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(sampw));
1665 base->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(sampw));
1666 base->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(sampw));
1667 base->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(sampw));
1668 base->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(sampw));
1669 base->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(sampw));
1670 base->logon_count = 0; /* ?? */
1671 base->bad_password_count = 0; /* ?? */
1672 base->rid = user_rid;
1673 base->primary_gid = group_rid;
1674 base->groups = groups;
1675 base->user_flags = NETLOGON_EXTRA_SIDS;
1676 base->key = user_session_key;
1677 base->logon_server.string = talloc_strdup(mem_ctx, my_name);
1678 base->domain.string = talloc_strdup(mem_ctx, pdb_get_domain(sampw));
1679 base->domain_sid = sid;
1680 base->LMSessKey = lm_session_key;
1681 base->acct_flags = pdb_get_acct_ctrl(sampw);
1683 ZERO_STRUCT(user_session_key);
1684 ZERO_STRUCT(lm_session_key);
1686 return NT_STATUS_OK;
1689 /****************************************************************************
1690 inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
1691 already be initialized and is used as the talloc parent for its members.
1692 *****************************************************************************/
1694 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
1695 uint8_t *pipe_session_key,
1696 size_t pipe_session_key_len,
1697 struct netr_SamInfo2 *sam2)
1699 NTSTATUS status;
1701 status = serverinfo_to_SamInfo_base(sam2,
1702 server_info,
1703 pipe_session_key,
1704 pipe_session_key_len,
1705 &sam2->base);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 return status;
1710 return NT_STATUS_OK;
1713 /****************************************************************************
1714 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
1715 already be initialized and is used as the talloc parent for its members.
1716 *****************************************************************************/
1718 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
1719 uint8_t *pipe_session_key,
1720 size_t pipe_session_key_len,
1721 struct netr_SamInfo3 *sam3)
1723 NTSTATUS status;
1725 status = serverinfo_to_SamInfo_base(sam3,
1726 server_info,
1727 pipe_session_key,
1728 pipe_session_key_len,
1729 &sam3->base);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 sam3->sidcount = 0;
1735 sam3->sids = NULL;
1737 return NT_STATUS_OK;
1740 /****************************************************************************
1741 inits a netr_SamInfo6 structure from an auth_serversupplied_info. sam6 must
1742 already be initialized and is used as the talloc parent for its members.
1743 *****************************************************************************/
1745 NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
1746 uint8_t *pipe_session_key,
1747 size_t pipe_session_key_len,
1748 struct netr_SamInfo6 *sam6)
1750 NTSTATUS status;
1751 struct pdb_domain_info *dominfo;
1753 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1754 DEBUG(10,("Not adding validation info level 6 "
1755 "without ADS passdb backend\n"));
1756 return NT_STATUS_INVALID_INFO_CLASS;
1759 dominfo = pdb_get_domain_info(sam6);
1760 if (dominfo == NULL) {
1761 return NT_STATUS_NO_MEMORY;
1764 status = serverinfo_to_SamInfo_base(sam6,
1765 server_info,
1766 pipe_session_key,
1767 pipe_session_key_len,
1768 &sam6->base);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 return status;
1773 sam6->sidcount = 0;
1774 sam6->sids = NULL;
1776 sam6->forest.string = talloc_strdup(sam6, dominfo->dns_forest);
1777 if (sam6->forest.string == NULL) {
1778 return NT_STATUS_NO_MEMORY;
1781 sam6->principle.string = talloc_asprintf(sam6, "%s@%s",
1782 pdb_get_username(server_info->sam_account),
1783 dominfo->dns_domain);
1784 if (sam6->principle.string == NULL) {
1785 return NT_STATUS_NO_MEMORY;
1788 return NT_STATUS_OK;