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 async_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 async_req *result;
1258 struct tevent_req *subreq;
1259 struct rpc_api_pipe_state *state;
1260 uint16_t max_recv_frag;
1263 if (!async_req_setup(mem_ctx, &result, &state,
1264 struct rpc_api_pipe_state)) {
1269 state->expected_pkt_type = expected_pkt_type;
1270 state->incoming_pdu_offset = 0;
1272 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1274 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1275 /* Make incoming_pdu dynamic with no memory. */
1276 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1278 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1281 * Ensure we're not sending too much.
1283 if (prs_offset(data) > cli->max_xmit_frag) {
1284 status = NT_STATUS_INVALID_PARAMETER;
1288 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1290 max_recv_frag = cli->max_recv_frag;
1293 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1296 subreq = cli_api_pipe_send(state, ev, cli->transport,
1297 (uint8_t *)prs_data_p(data),
1298 prs_offset(data), max_recv_frag);
1299 if (subreq == NULL) {
1300 status = NT_STATUS_NO_MEMORY;
1303 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, result);
1307 if (async_post_ntstatus(result, ev, status)) {
1310 TALLOC_FREE(result);
1314 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1316 struct async_req *req = tevent_req_callback_data(
1317 subreq, struct async_req);
1318 struct rpc_api_pipe_state *state = talloc_get_type_abort(
1319 req->private_data, struct rpc_api_pipe_state);
1321 uint8_t *rdata = NULL;
1322 uint32_t rdata_len = 0;
1325 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1326 TALLOC_FREE(subreq);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1329 async_req_nterror(req, status);
1333 if (rdata == NULL) {
1334 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1335 rpccli_pipe_txt(debug_ctx(), state->cli)));
1336 async_req_done(req);
1341 * Give the memory received from cli_trans as dynamic to the current
1342 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1345 rdata_copy = (char *)memdup(rdata, rdata_len);
1347 if (async_req_nomem(rdata_copy, req)) {
1350 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1352 /* Ensure we have enough data for a pdu. */
1353 subreq = get_complete_frag_send(state, state->ev, state->cli,
1354 &state->rhdr, &state->incoming_frag);
1355 if (async_req_nomem(subreq, req)) {
1358 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1361 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1363 struct async_req *req = tevent_req_callback_data(
1364 subreq, struct async_req);
1365 struct rpc_api_pipe_state *state = talloc_get_type_abort(
1366 req->private_data, struct rpc_api_pipe_state);
1369 uint32_t rdata_len = 0;
1371 status = get_complete_frag_recv(subreq);
1372 TALLOC_FREE(subreq);
1373 if (!NT_STATUS_IS_OK(status)) {
1374 DEBUG(5, ("get_complete_frag failed: %s\n",
1375 nt_errstr(status)));
1376 async_req_nterror(req, status);
1380 status = cli_pipe_validate_current_pdu(
1381 state->cli, &state->rhdr, &state->incoming_frag,
1382 state->expected_pkt_type, &rdata, &rdata_len,
1383 &state->incoming_pdu);
1385 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1386 (unsigned)prs_data_size(&state->incoming_frag),
1387 (unsigned)state->incoming_pdu_offset,
1388 nt_errstr(status)));
1390 if (!NT_STATUS_IS_OK(status)) {
1391 async_req_nterror(req, status);
1395 if ((state->rhdr.flags & RPC_FLG_FIRST)
1396 && (state->rhdr.pack_type[0] == 0)) {
1398 * Set the data type correctly for big-endian data on the
1401 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1403 rpccli_pipe_txt(debug_ctx(), state->cli)));
1404 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1407 * Check endianness on subsequent packets.
1409 if (state->incoming_frag.bigendian_data
1410 != state->incoming_pdu.bigendian_data) {
1411 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1413 state->incoming_pdu.bigendian_data?"big":"little",
1414 state->incoming_frag.bigendian_data?"big":"little"));
1415 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1419 /* Now copy the data portion out of the pdu into rbuf. */
1420 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1421 async_req_nterror(req, NT_STATUS_NO_MEMORY);
1425 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1426 rdata, (size_t)rdata_len);
1427 state->incoming_pdu_offset += rdata_len;
1429 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1430 &state->incoming_frag);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 async_req_nterror(req, status);
1436 if (state->rhdr.flags & RPC_FLG_LAST) {
1437 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1438 rpccli_pipe_txt(debug_ctx(), state->cli),
1439 (unsigned)prs_data_size(&state->incoming_pdu)));
1440 async_req_done(req);
1444 subreq = get_complete_frag_send(state, state->ev, state->cli,
1445 &state->rhdr, &state->incoming_frag);
1446 if (async_req_nomem(subreq, req)) {
1449 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1452 static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
1453 prs_struct *reply_pdu)
1455 struct rpc_api_pipe_state *state = talloc_get_type_abort(
1456 req->private_data, struct rpc_api_pipe_state);
1459 if (async_req_is_nterror(req, &status)) {
1463 *reply_pdu = state->incoming_pdu;
1464 reply_pdu->mem_ctx = mem_ctx;
1467 * Prevent state->incoming_pdu from being freed in
1468 * rpc_api_pipe_state_destructor()
1470 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1472 return NT_STATUS_OK;
1475 /*******************************************************************
1476 Creates krb5 auth bind.
1477 ********************************************************************/
1479 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1480 enum pipe_auth_level auth_level,
1481 RPC_HDR_AUTH *pauth_out,
1482 prs_struct *auth_data)
1486 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1487 DATA_BLOB tkt = data_blob_null;
1488 DATA_BLOB tkt_wrapped = data_blob_null;
1490 /* We may change the pad length before marshalling. */
1491 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1493 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1494 a->service_principal ));
1496 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1498 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1499 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1502 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1504 a->service_principal,
1505 error_message(ret) ));
1507 data_blob_free(&tkt);
1508 prs_mem_free(auth_data);
1509 return NT_STATUS_INVALID_PARAMETER;
1512 /* wrap that up in a nice GSS-API wrapping */
1513 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1515 data_blob_free(&tkt);
1517 /* Auth len in the rpc header doesn't include auth_header. */
1518 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1519 data_blob_free(&tkt_wrapped);
1520 prs_mem_free(auth_data);
1521 return NT_STATUS_NO_MEMORY;
1524 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1525 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1527 data_blob_free(&tkt_wrapped);
1528 return NT_STATUS_OK;
1530 return NT_STATUS_INVALID_PARAMETER;
1534 /*******************************************************************
1535 Creates SPNEGO NTLMSSP auth bind.
1536 ********************************************************************/
1538 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1539 enum pipe_auth_level auth_level,
1540 RPC_HDR_AUTH *pauth_out,
1541 prs_struct *auth_data)
1544 DATA_BLOB null_blob = data_blob_null;
1545 DATA_BLOB request = data_blob_null;
1546 DATA_BLOB spnego_msg = data_blob_null;
1548 /* We may change the pad length before marshalling. */
1549 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1551 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1552 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1556 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1557 data_blob_free(&request);
1558 prs_mem_free(auth_data);
1562 /* Wrap this in SPNEGO. */
1563 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1565 data_blob_free(&request);
1567 /* Auth len in the rpc header doesn't include auth_header. */
1568 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1569 data_blob_free(&spnego_msg);
1570 prs_mem_free(auth_data);
1571 return NT_STATUS_NO_MEMORY;
1574 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1575 dump_data(5, spnego_msg.data, spnego_msg.length);
1577 data_blob_free(&spnego_msg);
1578 return NT_STATUS_OK;
1581 /*******************************************************************
1582 Creates NTLMSSP auth bind.
1583 ********************************************************************/
1585 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1586 enum pipe_auth_level auth_level,
1587 RPC_HDR_AUTH *pauth_out,
1588 prs_struct *auth_data)
1591 DATA_BLOB null_blob = data_blob_null;
1592 DATA_BLOB request = data_blob_null;
1594 /* We may change the pad length before marshalling. */
1595 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1597 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1598 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1602 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1603 data_blob_free(&request);
1604 prs_mem_free(auth_data);
1608 /* Auth len in the rpc header doesn't include auth_header. */
1609 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1610 data_blob_free(&request);
1611 prs_mem_free(auth_data);
1612 return NT_STATUS_NO_MEMORY;
1615 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1616 dump_data(5, request.data, request.length);
1618 data_blob_free(&request);
1619 return NT_STATUS_OK;
1622 /*******************************************************************
1623 Creates schannel auth bind.
1624 ********************************************************************/
1626 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1627 enum pipe_auth_level auth_level,
1628 RPC_HDR_AUTH *pauth_out,
1629 prs_struct *auth_data)
1631 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1633 /* We may change the pad length before marshalling. */
1634 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1636 /* Use lp_workgroup() if domain not specified */
1638 if (!cli->auth->domain || !cli->auth->domain[0]) {
1639 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1640 if (cli->auth->domain == NULL) {
1641 return NT_STATUS_NO_MEMORY;
1645 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1649 * Now marshall the data into the auth parse_struct.
1652 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1653 &schannel_neg, auth_data, 0)) {
1654 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1655 prs_mem_free(auth_data);
1656 return NT_STATUS_NO_MEMORY;
1659 return NT_STATUS_OK;
1662 /*******************************************************************
1663 Creates the internals of a DCE/RPC bind request or alter context PDU.
1664 ********************************************************************/
1666 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1667 prs_struct *rpc_out,
1669 const RPC_IFACE *abstract,
1670 const RPC_IFACE *transfer,
1671 RPC_HDR_AUTH *phdr_auth,
1672 prs_struct *pauth_info)
1676 RPC_CONTEXT rpc_ctx;
1677 uint16 auth_len = prs_offset(pauth_info);
1678 uint8 ss_padding_len = 0;
1679 uint16 frag_len = 0;
1681 /* create the RPC context. */
1682 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1684 /* create the bind request RPC_HDR_RB */
1685 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1687 /* Start building the frag length. */
1688 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1690 /* Do we need to pad ? */
1692 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1694 ss_padding_len = 8 - (data_len % 8);
1695 phdr_auth->auth_pad_len = ss_padding_len;
1697 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1700 /* Create the request RPC_HDR */
1701 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1703 /* Marshall the RPC header */
1704 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1705 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1706 return NT_STATUS_NO_MEMORY;
1709 /* Marshall the bind request data */
1710 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1711 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1712 return NT_STATUS_NO_MEMORY;
1716 * Grow the outgoing buffer to store any auth info.
1720 if (ss_padding_len) {
1722 memset(pad, '\0', 8);
1723 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1724 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1725 return NT_STATUS_NO_MEMORY;
1729 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1730 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1731 return NT_STATUS_NO_MEMORY;
1735 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1736 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1737 return NT_STATUS_NO_MEMORY;
1741 return NT_STATUS_OK;
1744 /*******************************************************************
1745 Creates a DCE/RPC bind request.
1746 ********************************************************************/
1748 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1749 prs_struct *rpc_out,
1751 const RPC_IFACE *abstract,
1752 const RPC_IFACE *transfer,
1753 enum pipe_auth_type auth_type,
1754 enum pipe_auth_level auth_level)
1756 RPC_HDR_AUTH hdr_auth;
1757 prs_struct auth_info;
1758 NTSTATUS ret = NT_STATUS_OK;
1760 ZERO_STRUCT(hdr_auth);
1761 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1762 return NT_STATUS_NO_MEMORY;
1764 switch (auth_type) {
1765 case PIPE_AUTH_TYPE_SCHANNEL:
1766 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1767 if (!NT_STATUS_IS_OK(ret)) {
1768 prs_mem_free(&auth_info);
1773 case PIPE_AUTH_TYPE_NTLMSSP:
1774 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1775 if (!NT_STATUS_IS_OK(ret)) {
1776 prs_mem_free(&auth_info);
1781 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1782 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1783 if (!NT_STATUS_IS_OK(ret)) {
1784 prs_mem_free(&auth_info);
1789 case PIPE_AUTH_TYPE_KRB5:
1790 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1791 if (!NT_STATUS_IS_OK(ret)) {
1792 prs_mem_free(&auth_info);
1797 case PIPE_AUTH_TYPE_NONE:
1801 /* "Can't" happen. */
1802 return NT_STATUS_INVALID_INFO_CLASS;
1805 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1813 prs_mem_free(&auth_info);
1817 /*******************************************************************
1818 Create and add the NTLMSSP sign/seal auth header and data.
1819 ********************************************************************/
1821 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1823 uint32 ss_padding_len,
1824 prs_struct *outgoing_pdu)
1826 RPC_HDR_AUTH auth_info;
1828 DATA_BLOB auth_blob = data_blob_null;
1829 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1831 if (!cli->auth->a_u.ntlmssp_state) {
1832 return NT_STATUS_INVALID_PARAMETER;
1835 /* Init and marshall the auth header. */
1836 init_rpc_hdr_auth(&auth_info,
1837 map_pipe_auth_type_to_rpc_auth_type(
1838 cli->auth->auth_type),
1839 cli->auth->auth_level,
1841 1 /* context id. */);
1843 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1844 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1845 data_blob_free(&auth_blob);
1846 return NT_STATUS_NO_MEMORY;
1849 switch (cli->auth->auth_level) {
1850 case PIPE_AUTH_LEVEL_PRIVACY:
1851 /* Data portion is encrypted. */
1852 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1853 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1855 (unsigned char *)prs_data_p(outgoing_pdu),
1856 (size_t)prs_offset(outgoing_pdu),
1858 if (!NT_STATUS_IS_OK(status)) {
1859 data_blob_free(&auth_blob);
1864 case PIPE_AUTH_LEVEL_INTEGRITY:
1865 /* Data is signed. */
1866 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1867 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1869 (unsigned char *)prs_data_p(outgoing_pdu),
1870 (size_t)prs_offset(outgoing_pdu),
1872 if (!NT_STATUS_IS_OK(status)) {
1873 data_blob_free(&auth_blob);
1880 smb_panic("bad auth level");
1882 return NT_STATUS_INVALID_PARAMETER;
1885 /* Finally marshall the blob. */
1887 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1888 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1889 (unsigned int)NTLMSSP_SIG_SIZE));
1890 data_blob_free(&auth_blob);
1891 return NT_STATUS_NO_MEMORY;
1894 data_blob_free(&auth_blob);
1895 return NT_STATUS_OK;
1898 /*******************************************************************
1899 Create and add the schannel sign/seal auth header and data.
1900 ********************************************************************/
1902 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1904 uint32 ss_padding_len,
1905 prs_struct *outgoing_pdu)
1907 RPC_HDR_AUTH auth_info;
1908 RPC_AUTH_SCHANNEL_CHK verf;
1909 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1910 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1911 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1914 return NT_STATUS_INVALID_PARAMETER;
1917 /* Init and marshall the auth header. */
1918 init_rpc_hdr_auth(&auth_info,
1919 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1920 cli->auth->auth_level,
1922 1 /* context id. */);
1924 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1925 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1926 return NT_STATUS_NO_MEMORY;
1929 switch (cli->auth->auth_level) {
1930 case PIPE_AUTH_LEVEL_PRIVACY:
1931 case PIPE_AUTH_LEVEL_INTEGRITY:
1932 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1935 schannel_encode(sas,
1936 cli->auth->auth_level,
1937 SENDER_IS_INITIATOR,
1947 smb_panic("bad auth level");
1949 return NT_STATUS_INVALID_PARAMETER;
1952 /* Finally marshall the blob. */
1953 smb_io_rpc_auth_schannel_chk("",
1954 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1959 return NT_STATUS_OK;
1962 /*******************************************************************
1963 Calculate how much data we're going to send in this packet, also
1964 work out any sign/seal padding length.
1965 ********************************************************************/
1967 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1971 uint32 *p_ss_padding)
1973 uint32 data_space, data_len;
1976 if ((data_left > 0) && (sys_random() % 2)) {
1977 data_left = MAX(data_left/2, 1);
1981 switch (cli->auth->auth_level) {
1982 case PIPE_AUTH_LEVEL_NONE:
1983 case PIPE_AUTH_LEVEL_CONNECT:
1984 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1985 data_len = MIN(data_space, data_left);
1988 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1991 case PIPE_AUTH_LEVEL_INTEGRITY:
1992 case PIPE_AUTH_LEVEL_PRIVACY:
1993 /* Treat the same for all authenticated rpc requests. */
1994 switch(cli->auth->auth_type) {
1995 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1996 case PIPE_AUTH_TYPE_NTLMSSP:
1997 *p_auth_len = NTLMSSP_SIG_SIZE;
1999 case PIPE_AUTH_TYPE_SCHANNEL:
2000 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2003 smb_panic("bad auth type");
2007 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2008 RPC_HDR_AUTH_LEN - *p_auth_len;
2010 data_len = MIN(data_space, data_left);
2013 *p_ss_padding = 8 - (data_len % 8);
2015 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2016 data_len + *p_ss_padding + /* data plus padding. */
2017 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2021 smb_panic("bad auth level");
2027 /*******************************************************************
2029 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2030 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2031 and deals with signing/sealing details.
2032 ********************************************************************/
2034 struct rpc_api_pipe_req_state {
2035 struct event_context *ev;
2036 struct rpc_pipe_client *cli;
2039 prs_struct *req_data;
2040 uint32_t req_data_sent;
2041 prs_struct outgoing_frag;
2042 prs_struct reply_pdu;
2045 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2047 prs_mem_free(&s->outgoing_frag);
2048 prs_mem_free(&s->reply_pdu);
2052 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2053 static void rpc_api_pipe_req_done(struct async_req *subreq);
2054 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2055 bool *is_last_frag);
2057 struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2058 struct event_context *ev,
2059 struct rpc_pipe_client *cli,
2061 prs_struct *req_data)
2063 struct async_req *result, *subreq;
2064 struct tevent_req *subreq2;
2065 struct rpc_api_pipe_req_state *state;
2069 if (!async_req_setup(mem_ctx, &result, &state,
2070 struct rpc_api_pipe_req_state)) {
2075 state->op_num = op_num;
2076 state->req_data = req_data;
2077 state->req_data_sent = 0;
2078 state->call_id = get_rpc_call_id();
2080 if (cli->max_xmit_frag
2081 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2082 /* Server is screwed up ! */
2083 status = NT_STATUS_INVALID_PARAMETER;
2087 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2089 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2091 status = NT_STATUS_NO_MEMORY;
2095 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2097 status = prepare_next_frag(state, &is_last_frag);
2098 if (!NT_STATUS_IS_OK(status)) {
2103 subreq = rpc_api_pipe_send(state, ev, state->cli,
2104 &state->outgoing_frag,
2106 if (subreq == NULL) {
2107 status = NT_STATUS_NO_MEMORY;
2110 subreq->async.fn = rpc_api_pipe_req_done;
2111 subreq->async.priv = result;
2113 subreq2 = rpc_write_send(
2114 state, ev, cli->transport,
2115 (uint8_t *)prs_data_p(&state->outgoing_frag),
2116 prs_offset(&state->outgoing_frag));
2117 if (subreq2 == NULL) {
2118 status = NT_STATUS_NO_MEMORY;
2121 tevent_req_set_callback(subreq2, rpc_api_pipe_req_write_done,
2127 if (async_post_ntstatus(result, ev, status)) {
2130 TALLOC_FREE(result);
2134 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2138 RPC_HDR_REQ hdr_req;
2139 uint32_t data_sent_thistime;
2143 uint32_t ss_padding;
2145 char pad[8] = { 0, };
2148 data_left = prs_offset(state->req_data) - state->req_data_sent;
2150 data_sent_thistime = calculate_data_len_tosend(
2151 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2153 if (state->req_data_sent == 0) {
2154 flags = RPC_FLG_FIRST;
2157 if (data_sent_thistime == data_left) {
2158 flags |= RPC_FLG_LAST;
2161 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2162 return NT_STATUS_NO_MEMORY;
2165 /* Create and marshall the header and request header. */
2166 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2169 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2170 return NT_STATUS_NO_MEMORY;
2173 /* Create the rpc request RPC_HDR_REQ */
2174 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2177 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2178 &state->outgoing_frag, 0)) {
2179 return NT_STATUS_NO_MEMORY;
2182 /* Copy in the data, plus any ss padding. */
2183 if (!prs_append_some_prs_data(&state->outgoing_frag,
2184 state->req_data, state->req_data_sent,
2185 data_sent_thistime)) {
2186 return NT_STATUS_NO_MEMORY;
2189 /* Copy the sign/seal padding data. */
2190 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2191 return NT_STATUS_NO_MEMORY;
2194 /* Generate any auth sign/seal and add the auth footer. */
2195 switch (state->cli->auth->auth_type) {
2196 case PIPE_AUTH_TYPE_NONE:
2197 status = NT_STATUS_OK;
2199 case PIPE_AUTH_TYPE_NTLMSSP:
2200 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2201 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2202 &state->outgoing_frag);
2204 case PIPE_AUTH_TYPE_SCHANNEL:
2205 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2206 &state->outgoing_frag);
2209 status = NT_STATUS_INVALID_PARAMETER;
2213 state->req_data_sent += data_sent_thistime;
2214 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2219 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2221 struct async_req *req = tevent_req_callback_data(
2222 subreq, struct async_req);
2223 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2224 req->private_data, struct rpc_api_pipe_req_state);
2225 struct async_req *subreq2;
2229 status = rpc_write_recv(subreq);
2230 TALLOC_FREE(subreq);
2231 if (!NT_STATUS_IS_OK(status)) {
2232 async_req_nterror(req, status);
2236 status = prepare_next_frag(state, &is_last_frag);
2237 if (!NT_STATUS_IS_OK(status)) {
2238 async_req_nterror(req, status);
2243 subreq2 = rpc_api_pipe_send(state, state->ev, state->cli,
2244 &state->outgoing_frag,
2246 if (async_req_nomem(subreq2, req)) {
2249 subreq2->async.fn = rpc_api_pipe_req_done;
2250 subreq2->async.priv = req;
2252 subreq = rpc_write_send(
2254 state->cli->transport,
2255 (uint8_t *)prs_data_p(&state->outgoing_frag),
2256 prs_offset(&state->outgoing_frag));
2257 if (async_req_nomem(subreq, req)) {
2260 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2265 static void rpc_api_pipe_req_done(struct async_req *subreq)
2267 struct async_req *req = talloc_get_type_abort(
2268 subreq->async.priv, struct async_req);
2269 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2270 req->private_data, struct rpc_api_pipe_req_state);
2273 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2274 TALLOC_FREE(subreq);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 async_req_nterror(req, status);
2279 async_req_done(req);
2282 NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
2283 prs_struct *reply_pdu)
2285 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2286 req->private_data, struct rpc_api_pipe_req_state);
2289 if (async_req_is_nterror(req, &status)) {
2291 * We always have to initialize to reply pdu, even if there is
2292 * none. The rpccli_* caller routines expect this.
2294 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2298 *reply_pdu = state->reply_pdu;
2299 reply_pdu->mem_ctx = mem_ctx;
2302 * Prevent state->req_pdu from being freed in
2303 * rpc_api_pipe_req_state_destructor()
2305 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2307 return NT_STATUS_OK;
2310 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
2312 prs_struct *in_data,
2313 prs_struct *out_data)
2315 TALLOC_CTX *frame = talloc_stackframe();
2316 struct event_context *ev;
2317 struct async_req *req;
2318 NTSTATUS status = NT_STATUS_NO_MEMORY;
2320 ev = event_context_init(frame);
2325 req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
2330 while (req->state < ASYNC_REQ_DONE) {
2331 event_loop_once(ev);
2334 status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
2341 /****************************************************************************
2342 Set the handle state.
2343 ****************************************************************************/
2345 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2346 const char *pipe_name, uint16 device_state)
2348 bool state_set = False;
2350 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2351 char *rparam = NULL;
2353 uint32 rparam_len, rdata_len;
2355 if (pipe_name == NULL)
2358 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2359 cli->fnum, pipe_name, device_state));
2361 /* create parameters: device state */
2362 SSVAL(param, 0, device_state);
2364 /* create setup parameters. */
2366 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2368 /* send the data on \PIPE\ */
2369 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2370 setup, 2, 0, /* setup, length, max */
2371 param, 2, 0, /* param, length, max */
2372 NULL, 0, 1024, /* data, length, max */
2373 &rparam, &rparam_len, /* return param, length */
2374 &rdata, &rdata_len)) /* return data, length */
2376 DEBUG(5, ("Set Handle state: return OK\n"));
2387 /****************************************************************************
2388 Check the rpc bind acknowledge response.
2389 ****************************************************************************/
2391 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2393 if ( hdr_ba->addr.len == 0) {
2394 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2397 /* check the transfer syntax */
2398 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2399 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2400 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2404 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2405 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2406 hdr_ba->res.num_results, hdr_ba->res.reason));
2409 DEBUG(5,("check_bind_response: accepted!\n"));
2413 /*******************************************************************
2414 Creates a DCE/RPC bind authentication response.
2415 This is the packet that is sent back to the server once we
2416 have received a BIND-ACK, to finish the third leg of
2417 the authentication handshake.
2418 ********************************************************************/
2420 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2422 enum pipe_auth_type auth_type,
2423 enum pipe_auth_level auth_level,
2424 DATA_BLOB *pauth_blob,
2425 prs_struct *rpc_out)
2428 RPC_HDR_AUTH hdr_auth;
2431 /* Create the request RPC_HDR */
2432 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2433 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2434 pauth_blob->length );
2437 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2438 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2439 return NT_STATUS_NO_MEMORY;
2443 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2444 about padding - shouldn't this pad to length 8 ? JRA.
2447 /* 4 bytes padding. */
2448 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2449 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2450 return NT_STATUS_NO_MEMORY;
2453 /* Create the request RPC_HDR_AUTHA */
2454 init_rpc_hdr_auth(&hdr_auth,
2455 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2458 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2459 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2460 return NT_STATUS_NO_MEMORY;
2464 * Append the auth data to the outgoing buffer.
2467 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2468 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2469 return NT_STATUS_NO_MEMORY;
2472 return NT_STATUS_OK;
2475 /*******************************************************************
2476 Creates a DCE/RPC bind alter context authentication request which
2477 may contain a spnego auth blobl
2478 ********************************************************************/
2480 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2481 const RPC_IFACE *abstract,
2482 const RPC_IFACE *transfer,
2483 enum pipe_auth_level auth_level,
2484 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2485 prs_struct *rpc_out)
2487 RPC_HDR_AUTH hdr_auth;
2488 prs_struct auth_info;
2489 NTSTATUS ret = NT_STATUS_OK;
2491 ZERO_STRUCT(hdr_auth);
2492 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2493 return NT_STATUS_NO_MEMORY;
2495 /* We may change the pad length before marshalling. */
2496 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2498 if (pauth_blob->length) {
2499 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2500 prs_mem_free(&auth_info);
2501 return NT_STATUS_NO_MEMORY;
2505 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2512 prs_mem_free(&auth_info);
2516 /****************************************************************************
2518 ****************************************************************************/
2520 struct rpc_pipe_bind_state {
2521 struct event_context *ev;
2522 struct rpc_pipe_client *cli;
2524 uint32_t rpc_call_id;
2527 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2529 prs_mem_free(&state->rpc_out);
2533 static void rpc_pipe_bind_step_one_done(struct async_req *subreq);
2534 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2535 struct rpc_pipe_bind_state *state,
2536 struct rpc_hdr_info *phdr,
2537 prs_struct *reply_pdu);
2538 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2539 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2540 struct rpc_pipe_bind_state *state,
2541 struct rpc_hdr_info *phdr,
2542 prs_struct *reply_pdu);
2543 static void rpc_bind_ntlmssp_api_done(struct async_req *subreq);
2545 struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2546 struct event_context *ev,
2547 struct rpc_pipe_client *cli,
2548 struct cli_pipe_auth_data *auth)
2550 struct async_req *result, *subreq;
2551 struct rpc_pipe_bind_state *state;
2554 if (!async_req_setup(mem_ctx, &result, &state,
2555 struct rpc_pipe_bind_state)) {
2559 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2560 rpccli_pipe_txt(debug_ctx(), cli),
2561 (unsigned int)auth->auth_type,
2562 (unsigned int)auth->auth_level ));
2566 state->rpc_call_id = get_rpc_call_id();
2568 prs_init_empty(&state->rpc_out, state, MARSHALL);
2569 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2571 cli->auth = talloc_move(cli, &auth);
2573 /* Marshall the outgoing data. */
2574 status = create_rpc_bind_req(cli, &state->rpc_out,
2576 &cli->abstract_syntax,
2577 &cli->transfer_syntax,
2578 cli->auth->auth_type,
2579 cli->auth->auth_level);
2581 if (!NT_STATUS_IS_OK(status)) {
2585 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2587 if (subreq == NULL) {
2588 status = NT_STATUS_NO_MEMORY;
2591 subreq->async.fn = rpc_pipe_bind_step_one_done;
2592 subreq->async.priv = result;
2596 if (async_post_ntstatus(result, ev, status)) {
2599 TALLOC_FREE(result);
2603 static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
2605 struct async_req *req = talloc_get_type_abort(
2606 subreq->async.priv, struct async_req);
2607 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2608 req->private_data, struct rpc_pipe_bind_state);
2609 prs_struct reply_pdu;
2610 struct rpc_hdr_info hdr;
2611 struct rpc_hdr_ba_info hdr_ba;
2614 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2615 TALLOC_FREE(subreq);
2616 if (!NT_STATUS_IS_OK(status)) {
2617 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2618 rpccli_pipe_txt(debug_ctx(), state->cli),
2619 nt_errstr(status)));
2620 async_req_nterror(req, status);
2624 /* Unmarshall the RPC header */
2625 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2626 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2627 prs_mem_free(&reply_pdu);
2628 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2632 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2633 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2635 prs_mem_free(&reply_pdu);
2636 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2640 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2641 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2642 prs_mem_free(&reply_pdu);
2643 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2647 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2648 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2651 * For authenticated binds we may need to do 3 or 4 leg binds.
2654 switch(state->cli->auth->auth_type) {
2656 case PIPE_AUTH_TYPE_NONE:
2657 case PIPE_AUTH_TYPE_SCHANNEL:
2658 /* Bind complete. */
2659 prs_mem_free(&reply_pdu);
2660 async_req_done(req);
2663 case PIPE_AUTH_TYPE_NTLMSSP:
2664 /* Need to send AUTH3 packet - no reply. */
2665 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2667 prs_mem_free(&reply_pdu);
2668 if (!NT_STATUS_IS_OK(status)) {
2669 async_req_nterror(req, status);
2673 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2674 /* Need to send alter context request and reply. */
2675 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2677 prs_mem_free(&reply_pdu);
2678 if (!NT_STATUS_IS_OK(status)) {
2679 async_req_nterror(req, status);
2683 case PIPE_AUTH_TYPE_KRB5:
2687 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2688 (unsigned int)state->cli->auth->auth_type));
2689 prs_mem_free(&reply_pdu);
2690 async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2694 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2695 struct rpc_pipe_bind_state *state,
2696 struct rpc_hdr_info *phdr,
2697 prs_struct *reply_pdu)
2699 DATA_BLOB server_response = data_blob_null;
2700 DATA_BLOB client_reply = data_blob_null;
2701 struct rpc_hdr_auth_info hdr_auth;
2702 struct tevent_req *subreq;
2705 if ((phdr->auth_len == 0)
2706 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2707 return NT_STATUS_INVALID_PARAMETER;
2710 if (!prs_set_offset(
2712 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2713 return NT_STATUS_INVALID_PARAMETER;
2716 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2717 return NT_STATUS_INVALID_PARAMETER;
2720 /* TODO - check auth_type/auth_level match. */
2722 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2723 prs_copy_data_out((char *)server_response.data, reply_pdu,
2726 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2727 server_response, &client_reply);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2731 "blob failed: %s.\n", nt_errstr(status)));
2735 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2737 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2738 state->cli->auth->auth_type,
2739 state->cli->auth->auth_level,
2740 &client_reply, &state->rpc_out);
2741 data_blob_free(&client_reply);
2743 if (!NT_STATUS_IS_OK(status)) {
2747 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2748 (uint8_t *)prs_data_p(&state->rpc_out),
2749 prs_offset(&state->rpc_out));
2750 if (subreq == NULL) {
2751 return NT_STATUS_NO_MEMORY;
2753 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2754 return NT_STATUS_OK;
2757 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2759 struct async_req *req = tevent_req_callback_data(
2760 subreq, struct async_req);
2763 status = rpc_write_recv(subreq);
2764 TALLOC_FREE(subreq);
2765 if (!NT_STATUS_IS_OK(status)) {
2766 async_req_nterror(req, status);
2769 async_req_done(req);
2772 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2773 struct rpc_pipe_bind_state *state,
2774 struct rpc_hdr_info *phdr,
2775 prs_struct *reply_pdu)
2777 DATA_BLOB server_spnego_response = data_blob_null;
2778 DATA_BLOB server_ntlm_response = data_blob_null;
2779 DATA_BLOB client_reply = data_blob_null;
2780 DATA_BLOB tmp_blob = data_blob_null;
2781 RPC_HDR_AUTH hdr_auth;
2782 struct async_req *subreq;
2785 if ((phdr->auth_len == 0)
2786 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2787 return NT_STATUS_INVALID_PARAMETER;
2790 /* Process the returned NTLMSSP blob first. */
2791 if (!prs_set_offset(
2793 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2794 return NT_STATUS_INVALID_PARAMETER;
2797 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2798 return NT_STATUS_INVALID_PARAMETER;
2801 server_spnego_response = data_blob(NULL, phdr->auth_len);
2802 prs_copy_data_out((char *)server_spnego_response.data,
2803 reply_pdu, phdr->auth_len);
2806 * The server might give us back two challenges - tmp_blob is for the
2809 if (!spnego_parse_challenge(server_spnego_response,
2810 &server_ntlm_response, &tmp_blob)) {
2811 data_blob_free(&server_spnego_response);
2812 data_blob_free(&server_ntlm_response);
2813 data_blob_free(&tmp_blob);
2814 return NT_STATUS_INVALID_PARAMETER;
2817 /* We're finished with the server spnego response and the tmp_blob. */
2818 data_blob_free(&server_spnego_response);
2819 data_blob_free(&tmp_blob);
2821 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2822 server_ntlm_response, &client_reply);
2824 /* Finished with the server_ntlm response */
2825 data_blob_free(&server_ntlm_response);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2829 "using server blob failed.\n"));
2830 data_blob_free(&client_reply);
2834 /* SPNEGO wrap the client reply. */
2835 tmp_blob = spnego_gen_auth(client_reply);
2836 data_blob_free(&client_reply);
2837 client_reply = tmp_blob;
2838 tmp_blob = data_blob_null;
2840 /* Now prepare the alter context pdu. */
2841 prs_init_empty(&state->rpc_out, state, MARSHALL);
2843 status = create_rpc_alter_context(state->rpc_call_id,
2844 &state->cli->abstract_syntax,
2845 &state->cli->transfer_syntax,
2846 state->cli->auth->auth_level,
2849 data_blob_free(&client_reply);
2851 if (!NT_STATUS_IS_OK(status)) {
2855 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2856 &state->rpc_out, RPC_ALTCONTRESP);
2857 if (subreq == NULL) {
2858 return NT_STATUS_NO_MEMORY;
2860 subreq->async.fn = rpc_bind_ntlmssp_api_done;
2861 subreq->async.priv = req;
2862 return NT_STATUS_OK;
2865 static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
2867 struct async_req *req = talloc_get_type_abort(
2868 subreq->async.priv, struct async_req);
2869 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2870 req->private_data, struct rpc_pipe_bind_state);
2871 DATA_BLOB server_spnego_response = data_blob_null;
2872 DATA_BLOB tmp_blob = data_blob_null;
2873 prs_struct reply_pdu;
2874 struct rpc_hdr_info hdr;
2875 struct rpc_hdr_auth_info hdr_auth;
2878 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2879 TALLOC_FREE(subreq);
2880 if (!NT_STATUS_IS_OK(status)) {
2881 async_req_nterror(req, status);
2885 /* Get the auth blob from the reply. */
2886 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2887 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2888 "unmarshall RPC_HDR.\n"));
2889 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2893 if (!prs_set_offset(
2895 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2896 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2900 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2901 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2905 server_spnego_response = data_blob(NULL, hdr.auth_len);
2906 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2909 /* Check we got a valid auth response. */
2910 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2911 OID_NTLMSSP, &tmp_blob)) {
2912 data_blob_free(&server_spnego_response);
2913 data_blob_free(&tmp_blob);
2914 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2918 data_blob_free(&server_spnego_response);
2919 data_blob_free(&tmp_blob);
2921 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2922 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2923 async_req_done(req);
2926 NTSTATUS rpc_pipe_bind_recv(struct async_req *req)
2928 return async_req_simple_recv_ntstatus(req);
2931 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2932 struct cli_pipe_auth_data *auth)
2934 TALLOC_CTX *frame = talloc_stackframe();
2935 struct event_context *ev;
2936 struct async_req *req;
2937 NTSTATUS status = NT_STATUS_NO_MEMORY;
2939 ev = event_context_init(frame);
2944 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2949 while (req->state < ASYNC_REQ_DONE) {
2950 event_loop_once(ev);
2953 status = rpc_pipe_bind_recv(req);
2959 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2960 unsigned int timeout)
2962 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2967 return cli_set_timeout(cli, timeout);
2970 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2972 struct cli_state *cli;
2974 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2975 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2976 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2980 cli = rpc_pipe_np_smb_conn(rpc_cli);
2984 E_md4hash(cli->password ? cli->password : "", nt_hash);
2988 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2989 struct cli_pipe_auth_data **presult)
2991 struct cli_pipe_auth_data *result;
2993 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2994 if (result == NULL) {
2995 return NT_STATUS_NO_MEMORY;
2998 result->auth_type = PIPE_AUTH_TYPE_NONE;
2999 result->auth_level = PIPE_AUTH_LEVEL_NONE;
3001 result->user_name = talloc_strdup(result, "");
3002 result->domain = talloc_strdup(result, "");
3003 if ((result->user_name == NULL) || (result->domain == NULL)) {
3004 TALLOC_FREE(result);
3005 return NT_STATUS_NO_MEMORY;
3009 return NT_STATUS_OK;
3012 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3014 ntlmssp_end(&auth->a_u.ntlmssp_state);
3018 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3019 enum pipe_auth_type auth_type,
3020 enum pipe_auth_level auth_level,
3022 const char *username,
3023 const char *password,
3024 struct cli_pipe_auth_data **presult)
3026 struct cli_pipe_auth_data *result;
3029 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3030 if (result == NULL) {
3031 return NT_STATUS_NO_MEMORY;
3034 result->auth_type = auth_type;
3035 result->auth_level = auth_level;
3037 result->user_name = talloc_strdup(result, username);
3038 result->domain = talloc_strdup(result, domain);
3039 if ((result->user_name == NULL) || (result->domain == NULL)) {
3040 status = NT_STATUS_NO_MEMORY;
3044 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3045 if (!NT_STATUS_IS_OK(status)) {
3049 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3051 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3052 if (!NT_STATUS_IS_OK(status)) {
3056 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3057 if (!NT_STATUS_IS_OK(status)) {
3061 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3062 if (!NT_STATUS_IS_OK(status)) {
3067 * Turn off sign+seal to allow selected auth level to turn it back on.
3069 result->a_u.ntlmssp_state->neg_flags &=
3070 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3072 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
3073 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3074 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
3075 result->a_u.ntlmssp_state->neg_flags
3076 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3080 return NT_STATUS_OK;
3083 TALLOC_FREE(result);
3087 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3088 enum pipe_auth_level auth_level,
3089 const uint8_t sess_key[16],
3090 struct cli_pipe_auth_data **presult)
3092 struct cli_pipe_auth_data *result;
3094 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3095 if (result == NULL) {
3096 return NT_STATUS_NO_MEMORY;
3099 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3100 result->auth_level = auth_level;
3102 result->user_name = talloc_strdup(result, "");
3103 result->domain = talloc_strdup(result, domain);
3104 if ((result->user_name == NULL) || (result->domain == NULL)) {
3108 result->a_u.schannel_auth = talloc(result,
3109 struct schannel_auth_struct);
3110 if (result->a_u.schannel_auth == NULL) {
3114 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3115 sizeof(result->a_u.schannel_auth->sess_key));
3116 result->a_u.schannel_auth->seq_num = 0;
3119 return NT_STATUS_OK;
3122 TALLOC_FREE(result);
3123 return NT_STATUS_NO_MEMORY;
3127 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3129 data_blob_free(&auth->session_key);
3134 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3135 enum pipe_auth_level auth_level,
3136 const char *service_princ,
3137 const char *username,
3138 const char *password,
3139 struct cli_pipe_auth_data **presult)
3142 struct cli_pipe_auth_data *result;
3144 if ((username != NULL) && (password != NULL)) {
3145 int ret = kerberos_kinit_password(username, password, 0, NULL);
3147 return NT_STATUS_ACCESS_DENIED;
3151 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3152 if (result == NULL) {
3153 return NT_STATUS_NO_MEMORY;
3156 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3157 result->auth_level = auth_level;
3160 * Username / domain need fixing!
3162 result->user_name = talloc_strdup(result, "");
3163 result->domain = talloc_strdup(result, "");
3164 if ((result->user_name == NULL) || (result->domain == NULL)) {
3168 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3169 result, struct kerberos_auth_struct);
3170 if (result->a_u.kerberos_auth == NULL) {
3173 talloc_set_destructor(result->a_u.kerberos_auth,
3174 cli_auth_kerberos_data_destructor);
3176 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3177 result, service_princ);
3178 if (result->a_u.kerberos_auth->service_principal == NULL) {
3183 return NT_STATUS_OK;
3186 TALLOC_FREE(result);
3187 return NT_STATUS_NO_MEMORY;
3189 return NT_STATUS_NOT_SUPPORTED;
3194 * Create an rpc pipe client struct, connecting to a tcp port.
3196 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3198 const struct ndr_syntax_id *abstract_syntax,
3199 struct rpc_pipe_client **presult)
3201 struct rpc_pipe_client *result;
3202 struct sockaddr_storage addr;
3206 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3207 if (result == NULL) {
3208 return NT_STATUS_NO_MEMORY;
3211 result->abstract_syntax = *abstract_syntax;
3212 result->transfer_syntax = ndr_transfer_syntax;
3213 result->dispatch = cli_do_rpc_ndr;
3215 result->desthost = talloc_strdup(result, host);
3216 result->srv_name_slash = talloc_asprintf_strupper_m(
3217 result, "\\\\%s", result->desthost);
3218 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3219 status = NT_STATUS_NO_MEMORY;
3223 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3224 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3226 if (!resolve_name(host, &addr, 0)) {
3227 status = NT_STATUS_NOT_FOUND;
3231 status = open_socket_out(&addr, port, 60, &fd);
3232 if (!NT_STATUS_IS_OK(status)) {
3235 set_socket_options(fd, lp_socket_options());
3237 status = rpc_transport_sock_init(result, fd, &result->transport);
3238 if (!NT_STATUS_IS_OK(status)) {
3244 return NT_STATUS_OK;
3247 TALLOC_FREE(result);
3252 * Determine the tcp port on which a dcerpc interface is listening
3253 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3256 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3257 const struct ndr_syntax_id *abstract_syntax,
3261 struct rpc_pipe_client *epm_pipe = NULL;
3262 struct cli_pipe_auth_data *auth = NULL;
3263 struct dcerpc_binding *map_binding = NULL;
3264 struct dcerpc_binding *res_binding = NULL;
3265 struct epm_twr_t *map_tower = NULL;
3266 struct epm_twr_t *res_towers = NULL;
3267 struct policy_handle *entry_handle = NULL;
3268 uint32_t num_towers = 0;
3269 uint32_t max_towers = 1;
3270 struct epm_twr_p_t towers;
3271 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3273 if (pport == NULL) {
3274 status = NT_STATUS_INVALID_PARAMETER;
3278 /* open the connection to the endpoint mapper */
3279 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3280 &ndr_table_epmapper.syntax_id,
3283 if (!NT_STATUS_IS_OK(status)) {
3287 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3288 if (!NT_STATUS_IS_OK(status)) {
3292 status = rpc_pipe_bind(epm_pipe, auth);
3293 if (!NT_STATUS_IS_OK(status)) {
3297 /* create tower for asking the epmapper */
3299 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3300 if (map_binding == NULL) {
3301 status = NT_STATUS_NO_MEMORY;
3305 map_binding->transport = NCACN_IP_TCP;
3306 map_binding->object = *abstract_syntax;
3307 map_binding->host = host; /* needed? */
3308 map_binding->endpoint = "0"; /* correct? needed? */
3310 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3311 if (map_tower == NULL) {
3312 status = NT_STATUS_NO_MEMORY;
3316 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3317 &(map_tower->tower));
3318 if (!NT_STATUS_IS_OK(status)) {
3322 /* allocate further parameters for the epm_Map call */
3324 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3325 if (res_towers == NULL) {
3326 status = NT_STATUS_NO_MEMORY;
3329 towers.twr = res_towers;
3331 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3332 if (entry_handle == NULL) {
3333 status = NT_STATUS_NO_MEMORY;
3337 /* ask the endpoint mapper for the port */
3339 status = rpccli_epm_Map(epm_pipe,
3341 CONST_DISCARD(struct GUID *,
3342 &(abstract_syntax->uuid)),
3349 if (!NT_STATUS_IS_OK(status)) {
3353 if (num_towers != 1) {
3354 status = NT_STATUS_UNSUCCESSFUL;
3358 /* extract the port from the answer */
3360 status = dcerpc_binding_from_tower(tmp_ctx,
3361 &(towers.twr->tower),
3363 if (!NT_STATUS_IS_OK(status)) {
3367 /* are further checks here necessary? */
3368 if (res_binding->transport != NCACN_IP_TCP) {
3369 status = NT_STATUS_UNSUCCESSFUL;
3373 *pport = (uint16_t)atoi(res_binding->endpoint);
3376 TALLOC_FREE(tmp_ctx);
3381 * Create a rpc pipe client struct, connecting to a host via tcp.
3382 * The port is determined by asking the endpoint mapper on the given
3385 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3386 const struct ndr_syntax_id *abstract_syntax,
3387 struct rpc_pipe_client **presult)
3394 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3395 if (!NT_STATUS_IS_OK(status)) {
3399 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3400 abstract_syntax, presult);
3406 /********************************************************************
3407 Create a rpc pipe client struct, connecting to a unix domain socket
3408 ********************************************************************/
3409 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3410 const struct ndr_syntax_id *abstract_syntax,
3411 struct rpc_pipe_client **presult)
3413 struct rpc_pipe_client *result;
3414 struct sockaddr_un addr;
3418 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3419 if (result == NULL) {
3420 return NT_STATUS_NO_MEMORY;
3423 result->abstract_syntax = *abstract_syntax;
3424 result->transfer_syntax = ndr_transfer_syntax;
3425 result->dispatch = cli_do_rpc_ndr;
3427 result->desthost = get_myname(result);
3428 result->srv_name_slash = talloc_asprintf_strupper_m(
3429 result, "\\\\%s", result->desthost);
3430 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3431 status = NT_STATUS_NO_MEMORY;
3435 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3436 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3438 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3440 status = map_nt_error_from_unix(errno);
3445 addr.sun_family = AF_UNIX;
3446 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3448 if (sys_connect(fd, (struct sockaddr *)&addr) == -1) {
3449 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3452 return map_nt_error_from_unix(errno);
3455 status = rpc_transport_sock_init(result, fd, &result->transport);
3456 if (!NT_STATUS_IS_OK(status)) {
3462 return NT_STATUS_OK;
3465 TALLOC_FREE(result);
3469 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3471 struct cli_state *cli;
3473 cli = rpc_pipe_np_smb_conn(p);
3475 DLIST_REMOVE(cli->pipe_list, p);
3480 /****************************************************************************
3481 Open a named pipe over SMB to a remote server.
3483 * CAVEAT CALLER OF THIS FUNCTION:
3484 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3485 * so be sure that this function is called AFTER any structure (vs pointer)
3486 * assignment of the cli. In particular, libsmbclient does structure
3487 * assignments of cli, which invalidates the data in the returned
3488 * rpc_pipe_client if this function is called before the structure assignment
3491 ****************************************************************************/
3493 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3494 const struct ndr_syntax_id *abstract_syntax,
3495 struct rpc_pipe_client **presult)
3497 struct rpc_pipe_client *result;
3500 /* sanity check to protect against crashes */
3503 return NT_STATUS_INVALID_HANDLE;
3506 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3507 if (result == NULL) {
3508 return NT_STATUS_NO_MEMORY;
3511 result->abstract_syntax = *abstract_syntax;
3512 result->transfer_syntax = ndr_transfer_syntax;
3513 result->dispatch = cli_do_rpc_ndr;
3514 result->desthost = talloc_strdup(result, cli->desthost);
3515 result->srv_name_slash = talloc_asprintf_strupper_m(
3516 result, "\\\\%s", result->desthost);
3518 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3519 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3521 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3522 TALLOC_FREE(result);
3523 return NT_STATUS_NO_MEMORY;
3526 status = rpc_transport_np_init(result, cli, abstract_syntax,
3527 &result->transport);
3528 if (!NT_STATUS_IS_OK(status)) {
3529 TALLOC_FREE(result);
3533 DLIST_ADD(cli->pipe_list, result);
3534 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3537 return NT_STATUS_OK;
3540 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3541 struct rpc_cli_smbd_conn *conn,
3542 const struct ndr_syntax_id *syntax,
3543 struct rpc_pipe_client **presult)
3545 struct rpc_pipe_client *result;
3546 struct cli_pipe_auth_data *auth;
3549 result = talloc(mem_ctx, struct rpc_pipe_client);
3550 if (result == NULL) {
3551 return NT_STATUS_NO_MEMORY;
3553 result->abstract_syntax = *syntax;
3554 result->transfer_syntax = ndr_transfer_syntax;
3555 result->dispatch = cli_do_rpc_ndr;
3556 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3557 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3559 result->desthost = talloc_strdup(result, global_myname());
3560 result->srv_name_slash = talloc_asprintf_strupper_m(
3561 result, "\\\\%s", global_myname());
3562 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3563 TALLOC_FREE(result);
3564 return NT_STATUS_NO_MEMORY;
3567 status = rpc_transport_smbd_init(result, conn, syntax,
3568 &result->transport);
3569 if (!NT_STATUS_IS_OK(status)) {
3570 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3571 nt_errstr(status)));
3572 TALLOC_FREE(result);
3576 status = rpccli_anon_bind_data(result, &auth);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3579 nt_errstr(status)));
3580 TALLOC_FREE(result);
3584 status = rpc_pipe_bind(result, auth);
3585 if (!NT_STATUS_IS_OK(status)) {
3586 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3587 TALLOC_FREE(result);
3592 return NT_STATUS_OK;
3595 /****************************************************************************
3596 Open a pipe to a remote server.
3597 ****************************************************************************/
3599 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3600 const struct ndr_syntax_id *interface,
3601 struct rpc_pipe_client **presult)
3603 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3605 * We should have a better way to figure out this drsuapi
3608 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3612 return rpc_pipe_open_np(cli, interface, presult);
3615 /****************************************************************************
3616 Open a named pipe to an SMB server and bind anonymously.
3617 ****************************************************************************/
3619 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3620 const struct ndr_syntax_id *interface,
3621 struct rpc_pipe_client **presult)
3623 struct rpc_pipe_client *result;
3624 struct cli_pipe_auth_data *auth;
3627 status = cli_rpc_pipe_open(cli, interface, &result);
3628 if (!NT_STATUS_IS_OK(status)) {
3632 status = rpccli_anon_bind_data(result, &auth);
3633 if (!NT_STATUS_IS_OK(status)) {
3634 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3635 nt_errstr(status)));
3636 TALLOC_FREE(result);
3641 * This is a bit of an abstraction violation due to the fact that an
3642 * anonymous bind on an authenticated SMB inherits the user/domain
3643 * from the enclosing SMB creds
3646 TALLOC_FREE(auth->user_name);
3647 TALLOC_FREE(auth->domain);
3649 auth->user_name = talloc_strdup(auth, cli->user_name);
3650 auth->domain = talloc_strdup(auth, cli->domain);
3651 auth->user_session_key = data_blob_talloc(auth,
3652 cli->user_session_key.data,
3653 cli->user_session_key.length);
3655 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3656 TALLOC_FREE(result);
3657 return NT_STATUS_NO_MEMORY;
3660 status = rpc_pipe_bind(result, auth);
3661 if (!NT_STATUS_IS_OK(status)) {
3663 if (ndr_syntax_id_equal(interface,
3664 &ndr_table_dssetup.syntax_id)) {
3665 /* non AD domains just don't have this pipe, avoid
3666 * level 0 statement in that case - gd */
3669 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3670 "%s failed with error %s\n",
3671 get_pipe_name_from_iface(interface),
3672 nt_errstr(status) ));
3673 TALLOC_FREE(result);
3677 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3678 "%s and bound anonymously.\n",
3679 get_pipe_name_from_iface(interface), cli->desthost));
3682 return NT_STATUS_OK;
3685 /****************************************************************************
3686 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3687 ****************************************************************************/
3689 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3690 const struct ndr_syntax_id *interface,
3691 enum pipe_auth_type auth_type,
3692 enum pipe_auth_level auth_level,
3694 const char *username,
3695 const char *password,
3696 struct rpc_pipe_client **presult)
3698 struct rpc_pipe_client *result;
3699 struct cli_pipe_auth_data *auth;
3702 status = cli_rpc_pipe_open(cli, interface, &result);
3703 if (!NT_STATUS_IS_OK(status)) {
3707 status = rpccli_ntlmssp_bind_data(
3708 result, auth_type, auth_level, domain, username,
3710 if (!NT_STATUS_IS_OK(status)) {
3711 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3712 nt_errstr(status)));
3716 status = rpc_pipe_bind(result, auth);
3717 if (!NT_STATUS_IS_OK(status)) {
3718 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3719 nt_errstr(status) ));
3723 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3724 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3725 get_pipe_name_from_iface(interface), cli->desthost, domain,
3729 return NT_STATUS_OK;
3733 TALLOC_FREE(result);
3737 /****************************************************************************
3739 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3740 ****************************************************************************/
3742 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3743 const struct ndr_syntax_id *interface,
3744 enum pipe_auth_level auth_level,
3746 const char *username,
3747 const char *password,
3748 struct rpc_pipe_client **presult)
3750 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3752 PIPE_AUTH_TYPE_NTLMSSP,
3760 /****************************************************************************
3762 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3763 ****************************************************************************/
3765 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3766 const struct ndr_syntax_id *interface,
3767 enum pipe_auth_level auth_level,
3769 const char *username,
3770 const char *password,
3771 struct rpc_pipe_client **presult)
3773 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3775 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3783 /****************************************************************************
3784 Get a the schannel session key out of an already opened netlogon pipe.
3785 ****************************************************************************/
3786 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3787 struct cli_state *cli,
3791 uint32 sec_chan_type = 0;
3792 unsigned char machine_pwd[16];
3793 const char *machine_account;
3796 /* Get the machine account credentials from secrets.tdb. */
3797 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3800 DEBUG(0, ("get_schannel_session_key: could not fetch "
3801 "trust account password for domain '%s'\n",
3803 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3806 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3807 cli->desthost, /* server name */
3808 domain, /* domain */
3809 global_myname(), /* client name */
3810 machine_account, /* machine account name */
3815 if (!NT_STATUS_IS_OK(status)) {
3816 DEBUG(3, ("get_schannel_session_key_common: "
3817 "rpccli_netlogon_setup_creds failed with result %s "
3818 "to server %s, domain %s, machine account %s.\n",
3819 nt_errstr(status), cli->desthost, domain,
3824 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3825 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3827 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3830 return NT_STATUS_OK;;
3833 /****************************************************************************
3834 Open a netlogon pipe and get the schannel session key.
3835 Now exposed to external callers.
3836 ****************************************************************************/
3839 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3842 struct rpc_pipe_client **presult)
3844 struct rpc_pipe_client *netlogon_pipe = NULL;
3847 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3849 if (!NT_STATUS_IS_OK(status)) {
3853 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3855 if (!NT_STATUS_IS_OK(status)) {
3856 TALLOC_FREE(netlogon_pipe);
3860 *presult = netlogon_pipe;
3861 return NT_STATUS_OK;
3864 /****************************************************************************
3866 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3867 using session_key. sign and seal.
3868 ****************************************************************************/
3870 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3871 const struct ndr_syntax_id *interface,
3872 enum pipe_auth_level auth_level,
3874 const struct dcinfo *pdc,
3875 struct rpc_pipe_client **presult)
3877 struct rpc_pipe_client *result;
3878 struct cli_pipe_auth_data *auth;
3881 status = cli_rpc_pipe_open(cli, interface, &result);
3882 if (!NT_STATUS_IS_OK(status)) {
3886 status = rpccli_schannel_bind_data(result, domain, auth_level,
3887 pdc->sess_key, &auth);
3888 if (!NT_STATUS_IS_OK(status)) {
3889 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3890 nt_errstr(status)));
3891 TALLOC_FREE(result);
3895 status = rpc_pipe_bind(result, auth);
3896 if (!NT_STATUS_IS_OK(status)) {
3897 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3898 "cli_rpc_pipe_bind failed with error %s\n",
3899 nt_errstr(status) ));
3900 TALLOC_FREE(result);
3905 * The credentials on a new netlogon pipe are the ones we are passed
3906 * in - copy them over.
3908 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3909 if (result->dc == NULL) {
3910 DEBUG(0, ("talloc failed\n"));
3911 TALLOC_FREE(result);
3912 return NT_STATUS_NO_MEMORY;
3915 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3916 "for domain %s and bound using schannel.\n",
3917 get_pipe_name_from_iface(interface),
3918 cli->desthost, domain ));
3921 return NT_STATUS_OK;
3924 /****************************************************************************
3925 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3926 Fetch the session key ourselves using a temporary netlogon pipe. This
3927 version uses an ntlmssp auth bound netlogon pipe to get the key.
3928 ****************************************************************************/
3930 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3932 const char *username,
3933 const char *password,
3935 struct rpc_pipe_client **presult)
3937 struct rpc_pipe_client *netlogon_pipe = NULL;
3940 status = cli_rpc_pipe_open_spnego_ntlmssp(
3941 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3942 domain, username, password, &netlogon_pipe);
3943 if (!NT_STATUS_IS_OK(status)) {
3947 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3949 if (!NT_STATUS_IS_OK(status)) {
3950 TALLOC_FREE(netlogon_pipe);
3954 *presult = netlogon_pipe;
3955 return NT_STATUS_OK;
3958 /****************************************************************************
3959 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3960 Fetch the session key ourselves using a temporary netlogon pipe. This version
3961 uses an ntlmssp bind to get the session key.
3962 ****************************************************************************/
3964 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3965 const struct ndr_syntax_id *interface,
3966 enum pipe_auth_level auth_level,
3968 const char *username,
3969 const char *password,
3970 struct rpc_pipe_client **presult)
3972 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3973 struct rpc_pipe_client *netlogon_pipe = NULL;
3974 struct rpc_pipe_client *result = NULL;
3977 status = get_schannel_session_key_auth_ntlmssp(
3978 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3979 if (!NT_STATUS_IS_OK(status)) {
3980 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3981 "key from server %s for domain %s.\n",
3982 cli->desthost, domain ));
3986 status = cli_rpc_pipe_open_schannel_with_key(
3987 cli, interface, auth_level, domain, netlogon_pipe->dc,
3990 /* Now we've bound using the session key we can close the netlog pipe. */
3991 TALLOC_FREE(netlogon_pipe);
3993 if (NT_STATUS_IS_OK(status)) {
3999 /****************************************************************************
4000 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4001 Fetch the session key ourselves using a temporary netlogon pipe.
4002 ****************************************************************************/
4004 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4005 const struct ndr_syntax_id *interface,
4006 enum pipe_auth_level auth_level,
4008 struct rpc_pipe_client **presult)
4010 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4011 struct rpc_pipe_client *netlogon_pipe = NULL;
4012 struct rpc_pipe_client *result = NULL;
4015 status = get_schannel_session_key(cli, domain, &neg_flags,
4017 if (!NT_STATUS_IS_OK(status)) {
4018 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4019 "key from server %s for domain %s.\n",
4020 cli->desthost, domain ));
4024 status = cli_rpc_pipe_open_schannel_with_key(
4025 cli, interface, auth_level, domain, netlogon_pipe->dc,
4028 /* Now we've bound using the session key we can close the netlog pipe. */
4029 TALLOC_FREE(netlogon_pipe);
4031 if (NT_STATUS_IS_OK(status)) {
4035 return NT_STATUS_OK;
4038 /****************************************************************************
4039 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4040 The idea is this can be called with service_princ, username and password all
4041 NULL so long as the caller has a TGT.
4042 ****************************************************************************/
4044 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4045 const struct ndr_syntax_id *interface,
4046 enum pipe_auth_level auth_level,
4047 const char *service_princ,
4048 const char *username,
4049 const char *password,
4050 struct rpc_pipe_client **presult)
4053 struct rpc_pipe_client *result;
4054 struct cli_pipe_auth_data *auth;
4057 status = cli_rpc_pipe_open(cli, interface, &result);
4058 if (!NT_STATUS_IS_OK(status)) {
4062 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4063 username, password, &auth);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4066 nt_errstr(status)));
4067 TALLOC_FREE(result);
4071 status = rpc_pipe_bind(result, auth);
4072 if (!NT_STATUS_IS_OK(status)) {
4073 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4074 "with error %s\n", nt_errstr(status)));
4075 TALLOC_FREE(result);
4080 return NT_STATUS_OK;
4082 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4083 return NT_STATUS_NOT_IMPLEMENTED;
4087 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4088 struct rpc_pipe_client *cli,
4089 DATA_BLOB *session_key)
4091 if (!session_key || !cli) {
4092 return NT_STATUS_INVALID_PARAMETER;
4096 return NT_STATUS_INVALID_PARAMETER;
4099 switch (cli->auth->auth_type) {
4100 case PIPE_AUTH_TYPE_SCHANNEL:
4101 *session_key = data_blob_talloc(mem_ctx,
4102 cli->auth->a_u.schannel_auth->sess_key, 16);
4104 case PIPE_AUTH_TYPE_NTLMSSP:
4105 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4106 *session_key = data_blob_talloc(mem_ctx,
4107 cli->auth->a_u.ntlmssp_state->session_key.data,
4108 cli->auth->a_u.ntlmssp_state->session_key.length);
4110 case PIPE_AUTH_TYPE_KRB5:
4111 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4112 *session_key = data_blob_talloc(mem_ctx,
4113 cli->auth->a_u.kerberos_auth->session_key.data,
4114 cli->auth->a_u.kerberos_auth->session_key.length);
4116 case PIPE_AUTH_TYPE_NONE:
4117 *session_key = data_blob_talloc(mem_ctx,
4118 cli->auth->user_session_key.data,
4119 cli->auth->user_session_key.length);
4122 return NT_STATUS_NO_USER_SESSION_KEY;
4125 return NT_STATUS_OK;