Revert "s3: Consolidate getting the name out of a pipes_struct"
[Samba/bb.git] / source3 / rpc_server / srv_pipe_hnd.c
blob254241c74368a24816d3fd02905a82906c7b88ae
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 return data_returned;
909 /****************************************************************************
910 Close an rpc pipe.
911 ****************************************************************************/
913 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
915 if (!p) {
916 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
917 return False;
920 prs_mem_free(&p->out_data.frag);
921 prs_mem_free(&p->out_data.rdata);
922 prs_mem_free(&p->in_data.data);
924 if (p->auth.auth_data_free_func) {
925 (*p->auth.auth_data_free_func)(&p->auth);
928 TALLOC_FREE(p->mem_ctx);
930 free_pipe_rpc_context( p->contexts );
932 /* Free the handles database. */
933 close_policy_by_pipe(p);
935 DLIST_REMOVE(InternalPipes, p);
937 ZERO_STRUCTP(p);
939 TALLOC_FREE(p);
941 return True;
944 bool fsp_is_np(struct files_struct *fsp)
946 enum FAKE_FILE_TYPE type;
948 if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
949 return false;
952 type = fsp->fake_file_handle->type;
954 return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
955 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
958 struct np_proxy_state {
959 struct tevent_queue *read_queue;
960 struct tevent_queue *write_queue;
961 int fd;
963 uint8_t *msg;
964 size_t sent;
967 static int np_proxy_state_destructor(struct np_proxy_state *state)
969 if (state->fd != -1) {
970 close(state->fd);
972 return 0;
975 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
976 const char *pipe_name,
977 struct auth_serversupplied_info *server_info)
979 struct np_proxy_state *result;
980 struct sockaddr_un addr;
981 char *socket_path;
982 const char *socket_dir;
984 DATA_BLOB req_blob;
985 struct netr_SamInfo3 *info3;
986 struct named_pipe_auth_req req;
987 DATA_BLOB rep_blob;
988 uint8 rep_buf[20];
989 struct named_pipe_auth_rep rep;
990 enum ndr_err_code ndr_err;
991 NTSTATUS status;
992 ssize_t written;
994 result = talloc(mem_ctx, struct np_proxy_state);
995 if (result == NULL) {
996 DEBUG(0, ("talloc failed\n"));
997 return NULL;
1000 result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
1001 if (result->fd == -1) {
1002 DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
1003 goto fail;
1005 talloc_set_destructor(result, np_proxy_state_destructor);
1007 ZERO_STRUCT(addr);
1008 addr.sun_family = AF_UNIX;
1010 socket_dir = lp_parm_const_string(
1011 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
1012 get_dyn_NCALRPCDIR());
1013 if (socket_dir == NULL) {
1014 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
1015 goto fail;
1018 socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s",
1019 socket_dir, pipe_name);
1020 if (socket_path == NULL) {
1021 DEBUG(0, ("talloc_asprintf failed\n"));
1022 goto fail;
1024 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
1025 TALLOC_FREE(socket_path);
1027 become_root();
1028 if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
1029 unbecome_root();
1030 DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
1031 strerror(errno)));
1032 goto fail;
1034 unbecome_root();
1036 info3 = talloc(talloc_tos(), struct netr_SamInfo3);
1037 if (info3 == NULL) {
1038 DEBUG(0, ("talloc failed\n"));
1039 goto fail;
1042 status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 TALLOC_FREE(info3);
1045 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
1046 nt_errstr(status)));
1047 goto fail;
1050 req.level = 1;
1051 req.info.info1 = *info3;
1053 ndr_err = ndr_push_struct_blob(
1054 &req_blob, talloc_tos(), NULL, &req,
1055 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
1057 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1058 DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n",
1059 ndr_errstr(ndr_err)));
1060 goto fail;
1063 DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length));
1064 dump_data(10, req_blob.data, req_blob.length);
1066 written = write_data(result->fd, (char *)req_blob.data,
1067 req_blob.length);
1068 if (written == -1) {
1069 DEBUG(3, ("Could not write auth req data to RPC server\n"));
1070 goto fail;
1073 status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf));
1074 if (!NT_STATUS_IS_OK(status)) {
1075 DEBUG(3, ("Could not read auth result\n"));
1076 goto fail;
1079 rep_blob = data_blob_const(rep_buf, sizeof(rep_buf));
1081 DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length));
1082 dump_data(10, rep_blob.data, rep_blob.length);
1084 ndr_err = ndr_pull_struct_blob(
1085 &rep_blob, talloc_tos(), NULL, &rep,
1086 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
1088 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1089 DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
1090 ndr_errstr(ndr_err)));
1091 goto fail;
1094 if (rep.length != 16) {
1095 DEBUG(0, ("req invalid length: %u != 16\n",
1096 rep.length));
1097 goto fail;
1100 if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) {
1101 DEBUG(0, ("req invalid magic: %s != %s\n",
1102 rep.magic, NAMED_PIPE_AUTH_MAGIC));
1103 goto fail;
1106 if (!NT_STATUS_IS_OK(rep.status)) {
1107 DEBUG(0, ("req failed: %s\n",
1108 nt_errstr(rep.status)));
1109 goto fail;
1112 if (rep.level != 1) {
1113 DEBUG(0, ("req invalid level: %u != 1\n",
1114 rep.level));
1115 goto fail;
1118 result->msg = NULL;
1120 result->read_queue = tevent_queue_create(result, "np_read");
1121 if (result->read_queue == NULL) {
1122 goto fail;
1124 result->write_queue = tevent_queue_create(result, "np_write");
1125 if (result->write_queue == NULL) {
1126 goto fail;
1129 return result;
1131 fail:
1132 TALLOC_FREE(result);
1133 return NULL;
1136 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1137 const char *client_address,
1138 struct auth_serversupplied_info *server_info,
1139 struct fake_file_handle **phandle)
1141 const char **proxy_list;
1142 struct fake_file_handle *handle;
1144 proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1146 handle = talloc(mem_ctx, struct fake_file_handle);
1147 if (handle == NULL) {
1148 return NT_STATUS_NO_MEMORY;
1151 if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1152 struct np_proxy_state *p;
1154 p = make_external_rpc_pipe_p(handle, name, server_info);
1156 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1157 handle->private_data = p;
1158 } else {
1159 struct pipes_struct *p;
1160 struct ndr_syntax_id syntax;
1162 if (!is_known_pipename(name, &syntax)) {
1163 TALLOC_FREE(handle);
1164 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1167 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1168 server_info);
1170 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1171 handle->private_data = p;
1174 if (handle->private_data == NULL) {
1175 TALLOC_FREE(handle);
1176 return NT_STATUS_PIPE_NOT_AVAILABLE;
1179 *phandle = handle;
1181 return NT_STATUS_OK;
1184 struct np_write_state {
1185 struct event_context *ev;
1186 struct np_proxy_state *p;
1187 struct iovec iov;
1188 ssize_t nwritten;
1191 static void np_write_done(struct tevent_req *subreq);
1193 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1194 struct fake_file_handle *handle,
1195 const uint8_t *data, size_t len)
1197 struct tevent_req *req;
1198 struct np_write_state *state;
1199 NTSTATUS status;
1201 DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1202 dump_data(50, data, len);
1204 req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1205 if (req == NULL) {
1206 return NULL;
1209 if (len == 0) {
1210 state->nwritten = 0;
1211 status = NT_STATUS_OK;
1212 goto post_status;
1215 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1216 struct pipes_struct *p = talloc_get_type_abort(
1217 handle->private_data, struct pipes_struct);
1219 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1221 status = (state->nwritten >= 0)
1222 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1223 goto post_status;
1226 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1227 struct np_proxy_state *p = talloc_get_type_abort(
1228 handle->private_data, struct np_proxy_state);
1229 struct tevent_req *subreq;
1231 state->ev = ev;
1232 state->p = p;
1233 state->iov.iov_base = CONST_DISCARD(void *, data);
1234 state->iov.iov_len = len;
1236 subreq = writev_send(state, ev, p->write_queue, p->fd,
1237 false, &state->iov, 1);
1238 if (subreq == NULL) {
1239 goto fail;
1241 tevent_req_set_callback(subreq, np_write_done, req);
1242 return req;
1245 status = NT_STATUS_INVALID_HANDLE;
1246 post_status:
1247 if (NT_STATUS_IS_OK(status)) {
1248 tevent_req_done(req);
1249 } else {
1250 tevent_req_nterror(req, status);
1252 return tevent_req_post(req, ev);
1253 fail:
1254 TALLOC_FREE(req);
1255 return NULL;
1258 static void np_write_done(struct tevent_req *subreq)
1260 struct tevent_req *req = tevent_req_callback_data(
1261 subreq, struct tevent_req);
1262 struct np_write_state *state = tevent_req_data(
1263 req, struct np_write_state);
1264 ssize_t received;
1265 int err;
1267 received = writev_recv(subreq, &err);
1268 if (received < 0) {
1269 tevent_req_nterror(req, map_nt_error_from_unix(err));
1270 return;
1272 state->nwritten = received;
1273 tevent_req_done(req);
1276 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1278 struct np_write_state *state = tevent_req_data(
1279 req, struct np_write_state);
1280 NTSTATUS status;
1282 if (tevent_req_is_nterror(req, &status)) {
1283 return status;
1285 *pnwritten = state->nwritten;
1286 return NT_STATUS_OK;
1289 static ssize_t rpc_frag_more_fn(uint8_t *buf, size_t buflen, void *priv)
1291 prs_struct hdr_prs;
1292 struct rpc_hdr_info hdr;
1293 bool ret;
1295 if (buflen > RPC_HEADER_LEN) {
1296 return 0;
1298 prs_init_empty(&hdr_prs, talloc_tos(), UNMARSHALL);
1299 prs_give_memory(&hdr_prs, (char *)buf, RPC_HEADER_LEN, false);
1300 ret = smb_io_rpc_hdr("", &hdr, &hdr_prs, 0);
1301 prs_mem_free(&hdr_prs);
1303 if (!ret) {
1304 return -1;
1307 return (hdr.frag_len - RPC_HEADER_LEN);
1310 struct np_read_state {
1311 struct event_context *ev;
1312 struct np_proxy_state *p;
1313 uint8_t *data;
1314 size_t len;
1316 size_t nread;
1317 bool is_data_outstanding;
1320 static void np_read_trigger(struct tevent_req *req, void *private_data);
1321 static void np_read_done(struct tevent_req *subreq);
1323 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1324 struct fake_file_handle *handle,
1325 uint8_t *data, size_t len)
1327 struct tevent_req *req;
1328 struct np_read_state *state;
1329 NTSTATUS status;
1331 req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1332 if (req == NULL) {
1333 return NULL;
1336 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1337 struct pipes_struct *p = talloc_get_type_abort(
1338 handle->private_data, struct pipes_struct);
1340 state->nread = read_from_internal_pipe(
1341 p, (char *)data, len, &state->is_data_outstanding);
1343 status = (state->nread >= 0)
1344 ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1345 goto post_status;
1348 if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1349 struct np_proxy_state *p = talloc_get_type_abort(
1350 handle->private_data, struct np_proxy_state);
1352 if (p->msg != NULL) {
1353 size_t thistime;
1355 thistime = MIN(talloc_get_size(p->msg) - p->sent,
1356 len);
1358 memcpy(data, p->msg+p->sent, thistime);
1359 state->nread = thistime;
1360 p->sent += thistime;
1362 if (p->sent < talloc_get_size(p->msg)) {
1363 state->is_data_outstanding = true;
1364 } else {
1365 state->is_data_outstanding = false;
1366 TALLOC_FREE(p->msg);
1368 status = NT_STATUS_OK;
1369 goto post_status;
1372 state->ev = ev;
1373 state->p = p;
1374 state->data = data;
1375 state->len = len;
1377 if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
1378 NULL)) {
1379 goto fail;
1381 return req;
1384 status = NT_STATUS_INVALID_HANDLE;
1385 post_status:
1386 if (NT_STATUS_IS_OK(status)) {
1387 tevent_req_done(req);
1388 } else {
1389 tevent_req_nterror(req, status);
1391 return tevent_req_post(req, ev);
1392 fail:
1393 TALLOC_FREE(req);
1394 return NULL;
1397 static void np_read_trigger(struct tevent_req *req, void *private_data)
1399 struct np_read_state *state = tevent_req_data(
1400 req, struct np_read_state);
1401 struct tevent_req *subreq;
1403 subreq = read_packet_send(state, state->ev, state->p->fd,
1404 RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
1405 if (tevent_req_nomem(subreq, req)) {
1406 return;
1408 tevent_req_set_callback(subreq, np_read_done, req);
1411 static void np_read_done(struct tevent_req *subreq)
1413 struct tevent_req *req = tevent_req_callback_data(
1414 subreq, struct tevent_req);
1415 struct np_read_state *state = tevent_req_data(
1416 req, struct np_read_state);
1417 ssize_t received;
1418 size_t thistime;
1419 int err;
1421 received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
1422 TALLOC_FREE(subreq);
1423 if (received == -1) {
1424 tevent_req_nterror(req, map_nt_error_from_unix(err));
1425 return;
1428 thistime = MIN(received, state->len);
1430 memcpy(state->data, state->p->msg, thistime);
1431 state->p->sent = thistime;
1432 state->nread = thistime;
1434 if (state->p->sent < received) {
1435 state->is_data_outstanding = true;
1436 } else {
1437 TALLOC_FREE(state->p->msg);
1438 state->is_data_outstanding = false;
1441 tevent_req_done(req);
1442 return;
1445 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1446 bool *is_data_outstanding)
1448 struct np_read_state *state = tevent_req_data(
1449 req, struct np_read_state);
1450 NTSTATUS status;
1452 if (tevent_req_is_nterror(req, &status)) {
1453 return status;
1455 *nread = state->nread;
1456 *is_data_outstanding = state->is_data_outstanding;
1457 return NT_STATUS_OK;
1461 * Create a new RPC client context which uses a local dispatch function.
1463 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
1464 const struct ndr_syntax_id *abstract_syntax,
1465 NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
1466 TALLOC_CTX *mem_ctx,
1467 const char *interface,
1468 uint32_t interface_version,
1469 uint32_t opnum, void *r),
1470 struct auth_serversupplied_info *serversupplied_info,
1471 struct rpc_pipe_client **presult)
1473 struct rpc_pipe_client *result;
1475 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
1476 if (result == NULL) {
1477 return NT_STATUS_NO_MEMORY;
1480 result->abstract_syntax = *abstract_syntax;
1481 result->transfer_syntax = ndr_transfer_syntax;
1482 result->dispatch = dispatch;
1484 result->pipes_struct = make_internal_rpc_pipe_p(
1485 result, abstract_syntax, "", serversupplied_info);
1486 if (result->pipes_struct == NULL) {
1487 TALLOC_FREE(result);
1488 return NT_STATUS_NO_MEMORY;
1491 result->max_xmit_frag = -1;
1492 result->max_recv_frag = -1;
1494 *presult = result;
1495 return NT_STATUS_OK;
1498 /*******************************************************************
1499 gets a domain user's groups from their already-calculated NT_USER_TOKEN
1500 ********************************************************************/
1502 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
1503 const DOM_SID *domain_sid,
1504 size_t num_sids,
1505 const DOM_SID *sids,
1506 int *numgroups,
1507 struct samr_RidWithAttribute **pgids)
1509 int i;
1511 *numgroups=0;
1512 *pgids = NULL;
1514 for (i=0; i<num_sids; i++) {
1515 struct samr_RidWithAttribute gid;
1516 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
1517 continue;
1519 gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
1520 SE_GROUP_ENABLED);
1521 ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
1522 gid, pgids, numgroups);
1523 if (*pgids == NULL) {
1524 return NT_STATUS_NO_MEMORY;
1527 return NT_STATUS_OK;
1530 /****************************************************************************
1531 inits a netr_SamBaseInfo structure from an auth_serversupplied_info.
1532 *****************************************************************************/
1534 static NTSTATUS serverinfo_to_SamInfo_base(TALLOC_CTX *mem_ctx,
1535 struct auth_serversupplied_info *server_info,
1536 uint8_t *pipe_session_key,
1537 size_t pipe_session_key_len,
1538 struct netr_SamBaseInfo *base)
1540 struct samu *sampw;
1541 struct samr_RidWithAttribute *gids = NULL;
1542 const DOM_SID *user_sid = NULL;
1543 const DOM_SID *group_sid = NULL;
1544 DOM_SID domain_sid;
1545 uint32 user_rid, group_rid;
1546 NTSTATUS status;
1548 int num_gids = 0;
1549 const char *my_name;
1551 struct netr_UserSessionKey user_session_key;
1552 struct netr_LMSessionKey lm_session_key;
1554 NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
1555 NTTIME allow_password_change, force_password_change;
1556 struct samr_RidWithAttributeArray groups;
1557 int i;
1558 struct dom_sid2 *sid = NULL;
1560 ZERO_STRUCT(user_session_key);
1561 ZERO_STRUCT(lm_session_key);
1563 sampw = server_info->sam_account;
1565 user_sid = pdb_get_user_sid(sampw);
1566 group_sid = pdb_get_group_sid(sampw);
1568 if (pipe_session_key && pipe_session_key_len != 16) {
1569 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
1570 "pipe_session_key_len[%zu] != 16\n",
1571 pipe_session_key_len));
1572 return NT_STATUS_INTERNAL_ERROR;
1575 if ((user_sid == NULL) || (group_sid == NULL)) {
1576 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
1577 return NT_STATUS_UNSUCCESSFUL;
1580 sid_copy(&domain_sid, user_sid);
1581 sid_split_rid(&domain_sid, &user_rid);
1583 sid = sid_dup_talloc(mem_ctx, &domain_sid);
1584 if (!sid) {
1585 return NT_STATUS_NO_MEMORY;
1588 if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
1589 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
1590 "%s\n but group sid %s.\n"
1591 "The conflicting domain portions are not "
1592 "supported for NETLOGON calls\n",
1593 pdb_get_domain(sampw),
1594 pdb_get_username(sampw),
1595 sid_string_dbg(user_sid),
1596 sid_string_dbg(group_sid)));
1597 return NT_STATUS_UNSUCCESSFUL;
1600 if(server_info->login_server) {
1601 my_name = server_info->login_server;
1602 } else {
1603 my_name = global_myname();
1606 status = nt_token_to_group_list(mem_ctx, &domain_sid,
1607 server_info->num_sids,
1608 server_info->sids,
1609 &num_gids, &gids);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 return status;
1615 if (server_info->user_session_key.length) {
1616 memcpy(user_session_key.key,
1617 server_info->user_session_key.data,
1618 MIN(sizeof(user_session_key.key),
1619 server_info->user_session_key.length));
1620 if (pipe_session_key) {
1621 arcfour_crypt(user_session_key.key, pipe_session_key, 16);
1624 if (server_info->lm_session_key.length) {
1625 memcpy(lm_session_key.key,
1626 server_info->lm_session_key.data,
1627 MIN(sizeof(lm_session_key.key),
1628 server_info->lm_session_key.length));
1629 if (pipe_session_key) {
1630 arcfour_crypt(lm_session_key.key, pipe_session_key, 8);
1634 groups.count = num_gids;
1635 groups.rids = TALLOC_ARRAY(mem_ctx, struct samr_RidWithAttribute, groups.count);
1636 if (!groups.rids) {
1637 return NT_STATUS_NO_MEMORY;
1640 for (i=0; i < groups.count; i++) {
1641 groups.rids[i].rid = gids[i].rid;
1642 groups.rids[i].attributes = gids[i].attributes;
1645 unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
1646 unix_to_nt_time(&last_logoff, get_time_t_max());
1647 unix_to_nt_time(&acct_expiry, get_time_t_max());
1648 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
1649 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
1650 unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
1652 base->last_logon = last_logon;
1653 base->last_logoff = last_logoff;
1654 base->acct_expiry = acct_expiry;
1655 base->last_password_change = last_password_change;
1656 base->allow_password_change = allow_password_change;
1657 base->force_password_change = force_password_change;
1658 base->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(sampw));
1659 base->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(sampw));
1660 base->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(sampw));
1661 base->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(sampw));
1662 base->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(sampw));
1663 base->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(sampw));
1664 base->logon_count = 0; /* ?? */
1665 base->bad_password_count = 0; /* ?? */
1666 base->rid = user_rid;
1667 base->primary_gid = group_rid;
1668 base->groups = groups;
1669 base->user_flags = NETLOGON_EXTRA_SIDS;
1670 base->key = user_session_key;
1671 base->logon_server.string = talloc_strdup(mem_ctx, my_name);
1672 base->domain.string = talloc_strdup(mem_ctx, pdb_get_domain(sampw));
1673 base->domain_sid = sid;
1674 base->LMSessKey = lm_session_key;
1675 base->acct_flags = pdb_get_acct_ctrl(sampw);
1677 ZERO_STRUCT(user_session_key);
1678 ZERO_STRUCT(lm_session_key);
1680 return NT_STATUS_OK;
1683 /****************************************************************************
1684 inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
1685 already be initialized and is used as the talloc parent for its members.
1686 *****************************************************************************/
1688 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
1689 uint8_t *pipe_session_key,
1690 size_t pipe_session_key_len,
1691 struct netr_SamInfo2 *sam2)
1693 NTSTATUS status;
1695 status = serverinfo_to_SamInfo_base(sam2,
1696 server_info,
1697 pipe_session_key,
1698 pipe_session_key_len,
1699 &sam2->base);
1700 if (!NT_STATUS_IS_OK(status)) {
1701 return status;
1704 return NT_STATUS_OK;
1707 /****************************************************************************
1708 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
1709 already be initialized and is used as the talloc parent for its members.
1710 *****************************************************************************/
1712 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
1713 uint8_t *pipe_session_key,
1714 size_t pipe_session_key_len,
1715 struct netr_SamInfo3 *sam3)
1717 NTSTATUS status;
1719 status = serverinfo_to_SamInfo_base(sam3,
1720 server_info,
1721 pipe_session_key,
1722 pipe_session_key_len,
1723 &sam3->base);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 return status;
1728 sam3->sidcount = 0;
1729 sam3->sids = NULL;
1731 return NT_STATUS_OK;
1734 /****************************************************************************
1735 inits a netr_SamInfo6 structure from an auth_serversupplied_info. sam6 must
1736 already be initialized and is used as the talloc parent for its members.
1737 *****************************************************************************/
1739 NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
1740 uint8_t *pipe_session_key,
1741 size_t pipe_session_key_len,
1742 struct netr_SamInfo6 *sam6)
1744 NTSTATUS status;
1745 struct pdb_domain_info *dominfo;
1747 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1748 DEBUG(10,("Not adding validation info level 6 "
1749 "without ADS passdb backend\n"));
1750 return NT_STATUS_INVALID_INFO_CLASS;
1753 dominfo = pdb_get_domain_info(sam6);
1754 if (dominfo == NULL) {
1755 return NT_STATUS_NO_MEMORY;
1758 status = serverinfo_to_SamInfo_base(sam6,
1759 server_info,
1760 pipe_session_key,
1761 pipe_session_key_len,
1762 &sam6->base);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 return status;
1767 sam6->sidcount = 0;
1768 sam6->sids = NULL;
1770 sam6->forest.string = talloc_strdup(sam6, dominfo->dns_forest);
1771 if (sam6->forest.string == NULL) {
1772 return NT_STATUS_NO_MEMORY;
1775 sam6->principle.string = talloc_asprintf(sam6, "%s@%s",
1776 pdb_get_username(server_info->sam_account),
1777 dominfo->dns_domain);
1778 if (sam6->principle.string == NULL) {
1779 return NT_STATUS_NO_MEMORY;
1782 return NT_STATUS_OK;