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 "librpc/gen_ndr/cli_epmapper.h"
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
101 guid_str = GUID_string(talloc_tos(), &interface->uuid);
102 if (guid_str == NULL) {
105 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
106 (int)interface->if_version);
107 TALLOC_FREE(guid_str);
109 if (result == NULL) {
115 /********************************************************************
116 Map internal value to wire value.
117 ********************************************************************/
119 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
123 case PIPE_AUTH_TYPE_NONE:
124 return RPC_ANONYMOUS_AUTH_TYPE;
126 case PIPE_AUTH_TYPE_NTLMSSP:
127 return RPC_NTLMSSP_AUTH_TYPE;
129 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
130 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
131 return RPC_SPNEGO_AUTH_TYPE;
133 case PIPE_AUTH_TYPE_SCHANNEL:
134 return RPC_SCHANNEL_AUTH_TYPE;
136 case PIPE_AUTH_TYPE_KRB5:
137 return RPC_KRB5_AUTH_TYPE;
140 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
142 (unsigned int)auth_type ));
148 /********************************************************************
149 Pipe description for a DEBUG
150 ********************************************************************/
151 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
152 struct rpc_pipe_client *cli)
154 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
155 if (result == NULL) {
161 /********************************************************************
163 ********************************************************************/
165 static uint32 get_rpc_call_id(void)
167 static uint32 call_id = 0;
172 * Realloc pdu to have a least "size" bytes
175 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
179 if (prs_data_size(pdu) >= size) {
183 extra_size = size - prs_data_size(pdu);
185 if (!prs_force_grow(pdu, extra_size)) {
186 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
187 "%d bytes.\n", (int)extra_size));
191 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
192 (int)extra_size, prs_data_size(pdu)));
197 /*******************************************************************
198 Use SMBreadX to get rest of one fragment's worth of rpc data.
199 Reads the whole size or give an error message
200 ********************************************************************/
202 struct rpc_read_state {
203 struct event_context *ev;
204 struct rpc_cli_transport *transport;
210 static void rpc_read_done(struct async_req *subreq);
212 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
213 struct event_context *ev,
214 struct rpc_cli_transport *transport,
215 uint8_t *data, size_t size)
217 struct tevent_req *req;
218 struct async_req *subreq;
219 struct rpc_read_state *state;
221 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
226 state->transport = transport;
231 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
233 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
235 if (subreq == NULL) {
238 subreq->async.fn = rpc_read_done;
239 subreq->async.priv = req;
247 static void rpc_read_done(struct async_req *subreq)
249 struct tevent_req *req = talloc_get_type_abort(
250 subreq->async.priv, struct tevent_req);
251 struct rpc_read_state *state = tevent_req_data(
252 req, struct rpc_read_state);
256 status = state->transport->read_recv(subreq, &received);
258 if (!NT_STATUS_IS_OK(status)) {
259 tevent_req_nterror(req, status);
263 state->num_read += received;
264 if (state->num_read == state->size) {
265 tevent_req_done(req);
269 subreq = state->transport->read_send(state, state->ev,
270 state->data + state->num_read,
271 state->size - state->num_read,
272 state->transport->priv);
273 if (tevent_req_nomem(subreq, req)) {
276 subreq->async.fn = rpc_read_done;
277 subreq->async.priv = req;
280 static NTSTATUS rpc_read_recv(struct tevent_req *req)
282 return tevent_req_simple_recv_ntstatus(req);
285 struct rpc_write_state {
286 struct event_context *ev;
287 struct rpc_cli_transport *transport;
293 static void rpc_write_done(struct async_req *subreq);
295 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
296 struct event_context *ev,
297 struct rpc_cli_transport *transport,
298 const uint8_t *data, size_t size)
300 struct tevent_req *req;
301 struct async_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 subreq->async.fn = rpc_write_done;
321 subreq->async.priv = req;
328 static void rpc_write_done(struct async_req *subreq)
330 struct tevent_req *req = talloc_get_type_abort(
331 subreq->async.priv, struct tevent_req);
332 struct rpc_write_state *state = tevent_req_data(
333 req, struct rpc_write_state);
337 status = state->transport->write_recv(subreq, &written);
339 if (!NT_STATUS_IS_OK(status)) {
340 tevent_req_nterror(req, status);
344 state->num_written += written;
346 if (state->num_written == state->size) {
347 tevent_req_done(req);
351 subreq = state->transport->write_send(state, state->ev,
352 state->data + state->num_written,
353 state->size - state->num_written,
354 state->transport->priv);
355 if (tevent_req_nomem(subreq, req)) {
358 subreq->async.fn = rpc_write_done;
359 subreq->async.priv = req;
362 static NTSTATUS rpc_write_recv(struct tevent_req *req)
364 return tevent_req_simple_recv_ntstatus(req);
368 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
369 struct rpc_hdr_info *prhdr,
373 * This next call sets the endian bit correctly in current_pdu. We
374 * will propagate this to rbuf later.
377 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
378 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
379 return NT_STATUS_BUFFER_TOO_SMALL;
382 if (prhdr->frag_len > cli->max_recv_frag) {
383 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
384 " we only allow %d\n", (int)prhdr->frag_len,
385 (int)cli->max_recv_frag));
386 return NT_STATUS_BUFFER_TOO_SMALL;
392 /****************************************************************************
393 Try and get a PDU's worth of data from current_pdu. If not, then read more
395 ****************************************************************************/
397 struct get_complete_frag_state {
398 struct event_context *ev;
399 struct rpc_pipe_client *cli;
400 struct rpc_hdr_info *prhdr;
404 static void get_complete_frag_got_header(struct tevent_req *subreq);
405 static void get_complete_frag_got_rest(struct tevent_req *subreq);
407 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
408 struct event_context *ev,
409 struct rpc_pipe_client *cli,
410 struct rpc_hdr_info *prhdr,
413 struct tevent_req *req, *subreq;
414 struct get_complete_frag_state *state;
418 req = tevent_req_create(mem_ctx, &state,
419 struct get_complete_frag_state);
425 state->prhdr = prhdr;
428 pdu_len = prs_data_size(pdu);
429 if (pdu_len < RPC_HEADER_LEN) {
430 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
431 status = NT_STATUS_NO_MEMORY;
434 subreq = rpc_read_send(
436 state->cli->transport,
437 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
438 RPC_HEADER_LEN - pdu_len);
439 if (subreq == NULL) {
440 status = NT_STATUS_NO_MEMORY;
443 tevent_req_set_callback(subreq, get_complete_frag_got_header,
448 status = parse_rpc_header(cli, prhdr, pdu);
449 if (!NT_STATUS_IS_OK(status)) {
454 * Ensure we have frag_len bytes of data.
456 if (pdu_len < prhdr->frag_len) {
457 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
458 status = NT_STATUS_NO_MEMORY;
461 subreq = rpc_read_send(state, state->ev,
462 state->cli->transport,
463 (uint8_t *)(prs_data_p(pdu) + pdu_len),
464 prhdr->frag_len - pdu_len);
465 if (subreq == NULL) {
466 status = NT_STATUS_NO_MEMORY;
469 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
474 status = NT_STATUS_OK;
476 if (NT_STATUS_IS_OK(status)) {
477 tevent_req_done(req);
479 tevent_req_nterror(req, status);
481 return tevent_req_post(req, ev);
484 static void get_complete_frag_got_header(struct tevent_req *subreq)
486 struct tevent_req *req = tevent_req_callback_data(
487 subreq, struct tevent_req);
488 struct get_complete_frag_state *state = tevent_req_data(
489 req, struct get_complete_frag_state);
492 status = rpc_read_recv(subreq);
494 if (!NT_STATUS_IS_OK(status)) {
495 tevent_req_nterror(req, status);
499 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
500 if (!NT_STATUS_IS_OK(status)) {
501 tevent_req_nterror(req, status);
505 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
506 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
511 * We're here in this piece of code because we've read exactly
512 * RPC_HEADER_LEN bytes into state->pdu.
515 subreq = rpc_read_send(
516 state, state->ev, state->cli->transport,
517 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
518 state->prhdr->frag_len - RPC_HEADER_LEN);
519 if (tevent_req_nomem(subreq, req)) {
522 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
525 static void get_complete_frag_got_rest(struct tevent_req *subreq)
527 struct tevent_req *req = tevent_req_callback_data(
528 subreq, struct tevent_req);
531 status = rpc_read_recv(subreq);
533 if (!NT_STATUS_IS_OK(status)) {
534 tevent_req_nterror(req, status);
537 tevent_req_done(req);
540 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
542 return tevent_req_simple_recv_ntstatus(req);
545 /****************************************************************************
546 NTLMSSP specific sign/seal.
547 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
548 In fact I should probably abstract these into identical pieces of code... JRA.
549 ****************************************************************************/
551 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
552 prs_struct *current_pdu,
553 uint8 *p_ss_padding_len)
555 RPC_HDR_AUTH auth_info;
556 uint32 save_offset = prs_offset(current_pdu);
557 uint32 auth_len = prhdr->auth_len;
558 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
559 unsigned char *data = NULL;
561 unsigned char *full_packet_data = NULL;
562 size_t full_packet_data_len;
566 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
567 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
571 if (!ntlmssp_state) {
572 return NT_STATUS_INVALID_PARAMETER;
575 /* Ensure there's enough data for an authenticated response. */
576 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
577 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
578 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
579 (unsigned int)auth_len ));
580 return NT_STATUS_BUFFER_TOO_SMALL;
584 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
585 * after the RPC header.
586 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
587 * functions as NTLMv2 checks the rpc headers also.
590 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
591 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
593 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
594 full_packet_data_len = prhdr->frag_len - auth_len;
596 /* Pull the auth header and the following data into a blob. */
597 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
598 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
599 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
600 return NT_STATUS_BUFFER_TOO_SMALL;
603 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
604 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
605 return NT_STATUS_BUFFER_TOO_SMALL;
608 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
609 auth_blob.length = auth_len;
611 switch (cli->auth->auth_level) {
612 case PIPE_AUTH_LEVEL_PRIVACY:
613 /* Data is encrypted. */
614 status = ntlmssp_unseal_packet(ntlmssp_state,
617 full_packet_data_len,
619 if (!NT_STATUS_IS_OK(status)) {
620 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
621 "packet from %s. Error was %s.\n",
622 rpccli_pipe_txt(debug_ctx(), cli),
623 nt_errstr(status) ));
627 case PIPE_AUTH_LEVEL_INTEGRITY:
628 /* Data is signed. */
629 status = ntlmssp_check_packet(ntlmssp_state,
632 full_packet_data_len,
634 if (!NT_STATUS_IS_OK(status)) {
635 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
636 "packet from %s. Error was %s.\n",
637 rpccli_pipe_txt(debug_ctx(), cli),
638 nt_errstr(status) ));
643 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
644 "auth level %d\n", cli->auth->auth_level));
645 return NT_STATUS_INVALID_INFO_CLASS;
649 * Return the current pointer to the data offset.
652 if(!prs_set_offset(current_pdu, save_offset)) {
653 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
654 (unsigned int)save_offset ));
655 return NT_STATUS_BUFFER_TOO_SMALL;
659 * Remember the padding length. We must remove it from the real data
660 * stream once the sign/seal is done.
663 *p_ss_padding_len = auth_info.auth_pad_len;
668 /****************************************************************************
669 schannel specific sign/seal.
670 ****************************************************************************/
672 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
673 prs_struct *current_pdu,
674 uint8 *p_ss_padding_len)
676 RPC_HDR_AUTH auth_info;
677 RPC_AUTH_SCHANNEL_CHK schannel_chk;
678 uint32 auth_len = prhdr->auth_len;
679 uint32 save_offset = prs_offset(current_pdu);
680 struct schannel_auth_struct *schannel_auth =
681 cli->auth->a_u.schannel_auth;
684 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
685 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
689 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
690 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
691 return NT_STATUS_INVALID_PARAMETER;
694 if (!schannel_auth) {
695 return NT_STATUS_INVALID_PARAMETER;
698 /* Ensure there's enough data for an authenticated response. */
699 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
700 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
701 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
702 (unsigned int)auth_len ));
703 return NT_STATUS_INVALID_PARAMETER;
706 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
708 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
709 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
710 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
711 return NT_STATUS_BUFFER_TOO_SMALL;
714 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
715 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
716 return NT_STATUS_BUFFER_TOO_SMALL;
719 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
720 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
721 auth_info.auth_type));
722 return NT_STATUS_BUFFER_TOO_SMALL;
725 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
726 &schannel_chk, current_pdu, 0)) {
727 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
728 return NT_STATUS_BUFFER_TOO_SMALL;
731 if (!schannel_decode(schannel_auth,
732 cli->auth->auth_level,
735 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
737 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
738 "Connection to %s.\n",
739 rpccli_pipe_txt(debug_ctx(), cli)));
740 return NT_STATUS_INVALID_PARAMETER;
743 /* The sequence number gets incremented on both send and receive. */
744 schannel_auth->seq_num++;
747 * Return the current pointer to the data offset.
750 if(!prs_set_offset(current_pdu, save_offset)) {
751 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
752 (unsigned int)save_offset ));
753 return NT_STATUS_BUFFER_TOO_SMALL;
757 * Remember the padding length. We must remove it from the real data
758 * stream once the sign/seal is done.
761 *p_ss_padding_len = auth_info.auth_pad_len;
766 /****************************************************************************
767 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
768 ****************************************************************************/
770 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
771 prs_struct *current_pdu,
772 uint8 *p_ss_padding_len)
774 NTSTATUS ret = NT_STATUS_OK;
776 /* Paranioa checks for auth_len. */
777 if (prhdr->auth_len) {
778 if (prhdr->auth_len > prhdr->frag_len) {
779 return NT_STATUS_INVALID_PARAMETER;
782 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
783 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
784 /* Integer wrap attempt. */
785 return NT_STATUS_INVALID_PARAMETER;
790 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
793 switch(cli->auth->auth_type) {
794 case PIPE_AUTH_TYPE_NONE:
795 if (prhdr->auth_len) {
796 DEBUG(3, ("cli_pipe_validate_rpc_response: "
797 "Connection to %s - got non-zero "
799 rpccli_pipe_txt(debug_ctx(), cli),
800 (unsigned int)prhdr->auth_len ));
801 return NT_STATUS_INVALID_PARAMETER;
805 case PIPE_AUTH_TYPE_NTLMSSP:
806 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
807 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
808 if (!NT_STATUS_IS_OK(ret)) {
813 case PIPE_AUTH_TYPE_SCHANNEL:
814 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
815 if (!NT_STATUS_IS_OK(ret)) {
820 case PIPE_AUTH_TYPE_KRB5:
821 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
823 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
824 "to %s - unknown internal auth type %u.\n",
825 rpccli_pipe_txt(debug_ctx(), cli),
826 cli->auth->auth_type ));
827 return NT_STATUS_INVALID_INFO_CLASS;
833 /****************************************************************************
834 Do basic authentication checks on an incoming pdu.
835 ****************************************************************************/
837 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
838 prs_struct *current_pdu,
839 uint8 expected_pkt_type,
842 prs_struct *return_data)
845 NTSTATUS ret = NT_STATUS_OK;
846 uint32 current_pdu_len = prs_data_size(current_pdu);
848 if (current_pdu_len != prhdr->frag_len) {
849 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
850 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
851 return NT_STATUS_INVALID_PARAMETER;
855 * Point the return values at the real data including the RPC
856 * header. Just in case the caller wants it.
858 *ppdata = prs_data_p(current_pdu);
859 *pdata_len = current_pdu_len;
861 /* Ensure we have the correct type. */
862 switch (prhdr->pkt_type) {
863 case RPC_ALTCONTRESP:
866 /* Alter context and bind ack share the same packet definitions. */
872 RPC_HDR_RESP rhdr_resp;
873 uint8 ss_padding_len = 0;
875 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
876 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
877 return NT_STATUS_BUFFER_TOO_SMALL;
880 /* Here's where we deal with incoming sign/seal. */
881 ret = cli_pipe_validate_rpc_response(cli, prhdr,
882 current_pdu, &ss_padding_len);
883 if (!NT_STATUS_IS_OK(ret)) {
887 /* Point the return values at the NDR data. Remember to remove any ss padding. */
888 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
890 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
891 return NT_STATUS_BUFFER_TOO_SMALL;
894 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
896 /* Remember to remove the auth footer. */
897 if (prhdr->auth_len) {
898 /* We've already done integer wrap tests on auth_len in
899 cli_pipe_validate_rpc_response(). */
900 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
901 return NT_STATUS_BUFFER_TOO_SMALL;
903 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
906 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
907 current_pdu_len, *pdata_len, ss_padding_len ));
910 * If this is the first reply, and the allocation hint is reasonably, try and
911 * set up the return_data parse_struct to the correct size.
914 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
915 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
916 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
917 "too large to allocate\n",
918 (unsigned int)rhdr_resp.alloc_hint ));
919 return NT_STATUS_NO_MEMORY;
927 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
928 "received from %s!\n",
929 rpccli_pipe_txt(debug_ctx(), cli)));
930 /* Use this for now... */
931 return NT_STATUS_NETWORK_ACCESS_DENIED;
935 RPC_HDR_RESP rhdr_resp;
936 RPC_HDR_FAULT fault_resp;
938 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
939 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
940 return NT_STATUS_BUFFER_TOO_SMALL;
943 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
944 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
945 return NT_STATUS_BUFFER_TOO_SMALL;
948 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
949 "code %s received from %s!\n",
950 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
951 rpccli_pipe_txt(debug_ctx(), cli)));
952 if (NT_STATUS_IS_OK(fault_resp.status)) {
953 return NT_STATUS_UNSUCCESSFUL;
955 return fault_resp.status;
960 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
962 (unsigned int)prhdr->pkt_type,
963 rpccli_pipe_txt(debug_ctx(), cli)));
964 return NT_STATUS_INVALID_INFO_CLASS;
967 if (prhdr->pkt_type != expected_pkt_type) {
968 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
969 "got an unexpected RPC packet type - %u, not %u\n",
970 rpccli_pipe_txt(debug_ctx(), cli),
973 return NT_STATUS_INVALID_INFO_CLASS;
976 /* Do this just before return - we don't want to modify any rpc header
977 data before now as we may have needed to do cryptographic actions on
980 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
981 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
982 "setting fragment first/last ON.\n"));
983 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
989 /****************************************************************************
990 Ensure we eat the just processed pdu from the current_pdu prs_struct.
991 Normally the frag_len and buffer size will match, but on the first trans
992 reply there is a theoretical chance that buffer size > frag_len, so we must
994 ****************************************************************************/
996 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
998 uint32 current_pdu_len = prs_data_size(current_pdu);
1000 if (current_pdu_len < prhdr->frag_len) {
1001 return NT_STATUS_BUFFER_TOO_SMALL;
1005 if (current_pdu_len == (uint32)prhdr->frag_len) {
1006 prs_mem_free(current_pdu);
1007 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1008 /* Make current_pdu dynamic with no memory. */
1009 prs_give_memory(current_pdu, 0, 0, True);
1010 return NT_STATUS_OK;
1014 * Oh no ! More data in buffer than we processed in current pdu.
1015 * Cheat. Move the data down and shrink the buffer.
1018 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1019 current_pdu_len - prhdr->frag_len);
1021 /* Remember to set the read offset back to zero. */
1022 prs_set_offset(current_pdu, 0);
1024 /* Shrink the buffer. */
1025 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1026 return NT_STATUS_BUFFER_TOO_SMALL;
1029 return NT_STATUS_OK;
1032 /****************************************************************************
1033 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1034 ****************************************************************************/
1036 struct cli_api_pipe_state {
1037 struct event_context *ev;
1038 struct rpc_cli_transport *transport;
1043 static void cli_api_pipe_trans_done(struct async_req *subreq);
1044 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1045 static void cli_api_pipe_read_done(struct async_req *subreq);
1047 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1048 struct event_context *ev,
1049 struct rpc_cli_transport *transport,
1050 uint8_t *data, size_t data_len,
1051 uint32_t max_rdata_len)
1053 struct tevent_req *req;
1054 struct async_req *subreq;
1055 struct tevent_req *subreq2;
1056 struct cli_api_pipe_state *state;
1059 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1064 state->transport = transport;
1066 if (max_rdata_len < RPC_HEADER_LEN) {
1068 * For a RPC reply we always need at least RPC_HEADER_LEN
1069 * bytes. We check this here because we will receive
1070 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1072 status = NT_STATUS_INVALID_PARAMETER;
1076 if (transport->trans_send != NULL) {
1077 subreq = transport->trans_send(state, ev, data, data_len,
1078 max_rdata_len, transport->priv);
1079 if (subreq == NULL) {
1080 status = NT_STATUS_NO_MEMORY;
1083 subreq->async.fn = cli_api_pipe_trans_done;
1084 subreq->async.priv = req;
1089 * If the transport does not provide a "trans" routine, i.e. for
1090 * example the ncacn_ip_tcp transport, do the write/read step here.
1093 subreq2 = rpc_write_send(state, ev, transport, data, data_len);
1094 if (subreq2 == NULL) {
1097 tevent_req_set_callback(subreq2, cli_api_pipe_write_done, req);
1100 status = NT_STATUS_INVALID_PARAMETER;
1103 if (NT_STATUS_IS_OK(status)) {
1104 tevent_req_done(req);
1106 tevent_req_nterror(req, status);
1108 return tevent_req_post(req, ev);
1114 static void cli_api_pipe_trans_done(struct async_req *subreq)
1116 struct tevent_req *req = talloc_get_type_abort(
1117 subreq->async.priv, struct tevent_req);
1118 struct cli_api_pipe_state *state = tevent_req_data(
1119 req, struct cli_api_pipe_state);
1122 status = state->transport->trans_recv(subreq, state, &state->rdata,
1124 TALLOC_FREE(subreq);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 tevent_req_nterror(req, status);
1129 tevent_req_done(req);
1132 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1134 struct tevent_req *req = tevent_req_callback_data(
1135 subreq, struct tevent_req);
1136 struct cli_api_pipe_state *state = tevent_req_data(
1137 req, struct cli_api_pipe_state);
1138 struct async_req *subreq2;
1141 status = rpc_write_recv(subreq);
1142 TALLOC_FREE(subreq);
1143 if (!NT_STATUS_IS_OK(status)) {
1144 tevent_req_nterror(req, status);
1148 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1149 if (tevent_req_nomem(state->rdata, req)) {
1154 * We don't need to use rpc_read_send here, the upper layer will cope
1155 * with a short read, transport->trans_send could also return less
1156 * than state->max_rdata_len.
1158 subreq2 = state->transport->read_send(state, state->ev, state->rdata,
1160 state->transport->priv);
1161 if (tevent_req_nomem(subreq2, req)) {
1164 subreq2->async.fn = cli_api_pipe_read_done;
1165 subreq2->async.priv = req;
1168 static void cli_api_pipe_read_done(struct async_req *subreq)
1170 struct tevent_req *req = talloc_get_type_abort(
1171 subreq->async.priv, struct tevent_req);
1172 struct cli_api_pipe_state *state = tevent_req_data(
1173 req, struct cli_api_pipe_state);
1177 status = state->transport->read_recv(subreq, &received);
1178 TALLOC_FREE(subreq);
1179 if (!NT_STATUS_IS_OK(status)) {
1180 tevent_req_nterror(req, status);
1183 state->rdata_len = received;
1184 tevent_req_done(req);
1187 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1188 uint8_t **prdata, uint32_t *prdata_len)
1190 struct cli_api_pipe_state *state = tevent_req_data(
1191 req, struct cli_api_pipe_state);
1194 if (tevent_req_is_nterror(req, &status)) {
1198 *prdata = talloc_move(mem_ctx, &state->rdata);
1199 *prdata_len = state->rdata_len;
1200 return NT_STATUS_OK;
1203 /****************************************************************************
1204 Send data on an rpc pipe via trans. The prs_struct data must be the last
1205 pdu fragment of an NDR data stream.
1207 Receive response data from an rpc pipe, which may be large...
1209 Read the first fragment: unfortunately have to use SMBtrans for the first
1210 bit, then SMBreadX for subsequent bits.
1212 If first fragment received also wasn't the last fragment, continue
1213 getting fragments until we _do_ receive the last fragment.
1215 Request/Response PDU's look like the following...
1217 |<------------------PDU len----------------------------------------------->|
1218 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1220 +------------+-----------------+-------------+---------------+-------------+
1221 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1222 +------------+-----------------+-------------+---------------+-------------+
1224 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1225 signing & sealing being negotiated.
1227 ****************************************************************************/
1229 struct rpc_api_pipe_state {
1230 struct event_context *ev;
1231 struct rpc_pipe_client *cli;
1232 uint8_t expected_pkt_type;
1234 prs_struct incoming_frag;
1235 struct rpc_hdr_info rhdr;
1237 prs_struct incoming_pdu; /* Incoming reply */
1238 uint32_t incoming_pdu_offset;
1241 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1243 prs_mem_free(&state->incoming_frag);
1244 prs_mem_free(&state->incoming_pdu);
1248 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1249 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1251 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1252 struct event_context *ev,
1253 struct rpc_pipe_client *cli,
1254 prs_struct *data, /* Outgoing PDU */
1255 uint8_t expected_pkt_type)
1257 struct tevent_req *req, *subreq;
1258 struct rpc_api_pipe_state *state;
1259 uint16_t max_recv_frag;
1262 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1268 state->expected_pkt_type = expected_pkt_type;
1269 state->incoming_pdu_offset = 0;
1271 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1273 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1274 /* Make incoming_pdu dynamic with no memory. */
1275 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1277 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1280 * Ensure we're not sending too much.
1282 if (prs_offset(data) > cli->max_xmit_frag) {
1283 status = NT_STATUS_INVALID_PARAMETER;
1287 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1289 max_recv_frag = cli->max_recv_frag;
1292 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1295 subreq = cli_api_pipe_send(state, ev, cli->transport,
1296 (uint8_t *)prs_data_p(data),
1297 prs_offset(data), max_recv_frag);
1298 if (subreq == NULL) {
1301 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1305 tevent_req_nterror(req, status);
1306 return tevent_req_post(req, ev);
1312 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1314 struct tevent_req *req = tevent_req_callback_data(
1315 subreq, struct tevent_req);
1316 struct rpc_api_pipe_state *state = tevent_req_data(
1317 req, struct rpc_api_pipe_state);
1319 uint8_t *rdata = NULL;
1320 uint32_t rdata_len = 0;
1323 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1324 TALLOC_FREE(subreq);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1327 tevent_req_nterror(req, status);
1331 if (rdata == NULL) {
1332 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1333 rpccli_pipe_txt(debug_ctx(), state->cli)));
1334 tevent_req_done(req);
1339 * Give the memory received from cli_trans as dynamic to the current
1340 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1343 rdata_copy = (char *)memdup(rdata, rdata_len);
1345 if (tevent_req_nomem(rdata_copy, req)) {
1348 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1350 /* Ensure we have enough data for a pdu. */
1351 subreq = get_complete_frag_send(state, state->ev, state->cli,
1352 &state->rhdr, &state->incoming_frag);
1353 if (tevent_req_nomem(subreq, req)) {
1356 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1359 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1361 struct tevent_req *req = tevent_req_callback_data(
1362 subreq, struct tevent_req);
1363 struct rpc_api_pipe_state *state = tevent_req_data(
1364 req, struct rpc_api_pipe_state);
1367 uint32_t rdata_len = 0;
1369 status = get_complete_frag_recv(subreq);
1370 TALLOC_FREE(subreq);
1371 if (!NT_STATUS_IS_OK(status)) {
1372 DEBUG(5, ("get_complete_frag failed: %s\n",
1373 nt_errstr(status)));
1374 tevent_req_nterror(req, status);
1378 status = cli_pipe_validate_current_pdu(
1379 state->cli, &state->rhdr, &state->incoming_frag,
1380 state->expected_pkt_type, &rdata, &rdata_len,
1381 &state->incoming_pdu);
1383 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1384 (unsigned)prs_data_size(&state->incoming_frag),
1385 (unsigned)state->incoming_pdu_offset,
1386 nt_errstr(status)));
1388 if (!NT_STATUS_IS_OK(status)) {
1389 tevent_req_nterror(req, status);
1393 if ((state->rhdr.flags & RPC_FLG_FIRST)
1394 && (state->rhdr.pack_type[0] == 0)) {
1396 * Set the data type correctly for big-endian data on the
1399 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1401 rpccli_pipe_txt(debug_ctx(), state->cli)));
1402 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1405 * Check endianness on subsequent packets.
1407 if (state->incoming_frag.bigendian_data
1408 != state->incoming_pdu.bigendian_data) {
1409 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1411 state->incoming_pdu.bigendian_data?"big":"little",
1412 state->incoming_frag.bigendian_data?"big":"little"));
1413 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1417 /* Now copy the data portion out of the pdu into rbuf. */
1418 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1419 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1423 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1424 rdata, (size_t)rdata_len);
1425 state->incoming_pdu_offset += rdata_len;
1427 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1428 &state->incoming_frag);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 tevent_req_nterror(req, status);
1434 if (state->rhdr.flags & RPC_FLG_LAST) {
1435 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1436 rpccli_pipe_txt(debug_ctx(), state->cli),
1437 (unsigned)prs_data_size(&state->incoming_pdu)));
1438 tevent_req_done(req);
1442 subreq = get_complete_frag_send(state, state->ev, state->cli,
1443 &state->rhdr, &state->incoming_frag);
1444 if (tevent_req_nomem(subreq, req)) {
1447 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1450 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1451 prs_struct *reply_pdu)
1453 struct rpc_api_pipe_state *state = tevent_req_data(
1454 req, struct rpc_api_pipe_state);
1457 if (tevent_req_is_nterror(req, &status)) {
1461 *reply_pdu = state->incoming_pdu;
1462 reply_pdu->mem_ctx = mem_ctx;
1465 * Prevent state->incoming_pdu from being freed in
1466 * rpc_api_pipe_state_destructor()
1468 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1470 return NT_STATUS_OK;
1473 /*******************************************************************
1474 Creates krb5 auth bind.
1475 ********************************************************************/
1477 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1478 enum pipe_auth_level auth_level,
1479 RPC_HDR_AUTH *pauth_out,
1480 prs_struct *auth_data)
1484 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1485 DATA_BLOB tkt = data_blob_null;
1486 DATA_BLOB tkt_wrapped = data_blob_null;
1488 /* We may change the pad length before marshalling. */
1489 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1491 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1492 a->service_principal ));
1494 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1496 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1497 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1500 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1502 a->service_principal,
1503 error_message(ret) ));
1505 data_blob_free(&tkt);
1506 prs_mem_free(auth_data);
1507 return NT_STATUS_INVALID_PARAMETER;
1510 /* wrap that up in a nice GSS-API wrapping */
1511 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1513 data_blob_free(&tkt);
1515 /* Auth len in the rpc header doesn't include auth_header. */
1516 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1517 data_blob_free(&tkt_wrapped);
1518 prs_mem_free(auth_data);
1519 return NT_STATUS_NO_MEMORY;
1522 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1523 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1525 data_blob_free(&tkt_wrapped);
1526 return NT_STATUS_OK;
1528 return NT_STATUS_INVALID_PARAMETER;
1532 /*******************************************************************
1533 Creates SPNEGO NTLMSSP auth bind.
1534 ********************************************************************/
1536 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1537 enum pipe_auth_level auth_level,
1538 RPC_HDR_AUTH *pauth_out,
1539 prs_struct *auth_data)
1542 DATA_BLOB null_blob = data_blob_null;
1543 DATA_BLOB request = data_blob_null;
1544 DATA_BLOB spnego_msg = data_blob_null;
1546 /* We may change the pad length before marshalling. */
1547 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1549 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1550 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1554 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1555 data_blob_free(&request);
1556 prs_mem_free(auth_data);
1560 /* Wrap this in SPNEGO. */
1561 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1563 data_blob_free(&request);
1565 /* Auth len in the rpc header doesn't include auth_header. */
1566 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1567 data_blob_free(&spnego_msg);
1568 prs_mem_free(auth_data);
1569 return NT_STATUS_NO_MEMORY;
1572 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1573 dump_data(5, spnego_msg.data, spnego_msg.length);
1575 data_blob_free(&spnego_msg);
1576 return NT_STATUS_OK;
1579 /*******************************************************************
1580 Creates NTLMSSP auth bind.
1581 ********************************************************************/
1583 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1584 enum pipe_auth_level auth_level,
1585 RPC_HDR_AUTH *pauth_out,
1586 prs_struct *auth_data)
1589 DATA_BLOB null_blob = data_blob_null;
1590 DATA_BLOB request = data_blob_null;
1592 /* We may change the pad length before marshalling. */
1593 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1595 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1596 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1600 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1601 data_blob_free(&request);
1602 prs_mem_free(auth_data);
1606 /* Auth len in the rpc header doesn't include auth_header. */
1607 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1608 data_blob_free(&request);
1609 prs_mem_free(auth_data);
1610 return NT_STATUS_NO_MEMORY;
1613 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1614 dump_data(5, request.data, request.length);
1616 data_blob_free(&request);
1617 return NT_STATUS_OK;
1620 /*******************************************************************
1621 Creates schannel auth bind.
1622 ********************************************************************/
1624 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1625 enum pipe_auth_level auth_level,
1626 RPC_HDR_AUTH *pauth_out,
1627 prs_struct *auth_data)
1629 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1631 /* We may change the pad length before marshalling. */
1632 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1634 /* Use lp_workgroup() if domain not specified */
1636 if (!cli->auth->domain || !cli->auth->domain[0]) {
1637 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1638 if (cli->auth->domain == NULL) {
1639 return NT_STATUS_NO_MEMORY;
1643 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1647 * Now marshall the data into the auth parse_struct.
1650 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1651 &schannel_neg, auth_data, 0)) {
1652 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1653 prs_mem_free(auth_data);
1654 return NT_STATUS_NO_MEMORY;
1657 return NT_STATUS_OK;
1660 /*******************************************************************
1661 Creates the internals of a DCE/RPC bind request or alter context PDU.
1662 ********************************************************************/
1664 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1665 prs_struct *rpc_out,
1667 const RPC_IFACE *abstract,
1668 const RPC_IFACE *transfer,
1669 RPC_HDR_AUTH *phdr_auth,
1670 prs_struct *pauth_info)
1674 RPC_CONTEXT rpc_ctx;
1675 uint16 auth_len = prs_offset(pauth_info);
1676 uint8 ss_padding_len = 0;
1677 uint16 frag_len = 0;
1679 /* create the RPC context. */
1680 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1682 /* create the bind request RPC_HDR_RB */
1683 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1685 /* Start building the frag length. */
1686 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1688 /* Do we need to pad ? */
1690 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1692 ss_padding_len = 8 - (data_len % 8);
1693 phdr_auth->auth_pad_len = ss_padding_len;
1695 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1698 /* Create the request RPC_HDR */
1699 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1701 /* Marshall the RPC header */
1702 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1703 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1704 return NT_STATUS_NO_MEMORY;
1707 /* Marshall the bind request data */
1708 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1709 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1710 return NT_STATUS_NO_MEMORY;
1714 * Grow the outgoing buffer to store any auth info.
1718 if (ss_padding_len) {
1720 memset(pad, '\0', 8);
1721 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1722 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1723 return NT_STATUS_NO_MEMORY;
1727 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1728 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1729 return NT_STATUS_NO_MEMORY;
1733 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1734 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1735 return NT_STATUS_NO_MEMORY;
1739 return NT_STATUS_OK;
1742 /*******************************************************************
1743 Creates a DCE/RPC bind request.
1744 ********************************************************************/
1746 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1747 prs_struct *rpc_out,
1749 const RPC_IFACE *abstract,
1750 const RPC_IFACE *transfer,
1751 enum pipe_auth_type auth_type,
1752 enum pipe_auth_level auth_level)
1754 RPC_HDR_AUTH hdr_auth;
1755 prs_struct auth_info;
1756 NTSTATUS ret = NT_STATUS_OK;
1758 ZERO_STRUCT(hdr_auth);
1759 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1760 return NT_STATUS_NO_MEMORY;
1762 switch (auth_type) {
1763 case PIPE_AUTH_TYPE_SCHANNEL:
1764 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1765 if (!NT_STATUS_IS_OK(ret)) {
1766 prs_mem_free(&auth_info);
1771 case PIPE_AUTH_TYPE_NTLMSSP:
1772 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1773 if (!NT_STATUS_IS_OK(ret)) {
1774 prs_mem_free(&auth_info);
1779 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1780 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1781 if (!NT_STATUS_IS_OK(ret)) {
1782 prs_mem_free(&auth_info);
1787 case PIPE_AUTH_TYPE_KRB5:
1788 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1789 if (!NT_STATUS_IS_OK(ret)) {
1790 prs_mem_free(&auth_info);
1795 case PIPE_AUTH_TYPE_NONE:
1799 /* "Can't" happen. */
1800 return NT_STATUS_INVALID_INFO_CLASS;
1803 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1811 prs_mem_free(&auth_info);
1815 /*******************************************************************
1816 Create and add the NTLMSSP sign/seal auth header and data.
1817 ********************************************************************/
1819 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1821 uint32 ss_padding_len,
1822 prs_struct *outgoing_pdu)
1824 RPC_HDR_AUTH auth_info;
1826 DATA_BLOB auth_blob = data_blob_null;
1827 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1829 if (!cli->auth->a_u.ntlmssp_state) {
1830 return NT_STATUS_INVALID_PARAMETER;
1833 /* Init and marshall the auth header. */
1834 init_rpc_hdr_auth(&auth_info,
1835 map_pipe_auth_type_to_rpc_auth_type(
1836 cli->auth->auth_type),
1837 cli->auth->auth_level,
1839 1 /* context id. */);
1841 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1842 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1843 data_blob_free(&auth_blob);
1844 return NT_STATUS_NO_MEMORY;
1847 switch (cli->auth->auth_level) {
1848 case PIPE_AUTH_LEVEL_PRIVACY:
1849 /* Data portion is encrypted. */
1850 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1851 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1853 (unsigned char *)prs_data_p(outgoing_pdu),
1854 (size_t)prs_offset(outgoing_pdu),
1856 if (!NT_STATUS_IS_OK(status)) {
1857 data_blob_free(&auth_blob);
1862 case PIPE_AUTH_LEVEL_INTEGRITY:
1863 /* Data is signed. */
1864 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1865 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1867 (unsigned char *)prs_data_p(outgoing_pdu),
1868 (size_t)prs_offset(outgoing_pdu),
1870 if (!NT_STATUS_IS_OK(status)) {
1871 data_blob_free(&auth_blob);
1878 smb_panic("bad auth level");
1880 return NT_STATUS_INVALID_PARAMETER;
1883 /* Finally marshall the blob. */
1885 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1886 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1887 (unsigned int)NTLMSSP_SIG_SIZE));
1888 data_blob_free(&auth_blob);
1889 return NT_STATUS_NO_MEMORY;
1892 data_blob_free(&auth_blob);
1893 return NT_STATUS_OK;
1896 /*******************************************************************
1897 Create and add the schannel sign/seal auth header and data.
1898 ********************************************************************/
1900 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1902 uint32 ss_padding_len,
1903 prs_struct *outgoing_pdu)
1905 RPC_HDR_AUTH auth_info;
1906 RPC_AUTH_SCHANNEL_CHK verf;
1907 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1908 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1909 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1912 return NT_STATUS_INVALID_PARAMETER;
1915 /* Init and marshall the auth header. */
1916 init_rpc_hdr_auth(&auth_info,
1917 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1918 cli->auth->auth_level,
1920 1 /* context id. */);
1922 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1923 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1924 return NT_STATUS_NO_MEMORY;
1927 switch (cli->auth->auth_level) {
1928 case PIPE_AUTH_LEVEL_PRIVACY:
1929 case PIPE_AUTH_LEVEL_INTEGRITY:
1930 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1933 schannel_encode(sas,
1934 cli->auth->auth_level,
1935 SENDER_IS_INITIATOR,
1945 smb_panic("bad auth level");
1947 return NT_STATUS_INVALID_PARAMETER;
1950 /* Finally marshall the blob. */
1951 smb_io_rpc_auth_schannel_chk("",
1952 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1957 return NT_STATUS_OK;
1960 /*******************************************************************
1961 Calculate how much data we're going to send in this packet, also
1962 work out any sign/seal padding length.
1963 ********************************************************************/
1965 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1969 uint32 *p_ss_padding)
1971 uint32 data_space, data_len;
1974 if ((data_left > 0) && (sys_random() % 2)) {
1975 data_left = MAX(data_left/2, 1);
1979 switch (cli->auth->auth_level) {
1980 case PIPE_AUTH_LEVEL_NONE:
1981 case PIPE_AUTH_LEVEL_CONNECT:
1982 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1983 data_len = MIN(data_space, data_left);
1986 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1989 case PIPE_AUTH_LEVEL_INTEGRITY:
1990 case PIPE_AUTH_LEVEL_PRIVACY:
1991 /* Treat the same for all authenticated rpc requests. */
1992 switch(cli->auth->auth_type) {
1993 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1994 case PIPE_AUTH_TYPE_NTLMSSP:
1995 *p_auth_len = NTLMSSP_SIG_SIZE;
1997 case PIPE_AUTH_TYPE_SCHANNEL:
1998 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2001 smb_panic("bad auth type");
2005 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2006 RPC_HDR_AUTH_LEN - *p_auth_len;
2008 data_len = MIN(data_space, data_left);
2011 *p_ss_padding = 8 - (data_len % 8);
2013 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2014 data_len + *p_ss_padding + /* data plus padding. */
2015 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2019 smb_panic("bad auth level");
2025 /*******************************************************************
2027 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2028 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2029 and deals with signing/sealing details.
2030 ********************************************************************/
2032 struct rpc_api_pipe_req_state {
2033 struct event_context *ev;
2034 struct rpc_pipe_client *cli;
2037 prs_struct *req_data;
2038 uint32_t req_data_sent;
2039 prs_struct outgoing_frag;
2040 prs_struct reply_pdu;
2043 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2045 prs_mem_free(&s->outgoing_frag);
2046 prs_mem_free(&s->reply_pdu);
2050 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2051 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2052 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2053 bool *is_last_frag);
2055 struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2056 struct event_context *ev,
2057 struct rpc_pipe_client *cli,
2059 prs_struct *req_data)
2061 struct async_req *result;
2062 struct tevent_req *subreq;
2063 struct rpc_api_pipe_req_state *state;
2067 if (!async_req_setup(mem_ctx, &result, &state,
2068 struct rpc_api_pipe_req_state)) {
2073 state->op_num = op_num;
2074 state->req_data = req_data;
2075 state->req_data_sent = 0;
2076 state->call_id = get_rpc_call_id();
2078 if (cli->max_xmit_frag
2079 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2080 /* Server is screwed up ! */
2081 status = NT_STATUS_INVALID_PARAMETER;
2085 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2087 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2092 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2094 status = prepare_next_frag(state, &is_last_frag);
2095 if (!NT_STATUS_IS_OK(status)) {
2100 subreq = rpc_api_pipe_send(state, ev, state->cli,
2101 &state->outgoing_frag,
2103 if (subreq == NULL) {
2106 tevent_req_set_callback(subreq, rpc_api_pipe_req_done,
2109 subreq = rpc_write_send(
2110 state, ev, cli->transport,
2111 (uint8_t *)prs_data_p(&state->outgoing_frag),
2112 prs_offset(&state->outgoing_frag));
2113 if (subreq == NULL) {
2116 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2122 if (async_post_ntstatus(result, ev, status)) {
2126 TALLOC_FREE(result);
2130 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2134 RPC_HDR_REQ hdr_req;
2135 uint32_t data_sent_thistime;
2139 uint32_t ss_padding;
2141 char pad[8] = { 0, };
2144 data_left = prs_offset(state->req_data) - state->req_data_sent;
2146 data_sent_thistime = calculate_data_len_tosend(
2147 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2149 if (state->req_data_sent == 0) {
2150 flags = RPC_FLG_FIRST;
2153 if (data_sent_thistime == data_left) {
2154 flags |= RPC_FLG_LAST;
2157 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2158 return NT_STATUS_NO_MEMORY;
2161 /* Create and marshall the header and request header. */
2162 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2165 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2166 return NT_STATUS_NO_MEMORY;
2169 /* Create the rpc request RPC_HDR_REQ */
2170 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2173 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2174 &state->outgoing_frag, 0)) {
2175 return NT_STATUS_NO_MEMORY;
2178 /* Copy in the data, plus any ss padding. */
2179 if (!prs_append_some_prs_data(&state->outgoing_frag,
2180 state->req_data, state->req_data_sent,
2181 data_sent_thistime)) {
2182 return NT_STATUS_NO_MEMORY;
2185 /* Copy the sign/seal padding data. */
2186 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2187 return NT_STATUS_NO_MEMORY;
2190 /* Generate any auth sign/seal and add the auth footer. */
2191 switch (state->cli->auth->auth_type) {
2192 case PIPE_AUTH_TYPE_NONE:
2193 status = NT_STATUS_OK;
2195 case PIPE_AUTH_TYPE_NTLMSSP:
2196 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2197 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2198 &state->outgoing_frag);
2200 case PIPE_AUTH_TYPE_SCHANNEL:
2201 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2202 &state->outgoing_frag);
2205 status = NT_STATUS_INVALID_PARAMETER;
2209 state->req_data_sent += data_sent_thistime;
2210 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2215 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2217 struct async_req *req = tevent_req_callback_data(
2218 subreq, struct async_req);
2219 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2220 req->private_data, struct rpc_api_pipe_req_state);
2224 status = rpc_write_recv(subreq);
2225 TALLOC_FREE(subreq);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 async_req_nterror(req, status);
2231 status = prepare_next_frag(state, &is_last_frag);
2232 if (!NT_STATUS_IS_OK(status)) {
2233 async_req_nterror(req, status);
2238 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2239 &state->outgoing_frag,
2241 if (async_req_nomem(subreq, req)) {
2244 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2246 subreq = rpc_write_send(
2248 state->cli->transport,
2249 (uint8_t *)prs_data_p(&state->outgoing_frag),
2250 prs_offset(&state->outgoing_frag));
2251 if (async_req_nomem(subreq, req)) {
2254 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2259 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2261 struct async_req *req = tevent_req_callback_data(
2262 subreq, struct async_req);
2263 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2264 req->private_data, struct rpc_api_pipe_req_state);
2267 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2268 TALLOC_FREE(subreq);
2269 if (!NT_STATUS_IS_OK(status)) {
2270 async_req_nterror(req, status);
2273 async_req_done(req);
2276 NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
2277 prs_struct *reply_pdu)
2279 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2280 req->private_data, struct rpc_api_pipe_req_state);
2283 if (async_req_is_nterror(req, &status)) {
2285 * We always have to initialize to reply pdu, even if there is
2286 * none. The rpccli_* caller routines expect this.
2288 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2292 *reply_pdu = state->reply_pdu;
2293 reply_pdu->mem_ctx = mem_ctx;
2296 * Prevent state->req_pdu from being freed in
2297 * rpc_api_pipe_req_state_destructor()
2299 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2301 return NT_STATUS_OK;
2304 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
2306 prs_struct *in_data,
2307 prs_struct *out_data)
2309 TALLOC_CTX *frame = talloc_stackframe();
2310 struct event_context *ev;
2311 struct async_req *req;
2312 NTSTATUS status = NT_STATUS_NO_MEMORY;
2314 ev = event_context_init(frame);
2319 req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
2324 while (req->state < ASYNC_REQ_DONE) {
2325 event_loop_once(ev);
2328 status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
2335 /****************************************************************************
2336 Set the handle state.
2337 ****************************************************************************/
2339 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2340 const char *pipe_name, uint16 device_state)
2342 bool state_set = False;
2344 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2345 char *rparam = NULL;
2347 uint32 rparam_len, rdata_len;
2349 if (pipe_name == NULL)
2352 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2353 cli->fnum, pipe_name, device_state));
2355 /* create parameters: device state */
2356 SSVAL(param, 0, device_state);
2358 /* create setup parameters. */
2360 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2362 /* send the data on \PIPE\ */
2363 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2364 setup, 2, 0, /* setup, length, max */
2365 param, 2, 0, /* param, length, max */
2366 NULL, 0, 1024, /* data, length, max */
2367 &rparam, &rparam_len, /* return param, length */
2368 &rdata, &rdata_len)) /* return data, length */
2370 DEBUG(5, ("Set Handle state: return OK\n"));
2381 /****************************************************************************
2382 Check the rpc bind acknowledge response.
2383 ****************************************************************************/
2385 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2387 if ( hdr_ba->addr.len == 0) {
2388 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2391 /* check the transfer syntax */
2392 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2393 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2394 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2398 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2399 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2400 hdr_ba->res.num_results, hdr_ba->res.reason));
2403 DEBUG(5,("check_bind_response: accepted!\n"));
2407 /*******************************************************************
2408 Creates a DCE/RPC bind authentication response.
2409 This is the packet that is sent back to the server once we
2410 have received a BIND-ACK, to finish the third leg of
2411 the authentication handshake.
2412 ********************************************************************/
2414 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2416 enum pipe_auth_type auth_type,
2417 enum pipe_auth_level auth_level,
2418 DATA_BLOB *pauth_blob,
2419 prs_struct *rpc_out)
2422 RPC_HDR_AUTH hdr_auth;
2425 /* Create the request RPC_HDR */
2426 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2427 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2428 pauth_blob->length );
2431 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2432 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2433 return NT_STATUS_NO_MEMORY;
2437 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2438 about padding - shouldn't this pad to length 8 ? JRA.
2441 /* 4 bytes padding. */
2442 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2443 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2444 return NT_STATUS_NO_MEMORY;
2447 /* Create the request RPC_HDR_AUTHA */
2448 init_rpc_hdr_auth(&hdr_auth,
2449 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2452 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2453 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2454 return NT_STATUS_NO_MEMORY;
2458 * Append the auth data to the outgoing buffer.
2461 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2462 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2463 return NT_STATUS_NO_MEMORY;
2466 return NT_STATUS_OK;
2469 /*******************************************************************
2470 Creates a DCE/RPC bind alter context authentication request which
2471 may contain a spnego auth blobl
2472 ********************************************************************/
2474 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2475 const RPC_IFACE *abstract,
2476 const RPC_IFACE *transfer,
2477 enum pipe_auth_level auth_level,
2478 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2479 prs_struct *rpc_out)
2481 RPC_HDR_AUTH hdr_auth;
2482 prs_struct auth_info;
2483 NTSTATUS ret = NT_STATUS_OK;
2485 ZERO_STRUCT(hdr_auth);
2486 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2487 return NT_STATUS_NO_MEMORY;
2489 /* We may change the pad length before marshalling. */
2490 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2492 if (pauth_blob->length) {
2493 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2494 prs_mem_free(&auth_info);
2495 return NT_STATUS_NO_MEMORY;
2499 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2506 prs_mem_free(&auth_info);
2510 /****************************************************************************
2512 ****************************************************************************/
2514 struct rpc_pipe_bind_state {
2515 struct event_context *ev;
2516 struct rpc_pipe_client *cli;
2518 uint32_t rpc_call_id;
2521 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2523 prs_mem_free(&state->rpc_out);
2527 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2528 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2529 struct rpc_pipe_bind_state *state,
2530 struct rpc_hdr_info *phdr,
2531 prs_struct *reply_pdu);
2532 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2533 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2534 struct rpc_pipe_bind_state *state,
2535 struct rpc_hdr_info *phdr,
2536 prs_struct *reply_pdu);
2537 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2539 struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2540 struct event_context *ev,
2541 struct rpc_pipe_client *cli,
2542 struct cli_pipe_auth_data *auth)
2544 struct async_req *result;
2545 struct tevent_req *subreq;
2546 struct rpc_pipe_bind_state *state;
2549 if (!async_req_setup(mem_ctx, &result, &state,
2550 struct rpc_pipe_bind_state)) {
2554 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2555 rpccli_pipe_txt(debug_ctx(), cli),
2556 (unsigned int)auth->auth_type,
2557 (unsigned int)auth->auth_level ));
2561 state->rpc_call_id = get_rpc_call_id();
2563 prs_init_empty(&state->rpc_out, state, MARSHALL);
2564 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2566 cli->auth = talloc_move(cli, &auth);
2568 /* Marshall the outgoing data. */
2569 status = create_rpc_bind_req(cli, &state->rpc_out,
2571 &cli->abstract_syntax,
2572 &cli->transfer_syntax,
2573 cli->auth->auth_type,
2574 cli->auth->auth_level);
2576 if (!NT_STATUS_IS_OK(status)) {
2580 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2582 if (subreq == NULL) {
2585 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, result);
2589 if (async_post_ntstatus(result, ev, status)) {
2593 TALLOC_FREE(result);
2597 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2599 struct async_req *req = tevent_req_callback_data(
2600 subreq, struct async_req);
2601 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2602 req->private_data, struct rpc_pipe_bind_state);
2603 prs_struct reply_pdu;
2604 struct rpc_hdr_info hdr;
2605 struct rpc_hdr_ba_info hdr_ba;
2608 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2609 TALLOC_FREE(subreq);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2612 rpccli_pipe_txt(debug_ctx(), state->cli),
2613 nt_errstr(status)));
2614 async_req_nterror(req, status);
2618 /* Unmarshall the RPC header */
2619 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2620 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2621 prs_mem_free(&reply_pdu);
2622 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2626 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2627 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2629 prs_mem_free(&reply_pdu);
2630 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2634 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2635 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2636 prs_mem_free(&reply_pdu);
2637 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2641 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2642 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2645 * For authenticated binds we may need to do 3 or 4 leg binds.
2648 switch(state->cli->auth->auth_type) {
2650 case PIPE_AUTH_TYPE_NONE:
2651 case PIPE_AUTH_TYPE_SCHANNEL:
2652 /* Bind complete. */
2653 prs_mem_free(&reply_pdu);
2654 async_req_done(req);
2657 case PIPE_AUTH_TYPE_NTLMSSP:
2658 /* Need to send AUTH3 packet - no reply. */
2659 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2661 prs_mem_free(&reply_pdu);
2662 if (!NT_STATUS_IS_OK(status)) {
2663 async_req_nterror(req, status);
2667 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2668 /* Need to send alter context request and reply. */
2669 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2671 prs_mem_free(&reply_pdu);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 async_req_nterror(req, status);
2677 case PIPE_AUTH_TYPE_KRB5:
2681 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2682 (unsigned int)state->cli->auth->auth_type));
2683 prs_mem_free(&reply_pdu);
2684 async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2688 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2689 struct rpc_pipe_bind_state *state,
2690 struct rpc_hdr_info *phdr,
2691 prs_struct *reply_pdu)
2693 DATA_BLOB server_response = data_blob_null;
2694 DATA_BLOB client_reply = data_blob_null;
2695 struct rpc_hdr_auth_info hdr_auth;
2696 struct tevent_req *subreq;
2699 if ((phdr->auth_len == 0)
2700 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2701 return NT_STATUS_INVALID_PARAMETER;
2704 if (!prs_set_offset(
2706 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2707 return NT_STATUS_INVALID_PARAMETER;
2710 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2711 return NT_STATUS_INVALID_PARAMETER;
2714 /* TODO - check auth_type/auth_level match. */
2716 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2717 prs_copy_data_out((char *)server_response.data, reply_pdu,
2720 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2721 server_response, &client_reply);
2723 if (!NT_STATUS_IS_OK(status)) {
2724 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2725 "blob failed: %s.\n", nt_errstr(status)));
2729 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2731 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2732 state->cli->auth->auth_type,
2733 state->cli->auth->auth_level,
2734 &client_reply, &state->rpc_out);
2735 data_blob_free(&client_reply);
2737 if (!NT_STATUS_IS_OK(status)) {
2741 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2742 (uint8_t *)prs_data_p(&state->rpc_out),
2743 prs_offset(&state->rpc_out));
2744 if (subreq == NULL) {
2745 return NT_STATUS_NO_MEMORY;
2747 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2748 return NT_STATUS_OK;
2751 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2753 struct async_req *req = tevent_req_callback_data(
2754 subreq, struct async_req);
2757 status = rpc_write_recv(subreq);
2758 TALLOC_FREE(subreq);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 async_req_nterror(req, status);
2763 async_req_done(req);
2766 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2767 struct rpc_pipe_bind_state *state,
2768 struct rpc_hdr_info *phdr,
2769 prs_struct *reply_pdu)
2771 DATA_BLOB server_spnego_response = data_blob_null;
2772 DATA_BLOB server_ntlm_response = data_blob_null;
2773 DATA_BLOB client_reply = data_blob_null;
2774 DATA_BLOB tmp_blob = data_blob_null;
2775 RPC_HDR_AUTH hdr_auth;
2776 struct tevent_req *subreq;
2779 if ((phdr->auth_len == 0)
2780 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2781 return NT_STATUS_INVALID_PARAMETER;
2784 /* Process the returned NTLMSSP blob first. */
2785 if (!prs_set_offset(
2787 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2788 return NT_STATUS_INVALID_PARAMETER;
2791 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2792 return NT_STATUS_INVALID_PARAMETER;
2795 server_spnego_response = data_blob(NULL, phdr->auth_len);
2796 prs_copy_data_out((char *)server_spnego_response.data,
2797 reply_pdu, phdr->auth_len);
2800 * The server might give us back two challenges - tmp_blob is for the
2803 if (!spnego_parse_challenge(server_spnego_response,
2804 &server_ntlm_response, &tmp_blob)) {
2805 data_blob_free(&server_spnego_response);
2806 data_blob_free(&server_ntlm_response);
2807 data_blob_free(&tmp_blob);
2808 return NT_STATUS_INVALID_PARAMETER;
2811 /* We're finished with the server spnego response and the tmp_blob. */
2812 data_blob_free(&server_spnego_response);
2813 data_blob_free(&tmp_blob);
2815 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2816 server_ntlm_response, &client_reply);
2818 /* Finished with the server_ntlm response */
2819 data_blob_free(&server_ntlm_response);
2821 if (!NT_STATUS_IS_OK(status)) {
2822 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2823 "using server blob failed.\n"));
2824 data_blob_free(&client_reply);
2828 /* SPNEGO wrap the client reply. */
2829 tmp_blob = spnego_gen_auth(client_reply);
2830 data_blob_free(&client_reply);
2831 client_reply = tmp_blob;
2832 tmp_blob = data_blob_null;
2834 /* Now prepare the alter context pdu. */
2835 prs_init_empty(&state->rpc_out, state, MARSHALL);
2837 status = create_rpc_alter_context(state->rpc_call_id,
2838 &state->cli->abstract_syntax,
2839 &state->cli->transfer_syntax,
2840 state->cli->auth->auth_level,
2843 data_blob_free(&client_reply);
2845 if (!NT_STATUS_IS_OK(status)) {
2849 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2850 &state->rpc_out, RPC_ALTCONTRESP);
2851 if (subreq == NULL) {
2852 return NT_STATUS_NO_MEMORY;
2854 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2855 return NT_STATUS_OK;
2858 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2860 struct async_req *req = tevent_req_callback_data(
2861 subreq, struct async_req);
2862 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2863 req->private_data, struct rpc_pipe_bind_state);
2864 DATA_BLOB server_spnego_response = data_blob_null;
2865 DATA_BLOB tmp_blob = data_blob_null;
2866 prs_struct reply_pdu;
2867 struct rpc_hdr_info hdr;
2868 struct rpc_hdr_auth_info hdr_auth;
2871 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2872 TALLOC_FREE(subreq);
2873 if (!NT_STATUS_IS_OK(status)) {
2874 async_req_nterror(req, status);
2878 /* Get the auth blob from the reply. */
2879 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2880 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2881 "unmarshall RPC_HDR.\n"));
2882 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2886 if (!prs_set_offset(
2888 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2889 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2893 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2894 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2898 server_spnego_response = data_blob(NULL, hdr.auth_len);
2899 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2902 /* Check we got a valid auth response. */
2903 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2904 OID_NTLMSSP, &tmp_blob)) {
2905 data_blob_free(&server_spnego_response);
2906 data_blob_free(&tmp_blob);
2907 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2911 data_blob_free(&server_spnego_response);
2912 data_blob_free(&tmp_blob);
2914 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2915 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2916 async_req_done(req);
2919 NTSTATUS rpc_pipe_bind_recv(struct async_req *req)
2921 return async_req_simple_recv_ntstatus(req);
2924 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2925 struct cli_pipe_auth_data *auth)
2927 TALLOC_CTX *frame = talloc_stackframe();
2928 struct event_context *ev;
2929 struct async_req *req;
2930 NTSTATUS status = NT_STATUS_NO_MEMORY;
2932 ev = event_context_init(frame);
2937 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2942 while (req->state < ASYNC_REQ_DONE) {
2943 event_loop_once(ev);
2946 status = rpc_pipe_bind_recv(req);
2952 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2953 unsigned int timeout)
2955 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2960 return cli_set_timeout(cli, timeout);
2963 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2965 struct cli_state *cli;
2967 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2968 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2969 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2973 cli = rpc_pipe_np_smb_conn(rpc_cli);
2977 E_md4hash(cli->password ? cli->password : "", nt_hash);
2981 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2982 struct cli_pipe_auth_data **presult)
2984 struct cli_pipe_auth_data *result;
2986 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2987 if (result == NULL) {
2988 return NT_STATUS_NO_MEMORY;
2991 result->auth_type = PIPE_AUTH_TYPE_NONE;
2992 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2994 result->user_name = talloc_strdup(result, "");
2995 result->domain = talloc_strdup(result, "");
2996 if ((result->user_name == NULL) || (result->domain == NULL)) {
2997 TALLOC_FREE(result);
2998 return NT_STATUS_NO_MEMORY;
3002 return NT_STATUS_OK;
3005 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3007 ntlmssp_end(&auth->a_u.ntlmssp_state);
3011 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3012 enum pipe_auth_type auth_type,
3013 enum pipe_auth_level auth_level,
3015 const char *username,
3016 const char *password,
3017 struct cli_pipe_auth_data **presult)
3019 struct cli_pipe_auth_data *result;
3022 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3023 if (result == NULL) {
3024 return NT_STATUS_NO_MEMORY;
3027 result->auth_type = auth_type;
3028 result->auth_level = auth_level;
3030 result->user_name = talloc_strdup(result, username);
3031 result->domain = talloc_strdup(result, domain);
3032 if ((result->user_name == NULL) || (result->domain == NULL)) {
3033 status = NT_STATUS_NO_MEMORY;
3037 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3038 if (!NT_STATUS_IS_OK(status)) {
3042 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3044 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3045 if (!NT_STATUS_IS_OK(status)) {
3049 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3050 if (!NT_STATUS_IS_OK(status)) {
3054 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3055 if (!NT_STATUS_IS_OK(status)) {
3060 * Turn off sign+seal to allow selected auth level to turn it back on.
3062 result->a_u.ntlmssp_state->neg_flags &=
3063 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3065 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
3066 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3067 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
3068 result->a_u.ntlmssp_state->neg_flags
3069 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3073 return NT_STATUS_OK;
3076 TALLOC_FREE(result);
3080 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3081 enum pipe_auth_level auth_level,
3082 const uint8_t sess_key[16],
3083 struct cli_pipe_auth_data **presult)
3085 struct cli_pipe_auth_data *result;
3087 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3088 if (result == NULL) {
3089 return NT_STATUS_NO_MEMORY;
3092 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3093 result->auth_level = auth_level;
3095 result->user_name = talloc_strdup(result, "");
3096 result->domain = talloc_strdup(result, domain);
3097 if ((result->user_name == NULL) || (result->domain == NULL)) {
3101 result->a_u.schannel_auth = talloc(result,
3102 struct schannel_auth_struct);
3103 if (result->a_u.schannel_auth == NULL) {
3107 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3108 sizeof(result->a_u.schannel_auth->sess_key));
3109 result->a_u.schannel_auth->seq_num = 0;
3112 return NT_STATUS_OK;
3115 TALLOC_FREE(result);
3116 return NT_STATUS_NO_MEMORY;
3120 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3122 data_blob_free(&auth->session_key);
3127 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3128 enum pipe_auth_level auth_level,
3129 const char *service_princ,
3130 const char *username,
3131 const char *password,
3132 struct cli_pipe_auth_data **presult)
3135 struct cli_pipe_auth_data *result;
3137 if ((username != NULL) && (password != NULL)) {
3138 int ret = kerberos_kinit_password(username, password, 0, NULL);
3140 return NT_STATUS_ACCESS_DENIED;
3144 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3145 if (result == NULL) {
3146 return NT_STATUS_NO_MEMORY;
3149 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3150 result->auth_level = auth_level;
3153 * Username / domain need fixing!
3155 result->user_name = talloc_strdup(result, "");
3156 result->domain = talloc_strdup(result, "");
3157 if ((result->user_name == NULL) || (result->domain == NULL)) {
3161 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3162 result, struct kerberos_auth_struct);
3163 if (result->a_u.kerberos_auth == NULL) {
3166 talloc_set_destructor(result->a_u.kerberos_auth,
3167 cli_auth_kerberos_data_destructor);
3169 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3170 result, service_princ);
3171 if (result->a_u.kerberos_auth->service_principal == NULL) {
3176 return NT_STATUS_OK;
3179 TALLOC_FREE(result);
3180 return NT_STATUS_NO_MEMORY;
3182 return NT_STATUS_NOT_SUPPORTED;
3187 * Create an rpc pipe client struct, connecting to a tcp port.
3189 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3191 const struct ndr_syntax_id *abstract_syntax,
3192 struct rpc_pipe_client **presult)
3194 struct rpc_pipe_client *result;
3195 struct sockaddr_storage addr;
3199 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3200 if (result == NULL) {
3201 return NT_STATUS_NO_MEMORY;
3204 result->abstract_syntax = *abstract_syntax;
3205 result->transfer_syntax = ndr_transfer_syntax;
3206 result->dispatch = cli_do_rpc_ndr;
3208 result->desthost = talloc_strdup(result, host);
3209 result->srv_name_slash = talloc_asprintf_strupper_m(
3210 result, "\\\\%s", result->desthost);
3211 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3212 status = NT_STATUS_NO_MEMORY;
3216 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3217 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3219 if (!resolve_name(host, &addr, 0)) {
3220 status = NT_STATUS_NOT_FOUND;
3224 status = open_socket_out(&addr, port, 60, &fd);
3225 if (!NT_STATUS_IS_OK(status)) {
3228 set_socket_options(fd, lp_socket_options());
3230 status = rpc_transport_sock_init(result, fd, &result->transport);
3231 if (!NT_STATUS_IS_OK(status)) {
3237 return NT_STATUS_OK;
3240 TALLOC_FREE(result);
3245 * Determine the tcp port on which a dcerpc interface is listening
3246 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3249 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3250 const struct ndr_syntax_id *abstract_syntax,
3254 struct rpc_pipe_client *epm_pipe = NULL;
3255 struct cli_pipe_auth_data *auth = NULL;
3256 struct dcerpc_binding *map_binding = NULL;
3257 struct dcerpc_binding *res_binding = NULL;
3258 struct epm_twr_t *map_tower = NULL;
3259 struct epm_twr_t *res_towers = NULL;
3260 struct policy_handle *entry_handle = NULL;
3261 uint32_t num_towers = 0;
3262 uint32_t max_towers = 1;
3263 struct epm_twr_p_t towers;
3264 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3266 if (pport == NULL) {
3267 status = NT_STATUS_INVALID_PARAMETER;
3271 /* open the connection to the endpoint mapper */
3272 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3273 &ndr_table_epmapper.syntax_id,
3276 if (!NT_STATUS_IS_OK(status)) {
3280 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3281 if (!NT_STATUS_IS_OK(status)) {
3285 status = rpc_pipe_bind(epm_pipe, auth);
3286 if (!NT_STATUS_IS_OK(status)) {
3290 /* create tower for asking the epmapper */
3292 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3293 if (map_binding == NULL) {
3294 status = NT_STATUS_NO_MEMORY;
3298 map_binding->transport = NCACN_IP_TCP;
3299 map_binding->object = *abstract_syntax;
3300 map_binding->host = host; /* needed? */
3301 map_binding->endpoint = "0"; /* correct? needed? */
3303 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3304 if (map_tower == NULL) {
3305 status = NT_STATUS_NO_MEMORY;
3309 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3310 &(map_tower->tower));
3311 if (!NT_STATUS_IS_OK(status)) {
3315 /* allocate further parameters for the epm_Map call */
3317 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3318 if (res_towers == NULL) {
3319 status = NT_STATUS_NO_MEMORY;
3322 towers.twr = res_towers;
3324 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3325 if (entry_handle == NULL) {
3326 status = NT_STATUS_NO_MEMORY;
3330 /* ask the endpoint mapper for the port */
3332 status = rpccli_epm_Map(epm_pipe,
3334 CONST_DISCARD(struct GUID *,
3335 &(abstract_syntax->uuid)),
3342 if (!NT_STATUS_IS_OK(status)) {
3346 if (num_towers != 1) {
3347 status = NT_STATUS_UNSUCCESSFUL;
3351 /* extract the port from the answer */
3353 status = dcerpc_binding_from_tower(tmp_ctx,
3354 &(towers.twr->tower),
3356 if (!NT_STATUS_IS_OK(status)) {
3360 /* are further checks here necessary? */
3361 if (res_binding->transport != NCACN_IP_TCP) {
3362 status = NT_STATUS_UNSUCCESSFUL;
3366 *pport = (uint16_t)atoi(res_binding->endpoint);
3369 TALLOC_FREE(tmp_ctx);
3374 * Create a rpc pipe client struct, connecting to a host via tcp.
3375 * The port is determined by asking the endpoint mapper on the given
3378 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3379 const struct ndr_syntax_id *abstract_syntax,
3380 struct rpc_pipe_client **presult)
3387 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3388 if (!NT_STATUS_IS_OK(status)) {
3392 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3393 abstract_syntax, presult);
3399 /********************************************************************
3400 Create a rpc pipe client struct, connecting to a unix domain socket
3401 ********************************************************************/
3402 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3403 const struct ndr_syntax_id *abstract_syntax,
3404 struct rpc_pipe_client **presult)
3406 struct rpc_pipe_client *result;
3407 struct sockaddr_un addr;
3411 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3412 if (result == NULL) {
3413 return NT_STATUS_NO_MEMORY;
3416 result->abstract_syntax = *abstract_syntax;
3417 result->transfer_syntax = ndr_transfer_syntax;
3418 result->dispatch = cli_do_rpc_ndr;
3420 result->desthost = get_myname(result);
3421 result->srv_name_slash = talloc_asprintf_strupper_m(
3422 result, "\\\\%s", result->desthost);
3423 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3424 status = NT_STATUS_NO_MEMORY;
3428 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3429 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3431 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3433 status = map_nt_error_from_unix(errno);
3438 addr.sun_family = AF_UNIX;
3439 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3441 if (sys_connect(fd, (struct sockaddr *)&addr) == -1) {
3442 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3445 return map_nt_error_from_unix(errno);
3448 status = rpc_transport_sock_init(result, fd, &result->transport);
3449 if (!NT_STATUS_IS_OK(status)) {
3455 return NT_STATUS_OK;
3458 TALLOC_FREE(result);
3462 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3464 struct cli_state *cli;
3466 cli = rpc_pipe_np_smb_conn(p);
3468 DLIST_REMOVE(cli->pipe_list, p);
3473 /****************************************************************************
3474 Open a named pipe over SMB to a remote server.
3476 * CAVEAT CALLER OF THIS FUNCTION:
3477 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3478 * so be sure that this function is called AFTER any structure (vs pointer)
3479 * assignment of the cli. In particular, libsmbclient does structure
3480 * assignments of cli, which invalidates the data in the returned
3481 * rpc_pipe_client if this function is called before the structure assignment
3484 ****************************************************************************/
3486 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3487 const struct ndr_syntax_id *abstract_syntax,
3488 struct rpc_pipe_client **presult)
3490 struct rpc_pipe_client *result;
3493 /* sanity check to protect against crashes */
3496 return NT_STATUS_INVALID_HANDLE;
3499 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3500 if (result == NULL) {
3501 return NT_STATUS_NO_MEMORY;
3504 result->abstract_syntax = *abstract_syntax;
3505 result->transfer_syntax = ndr_transfer_syntax;
3506 result->dispatch = cli_do_rpc_ndr;
3507 result->desthost = talloc_strdup(result, cli->desthost);
3508 result->srv_name_slash = talloc_asprintf_strupper_m(
3509 result, "\\\\%s", result->desthost);
3511 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3512 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3514 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3515 TALLOC_FREE(result);
3516 return NT_STATUS_NO_MEMORY;
3519 status = rpc_transport_np_init(result, cli, abstract_syntax,
3520 &result->transport);
3521 if (!NT_STATUS_IS_OK(status)) {
3522 TALLOC_FREE(result);
3526 DLIST_ADD(cli->pipe_list, result);
3527 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3530 return NT_STATUS_OK;
3533 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3534 struct rpc_cli_smbd_conn *conn,
3535 const struct ndr_syntax_id *syntax,
3536 struct rpc_pipe_client **presult)
3538 struct rpc_pipe_client *result;
3539 struct cli_pipe_auth_data *auth;
3542 result = talloc(mem_ctx, struct rpc_pipe_client);
3543 if (result == NULL) {
3544 return NT_STATUS_NO_MEMORY;
3546 result->abstract_syntax = *syntax;
3547 result->transfer_syntax = ndr_transfer_syntax;
3548 result->dispatch = cli_do_rpc_ndr;
3549 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3550 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3552 result->desthost = talloc_strdup(result, global_myname());
3553 result->srv_name_slash = talloc_asprintf_strupper_m(
3554 result, "\\\\%s", global_myname());
3555 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3556 TALLOC_FREE(result);
3557 return NT_STATUS_NO_MEMORY;
3560 status = rpc_transport_smbd_init(result, conn, syntax,
3561 &result->transport);
3562 if (!NT_STATUS_IS_OK(status)) {
3563 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3564 nt_errstr(status)));
3565 TALLOC_FREE(result);
3569 status = rpccli_anon_bind_data(result, &auth);
3570 if (!NT_STATUS_IS_OK(status)) {
3571 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3572 nt_errstr(status)));
3573 TALLOC_FREE(result);
3577 status = rpc_pipe_bind(result, auth);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3580 TALLOC_FREE(result);
3585 return NT_STATUS_OK;
3588 /****************************************************************************
3589 Open a pipe to a remote server.
3590 ****************************************************************************/
3592 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3593 const struct ndr_syntax_id *interface,
3594 struct rpc_pipe_client **presult)
3596 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3598 * We should have a better way to figure out this drsuapi
3601 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3605 return rpc_pipe_open_np(cli, interface, presult);
3608 /****************************************************************************
3609 Open a named pipe to an SMB server and bind anonymously.
3610 ****************************************************************************/
3612 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3613 const struct ndr_syntax_id *interface,
3614 struct rpc_pipe_client **presult)
3616 struct rpc_pipe_client *result;
3617 struct cli_pipe_auth_data *auth;
3620 status = cli_rpc_pipe_open(cli, interface, &result);
3621 if (!NT_STATUS_IS_OK(status)) {
3625 status = rpccli_anon_bind_data(result, &auth);
3626 if (!NT_STATUS_IS_OK(status)) {
3627 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3628 nt_errstr(status)));
3629 TALLOC_FREE(result);
3634 * This is a bit of an abstraction violation due to the fact that an
3635 * anonymous bind on an authenticated SMB inherits the user/domain
3636 * from the enclosing SMB creds
3639 TALLOC_FREE(auth->user_name);
3640 TALLOC_FREE(auth->domain);
3642 auth->user_name = talloc_strdup(auth, cli->user_name);
3643 auth->domain = talloc_strdup(auth, cli->domain);
3644 auth->user_session_key = data_blob_talloc(auth,
3645 cli->user_session_key.data,
3646 cli->user_session_key.length);
3648 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3649 TALLOC_FREE(result);
3650 return NT_STATUS_NO_MEMORY;
3653 status = rpc_pipe_bind(result, auth);
3654 if (!NT_STATUS_IS_OK(status)) {
3656 if (ndr_syntax_id_equal(interface,
3657 &ndr_table_dssetup.syntax_id)) {
3658 /* non AD domains just don't have this pipe, avoid
3659 * level 0 statement in that case - gd */
3662 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3663 "%s failed with error %s\n",
3664 get_pipe_name_from_iface(interface),
3665 nt_errstr(status) ));
3666 TALLOC_FREE(result);
3670 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3671 "%s and bound anonymously.\n",
3672 get_pipe_name_from_iface(interface), cli->desthost));
3675 return NT_STATUS_OK;
3678 /****************************************************************************
3679 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3680 ****************************************************************************/
3682 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3683 const struct ndr_syntax_id *interface,
3684 enum pipe_auth_type auth_type,
3685 enum pipe_auth_level auth_level,
3687 const char *username,
3688 const char *password,
3689 struct rpc_pipe_client **presult)
3691 struct rpc_pipe_client *result;
3692 struct cli_pipe_auth_data *auth;
3695 status = cli_rpc_pipe_open(cli, interface, &result);
3696 if (!NT_STATUS_IS_OK(status)) {
3700 status = rpccli_ntlmssp_bind_data(
3701 result, auth_type, auth_level, domain, username,
3703 if (!NT_STATUS_IS_OK(status)) {
3704 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3705 nt_errstr(status)));
3709 status = rpc_pipe_bind(result, auth);
3710 if (!NT_STATUS_IS_OK(status)) {
3711 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3712 nt_errstr(status) ));
3716 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3717 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3718 get_pipe_name_from_iface(interface), cli->desthost, domain,
3722 return NT_STATUS_OK;
3726 TALLOC_FREE(result);
3730 /****************************************************************************
3732 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3733 ****************************************************************************/
3735 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3736 const struct ndr_syntax_id *interface,
3737 enum pipe_auth_level auth_level,
3739 const char *username,
3740 const char *password,
3741 struct rpc_pipe_client **presult)
3743 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3745 PIPE_AUTH_TYPE_NTLMSSP,
3753 /****************************************************************************
3755 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3756 ****************************************************************************/
3758 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3759 const struct ndr_syntax_id *interface,
3760 enum pipe_auth_level auth_level,
3762 const char *username,
3763 const char *password,
3764 struct rpc_pipe_client **presult)
3766 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3768 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3776 /****************************************************************************
3777 Get a the schannel session key out of an already opened netlogon pipe.
3778 ****************************************************************************/
3779 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3780 struct cli_state *cli,
3784 uint32 sec_chan_type = 0;
3785 unsigned char machine_pwd[16];
3786 const char *machine_account;
3789 /* Get the machine account credentials from secrets.tdb. */
3790 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3793 DEBUG(0, ("get_schannel_session_key: could not fetch "
3794 "trust account password for domain '%s'\n",
3796 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3799 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3800 cli->desthost, /* server name */
3801 domain, /* domain */
3802 global_myname(), /* client name */
3803 machine_account, /* machine account name */
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(3, ("get_schannel_session_key_common: "
3810 "rpccli_netlogon_setup_creds failed with result %s "
3811 "to server %s, domain %s, machine account %s.\n",
3812 nt_errstr(status), cli->desthost, domain,
3817 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3818 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3820 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3823 return NT_STATUS_OK;;
3826 /****************************************************************************
3827 Open a netlogon pipe and get the schannel session key.
3828 Now exposed to external callers.
3829 ****************************************************************************/
3832 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3835 struct rpc_pipe_client **presult)
3837 struct rpc_pipe_client *netlogon_pipe = NULL;
3840 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3842 if (!NT_STATUS_IS_OK(status)) {
3846 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3848 if (!NT_STATUS_IS_OK(status)) {
3849 TALLOC_FREE(netlogon_pipe);
3853 *presult = netlogon_pipe;
3854 return NT_STATUS_OK;
3857 /****************************************************************************
3859 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3860 using session_key. sign and seal.
3861 ****************************************************************************/
3863 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3864 const struct ndr_syntax_id *interface,
3865 enum pipe_auth_level auth_level,
3867 const struct dcinfo *pdc,
3868 struct rpc_pipe_client **presult)
3870 struct rpc_pipe_client *result;
3871 struct cli_pipe_auth_data *auth;
3874 status = cli_rpc_pipe_open(cli, interface, &result);
3875 if (!NT_STATUS_IS_OK(status)) {
3879 status = rpccli_schannel_bind_data(result, domain, auth_level,
3880 pdc->sess_key, &auth);
3881 if (!NT_STATUS_IS_OK(status)) {
3882 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3883 nt_errstr(status)));
3884 TALLOC_FREE(result);
3888 status = rpc_pipe_bind(result, auth);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3891 "cli_rpc_pipe_bind failed with error %s\n",
3892 nt_errstr(status) ));
3893 TALLOC_FREE(result);
3898 * The credentials on a new netlogon pipe are the ones we are passed
3899 * in - copy them over.
3901 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3902 if (result->dc == NULL) {
3903 DEBUG(0, ("talloc failed\n"));
3904 TALLOC_FREE(result);
3905 return NT_STATUS_NO_MEMORY;
3908 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3909 "for domain %s and bound using schannel.\n",
3910 get_pipe_name_from_iface(interface),
3911 cli->desthost, domain ));
3914 return NT_STATUS_OK;
3917 /****************************************************************************
3918 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3919 Fetch the session key ourselves using a temporary netlogon pipe. This
3920 version uses an ntlmssp auth bound netlogon pipe to get the key.
3921 ****************************************************************************/
3923 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3925 const char *username,
3926 const char *password,
3928 struct rpc_pipe_client **presult)
3930 struct rpc_pipe_client *netlogon_pipe = NULL;
3933 status = cli_rpc_pipe_open_spnego_ntlmssp(
3934 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3935 domain, username, password, &netlogon_pipe);
3936 if (!NT_STATUS_IS_OK(status)) {
3940 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3942 if (!NT_STATUS_IS_OK(status)) {
3943 TALLOC_FREE(netlogon_pipe);
3947 *presult = netlogon_pipe;
3948 return NT_STATUS_OK;
3951 /****************************************************************************
3952 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3953 Fetch the session key ourselves using a temporary netlogon pipe. This version
3954 uses an ntlmssp bind to get the session key.
3955 ****************************************************************************/
3957 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3958 const struct ndr_syntax_id *interface,
3959 enum pipe_auth_level auth_level,
3961 const char *username,
3962 const char *password,
3963 struct rpc_pipe_client **presult)
3965 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3966 struct rpc_pipe_client *netlogon_pipe = NULL;
3967 struct rpc_pipe_client *result = NULL;
3970 status = get_schannel_session_key_auth_ntlmssp(
3971 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3974 "key from server %s for domain %s.\n",
3975 cli->desthost, domain ));
3979 status = cli_rpc_pipe_open_schannel_with_key(
3980 cli, interface, auth_level, domain, netlogon_pipe->dc,
3983 /* Now we've bound using the session key we can close the netlog pipe. */
3984 TALLOC_FREE(netlogon_pipe);
3986 if (NT_STATUS_IS_OK(status)) {
3992 /****************************************************************************
3993 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3994 Fetch the session key ourselves using a temporary netlogon pipe.
3995 ****************************************************************************/
3997 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3998 const struct ndr_syntax_id *interface,
3999 enum pipe_auth_level auth_level,
4001 struct rpc_pipe_client **presult)
4003 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4004 struct rpc_pipe_client *netlogon_pipe = NULL;
4005 struct rpc_pipe_client *result = NULL;
4008 status = get_schannel_session_key(cli, domain, &neg_flags,
4010 if (!NT_STATUS_IS_OK(status)) {
4011 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4012 "key from server %s for domain %s.\n",
4013 cli->desthost, domain ));
4017 status = cli_rpc_pipe_open_schannel_with_key(
4018 cli, interface, auth_level, domain, netlogon_pipe->dc,
4021 /* Now we've bound using the session key we can close the netlog pipe. */
4022 TALLOC_FREE(netlogon_pipe);
4024 if (NT_STATUS_IS_OK(status)) {
4028 return NT_STATUS_OK;
4031 /****************************************************************************
4032 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4033 The idea is this can be called with service_princ, username and password all
4034 NULL so long as the caller has a TGT.
4035 ****************************************************************************/
4037 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4038 const struct ndr_syntax_id *interface,
4039 enum pipe_auth_level auth_level,
4040 const char *service_princ,
4041 const char *username,
4042 const char *password,
4043 struct rpc_pipe_client **presult)
4046 struct rpc_pipe_client *result;
4047 struct cli_pipe_auth_data *auth;
4050 status = cli_rpc_pipe_open(cli, interface, &result);
4051 if (!NT_STATUS_IS_OK(status)) {
4055 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4056 username, password, &auth);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4059 nt_errstr(status)));
4060 TALLOC_FREE(result);
4064 status = rpc_pipe_bind(result, auth);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4067 "with error %s\n", nt_errstr(status)));
4068 TALLOC_FREE(result);
4073 return NT_STATUS_OK;
4075 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4076 return NT_STATUS_NOT_IMPLEMENTED;
4080 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4081 struct rpc_pipe_client *cli,
4082 DATA_BLOB *session_key)
4084 if (!session_key || !cli) {
4085 return NT_STATUS_INVALID_PARAMETER;
4089 return NT_STATUS_INVALID_PARAMETER;
4092 switch (cli->auth->auth_type) {
4093 case PIPE_AUTH_TYPE_SCHANNEL:
4094 *session_key = data_blob_talloc(mem_ctx,
4095 cli->auth->a_u.schannel_auth->sess_key, 16);
4097 case PIPE_AUTH_TYPE_NTLMSSP:
4098 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4099 *session_key = data_blob_talloc(mem_ctx,
4100 cli->auth->a_u.ntlmssp_state->session_key.data,
4101 cli->auth->a_u.ntlmssp_state->session_key.length);
4103 case PIPE_AUTH_TYPE_KRB5:
4104 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4105 *session_key = data_blob_talloc(mem_ctx,
4106 cli->auth->a_u.kerberos_auth->session_key.data,
4107 cli->auth->a_u.kerberos_auth->session_key.length);
4109 case PIPE_AUTH_TYPE_NONE:
4110 *session_key = data_blob_talloc(mem_ctx,
4111 cli->auth->user_session_key.data,
4112 cli->auth->user_session_key.length);
4115 return NT_STATUS_NO_USER_SESSION_KEY;
4118 return NT_STATUS_OK;