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 tevent_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, *subreq;
218 struct rpc_read_state *state;
220 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
225 state->transport = transport;
230 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
232 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
234 if (subreq == NULL) {
237 tevent_req_set_callback(subreq, rpc_read_done, req);
245 static void rpc_read_done(struct tevent_req *subreq)
247 struct tevent_req *req = tevent_req_callback_data(
248 subreq, struct tevent_req);
249 struct rpc_read_state *state = tevent_req_data(
250 req, struct rpc_read_state);
254 status = state->transport->read_recv(subreq, &received);
256 if (!NT_STATUS_IS_OK(status)) {
257 tevent_req_nterror(req, status);
261 state->num_read += received;
262 if (state->num_read == state->size) {
263 tevent_req_done(req);
267 subreq = state->transport->read_send(state, state->ev,
268 state->data + state->num_read,
269 state->size - state->num_read,
270 state->transport->priv);
271 if (tevent_req_nomem(subreq, req)) {
274 tevent_req_set_callback(subreq, rpc_read_done, req);
277 static NTSTATUS rpc_read_recv(struct tevent_req *req)
279 return tevent_req_simple_recv_ntstatus(req);
282 struct rpc_write_state {
283 struct event_context *ev;
284 struct rpc_cli_transport *transport;
290 static void rpc_write_done(struct tevent_req *subreq);
292 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
293 struct event_context *ev,
294 struct rpc_cli_transport *transport,
295 const uint8_t *data, size_t size)
297 struct tevent_req *req, *subreq;
298 struct rpc_write_state *state;
300 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
305 state->transport = transport;
308 state->num_written = 0;
310 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
312 subreq = transport->write_send(state, ev, data, size, transport->priv);
313 if (subreq == NULL) {
316 tevent_req_set_callback(subreq, rpc_write_done, req);
323 static void rpc_write_done(struct tevent_req *subreq)
325 struct tevent_req *req = tevent_req_callback_data(
326 subreq, struct tevent_req);
327 struct rpc_write_state *state = tevent_req_data(
328 req, struct rpc_write_state);
332 status = state->transport->write_recv(subreq, &written);
334 if (!NT_STATUS_IS_OK(status)) {
335 tevent_req_nterror(req, status);
339 state->num_written += written;
341 if (state->num_written == state->size) {
342 tevent_req_done(req);
346 subreq = state->transport->write_send(state, state->ev,
347 state->data + state->num_written,
348 state->size - state->num_written,
349 state->transport->priv);
350 if (tevent_req_nomem(subreq, req)) {
353 tevent_req_set_callback(subreq, rpc_write_done, req);
356 static NTSTATUS rpc_write_recv(struct tevent_req *req)
358 return tevent_req_simple_recv_ntstatus(req);
362 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
363 struct rpc_hdr_info *prhdr,
367 * This next call sets the endian bit correctly in current_pdu. We
368 * will propagate this to rbuf later.
371 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
372 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
373 return NT_STATUS_BUFFER_TOO_SMALL;
376 if (prhdr->frag_len > cli->max_recv_frag) {
377 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
378 " we only allow %d\n", (int)prhdr->frag_len,
379 (int)cli->max_recv_frag));
380 return NT_STATUS_BUFFER_TOO_SMALL;
386 /****************************************************************************
387 Try and get a PDU's worth of data from current_pdu. If not, then read more
389 ****************************************************************************/
391 struct get_complete_frag_state {
392 struct event_context *ev;
393 struct rpc_pipe_client *cli;
394 struct rpc_hdr_info *prhdr;
398 static void get_complete_frag_got_header(struct tevent_req *subreq);
399 static void get_complete_frag_got_rest(struct tevent_req *subreq);
401 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
402 struct event_context *ev,
403 struct rpc_pipe_client *cli,
404 struct rpc_hdr_info *prhdr,
407 struct tevent_req *req, *subreq;
408 struct get_complete_frag_state *state;
412 req = tevent_req_create(mem_ctx, &state,
413 struct get_complete_frag_state);
419 state->prhdr = prhdr;
422 pdu_len = prs_data_size(pdu);
423 if (pdu_len < RPC_HEADER_LEN) {
424 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
425 status = NT_STATUS_NO_MEMORY;
428 subreq = rpc_read_send(
430 state->cli->transport,
431 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
432 RPC_HEADER_LEN - pdu_len);
433 if (subreq == NULL) {
434 status = NT_STATUS_NO_MEMORY;
437 tevent_req_set_callback(subreq, get_complete_frag_got_header,
442 status = parse_rpc_header(cli, prhdr, pdu);
443 if (!NT_STATUS_IS_OK(status)) {
448 * Ensure we have frag_len bytes of data.
450 if (pdu_len < prhdr->frag_len) {
451 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
452 status = NT_STATUS_NO_MEMORY;
455 subreq = rpc_read_send(state, state->ev,
456 state->cli->transport,
457 (uint8_t *)(prs_data_p(pdu) + pdu_len),
458 prhdr->frag_len - pdu_len);
459 if (subreq == NULL) {
460 status = NT_STATUS_NO_MEMORY;
463 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
468 status = NT_STATUS_OK;
470 if (NT_STATUS_IS_OK(status)) {
471 tevent_req_done(req);
473 tevent_req_nterror(req, status);
475 return tevent_req_post(req, ev);
478 static void get_complete_frag_got_header(struct tevent_req *subreq)
480 struct tevent_req *req = tevent_req_callback_data(
481 subreq, struct tevent_req);
482 struct get_complete_frag_state *state = tevent_req_data(
483 req, struct get_complete_frag_state);
486 status = rpc_read_recv(subreq);
488 if (!NT_STATUS_IS_OK(status)) {
489 tevent_req_nterror(req, status);
493 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
494 if (!NT_STATUS_IS_OK(status)) {
495 tevent_req_nterror(req, status);
499 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
500 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
505 * We're here in this piece of code because we've read exactly
506 * RPC_HEADER_LEN bytes into state->pdu.
509 subreq = rpc_read_send(
510 state, state->ev, state->cli->transport,
511 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
512 state->prhdr->frag_len - RPC_HEADER_LEN);
513 if (tevent_req_nomem(subreq, req)) {
516 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
519 static void get_complete_frag_got_rest(struct tevent_req *subreq)
521 struct tevent_req *req = tevent_req_callback_data(
522 subreq, struct tevent_req);
525 status = rpc_read_recv(subreq);
527 if (!NT_STATUS_IS_OK(status)) {
528 tevent_req_nterror(req, status);
531 tevent_req_done(req);
534 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
536 return tevent_req_simple_recv_ntstatus(req);
539 /****************************************************************************
540 NTLMSSP specific sign/seal.
541 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
542 In fact I should probably abstract these into identical pieces of code... JRA.
543 ****************************************************************************/
545 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
546 prs_struct *current_pdu,
547 uint8 *p_ss_padding_len)
549 RPC_HDR_AUTH auth_info;
550 uint32 save_offset = prs_offset(current_pdu);
551 uint32 auth_len = prhdr->auth_len;
552 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
553 unsigned char *data = NULL;
555 unsigned char *full_packet_data = NULL;
556 size_t full_packet_data_len;
560 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
561 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
565 if (!ntlmssp_state) {
566 return NT_STATUS_INVALID_PARAMETER;
569 /* Ensure there's enough data for an authenticated response. */
570 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
571 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
572 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
573 (unsigned int)auth_len ));
574 return NT_STATUS_BUFFER_TOO_SMALL;
578 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
579 * after the RPC header.
580 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
581 * functions as NTLMv2 checks the rpc headers also.
584 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
585 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
587 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
588 full_packet_data_len = prhdr->frag_len - auth_len;
590 /* Pull the auth header and the following data into a blob. */
591 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
592 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
593 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
594 return NT_STATUS_BUFFER_TOO_SMALL;
597 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
598 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
599 return NT_STATUS_BUFFER_TOO_SMALL;
602 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
603 auth_blob.length = auth_len;
605 switch (cli->auth->auth_level) {
606 case PIPE_AUTH_LEVEL_PRIVACY:
607 /* Data is encrypted. */
608 status = ntlmssp_unseal_packet(ntlmssp_state,
611 full_packet_data_len,
613 if (!NT_STATUS_IS_OK(status)) {
614 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
615 "packet from %s. Error was %s.\n",
616 rpccli_pipe_txt(debug_ctx(), cli),
617 nt_errstr(status) ));
621 case PIPE_AUTH_LEVEL_INTEGRITY:
622 /* Data is signed. */
623 status = ntlmssp_check_packet(ntlmssp_state,
626 full_packet_data_len,
628 if (!NT_STATUS_IS_OK(status)) {
629 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
630 "packet from %s. Error was %s.\n",
631 rpccli_pipe_txt(debug_ctx(), cli),
632 nt_errstr(status) ));
637 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
638 "auth level %d\n", cli->auth->auth_level));
639 return NT_STATUS_INVALID_INFO_CLASS;
643 * Return the current pointer to the data offset.
646 if(!prs_set_offset(current_pdu, save_offset)) {
647 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
648 (unsigned int)save_offset ));
649 return NT_STATUS_BUFFER_TOO_SMALL;
653 * Remember the padding length. We must remove it from the real data
654 * stream once the sign/seal is done.
657 *p_ss_padding_len = auth_info.auth_pad_len;
662 /****************************************************************************
663 schannel specific sign/seal.
664 ****************************************************************************/
666 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
667 prs_struct *current_pdu,
668 uint8 *p_ss_padding_len)
670 RPC_HDR_AUTH auth_info;
671 RPC_AUTH_SCHANNEL_CHK schannel_chk;
672 uint32 auth_len = prhdr->auth_len;
673 uint32 save_offset = prs_offset(current_pdu);
674 struct schannel_auth_struct *schannel_auth =
675 cli->auth->a_u.schannel_auth;
678 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
679 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
683 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
684 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
685 return NT_STATUS_INVALID_PARAMETER;
688 if (!schannel_auth) {
689 return NT_STATUS_INVALID_PARAMETER;
692 /* Ensure there's enough data for an authenticated response. */
693 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
694 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
695 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
696 (unsigned int)auth_len ));
697 return NT_STATUS_INVALID_PARAMETER;
700 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
702 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
703 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
704 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
705 return NT_STATUS_BUFFER_TOO_SMALL;
708 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
709 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
710 return NT_STATUS_BUFFER_TOO_SMALL;
713 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
714 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
715 auth_info.auth_type));
716 return NT_STATUS_BUFFER_TOO_SMALL;
719 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
720 &schannel_chk, current_pdu, 0)) {
721 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
722 return NT_STATUS_BUFFER_TOO_SMALL;
725 if (!schannel_decode(schannel_auth,
726 cli->auth->auth_level,
729 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
731 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
732 "Connection to %s.\n",
733 rpccli_pipe_txt(debug_ctx(), cli)));
734 return NT_STATUS_INVALID_PARAMETER;
737 /* The sequence number gets incremented on both send and receive. */
738 schannel_auth->seq_num++;
741 * Return the current pointer to the data offset.
744 if(!prs_set_offset(current_pdu, save_offset)) {
745 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
746 (unsigned int)save_offset ));
747 return NT_STATUS_BUFFER_TOO_SMALL;
751 * Remember the padding length. We must remove it from the real data
752 * stream once the sign/seal is done.
755 *p_ss_padding_len = auth_info.auth_pad_len;
760 /****************************************************************************
761 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
762 ****************************************************************************/
764 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
765 prs_struct *current_pdu,
766 uint8 *p_ss_padding_len)
768 NTSTATUS ret = NT_STATUS_OK;
770 /* Paranioa checks for auth_len. */
771 if (prhdr->auth_len) {
772 if (prhdr->auth_len > prhdr->frag_len) {
773 return NT_STATUS_INVALID_PARAMETER;
776 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
777 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
778 /* Integer wrap attempt. */
779 return NT_STATUS_INVALID_PARAMETER;
784 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
787 switch(cli->auth->auth_type) {
788 case PIPE_AUTH_TYPE_NONE:
789 if (prhdr->auth_len) {
790 DEBUG(3, ("cli_pipe_validate_rpc_response: "
791 "Connection to %s - got non-zero "
793 rpccli_pipe_txt(debug_ctx(), cli),
794 (unsigned int)prhdr->auth_len ));
795 return NT_STATUS_INVALID_PARAMETER;
799 case PIPE_AUTH_TYPE_NTLMSSP:
800 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
801 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
802 if (!NT_STATUS_IS_OK(ret)) {
807 case PIPE_AUTH_TYPE_SCHANNEL:
808 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
809 if (!NT_STATUS_IS_OK(ret)) {
814 case PIPE_AUTH_TYPE_KRB5:
815 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
817 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
818 "to %s - unknown internal auth type %u.\n",
819 rpccli_pipe_txt(debug_ctx(), cli),
820 cli->auth->auth_type ));
821 return NT_STATUS_INVALID_INFO_CLASS;
827 /****************************************************************************
828 Do basic authentication checks on an incoming pdu.
829 ****************************************************************************/
831 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
832 prs_struct *current_pdu,
833 uint8 expected_pkt_type,
836 prs_struct *return_data)
839 NTSTATUS ret = NT_STATUS_OK;
840 uint32 current_pdu_len = prs_data_size(current_pdu);
842 if (current_pdu_len != prhdr->frag_len) {
843 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
844 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
845 return NT_STATUS_INVALID_PARAMETER;
849 * Point the return values at the real data including the RPC
850 * header. Just in case the caller wants it.
852 *ppdata = prs_data_p(current_pdu);
853 *pdata_len = current_pdu_len;
855 /* Ensure we have the correct type. */
856 switch (prhdr->pkt_type) {
857 case RPC_ALTCONTRESP:
860 /* Alter context and bind ack share the same packet definitions. */
866 RPC_HDR_RESP rhdr_resp;
867 uint8 ss_padding_len = 0;
869 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
870 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
871 return NT_STATUS_BUFFER_TOO_SMALL;
874 /* Here's where we deal with incoming sign/seal. */
875 ret = cli_pipe_validate_rpc_response(cli, prhdr,
876 current_pdu, &ss_padding_len);
877 if (!NT_STATUS_IS_OK(ret)) {
881 /* Point the return values at the NDR data. Remember to remove any ss padding. */
882 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
884 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
885 return NT_STATUS_BUFFER_TOO_SMALL;
888 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
890 /* Remember to remove the auth footer. */
891 if (prhdr->auth_len) {
892 /* We've already done integer wrap tests on auth_len in
893 cli_pipe_validate_rpc_response(). */
894 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
895 return NT_STATUS_BUFFER_TOO_SMALL;
897 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
900 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
901 current_pdu_len, *pdata_len, ss_padding_len ));
904 * If this is the first reply, and the allocation hint is reasonably, try and
905 * set up the return_data parse_struct to the correct size.
908 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
909 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
910 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
911 "too large to allocate\n",
912 (unsigned int)rhdr_resp.alloc_hint ));
913 return NT_STATUS_NO_MEMORY;
921 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
922 "received from %s!\n",
923 rpccli_pipe_txt(debug_ctx(), cli)));
924 /* Use this for now... */
925 return NT_STATUS_NETWORK_ACCESS_DENIED;
929 RPC_HDR_RESP rhdr_resp;
930 RPC_HDR_FAULT fault_resp;
932 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
933 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
934 return NT_STATUS_BUFFER_TOO_SMALL;
937 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
938 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
939 return NT_STATUS_BUFFER_TOO_SMALL;
942 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
943 "code %s received from %s!\n",
944 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
945 rpccli_pipe_txt(debug_ctx(), cli)));
946 if (NT_STATUS_IS_OK(fault_resp.status)) {
947 return NT_STATUS_UNSUCCESSFUL;
949 return fault_resp.status;
954 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
956 (unsigned int)prhdr->pkt_type,
957 rpccli_pipe_txt(debug_ctx(), cli)));
958 return NT_STATUS_INVALID_INFO_CLASS;
961 if (prhdr->pkt_type != expected_pkt_type) {
962 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
963 "got an unexpected RPC packet type - %u, not %u\n",
964 rpccli_pipe_txt(debug_ctx(), cli),
967 return NT_STATUS_INVALID_INFO_CLASS;
970 /* Do this just before return - we don't want to modify any rpc header
971 data before now as we may have needed to do cryptographic actions on
974 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
975 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
976 "setting fragment first/last ON.\n"));
977 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
983 /****************************************************************************
984 Ensure we eat the just processed pdu from the current_pdu prs_struct.
985 Normally the frag_len and buffer size will match, but on the first trans
986 reply there is a theoretical chance that buffer size > frag_len, so we must
988 ****************************************************************************/
990 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
992 uint32 current_pdu_len = prs_data_size(current_pdu);
994 if (current_pdu_len < prhdr->frag_len) {
995 return NT_STATUS_BUFFER_TOO_SMALL;
999 if (current_pdu_len == (uint32)prhdr->frag_len) {
1000 prs_mem_free(current_pdu);
1001 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1002 /* Make current_pdu dynamic with no memory. */
1003 prs_give_memory(current_pdu, 0, 0, True);
1004 return NT_STATUS_OK;
1008 * Oh no ! More data in buffer than we processed in current pdu.
1009 * Cheat. Move the data down and shrink the buffer.
1012 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1013 current_pdu_len - prhdr->frag_len);
1015 /* Remember to set the read offset back to zero. */
1016 prs_set_offset(current_pdu, 0);
1018 /* Shrink the buffer. */
1019 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1020 return NT_STATUS_BUFFER_TOO_SMALL;
1023 return NT_STATUS_OK;
1026 /****************************************************************************
1027 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1028 ****************************************************************************/
1030 struct cli_api_pipe_state {
1031 struct event_context *ev;
1032 struct rpc_cli_transport *transport;
1037 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1038 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1039 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1041 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1042 struct event_context *ev,
1043 struct rpc_cli_transport *transport,
1044 uint8_t *data, size_t data_len,
1045 uint32_t max_rdata_len)
1047 struct tevent_req *req, *subreq;
1048 struct cli_api_pipe_state *state;
1051 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1056 state->transport = transport;
1058 if (max_rdata_len < RPC_HEADER_LEN) {
1060 * For a RPC reply we always need at least RPC_HEADER_LEN
1061 * bytes. We check this here because we will receive
1062 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1064 status = NT_STATUS_INVALID_PARAMETER;
1068 if (transport->trans_send != NULL) {
1069 subreq = transport->trans_send(state, ev, data, data_len,
1070 max_rdata_len, transport->priv);
1071 if (subreq == NULL) {
1074 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1079 * If the transport does not provide a "trans" routine, i.e. for
1080 * example the ncacn_ip_tcp transport, do the write/read step here.
1083 subreq = rpc_write_send(state, ev, transport, data, data_len);
1084 if (subreq == NULL) {
1087 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1090 status = NT_STATUS_INVALID_PARAMETER;
1093 tevent_req_nterror(req, status);
1094 return tevent_req_post(req, ev);
1100 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1102 struct tevent_req *req = tevent_req_callback_data(
1103 subreq, struct tevent_req);
1104 struct cli_api_pipe_state *state = tevent_req_data(
1105 req, struct cli_api_pipe_state);
1108 status = state->transport->trans_recv(subreq, state, &state->rdata,
1110 TALLOC_FREE(subreq);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 tevent_req_nterror(req, status);
1115 tevent_req_done(req);
1118 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1120 struct tevent_req *req = tevent_req_callback_data(
1121 subreq, struct tevent_req);
1122 struct cli_api_pipe_state *state = tevent_req_data(
1123 req, struct cli_api_pipe_state);
1126 status = rpc_write_recv(subreq);
1127 TALLOC_FREE(subreq);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 tevent_req_nterror(req, status);
1133 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1134 if (tevent_req_nomem(state->rdata, req)) {
1139 * We don't need to use rpc_read_send here, the upper layer will cope
1140 * with a short read, transport->trans_send could also return less
1141 * than state->max_rdata_len.
1143 subreq = state->transport->read_send(state, state->ev, state->rdata,
1145 state->transport->priv);
1146 if (tevent_req_nomem(subreq, req)) {
1149 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1152 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1154 struct tevent_req *req = tevent_req_callback_data(
1155 subreq, struct tevent_req);
1156 struct cli_api_pipe_state *state = tevent_req_data(
1157 req, struct cli_api_pipe_state);
1161 status = state->transport->read_recv(subreq, &received);
1162 TALLOC_FREE(subreq);
1163 if (!NT_STATUS_IS_OK(status)) {
1164 tevent_req_nterror(req, status);
1167 state->rdata_len = received;
1168 tevent_req_done(req);
1171 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1172 uint8_t **prdata, uint32_t *prdata_len)
1174 struct cli_api_pipe_state *state = tevent_req_data(
1175 req, struct cli_api_pipe_state);
1178 if (tevent_req_is_nterror(req, &status)) {
1182 *prdata = talloc_move(mem_ctx, &state->rdata);
1183 *prdata_len = state->rdata_len;
1184 return NT_STATUS_OK;
1187 /****************************************************************************
1188 Send data on an rpc pipe via trans. The prs_struct data must be the last
1189 pdu fragment of an NDR data stream.
1191 Receive response data from an rpc pipe, which may be large...
1193 Read the first fragment: unfortunately have to use SMBtrans for the first
1194 bit, then SMBreadX for subsequent bits.
1196 If first fragment received also wasn't the last fragment, continue
1197 getting fragments until we _do_ receive the last fragment.
1199 Request/Response PDU's look like the following...
1201 |<------------------PDU len----------------------------------------------->|
1202 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1204 +------------+-----------------+-------------+---------------+-------------+
1205 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1206 +------------+-----------------+-------------+---------------+-------------+
1208 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1209 signing & sealing being negotiated.
1211 ****************************************************************************/
1213 struct rpc_api_pipe_state {
1214 struct event_context *ev;
1215 struct rpc_pipe_client *cli;
1216 uint8_t expected_pkt_type;
1218 prs_struct incoming_frag;
1219 struct rpc_hdr_info rhdr;
1221 prs_struct incoming_pdu; /* Incoming reply */
1222 uint32_t incoming_pdu_offset;
1225 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1227 prs_mem_free(&state->incoming_frag);
1228 prs_mem_free(&state->incoming_pdu);
1232 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1233 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1235 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1236 struct event_context *ev,
1237 struct rpc_pipe_client *cli,
1238 prs_struct *data, /* Outgoing PDU */
1239 uint8_t expected_pkt_type)
1241 struct tevent_req *req, *subreq;
1242 struct rpc_api_pipe_state *state;
1243 uint16_t max_recv_frag;
1246 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1252 state->expected_pkt_type = expected_pkt_type;
1253 state->incoming_pdu_offset = 0;
1255 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1257 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1258 /* Make incoming_pdu dynamic with no memory. */
1259 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1261 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1264 * Ensure we're not sending too much.
1266 if (prs_offset(data) > cli->max_xmit_frag) {
1267 status = NT_STATUS_INVALID_PARAMETER;
1271 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1273 max_recv_frag = cli->max_recv_frag;
1276 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1279 subreq = cli_api_pipe_send(state, ev, cli->transport,
1280 (uint8_t *)prs_data_p(data),
1281 prs_offset(data), max_recv_frag);
1282 if (subreq == NULL) {
1285 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1289 tevent_req_nterror(req, status);
1290 return tevent_req_post(req, ev);
1296 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1298 struct tevent_req *req = tevent_req_callback_data(
1299 subreq, struct tevent_req);
1300 struct rpc_api_pipe_state *state = tevent_req_data(
1301 req, struct rpc_api_pipe_state);
1303 uint8_t *rdata = NULL;
1304 uint32_t rdata_len = 0;
1307 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1308 TALLOC_FREE(subreq);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1311 tevent_req_nterror(req, status);
1315 if (rdata == NULL) {
1316 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1317 rpccli_pipe_txt(debug_ctx(), state->cli)));
1318 tevent_req_done(req);
1323 * Give the memory received from cli_trans as dynamic to the current
1324 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1327 rdata_copy = (char *)memdup(rdata, rdata_len);
1329 if (tevent_req_nomem(rdata_copy, req)) {
1332 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1334 /* Ensure we have enough data for a pdu. */
1335 subreq = get_complete_frag_send(state, state->ev, state->cli,
1336 &state->rhdr, &state->incoming_frag);
1337 if (tevent_req_nomem(subreq, req)) {
1340 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1343 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1345 struct tevent_req *req = tevent_req_callback_data(
1346 subreq, struct tevent_req);
1347 struct rpc_api_pipe_state *state = tevent_req_data(
1348 req, struct rpc_api_pipe_state);
1351 uint32_t rdata_len = 0;
1353 status = get_complete_frag_recv(subreq);
1354 TALLOC_FREE(subreq);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 DEBUG(5, ("get_complete_frag failed: %s\n",
1357 nt_errstr(status)));
1358 tevent_req_nterror(req, status);
1362 status = cli_pipe_validate_current_pdu(
1363 state->cli, &state->rhdr, &state->incoming_frag,
1364 state->expected_pkt_type, &rdata, &rdata_len,
1365 &state->incoming_pdu);
1367 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1368 (unsigned)prs_data_size(&state->incoming_frag),
1369 (unsigned)state->incoming_pdu_offset,
1370 nt_errstr(status)));
1372 if (!NT_STATUS_IS_OK(status)) {
1373 tevent_req_nterror(req, status);
1377 if ((state->rhdr.flags & RPC_FLG_FIRST)
1378 && (state->rhdr.pack_type[0] == 0)) {
1380 * Set the data type correctly for big-endian data on the
1383 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1385 rpccli_pipe_txt(debug_ctx(), state->cli)));
1386 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1389 * Check endianness on subsequent packets.
1391 if (state->incoming_frag.bigendian_data
1392 != state->incoming_pdu.bigendian_data) {
1393 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1395 state->incoming_pdu.bigendian_data?"big":"little",
1396 state->incoming_frag.bigendian_data?"big":"little"));
1397 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1401 /* Now copy the data portion out of the pdu into rbuf. */
1402 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1403 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1407 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1408 rdata, (size_t)rdata_len);
1409 state->incoming_pdu_offset += rdata_len;
1411 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1412 &state->incoming_frag);
1413 if (!NT_STATUS_IS_OK(status)) {
1414 tevent_req_nterror(req, status);
1418 if (state->rhdr.flags & RPC_FLG_LAST) {
1419 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1420 rpccli_pipe_txt(debug_ctx(), state->cli),
1421 (unsigned)prs_data_size(&state->incoming_pdu)));
1422 tevent_req_done(req);
1426 subreq = get_complete_frag_send(state, state->ev, state->cli,
1427 &state->rhdr, &state->incoming_frag);
1428 if (tevent_req_nomem(subreq, req)) {
1431 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1434 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1435 prs_struct *reply_pdu)
1437 struct rpc_api_pipe_state *state = tevent_req_data(
1438 req, struct rpc_api_pipe_state);
1441 if (tevent_req_is_nterror(req, &status)) {
1445 *reply_pdu = state->incoming_pdu;
1446 reply_pdu->mem_ctx = mem_ctx;
1449 * Prevent state->incoming_pdu from being freed in
1450 * rpc_api_pipe_state_destructor()
1452 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1454 return NT_STATUS_OK;
1457 /*******************************************************************
1458 Creates krb5 auth bind.
1459 ********************************************************************/
1461 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1462 enum pipe_auth_level auth_level,
1463 RPC_HDR_AUTH *pauth_out,
1464 prs_struct *auth_data)
1468 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1469 DATA_BLOB tkt = data_blob_null;
1470 DATA_BLOB tkt_wrapped = data_blob_null;
1472 /* We may change the pad length before marshalling. */
1473 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1475 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1476 a->service_principal ));
1478 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1480 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1481 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1484 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1486 a->service_principal,
1487 error_message(ret) ));
1489 data_blob_free(&tkt);
1490 prs_mem_free(auth_data);
1491 return NT_STATUS_INVALID_PARAMETER;
1494 /* wrap that up in a nice GSS-API wrapping */
1495 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1497 data_blob_free(&tkt);
1499 /* Auth len in the rpc header doesn't include auth_header. */
1500 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1501 data_blob_free(&tkt_wrapped);
1502 prs_mem_free(auth_data);
1503 return NT_STATUS_NO_MEMORY;
1506 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1507 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1509 data_blob_free(&tkt_wrapped);
1510 return NT_STATUS_OK;
1512 return NT_STATUS_INVALID_PARAMETER;
1516 /*******************************************************************
1517 Creates SPNEGO NTLMSSP auth bind.
1518 ********************************************************************/
1520 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1521 enum pipe_auth_level auth_level,
1522 RPC_HDR_AUTH *pauth_out,
1523 prs_struct *auth_data)
1526 DATA_BLOB null_blob = data_blob_null;
1527 DATA_BLOB request = data_blob_null;
1528 DATA_BLOB spnego_msg = data_blob_null;
1530 /* We may change the pad length before marshalling. */
1531 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1533 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1534 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1538 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1539 data_blob_free(&request);
1540 prs_mem_free(auth_data);
1544 /* Wrap this in SPNEGO. */
1545 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1547 data_blob_free(&request);
1549 /* Auth len in the rpc header doesn't include auth_header. */
1550 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1551 data_blob_free(&spnego_msg);
1552 prs_mem_free(auth_data);
1553 return NT_STATUS_NO_MEMORY;
1556 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1557 dump_data(5, spnego_msg.data, spnego_msg.length);
1559 data_blob_free(&spnego_msg);
1560 return NT_STATUS_OK;
1563 /*******************************************************************
1564 Creates NTLMSSP auth bind.
1565 ********************************************************************/
1567 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1568 enum pipe_auth_level auth_level,
1569 RPC_HDR_AUTH *pauth_out,
1570 prs_struct *auth_data)
1573 DATA_BLOB null_blob = data_blob_null;
1574 DATA_BLOB request = data_blob_null;
1576 /* We may change the pad length before marshalling. */
1577 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1579 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1580 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1584 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1585 data_blob_free(&request);
1586 prs_mem_free(auth_data);
1590 /* Auth len in the rpc header doesn't include auth_header. */
1591 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1592 data_blob_free(&request);
1593 prs_mem_free(auth_data);
1594 return NT_STATUS_NO_MEMORY;
1597 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1598 dump_data(5, request.data, request.length);
1600 data_blob_free(&request);
1601 return NT_STATUS_OK;
1604 /*******************************************************************
1605 Creates schannel auth bind.
1606 ********************************************************************/
1608 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1609 enum pipe_auth_level auth_level,
1610 RPC_HDR_AUTH *pauth_out,
1611 prs_struct *auth_data)
1613 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1615 /* We may change the pad length before marshalling. */
1616 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1618 /* Use lp_workgroup() if domain not specified */
1620 if (!cli->auth->domain || !cli->auth->domain[0]) {
1621 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1622 if (cli->auth->domain == NULL) {
1623 return NT_STATUS_NO_MEMORY;
1627 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1631 * Now marshall the data into the auth parse_struct.
1634 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1635 &schannel_neg, auth_data, 0)) {
1636 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1637 prs_mem_free(auth_data);
1638 return NT_STATUS_NO_MEMORY;
1641 return NT_STATUS_OK;
1644 /*******************************************************************
1645 Creates the internals of a DCE/RPC bind request or alter context PDU.
1646 ********************************************************************/
1648 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1649 prs_struct *rpc_out,
1651 const RPC_IFACE *abstract,
1652 const RPC_IFACE *transfer,
1653 RPC_HDR_AUTH *phdr_auth,
1654 prs_struct *pauth_info)
1658 RPC_CONTEXT rpc_ctx;
1659 uint16 auth_len = prs_offset(pauth_info);
1660 uint8 ss_padding_len = 0;
1661 uint16 frag_len = 0;
1663 /* create the RPC context. */
1664 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1666 /* create the bind request RPC_HDR_RB */
1667 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1669 /* Start building the frag length. */
1670 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1672 /* Do we need to pad ? */
1674 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1676 ss_padding_len = 8 - (data_len % 8);
1677 phdr_auth->auth_pad_len = ss_padding_len;
1679 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1682 /* Create the request RPC_HDR */
1683 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1685 /* Marshall the RPC header */
1686 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1687 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1688 return NT_STATUS_NO_MEMORY;
1691 /* Marshall the bind request data */
1692 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1693 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1694 return NT_STATUS_NO_MEMORY;
1698 * Grow the outgoing buffer to store any auth info.
1702 if (ss_padding_len) {
1704 memset(pad, '\0', 8);
1705 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1706 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1707 return NT_STATUS_NO_MEMORY;
1711 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1712 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1713 return NT_STATUS_NO_MEMORY;
1717 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1718 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1719 return NT_STATUS_NO_MEMORY;
1723 return NT_STATUS_OK;
1726 /*******************************************************************
1727 Creates a DCE/RPC bind request.
1728 ********************************************************************/
1730 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1731 prs_struct *rpc_out,
1733 const RPC_IFACE *abstract,
1734 const RPC_IFACE *transfer,
1735 enum pipe_auth_type auth_type,
1736 enum pipe_auth_level auth_level)
1738 RPC_HDR_AUTH hdr_auth;
1739 prs_struct auth_info;
1740 NTSTATUS ret = NT_STATUS_OK;
1742 ZERO_STRUCT(hdr_auth);
1743 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1744 return NT_STATUS_NO_MEMORY;
1746 switch (auth_type) {
1747 case PIPE_AUTH_TYPE_SCHANNEL:
1748 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1749 if (!NT_STATUS_IS_OK(ret)) {
1750 prs_mem_free(&auth_info);
1755 case PIPE_AUTH_TYPE_NTLMSSP:
1756 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1757 if (!NT_STATUS_IS_OK(ret)) {
1758 prs_mem_free(&auth_info);
1763 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1764 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1765 if (!NT_STATUS_IS_OK(ret)) {
1766 prs_mem_free(&auth_info);
1771 case PIPE_AUTH_TYPE_KRB5:
1772 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1773 if (!NT_STATUS_IS_OK(ret)) {
1774 prs_mem_free(&auth_info);
1779 case PIPE_AUTH_TYPE_NONE:
1783 /* "Can't" happen. */
1784 return NT_STATUS_INVALID_INFO_CLASS;
1787 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1795 prs_mem_free(&auth_info);
1799 /*******************************************************************
1800 Create and add the NTLMSSP sign/seal auth header and data.
1801 ********************************************************************/
1803 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1805 uint32 ss_padding_len,
1806 prs_struct *outgoing_pdu)
1808 RPC_HDR_AUTH auth_info;
1810 DATA_BLOB auth_blob = data_blob_null;
1811 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1813 if (!cli->auth->a_u.ntlmssp_state) {
1814 return NT_STATUS_INVALID_PARAMETER;
1817 /* Init and marshall the auth header. */
1818 init_rpc_hdr_auth(&auth_info,
1819 map_pipe_auth_type_to_rpc_auth_type(
1820 cli->auth->auth_type),
1821 cli->auth->auth_level,
1823 1 /* context id. */);
1825 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1826 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1827 data_blob_free(&auth_blob);
1828 return NT_STATUS_NO_MEMORY;
1831 switch (cli->auth->auth_level) {
1832 case PIPE_AUTH_LEVEL_PRIVACY:
1833 /* Data portion is encrypted. */
1834 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1835 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1837 (unsigned char *)prs_data_p(outgoing_pdu),
1838 (size_t)prs_offset(outgoing_pdu),
1840 if (!NT_STATUS_IS_OK(status)) {
1841 data_blob_free(&auth_blob);
1846 case PIPE_AUTH_LEVEL_INTEGRITY:
1847 /* Data is signed. */
1848 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1849 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1851 (unsigned char *)prs_data_p(outgoing_pdu),
1852 (size_t)prs_offset(outgoing_pdu),
1854 if (!NT_STATUS_IS_OK(status)) {
1855 data_blob_free(&auth_blob);
1862 smb_panic("bad auth level");
1864 return NT_STATUS_INVALID_PARAMETER;
1867 /* Finally marshall the blob. */
1869 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1870 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1871 (unsigned int)NTLMSSP_SIG_SIZE));
1872 data_blob_free(&auth_blob);
1873 return NT_STATUS_NO_MEMORY;
1876 data_blob_free(&auth_blob);
1877 return NT_STATUS_OK;
1880 /*******************************************************************
1881 Create and add the schannel sign/seal auth header and data.
1882 ********************************************************************/
1884 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1886 uint32 ss_padding_len,
1887 prs_struct *outgoing_pdu)
1889 RPC_HDR_AUTH auth_info;
1890 RPC_AUTH_SCHANNEL_CHK verf;
1891 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1892 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1893 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1896 return NT_STATUS_INVALID_PARAMETER;
1899 /* Init and marshall the auth header. */
1900 init_rpc_hdr_auth(&auth_info,
1901 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1902 cli->auth->auth_level,
1904 1 /* context id. */);
1906 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1907 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1908 return NT_STATUS_NO_MEMORY;
1911 switch (cli->auth->auth_level) {
1912 case PIPE_AUTH_LEVEL_PRIVACY:
1913 case PIPE_AUTH_LEVEL_INTEGRITY:
1914 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1917 schannel_encode(sas,
1918 cli->auth->auth_level,
1919 SENDER_IS_INITIATOR,
1929 smb_panic("bad auth level");
1931 return NT_STATUS_INVALID_PARAMETER;
1934 /* Finally marshall the blob. */
1935 smb_io_rpc_auth_schannel_chk("",
1936 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1941 return NT_STATUS_OK;
1944 /*******************************************************************
1945 Calculate how much data we're going to send in this packet, also
1946 work out any sign/seal padding length.
1947 ********************************************************************/
1949 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1953 uint32 *p_ss_padding)
1955 uint32 data_space, data_len;
1958 if ((data_left > 0) && (sys_random() % 2)) {
1959 data_left = MAX(data_left/2, 1);
1963 switch (cli->auth->auth_level) {
1964 case PIPE_AUTH_LEVEL_NONE:
1965 case PIPE_AUTH_LEVEL_CONNECT:
1966 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1967 data_len = MIN(data_space, data_left);
1970 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1973 case PIPE_AUTH_LEVEL_INTEGRITY:
1974 case PIPE_AUTH_LEVEL_PRIVACY:
1975 /* Treat the same for all authenticated rpc requests. */
1976 switch(cli->auth->auth_type) {
1977 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1978 case PIPE_AUTH_TYPE_NTLMSSP:
1979 *p_auth_len = NTLMSSP_SIG_SIZE;
1981 case PIPE_AUTH_TYPE_SCHANNEL:
1982 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1985 smb_panic("bad auth type");
1989 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1990 RPC_HDR_AUTH_LEN - *p_auth_len;
1992 data_len = MIN(data_space, data_left);
1995 *p_ss_padding = 8 - (data_len % 8);
1997 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1998 data_len + *p_ss_padding + /* data plus padding. */
1999 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2003 smb_panic("bad auth level");
2009 /*******************************************************************
2011 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2012 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2013 and deals with signing/sealing details.
2014 ********************************************************************/
2016 struct rpc_api_pipe_req_state {
2017 struct event_context *ev;
2018 struct rpc_pipe_client *cli;
2021 prs_struct *req_data;
2022 uint32_t req_data_sent;
2023 prs_struct outgoing_frag;
2024 prs_struct reply_pdu;
2027 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2029 prs_mem_free(&s->outgoing_frag);
2030 prs_mem_free(&s->reply_pdu);
2034 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2035 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2036 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2037 bool *is_last_frag);
2039 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2040 struct event_context *ev,
2041 struct rpc_pipe_client *cli,
2043 prs_struct *req_data)
2045 struct tevent_req *req, *subreq;
2046 struct rpc_api_pipe_req_state *state;
2050 req = tevent_req_create(mem_ctx, &state,
2051 struct rpc_api_pipe_req_state);
2057 state->op_num = op_num;
2058 state->req_data = req_data;
2059 state->req_data_sent = 0;
2060 state->call_id = get_rpc_call_id();
2062 if (cli->max_xmit_frag
2063 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2064 /* Server is screwed up ! */
2065 status = NT_STATUS_INVALID_PARAMETER;
2069 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2071 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2076 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2078 status = prepare_next_frag(state, &is_last_frag);
2079 if (!NT_STATUS_IS_OK(status)) {
2084 subreq = rpc_api_pipe_send(state, ev, state->cli,
2085 &state->outgoing_frag,
2087 if (subreq == NULL) {
2090 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2092 subreq = rpc_write_send(
2093 state, ev, cli->transport,
2094 (uint8_t *)prs_data_p(&state->outgoing_frag),
2095 prs_offset(&state->outgoing_frag));
2096 if (subreq == NULL) {
2099 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2105 tevent_req_nterror(req, status);
2106 return tevent_req_post(req, ev);
2112 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2116 RPC_HDR_REQ hdr_req;
2117 uint32_t data_sent_thistime;
2121 uint32_t ss_padding;
2123 char pad[8] = { 0, };
2126 data_left = prs_offset(state->req_data) - state->req_data_sent;
2128 data_sent_thistime = calculate_data_len_tosend(
2129 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2131 if (state->req_data_sent == 0) {
2132 flags = RPC_FLG_FIRST;
2135 if (data_sent_thistime == data_left) {
2136 flags |= RPC_FLG_LAST;
2139 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2140 return NT_STATUS_NO_MEMORY;
2143 /* Create and marshall the header and request header. */
2144 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2147 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2148 return NT_STATUS_NO_MEMORY;
2151 /* Create the rpc request RPC_HDR_REQ */
2152 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2155 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2156 &state->outgoing_frag, 0)) {
2157 return NT_STATUS_NO_MEMORY;
2160 /* Copy in the data, plus any ss padding. */
2161 if (!prs_append_some_prs_data(&state->outgoing_frag,
2162 state->req_data, state->req_data_sent,
2163 data_sent_thistime)) {
2164 return NT_STATUS_NO_MEMORY;
2167 /* Copy the sign/seal padding data. */
2168 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2169 return NT_STATUS_NO_MEMORY;
2172 /* Generate any auth sign/seal and add the auth footer. */
2173 switch (state->cli->auth->auth_type) {
2174 case PIPE_AUTH_TYPE_NONE:
2175 status = NT_STATUS_OK;
2177 case PIPE_AUTH_TYPE_NTLMSSP:
2178 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2179 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2180 &state->outgoing_frag);
2182 case PIPE_AUTH_TYPE_SCHANNEL:
2183 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2184 &state->outgoing_frag);
2187 status = NT_STATUS_INVALID_PARAMETER;
2191 state->req_data_sent += data_sent_thistime;
2192 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2197 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2199 struct tevent_req *req = tevent_req_callback_data(
2200 subreq, struct tevent_req);
2201 struct rpc_api_pipe_req_state *state = tevent_req_data(
2202 req, struct rpc_api_pipe_req_state);
2206 status = rpc_write_recv(subreq);
2207 TALLOC_FREE(subreq);
2208 if (!NT_STATUS_IS_OK(status)) {
2209 tevent_req_nterror(req, status);
2213 status = prepare_next_frag(state, &is_last_frag);
2214 if (!NT_STATUS_IS_OK(status)) {
2215 tevent_req_nterror(req, status);
2220 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2221 &state->outgoing_frag,
2223 if (tevent_req_nomem(subreq, req)) {
2226 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2228 subreq = rpc_write_send(
2230 state->cli->transport,
2231 (uint8_t *)prs_data_p(&state->outgoing_frag),
2232 prs_offset(&state->outgoing_frag));
2233 if (tevent_req_nomem(subreq, req)) {
2236 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2241 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2243 struct tevent_req *req = tevent_req_callback_data(
2244 subreq, struct tevent_req);
2245 struct rpc_api_pipe_req_state *state = tevent_req_data(
2246 req, struct rpc_api_pipe_req_state);
2249 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2250 TALLOC_FREE(subreq);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 tevent_req_nterror(req, status);
2255 tevent_req_done(req);
2258 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2259 prs_struct *reply_pdu)
2261 struct rpc_api_pipe_req_state *state = tevent_req_data(
2262 req, struct rpc_api_pipe_req_state);
2265 if (tevent_req_is_nterror(req, &status)) {
2267 * We always have to initialize to reply pdu, even if there is
2268 * none. The rpccli_* caller routines expect this.
2270 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2274 *reply_pdu = state->reply_pdu;
2275 reply_pdu->mem_ctx = mem_ctx;
2278 * Prevent state->req_pdu from being freed in
2279 * rpc_api_pipe_req_state_destructor()
2281 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2283 return NT_STATUS_OK;
2286 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
2288 prs_struct *in_data,
2289 prs_struct *out_data)
2291 TALLOC_CTX *frame = talloc_stackframe();
2292 struct event_context *ev;
2293 struct tevent_req *req;
2294 NTSTATUS status = NT_STATUS_OK;
2296 ev = event_context_init(frame);
2298 status = NT_STATUS_NO_MEMORY;
2302 req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
2304 status = NT_STATUS_NO_MEMORY;
2308 if (!tevent_req_poll(req, ev)) {
2309 status = map_nt_error_from_unix(errno);
2313 status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
2320 /****************************************************************************
2321 Set the handle state.
2322 ****************************************************************************/
2324 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2325 const char *pipe_name, uint16 device_state)
2327 bool state_set = False;
2329 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2330 char *rparam = NULL;
2332 uint32 rparam_len, rdata_len;
2334 if (pipe_name == NULL)
2337 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2338 cli->fnum, pipe_name, device_state));
2340 /* create parameters: device state */
2341 SSVAL(param, 0, device_state);
2343 /* create setup parameters. */
2345 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2347 /* send the data on \PIPE\ */
2348 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2349 setup, 2, 0, /* setup, length, max */
2350 param, 2, 0, /* param, length, max */
2351 NULL, 0, 1024, /* data, length, max */
2352 &rparam, &rparam_len, /* return param, length */
2353 &rdata, &rdata_len)) /* return data, length */
2355 DEBUG(5, ("Set Handle state: return OK\n"));
2366 /****************************************************************************
2367 Check the rpc bind acknowledge response.
2368 ****************************************************************************/
2370 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2372 if ( hdr_ba->addr.len == 0) {
2373 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2376 /* check the transfer syntax */
2377 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2378 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2379 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2383 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2384 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2385 hdr_ba->res.num_results, hdr_ba->res.reason));
2388 DEBUG(5,("check_bind_response: accepted!\n"));
2392 /*******************************************************************
2393 Creates a DCE/RPC bind authentication response.
2394 This is the packet that is sent back to the server once we
2395 have received a BIND-ACK, to finish the third leg of
2396 the authentication handshake.
2397 ********************************************************************/
2399 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2401 enum pipe_auth_type auth_type,
2402 enum pipe_auth_level auth_level,
2403 DATA_BLOB *pauth_blob,
2404 prs_struct *rpc_out)
2407 RPC_HDR_AUTH hdr_auth;
2410 /* Create the request RPC_HDR */
2411 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2412 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2413 pauth_blob->length );
2416 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2417 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2418 return NT_STATUS_NO_MEMORY;
2422 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2423 about padding - shouldn't this pad to length 8 ? JRA.
2426 /* 4 bytes padding. */
2427 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2428 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2429 return NT_STATUS_NO_MEMORY;
2432 /* Create the request RPC_HDR_AUTHA */
2433 init_rpc_hdr_auth(&hdr_auth,
2434 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2437 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2438 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2439 return NT_STATUS_NO_MEMORY;
2443 * Append the auth data to the outgoing buffer.
2446 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2447 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2448 return NT_STATUS_NO_MEMORY;
2451 return NT_STATUS_OK;
2454 /*******************************************************************
2455 Creates a DCE/RPC bind alter context authentication request which
2456 may contain a spnego auth blobl
2457 ********************************************************************/
2459 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2460 const RPC_IFACE *abstract,
2461 const RPC_IFACE *transfer,
2462 enum pipe_auth_level auth_level,
2463 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2464 prs_struct *rpc_out)
2466 RPC_HDR_AUTH hdr_auth;
2467 prs_struct auth_info;
2468 NTSTATUS ret = NT_STATUS_OK;
2470 ZERO_STRUCT(hdr_auth);
2471 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2472 return NT_STATUS_NO_MEMORY;
2474 /* We may change the pad length before marshalling. */
2475 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2477 if (pauth_blob->length) {
2478 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2479 prs_mem_free(&auth_info);
2480 return NT_STATUS_NO_MEMORY;
2484 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2491 prs_mem_free(&auth_info);
2495 /****************************************************************************
2497 ****************************************************************************/
2499 struct rpc_pipe_bind_state {
2500 struct event_context *ev;
2501 struct rpc_pipe_client *cli;
2503 uint32_t rpc_call_id;
2506 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2508 prs_mem_free(&state->rpc_out);
2512 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2513 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2514 struct rpc_pipe_bind_state *state,
2515 struct rpc_hdr_info *phdr,
2516 prs_struct *reply_pdu);
2517 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2518 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2519 struct rpc_pipe_bind_state *state,
2520 struct rpc_hdr_info *phdr,
2521 prs_struct *reply_pdu);
2522 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2524 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2525 struct event_context *ev,
2526 struct rpc_pipe_client *cli,
2527 struct cli_pipe_auth_data *auth)
2529 struct tevent_req *req, *subreq;
2530 struct rpc_pipe_bind_state *state;
2533 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2538 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2539 rpccli_pipe_txt(debug_ctx(), cli),
2540 (unsigned int)auth->auth_type,
2541 (unsigned int)auth->auth_level ));
2545 state->rpc_call_id = get_rpc_call_id();
2547 prs_init_empty(&state->rpc_out, state, MARSHALL);
2548 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2550 cli->auth = talloc_move(cli, &auth);
2552 /* Marshall the outgoing data. */
2553 status = create_rpc_bind_req(cli, &state->rpc_out,
2555 &cli->abstract_syntax,
2556 &cli->transfer_syntax,
2557 cli->auth->auth_type,
2558 cli->auth->auth_level);
2560 if (!NT_STATUS_IS_OK(status)) {
2564 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2566 if (subreq == NULL) {
2569 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2573 tevent_req_nterror(req, status);
2574 return tevent_req_post(req, ev);
2580 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2582 struct tevent_req *req = tevent_req_callback_data(
2583 subreq, struct tevent_req);
2584 struct rpc_pipe_bind_state *state = tevent_req_data(
2585 req, struct rpc_pipe_bind_state);
2586 prs_struct reply_pdu;
2587 struct rpc_hdr_info hdr;
2588 struct rpc_hdr_ba_info hdr_ba;
2591 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2592 TALLOC_FREE(subreq);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2595 rpccli_pipe_txt(debug_ctx(), state->cli),
2596 nt_errstr(status)));
2597 tevent_req_nterror(req, status);
2601 /* Unmarshall the RPC header */
2602 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2603 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2604 prs_mem_free(&reply_pdu);
2605 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2609 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2610 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2612 prs_mem_free(&reply_pdu);
2613 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2617 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2618 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2619 prs_mem_free(&reply_pdu);
2620 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2624 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2625 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2628 * For authenticated binds we may need to do 3 or 4 leg binds.
2631 switch(state->cli->auth->auth_type) {
2633 case PIPE_AUTH_TYPE_NONE:
2634 case PIPE_AUTH_TYPE_SCHANNEL:
2635 /* Bind complete. */
2636 prs_mem_free(&reply_pdu);
2637 tevent_req_done(req);
2640 case PIPE_AUTH_TYPE_NTLMSSP:
2641 /* Need to send AUTH3 packet - no reply. */
2642 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2644 prs_mem_free(&reply_pdu);
2645 if (!NT_STATUS_IS_OK(status)) {
2646 tevent_req_nterror(req, status);
2650 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2651 /* Need to send alter context request and reply. */
2652 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2654 prs_mem_free(&reply_pdu);
2655 if (!NT_STATUS_IS_OK(status)) {
2656 tevent_req_nterror(req, status);
2660 case PIPE_AUTH_TYPE_KRB5:
2664 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2665 (unsigned int)state->cli->auth->auth_type));
2666 prs_mem_free(&reply_pdu);
2667 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2671 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2672 struct rpc_pipe_bind_state *state,
2673 struct rpc_hdr_info *phdr,
2674 prs_struct *reply_pdu)
2676 DATA_BLOB server_response = data_blob_null;
2677 DATA_BLOB client_reply = data_blob_null;
2678 struct rpc_hdr_auth_info hdr_auth;
2679 struct tevent_req *subreq;
2682 if ((phdr->auth_len == 0)
2683 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2684 return NT_STATUS_INVALID_PARAMETER;
2687 if (!prs_set_offset(
2689 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2690 return NT_STATUS_INVALID_PARAMETER;
2693 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2694 return NT_STATUS_INVALID_PARAMETER;
2697 /* TODO - check auth_type/auth_level match. */
2699 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2700 prs_copy_data_out((char *)server_response.data, reply_pdu,
2703 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2704 server_response, &client_reply);
2706 if (!NT_STATUS_IS_OK(status)) {
2707 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2708 "blob failed: %s.\n", nt_errstr(status)));
2712 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2714 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2715 state->cli->auth->auth_type,
2716 state->cli->auth->auth_level,
2717 &client_reply, &state->rpc_out);
2718 data_blob_free(&client_reply);
2720 if (!NT_STATUS_IS_OK(status)) {
2724 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2725 (uint8_t *)prs_data_p(&state->rpc_out),
2726 prs_offset(&state->rpc_out));
2727 if (subreq == NULL) {
2728 return NT_STATUS_NO_MEMORY;
2730 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2731 return NT_STATUS_OK;
2734 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2736 struct tevent_req *req = tevent_req_callback_data(
2737 subreq, struct tevent_req);
2740 status = rpc_write_recv(subreq);
2741 TALLOC_FREE(subreq);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 tevent_req_nterror(req, status);
2746 tevent_req_done(req);
2749 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2750 struct rpc_pipe_bind_state *state,
2751 struct rpc_hdr_info *phdr,
2752 prs_struct *reply_pdu)
2754 DATA_BLOB server_spnego_response = data_blob_null;
2755 DATA_BLOB server_ntlm_response = data_blob_null;
2756 DATA_BLOB client_reply = data_blob_null;
2757 DATA_BLOB tmp_blob = data_blob_null;
2758 RPC_HDR_AUTH hdr_auth;
2759 struct tevent_req *subreq;
2762 if ((phdr->auth_len == 0)
2763 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2764 return NT_STATUS_INVALID_PARAMETER;
2767 /* Process the returned NTLMSSP blob first. */
2768 if (!prs_set_offset(
2770 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2771 return NT_STATUS_INVALID_PARAMETER;
2774 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2775 return NT_STATUS_INVALID_PARAMETER;
2778 server_spnego_response = data_blob(NULL, phdr->auth_len);
2779 prs_copy_data_out((char *)server_spnego_response.data,
2780 reply_pdu, phdr->auth_len);
2783 * The server might give us back two challenges - tmp_blob is for the
2786 if (!spnego_parse_challenge(server_spnego_response,
2787 &server_ntlm_response, &tmp_blob)) {
2788 data_blob_free(&server_spnego_response);
2789 data_blob_free(&server_ntlm_response);
2790 data_blob_free(&tmp_blob);
2791 return NT_STATUS_INVALID_PARAMETER;
2794 /* We're finished with the server spnego response and the tmp_blob. */
2795 data_blob_free(&server_spnego_response);
2796 data_blob_free(&tmp_blob);
2798 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2799 server_ntlm_response, &client_reply);
2801 /* Finished with the server_ntlm response */
2802 data_blob_free(&server_ntlm_response);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2806 "using server blob failed.\n"));
2807 data_blob_free(&client_reply);
2811 /* SPNEGO wrap the client reply. */
2812 tmp_blob = spnego_gen_auth(client_reply);
2813 data_blob_free(&client_reply);
2814 client_reply = tmp_blob;
2815 tmp_blob = data_blob_null;
2817 /* Now prepare the alter context pdu. */
2818 prs_init_empty(&state->rpc_out, state, MARSHALL);
2820 status = create_rpc_alter_context(state->rpc_call_id,
2821 &state->cli->abstract_syntax,
2822 &state->cli->transfer_syntax,
2823 state->cli->auth->auth_level,
2826 data_blob_free(&client_reply);
2828 if (!NT_STATUS_IS_OK(status)) {
2832 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2833 &state->rpc_out, RPC_ALTCONTRESP);
2834 if (subreq == NULL) {
2835 return NT_STATUS_NO_MEMORY;
2837 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2838 return NT_STATUS_OK;
2841 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2843 struct tevent_req *req = tevent_req_callback_data(
2844 subreq, struct tevent_req);
2845 struct rpc_pipe_bind_state *state = tevent_req_data(
2846 req, struct rpc_pipe_bind_state);
2847 DATA_BLOB server_spnego_response = data_blob_null;
2848 DATA_BLOB tmp_blob = data_blob_null;
2849 prs_struct reply_pdu;
2850 struct rpc_hdr_info hdr;
2851 struct rpc_hdr_auth_info hdr_auth;
2854 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2855 TALLOC_FREE(subreq);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 tevent_req_nterror(req, status);
2861 /* Get the auth blob from the reply. */
2862 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2863 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2864 "unmarshall RPC_HDR.\n"));
2865 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2869 if (!prs_set_offset(
2871 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2872 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2876 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2877 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2881 server_spnego_response = data_blob(NULL, hdr.auth_len);
2882 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2885 /* Check we got a valid auth response. */
2886 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2887 OID_NTLMSSP, &tmp_blob)) {
2888 data_blob_free(&server_spnego_response);
2889 data_blob_free(&tmp_blob);
2890 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2894 data_blob_free(&server_spnego_response);
2895 data_blob_free(&tmp_blob);
2897 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2898 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2899 tevent_req_done(req);
2902 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2904 return tevent_req_simple_recv_ntstatus(req);
2907 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2908 struct cli_pipe_auth_data *auth)
2910 TALLOC_CTX *frame = talloc_stackframe();
2911 struct event_context *ev;
2912 struct tevent_req *req;
2913 NTSTATUS status = NT_STATUS_OK;
2915 ev = event_context_init(frame);
2917 status = NT_STATUS_NO_MEMORY;
2921 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2923 status = NT_STATUS_NO_MEMORY;
2927 if (!tevent_req_poll(req, ev)) {
2928 status = map_nt_error_from_unix(errno);
2932 status = rpc_pipe_bind_recv(req);
2938 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2939 unsigned int timeout)
2941 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2946 return cli_set_timeout(cli, timeout);
2949 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2951 struct cli_state *cli;
2953 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2954 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2955 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2959 cli = rpc_pipe_np_smb_conn(rpc_cli);
2963 E_md4hash(cli->password ? cli->password : "", nt_hash);
2967 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2968 struct cli_pipe_auth_data **presult)
2970 struct cli_pipe_auth_data *result;
2972 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2973 if (result == NULL) {
2974 return NT_STATUS_NO_MEMORY;
2977 result->auth_type = PIPE_AUTH_TYPE_NONE;
2978 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2980 result->user_name = talloc_strdup(result, "");
2981 result->domain = talloc_strdup(result, "");
2982 if ((result->user_name == NULL) || (result->domain == NULL)) {
2983 TALLOC_FREE(result);
2984 return NT_STATUS_NO_MEMORY;
2988 return NT_STATUS_OK;
2991 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2993 ntlmssp_end(&auth->a_u.ntlmssp_state);
2997 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2998 enum pipe_auth_type auth_type,
2999 enum pipe_auth_level auth_level,
3001 const char *username,
3002 const char *password,
3003 struct cli_pipe_auth_data **presult)
3005 struct cli_pipe_auth_data *result;
3008 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3009 if (result == NULL) {
3010 return NT_STATUS_NO_MEMORY;
3013 result->auth_type = auth_type;
3014 result->auth_level = auth_level;
3016 result->user_name = talloc_strdup(result, username);
3017 result->domain = talloc_strdup(result, domain);
3018 if ((result->user_name == NULL) || (result->domain == NULL)) {
3019 status = NT_STATUS_NO_MEMORY;
3023 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3024 if (!NT_STATUS_IS_OK(status)) {
3028 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3030 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3031 if (!NT_STATUS_IS_OK(status)) {
3035 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3036 if (!NT_STATUS_IS_OK(status)) {
3040 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3041 if (!NT_STATUS_IS_OK(status)) {
3046 * Turn off sign+seal to allow selected auth level to turn it back on.
3048 result->a_u.ntlmssp_state->neg_flags &=
3049 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3051 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
3052 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3053 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
3054 result->a_u.ntlmssp_state->neg_flags
3055 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3059 return NT_STATUS_OK;
3062 TALLOC_FREE(result);
3066 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3067 enum pipe_auth_level auth_level,
3068 const uint8_t sess_key[16],
3069 struct cli_pipe_auth_data **presult)
3071 struct cli_pipe_auth_data *result;
3073 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3074 if (result == NULL) {
3075 return NT_STATUS_NO_MEMORY;
3078 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3079 result->auth_level = auth_level;
3081 result->user_name = talloc_strdup(result, "");
3082 result->domain = talloc_strdup(result, domain);
3083 if ((result->user_name == NULL) || (result->domain == NULL)) {
3087 result->a_u.schannel_auth = talloc(result,
3088 struct schannel_auth_struct);
3089 if (result->a_u.schannel_auth == NULL) {
3093 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3094 sizeof(result->a_u.schannel_auth->sess_key));
3095 result->a_u.schannel_auth->seq_num = 0;
3098 return NT_STATUS_OK;
3101 TALLOC_FREE(result);
3102 return NT_STATUS_NO_MEMORY;
3106 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3108 data_blob_free(&auth->session_key);
3113 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3114 enum pipe_auth_level auth_level,
3115 const char *service_princ,
3116 const char *username,
3117 const char *password,
3118 struct cli_pipe_auth_data **presult)
3121 struct cli_pipe_auth_data *result;
3123 if ((username != NULL) && (password != NULL)) {
3124 int ret = kerberos_kinit_password(username, password, 0, NULL);
3126 return NT_STATUS_ACCESS_DENIED;
3130 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3131 if (result == NULL) {
3132 return NT_STATUS_NO_MEMORY;
3135 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3136 result->auth_level = auth_level;
3139 * Username / domain need fixing!
3141 result->user_name = talloc_strdup(result, "");
3142 result->domain = talloc_strdup(result, "");
3143 if ((result->user_name == NULL) || (result->domain == NULL)) {
3147 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3148 result, struct kerberos_auth_struct);
3149 if (result->a_u.kerberos_auth == NULL) {
3152 talloc_set_destructor(result->a_u.kerberos_auth,
3153 cli_auth_kerberos_data_destructor);
3155 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3156 result, service_princ);
3157 if (result->a_u.kerberos_auth->service_principal == NULL) {
3162 return NT_STATUS_OK;
3165 TALLOC_FREE(result);
3166 return NT_STATUS_NO_MEMORY;
3168 return NT_STATUS_NOT_SUPPORTED;
3173 * Create an rpc pipe client struct, connecting to a tcp port.
3175 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3177 const struct ndr_syntax_id *abstract_syntax,
3178 struct rpc_pipe_client **presult)
3180 struct rpc_pipe_client *result;
3181 struct sockaddr_storage addr;
3185 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3186 if (result == NULL) {
3187 return NT_STATUS_NO_MEMORY;
3190 result->abstract_syntax = *abstract_syntax;
3191 result->transfer_syntax = ndr_transfer_syntax;
3192 result->dispatch = cli_do_rpc_ndr;
3194 result->desthost = talloc_strdup(result, host);
3195 result->srv_name_slash = talloc_asprintf_strupper_m(
3196 result, "\\\\%s", result->desthost);
3197 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3198 status = NT_STATUS_NO_MEMORY;
3202 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3203 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3205 if (!resolve_name(host, &addr, 0)) {
3206 status = NT_STATUS_NOT_FOUND;
3210 status = open_socket_out(&addr, port, 60, &fd);
3211 if (!NT_STATUS_IS_OK(status)) {
3214 set_socket_options(fd, lp_socket_options());
3216 status = rpc_transport_sock_init(result, fd, &result->transport);
3217 if (!NT_STATUS_IS_OK(status)) {
3223 return NT_STATUS_OK;
3226 TALLOC_FREE(result);
3231 * Determine the tcp port on which a dcerpc interface is listening
3232 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3235 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3236 const struct ndr_syntax_id *abstract_syntax,
3240 struct rpc_pipe_client *epm_pipe = NULL;
3241 struct cli_pipe_auth_data *auth = NULL;
3242 struct dcerpc_binding *map_binding = NULL;
3243 struct dcerpc_binding *res_binding = NULL;
3244 struct epm_twr_t *map_tower = NULL;
3245 struct epm_twr_t *res_towers = NULL;
3246 struct policy_handle *entry_handle = NULL;
3247 uint32_t num_towers = 0;
3248 uint32_t max_towers = 1;
3249 struct epm_twr_p_t towers;
3250 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3252 if (pport == NULL) {
3253 status = NT_STATUS_INVALID_PARAMETER;
3257 /* open the connection to the endpoint mapper */
3258 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3259 &ndr_table_epmapper.syntax_id,
3262 if (!NT_STATUS_IS_OK(status)) {
3266 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3267 if (!NT_STATUS_IS_OK(status)) {
3271 status = rpc_pipe_bind(epm_pipe, auth);
3272 if (!NT_STATUS_IS_OK(status)) {
3276 /* create tower for asking the epmapper */
3278 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3279 if (map_binding == NULL) {
3280 status = NT_STATUS_NO_MEMORY;
3284 map_binding->transport = NCACN_IP_TCP;
3285 map_binding->object = *abstract_syntax;
3286 map_binding->host = host; /* needed? */
3287 map_binding->endpoint = "0"; /* correct? needed? */
3289 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3290 if (map_tower == NULL) {
3291 status = NT_STATUS_NO_MEMORY;
3295 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3296 &(map_tower->tower));
3297 if (!NT_STATUS_IS_OK(status)) {
3301 /* allocate further parameters for the epm_Map call */
3303 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3304 if (res_towers == NULL) {
3305 status = NT_STATUS_NO_MEMORY;
3308 towers.twr = res_towers;
3310 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3311 if (entry_handle == NULL) {
3312 status = NT_STATUS_NO_MEMORY;
3316 /* ask the endpoint mapper for the port */
3318 status = rpccli_epm_Map(epm_pipe,
3320 CONST_DISCARD(struct GUID *,
3321 &(abstract_syntax->uuid)),
3328 if (!NT_STATUS_IS_OK(status)) {
3332 if (num_towers != 1) {
3333 status = NT_STATUS_UNSUCCESSFUL;
3337 /* extract the port from the answer */
3339 status = dcerpc_binding_from_tower(tmp_ctx,
3340 &(towers.twr->tower),
3342 if (!NT_STATUS_IS_OK(status)) {
3346 /* are further checks here necessary? */
3347 if (res_binding->transport != NCACN_IP_TCP) {
3348 status = NT_STATUS_UNSUCCESSFUL;
3352 *pport = (uint16_t)atoi(res_binding->endpoint);
3355 TALLOC_FREE(tmp_ctx);
3360 * Create a rpc pipe client struct, connecting to a host via tcp.
3361 * The port is determined by asking the endpoint mapper on the given
3364 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3365 const struct ndr_syntax_id *abstract_syntax,
3366 struct rpc_pipe_client **presult)
3373 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3374 if (!NT_STATUS_IS_OK(status)) {
3378 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3379 abstract_syntax, presult);
3385 /********************************************************************
3386 Create a rpc pipe client struct, connecting to a unix domain socket
3387 ********************************************************************/
3388 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3389 const struct ndr_syntax_id *abstract_syntax,
3390 struct rpc_pipe_client **presult)
3392 struct rpc_pipe_client *result;
3393 struct sockaddr_un addr;
3397 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3398 if (result == NULL) {
3399 return NT_STATUS_NO_MEMORY;
3402 result->abstract_syntax = *abstract_syntax;
3403 result->transfer_syntax = ndr_transfer_syntax;
3404 result->dispatch = cli_do_rpc_ndr;
3406 result->desthost = get_myname(result);
3407 result->srv_name_slash = talloc_asprintf_strupper_m(
3408 result, "\\\\%s", result->desthost);
3409 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3410 status = NT_STATUS_NO_MEMORY;
3414 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3415 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3417 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3419 status = map_nt_error_from_unix(errno);
3424 addr.sun_family = AF_UNIX;
3425 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3427 if (sys_connect(fd, (struct sockaddr *)&addr) == -1) {
3428 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3431 return map_nt_error_from_unix(errno);
3434 status = rpc_transport_sock_init(result, fd, &result->transport);
3435 if (!NT_STATUS_IS_OK(status)) {
3441 return NT_STATUS_OK;
3444 TALLOC_FREE(result);
3448 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3450 struct cli_state *cli;
3452 cli = rpc_pipe_np_smb_conn(p);
3454 DLIST_REMOVE(cli->pipe_list, p);
3459 /****************************************************************************
3460 Open a named pipe over SMB to a remote server.
3462 * CAVEAT CALLER OF THIS FUNCTION:
3463 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3464 * so be sure that this function is called AFTER any structure (vs pointer)
3465 * assignment of the cli. In particular, libsmbclient does structure
3466 * assignments of cli, which invalidates the data in the returned
3467 * rpc_pipe_client if this function is called before the structure assignment
3470 ****************************************************************************/
3472 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3473 const struct ndr_syntax_id *abstract_syntax,
3474 struct rpc_pipe_client **presult)
3476 struct rpc_pipe_client *result;
3479 /* sanity check to protect against crashes */
3482 return NT_STATUS_INVALID_HANDLE;
3485 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3486 if (result == NULL) {
3487 return NT_STATUS_NO_MEMORY;
3490 result->abstract_syntax = *abstract_syntax;
3491 result->transfer_syntax = ndr_transfer_syntax;
3492 result->dispatch = cli_do_rpc_ndr;
3493 result->desthost = talloc_strdup(result, cli->desthost);
3494 result->srv_name_slash = talloc_asprintf_strupper_m(
3495 result, "\\\\%s", result->desthost);
3497 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3498 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3500 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3501 TALLOC_FREE(result);
3502 return NT_STATUS_NO_MEMORY;
3505 status = rpc_transport_np_init(result, cli, abstract_syntax,
3506 &result->transport);
3507 if (!NT_STATUS_IS_OK(status)) {
3508 TALLOC_FREE(result);
3512 DLIST_ADD(cli->pipe_list, result);
3513 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3516 return NT_STATUS_OK;
3519 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3520 struct rpc_cli_smbd_conn *conn,
3521 const struct ndr_syntax_id *syntax,
3522 struct rpc_pipe_client **presult)
3524 struct rpc_pipe_client *result;
3525 struct cli_pipe_auth_data *auth;
3528 result = talloc(mem_ctx, struct rpc_pipe_client);
3529 if (result == NULL) {
3530 return NT_STATUS_NO_MEMORY;
3532 result->abstract_syntax = *syntax;
3533 result->transfer_syntax = ndr_transfer_syntax;
3534 result->dispatch = cli_do_rpc_ndr;
3535 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3536 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3538 result->desthost = talloc_strdup(result, global_myname());
3539 result->srv_name_slash = talloc_asprintf_strupper_m(
3540 result, "\\\\%s", global_myname());
3541 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3542 TALLOC_FREE(result);
3543 return NT_STATUS_NO_MEMORY;
3546 status = rpc_transport_smbd_init(result, conn, syntax,
3547 &result->transport);
3548 if (!NT_STATUS_IS_OK(status)) {
3549 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3550 nt_errstr(status)));
3551 TALLOC_FREE(result);
3555 status = rpccli_anon_bind_data(result, &auth);
3556 if (!NT_STATUS_IS_OK(status)) {
3557 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3558 nt_errstr(status)));
3559 TALLOC_FREE(result);
3563 status = rpc_pipe_bind(result, auth);
3564 if (!NT_STATUS_IS_OK(status)) {
3565 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3566 TALLOC_FREE(result);
3571 return NT_STATUS_OK;
3574 /****************************************************************************
3575 Open a pipe to a remote server.
3576 ****************************************************************************/
3578 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3579 const struct ndr_syntax_id *interface,
3580 struct rpc_pipe_client **presult)
3582 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3584 * We should have a better way to figure out this drsuapi
3587 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3591 return rpc_pipe_open_np(cli, interface, presult);
3594 /****************************************************************************
3595 Open a named pipe to an SMB server and bind anonymously.
3596 ****************************************************************************/
3598 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3599 const struct ndr_syntax_id *interface,
3600 struct rpc_pipe_client **presult)
3602 struct rpc_pipe_client *result;
3603 struct cli_pipe_auth_data *auth;
3606 status = cli_rpc_pipe_open(cli, interface, &result);
3607 if (!NT_STATUS_IS_OK(status)) {
3611 status = rpccli_anon_bind_data(result, &auth);
3612 if (!NT_STATUS_IS_OK(status)) {
3613 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3614 nt_errstr(status)));
3615 TALLOC_FREE(result);
3620 * This is a bit of an abstraction violation due to the fact that an
3621 * anonymous bind on an authenticated SMB inherits the user/domain
3622 * from the enclosing SMB creds
3625 TALLOC_FREE(auth->user_name);
3626 TALLOC_FREE(auth->domain);
3628 auth->user_name = talloc_strdup(auth, cli->user_name);
3629 auth->domain = talloc_strdup(auth, cli->domain);
3630 auth->user_session_key = data_blob_talloc(auth,
3631 cli->user_session_key.data,
3632 cli->user_session_key.length);
3634 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3635 TALLOC_FREE(result);
3636 return NT_STATUS_NO_MEMORY;
3639 status = rpc_pipe_bind(result, auth);
3640 if (!NT_STATUS_IS_OK(status)) {
3642 if (ndr_syntax_id_equal(interface,
3643 &ndr_table_dssetup.syntax_id)) {
3644 /* non AD domains just don't have this pipe, avoid
3645 * level 0 statement in that case - gd */
3648 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3649 "%s failed with error %s\n",
3650 get_pipe_name_from_iface(interface),
3651 nt_errstr(status) ));
3652 TALLOC_FREE(result);
3656 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3657 "%s and bound anonymously.\n",
3658 get_pipe_name_from_iface(interface), cli->desthost));
3661 return NT_STATUS_OK;
3664 /****************************************************************************
3665 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3666 ****************************************************************************/
3668 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3669 const struct ndr_syntax_id *interface,
3670 enum pipe_auth_type auth_type,
3671 enum pipe_auth_level auth_level,
3673 const char *username,
3674 const char *password,
3675 struct rpc_pipe_client **presult)
3677 struct rpc_pipe_client *result;
3678 struct cli_pipe_auth_data *auth;
3681 status = cli_rpc_pipe_open(cli, interface, &result);
3682 if (!NT_STATUS_IS_OK(status)) {
3686 status = rpccli_ntlmssp_bind_data(
3687 result, auth_type, auth_level, domain, username,
3689 if (!NT_STATUS_IS_OK(status)) {
3690 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3691 nt_errstr(status)));
3695 status = rpc_pipe_bind(result, auth);
3696 if (!NT_STATUS_IS_OK(status)) {
3697 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3698 nt_errstr(status) ));
3702 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3703 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3704 get_pipe_name_from_iface(interface), cli->desthost, domain,
3708 return NT_STATUS_OK;
3712 TALLOC_FREE(result);
3716 /****************************************************************************
3718 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3719 ****************************************************************************/
3721 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3722 const struct ndr_syntax_id *interface,
3723 enum pipe_auth_level auth_level,
3725 const char *username,
3726 const char *password,
3727 struct rpc_pipe_client **presult)
3729 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3731 PIPE_AUTH_TYPE_NTLMSSP,
3739 /****************************************************************************
3741 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3742 ****************************************************************************/
3744 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3745 const struct ndr_syntax_id *interface,
3746 enum pipe_auth_level auth_level,
3748 const char *username,
3749 const char *password,
3750 struct rpc_pipe_client **presult)
3752 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3754 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3762 /****************************************************************************
3763 Get a the schannel session key out of an already opened netlogon pipe.
3764 ****************************************************************************/
3765 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3766 struct cli_state *cli,
3770 uint32 sec_chan_type = 0;
3771 unsigned char machine_pwd[16];
3772 const char *machine_account;
3775 /* Get the machine account credentials from secrets.tdb. */
3776 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3779 DEBUG(0, ("get_schannel_session_key: could not fetch "
3780 "trust account password for domain '%s'\n",
3782 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3785 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3786 cli->desthost, /* server name */
3787 domain, /* domain */
3788 global_myname(), /* client name */
3789 machine_account, /* machine account name */
3794 if (!NT_STATUS_IS_OK(status)) {
3795 DEBUG(3, ("get_schannel_session_key_common: "
3796 "rpccli_netlogon_setup_creds failed with result %s "
3797 "to server %s, domain %s, machine account %s.\n",
3798 nt_errstr(status), cli->desthost, domain,
3803 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3804 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3806 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3809 return NT_STATUS_OK;;
3812 /****************************************************************************
3813 Open a netlogon pipe and get the schannel session key.
3814 Now exposed to external callers.
3815 ****************************************************************************/
3818 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3821 struct rpc_pipe_client **presult)
3823 struct rpc_pipe_client *netlogon_pipe = NULL;
3826 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3828 if (!NT_STATUS_IS_OK(status)) {
3832 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3834 if (!NT_STATUS_IS_OK(status)) {
3835 TALLOC_FREE(netlogon_pipe);
3839 *presult = netlogon_pipe;
3840 return NT_STATUS_OK;
3843 /****************************************************************************
3845 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3846 using session_key. sign and seal.
3847 ****************************************************************************/
3849 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3850 const struct ndr_syntax_id *interface,
3851 enum pipe_auth_level auth_level,
3853 const struct dcinfo *pdc,
3854 struct rpc_pipe_client **presult)
3856 struct rpc_pipe_client *result;
3857 struct cli_pipe_auth_data *auth;
3860 status = cli_rpc_pipe_open(cli, interface, &result);
3861 if (!NT_STATUS_IS_OK(status)) {
3865 status = rpccli_schannel_bind_data(result, domain, auth_level,
3866 pdc->sess_key, &auth);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3869 nt_errstr(status)));
3870 TALLOC_FREE(result);
3874 status = rpc_pipe_bind(result, auth);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3877 "cli_rpc_pipe_bind failed with error %s\n",
3878 nt_errstr(status) ));
3879 TALLOC_FREE(result);
3884 * The credentials on a new netlogon pipe are the ones we are passed
3885 * in - copy them over.
3887 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3888 if (result->dc == NULL) {
3889 DEBUG(0, ("talloc failed\n"));
3890 TALLOC_FREE(result);
3891 return NT_STATUS_NO_MEMORY;
3894 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3895 "for domain %s and bound using schannel.\n",
3896 get_pipe_name_from_iface(interface),
3897 cli->desthost, domain ));
3900 return NT_STATUS_OK;
3903 /****************************************************************************
3904 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3905 Fetch the session key ourselves using a temporary netlogon pipe. This
3906 version uses an ntlmssp auth bound netlogon pipe to get the key.
3907 ****************************************************************************/
3909 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3911 const char *username,
3912 const char *password,
3914 struct rpc_pipe_client **presult)
3916 struct rpc_pipe_client *netlogon_pipe = NULL;
3919 status = cli_rpc_pipe_open_spnego_ntlmssp(
3920 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3921 domain, username, password, &netlogon_pipe);
3922 if (!NT_STATUS_IS_OK(status)) {
3926 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3928 if (!NT_STATUS_IS_OK(status)) {
3929 TALLOC_FREE(netlogon_pipe);
3933 *presult = netlogon_pipe;
3934 return NT_STATUS_OK;
3937 /****************************************************************************
3938 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3939 Fetch the session key ourselves using a temporary netlogon pipe. This version
3940 uses an ntlmssp bind to get the session key.
3941 ****************************************************************************/
3943 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3944 const struct ndr_syntax_id *interface,
3945 enum pipe_auth_level auth_level,
3947 const char *username,
3948 const char *password,
3949 struct rpc_pipe_client **presult)
3951 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3952 struct rpc_pipe_client *netlogon_pipe = NULL;
3953 struct rpc_pipe_client *result = NULL;
3956 status = get_schannel_session_key_auth_ntlmssp(
3957 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3958 if (!NT_STATUS_IS_OK(status)) {
3959 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3960 "key from server %s for domain %s.\n",
3961 cli->desthost, domain ));
3965 status = cli_rpc_pipe_open_schannel_with_key(
3966 cli, interface, auth_level, domain, netlogon_pipe->dc,
3969 /* Now we've bound using the session key we can close the netlog pipe. */
3970 TALLOC_FREE(netlogon_pipe);
3972 if (NT_STATUS_IS_OK(status)) {
3978 /****************************************************************************
3979 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3980 Fetch the session key ourselves using a temporary netlogon pipe.
3981 ****************************************************************************/
3983 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3984 const struct ndr_syntax_id *interface,
3985 enum pipe_auth_level auth_level,
3987 struct rpc_pipe_client **presult)
3989 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3990 struct rpc_pipe_client *netlogon_pipe = NULL;
3991 struct rpc_pipe_client *result = NULL;
3994 status = get_schannel_session_key(cli, domain, &neg_flags,
3996 if (!NT_STATUS_IS_OK(status)) {
3997 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3998 "key from server %s for domain %s.\n",
3999 cli->desthost, domain ));
4003 status = cli_rpc_pipe_open_schannel_with_key(
4004 cli, interface, auth_level, domain, netlogon_pipe->dc,
4007 /* Now we've bound using the session key we can close the netlog pipe. */
4008 TALLOC_FREE(netlogon_pipe);
4010 if (NT_STATUS_IS_OK(status)) {
4014 return NT_STATUS_OK;
4017 /****************************************************************************
4018 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4019 The idea is this can be called with service_princ, username and password all
4020 NULL so long as the caller has a TGT.
4021 ****************************************************************************/
4023 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4024 const struct ndr_syntax_id *interface,
4025 enum pipe_auth_level auth_level,
4026 const char *service_princ,
4027 const char *username,
4028 const char *password,
4029 struct rpc_pipe_client **presult)
4032 struct rpc_pipe_client *result;
4033 struct cli_pipe_auth_data *auth;
4036 status = cli_rpc_pipe_open(cli, interface, &result);
4037 if (!NT_STATUS_IS_OK(status)) {
4041 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4042 username, password, &auth);
4043 if (!NT_STATUS_IS_OK(status)) {
4044 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4045 nt_errstr(status)));
4046 TALLOC_FREE(result);
4050 status = rpc_pipe_bind(result, auth);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4053 "with error %s\n", nt_errstr(status)));
4054 TALLOC_FREE(result);
4059 return NT_STATUS_OK;
4061 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4062 return NT_STATUS_NOT_IMPLEMENTED;
4066 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4067 struct rpc_pipe_client *cli,
4068 DATA_BLOB *session_key)
4070 if (!session_key || !cli) {
4071 return NT_STATUS_INVALID_PARAMETER;
4075 return NT_STATUS_INVALID_PARAMETER;
4078 switch (cli->auth->auth_type) {
4079 case PIPE_AUTH_TYPE_SCHANNEL:
4080 *session_key = data_blob_talloc(mem_ctx,
4081 cli->auth->a_u.schannel_auth->sess_key, 16);
4083 case PIPE_AUTH_TYPE_NTLMSSP:
4084 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4085 *session_key = data_blob_talloc(mem_ctx,
4086 cli->auth->a_u.ntlmssp_state->session_key.data,
4087 cli->auth->a_u.ntlmssp_state->session_key.length);
4089 case PIPE_AUTH_TYPE_KRB5:
4090 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4091 *session_key = data_blob_talloc(mem_ctx,
4092 cli->auth->a_u.kerberos_auth->session_key.data,
4093 cli->auth->a_u.kerberos_auth->session_key.length);
4095 case PIPE_AUTH_TYPE_NONE:
4096 *session_key = data_blob_talloc(mem_ctx,
4097 cli->auth->user_session_key.data,
4098 cli->auth->user_session_key.length);
4101 return NT_STATUS_NO_USER_SESSION_KEY;
4104 return NT_STATUS_OK;