2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
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/>.
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"
28 #define DBGC_CLASS DBGC_RPC_CLI
30 /*******************************************************************
31 interface/version dce/rpc pipe identification
32 ********************************************************************/
34 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
35 #define PIPE_SAMR "\\PIPE\\samr"
36 #define PIPE_WINREG "\\PIPE\\winreg"
37 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
38 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
39 #define PIPE_NTLSA "\\PIPE\\ntlsa"
40 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
41 #define PIPE_LSASS "\\PIPE\\lsass"
42 #define PIPE_LSARPC "\\PIPE\\lsarpc"
43 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
44 #define PIPE_NETDFS "\\PIPE\\netdfs"
45 #define PIPE_ECHO "\\PIPE\\rpcecho"
46 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
47 #define PIPE_EPM "\\PIPE\\epmapper"
48 #define PIPE_SVCCTL "\\PIPE\\svcctl"
49 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
50 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
51 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
54 * IMPORTANT!! If you update this structure, make sure to
55 * update the index #defines in smb.h.
58 static const struct pipe_id_info {
59 /* the names appear not to matter: the syntaxes _do_ matter */
61 const char *client_pipe;
62 const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
65 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
66 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
67 { PIPE_SAMR, &ndr_table_samr.syntax_id },
68 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
69 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
70 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
71 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
72 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
73 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
74 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
75 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
76 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
77 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
78 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
79 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
80 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
84 /****************************************************************************
85 Return the pipe name from the interface.
86 ****************************************************************************/
88 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
93 for (i = 0; pipe_names[i].client_pipe; i++) {
94 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
96 return &pipe_names[i].client_pipe[5];
101 * Here we should ask \\epmapper, but for now our code is only
102 * interested in the known pipes mentioned in pipe_names[]
105 guid_str = GUID_string(talloc_tos(), &interface->uuid);
106 if (guid_str == NULL) {
109 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
110 (int)interface->if_version);
111 TALLOC_FREE(guid_str);
113 if (result == NULL) {
119 /********************************************************************
120 Map internal value to wire value.
121 ********************************************************************/
123 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
127 case PIPE_AUTH_TYPE_NONE:
128 return DCERPC_AUTH_TYPE_NONE;
130 case PIPE_AUTH_TYPE_NTLMSSP:
131 return DCERPC_AUTH_TYPE_NTLMSSP;
133 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
134 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
135 return DCERPC_AUTH_TYPE_SPNEGO;
137 case PIPE_AUTH_TYPE_SCHANNEL:
138 return DCERPC_AUTH_TYPE_SCHANNEL;
140 case PIPE_AUTH_TYPE_KRB5:
141 return DCERPC_AUTH_TYPE_KRB5;
144 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
146 (unsigned int)auth_type ));
152 /********************************************************************
153 Pipe description for a DEBUG
154 ********************************************************************/
155 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
156 struct rpc_pipe_client *cli)
158 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
159 if (result == NULL) {
165 /********************************************************************
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
176 * Realloc pdu to have a least "size" bytes
179 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
183 if (prs_data_size(pdu) >= size) {
187 extra_size = size - prs_data_size(pdu);
189 if (!prs_force_grow(pdu, extra_size)) {
190 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
191 "%d bytes.\n", (int)extra_size));
195 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
196 (int)extra_size, prs_data_size(pdu)));
201 /*******************************************************************
202 Use SMBreadX to get rest of one fragment's worth of rpc data.
203 Reads the whole size or give an error message
204 ********************************************************************/
206 struct rpc_read_state {
207 struct event_context *ev;
208 struct rpc_cli_transport *transport;
214 static void rpc_read_done(struct tevent_req *subreq);
216 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
217 struct event_context *ev,
218 struct rpc_cli_transport *transport,
219 uint8_t *data, size_t size)
221 struct tevent_req *req, *subreq;
222 struct rpc_read_state *state;
224 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
229 state->transport = transport;
234 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
236 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
238 if (subreq == NULL) {
241 tevent_req_set_callback(subreq, rpc_read_done, req);
249 static void rpc_read_done(struct tevent_req *subreq)
251 struct tevent_req *req = tevent_req_callback_data(
252 subreq, struct tevent_req);
253 struct rpc_read_state *state = tevent_req_data(
254 req, struct rpc_read_state);
258 status = state->transport->read_recv(subreq, &received);
260 if (!NT_STATUS_IS_OK(status)) {
261 tevent_req_nterror(req, status);
265 state->num_read += received;
266 if (state->num_read == state->size) {
267 tevent_req_done(req);
271 subreq = state->transport->read_send(state, state->ev,
272 state->data + state->num_read,
273 state->size - state->num_read,
274 state->transport->priv);
275 if (tevent_req_nomem(subreq, req)) {
278 tevent_req_set_callback(subreq, rpc_read_done, req);
281 static NTSTATUS rpc_read_recv(struct tevent_req *req)
283 return tevent_req_simple_recv_ntstatus(req);
286 struct rpc_write_state {
287 struct event_context *ev;
288 struct rpc_cli_transport *transport;
294 static void rpc_write_done(struct tevent_req *subreq);
296 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
297 struct event_context *ev,
298 struct rpc_cli_transport *transport,
299 const uint8_t *data, size_t size)
301 struct tevent_req *req, *subreq;
302 struct rpc_write_state *state;
304 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
309 state->transport = transport;
312 state->num_written = 0;
314 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
316 subreq = transport->write_send(state, ev, data, size, transport->priv);
317 if (subreq == NULL) {
320 tevent_req_set_callback(subreq, rpc_write_done, req);
327 static void rpc_write_done(struct tevent_req *subreq)
329 struct tevent_req *req = tevent_req_callback_data(
330 subreq, struct tevent_req);
331 struct rpc_write_state *state = tevent_req_data(
332 req, struct rpc_write_state);
336 status = state->transport->write_recv(subreq, &written);
338 if (!NT_STATUS_IS_OK(status)) {
339 tevent_req_nterror(req, status);
343 state->num_written += written;
345 if (state->num_written == state->size) {
346 tevent_req_done(req);
350 subreq = state->transport->write_send(state, state->ev,
351 state->data + state->num_written,
352 state->size - state->num_written,
353 state->transport->priv);
354 if (tevent_req_nomem(subreq, req)) {
357 tevent_req_set_callback(subreq, rpc_write_done, req);
360 static NTSTATUS rpc_write_recv(struct tevent_req *req)
362 return tevent_req_simple_recv_ntstatus(req);
366 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
367 struct rpc_hdr_info *prhdr,
371 * This next call sets the endian bit correctly in current_pdu. We
372 * will propagate this to rbuf later.
375 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
376 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
377 return NT_STATUS_BUFFER_TOO_SMALL;
380 if (prhdr->frag_len > cli->max_recv_frag) {
381 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
382 " we only allow %d\n", (int)prhdr->frag_len,
383 (int)cli->max_recv_frag));
384 return NT_STATUS_BUFFER_TOO_SMALL;
390 /****************************************************************************
391 Try and get a PDU's worth of data from current_pdu. If not, then read more
393 ****************************************************************************/
395 struct get_complete_frag_state {
396 struct event_context *ev;
397 struct rpc_pipe_client *cli;
398 struct rpc_hdr_info *prhdr;
402 static void get_complete_frag_got_header(struct tevent_req *subreq);
403 static void get_complete_frag_got_rest(struct tevent_req *subreq);
405 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
406 struct event_context *ev,
407 struct rpc_pipe_client *cli,
408 struct rpc_hdr_info *prhdr,
411 struct tevent_req *req, *subreq;
412 struct get_complete_frag_state *state;
416 req = tevent_req_create(mem_ctx, &state,
417 struct get_complete_frag_state);
423 state->prhdr = prhdr;
426 pdu_len = prs_data_size(pdu);
427 if (pdu_len < RPC_HEADER_LEN) {
428 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
429 status = NT_STATUS_NO_MEMORY;
432 subreq = rpc_read_send(
434 state->cli->transport,
435 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
436 RPC_HEADER_LEN - pdu_len);
437 if (subreq == NULL) {
438 status = NT_STATUS_NO_MEMORY;
441 tevent_req_set_callback(subreq, get_complete_frag_got_header,
446 status = parse_rpc_header(cli, prhdr, pdu);
447 if (!NT_STATUS_IS_OK(status)) {
452 * Ensure we have frag_len bytes of data.
454 if (pdu_len < prhdr->frag_len) {
455 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
456 status = NT_STATUS_NO_MEMORY;
459 subreq = rpc_read_send(state, state->ev,
460 state->cli->transport,
461 (uint8_t *)(prs_data_p(pdu) + pdu_len),
462 prhdr->frag_len - pdu_len);
463 if (subreq == NULL) {
464 status = NT_STATUS_NO_MEMORY;
467 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
472 status = NT_STATUS_OK;
474 if (NT_STATUS_IS_OK(status)) {
475 tevent_req_done(req);
477 tevent_req_nterror(req, status);
479 return tevent_req_post(req, ev);
482 static void get_complete_frag_got_header(struct tevent_req *subreq)
484 struct tevent_req *req = tevent_req_callback_data(
485 subreq, struct tevent_req);
486 struct get_complete_frag_state *state = tevent_req_data(
487 req, struct get_complete_frag_state);
490 status = rpc_read_recv(subreq);
492 if (!NT_STATUS_IS_OK(status)) {
493 tevent_req_nterror(req, status);
497 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
498 if (!NT_STATUS_IS_OK(status)) {
499 tevent_req_nterror(req, status);
503 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
504 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
509 * We're here in this piece of code because we've read exactly
510 * RPC_HEADER_LEN bytes into state->pdu.
513 subreq = rpc_read_send(
514 state, state->ev, state->cli->transport,
515 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
516 state->prhdr->frag_len - RPC_HEADER_LEN);
517 if (tevent_req_nomem(subreq, req)) {
520 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
523 static void get_complete_frag_got_rest(struct tevent_req *subreq)
525 struct tevent_req *req = tevent_req_callback_data(
526 subreq, struct tevent_req);
529 status = rpc_read_recv(subreq);
531 if (!NT_STATUS_IS_OK(status)) {
532 tevent_req_nterror(req, status);
535 tevent_req_done(req);
538 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
540 return tevent_req_simple_recv_ntstatus(req);
543 /****************************************************************************
544 NTLMSSP specific sign/seal.
545 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
546 In fact I should probably abstract these into identical pieces of code... JRA.
547 ****************************************************************************/
549 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
550 prs_struct *current_pdu,
551 uint8 *p_ss_padding_len)
553 RPC_HDR_AUTH auth_info;
554 uint32 save_offset = prs_offset(current_pdu);
555 uint32 auth_len = prhdr->auth_len;
556 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
557 unsigned char *data = NULL;
559 unsigned char *full_packet_data = NULL;
560 size_t full_packet_data_len;
564 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
565 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
569 if (!ntlmssp_state) {
570 return NT_STATUS_INVALID_PARAMETER;
573 /* Ensure there's enough data for an authenticated response. */
574 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
575 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
576 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
577 (unsigned int)auth_len ));
578 return NT_STATUS_BUFFER_TOO_SMALL;
582 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
583 * after the RPC header.
584 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
585 * functions as NTLMv2 checks the rpc headers also.
588 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
589 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
591 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
592 full_packet_data_len = prhdr->frag_len - auth_len;
594 /* Pull the auth header and the following data into a blob. */
595 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
596 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
597 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
598 return NT_STATUS_BUFFER_TOO_SMALL;
601 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
602 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
603 return NT_STATUS_BUFFER_TOO_SMALL;
606 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
607 auth_blob.length = auth_len;
609 switch (cli->auth->auth_level) {
610 case DCERPC_AUTH_LEVEL_PRIVACY:
611 /* Data is encrypted. */
612 status = ntlmssp_unseal_packet(ntlmssp_state,
615 full_packet_data_len,
617 if (!NT_STATUS_IS_OK(status)) {
618 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
619 "packet from %s. Error was %s.\n",
620 rpccli_pipe_txt(debug_ctx(), cli),
621 nt_errstr(status) ));
625 case DCERPC_AUTH_LEVEL_INTEGRITY:
626 /* Data is signed. */
627 status = ntlmssp_check_packet(ntlmssp_state,
630 full_packet_data_len,
632 if (!NT_STATUS_IS_OK(status)) {
633 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
634 "packet from %s. Error was %s.\n",
635 rpccli_pipe_txt(debug_ctx(), cli),
636 nt_errstr(status) ));
641 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
642 "auth level %d\n", cli->auth->auth_level));
643 return NT_STATUS_INVALID_INFO_CLASS;
647 * Return the current pointer to the data offset.
650 if(!prs_set_offset(current_pdu, save_offset)) {
651 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
652 (unsigned int)save_offset ));
653 return NT_STATUS_BUFFER_TOO_SMALL;
657 * Remember the padding length. We must remove it from the real data
658 * stream once the sign/seal is done.
661 *p_ss_padding_len = auth_info.auth_pad_len;
666 /****************************************************************************
667 schannel specific sign/seal.
668 ****************************************************************************/
670 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
671 prs_struct *current_pdu,
672 uint8 *p_ss_padding_len)
674 RPC_HDR_AUTH auth_info;
675 uint32 auth_len = prhdr->auth_len;
676 uint32 save_offset = prs_offset(current_pdu);
677 struct schannel_state *schannel_auth =
678 cli->auth->a_u.schannel_auth;
683 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
684 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
688 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
689 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
690 return NT_STATUS_INVALID_PARAMETER;
693 if (!schannel_auth) {
694 return NT_STATUS_INVALID_PARAMETER;
697 /* Ensure there's enough data for an authenticated response. */
698 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
699 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
700 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
701 (unsigned int)auth_len ));
702 return NT_STATUS_INVALID_PARAMETER;
705 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
707 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
708 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
709 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
710 return NT_STATUS_BUFFER_TOO_SMALL;
713 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
714 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
715 return NT_STATUS_BUFFER_TOO_SMALL;
718 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
719 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
720 auth_info.auth_type));
721 return NT_STATUS_BUFFER_TOO_SMALL;
724 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
726 if (DEBUGLEVEL >= 10) {
727 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
730 switch (cli->auth->auth_level) {
731 case DCERPC_AUTH_LEVEL_PRIVACY:
732 status = schannel_unseal_packet(schannel_auth,
734 (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
738 case DCERPC_AUTH_LEVEL_INTEGRITY:
739 status = schannel_check_packet(schannel_auth,
741 (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
746 status = NT_STATUS_INTERNAL_ERROR;
750 if (!NT_STATUS_IS_OK(status)) {
751 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
752 "Connection to %s (%s).\n",
753 rpccli_pipe_txt(debug_ctx(), cli),
755 return NT_STATUS_INVALID_PARAMETER;
759 * Return the current pointer to the data offset.
762 if(!prs_set_offset(current_pdu, save_offset)) {
763 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
764 (unsigned int)save_offset ));
765 return NT_STATUS_BUFFER_TOO_SMALL;
769 * Remember the padding length. We must remove it from the real data
770 * stream once the sign/seal is done.
773 *p_ss_padding_len = auth_info.auth_pad_len;
778 /****************************************************************************
779 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
780 ****************************************************************************/
782 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
783 prs_struct *current_pdu,
784 uint8 *p_ss_padding_len)
786 NTSTATUS ret = NT_STATUS_OK;
788 /* Paranioa checks for auth_len. */
789 if (prhdr->auth_len) {
790 if (prhdr->auth_len > prhdr->frag_len) {
791 return NT_STATUS_INVALID_PARAMETER;
794 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
795 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
796 /* Integer wrap attempt. */
797 return NT_STATUS_INVALID_PARAMETER;
802 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
805 switch(cli->auth->auth_type) {
806 case PIPE_AUTH_TYPE_NONE:
807 if (prhdr->auth_len) {
808 DEBUG(3, ("cli_pipe_validate_rpc_response: "
809 "Connection to %s - got non-zero "
811 rpccli_pipe_txt(debug_ctx(), cli),
812 (unsigned int)prhdr->auth_len ));
813 return NT_STATUS_INVALID_PARAMETER;
817 case PIPE_AUTH_TYPE_NTLMSSP:
818 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
819 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
820 if (!NT_STATUS_IS_OK(ret)) {
825 case PIPE_AUTH_TYPE_SCHANNEL:
826 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
827 if (!NT_STATUS_IS_OK(ret)) {
832 case PIPE_AUTH_TYPE_KRB5:
833 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
835 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
836 "to %s - unknown internal auth type %u.\n",
837 rpccli_pipe_txt(debug_ctx(), cli),
838 cli->auth->auth_type ));
839 return NT_STATUS_INVALID_INFO_CLASS;
845 /****************************************************************************
846 Do basic authentication checks on an incoming pdu.
847 ****************************************************************************/
849 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
850 prs_struct *current_pdu,
851 uint8 expected_pkt_type,
854 prs_struct *return_data)
857 NTSTATUS ret = NT_STATUS_OK;
858 uint32 current_pdu_len = prs_data_size(current_pdu);
860 if (current_pdu_len != prhdr->frag_len) {
861 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
862 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
863 return NT_STATUS_INVALID_PARAMETER;
867 * Point the return values at the real data including the RPC
868 * header. Just in case the caller wants it.
870 *ppdata = prs_data_p(current_pdu);
871 *pdata_len = current_pdu_len;
873 /* Ensure we have the correct type. */
874 switch (prhdr->pkt_type) {
875 case RPC_ALTCONTRESP:
878 /* Alter context and bind ack share the same packet definitions. */
884 RPC_HDR_RESP rhdr_resp;
885 uint8 ss_padding_len = 0;
887 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
888 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
889 return NT_STATUS_BUFFER_TOO_SMALL;
892 /* Here's where we deal with incoming sign/seal. */
893 ret = cli_pipe_validate_rpc_response(cli, prhdr,
894 current_pdu, &ss_padding_len);
895 if (!NT_STATUS_IS_OK(ret)) {
899 /* Point the return values at the NDR data. Remember to remove any ss padding. */
900 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
902 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
903 return NT_STATUS_BUFFER_TOO_SMALL;
906 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
908 /* Remember to remove the auth footer. */
909 if (prhdr->auth_len) {
910 /* We've already done integer wrap tests on auth_len in
911 cli_pipe_validate_rpc_response(). */
912 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
913 return NT_STATUS_BUFFER_TOO_SMALL;
915 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
918 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
919 current_pdu_len, *pdata_len, ss_padding_len ));
922 * If this is the first reply, and the allocation hint is reasonably, try and
923 * set up the return_data parse_struct to the correct size.
926 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
927 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
928 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
929 "too large to allocate\n",
930 (unsigned int)rhdr_resp.alloc_hint ));
931 return NT_STATUS_NO_MEMORY;
939 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
940 "received from %s!\n",
941 rpccli_pipe_txt(debug_ctx(), cli)));
942 /* Use this for now... */
943 return NT_STATUS_NETWORK_ACCESS_DENIED;
947 RPC_HDR_RESP rhdr_resp;
948 RPC_HDR_FAULT fault_resp;
950 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
951 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
952 return NT_STATUS_BUFFER_TOO_SMALL;
955 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
956 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
957 return NT_STATUS_BUFFER_TOO_SMALL;
960 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
961 "code %s received from %s!\n",
962 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
963 rpccli_pipe_txt(debug_ctx(), cli)));
964 if (NT_STATUS_IS_OK(fault_resp.status)) {
965 return NT_STATUS_UNSUCCESSFUL;
967 return fault_resp.status;
972 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
974 (unsigned int)prhdr->pkt_type,
975 rpccli_pipe_txt(debug_ctx(), cli)));
976 return NT_STATUS_INVALID_INFO_CLASS;
979 if (prhdr->pkt_type != expected_pkt_type) {
980 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
981 "got an unexpected RPC packet type - %u, not %u\n",
982 rpccli_pipe_txt(debug_ctx(), cli),
985 return NT_STATUS_INVALID_INFO_CLASS;
988 /* Do this just before return - we don't want to modify any rpc header
989 data before now as we may have needed to do cryptographic actions on
992 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
993 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
994 "setting fragment first/last ON.\n"));
995 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
1001 /****************************************************************************
1002 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1003 Normally the frag_len and buffer size will match, but on the first trans
1004 reply there is a theoretical chance that buffer size > frag_len, so we must
1006 ****************************************************************************/
1008 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1010 uint32 current_pdu_len = prs_data_size(current_pdu);
1012 if (current_pdu_len < prhdr->frag_len) {
1013 return NT_STATUS_BUFFER_TOO_SMALL;
1017 if (current_pdu_len == (uint32)prhdr->frag_len) {
1018 prs_mem_free(current_pdu);
1019 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1020 /* Make current_pdu dynamic with no memory. */
1021 prs_give_memory(current_pdu, 0, 0, True);
1022 return NT_STATUS_OK;
1026 * Oh no ! More data in buffer than we processed in current pdu.
1027 * Cheat. Move the data down and shrink the buffer.
1030 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1031 current_pdu_len - prhdr->frag_len);
1033 /* Remember to set the read offset back to zero. */
1034 prs_set_offset(current_pdu, 0);
1036 /* Shrink the buffer. */
1037 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1038 return NT_STATUS_BUFFER_TOO_SMALL;
1041 return NT_STATUS_OK;
1044 /****************************************************************************
1045 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1046 ****************************************************************************/
1048 struct cli_api_pipe_state {
1049 struct event_context *ev;
1050 struct rpc_cli_transport *transport;
1055 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1056 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1057 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1059 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1060 struct event_context *ev,
1061 struct rpc_cli_transport *transport,
1062 uint8_t *data, size_t data_len,
1063 uint32_t max_rdata_len)
1065 struct tevent_req *req, *subreq;
1066 struct cli_api_pipe_state *state;
1069 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1074 state->transport = transport;
1076 if (max_rdata_len < RPC_HEADER_LEN) {
1078 * For a RPC reply we always need at least RPC_HEADER_LEN
1079 * bytes. We check this here because we will receive
1080 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1082 status = NT_STATUS_INVALID_PARAMETER;
1086 if (transport->trans_send != NULL) {
1087 subreq = transport->trans_send(state, ev, data, data_len,
1088 max_rdata_len, transport->priv);
1089 if (subreq == NULL) {
1092 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1097 * If the transport does not provide a "trans" routine, i.e. for
1098 * example the ncacn_ip_tcp transport, do the write/read step here.
1101 subreq = rpc_write_send(state, ev, transport, data, data_len);
1102 if (subreq == NULL) {
1105 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1108 status = NT_STATUS_INVALID_PARAMETER;
1111 tevent_req_nterror(req, status);
1112 return tevent_req_post(req, ev);
1118 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1120 struct tevent_req *req = tevent_req_callback_data(
1121 subreq, struct tevent_req);
1122 struct cli_api_pipe_state *state = tevent_req_data(
1123 req, struct cli_api_pipe_state);
1126 status = state->transport->trans_recv(subreq, state, &state->rdata,
1128 TALLOC_FREE(subreq);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 tevent_req_nterror(req, status);
1133 tevent_req_done(req);
1136 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1138 struct tevent_req *req = tevent_req_callback_data(
1139 subreq, struct tevent_req);
1140 struct cli_api_pipe_state *state = tevent_req_data(
1141 req, struct cli_api_pipe_state);
1144 status = rpc_write_recv(subreq);
1145 TALLOC_FREE(subreq);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 tevent_req_nterror(req, status);
1151 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1152 if (tevent_req_nomem(state->rdata, req)) {
1157 * We don't need to use rpc_read_send here, the upper layer will cope
1158 * with a short read, transport->trans_send could also return less
1159 * than state->max_rdata_len.
1161 subreq = state->transport->read_send(state, state->ev, state->rdata,
1163 state->transport->priv);
1164 if (tevent_req_nomem(subreq, req)) {
1167 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1170 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1172 struct tevent_req *req = tevent_req_callback_data(
1173 subreq, struct tevent_req);
1174 struct cli_api_pipe_state *state = tevent_req_data(
1175 req, struct cli_api_pipe_state);
1179 status = state->transport->read_recv(subreq, &received);
1180 TALLOC_FREE(subreq);
1181 if (!NT_STATUS_IS_OK(status)) {
1182 tevent_req_nterror(req, status);
1185 state->rdata_len = received;
1186 tevent_req_done(req);
1189 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1190 uint8_t **prdata, uint32_t *prdata_len)
1192 struct cli_api_pipe_state *state = tevent_req_data(
1193 req, struct cli_api_pipe_state);
1196 if (tevent_req_is_nterror(req, &status)) {
1200 *prdata = talloc_move(mem_ctx, &state->rdata);
1201 *prdata_len = state->rdata_len;
1202 return NT_STATUS_OK;
1205 /****************************************************************************
1206 Send data on an rpc pipe via trans. The prs_struct data must be the last
1207 pdu fragment of an NDR data stream.
1209 Receive response data from an rpc pipe, which may be large...
1211 Read the first fragment: unfortunately have to use SMBtrans for the first
1212 bit, then SMBreadX for subsequent bits.
1214 If first fragment received also wasn't the last fragment, continue
1215 getting fragments until we _do_ receive the last fragment.
1217 Request/Response PDU's look like the following...
1219 |<------------------PDU len----------------------------------------------->|
1220 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1222 +------------+-----------------+-------------+---------------+-------------+
1223 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1224 +------------+-----------------+-------------+---------------+-------------+
1226 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1227 signing & sealing being negotiated.
1229 ****************************************************************************/
1231 struct rpc_api_pipe_state {
1232 struct event_context *ev;
1233 struct rpc_pipe_client *cli;
1234 uint8_t expected_pkt_type;
1236 prs_struct incoming_frag;
1237 struct rpc_hdr_info rhdr;
1239 prs_struct incoming_pdu; /* Incoming reply */
1240 uint32_t incoming_pdu_offset;
1243 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1245 prs_mem_free(&state->incoming_frag);
1246 prs_mem_free(&state->incoming_pdu);
1250 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1251 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1253 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1254 struct event_context *ev,
1255 struct rpc_pipe_client *cli,
1256 prs_struct *data, /* Outgoing PDU */
1257 uint8_t expected_pkt_type)
1259 struct tevent_req *req, *subreq;
1260 struct rpc_api_pipe_state *state;
1261 uint16_t max_recv_frag;
1264 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1270 state->expected_pkt_type = expected_pkt_type;
1271 state->incoming_pdu_offset = 0;
1273 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1275 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1276 /* Make incoming_pdu dynamic with no memory. */
1277 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1279 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1282 * Ensure we're not sending too much.
1284 if (prs_offset(data) > cli->max_xmit_frag) {
1285 status = NT_STATUS_INVALID_PARAMETER;
1289 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1291 max_recv_frag = cli->max_recv_frag;
1294 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1297 subreq = cli_api_pipe_send(state, ev, cli->transport,
1298 (uint8_t *)prs_data_p(data),
1299 prs_offset(data), max_recv_frag);
1300 if (subreq == NULL) {
1303 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1307 tevent_req_nterror(req, status);
1308 return tevent_req_post(req, ev);
1314 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1316 struct tevent_req *req = tevent_req_callback_data(
1317 subreq, struct tevent_req);
1318 struct rpc_api_pipe_state *state = tevent_req_data(
1319 req, struct rpc_api_pipe_state);
1321 uint8_t *rdata = NULL;
1322 uint32_t rdata_len = 0;
1325 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1326 TALLOC_FREE(subreq);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1329 tevent_req_nterror(req, status);
1333 if (rdata == NULL) {
1334 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1335 rpccli_pipe_txt(debug_ctx(), state->cli)));
1336 tevent_req_done(req);
1341 * Give the memory received from cli_trans as dynamic to the current
1342 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1345 rdata_copy = (char *)memdup(rdata, rdata_len);
1347 if (tevent_req_nomem(rdata_copy, req)) {
1350 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1352 /* Ensure we have enough data for a pdu. */
1353 subreq = get_complete_frag_send(state, state->ev, state->cli,
1354 &state->rhdr, &state->incoming_frag);
1355 if (tevent_req_nomem(subreq, req)) {
1358 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1361 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1363 struct tevent_req *req = tevent_req_callback_data(
1364 subreq, struct tevent_req);
1365 struct rpc_api_pipe_state *state = tevent_req_data(
1366 req, struct rpc_api_pipe_state);
1369 uint32_t rdata_len = 0;
1371 status = get_complete_frag_recv(subreq);
1372 TALLOC_FREE(subreq);
1373 if (!NT_STATUS_IS_OK(status)) {
1374 DEBUG(5, ("get_complete_frag failed: %s\n",
1375 nt_errstr(status)));
1376 tevent_req_nterror(req, status);
1380 status = cli_pipe_validate_current_pdu(
1381 state->cli, &state->rhdr, &state->incoming_frag,
1382 state->expected_pkt_type, &rdata, &rdata_len,
1383 &state->incoming_pdu);
1385 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1386 (unsigned)prs_data_size(&state->incoming_frag),
1387 (unsigned)state->incoming_pdu_offset,
1388 nt_errstr(status)));
1390 if (!NT_STATUS_IS_OK(status)) {
1391 tevent_req_nterror(req, status);
1395 if ((state->rhdr.flags & RPC_FLG_FIRST)
1396 && (state->rhdr.pack_type[0] == 0)) {
1398 * Set the data type correctly for big-endian data on the
1401 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1403 rpccli_pipe_txt(debug_ctx(), state->cli)));
1404 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1407 * Check endianness on subsequent packets.
1409 if (state->incoming_frag.bigendian_data
1410 != state->incoming_pdu.bigendian_data) {
1411 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1413 state->incoming_pdu.bigendian_data?"big":"little",
1414 state->incoming_frag.bigendian_data?"big":"little"));
1415 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1419 /* Now copy the data portion out of the pdu into rbuf. */
1420 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1421 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1425 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1426 rdata, (size_t)rdata_len);
1427 state->incoming_pdu_offset += rdata_len;
1429 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1430 &state->incoming_frag);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 tevent_req_nterror(req, status);
1436 if (state->rhdr.flags & RPC_FLG_LAST) {
1437 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1438 rpccli_pipe_txt(debug_ctx(), state->cli),
1439 (unsigned)prs_data_size(&state->incoming_pdu)));
1440 tevent_req_done(req);
1444 subreq = get_complete_frag_send(state, state->ev, state->cli,
1445 &state->rhdr, &state->incoming_frag);
1446 if (tevent_req_nomem(subreq, req)) {
1449 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1452 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1453 prs_struct *reply_pdu)
1455 struct rpc_api_pipe_state *state = tevent_req_data(
1456 req, struct rpc_api_pipe_state);
1459 if (tevent_req_is_nterror(req, &status)) {
1463 *reply_pdu = state->incoming_pdu;
1464 reply_pdu->mem_ctx = mem_ctx;
1467 * Prevent state->incoming_pdu from being freed in
1468 * rpc_api_pipe_state_destructor()
1470 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1472 return NT_STATUS_OK;
1475 /*******************************************************************
1476 Creates krb5 auth bind.
1477 ********************************************************************/
1479 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1480 enum dcerpc_AuthLevel auth_level,
1481 RPC_HDR_AUTH *pauth_out,
1482 prs_struct *auth_data)
1486 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1487 DATA_BLOB tkt = data_blob_null;
1488 DATA_BLOB tkt_wrapped = data_blob_null;
1490 /* We may change the pad length before marshalling. */
1491 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1493 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1494 a->service_principal ));
1496 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1498 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1499 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1502 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1504 a->service_principal,
1505 error_message(ret) ));
1507 data_blob_free(&tkt);
1508 prs_mem_free(auth_data);
1509 return NT_STATUS_INVALID_PARAMETER;
1512 /* wrap that up in a nice GSS-API wrapping */
1513 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1515 data_blob_free(&tkt);
1517 /* Auth len in the rpc header doesn't include auth_header. */
1518 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1519 data_blob_free(&tkt_wrapped);
1520 prs_mem_free(auth_data);
1521 return NT_STATUS_NO_MEMORY;
1524 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1525 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1527 data_blob_free(&tkt_wrapped);
1528 return NT_STATUS_OK;
1530 return NT_STATUS_INVALID_PARAMETER;
1534 /*******************************************************************
1535 Creates SPNEGO NTLMSSP auth bind.
1536 ********************************************************************/
1538 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1539 enum dcerpc_AuthLevel auth_level,
1540 RPC_HDR_AUTH *pauth_out,
1541 prs_struct *auth_data)
1544 DATA_BLOB null_blob = data_blob_null;
1545 DATA_BLOB request = data_blob_null;
1546 DATA_BLOB spnego_msg = data_blob_null;
1548 /* We may change the pad length before marshalling. */
1549 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1551 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1552 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1556 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1557 data_blob_free(&request);
1558 prs_mem_free(auth_data);
1562 /* Wrap this in SPNEGO. */
1563 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1565 data_blob_free(&request);
1567 /* Auth len in the rpc header doesn't include auth_header. */
1568 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1569 data_blob_free(&spnego_msg);
1570 prs_mem_free(auth_data);
1571 return NT_STATUS_NO_MEMORY;
1574 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1575 dump_data(5, spnego_msg.data, spnego_msg.length);
1577 data_blob_free(&spnego_msg);
1578 return NT_STATUS_OK;
1581 /*******************************************************************
1582 Creates NTLMSSP auth bind.
1583 ********************************************************************/
1585 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1586 enum dcerpc_AuthLevel auth_level,
1587 RPC_HDR_AUTH *pauth_out,
1588 prs_struct *auth_data)
1591 DATA_BLOB null_blob = data_blob_null;
1592 DATA_BLOB request = data_blob_null;
1594 /* We may change the pad length before marshalling. */
1595 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1597 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1598 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1602 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1603 data_blob_free(&request);
1604 prs_mem_free(auth_data);
1608 /* Auth len in the rpc header doesn't include auth_header. */
1609 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1610 data_blob_free(&request);
1611 prs_mem_free(auth_data);
1612 return NT_STATUS_NO_MEMORY;
1615 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1616 dump_data(5, request.data, request.length);
1618 data_blob_free(&request);
1619 return NT_STATUS_OK;
1622 /*******************************************************************
1623 Creates schannel auth bind.
1624 ********************************************************************/
1626 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1627 enum dcerpc_AuthLevel auth_level,
1628 RPC_HDR_AUTH *pauth_out,
1629 prs_struct *auth_data)
1631 struct NL_AUTH_MESSAGE r;
1632 enum ndr_err_code ndr_err;
1635 /* We may change the pad length before marshalling. */
1636 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1638 /* Use lp_workgroup() if domain not specified */
1640 if (!cli->auth->domain || !cli->auth->domain[0]) {
1641 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1642 if (cli->auth->domain == NULL) {
1643 return NT_STATUS_NO_MEMORY;
1648 * Now marshall the data into the auth parse_struct.
1651 r.MessageType = NL_NEGOTIATE_REQUEST;
1652 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1653 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1654 r.oem_netbios_domain.a = cli->auth->domain;
1655 r.oem_netbios_computer.a = global_myname();
1657 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1658 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1659 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1660 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1661 prs_mem_free(auth_data);
1662 return ndr_map_error2ntstatus(ndr_err);
1665 if (DEBUGLEVEL >= 10) {
1666 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1669 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1671 prs_mem_free(auth_data);
1672 return NT_STATUS_NO_MEMORY;
1675 return NT_STATUS_OK;
1678 /*******************************************************************
1679 Creates the internals of a DCE/RPC bind request or alter context PDU.
1680 ********************************************************************/
1682 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1683 prs_struct *rpc_out,
1685 const struct ndr_syntax_id *abstract,
1686 const struct ndr_syntax_id *transfer,
1687 RPC_HDR_AUTH *phdr_auth,
1688 prs_struct *pauth_info)
1692 RPC_CONTEXT rpc_ctx;
1693 uint16 auth_len = prs_offset(pauth_info);
1694 uint8 ss_padding_len = 0;
1695 uint16 frag_len = 0;
1697 /* create the RPC context. */
1698 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1700 /* create the bind request RPC_HDR_RB */
1701 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1703 /* Start building the frag length. */
1704 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1706 /* Do we need to pad ? */
1708 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1710 ss_padding_len = 8 - (data_len % 8);
1711 phdr_auth->auth_pad_len = ss_padding_len;
1713 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1716 /* Create the request RPC_HDR */
1717 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1719 /* Marshall the RPC header */
1720 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1721 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1722 return NT_STATUS_NO_MEMORY;
1725 /* Marshall the bind request data */
1726 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1727 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1728 return NT_STATUS_NO_MEMORY;
1732 * Grow the outgoing buffer to store any auth info.
1736 if (ss_padding_len) {
1738 memset(pad, '\0', 8);
1739 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1740 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1741 return NT_STATUS_NO_MEMORY;
1745 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1746 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1747 return NT_STATUS_NO_MEMORY;
1751 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1752 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1753 return NT_STATUS_NO_MEMORY;
1757 return NT_STATUS_OK;
1760 /*******************************************************************
1761 Creates a DCE/RPC bind request.
1762 ********************************************************************/
1764 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1765 prs_struct *rpc_out,
1767 const struct ndr_syntax_id *abstract,
1768 const struct ndr_syntax_id *transfer,
1769 enum pipe_auth_type auth_type,
1770 enum dcerpc_AuthLevel auth_level)
1772 RPC_HDR_AUTH hdr_auth;
1773 prs_struct auth_info;
1774 NTSTATUS ret = NT_STATUS_OK;
1776 ZERO_STRUCT(hdr_auth);
1777 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1778 return NT_STATUS_NO_MEMORY;
1780 switch (auth_type) {
1781 case PIPE_AUTH_TYPE_SCHANNEL:
1782 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1783 if (!NT_STATUS_IS_OK(ret)) {
1784 prs_mem_free(&auth_info);
1789 case PIPE_AUTH_TYPE_NTLMSSP:
1790 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1791 if (!NT_STATUS_IS_OK(ret)) {
1792 prs_mem_free(&auth_info);
1797 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1798 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1799 if (!NT_STATUS_IS_OK(ret)) {
1800 prs_mem_free(&auth_info);
1805 case PIPE_AUTH_TYPE_KRB5:
1806 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1807 if (!NT_STATUS_IS_OK(ret)) {
1808 prs_mem_free(&auth_info);
1813 case PIPE_AUTH_TYPE_NONE:
1817 /* "Can't" happen. */
1818 return NT_STATUS_INVALID_INFO_CLASS;
1821 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1829 prs_mem_free(&auth_info);
1833 /*******************************************************************
1834 Create and add the NTLMSSP sign/seal auth header and data.
1835 ********************************************************************/
1837 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1839 uint32 ss_padding_len,
1840 prs_struct *outgoing_pdu)
1842 RPC_HDR_AUTH auth_info;
1844 DATA_BLOB auth_blob = data_blob_null;
1845 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1847 if (!cli->auth->a_u.ntlmssp_state) {
1848 return NT_STATUS_INVALID_PARAMETER;
1851 /* Init and marshall the auth header. */
1852 init_rpc_hdr_auth(&auth_info,
1853 map_pipe_auth_type_to_rpc_auth_type(
1854 cli->auth->auth_type),
1855 cli->auth->auth_level,
1857 1 /* context id. */);
1859 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1860 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1861 data_blob_free(&auth_blob);
1862 return NT_STATUS_NO_MEMORY;
1865 switch (cli->auth->auth_level) {
1866 case DCERPC_AUTH_LEVEL_PRIVACY:
1867 /* Data portion is encrypted. */
1868 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1869 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1871 (unsigned char *)prs_data_p(outgoing_pdu),
1872 (size_t)prs_offset(outgoing_pdu),
1874 if (!NT_STATUS_IS_OK(status)) {
1875 data_blob_free(&auth_blob);
1880 case DCERPC_AUTH_LEVEL_INTEGRITY:
1881 /* Data is signed. */
1882 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1883 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1885 (unsigned char *)prs_data_p(outgoing_pdu),
1886 (size_t)prs_offset(outgoing_pdu),
1888 if (!NT_STATUS_IS_OK(status)) {
1889 data_blob_free(&auth_blob);
1896 smb_panic("bad auth level");
1898 return NT_STATUS_INVALID_PARAMETER;
1901 /* Finally marshall the blob. */
1903 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1904 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1905 (unsigned int)NTLMSSP_SIG_SIZE));
1906 data_blob_free(&auth_blob);
1907 return NT_STATUS_NO_MEMORY;
1910 data_blob_free(&auth_blob);
1911 return NT_STATUS_OK;
1914 /*******************************************************************
1915 Create and add the schannel sign/seal auth header and data.
1916 ********************************************************************/
1918 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1920 uint32 ss_padding_len,
1921 prs_struct *outgoing_pdu)
1923 RPC_HDR_AUTH auth_info;
1924 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1925 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1926 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1931 return NT_STATUS_INVALID_PARAMETER;
1934 /* Init and marshall the auth header. */
1935 init_rpc_hdr_auth(&auth_info,
1936 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1937 cli->auth->auth_level,
1939 1 /* context id. */);
1941 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1942 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1943 return NT_STATUS_NO_MEMORY;
1946 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1949 switch (cli->auth->auth_level) {
1950 case DCERPC_AUTH_LEVEL_PRIVACY:
1951 status = schannel_seal_packet(sas,
1957 case DCERPC_AUTH_LEVEL_INTEGRITY:
1958 status = schannel_sign_packet(sas,
1965 status = NT_STATUS_INTERNAL_ERROR;
1969 if (!NT_STATUS_IS_OK(status)) {
1970 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1971 nt_errstr(status)));
1975 if (DEBUGLEVEL >= 10) {
1976 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1979 /* Finally marshall the blob. */
1980 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
1981 return NT_STATUS_NO_MEMORY;
1984 return NT_STATUS_OK;
1987 /*******************************************************************
1988 Calculate how much data we're going to send in this packet, also
1989 work out any sign/seal padding length.
1990 ********************************************************************/
1992 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1996 uint32 *p_ss_padding)
1998 uint32 data_space, data_len;
2001 if ((data_left > 0) && (sys_random() % 2)) {
2002 data_left = MAX(data_left/2, 1);
2006 switch (cli->auth->auth_level) {
2007 case DCERPC_AUTH_LEVEL_NONE:
2008 case DCERPC_AUTH_LEVEL_CONNECT:
2009 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2010 data_len = MIN(data_space, data_left);
2013 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2016 case DCERPC_AUTH_LEVEL_INTEGRITY:
2017 case DCERPC_AUTH_LEVEL_PRIVACY:
2018 /* Treat the same for all authenticated rpc requests. */
2019 switch(cli->auth->auth_type) {
2020 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2021 case PIPE_AUTH_TYPE_NTLMSSP:
2022 *p_auth_len = NTLMSSP_SIG_SIZE;
2024 case PIPE_AUTH_TYPE_SCHANNEL:
2025 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2028 smb_panic("bad auth type");
2032 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2033 RPC_HDR_AUTH_LEN - *p_auth_len;
2035 data_len = MIN(data_space, data_left);
2038 *p_ss_padding = 8 - (data_len % 8);
2040 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2041 data_len + *p_ss_padding + /* data plus padding. */
2042 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2046 smb_panic("bad auth level");
2052 /*******************************************************************
2054 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2055 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2056 and deals with signing/sealing details.
2057 ********************************************************************/
2059 struct rpc_api_pipe_req_state {
2060 struct event_context *ev;
2061 struct rpc_pipe_client *cli;
2064 prs_struct *req_data;
2065 uint32_t req_data_sent;
2066 prs_struct outgoing_frag;
2067 prs_struct reply_pdu;
2070 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2072 prs_mem_free(&s->outgoing_frag);
2073 prs_mem_free(&s->reply_pdu);
2077 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2078 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2079 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2080 bool *is_last_frag);
2082 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2083 struct event_context *ev,
2084 struct rpc_pipe_client *cli,
2086 prs_struct *req_data)
2088 struct tevent_req *req, *subreq;
2089 struct rpc_api_pipe_req_state *state;
2093 req = tevent_req_create(mem_ctx, &state,
2094 struct rpc_api_pipe_req_state);
2100 state->op_num = op_num;
2101 state->req_data = req_data;
2102 state->req_data_sent = 0;
2103 state->call_id = get_rpc_call_id();
2105 if (cli->max_xmit_frag
2106 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2107 /* Server is screwed up ! */
2108 status = NT_STATUS_INVALID_PARAMETER;
2112 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2114 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2119 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2121 status = prepare_next_frag(state, &is_last_frag);
2122 if (!NT_STATUS_IS_OK(status)) {
2127 subreq = rpc_api_pipe_send(state, ev, state->cli,
2128 &state->outgoing_frag,
2130 if (subreq == NULL) {
2133 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2135 subreq = rpc_write_send(
2136 state, ev, cli->transport,
2137 (uint8_t *)prs_data_p(&state->outgoing_frag),
2138 prs_offset(&state->outgoing_frag));
2139 if (subreq == NULL) {
2142 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2148 tevent_req_nterror(req, status);
2149 return tevent_req_post(req, ev);
2155 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2159 RPC_HDR_REQ hdr_req;
2160 uint32_t data_sent_thistime;
2164 uint32_t ss_padding;
2166 char pad[8] = { 0, };
2169 data_left = prs_offset(state->req_data) - state->req_data_sent;
2171 data_sent_thistime = calculate_data_len_tosend(
2172 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2174 if (state->req_data_sent == 0) {
2175 flags = RPC_FLG_FIRST;
2178 if (data_sent_thistime == data_left) {
2179 flags |= RPC_FLG_LAST;
2182 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2183 return NT_STATUS_NO_MEMORY;
2186 /* Create and marshall the header and request header. */
2187 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2190 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2191 return NT_STATUS_NO_MEMORY;
2194 /* Create the rpc request RPC_HDR_REQ */
2195 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2198 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2199 &state->outgoing_frag, 0)) {
2200 return NT_STATUS_NO_MEMORY;
2203 /* Copy in the data, plus any ss padding. */
2204 if (!prs_append_some_prs_data(&state->outgoing_frag,
2205 state->req_data, state->req_data_sent,
2206 data_sent_thistime)) {
2207 return NT_STATUS_NO_MEMORY;
2210 /* Copy the sign/seal padding data. */
2211 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2212 return NT_STATUS_NO_MEMORY;
2215 /* Generate any auth sign/seal and add the auth footer. */
2216 switch (state->cli->auth->auth_type) {
2217 case PIPE_AUTH_TYPE_NONE:
2218 status = NT_STATUS_OK;
2220 case PIPE_AUTH_TYPE_NTLMSSP:
2221 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2222 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2223 &state->outgoing_frag);
2225 case PIPE_AUTH_TYPE_SCHANNEL:
2226 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2227 &state->outgoing_frag);
2230 status = NT_STATUS_INVALID_PARAMETER;
2234 state->req_data_sent += data_sent_thistime;
2235 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2240 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2242 struct tevent_req *req = tevent_req_callback_data(
2243 subreq, struct tevent_req);
2244 struct rpc_api_pipe_req_state *state = tevent_req_data(
2245 req, struct rpc_api_pipe_req_state);
2249 status = rpc_write_recv(subreq);
2250 TALLOC_FREE(subreq);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 tevent_req_nterror(req, status);
2256 status = prepare_next_frag(state, &is_last_frag);
2257 if (!NT_STATUS_IS_OK(status)) {
2258 tevent_req_nterror(req, status);
2263 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2264 &state->outgoing_frag,
2266 if (tevent_req_nomem(subreq, req)) {
2269 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2271 subreq = rpc_write_send(
2273 state->cli->transport,
2274 (uint8_t *)prs_data_p(&state->outgoing_frag),
2275 prs_offset(&state->outgoing_frag));
2276 if (tevent_req_nomem(subreq, req)) {
2279 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2284 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2286 struct tevent_req *req = tevent_req_callback_data(
2287 subreq, struct tevent_req);
2288 struct rpc_api_pipe_req_state *state = tevent_req_data(
2289 req, struct rpc_api_pipe_req_state);
2292 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2293 TALLOC_FREE(subreq);
2294 if (!NT_STATUS_IS_OK(status)) {
2295 tevent_req_nterror(req, status);
2298 tevent_req_done(req);
2301 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2302 prs_struct *reply_pdu)
2304 struct rpc_api_pipe_req_state *state = tevent_req_data(
2305 req, struct rpc_api_pipe_req_state);
2308 if (tevent_req_is_nterror(req, &status)) {
2310 * We always have to initialize to reply pdu, even if there is
2311 * none. The rpccli_* caller routines expect this.
2313 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2317 *reply_pdu = state->reply_pdu;
2318 reply_pdu->mem_ctx = mem_ctx;
2321 * Prevent state->req_pdu from being freed in
2322 * rpc_api_pipe_req_state_destructor()
2324 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2326 return NT_STATUS_OK;
2330 /****************************************************************************
2331 Set the handle state.
2332 ****************************************************************************/
2334 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2335 const char *pipe_name, uint16 device_state)
2337 bool state_set = False;
2339 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2340 char *rparam = NULL;
2342 uint32 rparam_len, rdata_len;
2344 if (pipe_name == NULL)
2347 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2348 cli->fnum, pipe_name, device_state));
2350 /* create parameters: device state */
2351 SSVAL(param, 0, device_state);
2353 /* create setup parameters. */
2355 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2357 /* send the data on \PIPE\ */
2358 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2359 setup, 2, 0, /* setup, length, max */
2360 param, 2, 0, /* param, length, max */
2361 NULL, 0, 1024, /* data, length, max */
2362 &rparam, &rparam_len, /* return param, length */
2363 &rdata, &rdata_len)) /* return data, length */
2365 DEBUG(5, ("Set Handle state: return OK\n"));
2376 /****************************************************************************
2377 Check the rpc bind acknowledge response.
2378 ****************************************************************************/
2380 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2381 const struct ndr_syntax_id *transfer)
2383 if ( hdr_ba->addr.len == 0) {
2384 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2387 /* check the transfer syntax */
2388 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2389 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2390 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2394 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2395 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2396 hdr_ba->res.num_results, hdr_ba->res.reason));
2399 DEBUG(5,("check_bind_response: accepted!\n"));
2403 /*******************************************************************
2404 Creates a DCE/RPC bind authentication response.
2405 This is the packet that is sent back to the server once we
2406 have received a BIND-ACK, to finish the third leg of
2407 the authentication handshake.
2408 ********************************************************************/
2410 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2412 enum pipe_auth_type auth_type,
2413 enum dcerpc_AuthLevel auth_level,
2414 DATA_BLOB *pauth_blob,
2415 prs_struct *rpc_out)
2418 RPC_HDR_AUTH hdr_auth;
2421 /* Create the request RPC_HDR */
2422 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2423 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2424 pauth_blob->length );
2427 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2428 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2429 return NT_STATUS_NO_MEMORY;
2433 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2434 about padding - shouldn't this pad to length 8 ? JRA.
2437 /* 4 bytes padding. */
2438 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2439 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2440 return NT_STATUS_NO_MEMORY;
2443 /* Create the request RPC_HDR_AUTHA */
2444 init_rpc_hdr_auth(&hdr_auth,
2445 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2448 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2449 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2450 return NT_STATUS_NO_MEMORY;
2454 * Append the auth data to the outgoing buffer.
2457 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2458 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2459 return NT_STATUS_NO_MEMORY;
2462 return NT_STATUS_OK;
2465 /*******************************************************************
2466 Creates a DCE/RPC bind alter context authentication request which
2467 may contain a spnego auth blobl
2468 ********************************************************************/
2470 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2471 const struct ndr_syntax_id *abstract,
2472 const struct ndr_syntax_id *transfer,
2473 enum dcerpc_AuthLevel auth_level,
2474 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2475 prs_struct *rpc_out)
2477 RPC_HDR_AUTH hdr_auth;
2478 prs_struct auth_info;
2479 NTSTATUS ret = NT_STATUS_OK;
2481 ZERO_STRUCT(hdr_auth);
2482 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2483 return NT_STATUS_NO_MEMORY;
2485 /* We may change the pad length before marshalling. */
2486 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2488 if (pauth_blob->length) {
2489 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2490 prs_mem_free(&auth_info);
2491 return NT_STATUS_NO_MEMORY;
2495 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2502 prs_mem_free(&auth_info);
2506 /****************************************************************************
2508 ****************************************************************************/
2510 struct rpc_pipe_bind_state {
2511 struct event_context *ev;
2512 struct rpc_pipe_client *cli;
2514 uint32_t rpc_call_id;
2517 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2519 prs_mem_free(&state->rpc_out);
2523 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2524 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2525 struct rpc_pipe_bind_state *state,
2526 struct rpc_hdr_info *phdr,
2527 prs_struct *reply_pdu);
2528 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2529 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2530 struct rpc_pipe_bind_state *state,
2531 struct rpc_hdr_info *phdr,
2532 prs_struct *reply_pdu);
2533 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2535 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2536 struct event_context *ev,
2537 struct rpc_pipe_client *cli,
2538 struct cli_pipe_auth_data *auth)
2540 struct tevent_req *req, *subreq;
2541 struct rpc_pipe_bind_state *state;
2544 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2549 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2550 rpccli_pipe_txt(debug_ctx(), cli),
2551 (unsigned int)auth->auth_type,
2552 (unsigned int)auth->auth_level ));
2556 state->rpc_call_id = get_rpc_call_id();
2558 prs_init_empty(&state->rpc_out, state, MARSHALL);
2559 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2561 cli->auth = talloc_move(cli, &auth);
2563 /* Marshall the outgoing data. */
2564 status = create_rpc_bind_req(cli, &state->rpc_out,
2566 &cli->abstract_syntax,
2567 &cli->transfer_syntax,
2568 cli->auth->auth_type,
2569 cli->auth->auth_level);
2571 if (!NT_STATUS_IS_OK(status)) {
2575 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2577 if (subreq == NULL) {
2580 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2584 tevent_req_nterror(req, status);
2585 return tevent_req_post(req, ev);
2591 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2593 struct tevent_req *req = tevent_req_callback_data(
2594 subreq, struct tevent_req);
2595 struct rpc_pipe_bind_state *state = tevent_req_data(
2596 req, struct rpc_pipe_bind_state);
2597 prs_struct reply_pdu;
2598 struct rpc_hdr_info hdr;
2599 struct rpc_hdr_ba_info hdr_ba;
2602 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2603 TALLOC_FREE(subreq);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2606 rpccli_pipe_txt(debug_ctx(), state->cli),
2607 nt_errstr(status)));
2608 tevent_req_nterror(req, status);
2612 /* Unmarshall the RPC header */
2613 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2614 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2615 prs_mem_free(&reply_pdu);
2616 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2620 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2621 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2623 prs_mem_free(&reply_pdu);
2624 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2628 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2629 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2630 prs_mem_free(&reply_pdu);
2631 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2635 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2636 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2639 * For authenticated binds we may need to do 3 or 4 leg binds.
2642 switch(state->cli->auth->auth_type) {
2644 case PIPE_AUTH_TYPE_NONE:
2645 case PIPE_AUTH_TYPE_SCHANNEL:
2646 /* Bind complete. */
2647 prs_mem_free(&reply_pdu);
2648 tevent_req_done(req);
2651 case PIPE_AUTH_TYPE_NTLMSSP:
2652 /* Need to send AUTH3 packet - no reply. */
2653 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2655 prs_mem_free(&reply_pdu);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 tevent_req_nterror(req, status);
2661 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2662 /* Need to send alter context request and reply. */
2663 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2665 prs_mem_free(&reply_pdu);
2666 if (!NT_STATUS_IS_OK(status)) {
2667 tevent_req_nterror(req, status);
2671 case PIPE_AUTH_TYPE_KRB5:
2675 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2676 (unsigned int)state->cli->auth->auth_type));
2677 prs_mem_free(&reply_pdu);
2678 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2682 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2683 struct rpc_pipe_bind_state *state,
2684 struct rpc_hdr_info *phdr,
2685 prs_struct *reply_pdu)
2687 DATA_BLOB server_response = data_blob_null;
2688 DATA_BLOB client_reply = data_blob_null;
2689 struct rpc_hdr_auth_info hdr_auth;
2690 struct tevent_req *subreq;
2693 if ((phdr->auth_len == 0)
2694 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2695 return NT_STATUS_INVALID_PARAMETER;
2698 if (!prs_set_offset(
2700 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2701 return NT_STATUS_INVALID_PARAMETER;
2704 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2705 return NT_STATUS_INVALID_PARAMETER;
2708 /* TODO - check auth_type/auth_level match. */
2710 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2711 prs_copy_data_out((char *)server_response.data, reply_pdu,
2714 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2715 server_response, &client_reply);
2717 if (!NT_STATUS_IS_OK(status)) {
2718 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2719 "blob failed: %s.\n", nt_errstr(status)));
2723 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2725 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2726 state->cli->auth->auth_type,
2727 state->cli->auth->auth_level,
2728 &client_reply, &state->rpc_out);
2729 data_blob_free(&client_reply);
2731 if (!NT_STATUS_IS_OK(status)) {
2735 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2736 (uint8_t *)prs_data_p(&state->rpc_out),
2737 prs_offset(&state->rpc_out));
2738 if (subreq == NULL) {
2739 return NT_STATUS_NO_MEMORY;
2741 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2742 return NT_STATUS_OK;
2745 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2747 struct tevent_req *req = tevent_req_callback_data(
2748 subreq, struct tevent_req);
2751 status = rpc_write_recv(subreq);
2752 TALLOC_FREE(subreq);
2753 if (!NT_STATUS_IS_OK(status)) {
2754 tevent_req_nterror(req, status);
2757 tevent_req_done(req);
2760 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2761 struct rpc_pipe_bind_state *state,
2762 struct rpc_hdr_info *phdr,
2763 prs_struct *reply_pdu)
2765 DATA_BLOB server_spnego_response = data_blob_null;
2766 DATA_BLOB server_ntlm_response = data_blob_null;
2767 DATA_BLOB client_reply = data_blob_null;
2768 DATA_BLOB tmp_blob = data_blob_null;
2769 RPC_HDR_AUTH hdr_auth;
2770 struct tevent_req *subreq;
2773 if ((phdr->auth_len == 0)
2774 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2775 return NT_STATUS_INVALID_PARAMETER;
2778 /* Process the returned NTLMSSP blob first. */
2779 if (!prs_set_offset(
2781 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2782 return NT_STATUS_INVALID_PARAMETER;
2785 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2786 return NT_STATUS_INVALID_PARAMETER;
2789 server_spnego_response = data_blob(NULL, phdr->auth_len);
2790 prs_copy_data_out((char *)server_spnego_response.data,
2791 reply_pdu, phdr->auth_len);
2794 * The server might give us back two challenges - tmp_blob is for the
2797 if (!spnego_parse_challenge(server_spnego_response,
2798 &server_ntlm_response, &tmp_blob)) {
2799 data_blob_free(&server_spnego_response);
2800 data_blob_free(&server_ntlm_response);
2801 data_blob_free(&tmp_blob);
2802 return NT_STATUS_INVALID_PARAMETER;
2805 /* We're finished with the server spnego response and the tmp_blob. */
2806 data_blob_free(&server_spnego_response);
2807 data_blob_free(&tmp_blob);
2809 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2810 server_ntlm_response, &client_reply);
2812 /* Finished with the server_ntlm response */
2813 data_blob_free(&server_ntlm_response);
2815 if (!NT_STATUS_IS_OK(status)) {
2816 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2817 "using server blob failed.\n"));
2818 data_blob_free(&client_reply);
2822 /* SPNEGO wrap the client reply. */
2823 tmp_blob = spnego_gen_auth(client_reply);
2824 data_blob_free(&client_reply);
2825 client_reply = tmp_blob;
2826 tmp_blob = data_blob_null;
2828 /* Now prepare the alter context pdu. */
2829 prs_init_empty(&state->rpc_out, state, MARSHALL);
2831 status = create_rpc_alter_context(state->rpc_call_id,
2832 &state->cli->abstract_syntax,
2833 &state->cli->transfer_syntax,
2834 state->cli->auth->auth_level,
2837 data_blob_free(&client_reply);
2839 if (!NT_STATUS_IS_OK(status)) {
2843 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2844 &state->rpc_out, RPC_ALTCONTRESP);
2845 if (subreq == NULL) {
2846 return NT_STATUS_NO_MEMORY;
2848 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2849 return NT_STATUS_OK;
2852 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2854 struct tevent_req *req = tevent_req_callback_data(
2855 subreq, struct tevent_req);
2856 struct rpc_pipe_bind_state *state = tevent_req_data(
2857 req, struct rpc_pipe_bind_state);
2858 DATA_BLOB server_spnego_response = data_blob_null;
2859 DATA_BLOB tmp_blob = data_blob_null;
2860 prs_struct reply_pdu;
2861 struct rpc_hdr_info hdr;
2862 struct rpc_hdr_auth_info hdr_auth;
2865 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2866 TALLOC_FREE(subreq);
2867 if (!NT_STATUS_IS_OK(status)) {
2868 tevent_req_nterror(req, status);
2872 /* Get the auth blob from the reply. */
2873 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2874 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2875 "unmarshall RPC_HDR.\n"));
2876 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2880 if (!prs_set_offset(
2882 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2883 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2887 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2888 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2892 server_spnego_response = data_blob(NULL, hdr.auth_len);
2893 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2896 /* Check we got a valid auth response. */
2897 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2898 OID_NTLMSSP, &tmp_blob)) {
2899 data_blob_free(&server_spnego_response);
2900 data_blob_free(&tmp_blob);
2901 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2905 data_blob_free(&server_spnego_response);
2906 data_blob_free(&tmp_blob);
2908 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2909 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2910 tevent_req_done(req);
2913 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2915 return tevent_req_simple_recv_ntstatus(req);
2918 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2919 struct cli_pipe_auth_data *auth)
2921 TALLOC_CTX *frame = talloc_stackframe();
2922 struct event_context *ev;
2923 struct tevent_req *req;
2924 NTSTATUS status = NT_STATUS_OK;
2926 ev = event_context_init(frame);
2928 status = NT_STATUS_NO_MEMORY;
2932 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2934 status = NT_STATUS_NO_MEMORY;
2938 if (!tevent_req_poll(req, ev)) {
2939 status = map_nt_error_from_unix(errno);
2943 status = rpc_pipe_bind_recv(req);
2949 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2950 unsigned int timeout)
2952 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2957 return cli_set_timeout(cli, timeout);
2960 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2962 struct cli_state *cli;
2964 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2965 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2966 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2970 cli = rpc_pipe_np_smb_conn(rpc_cli);
2974 E_md4hash(cli->password ? cli->password : "", nt_hash);
2978 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2979 struct cli_pipe_auth_data **presult)
2981 struct cli_pipe_auth_data *result;
2983 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2984 if (result == NULL) {
2985 return NT_STATUS_NO_MEMORY;
2988 result->auth_type = PIPE_AUTH_TYPE_NONE;
2989 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2991 result->user_name = talloc_strdup(result, "");
2992 result->domain = talloc_strdup(result, "");
2993 if ((result->user_name == NULL) || (result->domain == NULL)) {
2994 TALLOC_FREE(result);
2995 return NT_STATUS_NO_MEMORY;
2999 return NT_STATUS_OK;
3002 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3004 ntlmssp_end(&auth->a_u.ntlmssp_state);
3008 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3009 enum pipe_auth_type auth_type,
3010 enum dcerpc_AuthLevel auth_level,
3012 const char *username,
3013 const char *password,
3014 struct cli_pipe_auth_data **presult)
3016 struct cli_pipe_auth_data *result;
3019 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3020 if (result == NULL) {
3021 return NT_STATUS_NO_MEMORY;
3024 result->auth_type = auth_type;
3025 result->auth_level = auth_level;
3027 result->user_name = talloc_strdup(result, username);
3028 result->domain = talloc_strdup(result, domain);
3029 if ((result->user_name == NULL) || (result->domain == NULL)) {
3030 status = NT_STATUS_NO_MEMORY;
3034 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3035 if (!NT_STATUS_IS_OK(status)) {
3039 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3041 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3042 if (!NT_STATUS_IS_OK(status)) {
3046 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3047 if (!NT_STATUS_IS_OK(status)) {
3051 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3052 if (!NT_STATUS_IS_OK(status)) {
3057 * Turn off sign+seal to allow selected auth level to turn it back on.
3059 result->a_u.ntlmssp_state->neg_flags &=
3060 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3062 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3063 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3064 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3065 result->a_u.ntlmssp_state->neg_flags
3066 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3070 return NT_STATUS_OK;
3073 TALLOC_FREE(result);
3077 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3078 enum dcerpc_AuthLevel auth_level,
3079 struct netlogon_creds_CredentialState *creds,
3080 struct cli_pipe_auth_data **presult)
3082 struct cli_pipe_auth_data *result;
3084 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3085 if (result == NULL) {
3086 return NT_STATUS_NO_MEMORY;
3089 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3090 result->auth_level = auth_level;
3092 result->user_name = talloc_strdup(result, "");
3093 result->domain = talloc_strdup(result, domain);
3094 if ((result->user_name == NULL) || (result->domain == NULL)) {
3098 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3099 if (result->a_u.schannel_auth == NULL) {
3103 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3104 result->a_u.schannel_auth->seq_num = 0;
3105 result->a_u.schannel_auth->initiator = true;
3106 result->a_u.schannel_auth->creds = creds;
3109 return NT_STATUS_OK;
3112 TALLOC_FREE(result);
3113 return NT_STATUS_NO_MEMORY;
3117 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3119 data_blob_free(&auth->session_key);
3124 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3125 enum dcerpc_AuthLevel auth_level,
3126 const char *service_princ,
3127 const char *username,
3128 const char *password,
3129 struct cli_pipe_auth_data **presult)
3132 struct cli_pipe_auth_data *result;
3134 if ((username != NULL) && (password != NULL)) {
3135 int ret = kerberos_kinit_password(username, password, 0, NULL);
3137 return NT_STATUS_ACCESS_DENIED;
3141 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3142 if (result == NULL) {
3143 return NT_STATUS_NO_MEMORY;
3146 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3147 result->auth_level = auth_level;
3150 * Username / domain need fixing!
3152 result->user_name = talloc_strdup(result, "");
3153 result->domain = talloc_strdup(result, "");
3154 if ((result->user_name == NULL) || (result->domain == NULL)) {
3158 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3159 result, struct kerberos_auth_struct);
3160 if (result->a_u.kerberos_auth == NULL) {
3163 talloc_set_destructor(result->a_u.kerberos_auth,
3164 cli_auth_kerberos_data_destructor);
3166 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3167 result, service_princ);
3168 if (result->a_u.kerberos_auth->service_principal == NULL) {
3173 return NT_STATUS_OK;
3176 TALLOC_FREE(result);
3177 return NT_STATUS_NO_MEMORY;
3179 return NT_STATUS_NOT_SUPPORTED;
3184 * Create an rpc pipe client struct, connecting to a tcp port.
3186 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3188 const struct ndr_syntax_id *abstract_syntax,
3189 struct rpc_pipe_client **presult)
3191 struct rpc_pipe_client *result;
3192 struct sockaddr_storage addr;
3196 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3197 if (result == NULL) {
3198 return NT_STATUS_NO_MEMORY;
3201 result->abstract_syntax = *abstract_syntax;
3202 result->transfer_syntax = ndr_transfer_syntax;
3203 result->dispatch = cli_do_rpc_ndr;
3204 result->dispatch_send = cli_do_rpc_ndr_send;
3205 result->dispatch_recv = cli_do_rpc_ndr_recv;
3207 result->desthost = talloc_strdup(result, host);
3208 result->srv_name_slash = talloc_asprintf_strupper_m(
3209 result, "\\\\%s", result->desthost);
3210 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3211 status = NT_STATUS_NO_MEMORY;
3215 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3216 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3218 if (!resolve_name(host, &addr, 0, false)) {
3219 status = NT_STATUS_NOT_FOUND;
3223 status = open_socket_out(&addr, port, 60, &fd);
3224 if (!NT_STATUS_IS_OK(status)) {
3227 set_socket_options(fd, lp_socket_options());
3229 status = rpc_transport_sock_init(result, fd, &result->transport);
3230 if (!NT_STATUS_IS_OK(status)) {
3235 result->transport->transport = NCACN_IP_TCP;
3238 return NT_STATUS_OK;
3241 TALLOC_FREE(result);
3246 * Determine the tcp port on which a dcerpc interface is listening
3247 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3250 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3251 const struct ndr_syntax_id *abstract_syntax,
3255 struct rpc_pipe_client *epm_pipe = NULL;
3256 struct cli_pipe_auth_data *auth = NULL;
3257 struct dcerpc_binding *map_binding = NULL;
3258 struct dcerpc_binding *res_binding = NULL;
3259 struct epm_twr_t *map_tower = NULL;
3260 struct epm_twr_t *res_towers = NULL;
3261 struct policy_handle *entry_handle = NULL;
3262 uint32_t num_towers = 0;
3263 uint32_t max_towers = 1;
3264 struct epm_twr_p_t towers;
3265 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3267 if (pport == NULL) {
3268 status = NT_STATUS_INVALID_PARAMETER;
3272 /* open the connection to the endpoint mapper */
3273 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3274 &ndr_table_epmapper.syntax_id,
3277 if (!NT_STATUS_IS_OK(status)) {
3281 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3282 if (!NT_STATUS_IS_OK(status)) {
3286 status = rpc_pipe_bind(epm_pipe, auth);
3287 if (!NT_STATUS_IS_OK(status)) {
3291 /* create tower for asking the epmapper */
3293 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3294 if (map_binding == NULL) {
3295 status = NT_STATUS_NO_MEMORY;
3299 map_binding->transport = NCACN_IP_TCP;
3300 map_binding->object = *abstract_syntax;
3301 map_binding->host = host; /* needed? */
3302 map_binding->endpoint = "0"; /* correct? needed? */
3304 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3305 if (map_tower == NULL) {
3306 status = NT_STATUS_NO_MEMORY;
3310 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3311 &(map_tower->tower));
3312 if (!NT_STATUS_IS_OK(status)) {
3316 /* allocate further parameters for the epm_Map call */
3318 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3319 if (res_towers == NULL) {
3320 status = NT_STATUS_NO_MEMORY;
3323 towers.twr = res_towers;
3325 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3326 if (entry_handle == NULL) {
3327 status = NT_STATUS_NO_MEMORY;
3331 /* ask the endpoint mapper for the port */
3333 status = rpccli_epm_Map(epm_pipe,
3335 CONST_DISCARD(struct GUID *,
3336 &(abstract_syntax->uuid)),
3343 if (!NT_STATUS_IS_OK(status)) {
3347 if (num_towers != 1) {
3348 status = NT_STATUS_UNSUCCESSFUL;
3352 /* extract the port from the answer */
3354 status = dcerpc_binding_from_tower(tmp_ctx,
3355 &(towers.twr->tower),
3357 if (!NT_STATUS_IS_OK(status)) {
3361 /* are further checks here necessary? */
3362 if (res_binding->transport != NCACN_IP_TCP) {
3363 status = NT_STATUS_UNSUCCESSFUL;
3367 *pport = (uint16_t)atoi(res_binding->endpoint);
3370 TALLOC_FREE(tmp_ctx);
3375 * Create a rpc pipe client struct, connecting to a host via tcp.
3376 * The port is determined by asking the endpoint mapper on the given
3379 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3380 const struct ndr_syntax_id *abstract_syntax,
3381 struct rpc_pipe_client **presult)
3388 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3389 if (!NT_STATUS_IS_OK(status)) {
3393 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3394 abstract_syntax, presult);
3400 /********************************************************************
3401 Create a rpc pipe client struct, connecting to a unix domain socket
3402 ********************************************************************/
3403 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3404 const struct ndr_syntax_id *abstract_syntax,
3405 struct rpc_pipe_client **presult)
3407 struct rpc_pipe_client *result;
3408 struct sockaddr_un addr;
3412 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3413 if (result == NULL) {
3414 return NT_STATUS_NO_MEMORY;
3417 result->abstract_syntax = *abstract_syntax;
3418 result->transfer_syntax = ndr_transfer_syntax;
3419 result->dispatch = cli_do_rpc_ndr;
3420 result->dispatch_send = cli_do_rpc_ndr_send;
3421 result->dispatch_recv = cli_do_rpc_ndr_recv;
3423 result->desthost = get_myname(result);
3424 result->srv_name_slash = talloc_asprintf_strupper_m(
3425 result, "\\\\%s", result->desthost);
3426 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3427 status = NT_STATUS_NO_MEMORY;
3431 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3432 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3434 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3436 status = map_nt_error_from_unix(errno);
3441 addr.sun_family = AF_UNIX;
3442 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3444 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3445 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3448 return map_nt_error_from_unix(errno);
3451 status = rpc_transport_sock_init(result, fd, &result->transport);
3452 if (!NT_STATUS_IS_OK(status)) {
3457 result->transport->transport = NCALRPC;
3460 return NT_STATUS_OK;
3463 TALLOC_FREE(result);
3467 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3469 struct cli_state *cli;
3471 cli = rpc_pipe_np_smb_conn(p);
3473 DLIST_REMOVE(cli->pipe_list, p);
3478 /****************************************************************************
3479 Open a named pipe over SMB to a remote server.
3481 * CAVEAT CALLER OF THIS FUNCTION:
3482 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3483 * so be sure that this function is called AFTER any structure (vs pointer)
3484 * assignment of the cli. In particular, libsmbclient does structure
3485 * assignments of cli, which invalidates the data in the returned
3486 * rpc_pipe_client if this function is called before the structure assignment
3489 ****************************************************************************/
3491 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3492 const struct ndr_syntax_id *abstract_syntax,
3493 struct rpc_pipe_client **presult)
3495 struct rpc_pipe_client *result;
3498 /* sanity check to protect against crashes */
3501 return NT_STATUS_INVALID_HANDLE;
3504 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3505 if (result == NULL) {
3506 return NT_STATUS_NO_MEMORY;
3509 result->abstract_syntax = *abstract_syntax;
3510 result->transfer_syntax = ndr_transfer_syntax;
3511 result->dispatch = cli_do_rpc_ndr;
3512 result->dispatch_send = cli_do_rpc_ndr_send;
3513 result->dispatch_recv = cli_do_rpc_ndr_recv;
3514 result->desthost = talloc_strdup(result, cli->desthost);
3515 result->srv_name_slash = talloc_asprintf_strupper_m(
3516 result, "\\\\%s", result->desthost);
3518 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3519 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3521 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3522 TALLOC_FREE(result);
3523 return NT_STATUS_NO_MEMORY;
3526 status = rpc_transport_np_init(result, cli, abstract_syntax,
3527 &result->transport);
3528 if (!NT_STATUS_IS_OK(status)) {
3529 TALLOC_FREE(result);
3533 result->transport->transport = NCACN_NP;
3535 DLIST_ADD(cli->pipe_list, result);
3536 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3539 return NT_STATUS_OK;
3542 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3543 struct rpc_cli_smbd_conn *conn,
3544 const struct ndr_syntax_id *syntax,
3545 struct rpc_pipe_client **presult)
3547 struct rpc_pipe_client *result;
3548 struct cli_pipe_auth_data *auth;
3551 result = talloc(mem_ctx, struct rpc_pipe_client);
3552 if (result == NULL) {
3553 return NT_STATUS_NO_MEMORY;
3555 result->abstract_syntax = *syntax;
3556 result->transfer_syntax = ndr_transfer_syntax;
3557 result->dispatch = cli_do_rpc_ndr;
3558 result->dispatch_send = cli_do_rpc_ndr_send;
3559 result->dispatch_recv = cli_do_rpc_ndr_recv;
3560 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3561 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3563 result->desthost = talloc_strdup(result, global_myname());
3564 result->srv_name_slash = talloc_asprintf_strupper_m(
3565 result, "\\\\%s", global_myname());
3566 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3567 TALLOC_FREE(result);
3568 return NT_STATUS_NO_MEMORY;
3571 status = rpc_transport_smbd_init(result, conn, syntax,
3572 &result->transport);
3573 if (!NT_STATUS_IS_OK(status)) {
3574 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3575 nt_errstr(status)));
3576 TALLOC_FREE(result);
3580 status = rpccli_anon_bind_data(result, &auth);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3583 nt_errstr(status)));
3584 TALLOC_FREE(result);
3588 status = rpc_pipe_bind(result, auth);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3591 TALLOC_FREE(result);
3595 result->transport->transport = NCACN_INTERNAL;
3598 return NT_STATUS_OK;
3601 /****************************************************************************
3602 Open a pipe to a remote server.
3603 ****************************************************************************/
3605 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3606 enum dcerpc_transport_t transport,
3607 const struct ndr_syntax_id *interface,
3608 struct rpc_pipe_client **presult)
3610 switch (transport) {
3612 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3615 return rpc_pipe_open_np(cli, interface, presult);
3617 return NT_STATUS_NOT_IMPLEMENTED;
3621 /****************************************************************************
3622 Open a named pipe to an SMB server and bind anonymously.
3623 ****************************************************************************/
3625 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3626 enum dcerpc_transport_t transport,
3627 const struct ndr_syntax_id *interface,
3628 struct rpc_pipe_client **presult)
3630 struct rpc_pipe_client *result;
3631 struct cli_pipe_auth_data *auth;
3634 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3635 if (!NT_STATUS_IS_OK(status)) {
3639 status = rpccli_anon_bind_data(result, &auth);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3642 nt_errstr(status)));
3643 TALLOC_FREE(result);
3648 * This is a bit of an abstraction violation due to the fact that an
3649 * anonymous bind on an authenticated SMB inherits the user/domain
3650 * from the enclosing SMB creds
3653 TALLOC_FREE(auth->user_name);
3654 TALLOC_FREE(auth->domain);
3656 auth->user_name = talloc_strdup(auth, cli->user_name);
3657 auth->domain = talloc_strdup(auth, cli->domain);
3658 auth->user_session_key = data_blob_talloc(auth,
3659 cli->user_session_key.data,
3660 cli->user_session_key.length);
3662 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3663 TALLOC_FREE(result);
3664 return NT_STATUS_NO_MEMORY;
3667 status = rpc_pipe_bind(result, auth);
3668 if (!NT_STATUS_IS_OK(status)) {
3670 if (ndr_syntax_id_equal(interface,
3671 &ndr_table_dssetup.syntax_id)) {
3672 /* non AD domains just don't have this pipe, avoid
3673 * level 0 statement in that case - gd */
3676 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3677 "%s failed with error %s\n",
3678 get_pipe_name_from_iface(interface),
3679 nt_errstr(status) ));
3680 TALLOC_FREE(result);
3684 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3685 "%s and bound anonymously.\n",
3686 get_pipe_name_from_iface(interface), cli->desthost));
3689 return NT_STATUS_OK;
3692 /****************************************************************************
3693 ****************************************************************************/
3695 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3696 const struct ndr_syntax_id *interface,
3697 struct rpc_pipe_client **presult)
3699 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3700 interface, presult);
3703 /****************************************************************************
3704 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3705 ****************************************************************************/
3707 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3708 const struct ndr_syntax_id *interface,
3709 enum dcerpc_transport_t transport,
3710 enum pipe_auth_type auth_type,
3711 enum dcerpc_AuthLevel auth_level,
3713 const char *username,
3714 const char *password,
3715 struct rpc_pipe_client **presult)
3717 struct rpc_pipe_client *result;
3718 struct cli_pipe_auth_data *auth;
3721 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3722 if (!NT_STATUS_IS_OK(status)) {
3726 status = rpccli_ntlmssp_bind_data(
3727 result, auth_type, auth_level, domain, username,
3729 if (!NT_STATUS_IS_OK(status)) {
3730 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3731 nt_errstr(status)));
3735 status = rpc_pipe_bind(result, auth);
3736 if (!NT_STATUS_IS_OK(status)) {
3737 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3738 nt_errstr(status) ));
3742 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3743 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3744 get_pipe_name_from_iface(interface), cli->desthost, domain,
3748 return NT_STATUS_OK;
3752 TALLOC_FREE(result);
3756 /****************************************************************************
3758 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3759 ****************************************************************************/
3761 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3762 const struct ndr_syntax_id *interface,
3763 enum dcerpc_transport_t transport,
3764 enum dcerpc_AuthLevel auth_level,
3766 const char *username,
3767 const char *password,
3768 struct rpc_pipe_client **presult)
3770 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3773 PIPE_AUTH_TYPE_NTLMSSP,
3781 /****************************************************************************
3783 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3784 ****************************************************************************/
3786 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3787 const struct ndr_syntax_id *interface,
3788 enum dcerpc_transport_t transport,
3789 enum dcerpc_AuthLevel auth_level,
3791 const char *username,
3792 const char *password,
3793 struct rpc_pipe_client **presult)
3795 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3798 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3806 /****************************************************************************
3807 Get a the schannel session key out of an already opened netlogon pipe.
3808 ****************************************************************************/
3809 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3810 struct cli_state *cli,
3814 uint32 sec_chan_type = 0;
3815 unsigned char machine_pwd[16];
3816 const char *machine_account;
3819 /* Get the machine account credentials from secrets.tdb. */
3820 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3823 DEBUG(0, ("get_schannel_session_key: could not fetch "
3824 "trust account password for domain '%s'\n",
3826 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3829 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3830 cli->desthost, /* server name */
3831 domain, /* domain */
3832 global_myname(), /* client name */
3833 machine_account, /* machine account name */
3838 if (!NT_STATUS_IS_OK(status)) {
3839 DEBUG(3, ("get_schannel_session_key_common: "
3840 "rpccli_netlogon_setup_creds failed with result %s "
3841 "to server %s, domain %s, machine account %s.\n",
3842 nt_errstr(status), cli->desthost, domain,
3847 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3848 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3850 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3853 return NT_STATUS_OK;;
3856 /****************************************************************************
3857 Open a netlogon pipe and get the schannel session key.
3858 Now exposed to external callers.
3859 ****************************************************************************/
3862 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3865 struct rpc_pipe_client **presult)
3867 struct rpc_pipe_client *netlogon_pipe = NULL;
3870 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3872 if (!NT_STATUS_IS_OK(status)) {
3876 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3878 if (!NT_STATUS_IS_OK(status)) {
3879 TALLOC_FREE(netlogon_pipe);
3883 *presult = netlogon_pipe;
3884 return NT_STATUS_OK;
3887 /****************************************************************************
3889 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3890 using session_key. sign and seal.
3892 The *pdc will be stolen onto this new pipe
3893 ****************************************************************************/
3895 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3896 const struct ndr_syntax_id *interface,
3897 enum dcerpc_transport_t transport,
3898 enum dcerpc_AuthLevel auth_level,
3900 struct netlogon_creds_CredentialState **pdc,
3901 struct rpc_pipe_client **presult)
3903 struct rpc_pipe_client *result;
3904 struct cli_pipe_auth_data *auth;
3907 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3908 if (!NT_STATUS_IS_OK(status)) {
3912 status = rpccli_schannel_bind_data(result, domain, auth_level,
3914 if (!NT_STATUS_IS_OK(status)) {
3915 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3916 nt_errstr(status)));
3917 TALLOC_FREE(result);
3921 status = rpc_pipe_bind(result, auth);
3922 if (!NT_STATUS_IS_OK(status)) {
3923 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3924 "cli_rpc_pipe_bind failed with error %s\n",
3925 nt_errstr(status) ));
3926 TALLOC_FREE(result);
3931 * The credentials on a new netlogon pipe are the ones we are passed
3932 * in - reference them in
3934 result->dc = talloc_move(result, pdc);
3935 if (result->dc == NULL) {
3936 DEBUG(0, ("talloc reference failed\n"));
3937 TALLOC_FREE(result);
3938 return NT_STATUS_NO_MEMORY;
3941 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3942 "for domain %s and bound using schannel.\n",
3943 get_pipe_name_from_iface(interface),
3944 cli->desthost, domain ));
3947 return NT_STATUS_OK;
3950 /****************************************************************************
3951 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3952 Fetch the session key ourselves using a temporary netlogon pipe. This
3953 version uses an ntlmssp auth bound netlogon pipe to get the key.
3954 ****************************************************************************/
3956 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3958 const char *username,
3959 const char *password,
3961 struct rpc_pipe_client **presult)
3963 struct rpc_pipe_client *netlogon_pipe = NULL;
3966 status = cli_rpc_pipe_open_spnego_ntlmssp(
3967 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3968 DCERPC_AUTH_LEVEL_PRIVACY,
3969 domain, username, password, &netlogon_pipe);
3970 if (!NT_STATUS_IS_OK(status)) {
3974 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3976 if (!NT_STATUS_IS_OK(status)) {
3977 TALLOC_FREE(netlogon_pipe);
3981 *presult = netlogon_pipe;
3982 return NT_STATUS_OK;
3985 /****************************************************************************
3986 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3987 Fetch the session key ourselves using a temporary netlogon pipe. This version
3988 uses an ntlmssp bind to get the session key.
3989 ****************************************************************************/
3991 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3992 const struct ndr_syntax_id *interface,
3993 enum dcerpc_transport_t transport,
3994 enum dcerpc_AuthLevel auth_level,
3996 const char *username,
3997 const char *password,
3998 struct rpc_pipe_client **presult)
4000 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4001 struct rpc_pipe_client *netlogon_pipe = NULL;
4002 struct rpc_pipe_client *result = NULL;
4005 status = get_schannel_session_key_auth_ntlmssp(
4006 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4007 if (!NT_STATUS_IS_OK(status)) {
4008 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4009 "key from server %s for domain %s.\n",
4010 cli->desthost, domain ));
4014 status = cli_rpc_pipe_open_schannel_with_key(
4015 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4018 /* Now we've bound using the session key we can close the netlog pipe. */
4019 TALLOC_FREE(netlogon_pipe);
4021 if (NT_STATUS_IS_OK(status)) {
4027 /****************************************************************************
4028 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4029 Fetch the session key ourselves using a temporary netlogon pipe.
4030 ****************************************************************************/
4032 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4033 const struct ndr_syntax_id *interface,
4034 enum dcerpc_transport_t transport,
4035 enum dcerpc_AuthLevel auth_level,
4037 struct rpc_pipe_client **presult)
4039 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4040 struct rpc_pipe_client *netlogon_pipe = NULL;
4041 struct rpc_pipe_client *result = NULL;
4044 status = get_schannel_session_key(cli, domain, &neg_flags,
4046 if (!NT_STATUS_IS_OK(status)) {
4047 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4048 "key from server %s for domain %s.\n",
4049 cli->desthost, domain ));
4053 status = cli_rpc_pipe_open_schannel_with_key(
4054 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4057 /* Now we've bound using the session key we can close the netlog pipe. */
4058 TALLOC_FREE(netlogon_pipe);
4060 if (NT_STATUS_IS_OK(status)) {
4064 return NT_STATUS_OK;
4067 /****************************************************************************
4068 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4069 The idea is this can be called with service_princ, username and password all
4070 NULL so long as the caller has a TGT.
4071 ****************************************************************************/
4073 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4074 const struct ndr_syntax_id *interface,
4075 enum dcerpc_AuthLevel auth_level,
4076 const char *service_princ,
4077 const char *username,
4078 const char *password,
4079 struct rpc_pipe_client **presult)
4082 struct rpc_pipe_client *result;
4083 struct cli_pipe_auth_data *auth;
4086 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4087 if (!NT_STATUS_IS_OK(status)) {
4091 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4092 username, password, &auth);
4093 if (!NT_STATUS_IS_OK(status)) {
4094 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4095 nt_errstr(status)));
4096 TALLOC_FREE(result);
4100 status = rpc_pipe_bind(result, auth);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4103 "with error %s\n", nt_errstr(status)));
4104 TALLOC_FREE(result);
4109 return NT_STATUS_OK;
4111 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4112 return NT_STATUS_NOT_IMPLEMENTED;
4116 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4117 struct rpc_pipe_client *cli,
4118 DATA_BLOB *session_key)
4120 if (!session_key || !cli) {
4121 return NT_STATUS_INVALID_PARAMETER;
4125 return NT_STATUS_INVALID_PARAMETER;
4128 switch (cli->auth->auth_type) {
4129 case PIPE_AUTH_TYPE_SCHANNEL:
4130 *session_key = data_blob_talloc(mem_ctx,
4131 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4133 case PIPE_AUTH_TYPE_NTLMSSP:
4134 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4135 *session_key = data_blob_talloc(mem_ctx,
4136 cli->auth->a_u.ntlmssp_state->session_key.data,
4137 cli->auth->a_u.ntlmssp_state->session_key.length);
4139 case PIPE_AUTH_TYPE_KRB5:
4140 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4141 *session_key = data_blob_talloc(mem_ctx,
4142 cli->auth->a_u.kerberos_auth->session_key.data,
4143 cli->auth->a_u.kerberos_auth->session_key.length);
4145 case PIPE_AUTH_TYPE_NONE:
4146 *session_key = data_blob_talloc(mem_ctx,
4147 cli->auth->user_session_key.data,
4148 cli->auth->user_session_key.length);
4151 return NT_STATUS_NO_USER_SESSION_KEY;
4154 return NT_STATUS_OK;