Ensure all callers to the rpc_client/cli_pipe functions correctly
[Samba/fernandojvsilva.git] / source3 / rpc_client / cli_pipe.c
blobda54fca85d3c2c7609e7b1b14813a4f416a5cc4b
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
26 #include "../libcli/auth/spnego.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_CLI
31 static const char *get_pipe_name_from_iface(
32 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
34 int i;
35 const struct ndr_interface_string_array *ep = interface->endpoints;
36 char *p;
38 for (i=0; i<ep->count; i++) {
39 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
40 break;
43 if (i == ep->count) {
44 return NULL;
48 * extract the pipe name without \\pipe from for example
49 * ncacn_np:[\\pipe\\epmapper]
51 p = strchr(ep->names[i]+15, ']');
52 if (p == NULL) {
53 return "PIPE";
55 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
58 static const struct ndr_interface_table **interfaces;
60 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
62 int num_interfaces = talloc_array_length(interfaces);
63 const struct ndr_interface_table **tmp;
64 int i;
66 for (i=0; i<num_interfaces; i++) {
67 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
68 &interface->syntax_id)) {
69 return true;
73 tmp = talloc_realloc(NULL, interfaces,
74 const struct ndr_interface_table *,
75 num_interfaces + 1);
76 if (tmp == NULL) {
77 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
78 return false;
80 interfaces = tmp;
81 interfaces[num_interfaces] = interface;
82 return true;
85 static bool initialize_interfaces(void)
87 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
88 return false;
90 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
91 return false;
93 if (!smb_register_ndr_interface(&ndr_table_samr)) {
94 return false;
96 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
97 return false;
99 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
100 return false;
102 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
103 return false;
105 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
106 return false;
108 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
109 return false;
111 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
112 return false;
114 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
115 return false;
117 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
118 return false;
120 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
121 return false;
123 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
124 return false;
126 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
127 return false;
129 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
130 return false;
132 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
133 return false;
135 return true;
138 const struct ndr_interface_table *get_iface_from_syntax(
139 const struct ndr_syntax_id *syntax)
141 int num_interfaces;
142 int i;
144 if (interfaces == NULL) {
145 if (!initialize_interfaces()) {
146 return NULL;
149 num_interfaces = talloc_array_length(interfaces);
151 for (i=0; i<num_interfaces; i++) {
152 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
153 return interfaces[i];
157 return NULL;
160 /****************************************************************************
161 Return the pipe name from the interface.
162 ****************************************************************************/
164 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
165 const struct ndr_syntax_id *syntax)
167 const struct ndr_interface_table *interface;
168 char *guid_str;
169 const char *result;
171 interface = get_iface_from_syntax(syntax);
172 if (interface != NULL) {
173 result = get_pipe_name_from_iface(mem_ctx, interface);
174 if (result != NULL) {
175 return result;
180 * Here we should ask \\epmapper, but for now our code is only
181 * interested in the known pipes mentioned in pipe_names[]
184 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
185 if (guid_str == NULL) {
186 return NULL;
188 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
189 (int)syntax->if_version);
190 TALLOC_FREE(guid_str);
192 if (result == NULL) {
193 return "PIPE";
195 return result;
198 /********************************************************************
199 Map internal value to wire value.
200 ********************************************************************/
202 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
204 switch (auth_type) {
206 case PIPE_AUTH_TYPE_NONE:
207 return DCERPC_AUTH_TYPE_NONE;
209 case PIPE_AUTH_TYPE_NTLMSSP:
210 return DCERPC_AUTH_TYPE_NTLMSSP;
212 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
213 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
214 return DCERPC_AUTH_TYPE_SPNEGO;
216 case PIPE_AUTH_TYPE_SCHANNEL:
217 return DCERPC_AUTH_TYPE_SCHANNEL;
219 case PIPE_AUTH_TYPE_KRB5:
220 return DCERPC_AUTH_TYPE_KRB5;
222 default:
223 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
224 "auth type %u\n",
225 (unsigned int)auth_type ));
226 break;
228 return -1;
231 /********************************************************************
232 Pipe description for a DEBUG
233 ********************************************************************/
234 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
235 struct rpc_pipe_client *cli)
237 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
238 if (result == NULL) {
239 return "pipe";
241 return result;
244 /********************************************************************
245 Rpc pipe call id.
246 ********************************************************************/
248 static uint32 get_rpc_call_id(void)
250 static uint32 call_id = 0;
251 return ++call_id;
255 * Realloc pdu to have a least "size" bytes
258 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
260 size_t extra_size;
262 if (prs_data_size(pdu) >= size) {
263 return true;
266 extra_size = size - prs_data_size(pdu);
268 if (!prs_force_grow(pdu, extra_size)) {
269 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
270 "%d bytes.\n", (int)extra_size));
271 return false;
274 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
275 (int)extra_size, prs_data_size(pdu)));
276 return true;
280 /*******************************************************************
281 Use SMBreadX to get rest of one fragment's worth of rpc data.
282 Reads the whole size or give an error message
283 ********************************************************************/
285 struct rpc_read_state {
286 struct event_context *ev;
287 struct rpc_cli_transport *transport;
288 uint8_t *data;
289 size_t size;
290 size_t num_read;
293 static void rpc_read_done(struct tevent_req *subreq);
295 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
296 struct event_context *ev,
297 struct rpc_cli_transport *transport,
298 uint8_t *data, size_t size)
300 struct tevent_req *req, *subreq;
301 struct rpc_read_state *state;
303 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
304 if (req == NULL) {
305 return NULL;
307 state->ev = ev;
308 state->transport = transport;
309 state->data = data;
310 state->size = size;
311 state->num_read = 0;
313 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
315 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
316 transport->priv);
317 if (subreq == NULL) {
318 goto fail;
320 tevent_req_set_callback(subreq, rpc_read_done, req);
321 return req;
323 fail:
324 TALLOC_FREE(req);
325 return NULL;
328 static void rpc_read_done(struct tevent_req *subreq)
330 struct tevent_req *req = tevent_req_callback_data(
331 subreq, struct tevent_req);
332 struct rpc_read_state *state = tevent_req_data(
333 req, struct rpc_read_state);
334 NTSTATUS status;
335 ssize_t received;
337 status = state->transport->read_recv(subreq, &received);
338 TALLOC_FREE(subreq);
339 if (!NT_STATUS_IS_OK(status)) {
340 tevent_req_nterror(req, status);
341 return;
344 state->num_read += received;
345 if (state->num_read == state->size) {
346 tevent_req_done(req);
347 return;
350 subreq = state->transport->read_send(state, state->ev,
351 state->data + state->num_read,
352 state->size - state->num_read,
353 state->transport->priv);
354 if (tevent_req_nomem(subreq, req)) {
355 return;
357 tevent_req_set_callback(subreq, rpc_read_done, req);
360 static NTSTATUS rpc_read_recv(struct tevent_req *req)
362 return tevent_req_simple_recv_ntstatus(req);
365 struct rpc_write_state {
366 struct event_context *ev;
367 struct rpc_cli_transport *transport;
368 const uint8_t *data;
369 size_t size;
370 size_t num_written;
373 static void rpc_write_done(struct tevent_req *subreq);
375 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
376 struct event_context *ev,
377 struct rpc_cli_transport *transport,
378 const uint8_t *data, size_t size)
380 struct tevent_req *req, *subreq;
381 struct rpc_write_state *state;
383 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
384 if (req == NULL) {
385 return NULL;
387 state->ev = ev;
388 state->transport = transport;
389 state->data = data;
390 state->size = size;
391 state->num_written = 0;
393 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
395 subreq = transport->write_send(state, ev, data, size, transport->priv);
396 if (subreq == NULL) {
397 goto fail;
399 tevent_req_set_callback(subreq, rpc_write_done, req);
400 return req;
401 fail:
402 TALLOC_FREE(req);
403 return NULL;
406 static void rpc_write_done(struct tevent_req *subreq)
408 struct tevent_req *req = tevent_req_callback_data(
409 subreq, struct tevent_req);
410 struct rpc_write_state *state = tevent_req_data(
411 req, struct rpc_write_state);
412 NTSTATUS status;
413 ssize_t written;
415 status = state->transport->write_recv(subreq, &written);
416 TALLOC_FREE(subreq);
417 if (!NT_STATUS_IS_OK(status)) {
418 tevent_req_nterror(req, status);
419 return;
422 state->num_written += written;
424 if (state->num_written == state->size) {
425 tevent_req_done(req);
426 return;
429 subreq = state->transport->write_send(state, state->ev,
430 state->data + state->num_written,
431 state->size - state->num_written,
432 state->transport->priv);
433 if (tevent_req_nomem(subreq, req)) {
434 return;
436 tevent_req_set_callback(subreq, rpc_write_done, req);
439 static NTSTATUS rpc_write_recv(struct tevent_req *req)
441 return tevent_req_simple_recv_ntstatus(req);
445 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
446 struct rpc_hdr_info *prhdr,
447 prs_struct *pdu)
450 * This next call sets the endian bit correctly in current_pdu. We
451 * will propagate this to rbuf later.
454 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
455 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
456 return NT_STATUS_BUFFER_TOO_SMALL;
459 if (prhdr->frag_len > cli->max_recv_frag) {
460 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
461 " we only allow %d\n", (int)prhdr->frag_len,
462 (int)cli->max_recv_frag));
463 return NT_STATUS_BUFFER_TOO_SMALL;
466 return NT_STATUS_OK;
469 /****************************************************************************
470 Try and get a PDU's worth of data from current_pdu. If not, then read more
471 from the wire.
472 ****************************************************************************/
474 struct get_complete_frag_state {
475 struct event_context *ev;
476 struct rpc_pipe_client *cli;
477 struct rpc_hdr_info *prhdr;
478 prs_struct *pdu;
481 static void get_complete_frag_got_header(struct tevent_req *subreq);
482 static void get_complete_frag_got_rest(struct tevent_req *subreq);
484 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
485 struct event_context *ev,
486 struct rpc_pipe_client *cli,
487 struct rpc_hdr_info *prhdr,
488 prs_struct *pdu)
490 struct tevent_req *req, *subreq;
491 struct get_complete_frag_state *state;
492 uint32_t pdu_len;
493 NTSTATUS status;
495 req = tevent_req_create(mem_ctx, &state,
496 struct get_complete_frag_state);
497 if (req == NULL) {
498 return NULL;
500 state->ev = ev;
501 state->cli = cli;
502 state->prhdr = prhdr;
503 state->pdu = pdu;
505 pdu_len = prs_data_size(pdu);
506 if (pdu_len < RPC_HEADER_LEN) {
507 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
508 status = NT_STATUS_NO_MEMORY;
509 goto post_status;
511 subreq = rpc_read_send(
512 state, state->ev,
513 state->cli->transport,
514 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
515 RPC_HEADER_LEN - pdu_len);
516 if (subreq == NULL) {
517 status = NT_STATUS_NO_MEMORY;
518 goto post_status;
520 tevent_req_set_callback(subreq, get_complete_frag_got_header,
521 req);
522 return req;
525 status = parse_rpc_header(cli, prhdr, pdu);
526 if (!NT_STATUS_IS_OK(status)) {
527 goto post_status;
531 * Ensure we have frag_len bytes of data.
533 if (pdu_len < prhdr->frag_len) {
534 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
535 status = NT_STATUS_NO_MEMORY;
536 goto post_status;
538 subreq = rpc_read_send(state, state->ev,
539 state->cli->transport,
540 (uint8_t *)(prs_data_p(pdu) + pdu_len),
541 prhdr->frag_len - pdu_len);
542 if (subreq == NULL) {
543 status = NT_STATUS_NO_MEMORY;
544 goto post_status;
546 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
547 req);
548 return req;
551 status = NT_STATUS_OK;
552 post_status:
553 if (NT_STATUS_IS_OK(status)) {
554 tevent_req_done(req);
555 } else {
556 tevent_req_nterror(req, status);
558 return tevent_req_post(req, ev);
561 static void get_complete_frag_got_header(struct tevent_req *subreq)
563 struct tevent_req *req = tevent_req_callback_data(
564 subreq, struct tevent_req);
565 struct get_complete_frag_state *state = tevent_req_data(
566 req, struct get_complete_frag_state);
567 NTSTATUS status;
569 status = rpc_read_recv(subreq);
570 TALLOC_FREE(subreq);
571 if (!NT_STATUS_IS_OK(status)) {
572 tevent_req_nterror(req, status);
573 return;
576 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
577 if (!NT_STATUS_IS_OK(status)) {
578 tevent_req_nterror(req, status);
579 return;
582 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
583 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
584 return;
588 * We're here in this piece of code because we've read exactly
589 * RPC_HEADER_LEN bytes into state->pdu.
592 subreq = rpc_read_send(
593 state, state->ev, state->cli->transport,
594 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
595 state->prhdr->frag_len - RPC_HEADER_LEN);
596 if (tevent_req_nomem(subreq, req)) {
597 return;
599 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
602 static void get_complete_frag_got_rest(struct tevent_req *subreq)
604 struct tevent_req *req = tevent_req_callback_data(
605 subreq, struct tevent_req);
606 NTSTATUS status;
608 status = rpc_read_recv(subreq);
609 TALLOC_FREE(subreq);
610 if (!NT_STATUS_IS_OK(status)) {
611 tevent_req_nterror(req, status);
612 return;
614 tevent_req_done(req);
617 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
619 return tevent_req_simple_recv_ntstatus(req);
622 /****************************************************************************
623 NTLMSSP specific sign/seal.
624 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
625 In fact I should probably abstract these into identical pieces of code... JRA.
626 ****************************************************************************/
628 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
629 prs_struct *current_pdu,
630 uint8 *p_ss_padding_len)
632 RPC_HDR_AUTH auth_info;
633 uint32 save_offset = prs_offset(current_pdu);
634 uint32 auth_len = prhdr->auth_len;
635 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
636 unsigned char *data = NULL;
637 size_t data_len;
638 unsigned char *full_packet_data = NULL;
639 size_t full_packet_data_len;
640 DATA_BLOB auth_blob;
641 NTSTATUS status;
643 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
644 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
645 return NT_STATUS_OK;
648 if (!ntlmssp_state) {
649 return NT_STATUS_INVALID_PARAMETER;
652 /* Ensure there's enough data for an authenticated response. */
653 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
654 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
655 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
656 (unsigned int)auth_len ));
657 return NT_STATUS_BUFFER_TOO_SMALL;
661 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
662 * after the RPC header.
663 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
664 * functions as NTLMv2 checks the rpc headers also.
667 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
668 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
670 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
671 full_packet_data_len = prhdr->frag_len - auth_len;
673 /* Pull the auth header and the following data into a blob. */
674 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
675 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
676 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
677 return NT_STATUS_BUFFER_TOO_SMALL;
680 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
681 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
682 return NT_STATUS_BUFFER_TOO_SMALL;
685 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
686 auth_blob.length = auth_len;
688 switch (cli->auth->auth_level) {
689 case DCERPC_AUTH_LEVEL_PRIVACY:
690 /* Data is encrypted. */
691 status = ntlmssp_unseal_packet(ntlmssp_state,
692 data, data_len,
693 full_packet_data,
694 full_packet_data_len,
695 &auth_blob);
696 if (!NT_STATUS_IS_OK(status)) {
697 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
698 "packet from %s. Error was %s.\n",
699 rpccli_pipe_txt(talloc_tos(), cli),
700 nt_errstr(status) ));
701 return status;
703 break;
704 case DCERPC_AUTH_LEVEL_INTEGRITY:
705 /* Data is signed. */
706 status = ntlmssp_check_packet(ntlmssp_state,
707 data, data_len,
708 full_packet_data,
709 full_packet_data_len,
710 &auth_blob);
711 if (!NT_STATUS_IS_OK(status)) {
712 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
713 "packet from %s. Error was %s.\n",
714 rpccli_pipe_txt(talloc_tos(), cli),
715 nt_errstr(status) ));
716 return status;
718 break;
719 default:
720 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
721 "auth level %d\n", cli->auth->auth_level));
722 return NT_STATUS_INVALID_INFO_CLASS;
726 * Return the current pointer to the data offset.
729 if(!prs_set_offset(current_pdu, save_offset)) {
730 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
731 (unsigned int)save_offset ));
732 return NT_STATUS_BUFFER_TOO_SMALL;
736 * Remember the padding length. We must remove it from the real data
737 * stream once the sign/seal is done.
740 *p_ss_padding_len = auth_info.auth_pad_len;
742 return NT_STATUS_OK;
745 /****************************************************************************
746 schannel specific sign/seal.
747 ****************************************************************************/
749 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
750 prs_struct *current_pdu,
751 uint8 *p_ss_padding_len)
753 RPC_HDR_AUTH auth_info;
754 uint32 auth_len = prhdr->auth_len;
755 uint32 save_offset = prs_offset(current_pdu);
756 struct schannel_state *schannel_auth =
757 cli->auth->a_u.schannel_auth;
758 uint8_t *data;
759 uint32 data_len;
760 DATA_BLOB blob;
761 NTSTATUS status;
763 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
764 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
765 return NT_STATUS_OK;
768 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
769 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
770 return NT_STATUS_INVALID_PARAMETER;
773 if (!schannel_auth) {
774 return NT_STATUS_INVALID_PARAMETER;
777 /* Ensure there's enough data for an authenticated response. */
778 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
779 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
780 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
781 (unsigned int)auth_len ));
782 return NT_STATUS_INVALID_PARAMETER;
785 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
787 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
788 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
789 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
790 return NT_STATUS_BUFFER_TOO_SMALL;
793 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
794 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
795 return NT_STATUS_BUFFER_TOO_SMALL;
798 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
799 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
800 auth_info.auth_type));
801 return NT_STATUS_BUFFER_TOO_SMALL;
804 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
806 if (DEBUGLEVEL >= 10) {
807 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
810 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
812 switch (cli->auth->auth_level) {
813 case DCERPC_AUTH_LEVEL_PRIVACY:
814 status = netsec_incoming_packet(schannel_auth,
815 talloc_tos(),
816 true,
817 data,
818 data_len,
819 &blob);
820 break;
821 case DCERPC_AUTH_LEVEL_INTEGRITY:
822 status = netsec_incoming_packet(schannel_auth,
823 talloc_tos(),
824 false,
825 data,
826 data_len,
827 &blob);
828 break;
829 default:
830 status = NT_STATUS_INTERNAL_ERROR;
831 break;
834 if (!NT_STATUS_IS_OK(status)) {
835 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
836 "Connection to %s (%s).\n",
837 rpccli_pipe_txt(talloc_tos(), cli),
838 nt_errstr(status)));
839 return NT_STATUS_INVALID_PARAMETER;
843 * Return the current pointer to the data offset.
846 if(!prs_set_offset(current_pdu, save_offset)) {
847 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
848 (unsigned int)save_offset ));
849 return NT_STATUS_BUFFER_TOO_SMALL;
853 * Remember the padding length. We must remove it from the real data
854 * stream once the sign/seal is done.
857 *p_ss_padding_len = auth_info.auth_pad_len;
859 return NT_STATUS_OK;
862 /****************************************************************************
863 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
864 ****************************************************************************/
866 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
867 prs_struct *current_pdu,
868 uint8 *p_ss_padding_len)
870 NTSTATUS ret = NT_STATUS_OK;
872 /* Paranioa checks for auth_len. */
873 if (prhdr->auth_len) {
874 if (prhdr->auth_len > prhdr->frag_len) {
875 return NT_STATUS_INVALID_PARAMETER;
878 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
879 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
880 /* Integer wrap attempt. */
881 return NT_STATUS_INVALID_PARAMETER;
886 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
889 switch(cli->auth->auth_type) {
890 case PIPE_AUTH_TYPE_NONE:
891 if (prhdr->auth_len) {
892 DEBUG(3, ("cli_pipe_validate_rpc_response: "
893 "Connection to %s - got non-zero "
894 "auth len %u.\n",
895 rpccli_pipe_txt(talloc_tos(), cli),
896 (unsigned int)prhdr->auth_len ));
897 return NT_STATUS_INVALID_PARAMETER;
899 break;
901 case PIPE_AUTH_TYPE_NTLMSSP:
902 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
903 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
904 if (!NT_STATUS_IS_OK(ret)) {
905 return ret;
907 break;
909 case PIPE_AUTH_TYPE_SCHANNEL:
910 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
911 if (!NT_STATUS_IS_OK(ret)) {
912 return ret;
914 break;
916 case PIPE_AUTH_TYPE_KRB5:
917 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
918 default:
919 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
920 "to %s - unknown internal auth type %u.\n",
921 rpccli_pipe_txt(talloc_tos(), cli),
922 cli->auth->auth_type ));
923 return NT_STATUS_INVALID_INFO_CLASS;
926 return NT_STATUS_OK;
929 /****************************************************************************
930 Do basic authentication checks on an incoming pdu.
931 ****************************************************************************/
933 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
934 prs_struct *current_pdu,
935 uint8 expected_pkt_type,
936 char **ppdata,
937 uint32 *pdata_len,
938 prs_struct *return_data)
941 NTSTATUS ret = NT_STATUS_OK;
942 uint32 current_pdu_len = prs_data_size(current_pdu);
944 if (current_pdu_len != prhdr->frag_len) {
945 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
946 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
947 return NT_STATUS_INVALID_PARAMETER;
951 * Point the return values at the real data including the RPC
952 * header. Just in case the caller wants it.
954 *ppdata = prs_data_p(current_pdu);
955 *pdata_len = current_pdu_len;
957 /* Ensure we have the correct type. */
958 switch (prhdr->pkt_type) {
959 case DCERPC_PKT_ALTER_RESP:
960 case DCERPC_PKT_BIND_ACK:
962 /* Alter context and bind ack share the same packet definitions. */
963 break;
966 case DCERPC_PKT_RESPONSE:
968 RPC_HDR_RESP rhdr_resp;
969 uint8 ss_padding_len = 0;
971 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
972 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
973 return NT_STATUS_BUFFER_TOO_SMALL;
976 /* Here's where we deal with incoming sign/seal. */
977 ret = cli_pipe_validate_rpc_response(cli, prhdr,
978 current_pdu, &ss_padding_len);
979 if (!NT_STATUS_IS_OK(ret)) {
980 return ret;
983 /* Point the return values at the NDR data. Remember to remove any ss padding. */
984 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
986 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
987 return NT_STATUS_BUFFER_TOO_SMALL;
990 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
992 /* Remember to remove the auth footer. */
993 if (prhdr->auth_len) {
994 /* We've already done integer wrap tests on auth_len in
995 cli_pipe_validate_rpc_response(). */
996 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
997 return NT_STATUS_BUFFER_TOO_SMALL;
999 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1002 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1003 current_pdu_len, *pdata_len, ss_padding_len ));
1006 * If this is the first reply, and the allocation hint is reasonably, try and
1007 * set up the return_data parse_struct to the correct size.
1010 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1011 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1012 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1013 "too large to allocate\n",
1014 (unsigned int)rhdr_resp.alloc_hint ));
1015 return NT_STATUS_NO_MEMORY;
1019 break;
1022 case DCERPC_PKT_BIND_NAK:
1023 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1024 "received from %s!\n",
1025 rpccli_pipe_txt(talloc_tos(), cli)));
1026 /* Use this for now... */
1027 return NT_STATUS_NETWORK_ACCESS_DENIED;
1029 case DCERPC_PKT_FAULT:
1031 RPC_HDR_RESP rhdr_resp;
1032 RPC_HDR_FAULT fault_resp;
1034 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1035 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1036 return NT_STATUS_BUFFER_TOO_SMALL;
1039 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1040 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1041 return NT_STATUS_BUFFER_TOO_SMALL;
1044 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1045 "code %s received from %s!\n",
1046 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1047 rpccli_pipe_txt(talloc_tos(), cli)));
1048 if (NT_STATUS_IS_OK(fault_resp.status)) {
1049 return NT_STATUS_UNSUCCESSFUL;
1050 } else {
1051 return fault_resp.status;
1055 default:
1056 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1057 "from %s!\n",
1058 (unsigned int)prhdr->pkt_type,
1059 rpccli_pipe_txt(talloc_tos(), cli)));
1060 return NT_STATUS_INVALID_INFO_CLASS;
1063 if (prhdr->pkt_type != expected_pkt_type) {
1064 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1065 "got an unexpected RPC packet type - %u, not %u\n",
1066 rpccli_pipe_txt(talloc_tos(), cli),
1067 prhdr->pkt_type,
1068 expected_pkt_type));
1069 return NT_STATUS_INVALID_INFO_CLASS;
1072 /* Do this just before return - we don't want to modify any rpc header
1073 data before now as we may have needed to do cryptographic actions on
1074 it before. */
1076 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1077 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1078 "setting fragment first/last ON.\n"));
1079 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1082 return NT_STATUS_OK;
1085 /****************************************************************************
1086 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1087 Normally the frag_len and buffer size will match, but on the first trans
1088 reply there is a theoretical chance that buffer size > frag_len, so we must
1089 deal with that.
1090 ****************************************************************************/
1092 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1094 uint32 current_pdu_len = prs_data_size(current_pdu);
1096 if (current_pdu_len < prhdr->frag_len) {
1097 return NT_STATUS_BUFFER_TOO_SMALL;
1100 /* Common case. */
1101 if (current_pdu_len == (uint32)prhdr->frag_len) {
1102 prs_mem_free(current_pdu);
1103 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1104 /* Make current_pdu dynamic with no memory. */
1105 prs_give_memory(current_pdu, 0, 0, True);
1106 return NT_STATUS_OK;
1110 * Oh no ! More data in buffer than we processed in current pdu.
1111 * Cheat. Move the data down and shrink the buffer.
1114 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1115 current_pdu_len - prhdr->frag_len);
1117 /* Remember to set the read offset back to zero. */
1118 prs_set_offset(current_pdu, 0);
1120 /* Shrink the buffer. */
1121 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1122 return NT_STATUS_BUFFER_TOO_SMALL;
1125 return NT_STATUS_OK;
1128 /****************************************************************************
1129 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1130 ****************************************************************************/
1132 struct cli_api_pipe_state {
1133 struct event_context *ev;
1134 struct rpc_cli_transport *transport;
1135 uint8_t *rdata;
1136 uint32_t rdata_len;
1139 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1140 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1141 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1143 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1144 struct event_context *ev,
1145 struct rpc_cli_transport *transport,
1146 uint8_t *data, size_t data_len,
1147 uint32_t max_rdata_len)
1149 struct tevent_req *req, *subreq;
1150 struct cli_api_pipe_state *state;
1151 NTSTATUS status;
1153 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1154 if (req == NULL) {
1155 return NULL;
1157 state->ev = ev;
1158 state->transport = transport;
1160 if (max_rdata_len < RPC_HEADER_LEN) {
1162 * For a RPC reply we always need at least RPC_HEADER_LEN
1163 * bytes. We check this here because we will receive
1164 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1166 status = NT_STATUS_INVALID_PARAMETER;
1167 goto post_status;
1170 if (transport->trans_send != NULL) {
1171 subreq = transport->trans_send(state, ev, data, data_len,
1172 max_rdata_len, transport->priv);
1173 if (subreq == NULL) {
1174 goto fail;
1176 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1177 return req;
1181 * If the transport does not provide a "trans" routine, i.e. for
1182 * example the ncacn_ip_tcp transport, do the write/read step here.
1185 subreq = rpc_write_send(state, ev, transport, data, data_len);
1186 if (subreq == NULL) {
1187 goto fail;
1189 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1190 return req;
1192 status = NT_STATUS_INVALID_PARAMETER;
1194 post_status:
1195 tevent_req_nterror(req, status);
1196 return tevent_req_post(req, ev);
1197 fail:
1198 TALLOC_FREE(req);
1199 return NULL;
1202 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1204 struct tevent_req *req = tevent_req_callback_data(
1205 subreq, struct tevent_req);
1206 struct cli_api_pipe_state *state = tevent_req_data(
1207 req, struct cli_api_pipe_state);
1208 NTSTATUS status;
1210 status = state->transport->trans_recv(subreq, state, &state->rdata,
1211 &state->rdata_len);
1212 TALLOC_FREE(subreq);
1213 if (!NT_STATUS_IS_OK(status)) {
1214 tevent_req_nterror(req, status);
1215 return;
1217 tevent_req_done(req);
1220 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1222 struct tevent_req *req = tevent_req_callback_data(
1223 subreq, struct tevent_req);
1224 struct cli_api_pipe_state *state = tevent_req_data(
1225 req, struct cli_api_pipe_state);
1226 NTSTATUS status;
1228 status = rpc_write_recv(subreq);
1229 TALLOC_FREE(subreq);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 tevent_req_nterror(req, status);
1232 return;
1235 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1236 if (tevent_req_nomem(state->rdata, req)) {
1237 return;
1241 * We don't need to use rpc_read_send here, the upper layer will cope
1242 * with a short read, transport->trans_send could also return less
1243 * than state->max_rdata_len.
1245 subreq = state->transport->read_send(state, state->ev, state->rdata,
1246 RPC_HEADER_LEN,
1247 state->transport->priv);
1248 if (tevent_req_nomem(subreq, req)) {
1249 return;
1251 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1254 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1256 struct tevent_req *req = tevent_req_callback_data(
1257 subreq, struct tevent_req);
1258 struct cli_api_pipe_state *state = tevent_req_data(
1259 req, struct cli_api_pipe_state);
1260 NTSTATUS status;
1261 ssize_t received;
1263 status = state->transport->read_recv(subreq, &received);
1264 TALLOC_FREE(subreq);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 tevent_req_nterror(req, status);
1267 return;
1269 state->rdata_len = received;
1270 tevent_req_done(req);
1273 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1274 uint8_t **prdata, uint32_t *prdata_len)
1276 struct cli_api_pipe_state *state = tevent_req_data(
1277 req, struct cli_api_pipe_state);
1278 NTSTATUS status;
1280 if (tevent_req_is_nterror(req, &status)) {
1281 return status;
1284 *prdata = talloc_move(mem_ctx, &state->rdata);
1285 *prdata_len = state->rdata_len;
1286 return NT_STATUS_OK;
1289 /****************************************************************************
1290 Send data on an rpc pipe via trans. The prs_struct data must be the last
1291 pdu fragment of an NDR data stream.
1293 Receive response data from an rpc pipe, which may be large...
1295 Read the first fragment: unfortunately have to use SMBtrans for the first
1296 bit, then SMBreadX for subsequent bits.
1298 If first fragment received also wasn't the last fragment, continue
1299 getting fragments until we _do_ receive the last fragment.
1301 Request/Response PDU's look like the following...
1303 |<------------------PDU len----------------------------------------------->|
1304 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1306 +------------+-----------------+-------------+---------------+-------------+
1307 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1308 +------------+-----------------+-------------+---------------+-------------+
1310 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1311 signing & sealing being negotiated.
1313 ****************************************************************************/
1315 struct rpc_api_pipe_state {
1316 struct event_context *ev;
1317 struct rpc_pipe_client *cli;
1318 uint8_t expected_pkt_type;
1320 prs_struct incoming_frag;
1321 struct rpc_hdr_info rhdr;
1323 prs_struct incoming_pdu; /* Incoming reply */
1324 uint32_t incoming_pdu_offset;
1327 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1329 prs_mem_free(&state->incoming_frag);
1330 prs_mem_free(&state->incoming_pdu);
1331 return 0;
1334 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1335 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1337 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1338 struct event_context *ev,
1339 struct rpc_pipe_client *cli,
1340 prs_struct *data, /* Outgoing PDU */
1341 uint8_t expected_pkt_type)
1343 struct tevent_req *req, *subreq;
1344 struct rpc_api_pipe_state *state;
1345 uint16_t max_recv_frag;
1346 NTSTATUS status;
1348 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1349 if (req == NULL) {
1350 return NULL;
1352 state->ev = ev;
1353 state->cli = cli;
1354 state->expected_pkt_type = expected_pkt_type;
1355 state->incoming_pdu_offset = 0;
1357 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1359 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1360 /* Make incoming_pdu dynamic with no memory. */
1361 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1363 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1366 * Ensure we're not sending too much.
1368 if (prs_offset(data) > cli->max_xmit_frag) {
1369 status = NT_STATUS_INVALID_PARAMETER;
1370 goto post_status;
1373 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1375 max_recv_frag = cli->max_recv_frag;
1377 #if 0
1378 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1379 #endif
1381 subreq = cli_api_pipe_send(state, ev, cli->transport,
1382 (uint8_t *)prs_data_p(data),
1383 prs_offset(data), max_recv_frag);
1384 if (subreq == NULL) {
1385 goto fail;
1387 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1388 return req;
1390 post_status:
1391 tevent_req_nterror(req, status);
1392 return tevent_req_post(req, ev);
1393 fail:
1394 TALLOC_FREE(req);
1395 return NULL;
1398 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1400 struct tevent_req *req = tevent_req_callback_data(
1401 subreq, struct tevent_req);
1402 struct rpc_api_pipe_state *state = tevent_req_data(
1403 req, struct rpc_api_pipe_state);
1404 NTSTATUS status;
1405 uint8_t *rdata = NULL;
1406 uint32_t rdata_len = 0;
1407 char *rdata_copy;
1409 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1410 TALLOC_FREE(subreq);
1411 if (!NT_STATUS_IS_OK(status)) {
1412 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1413 tevent_req_nterror(req, status);
1414 return;
1417 if (rdata == NULL) {
1418 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1419 rpccli_pipe_txt(talloc_tos(), state->cli)));
1420 tevent_req_done(req);
1421 return;
1425 * Give the memory received from cli_trans as dynamic to the current
1426 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1427 * :-(
1429 rdata_copy = (char *)memdup(rdata, rdata_len);
1430 TALLOC_FREE(rdata);
1431 if (tevent_req_nomem(rdata_copy, req)) {
1432 return;
1434 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1436 /* Ensure we have enough data for a pdu. */
1437 subreq = get_complete_frag_send(state, state->ev, state->cli,
1438 &state->rhdr, &state->incoming_frag);
1439 if (tevent_req_nomem(subreq, req)) {
1440 return;
1442 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1445 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1447 struct tevent_req *req = tevent_req_callback_data(
1448 subreq, struct tevent_req);
1449 struct rpc_api_pipe_state *state = tevent_req_data(
1450 req, struct rpc_api_pipe_state);
1451 NTSTATUS status;
1452 char *rdata = NULL;
1453 uint32_t rdata_len = 0;
1455 status = get_complete_frag_recv(subreq);
1456 TALLOC_FREE(subreq);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 DEBUG(5, ("get_complete_frag failed: %s\n",
1459 nt_errstr(status)));
1460 tevent_req_nterror(req, status);
1461 return;
1464 status = cli_pipe_validate_current_pdu(
1465 state->cli, &state->rhdr, &state->incoming_frag,
1466 state->expected_pkt_type, &rdata, &rdata_len,
1467 &state->incoming_pdu);
1469 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1470 (unsigned)prs_data_size(&state->incoming_frag),
1471 (unsigned)state->incoming_pdu_offset,
1472 nt_errstr(status)));
1474 if (!NT_STATUS_IS_OK(status)) {
1475 tevent_req_nterror(req, status);
1476 return;
1479 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1480 && (state->rhdr.pack_type[0] == 0)) {
1482 * Set the data type correctly for big-endian data on the
1483 * first packet.
1485 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1486 "big-endian.\n",
1487 rpccli_pipe_txt(talloc_tos(), state->cli)));
1488 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1491 * Check endianness on subsequent packets.
1493 if (state->incoming_frag.bigendian_data
1494 != state->incoming_pdu.bigendian_data) {
1495 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1496 "%s\n",
1497 state->incoming_pdu.bigendian_data?"big":"little",
1498 state->incoming_frag.bigendian_data?"big":"little"));
1499 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1500 return;
1503 /* Now copy the data portion out of the pdu into rbuf. */
1504 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1505 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1506 return;
1509 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1510 rdata, (size_t)rdata_len);
1511 state->incoming_pdu_offset += rdata_len;
1513 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1514 &state->incoming_frag);
1515 if (!NT_STATUS_IS_OK(status)) {
1516 tevent_req_nterror(req, status);
1517 return;
1520 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1521 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1522 rpccli_pipe_txt(talloc_tos(), state->cli),
1523 (unsigned)prs_data_size(&state->incoming_pdu)));
1524 tevent_req_done(req);
1525 return;
1528 subreq = get_complete_frag_send(state, state->ev, state->cli,
1529 &state->rhdr, &state->incoming_frag);
1530 if (tevent_req_nomem(subreq, req)) {
1531 return;
1533 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1536 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1537 prs_struct *reply_pdu)
1539 struct rpc_api_pipe_state *state = tevent_req_data(
1540 req, struct rpc_api_pipe_state);
1541 NTSTATUS status;
1543 if (tevent_req_is_nterror(req, &status)) {
1544 return status;
1547 *reply_pdu = state->incoming_pdu;
1548 reply_pdu->mem_ctx = mem_ctx;
1551 * Prevent state->incoming_pdu from being freed in
1552 * rpc_api_pipe_state_destructor()
1554 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1556 return NT_STATUS_OK;
1559 /*******************************************************************
1560 Creates krb5 auth bind.
1561 ********************************************************************/
1563 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1564 enum dcerpc_AuthLevel auth_level,
1565 RPC_HDR_AUTH *pauth_out,
1566 prs_struct *auth_data)
1568 #ifdef HAVE_KRB5
1569 int ret;
1570 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1571 DATA_BLOB tkt = data_blob_null;
1572 DATA_BLOB tkt_wrapped = data_blob_null;
1574 /* We may change the pad length before marshalling. */
1575 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1577 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1578 a->service_principal ));
1580 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1582 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1583 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1585 if (ret) {
1586 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1587 "failed with %s\n",
1588 a->service_principal,
1589 error_message(ret) ));
1591 data_blob_free(&tkt);
1592 prs_mem_free(auth_data);
1593 return NT_STATUS_INVALID_PARAMETER;
1596 /* wrap that up in a nice GSS-API wrapping */
1597 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1599 data_blob_free(&tkt);
1601 /* Auth len in the rpc header doesn't include auth_header. */
1602 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1603 data_blob_free(&tkt_wrapped);
1604 prs_mem_free(auth_data);
1605 return NT_STATUS_NO_MEMORY;
1608 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1609 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1611 data_blob_free(&tkt_wrapped);
1612 return NT_STATUS_OK;
1613 #else
1614 return NT_STATUS_INVALID_PARAMETER;
1615 #endif
1618 /*******************************************************************
1619 Creates SPNEGO NTLMSSP auth bind.
1620 ********************************************************************/
1622 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1623 enum dcerpc_AuthLevel auth_level,
1624 RPC_HDR_AUTH *pauth_out,
1625 prs_struct *auth_data)
1627 NTSTATUS nt_status;
1628 DATA_BLOB null_blob = data_blob_null;
1629 DATA_BLOB request = data_blob_null;
1630 DATA_BLOB spnego_msg = data_blob_null;
1632 /* We may change the pad length before marshalling. */
1633 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1635 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1636 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1637 null_blob,
1638 &request);
1640 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1641 data_blob_free(&request);
1642 prs_mem_free(auth_data);
1643 return nt_status;
1646 /* Wrap this in SPNEGO. */
1647 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1649 data_blob_free(&request);
1651 /* Auth len in the rpc header doesn't include auth_header. */
1652 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1653 data_blob_free(&spnego_msg);
1654 prs_mem_free(auth_data);
1655 return NT_STATUS_NO_MEMORY;
1658 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1659 dump_data(5, spnego_msg.data, spnego_msg.length);
1661 data_blob_free(&spnego_msg);
1662 return NT_STATUS_OK;
1665 /*******************************************************************
1666 Creates NTLMSSP auth bind.
1667 ********************************************************************/
1669 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1670 enum dcerpc_AuthLevel auth_level,
1671 RPC_HDR_AUTH *pauth_out,
1672 prs_struct *auth_data)
1674 NTSTATUS nt_status;
1675 DATA_BLOB null_blob = data_blob_null;
1676 DATA_BLOB request = data_blob_null;
1678 /* We may change the pad length before marshalling. */
1679 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1681 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1682 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1683 null_blob,
1684 &request);
1686 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1687 data_blob_free(&request);
1688 prs_mem_free(auth_data);
1689 return nt_status;
1692 /* Auth len in the rpc header doesn't include auth_header. */
1693 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1694 data_blob_free(&request);
1695 prs_mem_free(auth_data);
1696 return NT_STATUS_NO_MEMORY;
1699 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1700 dump_data(5, request.data, request.length);
1702 data_blob_free(&request);
1703 return NT_STATUS_OK;
1706 /*******************************************************************
1707 Creates schannel auth bind.
1708 ********************************************************************/
1710 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1711 enum dcerpc_AuthLevel auth_level,
1712 RPC_HDR_AUTH *pauth_out,
1713 prs_struct *auth_data)
1715 struct NL_AUTH_MESSAGE r;
1716 enum ndr_err_code ndr_err;
1717 DATA_BLOB blob;
1719 /* We may change the pad length before marshalling. */
1720 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1722 /* Use lp_workgroup() if domain not specified */
1724 if (!cli->auth->domain || !cli->auth->domain[0]) {
1725 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1726 if (cli->auth->domain == NULL) {
1727 return NT_STATUS_NO_MEMORY;
1732 * Now marshall the data into the auth parse_struct.
1735 r.MessageType = NL_NEGOTIATE_REQUEST;
1736 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1737 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1738 r.oem_netbios_domain.a = cli->auth->domain;
1739 r.oem_netbios_computer.a = global_myname();
1741 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1742 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1743 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1744 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1745 prs_mem_free(auth_data);
1746 return ndr_map_error2ntstatus(ndr_err);
1749 if (DEBUGLEVEL >= 10) {
1750 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1753 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1755 prs_mem_free(auth_data);
1756 return NT_STATUS_NO_MEMORY;
1759 return NT_STATUS_OK;
1762 /*******************************************************************
1763 Creates the internals of a DCE/RPC bind request or alter context PDU.
1764 ********************************************************************/
1766 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1767 prs_struct *rpc_out,
1768 uint32 rpc_call_id,
1769 const struct ndr_syntax_id *abstract,
1770 const struct ndr_syntax_id *transfer,
1771 RPC_HDR_AUTH *phdr_auth,
1772 prs_struct *pauth_info)
1774 RPC_HDR hdr;
1775 RPC_HDR_RB hdr_rb;
1776 RPC_CONTEXT rpc_ctx;
1777 uint16 auth_len = prs_offset(pauth_info);
1778 uint8 ss_padding_len = 0;
1779 uint16 frag_len = 0;
1781 /* create the RPC context. */
1782 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1784 /* create the bind request RPC_HDR_RB */
1785 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1787 /* Start building the frag length. */
1788 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1790 /* Do we need to pad ? */
1791 if (auth_len) {
1792 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1793 if (data_len % 8) {
1794 ss_padding_len = 8 - (data_len % 8);
1795 phdr_auth->auth_pad_len = ss_padding_len;
1797 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1800 /* Create the request RPC_HDR */
1801 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1803 /* Marshall the RPC header */
1804 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1805 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1806 return NT_STATUS_NO_MEMORY;
1809 /* Marshall the bind request data */
1810 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1811 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1812 return NT_STATUS_NO_MEMORY;
1816 * Grow the outgoing buffer to store any auth info.
1819 if(auth_len != 0) {
1820 if (ss_padding_len) {
1821 char pad[8];
1822 memset(pad, '\0', 8);
1823 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1824 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1825 return NT_STATUS_NO_MEMORY;
1829 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1830 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1831 return NT_STATUS_NO_MEMORY;
1835 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1836 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1837 return NT_STATUS_NO_MEMORY;
1841 return NT_STATUS_OK;
1844 /*******************************************************************
1845 Creates a DCE/RPC bind request.
1846 ********************************************************************/
1848 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1849 prs_struct *rpc_out,
1850 uint32 rpc_call_id,
1851 const struct ndr_syntax_id *abstract,
1852 const struct ndr_syntax_id *transfer,
1853 enum pipe_auth_type auth_type,
1854 enum dcerpc_AuthLevel auth_level)
1856 RPC_HDR_AUTH hdr_auth;
1857 prs_struct auth_info;
1858 NTSTATUS ret = NT_STATUS_OK;
1860 ZERO_STRUCT(hdr_auth);
1861 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1862 return NT_STATUS_NO_MEMORY;
1864 switch (auth_type) {
1865 case PIPE_AUTH_TYPE_SCHANNEL:
1866 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1867 if (!NT_STATUS_IS_OK(ret)) {
1868 prs_mem_free(&auth_info);
1869 return ret;
1871 break;
1873 case PIPE_AUTH_TYPE_NTLMSSP:
1874 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1875 if (!NT_STATUS_IS_OK(ret)) {
1876 prs_mem_free(&auth_info);
1877 return ret;
1879 break;
1881 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1882 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1883 if (!NT_STATUS_IS_OK(ret)) {
1884 prs_mem_free(&auth_info);
1885 return ret;
1887 break;
1889 case PIPE_AUTH_TYPE_KRB5:
1890 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1891 if (!NT_STATUS_IS_OK(ret)) {
1892 prs_mem_free(&auth_info);
1893 return ret;
1895 break;
1897 case PIPE_AUTH_TYPE_NONE:
1898 break;
1900 default:
1901 /* "Can't" happen. */
1902 return NT_STATUS_INVALID_INFO_CLASS;
1905 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1906 rpc_out,
1907 rpc_call_id,
1908 abstract,
1909 transfer,
1910 &hdr_auth,
1911 &auth_info);
1913 prs_mem_free(&auth_info);
1914 return ret;
1917 /*******************************************************************
1918 Create and add the NTLMSSP sign/seal auth header and data.
1919 ********************************************************************/
1921 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1922 RPC_HDR *phdr,
1923 uint32 ss_padding_len,
1924 prs_struct *outgoing_pdu)
1926 RPC_HDR_AUTH auth_info;
1927 NTSTATUS status;
1928 DATA_BLOB auth_blob = data_blob_null;
1929 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1931 if (!cli->auth->a_u.ntlmssp_state) {
1932 return NT_STATUS_INVALID_PARAMETER;
1935 /* Init and marshall the auth header. */
1936 init_rpc_hdr_auth(&auth_info,
1937 map_pipe_auth_type_to_rpc_auth_type(
1938 cli->auth->auth_type),
1939 cli->auth->auth_level,
1940 ss_padding_len,
1941 1 /* context id. */);
1943 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1944 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1945 data_blob_free(&auth_blob);
1946 return NT_STATUS_NO_MEMORY;
1949 switch (cli->auth->auth_level) {
1950 case DCERPC_AUTH_LEVEL_PRIVACY:
1951 /* Data portion is encrypted. */
1952 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1953 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1954 data_and_pad_len,
1955 (unsigned char *)prs_data_p(outgoing_pdu),
1956 (size_t)prs_offset(outgoing_pdu),
1957 &auth_blob);
1958 if (!NT_STATUS_IS_OK(status)) {
1959 data_blob_free(&auth_blob);
1960 return status;
1962 break;
1964 case DCERPC_AUTH_LEVEL_INTEGRITY:
1965 /* Data is signed. */
1966 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1967 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1968 data_and_pad_len,
1969 (unsigned char *)prs_data_p(outgoing_pdu),
1970 (size_t)prs_offset(outgoing_pdu),
1971 &auth_blob);
1972 if (!NT_STATUS_IS_OK(status)) {
1973 data_blob_free(&auth_blob);
1974 return status;
1976 break;
1978 default:
1979 /* Can't happen. */
1980 smb_panic("bad auth level");
1981 /* Notreached. */
1982 return NT_STATUS_INVALID_PARAMETER;
1985 /* Finally marshall the blob. */
1987 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1988 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1989 (unsigned int)NTLMSSP_SIG_SIZE));
1990 data_blob_free(&auth_blob);
1991 return NT_STATUS_NO_MEMORY;
1994 data_blob_free(&auth_blob);
1995 return NT_STATUS_OK;
1998 /*******************************************************************
1999 Create and add the schannel sign/seal auth header and data.
2000 ********************************************************************/
2002 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2003 RPC_HDR *phdr,
2004 uint32 ss_padding_len,
2005 prs_struct *outgoing_pdu)
2007 RPC_HDR_AUTH auth_info;
2008 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2009 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2010 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2011 DATA_BLOB blob;
2012 NTSTATUS status;
2014 if (!sas) {
2015 return NT_STATUS_INVALID_PARAMETER;
2018 /* Init and marshall the auth header. */
2019 init_rpc_hdr_auth(&auth_info,
2020 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2021 cli->auth->auth_level,
2022 ss_padding_len,
2023 1 /* context id. */);
2025 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2026 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2027 return NT_STATUS_NO_MEMORY;
2030 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2031 sas->seq_num));
2033 switch (cli->auth->auth_level) {
2034 case DCERPC_AUTH_LEVEL_PRIVACY:
2035 status = netsec_outgoing_packet(sas,
2036 talloc_tos(),
2037 true,
2038 (uint8_t *)data_p,
2039 data_and_pad_len,
2040 &blob);
2041 break;
2042 case DCERPC_AUTH_LEVEL_INTEGRITY:
2043 status = netsec_outgoing_packet(sas,
2044 talloc_tos(),
2045 false,
2046 (uint8_t *)data_p,
2047 data_and_pad_len,
2048 &blob);
2049 break;
2050 default:
2051 status = NT_STATUS_INTERNAL_ERROR;
2052 break;
2055 if (!NT_STATUS_IS_OK(status)) {
2056 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2057 nt_errstr(status)));
2058 return status;
2061 if (DEBUGLEVEL >= 10) {
2062 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2065 /* Finally marshall the blob. */
2066 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2067 return NT_STATUS_NO_MEMORY;
2070 return NT_STATUS_OK;
2073 /*******************************************************************
2074 Calculate how much data we're going to send in this packet, also
2075 work out any sign/seal padding length.
2076 ********************************************************************/
2078 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2079 uint32 data_left,
2080 uint16 *p_frag_len,
2081 uint16 *p_auth_len,
2082 uint32 *p_ss_padding)
2084 uint32 data_space, data_len;
2086 #if 0
2087 if ((data_left > 0) && (sys_random() % 2)) {
2088 data_left = MAX(data_left/2, 1);
2090 #endif
2092 switch (cli->auth->auth_level) {
2093 case DCERPC_AUTH_LEVEL_NONE:
2094 case DCERPC_AUTH_LEVEL_CONNECT:
2095 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2096 data_len = MIN(data_space, data_left);
2097 *p_ss_padding = 0;
2098 *p_auth_len = 0;
2099 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2100 return data_len;
2102 case DCERPC_AUTH_LEVEL_INTEGRITY:
2103 case DCERPC_AUTH_LEVEL_PRIVACY:
2104 /* Treat the same for all authenticated rpc requests. */
2105 switch(cli->auth->auth_type) {
2106 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2107 case PIPE_AUTH_TYPE_NTLMSSP:
2108 *p_auth_len = NTLMSSP_SIG_SIZE;
2109 break;
2110 case PIPE_AUTH_TYPE_SCHANNEL:
2111 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2112 break;
2113 default:
2114 smb_panic("bad auth type");
2115 break;
2118 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2119 RPC_HDR_AUTH_LEN - *p_auth_len;
2121 data_len = MIN(data_space, data_left);
2122 *p_ss_padding = 0;
2123 if (data_len % 8) {
2124 *p_ss_padding = 8 - (data_len % 8);
2126 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2127 data_len + *p_ss_padding + /* data plus padding. */
2128 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2129 return data_len;
2131 default:
2132 smb_panic("bad auth level");
2133 /* Notreached. */
2134 return 0;
2138 /*******************************************************************
2139 External interface.
2140 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2141 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2142 and deals with signing/sealing details.
2143 ********************************************************************/
2145 struct rpc_api_pipe_req_state {
2146 struct event_context *ev;
2147 struct rpc_pipe_client *cli;
2148 uint8_t op_num;
2149 uint32_t call_id;
2150 prs_struct *req_data;
2151 uint32_t req_data_sent;
2152 prs_struct outgoing_frag;
2153 prs_struct reply_pdu;
2156 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2158 prs_mem_free(&s->outgoing_frag);
2159 prs_mem_free(&s->reply_pdu);
2160 return 0;
2163 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2164 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2165 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2166 bool *is_last_frag);
2168 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2169 struct event_context *ev,
2170 struct rpc_pipe_client *cli,
2171 uint8_t op_num,
2172 prs_struct *req_data)
2174 struct tevent_req *req, *subreq;
2175 struct rpc_api_pipe_req_state *state;
2176 NTSTATUS status;
2177 bool is_last_frag;
2179 req = tevent_req_create(mem_ctx, &state,
2180 struct rpc_api_pipe_req_state);
2181 if (req == NULL) {
2182 return NULL;
2184 state->ev = ev;
2185 state->cli = cli;
2186 state->op_num = op_num;
2187 state->req_data = req_data;
2188 state->req_data_sent = 0;
2189 state->call_id = get_rpc_call_id();
2191 if (cli->max_xmit_frag
2192 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2193 /* Server is screwed up ! */
2194 status = NT_STATUS_INVALID_PARAMETER;
2195 goto post_status;
2198 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2200 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2201 state, MARSHALL)) {
2202 goto fail;
2205 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2207 status = prepare_next_frag(state, &is_last_frag);
2208 if (!NT_STATUS_IS_OK(status)) {
2209 goto post_status;
2212 if (is_last_frag) {
2213 subreq = rpc_api_pipe_send(state, ev, state->cli,
2214 &state->outgoing_frag,
2215 DCERPC_PKT_RESPONSE);
2216 if (subreq == NULL) {
2217 goto fail;
2219 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2220 } else {
2221 subreq = rpc_write_send(
2222 state, ev, cli->transport,
2223 (uint8_t *)prs_data_p(&state->outgoing_frag),
2224 prs_offset(&state->outgoing_frag));
2225 if (subreq == NULL) {
2226 goto fail;
2228 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2229 req);
2231 return req;
2233 post_status:
2234 tevent_req_nterror(req, status);
2235 return tevent_req_post(req, ev);
2236 fail:
2237 TALLOC_FREE(req);
2238 return NULL;
2241 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2242 bool *is_last_frag)
2244 RPC_HDR hdr;
2245 RPC_HDR_REQ hdr_req;
2246 uint32_t data_sent_thistime;
2247 uint16_t auth_len;
2248 uint16_t frag_len;
2249 uint8_t flags = 0;
2250 uint32_t ss_padding;
2251 uint32_t data_left;
2252 char pad[8] = { 0, };
2253 NTSTATUS status;
2255 data_left = prs_offset(state->req_data) - state->req_data_sent;
2257 data_sent_thistime = calculate_data_len_tosend(
2258 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2260 if (state->req_data_sent == 0) {
2261 flags = DCERPC_PFC_FLAG_FIRST;
2264 if (data_sent_thistime == data_left) {
2265 flags |= DCERPC_PFC_FLAG_LAST;
2268 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2269 return NT_STATUS_NO_MEMORY;
2272 /* Create and marshall the header and request header. */
2273 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2274 auth_len);
2276 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2277 return NT_STATUS_NO_MEMORY;
2280 /* Create the rpc request RPC_HDR_REQ */
2281 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2282 state->op_num);
2284 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2285 &state->outgoing_frag, 0)) {
2286 return NT_STATUS_NO_MEMORY;
2289 /* Copy in the data, plus any ss padding. */
2290 if (!prs_append_some_prs_data(&state->outgoing_frag,
2291 state->req_data, state->req_data_sent,
2292 data_sent_thistime)) {
2293 return NT_STATUS_NO_MEMORY;
2296 /* Copy the sign/seal padding data. */
2297 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2298 return NT_STATUS_NO_MEMORY;
2301 /* Generate any auth sign/seal and add the auth footer. */
2302 switch (state->cli->auth->auth_type) {
2303 case PIPE_AUTH_TYPE_NONE:
2304 status = NT_STATUS_OK;
2305 break;
2306 case PIPE_AUTH_TYPE_NTLMSSP:
2307 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2308 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2309 &state->outgoing_frag);
2310 break;
2311 case PIPE_AUTH_TYPE_SCHANNEL:
2312 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2313 &state->outgoing_frag);
2314 break;
2315 default:
2316 status = NT_STATUS_INVALID_PARAMETER;
2317 break;
2320 state->req_data_sent += data_sent_thistime;
2321 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2323 return status;
2326 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2328 struct tevent_req *req = tevent_req_callback_data(
2329 subreq, struct tevent_req);
2330 struct rpc_api_pipe_req_state *state = tevent_req_data(
2331 req, struct rpc_api_pipe_req_state);
2332 NTSTATUS status;
2333 bool is_last_frag;
2335 status = rpc_write_recv(subreq);
2336 TALLOC_FREE(subreq);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 tevent_req_nterror(req, status);
2339 return;
2342 status = prepare_next_frag(state, &is_last_frag);
2343 if (!NT_STATUS_IS_OK(status)) {
2344 tevent_req_nterror(req, status);
2345 return;
2348 if (is_last_frag) {
2349 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2350 &state->outgoing_frag,
2351 DCERPC_PKT_RESPONSE);
2352 if (tevent_req_nomem(subreq, req)) {
2353 return;
2355 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2356 } else {
2357 subreq = rpc_write_send(
2358 state, state->ev,
2359 state->cli->transport,
2360 (uint8_t *)prs_data_p(&state->outgoing_frag),
2361 prs_offset(&state->outgoing_frag));
2362 if (tevent_req_nomem(subreq, req)) {
2363 return;
2365 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2366 req);
2370 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2372 struct tevent_req *req = tevent_req_callback_data(
2373 subreq, struct tevent_req);
2374 struct rpc_api_pipe_req_state *state = tevent_req_data(
2375 req, struct rpc_api_pipe_req_state);
2376 NTSTATUS status;
2378 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2379 TALLOC_FREE(subreq);
2380 if (!NT_STATUS_IS_OK(status)) {
2381 tevent_req_nterror(req, status);
2382 return;
2384 tevent_req_done(req);
2387 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2388 prs_struct *reply_pdu)
2390 struct rpc_api_pipe_req_state *state = tevent_req_data(
2391 req, struct rpc_api_pipe_req_state);
2392 NTSTATUS status;
2394 if (tevent_req_is_nterror(req, &status)) {
2396 * We always have to initialize to reply pdu, even if there is
2397 * none. The rpccli_* caller routines expect this.
2399 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2400 return status;
2403 *reply_pdu = state->reply_pdu;
2404 reply_pdu->mem_ctx = mem_ctx;
2407 * Prevent state->req_pdu from being freed in
2408 * rpc_api_pipe_req_state_destructor()
2410 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2412 return NT_STATUS_OK;
2415 #if 0
2416 /****************************************************************************
2417 Set the handle state.
2418 ****************************************************************************/
2420 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2421 const char *pipe_name, uint16 device_state)
2423 bool state_set = False;
2424 char param[2];
2425 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2426 char *rparam = NULL;
2427 char *rdata = NULL;
2428 uint32 rparam_len, rdata_len;
2430 if (pipe_name == NULL)
2431 return False;
2433 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2434 cli->fnum, pipe_name, device_state));
2436 /* create parameters: device state */
2437 SSVAL(param, 0, device_state);
2439 /* create setup parameters. */
2440 setup[0] = 0x0001;
2441 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2443 /* send the data on \PIPE\ */
2444 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2445 setup, 2, 0, /* setup, length, max */
2446 param, 2, 0, /* param, length, max */
2447 NULL, 0, 1024, /* data, length, max */
2448 &rparam, &rparam_len, /* return param, length */
2449 &rdata, &rdata_len)) /* return data, length */
2451 DEBUG(5, ("Set Handle state: return OK\n"));
2452 state_set = True;
2455 SAFE_FREE(rparam);
2456 SAFE_FREE(rdata);
2458 return state_set;
2460 #endif
2462 /****************************************************************************
2463 Check the rpc bind acknowledge response.
2464 ****************************************************************************/
2466 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2467 const struct ndr_syntax_id *transfer)
2469 if ( hdr_ba->addr.len == 0) {
2470 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2473 /* check the transfer syntax */
2474 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2475 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2476 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2477 return False;
2480 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2481 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2482 hdr_ba->res.num_results, hdr_ba->res.reason));
2485 DEBUG(5,("check_bind_response: accepted!\n"));
2486 return True;
2489 /*******************************************************************
2490 Creates a DCE/RPC bind authentication response.
2491 This is the packet that is sent back to the server once we
2492 have received a BIND-ACK, to finish the third leg of
2493 the authentication handshake.
2494 ********************************************************************/
2496 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2497 uint32 rpc_call_id,
2498 enum pipe_auth_type auth_type,
2499 enum dcerpc_AuthLevel auth_level,
2500 DATA_BLOB *pauth_blob,
2501 prs_struct *rpc_out)
2503 RPC_HDR hdr;
2504 RPC_HDR_AUTH hdr_auth;
2505 uint32 pad = 0;
2507 /* Create the request RPC_HDR */
2508 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2509 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2510 pauth_blob->length );
2512 /* Marshall it. */
2513 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2514 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2515 return NT_STATUS_NO_MEMORY;
2519 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2520 about padding - shouldn't this pad to length 8 ? JRA.
2523 /* 4 bytes padding. */
2524 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2525 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2526 return NT_STATUS_NO_MEMORY;
2529 /* Create the request RPC_HDR_AUTHA */
2530 init_rpc_hdr_auth(&hdr_auth,
2531 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2532 auth_level, 0, 1);
2534 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2535 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2536 return NT_STATUS_NO_MEMORY;
2540 * Append the auth data to the outgoing buffer.
2543 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2544 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2545 return NT_STATUS_NO_MEMORY;
2548 return NT_STATUS_OK;
2551 /*******************************************************************
2552 Creates a DCE/RPC bind alter context authentication request which
2553 may contain a spnego auth blobl
2554 ********************************************************************/
2556 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2557 const struct ndr_syntax_id *abstract,
2558 const struct ndr_syntax_id *transfer,
2559 enum dcerpc_AuthLevel auth_level,
2560 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2561 prs_struct *rpc_out)
2563 RPC_HDR_AUTH hdr_auth;
2564 prs_struct auth_info;
2565 NTSTATUS ret = NT_STATUS_OK;
2567 ZERO_STRUCT(hdr_auth);
2568 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2569 return NT_STATUS_NO_MEMORY;
2571 /* We may change the pad length before marshalling. */
2572 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2574 if (pauth_blob->length) {
2575 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2576 prs_mem_free(&auth_info);
2577 return NT_STATUS_NO_MEMORY;
2581 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2582 rpc_out,
2583 rpc_call_id,
2584 abstract,
2585 transfer,
2586 &hdr_auth,
2587 &auth_info);
2588 prs_mem_free(&auth_info);
2589 return ret;
2592 /****************************************************************************
2593 Do an rpc bind.
2594 ****************************************************************************/
2596 struct rpc_pipe_bind_state {
2597 struct event_context *ev;
2598 struct rpc_pipe_client *cli;
2599 prs_struct rpc_out;
2600 uint32_t rpc_call_id;
2603 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2605 prs_mem_free(&state->rpc_out);
2606 return 0;
2609 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2610 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2611 struct rpc_pipe_bind_state *state,
2612 struct rpc_hdr_info *phdr,
2613 prs_struct *reply_pdu);
2614 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2615 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2616 struct rpc_pipe_bind_state *state,
2617 struct rpc_hdr_info *phdr,
2618 prs_struct *reply_pdu);
2619 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2621 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2622 struct event_context *ev,
2623 struct rpc_pipe_client *cli,
2624 struct cli_pipe_auth_data *auth)
2626 struct tevent_req *req, *subreq;
2627 struct rpc_pipe_bind_state *state;
2628 NTSTATUS status;
2630 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2631 if (req == NULL) {
2632 return NULL;
2635 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2636 rpccli_pipe_txt(talloc_tos(), cli),
2637 (unsigned int)auth->auth_type,
2638 (unsigned int)auth->auth_level ));
2640 state->ev = ev;
2641 state->cli = cli;
2642 state->rpc_call_id = get_rpc_call_id();
2644 prs_init_empty(&state->rpc_out, state, MARSHALL);
2645 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2647 cli->auth = talloc_move(cli, &auth);
2649 /* Marshall the outgoing data. */
2650 status = create_rpc_bind_req(cli, &state->rpc_out,
2651 state->rpc_call_id,
2652 &cli->abstract_syntax,
2653 &cli->transfer_syntax,
2654 cli->auth->auth_type,
2655 cli->auth->auth_level);
2657 if (!NT_STATUS_IS_OK(status)) {
2658 goto post_status;
2661 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2662 DCERPC_PKT_BIND_ACK);
2663 if (subreq == NULL) {
2664 goto fail;
2666 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2667 return req;
2669 post_status:
2670 tevent_req_nterror(req, status);
2671 return tevent_req_post(req, ev);
2672 fail:
2673 TALLOC_FREE(req);
2674 return NULL;
2677 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2679 struct tevent_req *req = tevent_req_callback_data(
2680 subreq, struct tevent_req);
2681 struct rpc_pipe_bind_state *state = tevent_req_data(
2682 req, struct rpc_pipe_bind_state);
2683 prs_struct reply_pdu;
2684 struct rpc_hdr_info hdr;
2685 struct rpc_hdr_ba_info hdr_ba;
2686 NTSTATUS status;
2688 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2689 TALLOC_FREE(subreq);
2690 if (!NT_STATUS_IS_OK(status)) {
2691 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2692 rpccli_pipe_txt(talloc_tos(), state->cli),
2693 nt_errstr(status)));
2694 tevent_req_nterror(req, status);
2695 return;
2698 /* Unmarshall the RPC header */
2699 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2700 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2701 prs_mem_free(&reply_pdu);
2702 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2703 return;
2706 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2707 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2708 "RPC_HDR_BA.\n"));
2709 prs_mem_free(&reply_pdu);
2710 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2711 return;
2714 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2715 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2716 prs_mem_free(&reply_pdu);
2717 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2718 return;
2721 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2722 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2725 * For authenticated binds we may need to do 3 or 4 leg binds.
2728 switch(state->cli->auth->auth_type) {
2730 case PIPE_AUTH_TYPE_NONE:
2731 case PIPE_AUTH_TYPE_SCHANNEL:
2732 /* Bind complete. */
2733 prs_mem_free(&reply_pdu);
2734 tevent_req_done(req);
2735 break;
2737 case PIPE_AUTH_TYPE_NTLMSSP:
2738 /* Need to send AUTH3 packet - no reply. */
2739 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2740 &reply_pdu);
2741 prs_mem_free(&reply_pdu);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 tevent_req_nterror(req, status);
2745 break;
2747 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2748 /* Need to send alter context request and reply. */
2749 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2750 &reply_pdu);
2751 prs_mem_free(&reply_pdu);
2752 if (!NT_STATUS_IS_OK(status)) {
2753 tevent_req_nterror(req, status);
2755 break;
2757 case PIPE_AUTH_TYPE_KRB5:
2758 /* */
2760 default:
2761 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2762 (unsigned int)state->cli->auth->auth_type));
2763 prs_mem_free(&reply_pdu);
2764 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2768 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2769 struct rpc_pipe_bind_state *state,
2770 struct rpc_hdr_info *phdr,
2771 prs_struct *reply_pdu)
2773 DATA_BLOB server_response = data_blob_null;
2774 DATA_BLOB client_reply = data_blob_null;
2775 struct rpc_hdr_auth_info hdr_auth;
2776 struct tevent_req *subreq;
2777 NTSTATUS status;
2779 if ((phdr->auth_len == 0)
2780 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2781 return NT_STATUS_INVALID_PARAMETER;
2784 if (!prs_set_offset(
2785 reply_pdu,
2786 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2787 return NT_STATUS_INVALID_PARAMETER;
2790 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2791 return NT_STATUS_INVALID_PARAMETER;
2794 /* TODO - check auth_type/auth_level match. */
2796 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2797 prs_copy_data_out((char *)server_response.data, reply_pdu,
2798 phdr->auth_len);
2800 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2801 server_response, &client_reply);
2803 if (!NT_STATUS_IS_OK(status)) {
2804 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2805 "blob failed: %s.\n", nt_errstr(status)));
2806 return status;
2809 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2811 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2812 state->cli->auth->auth_type,
2813 state->cli->auth->auth_level,
2814 &client_reply, &state->rpc_out);
2815 data_blob_free(&client_reply);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 return status;
2821 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2822 (uint8_t *)prs_data_p(&state->rpc_out),
2823 prs_offset(&state->rpc_out));
2824 if (subreq == NULL) {
2825 return NT_STATUS_NO_MEMORY;
2827 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2828 return NT_STATUS_OK;
2831 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2833 struct tevent_req *req = tevent_req_callback_data(
2834 subreq, struct tevent_req);
2835 NTSTATUS status;
2837 status = rpc_write_recv(subreq);
2838 TALLOC_FREE(subreq);
2839 if (!NT_STATUS_IS_OK(status)) {
2840 tevent_req_nterror(req, status);
2841 return;
2843 tevent_req_done(req);
2846 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2847 struct rpc_pipe_bind_state *state,
2848 struct rpc_hdr_info *phdr,
2849 prs_struct *reply_pdu)
2851 DATA_BLOB server_spnego_response = data_blob_null;
2852 DATA_BLOB server_ntlm_response = data_blob_null;
2853 DATA_BLOB client_reply = data_blob_null;
2854 DATA_BLOB tmp_blob = data_blob_null;
2855 RPC_HDR_AUTH hdr_auth;
2856 struct tevent_req *subreq;
2857 NTSTATUS status;
2859 if ((phdr->auth_len == 0)
2860 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2861 return NT_STATUS_INVALID_PARAMETER;
2864 /* Process the returned NTLMSSP blob first. */
2865 if (!prs_set_offset(
2866 reply_pdu,
2867 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2868 return NT_STATUS_INVALID_PARAMETER;
2871 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2872 return NT_STATUS_INVALID_PARAMETER;
2875 server_spnego_response = data_blob(NULL, phdr->auth_len);
2876 prs_copy_data_out((char *)server_spnego_response.data,
2877 reply_pdu, phdr->auth_len);
2880 * The server might give us back two challenges - tmp_blob is for the
2881 * second.
2883 if (!spnego_parse_challenge(server_spnego_response,
2884 &server_ntlm_response, &tmp_blob)) {
2885 data_blob_free(&server_spnego_response);
2886 data_blob_free(&server_ntlm_response);
2887 data_blob_free(&tmp_blob);
2888 return NT_STATUS_INVALID_PARAMETER;
2891 /* We're finished with the server spnego response and the tmp_blob. */
2892 data_blob_free(&server_spnego_response);
2893 data_blob_free(&tmp_blob);
2895 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2896 server_ntlm_response, &client_reply);
2898 /* Finished with the server_ntlm response */
2899 data_blob_free(&server_ntlm_response);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2903 "using server blob failed.\n"));
2904 data_blob_free(&client_reply);
2905 return status;
2908 /* SPNEGO wrap the client reply. */
2909 tmp_blob = spnego_gen_auth(client_reply);
2910 data_blob_free(&client_reply);
2911 client_reply = tmp_blob;
2912 tmp_blob = data_blob_null;
2914 /* Now prepare the alter context pdu. */
2915 prs_init_empty(&state->rpc_out, state, MARSHALL);
2917 status = create_rpc_alter_context(state->rpc_call_id,
2918 &state->cli->abstract_syntax,
2919 &state->cli->transfer_syntax,
2920 state->cli->auth->auth_level,
2921 &client_reply,
2922 &state->rpc_out);
2923 data_blob_free(&client_reply);
2925 if (!NT_STATUS_IS_OK(status)) {
2926 return status;
2929 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2930 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2931 if (subreq == NULL) {
2932 return NT_STATUS_NO_MEMORY;
2934 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2935 return NT_STATUS_OK;
2938 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2940 struct tevent_req *req = tevent_req_callback_data(
2941 subreq, struct tevent_req);
2942 struct rpc_pipe_bind_state *state = tevent_req_data(
2943 req, struct rpc_pipe_bind_state);
2944 DATA_BLOB server_spnego_response = data_blob_null;
2945 DATA_BLOB tmp_blob = data_blob_null;
2946 prs_struct reply_pdu;
2947 struct rpc_hdr_info hdr;
2948 struct rpc_hdr_auth_info hdr_auth;
2949 NTSTATUS status;
2951 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2952 TALLOC_FREE(subreq);
2953 if (!NT_STATUS_IS_OK(status)) {
2954 tevent_req_nterror(req, status);
2955 return;
2958 /* Get the auth blob from the reply. */
2959 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2960 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2961 "unmarshall RPC_HDR.\n"));
2962 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2963 return;
2966 if (!prs_set_offset(
2967 &reply_pdu,
2968 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2969 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2970 return;
2973 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2974 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2975 return;
2978 server_spnego_response = data_blob(NULL, hdr.auth_len);
2979 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2980 hdr.auth_len);
2982 /* Check we got a valid auth response. */
2983 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2984 OID_NTLMSSP, &tmp_blob)) {
2985 data_blob_free(&server_spnego_response);
2986 data_blob_free(&tmp_blob);
2987 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2988 return;
2991 data_blob_free(&server_spnego_response);
2992 data_blob_free(&tmp_blob);
2994 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2995 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2996 tevent_req_done(req);
2999 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3001 return tevent_req_simple_recv_ntstatus(req);
3004 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3005 struct cli_pipe_auth_data *auth)
3007 TALLOC_CTX *frame = talloc_stackframe();
3008 struct event_context *ev;
3009 struct tevent_req *req;
3010 NTSTATUS status = NT_STATUS_OK;
3012 ev = event_context_init(frame);
3013 if (ev == NULL) {
3014 status = NT_STATUS_NO_MEMORY;
3015 goto fail;
3018 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3019 if (req == NULL) {
3020 status = NT_STATUS_NO_MEMORY;
3021 goto fail;
3024 if (!tevent_req_poll(req, ev)) {
3025 status = map_nt_error_from_unix(errno);
3026 goto fail;
3029 status = rpc_pipe_bind_recv(req);
3030 fail:
3031 TALLOC_FREE(frame);
3032 return status;
3035 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3036 unsigned int timeout)
3038 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
3040 if (cli == NULL) {
3041 return 0;
3043 return cli_set_timeout(cli, timeout);
3046 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3048 struct cli_state *cli;
3050 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3051 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3052 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3053 return true;
3056 cli = rpc_pipe_np_smb_conn(rpc_cli);
3057 if (cli == NULL) {
3058 return false;
3060 E_md4hash(cli->password ? cli->password : "", nt_hash);
3061 return true;
3064 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3065 struct cli_pipe_auth_data **presult)
3067 struct cli_pipe_auth_data *result;
3069 *presult = NULL;
3071 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3072 if (result == NULL) {
3073 return NT_STATUS_NO_MEMORY;
3076 result->auth_type = PIPE_AUTH_TYPE_NONE;
3077 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3079 result->user_name = talloc_strdup(result, "");
3080 result->domain = talloc_strdup(result, "");
3081 if ((result->user_name == NULL) || (result->domain == NULL)) {
3082 TALLOC_FREE(result);
3083 return NT_STATUS_NO_MEMORY;
3086 *presult = result;
3087 return NT_STATUS_OK;
3090 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3092 ntlmssp_end(&auth->a_u.ntlmssp_state);
3093 return 0;
3096 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3097 enum pipe_auth_type auth_type,
3098 enum dcerpc_AuthLevel auth_level,
3099 const char *domain,
3100 const char *username,
3101 const char *password,
3102 struct cli_pipe_auth_data **presult)
3104 struct cli_pipe_auth_data *result;
3105 NTSTATUS status;
3107 *presult = NULL;
3109 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3110 if (result == NULL) {
3111 return NT_STATUS_NO_MEMORY;
3114 result->auth_type = auth_type;
3115 result->auth_level = auth_level;
3117 result->user_name = talloc_strdup(result, username);
3118 result->domain = talloc_strdup(result, domain);
3119 if ((result->user_name == NULL) || (result->domain == NULL)) {
3120 status = NT_STATUS_NO_MEMORY;
3121 goto fail;
3124 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3125 if (!NT_STATUS_IS_OK(status)) {
3126 goto fail;
3129 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3131 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 goto fail;
3136 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3137 if (!NT_STATUS_IS_OK(status)) {
3138 goto fail;
3141 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3142 if (!NT_STATUS_IS_OK(status)) {
3143 goto fail;
3147 * Turn off sign+seal to allow selected auth level to turn it back on.
3149 result->a_u.ntlmssp_state->neg_flags &=
3150 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3152 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3153 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3154 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3155 result->a_u.ntlmssp_state->neg_flags
3156 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3159 *presult = result;
3160 return NT_STATUS_OK;
3162 fail:
3163 TALLOC_FREE(result);
3164 return status;
3167 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3168 enum dcerpc_AuthLevel auth_level,
3169 struct netlogon_creds_CredentialState *creds,
3170 struct cli_pipe_auth_data **presult)
3172 struct cli_pipe_auth_data *result;
3174 *presult = NULL;
3176 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3177 if (result == NULL) {
3178 return NT_STATUS_NO_MEMORY;
3181 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3182 result->auth_level = auth_level;
3184 result->user_name = talloc_strdup(result, "");
3185 result->domain = talloc_strdup(result, domain);
3186 if ((result->user_name == NULL) || (result->domain == NULL)) {
3187 goto fail;
3190 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3191 if (result->a_u.schannel_auth == NULL) {
3192 goto fail;
3195 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3196 result->a_u.schannel_auth->seq_num = 0;
3197 result->a_u.schannel_auth->initiator = true;
3198 result->a_u.schannel_auth->creds = creds;
3200 *presult = result;
3201 return NT_STATUS_OK;
3203 fail:
3204 TALLOC_FREE(result);
3205 return NT_STATUS_NO_MEMORY;
3208 #ifdef HAVE_KRB5
3209 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3211 data_blob_free(&auth->session_key);
3212 return 0;
3214 #endif
3216 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3217 enum dcerpc_AuthLevel auth_level,
3218 const char *service_princ,
3219 const char *username,
3220 const char *password,
3221 struct cli_pipe_auth_data **presult)
3223 #ifdef HAVE_KRB5
3224 struct cli_pipe_auth_data *result;
3226 *presult = NULL;
3228 if ((username != NULL) && (password != NULL)) {
3229 int ret = kerberos_kinit_password(username, password, 0, NULL);
3230 if (ret != 0) {
3231 return NT_STATUS_ACCESS_DENIED;
3235 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3236 if (result == NULL) {
3237 return NT_STATUS_NO_MEMORY;
3240 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3241 result->auth_level = auth_level;
3244 * Username / domain need fixing!
3246 result->user_name = talloc_strdup(result, "");
3247 result->domain = talloc_strdup(result, "");
3248 if ((result->user_name == NULL) || (result->domain == NULL)) {
3249 goto fail;
3252 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3253 result, struct kerberos_auth_struct);
3254 if (result->a_u.kerberos_auth == NULL) {
3255 goto fail;
3257 talloc_set_destructor(result->a_u.kerberos_auth,
3258 cli_auth_kerberos_data_destructor);
3260 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3261 result, service_princ);
3262 if (result->a_u.kerberos_auth->service_principal == NULL) {
3263 goto fail;
3266 *presult = result;
3267 return NT_STATUS_OK;
3269 fail:
3270 TALLOC_FREE(result);
3271 return NT_STATUS_NO_MEMORY;
3272 #else
3273 *presult = NULL;
3274 return NT_STATUS_NOT_SUPPORTED;
3275 #endif
3279 * Create an rpc pipe client struct, connecting to a tcp port.
3281 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3282 uint16_t port,
3283 const struct ndr_syntax_id *abstract_syntax,
3284 struct rpc_pipe_client **presult)
3286 struct rpc_pipe_client *result;
3287 struct sockaddr_storage addr;
3288 NTSTATUS status;
3289 int fd;
3291 *presult = NULL;
3293 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3294 if (result == NULL) {
3295 return NT_STATUS_NO_MEMORY;
3298 result->abstract_syntax = *abstract_syntax;
3299 result->transfer_syntax = ndr_transfer_syntax;
3300 result->dispatch = cli_do_rpc_ndr;
3301 result->dispatch_send = cli_do_rpc_ndr_send;
3302 result->dispatch_recv = cli_do_rpc_ndr_recv;
3304 result->desthost = talloc_strdup(result, host);
3305 result->srv_name_slash = talloc_asprintf_strupper_m(
3306 result, "\\\\%s", result->desthost);
3307 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3308 status = NT_STATUS_NO_MEMORY;
3309 goto fail;
3312 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3313 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3315 if (!resolve_name(host, &addr, 0, false)) {
3316 status = NT_STATUS_NOT_FOUND;
3317 goto fail;
3320 status = open_socket_out(&addr, port, 60, &fd);
3321 if (!NT_STATUS_IS_OK(status)) {
3322 goto fail;
3324 set_socket_options(fd, lp_socket_options());
3326 status = rpc_transport_sock_init(result, fd, &result->transport);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 close(fd);
3329 goto fail;
3332 result->transport->transport = NCACN_IP_TCP;
3334 *presult = result;
3335 return NT_STATUS_OK;
3337 fail:
3338 TALLOC_FREE(result);
3339 return status;
3343 * Determine the tcp port on which a dcerpc interface is listening
3344 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3345 * target host.
3347 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3348 const struct ndr_syntax_id *abstract_syntax,
3349 uint16_t *pport)
3351 NTSTATUS status;
3352 struct rpc_pipe_client *epm_pipe = NULL;
3353 struct cli_pipe_auth_data *auth = NULL;
3354 struct dcerpc_binding *map_binding = NULL;
3355 struct dcerpc_binding *res_binding = NULL;
3356 struct epm_twr_t *map_tower = NULL;
3357 struct epm_twr_t *res_towers = NULL;
3358 struct policy_handle *entry_handle = NULL;
3359 uint32_t num_towers = 0;
3360 uint32_t max_towers = 1;
3361 struct epm_twr_p_t towers;
3362 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3364 if (pport == NULL) {
3365 status = NT_STATUS_INVALID_PARAMETER;
3366 goto done;
3369 /* open the connection to the endpoint mapper */
3370 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3371 &ndr_table_epmapper.syntax_id,
3372 &epm_pipe);
3374 if (!NT_STATUS_IS_OK(status)) {
3375 goto done;
3378 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3379 if (!NT_STATUS_IS_OK(status)) {
3380 goto done;
3383 status = rpc_pipe_bind(epm_pipe, auth);
3384 if (!NT_STATUS_IS_OK(status)) {
3385 goto done;
3388 /* create tower for asking the epmapper */
3390 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3391 if (map_binding == NULL) {
3392 status = NT_STATUS_NO_MEMORY;
3393 goto done;
3396 map_binding->transport = NCACN_IP_TCP;
3397 map_binding->object = *abstract_syntax;
3398 map_binding->host = host; /* needed? */
3399 map_binding->endpoint = "0"; /* correct? needed? */
3401 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3402 if (map_tower == NULL) {
3403 status = NT_STATUS_NO_MEMORY;
3404 goto done;
3407 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3408 &(map_tower->tower));
3409 if (!NT_STATUS_IS_OK(status)) {
3410 goto done;
3413 /* allocate further parameters for the epm_Map call */
3415 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3416 if (res_towers == NULL) {
3417 status = NT_STATUS_NO_MEMORY;
3418 goto done;
3420 towers.twr = res_towers;
3422 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3423 if (entry_handle == NULL) {
3424 status = NT_STATUS_NO_MEMORY;
3425 goto done;
3428 /* ask the endpoint mapper for the port */
3430 status = rpccli_epm_Map(epm_pipe,
3431 tmp_ctx,
3432 CONST_DISCARD(struct GUID *,
3433 &(abstract_syntax->uuid)),
3434 map_tower,
3435 entry_handle,
3436 max_towers,
3437 &num_towers,
3438 &towers);
3440 if (!NT_STATUS_IS_OK(status)) {
3441 goto done;
3444 if (num_towers != 1) {
3445 status = NT_STATUS_UNSUCCESSFUL;
3446 goto done;
3449 /* extract the port from the answer */
3451 status = dcerpc_binding_from_tower(tmp_ctx,
3452 &(towers.twr->tower),
3453 &res_binding);
3454 if (!NT_STATUS_IS_OK(status)) {
3455 goto done;
3458 /* are further checks here necessary? */
3459 if (res_binding->transport != NCACN_IP_TCP) {
3460 status = NT_STATUS_UNSUCCESSFUL;
3461 goto done;
3464 *pport = (uint16_t)atoi(res_binding->endpoint);
3466 done:
3467 TALLOC_FREE(tmp_ctx);
3468 return status;
3472 * Create a rpc pipe client struct, connecting to a host via tcp.
3473 * The port is determined by asking the endpoint mapper on the given
3474 * host.
3476 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3477 const struct ndr_syntax_id *abstract_syntax,
3478 struct rpc_pipe_client **presult)
3480 NTSTATUS status;
3481 uint16_t port = 0;
3483 *presult = NULL;
3485 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3486 if (!NT_STATUS_IS_OK(status)) {
3487 goto done;
3490 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3491 abstract_syntax, presult);
3493 done:
3494 return status;
3497 /********************************************************************
3498 Create a rpc pipe client struct, connecting to a unix domain socket
3499 ********************************************************************/
3500 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3501 const struct ndr_syntax_id *abstract_syntax,
3502 struct rpc_pipe_client **presult)
3504 struct rpc_pipe_client *result;
3505 struct sockaddr_un addr;
3506 NTSTATUS status;
3507 int fd;
3509 *presult = NULL;
3511 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3512 if (result == NULL) {
3513 return NT_STATUS_NO_MEMORY;
3516 result->abstract_syntax = *abstract_syntax;
3517 result->transfer_syntax = ndr_transfer_syntax;
3518 result->dispatch = cli_do_rpc_ndr;
3519 result->dispatch_send = cli_do_rpc_ndr_send;
3520 result->dispatch_recv = cli_do_rpc_ndr_recv;
3522 result->desthost = get_myname(result);
3523 result->srv_name_slash = talloc_asprintf_strupper_m(
3524 result, "\\\\%s", result->desthost);
3525 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3526 status = NT_STATUS_NO_MEMORY;
3527 goto fail;
3530 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3531 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3533 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3534 if (fd == -1) {
3535 status = map_nt_error_from_unix(errno);
3536 goto fail;
3539 ZERO_STRUCT(addr);
3540 addr.sun_family = AF_UNIX;
3541 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3543 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3544 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3545 strerror(errno)));
3546 close(fd);
3547 return map_nt_error_from_unix(errno);
3550 status = rpc_transport_sock_init(result, fd, &result->transport);
3551 if (!NT_STATUS_IS_OK(status)) {
3552 close(fd);
3553 goto fail;
3556 result->transport->transport = NCALRPC;
3558 *presult = result;
3559 return NT_STATUS_OK;
3561 fail:
3562 TALLOC_FREE(result);
3563 return status;
3566 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3568 struct cli_state *cli;
3570 cli = rpc_pipe_np_smb_conn(p);
3571 if (cli != NULL) {
3572 DLIST_REMOVE(cli->pipe_list, p);
3574 return 0;
3577 /****************************************************************************
3578 Open a named pipe over SMB to a remote server.
3580 * CAVEAT CALLER OF THIS FUNCTION:
3581 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3582 * so be sure that this function is called AFTER any structure (vs pointer)
3583 * assignment of the cli. In particular, libsmbclient does structure
3584 * assignments of cli, which invalidates the data in the returned
3585 * rpc_pipe_client if this function is called before the structure assignment
3586 * of cli.
3588 ****************************************************************************/
3590 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3591 const struct ndr_syntax_id *abstract_syntax,
3592 struct rpc_pipe_client **presult)
3594 struct rpc_pipe_client *result;
3595 NTSTATUS status;
3597 *presult = NULL;
3599 /* sanity check to protect against crashes */
3601 if ( !cli ) {
3602 return NT_STATUS_INVALID_HANDLE;
3605 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3606 if (result == NULL) {
3607 return NT_STATUS_NO_MEMORY;
3610 result->abstract_syntax = *abstract_syntax;
3611 result->transfer_syntax = ndr_transfer_syntax;
3612 result->dispatch = cli_do_rpc_ndr;
3613 result->dispatch_send = cli_do_rpc_ndr_send;
3614 result->dispatch_recv = cli_do_rpc_ndr_recv;
3615 result->desthost = talloc_strdup(result, cli->desthost);
3616 result->srv_name_slash = talloc_asprintf_strupper_m(
3617 result, "\\\\%s", result->desthost);
3619 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3620 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3622 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3623 TALLOC_FREE(result);
3624 return NT_STATUS_NO_MEMORY;
3627 status = rpc_transport_np_init(result, cli, abstract_syntax,
3628 &result->transport);
3629 if (!NT_STATUS_IS_OK(status)) {
3630 TALLOC_FREE(result);
3631 return status;
3634 result->transport->transport = NCACN_NP;
3636 DLIST_ADD(cli->pipe_list, result);
3637 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3639 *presult = result;
3640 return NT_STATUS_OK;
3643 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3644 struct rpc_cli_smbd_conn *conn,
3645 const struct ndr_syntax_id *syntax,
3646 struct rpc_pipe_client **presult)
3648 struct rpc_pipe_client *result;
3649 struct cli_pipe_auth_data *auth;
3650 NTSTATUS status;
3652 *presult = NULL;
3654 result = talloc(mem_ctx, struct rpc_pipe_client);
3655 if (result == NULL) {
3656 return NT_STATUS_NO_MEMORY;
3658 result->abstract_syntax = *syntax;
3659 result->transfer_syntax = ndr_transfer_syntax;
3660 result->dispatch = cli_do_rpc_ndr;
3661 result->dispatch_send = cli_do_rpc_ndr_send;
3662 result->dispatch_recv = cli_do_rpc_ndr_recv;
3663 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3664 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3666 result->desthost = talloc_strdup(result, global_myname());
3667 result->srv_name_slash = talloc_asprintf_strupper_m(
3668 result, "\\\\%s", global_myname());
3669 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3670 TALLOC_FREE(result);
3671 return NT_STATUS_NO_MEMORY;
3674 status = rpc_transport_smbd_init(result, conn, syntax,
3675 &result->transport);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3678 nt_errstr(status)));
3679 TALLOC_FREE(result);
3680 return status;
3683 status = rpccli_anon_bind_data(result, &auth);
3684 if (!NT_STATUS_IS_OK(status)) {
3685 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3686 nt_errstr(status)));
3687 TALLOC_FREE(result);
3688 return status;
3691 status = rpc_pipe_bind(result, auth);
3692 if (!NT_STATUS_IS_OK(status)) {
3693 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3694 TALLOC_FREE(result);
3695 return status;
3698 result->transport->transport = NCACN_INTERNAL;
3700 *presult = result;
3701 return NT_STATUS_OK;
3704 /****************************************************************************
3705 Open a pipe to a remote server.
3706 ****************************************************************************/
3708 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3709 enum dcerpc_transport_t transport,
3710 const struct ndr_syntax_id *interface,
3711 struct rpc_pipe_client **presult)
3713 *presult = NULL;
3715 switch (transport) {
3716 case NCACN_IP_TCP:
3717 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3718 presult);
3719 case NCACN_NP:
3720 return rpc_pipe_open_np(cli, interface, presult);
3721 default:
3722 return NT_STATUS_NOT_IMPLEMENTED;
3726 /****************************************************************************
3727 Open a named pipe to an SMB server and bind anonymously.
3728 ****************************************************************************/
3730 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3731 enum dcerpc_transport_t transport,
3732 const struct ndr_syntax_id *interface,
3733 struct rpc_pipe_client **presult)
3735 struct rpc_pipe_client *result;
3736 struct cli_pipe_auth_data *auth;
3737 NTSTATUS status;
3739 *presult = NULL;
3741 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 return status;
3746 status = rpccli_anon_bind_data(result, &auth);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3749 nt_errstr(status)));
3750 TALLOC_FREE(result);
3751 return status;
3755 * This is a bit of an abstraction violation due to the fact that an
3756 * anonymous bind on an authenticated SMB inherits the user/domain
3757 * from the enclosing SMB creds
3760 TALLOC_FREE(auth->user_name);
3761 TALLOC_FREE(auth->domain);
3763 auth->user_name = talloc_strdup(auth, cli->user_name);
3764 auth->domain = talloc_strdup(auth, cli->domain);
3765 auth->user_session_key = data_blob_talloc(auth,
3766 cli->user_session_key.data,
3767 cli->user_session_key.length);
3769 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3770 TALLOC_FREE(result);
3771 return NT_STATUS_NO_MEMORY;
3774 status = rpc_pipe_bind(result, auth);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 int lvl = 0;
3777 if (ndr_syntax_id_equal(interface,
3778 &ndr_table_dssetup.syntax_id)) {
3779 /* non AD domains just don't have this pipe, avoid
3780 * level 0 statement in that case - gd */
3781 lvl = 3;
3783 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3784 "%s failed with error %s\n",
3785 get_pipe_name_from_syntax(talloc_tos(), interface),
3786 nt_errstr(status) ));
3787 TALLOC_FREE(result);
3788 return status;
3791 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3792 "%s and bound anonymously.\n",
3793 get_pipe_name_from_syntax(talloc_tos(), interface),
3794 cli->desthost));
3796 *presult = result;
3797 return NT_STATUS_OK;
3800 /****************************************************************************
3801 ****************************************************************************/
3803 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3804 const struct ndr_syntax_id *interface,
3805 struct rpc_pipe_client **presult)
3807 *presult = NULL;
3809 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3810 interface, presult);
3813 /****************************************************************************
3814 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3815 ****************************************************************************/
3817 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3818 const struct ndr_syntax_id *interface,
3819 enum dcerpc_transport_t transport,
3820 enum pipe_auth_type auth_type,
3821 enum dcerpc_AuthLevel auth_level,
3822 const char *domain,
3823 const char *username,
3824 const char *password,
3825 struct rpc_pipe_client **presult)
3827 struct rpc_pipe_client *result;
3828 struct cli_pipe_auth_data *auth;
3829 NTSTATUS status;
3831 *presult = NULL;
3833 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3834 if (!NT_STATUS_IS_OK(status)) {
3835 return status;
3838 status = rpccli_ntlmssp_bind_data(
3839 result, auth_type, auth_level, domain, username,
3840 password, &auth);
3841 if (!NT_STATUS_IS_OK(status)) {
3842 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3843 nt_errstr(status)));
3844 goto err;
3847 status = rpc_pipe_bind(result, auth);
3848 if (!NT_STATUS_IS_OK(status)) {
3849 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3850 nt_errstr(status) ));
3851 goto err;
3854 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3855 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3856 get_pipe_name_from_syntax(talloc_tos(), interface),
3857 cli->desthost, domain, username ));
3859 *presult = result;
3860 return NT_STATUS_OK;
3862 err:
3864 TALLOC_FREE(result);
3865 return status;
3868 /****************************************************************************
3869 External interface.
3870 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3871 ****************************************************************************/
3873 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3874 const struct ndr_syntax_id *interface,
3875 enum dcerpc_transport_t transport,
3876 enum dcerpc_AuthLevel auth_level,
3877 const char *domain,
3878 const char *username,
3879 const char *password,
3880 struct rpc_pipe_client **presult)
3882 *presult = NULL;
3884 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3885 interface,
3886 transport,
3887 PIPE_AUTH_TYPE_NTLMSSP,
3888 auth_level,
3889 domain,
3890 username,
3891 password,
3892 presult);
3895 /****************************************************************************
3896 External interface.
3897 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3898 ****************************************************************************/
3900 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3901 const struct ndr_syntax_id *interface,
3902 enum dcerpc_transport_t transport,
3903 enum dcerpc_AuthLevel auth_level,
3904 const char *domain,
3905 const char *username,
3906 const char *password,
3907 struct rpc_pipe_client **presult)
3909 *presult = NULL;
3911 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3912 interface,
3913 transport,
3914 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3915 auth_level,
3916 domain,
3917 username,
3918 password,
3919 presult);
3922 /****************************************************************************
3923 Get a the schannel session key out of an already opened netlogon pipe.
3924 ****************************************************************************/
3925 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3926 struct cli_state *cli,
3927 const char *domain,
3928 uint32 *pneg_flags)
3930 enum netr_SchannelType sec_chan_type = 0;
3931 unsigned char machine_pwd[16];
3932 const char *machine_account;
3933 NTSTATUS status;
3935 /* Get the machine account credentials from secrets.tdb. */
3936 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3937 &sec_chan_type))
3939 DEBUG(0, ("get_schannel_session_key: could not fetch "
3940 "trust account password for domain '%s'\n",
3941 domain));
3942 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3945 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3946 cli->desthost, /* server name */
3947 domain, /* domain */
3948 global_myname(), /* client name */
3949 machine_account, /* machine account name */
3950 machine_pwd,
3951 sec_chan_type,
3952 pneg_flags);
3954 if (!NT_STATUS_IS_OK(status)) {
3955 DEBUG(3, ("get_schannel_session_key_common: "
3956 "rpccli_netlogon_setup_creds failed with result %s "
3957 "to server %s, domain %s, machine account %s.\n",
3958 nt_errstr(status), cli->desthost, domain,
3959 machine_account ));
3960 return status;
3963 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3964 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3965 cli->desthost));
3966 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3969 return NT_STATUS_OK;;
3972 /****************************************************************************
3973 Open a netlogon pipe and get the schannel session key.
3974 Now exposed to external callers.
3975 ****************************************************************************/
3978 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3979 const char *domain,
3980 uint32 *pneg_flags,
3981 struct rpc_pipe_client **presult)
3983 struct rpc_pipe_client *netlogon_pipe = NULL;
3984 NTSTATUS status;
3986 *presult = NULL;
3988 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3989 &netlogon_pipe);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 return status;
3994 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3995 pneg_flags);
3996 if (!NT_STATUS_IS_OK(status)) {
3997 TALLOC_FREE(netlogon_pipe);
3998 return status;
4001 *presult = netlogon_pipe;
4002 return NT_STATUS_OK;
4005 /****************************************************************************
4006 External interface.
4007 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4008 using session_key. sign and seal.
4010 The *pdc will be stolen onto this new pipe
4011 ****************************************************************************/
4013 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4014 const struct ndr_syntax_id *interface,
4015 enum dcerpc_transport_t transport,
4016 enum dcerpc_AuthLevel auth_level,
4017 const char *domain,
4018 struct netlogon_creds_CredentialState **pdc,
4019 struct rpc_pipe_client **presult)
4021 struct rpc_pipe_client *result;
4022 struct cli_pipe_auth_data *auth;
4023 NTSTATUS status;
4025 *presult = NULL;
4027 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4028 if (!NT_STATUS_IS_OK(status)) {
4029 return status;
4032 status = rpccli_schannel_bind_data(result, domain, auth_level,
4033 *pdc, &auth);
4034 if (!NT_STATUS_IS_OK(status)) {
4035 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4036 nt_errstr(status)));
4037 TALLOC_FREE(result);
4038 return status;
4041 status = rpc_pipe_bind(result, auth);
4042 if (!NT_STATUS_IS_OK(status)) {
4043 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4044 "cli_rpc_pipe_bind failed with error %s\n",
4045 nt_errstr(status) ));
4046 TALLOC_FREE(result);
4047 return status;
4051 * The credentials on a new netlogon pipe are the ones we are passed
4052 * in - reference them in
4054 result->dc = talloc_move(result, pdc);
4056 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4057 "for domain %s and bound using schannel.\n",
4058 get_pipe_name_from_syntax(talloc_tos(), interface),
4059 cli->desthost, domain ));
4061 *presult = result;
4062 return NT_STATUS_OK;
4065 /****************************************************************************
4066 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4067 Fetch the session key ourselves using a temporary netlogon pipe. This
4068 version uses an ntlmssp auth bound netlogon pipe to get the key.
4069 ****************************************************************************/
4071 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4072 const char *domain,
4073 const char *username,
4074 const char *password,
4075 uint32 *pneg_flags,
4076 struct rpc_pipe_client **presult)
4078 struct rpc_pipe_client *netlogon_pipe = NULL;
4079 NTSTATUS status;
4081 *presult = NULL;
4083 status = cli_rpc_pipe_open_spnego_ntlmssp(
4084 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4085 DCERPC_AUTH_LEVEL_PRIVACY,
4086 domain, username, password, &netlogon_pipe);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 return status;
4091 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4092 pneg_flags);
4093 if (!NT_STATUS_IS_OK(status)) {
4094 TALLOC_FREE(netlogon_pipe);
4095 return status;
4098 *presult = netlogon_pipe;
4099 return NT_STATUS_OK;
4102 /****************************************************************************
4103 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4104 Fetch the session key ourselves using a temporary netlogon pipe. This version
4105 uses an ntlmssp bind to get the session key.
4106 ****************************************************************************/
4108 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4109 const struct ndr_syntax_id *interface,
4110 enum dcerpc_transport_t transport,
4111 enum dcerpc_AuthLevel auth_level,
4112 const char *domain,
4113 const char *username,
4114 const char *password,
4115 struct rpc_pipe_client **presult)
4117 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4118 struct rpc_pipe_client *netlogon_pipe = NULL;
4119 struct rpc_pipe_client *result = NULL;
4120 NTSTATUS status;
4122 *presult = NULL;
4124 status = get_schannel_session_key_auth_ntlmssp(
4125 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4128 "key from server %s for domain %s.\n",
4129 cli->desthost, domain ));
4130 return status;
4133 status = cli_rpc_pipe_open_schannel_with_key(
4134 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4135 &result);
4137 /* Now we've bound using the session key we can close the netlog pipe. */
4138 TALLOC_FREE(netlogon_pipe);
4140 if (NT_STATUS_IS_OK(status)) {
4141 *presult = result;
4143 return status;
4146 /****************************************************************************
4147 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4148 Fetch the session key ourselves using a temporary netlogon pipe.
4149 ****************************************************************************/
4151 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4152 const struct ndr_syntax_id *interface,
4153 enum dcerpc_transport_t transport,
4154 enum dcerpc_AuthLevel auth_level,
4155 const char *domain,
4156 struct rpc_pipe_client **presult)
4158 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4159 struct rpc_pipe_client *netlogon_pipe = NULL;
4160 struct rpc_pipe_client *result = NULL;
4161 NTSTATUS status;
4163 *presult = NULL;
4165 status = get_schannel_session_key(cli, domain, &neg_flags,
4166 &netlogon_pipe);
4167 if (!NT_STATUS_IS_OK(status)) {
4168 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4169 "key from server %s for domain %s.\n",
4170 cli->desthost, domain ));
4171 return status;
4174 status = cli_rpc_pipe_open_schannel_with_key(
4175 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4176 &result);
4178 /* Now we've bound using the session key we can close the netlog pipe. */
4179 TALLOC_FREE(netlogon_pipe);
4181 if (NT_STATUS_IS_OK(status)) {
4182 *presult = result;
4185 return status;
4188 /****************************************************************************
4189 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4190 The idea is this can be called with service_princ, username and password all
4191 NULL so long as the caller has a TGT.
4192 ****************************************************************************/
4194 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4195 const struct ndr_syntax_id *interface,
4196 enum dcerpc_AuthLevel auth_level,
4197 const char *service_princ,
4198 const char *username,
4199 const char *password,
4200 struct rpc_pipe_client **presult)
4202 #ifdef HAVE_KRB5
4203 struct rpc_pipe_client *result;
4204 struct cli_pipe_auth_data *auth;
4205 NTSTATUS status;
4207 *presult = NULL;
4209 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4210 if (!NT_STATUS_IS_OK(status)) {
4211 return status;
4214 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4215 username, password, &auth);
4216 if (!NT_STATUS_IS_OK(status)) {
4217 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4218 nt_errstr(status)));
4219 TALLOC_FREE(result);
4220 return status;
4223 status = rpc_pipe_bind(result, auth);
4224 if (!NT_STATUS_IS_OK(status)) {
4225 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4226 "with error %s\n", nt_errstr(status)));
4227 TALLOC_FREE(result);
4228 return status;
4231 *presult = result;
4232 return NT_STATUS_OK;
4233 #else
4234 *presult = NULL;
4235 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4236 return NT_STATUS_NOT_IMPLEMENTED;
4237 #endif
4240 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4241 struct rpc_pipe_client *cli,
4242 DATA_BLOB *session_key)
4244 if (!session_key || !cli) {
4245 return NT_STATUS_INVALID_PARAMETER;
4248 if (!cli->auth) {
4249 return NT_STATUS_INVALID_PARAMETER;
4252 switch (cli->auth->auth_type) {
4253 case PIPE_AUTH_TYPE_SCHANNEL:
4254 *session_key = data_blob_talloc(mem_ctx,
4255 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4256 break;
4257 case PIPE_AUTH_TYPE_NTLMSSP:
4258 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4259 *session_key = data_blob_talloc(mem_ctx,
4260 cli->auth->a_u.ntlmssp_state->session_key.data,
4261 cli->auth->a_u.ntlmssp_state->session_key.length);
4262 break;
4263 case PIPE_AUTH_TYPE_KRB5:
4264 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4265 *session_key = data_blob_talloc(mem_ctx,
4266 cli->auth->a_u.kerberos_auth->session_key.data,
4267 cli->auth->a_u.kerberos_auth->session_key.length);
4268 break;
4269 case PIPE_AUTH_TYPE_NONE:
4270 *session_key = data_blob_talloc(mem_ctx,
4271 cli->auth->user_session_key.data,
4272 cli->auth->user_session_key.length);
4273 break;
4274 default:
4275 return NT_STATUS_NO_USER_SESSION_KEY;
4278 return NT_STATUS_OK;