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"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../libcli/auth/schannel.h"
24 #include "../libcli/auth/spnego.h"
28 #define DBGC_CLASS DBGC_RPC_CLI
30 static const char *get_pipe_name_from_iface(
31 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
34 const struct ndr_interface_string_array *ep = interface->endpoints;
37 for (i=0; i<ep->count; i++) {
38 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
47 * extract the pipe name without \\pipe from for example
48 * ncacn_np:[\\pipe\\epmapper]
50 p = strchr(ep->names[i]+15, ']');
54 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
57 static const struct ndr_interface_table **interfaces;
59 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
61 int num_interfaces = talloc_array_length(interfaces);
62 const struct ndr_interface_table **tmp;
65 for (i=0; i<num_interfaces; i++) {
66 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
67 &interface->syntax_id)) {
72 tmp = talloc_realloc(NULL, interfaces,
73 const struct ndr_interface_table *,
76 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
80 interfaces[num_interfaces] = interface;
84 static bool initialize_interfaces(void)
86 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
89 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
92 if (!smb_register_ndr_interface(&ndr_table_samr)) {
95 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
98 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
101 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
104 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
107 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
110 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
113 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
116 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
119 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
122 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
125 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
128 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
131 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
137 const struct ndr_interface_table *get_iface_from_syntax(
138 const struct ndr_syntax_id *syntax)
143 if (interfaces == NULL) {
144 if (!initialize_interfaces()) {
148 num_interfaces = talloc_array_length(interfaces);
150 for (i=0; i<num_interfaces; i++) {
151 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
152 return interfaces[i];
159 /****************************************************************************
160 Return the pipe name from the interface.
161 ****************************************************************************/
163 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
164 const struct ndr_syntax_id *syntax)
166 const struct ndr_interface_table *interface;
170 interface = get_iface_from_syntax(syntax);
171 if (interface != NULL) {
172 result = get_pipe_name_from_iface(mem_ctx, interface);
173 if (result != NULL) {
179 * Here we should ask \\epmapper, but for now our code is only
180 * interested in the known pipes mentioned in pipe_names[]
183 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
184 if (guid_str == NULL) {
187 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
188 (int)syntax->if_version);
189 TALLOC_FREE(guid_str);
191 if (result == NULL) {
197 /********************************************************************
198 Map internal value to wire value.
199 ********************************************************************/
201 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
205 case PIPE_AUTH_TYPE_NONE:
206 return DCERPC_AUTH_TYPE_NONE;
208 case PIPE_AUTH_TYPE_NTLMSSP:
209 return DCERPC_AUTH_TYPE_NTLMSSP;
211 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
212 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
213 return DCERPC_AUTH_TYPE_SPNEGO;
215 case PIPE_AUTH_TYPE_SCHANNEL:
216 return DCERPC_AUTH_TYPE_SCHANNEL;
218 case PIPE_AUTH_TYPE_KRB5:
219 return DCERPC_AUTH_TYPE_KRB5;
222 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
224 (unsigned int)auth_type ));
230 /********************************************************************
231 Pipe description for a DEBUG
232 ********************************************************************/
233 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
234 struct rpc_pipe_client *cli)
236 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
237 if (result == NULL) {
243 /********************************************************************
245 ********************************************************************/
247 static uint32 get_rpc_call_id(void)
249 static uint32 call_id = 0;
254 * Realloc pdu to have a least "size" bytes
257 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
261 if (prs_data_size(pdu) >= size) {
265 extra_size = size - prs_data_size(pdu);
267 if (!prs_force_grow(pdu, extra_size)) {
268 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
269 "%d bytes.\n", (int)extra_size));
273 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
274 (int)extra_size, prs_data_size(pdu)));
279 /*******************************************************************
280 Use SMBreadX to get rest of one fragment's worth of rpc data.
281 Reads the whole size or give an error message
282 ********************************************************************/
284 struct rpc_read_state {
285 struct event_context *ev;
286 struct rpc_cli_transport *transport;
292 static void rpc_read_done(struct tevent_req *subreq);
294 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
295 struct event_context *ev,
296 struct rpc_cli_transport *transport,
297 uint8_t *data, size_t size)
299 struct tevent_req *req, *subreq;
300 struct rpc_read_state *state;
302 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
307 state->transport = transport;
312 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
314 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
316 if (subreq == NULL) {
319 tevent_req_set_callback(subreq, rpc_read_done, req);
327 static void rpc_read_done(struct tevent_req *subreq)
329 struct tevent_req *req = tevent_req_callback_data(
330 subreq, struct tevent_req);
331 struct rpc_read_state *state = tevent_req_data(
332 req, struct rpc_read_state);
336 status = state->transport->read_recv(subreq, &received);
338 if (!NT_STATUS_IS_OK(status)) {
339 tevent_req_nterror(req, status);
343 state->num_read += received;
344 if (state->num_read == state->size) {
345 tevent_req_done(req);
349 subreq = state->transport->read_send(state, state->ev,
350 state->data + state->num_read,
351 state->size - state->num_read,
352 state->transport->priv);
353 if (tevent_req_nomem(subreq, req)) {
356 tevent_req_set_callback(subreq, rpc_read_done, req);
359 static NTSTATUS rpc_read_recv(struct tevent_req *req)
361 return tevent_req_simple_recv_ntstatus(req);
364 struct rpc_write_state {
365 struct event_context *ev;
366 struct rpc_cli_transport *transport;
372 static void rpc_write_done(struct tevent_req *subreq);
374 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
375 struct event_context *ev,
376 struct rpc_cli_transport *transport,
377 const uint8_t *data, size_t size)
379 struct tevent_req *req, *subreq;
380 struct rpc_write_state *state;
382 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
387 state->transport = transport;
390 state->num_written = 0;
392 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
394 subreq = transport->write_send(state, ev, data, size, transport->priv);
395 if (subreq == NULL) {
398 tevent_req_set_callback(subreq, rpc_write_done, req);
405 static void rpc_write_done(struct tevent_req *subreq)
407 struct tevent_req *req = tevent_req_callback_data(
408 subreq, struct tevent_req);
409 struct rpc_write_state *state = tevent_req_data(
410 req, struct rpc_write_state);
414 status = state->transport->write_recv(subreq, &written);
416 if (!NT_STATUS_IS_OK(status)) {
417 tevent_req_nterror(req, status);
421 state->num_written += written;
423 if (state->num_written == state->size) {
424 tevent_req_done(req);
428 subreq = state->transport->write_send(state, state->ev,
429 state->data + state->num_written,
430 state->size - state->num_written,
431 state->transport->priv);
432 if (tevent_req_nomem(subreq, req)) {
435 tevent_req_set_callback(subreq, rpc_write_done, req);
438 static NTSTATUS rpc_write_recv(struct tevent_req *req)
440 return tevent_req_simple_recv_ntstatus(req);
444 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
445 struct rpc_hdr_info *prhdr,
449 * This next call sets the endian bit correctly in current_pdu. We
450 * will propagate this to rbuf later.
453 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
454 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
455 return NT_STATUS_BUFFER_TOO_SMALL;
458 if (prhdr->frag_len > cli->max_recv_frag) {
459 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
460 " we only allow %d\n", (int)prhdr->frag_len,
461 (int)cli->max_recv_frag));
462 return NT_STATUS_BUFFER_TOO_SMALL;
468 /****************************************************************************
469 Try and get a PDU's worth of data from current_pdu. If not, then read more
471 ****************************************************************************/
473 struct get_complete_frag_state {
474 struct event_context *ev;
475 struct rpc_pipe_client *cli;
476 struct rpc_hdr_info *prhdr;
480 static void get_complete_frag_got_header(struct tevent_req *subreq);
481 static void get_complete_frag_got_rest(struct tevent_req *subreq);
483 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
484 struct event_context *ev,
485 struct rpc_pipe_client *cli,
486 struct rpc_hdr_info *prhdr,
489 struct tevent_req *req, *subreq;
490 struct get_complete_frag_state *state;
494 req = tevent_req_create(mem_ctx, &state,
495 struct get_complete_frag_state);
501 state->prhdr = prhdr;
504 pdu_len = prs_data_size(pdu);
505 if (pdu_len < RPC_HEADER_LEN) {
506 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
507 status = NT_STATUS_NO_MEMORY;
510 subreq = rpc_read_send(
512 state->cli->transport,
513 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
514 RPC_HEADER_LEN - pdu_len);
515 if (subreq == NULL) {
516 status = NT_STATUS_NO_MEMORY;
519 tevent_req_set_callback(subreq, get_complete_frag_got_header,
524 status = parse_rpc_header(cli, prhdr, pdu);
525 if (!NT_STATUS_IS_OK(status)) {
530 * Ensure we have frag_len bytes of data.
532 if (pdu_len < prhdr->frag_len) {
533 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
534 status = NT_STATUS_NO_MEMORY;
537 subreq = rpc_read_send(state, state->ev,
538 state->cli->transport,
539 (uint8_t *)(prs_data_p(pdu) + pdu_len),
540 prhdr->frag_len - pdu_len);
541 if (subreq == NULL) {
542 status = NT_STATUS_NO_MEMORY;
545 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
550 status = NT_STATUS_OK;
552 if (NT_STATUS_IS_OK(status)) {
553 tevent_req_done(req);
555 tevent_req_nterror(req, status);
557 return tevent_req_post(req, ev);
560 static void get_complete_frag_got_header(struct tevent_req *subreq)
562 struct tevent_req *req = tevent_req_callback_data(
563 subreq, struct tevent_req);
564 struct get_complete_frag_state *state = tevent_req_data(
565 req, struct get_complete_frag_state);
568 status = rpc_read_recv(subreq);
570 if (!NT_STATUS_IS_OK(status)) {
571 tevent_req_nterror(req, status);
575 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
576 if (!NT_STATUS_IS_OK(status)) {
577 tevent_req_nterror(req, status);
581 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
582 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
587 * We're here in this piece of code because we've read exactly
588 * RPC_HEADER_LEN bytes into state->pdu.
591 subreq = rpc_read_send(
592 state, state->ev, state->cli->transport,
593 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
594 state->prhdr->frag_len - RPC_HEADER_LEN);
595 if (tevent_req_nomem(subreq, req)) {
598 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
601 static void get_complete_frag_got_rest(struct tevent_req *subreq)
603 struct tevent_req *req = tevent_req_callback_data(
604 subreq, struct tevent_req);
607 status = rpc_read_recv(subreq);
609 if (!NT_STATUS_IS_OK(status)) {
610 tevent_req_nterror(req, status);
613 tevent_req_done(req);
616 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
618 return tevent_req_simple_recv_ntstatus(req);
621 /****************************************************************************
622 NTLMSSP specific sign/seal.
623 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
624 In fact I should probably abstract these into identical pieces of code... JRA.
625 ****************************************************************************/
627 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
628 prs_struct *current_pdu,
629 uint8 *p_ss_padding_len)
631 RPC_HDR_AUTH auth_info;
632 uint32 save_offset = prs_offset(current_pdu);
633 uint32 auth_len = prhdr->auth_len;
634 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
635 unsigned char *data = NULL;
637 unsigned char *full_packet_data = NULL;
638 size_t full_packet_data_len;
642 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
643 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
647 if (!ntlmssp_state) {
648 return NT_STATUS_INVALID_PARAMETER;
651 /* Ensure there's enough data for an authenticated response. */
652 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
653 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
654 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
655 (unsigned int)auth_len ));
656 return NT_STATUS_BUFFER_TOO_SMALL;
660 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
661 * after the RPC header.
662 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
663 * functions as NTLMv2 checks the rpc headers also.
666 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
667 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
669 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
670 full_packet_data_len = prhdr->frag_len - auth_len;
672 /* Pull the auth header and the following data into a blob. */
673 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
674 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
675 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
676 return NT_STATUS_BUFFER_TOO_SMALL;
679 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
680 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
681 return NT_STATUS_BUFFER_TOO_SMALL;
684 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
685 auth_blob.length = auth_len;
687 switch (cli->auth->auth_level) {
688 case DCERPC_AUTH_LEVEL_PRIVACY:
689 /* Data is encrypted. */
690 status = ntlmssp_unseal_packet(ntlmssp_state,
693 full_packet_data_len,
695 if (!NT_STATUS_IS_OK(status)) {
696 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
697 "packet from %s. Error was %s.\n",
698 rpccli_pipe_txt(talloc_tos(), cli),
699 nt_errstr(status) ));
703 case DCERPC_AUTH_LEVEL_INTEGRITY:
704 /* Data is signed. */
705 status = ntlmssp_check_packet(ntlmssp_state,
708 full_packet_data_len,
710 if (!NT_STATUS_IS_OK(status)) {
711 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
712 "packet from %s. Error was %s.\n",
713 rpccli_pipe_txt(talloc_tos(), cli),
714 nt_errstr(status) ));
719 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
720 "auth level %d\n", cli->auth->auth_level));
721 return NT_STATUS_INVALID_INFO_CLASS;
725 * Return the current pointer to the data offset.
728 if(!prs_set_offset(current_pdu, save_offset)) {
729 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
730 (unsigned int)save_offset ));
731 return NT_STATUS_BUFFER_TOO_SMALL;
735 * Remember the padding length. We must remove it from the real data
736 * stream once the sign/seal is done.
739 *p_ss_padding_len = auth_info.auth_pad_len;
744 /****************************************************************************
745 schannel specific sign/seal.
746 ****************************************************************************/
748 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
749 prs_struct *current_pdu,
750 uint8 *p_ss_padding_len)
752 RPC_HDR_AUTH auth_info;
753 uint32 auth_len = prhdr->auth_len;
754 uint32 save_offset = prs_offset(current_pdu);
755 struct schannel_state *schannel_auth =
756 cli->auth->a_u.schannel_auth;
762 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
763 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
767 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
768 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
769 return NT_STATUS_INVALID_PARAMETER;
772 if (!schannel_auth) {
773 return NT_STATUS_INVALID_PARAMETER;
776 /* Ensure there's enough data for an authenticated response. */
777 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
778 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
779 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
780 (unsigned int)auth_len ));
781 return NT_STATUS_INVALID_PARAMETER;
784 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
786 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
787 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
788 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
789 return NT_STATUS_BUFFER_TOO_SMALL;
792 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
793 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
794 return NT_STATUS_BUFFER_TOO_SMALL;
797 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
798 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
799 auth_info.auth_type));
800 return NT_STATUS_BUFFER_TOO_SMALL;
803 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
805 if (DEBUGLEVEL >= 10) {
806 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
809 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
811 switch (cli->auth->auth_level) {
812 case DCERPC_AUTH_LEVEL_PRIVACY:
813 status = netsec_incoming_packet(schannel_auth,
820 case DCERPC_AUTH_LEVEL_INTEGRITY:
821 status = netsec_incoming_packet(schannel_auth,
829 status = NT_STATUS_INTERNAL_ERROR;
833 if (!NT_STATUS_IS_OK(status)) {
834 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
835 "Connection to %s (%s).\n",
836 rpccli_pipe_txt(talloc_tos(), cli),
838 return NT_STATUS_INVALID_PARAMETER;
842 * Return the current pointer to the data offset.
845 if(!prs_set_offset(current_pdu, save_offset)) {
846 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
847 (unsigned int)save_offset ));
848 return NT_STATUS_BUFFER_TOO_SMALL;
852 * Remember the padding length. We must remove it from the real data
853 * stream once the sign/seal is done.
856 *p_ss_padding_len = auth_info.auth_pad_len;
861 /****************************************************************************
862 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
863 ****************************************************************************/
865 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
866 prs_struct *current_pdu,
867 uint8 *p_ss_padding_len)
869 NTSTATUS ret = NT_STATUS_OK;
871 /* Paranioa checks for auth_len. */
872 if (prhdr->auth_len) {
873 if (prhdr->auth_len > prhdr->frag_len) {
874 return NT_STATUS_INVALID_PARAMETER;
877 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
878 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
879 /* Integer wrap attempt. */
880 return NT_STATUS_INVALID_PARAMETER;
885 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
888 switch(cli->auth->auth_type) {
889 case PIPE_AUTH_TYPE_NONE:
890 if (prhdr->auth_len) {
891 DEBUG(3, ("cli_pipe_validate_rpc_response: "
892 "Connection to %s - got non-zero "
894 rpccli_pipe_txt(talloc_tos(), cli),
895 (unsigned int)prhdr->auth_len ));
896 return NT_STATUS_INVALID_PARAMETER;
900 case PIPE_AUTH_TYPE_NTLMSSP:
901 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
902 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
903 if (!NT_STATUS_IS_OK(ret)) {
908 case PIPE_AUTH_TYPE_SCHANNEL:
909 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
910 if (!NT_STATUS_IS_OK(ret)) {
915 case PIPE_AUTH_TYPE_KRB5:
916 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
918 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
919 "to %s - unknown internal auth type %u.\n",
920 rpccli_pipe_txt(talloc_tos(), cli),
921 cli->auth->auth_type ));
922 return NT_STATUS_INVALID_INFO_CLASS;
928 /****************************************************************************
929 Do basic authentication checks on an incoming pdu.
930 ****************************************************************************/
932 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
933 prs_struct *current_pdu,
934 uint8 expected_pkt_type,
937 prs_struct *return_data)
940 NTSTATUS ret = NT_STATUS_OK;
941 uint32 current_pdu_len = prs_data_size(current_pdu);
943 if (current_pdu_len != prhdr->frag_len) {
944 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
945 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
946 return NT_STATUS_INVALID_PARAMETER;
950 * Point the return values at the real data including the RPC
951 * header. Just in case the caller wants it.
953 *ppdata = prs_data_p(current_pdu);
954 *pdata_len = current_pdu_len;
956 /* Ensure we have the correct type. */
957 switch (prhdr->pkt_type) {
958 case DCERPC_PKT_ALTER_RESP:
959 case DCERPC_PKT_BIND_ACK:
961 /* Alter context and bind ack share the same packet definitions. */
965 case DCERPC_PKT_RESPONSE:
967 RPC_HDR_RESP rhdr_resp;
968 uint8 ss_padding_len = 0;
970 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
971 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
972 return NT_STATUS_BUFFER_TOO_SMALL;
975 /* Here's where we deal with incoming sign/seal. */
976 ret = cli_pipe_validate_rpc_response(cli, prhdr,
977 current_pdu, &ss_padding_len);
978 if (!NT_STATUS_IS_OK(ret)) {
982 /* Point the return values at the NDR data. Remember to remove any ss padding. */
983 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
985 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
986 return NT_STATUS_BUFFER_TOO_SMALL;
989 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
991 /* Remember to remove the auth footer. */
992 if (prhdr->auth_len) {
993 /* We've already done integer wrap tests on auth_len in
994 cli_pipe_validate_rpc_response(). */
995 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
996 return NT_STATUS_BUFFER_TOO_SMALL;
998 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1001 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1002 current_pdu_len, *pdata_len, ss_padding_len ));
1005 * If this is the first reply, and the allocation hint is reasonably, try and
1006 * set up the return_data parse_struct to the correct size.
1009 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1010 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1011 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1012 "too large to allocate\n",
1013 (unsigned int)rhdr_resp.alloc_hint ));
1014 return NT_STATUS_NO_MEMORY;
1021 case DCERPC_PKT_BIND_NAK:
1022 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1023 "received from %s!\n",
1024 rpccli_pipe_txt(talloc_tos(), cli)));
1025 /* Use this for now... */
1026 return NT_STATUS_NETWORK_ACCESS_DENIED;
1028 case DCERPC_PKT_FAULT:
1030 RPC_HDR_RESP rhdr_resp;
1031 RPC_HDR_FAULT fault_resp;
1033 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1034 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1035 return NT_STATUS_BUFFER_TOO_SMALL;
1038 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1039 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1040 return NT_STATUS_BUFFER_TOO_SMALL;
1043 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1044 "code %s received from %s!\n",
1045 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1046 rpccli_pipe_txt(talloc_tos(), cli)));
1047 if (NT_STATUS_IS_OK(fault_resp.status)) {
1048 return NT_STATUS_UNSUCCESSFUL;
1050 return fault_resp.status;
1055 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1057 (unsigned int)prhdr->pkt_type,
1058 rpccli_pipe_txt(talloc_tos(), cli)));
1059 return NT_STATUS_INVALID_INFO_CLASS;
1062 if (prhdr->pkt_type != expected_pkt_type) {
1063 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1064 "got an unexpected RPC packet type - %u, not %u\n",
1065 rpccli_pipe_txt(talloc_tos(), cli),
1067 expected_pkt_type));
1068 return NT_STATUS_INVALID_INFO_CLASS;
1071 /* Do this just before return - we don't want to modify any rpc header
1072 data before now as we may have needed to do cryptographic actions on
1075 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1076 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1077 "setting fragment first/last ON.\n"));
1078 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1081 return NT_STATUS_OK;
1084 /****************************************************************************
1085 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1086 Normally the frag_len and buffer size will match, but on the first trans
1087 reply there is a theoretical chance that buffer size > frag_len, so we must
1089 ****************************************************************************/
1091 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1093 uint32 current_pdu_len = prs_data_size(current_pdu);
1095 if (current_pdu_len < prhdr->frag_len) {
1096 return NT_STATUS_BUFFER_TOO_SMALL;
1100 if (current_pdu_len == (uint32)prhdr->frag_len) {
1101 prs_mem_free(current_pdu);
1102 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1103 /* Make current_pdu dynamic with no memory. */
1104 prs_give_memory(current_pdu, 0, 0, True);
1105 return NT_STATUS_OK;
1109 * Oh no ! More data in buffer than we processed in current pdu.
1110 * Cheat. Move the data down and shrink the buffer.
1113 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1114 current_pdu_len - prhdr->frag_len);
1116 /* Remember to set the read offset back to zero. */
1117 prs_set_offset(current_pdu, 0);
1119 /* Shrink the buffer. */
1120 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1121 return NT_STATUS_BUFFER_TOO_SMALL;
1124 return NT_STATUS_OK;
1127 /****************************************************************************
1128 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1129 ****************************************************************************/
1131 struct cli_api_pipe_state {
1132 struct event_context *ev;
1133 struct rpc_cli_transport *transport;
1138 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1139 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1140 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1142 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1143 struct event_context *ev,
1144 struct rpc_cli_transport *transport,
1145 uint8_t *data, size_t data_len,
1146 uint32_t max_rdata_len)
1148 struct tevent_req *req, *subreq;
1149 struct cli_api_pipe_state *state;
1152 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1157 state->transport = transport;
1159 if (max_rdata_len < RPC_HEADER_LEN) {
1161 * For a RPC reply we always need at least RPC_HEADER_LEN
1162 * bytes. We check this here because we will receive
1163 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1165 status = NT_STATUS_INVALID_PARAMETER;
1169 if (transport->trans_send != NULL) {
1170 subreq = transport->trans_send(state, ev, data, data_len,
1171 max_rdata_len, transport->priv);
1172 if (subreq == NULL) {
1175 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1180 * If the transport does not provide a "trans" routine, i.e. for
1181 * example the ncacn_ip_tcp transport, do the write/read step here.
1184 subreq = rpc_write_send(state, ev, transport, data, data_len);
1185 if (subreq == NULL) {
1188 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1191 status = NT_STATUS_INVALID_PARAMETER;
1194 tevent_req_nterror(req, status);
1195 return tevent_req_post(req, ev);
1201 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1203 struct tevent_req *req = tevent_req_callback_data(
1204 subreq, struct tevent_req);
1205 struct cli_api_pipe_state *state = tevent_req_data(
1206 req, struct cli_api_pipe_state);
1209 status = state->transport->trans_recv(subreq, state, &state->rdata,
1211 TALLOC_FREE(subreq);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 tevent_req_nterror(req, status);
1216 tevent_req_done(req);
1219 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1221 struct tevent_req *req = tevent_req_callback_data(
1222 subreq, struct tevent_req);
1223 struct cli_api_pipe_state *state = tevent_req_data(
1224 req, struct cli_api_pipe_state);
1227 status = rpc_write_recv(subreq);
1228 TALLOC_FREE(subreq);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 tevent_req_nterror(req, status);
1234 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1235 if (tevent_req_nomem(state->rdata, req)) {
1240 * We don't need to use rpc_read_send here, the upper layer will cope
1241 * with a short read, transport->trans_send could also return less
1242 * than state->max_rdata_len.
1244 subreq = state->transport->read_send(state, state->ev, state->rdata,
1246 state->transport->priv);
1247 if (tevent_req_nomem(subreq, req)) {
1250 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1253 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1255 struct tevent_req *req = tevent_req_callback_data(
1256 subreq, struct tevent_req);
1257 struct cli_api_pipe_state *state = tevent_req_data(
1258 req, struct cli_api_pipe_state);
1262 status = state->transport->read_recv(subreq, &received);
1263 TALLOC_FREE(subreq);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 tevent_req_nterror(req, status);
1268 state->rdata_len = received;
1269 tevent_req_done(req);
1272 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1273 uint8_t **prdata, uint32_t *prdata_len)
1275 struct cli_api_pipe_state *state = tevent_req_data(
1276 req, struct cli_api_pipe_state);
1279 if (tevent_req_is_nterror(req, &status)) {
1283 *prdata = talloc_move(mem_ctx, &state->rdata);
1284 *prdata_len = state->rdata_len;
1285 return NT_STATUS_OK;
1288 /****************************************************************************
1289 Send data on an rpc pipe via trans. The prs_struct data must be the last
1290 pdu fragment of an NDR data stream.
1292 Receive response data from an rpc pipe, which may be large...
1294 Read the first fragment: unfortunately have to use SMBtrans for the first
1295 bit, then SMBreadX for subsequent bits.
1297 If first fragment received also wasn't the last fragment, continue
1298 getting fragments until we _do_ receive the last fragment.
1300 Request/Response PDU's look like the following...
1302 |<------------------PDU len----------------------------------------------->|
1303 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1305 +------------+-----------------+-------------+---------------+-------------+
1306 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1307 +------------+-----------------+-------------+---------------+-------------+
1309 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1310 signing & sealing being negotiated.
1312 ****************************************************************************/
1314 struct rpc_api_pipe_state {
1315 struct event_context *ev;
1316 struct rpc_pipe_client *cli;
1317 uint8_t expected_pkt_type;
1319 prs_struct incoming_frag;
1320 struct rpc_hdr_info rhdr;
1322 prs_struct incoming_pdu; /* Incoming reply */
1323 uint32_t incoming_pdu_offset;
1326 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1328 prs_mem_free(&state->incoming_frag);
1329 prs_mem_free(&state->incoming_pdu);
1333 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1334 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1336 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1337 struct event_context *ev,
1338 struct rpc_pipe_client *cli,
1339 prs_struct *data, /* Outgoing PDU */
1340 uint8_t expected_pkt_type)
1342 struct tevent_req *req, *subreq;
1343 struct rpc_api_pipe_state *state;
1344 uint16_t max_recv_frag;
1347 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1353 state->expected_pkt_type = expected_pkt_type;
1354 state->incoming_pdu_offset = 0;
1356 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1358 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1359 /* Make incoming_pdu dynamic with no memory. */
1360 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1362 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1365 * Ensure we're not sending too much.
1367 if (prs_offset(data) > cli->max_xmit_frag) {
1368 status = NT_STATUS_INVALID_PARAMETER;
1372 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1374 max_recv_frag = cli->max_recv_frag;
1377 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1380 subreq = cli_api_pipe_send(state, ev, cli->transport,
1381 (uint8_t *)prs_data_p(data),
1382 prs_offset(data), max_recv_frag);
1383 if (subreq == NULL) {
1386 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1390 tevent_req_nterror(req, status);
1391 return tevent_req_post(req, ev);
1397 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1399 struct tevent_req *req = tevent_req_callback_data(
1400 subreq, struct tevent_req);
1401 struct rpc_api_pipe_state *state = tevent_req_data(
1402 req, struct rpc_api_pipe_state);
1404 uint8_t *rdata = NULL;
1405 uint32_t rdata_len = 0;
1408 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1409 TALLOC_FREE(subreq);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1412 tevent_req_nterror(req, status);
1416 if (rdata == NULL) {
1417 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1418 rpccli_pipe_txt(talloc_tos(), state->cli)));
1419 tevent_req_done(req);
1424 * Give the memory received from cli_trans as dynamic to the current
1425 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1428 rdata_copy = (char *)memdup(rdata, rdata_len);
1430 if (tevent_req_nomem(rdata_copy, req)) {
1433 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1435 /* Ensure we have enough data for a pdu. */
1436 subreq = get_complete_frag_send(state, state->ev, state->cli,
1437 &state->rhdr, &state->incoming_frag);
1438 if (tevent_req_nomem(subreq, req)) {
1441 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1444 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1446 struct tevent_req *req = tevent_req_callback_data(
1447 subreq, struct tevent_req);
1448 struct rpc_api_pipe_state *state = tevent_req_data(
1449 req, struct rpc_api_pipe_state);
1452 uint32_t rdata_len = 0;
1454 status = get_complete_frag_recv(subreq);
1455 TALLOC_FREE(subreq);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 DEBUG(5, ("get_complete_frag failed: %s\n",
1458 nt_errstr(status)));
1459 tevent_req_nterror(req, status);
1463 status = cli_pipe_validate_current_pdu(
1464 state->cli, &state->rhdr, &state->incoming_frag,
1465 state->expected_pkt_type, &rdata, &rdata_len,
1466 &state->incoming_pdu);
1468 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1469 (unsigned)prs_data_size(&state->incoming_frag),
1470 (unsigned)state->incoming_pdu_offset,
1471 nt_errstr(status)));
1473 if (!NT_STATUS_IS_OK(status)) {
1474 tevent_req_nterror(req, status);
1478 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1479 && (state->rhdr.pack_type[0] == 0)) {
1481 * Set the data type correctly for big-endian data on the
1484 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1486 rpccli_pipe_txt(talloc_tos(), state->cli)));
1487 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1490 * Check endianness on subsequent packets.
1492 if (state->incoming_frag.bigendian_data
1493 != state->incoming_pdu.bigendian_data) {
1494 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1496 state->incoming_pdu.bigendian_data?"big":"little",
1497 state->incoming_frag.bigendian_data?"big":"little"));
1498 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1502 /* Now copy the data portion out of the pdu into rbuf. */
1503 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1504 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1508 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1509 rdata, (size_t)rdata_len);
1510 state->incoming_pdu_offset += rdata_len;
1512 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1513 &state->incoming_frag);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 tevent_req_nterror(req, status);
1519 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1520 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1521 rpccli_pipe_txt(talloc_tos(), state->cli),
1522 (unsigned)prs_data_size(&state->incoming_pdu)));
1523 tevent_req_done(req);
1527 subreq = get_complete_frag_send(state, state->ev, state->cli,
1528 &state->rhdr, &state->incoming_frag);
1529 if (tevent_req_nomem(subreq, req)) {
1532 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1535 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1536 prs_struct *reply_pdu)
1538 struct rpc_api_pipe_state *state = tevent_req_data(
1539 req, struct rpc_api_pipe_state);
1542 if (tevent_req_is_nterror(req, &status)) {
1546 *reply_pdu = state->incoming_pdu;
1547 reply_pdu->mem_ctx = mem_ctx;
1550 * Prevent state->incoming_pdu from being freed in
1551 * rpc_api_pipe_state_destructor()
1553 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1555 return NT_STATUS_OK;
1558 /*******************************************************************
1559 Creates krb5 auth bind.
1560 ********************************************************************/
1562 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1563 enum dcerpc_AuthLevel auth_level,
1564 RPC_HDR_AUTH *pauth_out,
1565 prs_struct *auth_data)
1569 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1570 DATA_BLOB tkt = data_blob_null;
1571 DATA_BLOB tkt_wrapped = data_blob_null;
1573 /* We may change the pad length before marshalling. */
1574 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1576 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1577 a->service_principal ));
1579 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1581 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1582 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1585 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1587 a->service_principal,
1588 error_message(ret) ));
1590 data_blob_free(&tkt);
1591 prs_mem_free(auth_data);
1592 return NT_STATUS_INVALID_PARAMETER;
1595 /* wrap that up in a nice GSS-API wrapping */
1596 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1598 data_blob_free(&tkt);
1600 /* Auth len in the rpc header doesn't include auth_header. */
1601 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1602 data_blob_free(&tkt_wrapped);
1603 prs_mem_free(auth_data);
1604 return NT_STATUS_NO_MEMORY;
1607 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1608 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1610 data_blob_free(&tkt_wrapped);
1611 return NT_STATUS_OK;
1613 return NT_STATUS_INVALID_PARAMETER;
1617 /*******************************************************************
1618 Creates SPNEGO NTLMSSP auth bind.
1619 ********************************************************************/
1621 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1622 enum dcerpc_AuthLevel auth_level,
1623 RPC_HDR_AUTH *pauth_out,
1624 prs_struct *auth_data)
1627 DATA_BLOB null_blob = data_blob_null;
1628 DATA_BLOB request = data_blob_null;
1629 DATA_BLOB spnego_msg = data_blob_null;
1631 /* We may change the pad length before marshalling. */
1632 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1634 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1635 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1639 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1640 data_blob_free(&request);
1641 prs_mem_free(auth_data);
1645 /* Wrap this in SPNEGO. */
1646 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1648 data_blob_free(&request);
1650 /* Auth len in the rpc header doesn't include auth_header. */
1651 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1652 data_blob_free(&spnego_msg);
1653 prs_mem_free(auth_data);
1654 return NT_STATUS_NO_MEMORY;
1657 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1658 dump_data(5, spnego_msg.data, spnego_msg.length);
1660 data_blob_free(&spnego_msg);
1661 return NT_STATUS_OK;
1664 /*******************************************************************
1665 Creates NTLMSSP auth bind.
1666 ********************************************************************/
1668 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1669 enum dcerpc_AuthLevel auth_level,
1670 RPC_HDR_AUTH *pauth_out,
1671 prs_struct *auth_data)
1674 DATA_BLOB null_blob = data_blob_null;
1675 DATA_BLOB request = data_blob_null;
1677 /* We may change the pad length before marshalling. */
1678 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1680 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1681 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1685 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1686 data_blob_free(&request);
1687 prs_mem_free(auth_data);
1691 /* Auth len in the rpc header doesn't include auth_header. */
1692 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1693 data_blob_free(&request);
1694 prs_mem_free(auth_data);
1695 return NT_STATUS_NO_MEMORY;
1698 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1699 dump_data(5, request.data, request.length);
1701 data_blob_free(&request);
1702 return NT_STATUS_OK;
1705 /*******************************************************************
1706 Creates schannel auth bind.
1707 ********************************************************************/
1709 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1710 enum dcerpc_AuthLevel auth_level,
1711 RPC_HDR_AUTH *pauth_out,
1712 prs_struct *auth_data)
1714 struct NL_AUTH_MESSAGE r;
1715 enum ndr_err_code ndr_err;
1718 /* We may change the pad length before marshalling. */
1719 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1721 /* Use lp_workgroup() if domain not specified */
1723 if (!cli->auth->domain || !cli->auth->domain[0]) {
1724 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1725 if (cli->auth->domain == NULL) {
1726 return NT_STATUS_NO_MEMORY;
1731 * Now marshall the data into the auth parse_struct.
1734 r.MessageType = NL_NEGOTIATE_REQUEST;
1735 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1736 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1737 r.oem_netbios_domain.a = cli->auth->domain;
1738 r.oem_netbios_computer.a = global_myname();
1740 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1741 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1744 prs_mem_free(auth_data);
1745 return ndr_map_error2ntstatus(ndr_err);
1748 if (DEBUGLEVEL >= 10) {
1749 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1752 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1754 prs_mem_free(auth_data);
1755 return NT_STATUS_NO_MEMORY;
1758 return NT_STATUS_OK;
1761 /*******************************************************************
1762 Creates the internals of a DCE/RPC bind request or alter context PDU.
1763 ********************************************************************/
1765 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1766 prs_struct *rpc_out,
1768 const struct ndr_syntax_id *abstract,
1769 const struct ndr_syntax_id *transfer,
1770 RPC_HDR_AUTH *phdr_auth,
1771 prs_struct *pauth_info)
1775 RPC_CONTEXT rpc_ctx;
1776 uint16 auth_len = prs_offset(pauth_info);
1777 uint8 ss_padding_len = 0;
1778 uint16 frag_len = 0;
1780 /* create the RPC context. */
1781 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1783 /* create the bind request RPC_HDR_RB */
1784 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1786 /* Start building the frag length. */
1787 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1789 /* Do we need to pad ? */
1791 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1793 ss_padding_len = 8 - (data_len % 8);
1794 phdr_auth->auth_pad_len = ss_padding_len;
1796 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1799 /* Create the request RPC_HDR */
1800 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1802 /* Marshall the RPC header */
1803 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1804 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1805 return NT_STATUS_NO_MEMORY;
1808 /* Marshall the bind request data */
1809 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1810 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1811 return NT_STATUS_NO_MEMORY;
1815 * Grow the outgoing buffer to store any auth info.
1819 if (ss_padding_len) {
1821 memset(pad, '\0', 8);
1822 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1823 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1824 return NT_STATUS_NO_MEMORY;
1828 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1829 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1830 return NT_STATUS_NO_MEMORY;
1834 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1835 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1836 return NT_STATUS_NO_MEMORY;
1840 return NT_STATUS_OK;
1843 /*******************************************************************
1844 Creates a DCE/RPC bind request.
1845 ********************************************************************/
1847 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1848 prs_struct *rpc_out,
1850 const struct ndr_syntax_id *abstract,
1851 const struct ndr_syntax_id *transfer,
1852 enum pipe_auth_type auth_type,
1853 enum dcerpc_AuthLevel auth_level)
1855 RPC_HDR_AUTH hdr_auth;
1856 prs_struct auth_info;
1857 NTSTATUS ret = NT_STATUS_OK;
1859 ZERO_STRUCT(hdr_auth);
1860 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1861 return NT_STATUS_NO_MEMORY;
1863 switch (auth_type) {
1864 case PIPE_AUTH_TYPE_SCHANNEL:
1865 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1866 if (!NT_STATUS_IS_OK(ret)) {
1867 prs_mem_free(&auth_info);
1872 case PIPE_AUTH_TYPE_NTLMSSP:
1873 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1874 if (!NT_STATUS_IS_OK(ret)) {
1875 prs_mem_free(&auth_info);
1880 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1881 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1882 if (!NT_STATUS_IS_OK(ret)) {
1883 prs_mem_free(&auth_info);
1888 case PIPE_AUTH_TYPE_KRB5:
1889 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1890 if (!NT_STATUS_IS_OK(ret)) {
1891 prs_mem_free(&auth_info);
1896 case PIPE_AUTH_TYPE_NONE:
1900 /* "Can't" happen. */
1901 return NT_STATUS_INVALID_INFO_CLASS;
1904 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1912 prs_mem_free(&auth_info);
1916 /*******************************************************************
1917 Create and add the NTLMSSP sign/seal auth header and data.
1918 ********************************************************************/
1920 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1922 uint32 ss_padding_len,
1923 prs_struct *outgoing_pdu)
1925 RPC_HDR_AUTH auth_info;
1927 DATA_BLOB auth_blob = data_blob_null;
1928 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1930 if (!cli->auth->a_u.ntlmssp_state) {
1931 return NT_STATUS_INVALID_PARAMETER;
1934 /* Init and marshall the auth header. */
1935 init_rpc_hdr_auth(&auth_info,
1936 map_pipe_auth_type_to_rpc_auth_type(
1937 cli->auth->auth_type),
1938 cli->auth->auth_level,
1940 1 /* context id. */);
1942 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1943 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1944 data_blob_free(&auth_blob);
1945 return NT_STATUS_NO_MEMORY;
1948 switch (cli->auth->auth_level) {
1949 case DCERPC_AUTH_LEVEL_PRIVACY:
1950 /* Data portion is encrypted. */
1951 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1952 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1954 (unsigned char *)prs_data_p(outgoing_pdu),
1955 (size_t)prs_offset(outgoing_pdu),
1957 if (!NT_STATUS_IS_OK(status)) {
1958 data_blob_free(&auth_blob);
1963 case DCERPC_AUTH_LEVEL_INTEGRITY:
1964 /* Data is signed. */
1965 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1966 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1968 (unsigned char *)prs_data_p(outgoing_pdu),
1969 (size_t)prs_offset(outgoing_pdu),
1971 if (!NT_STATUS_IS_OK(status)) {
1972 data_blob_free(&auth_blob);
1979 smb_panic("bad auth level");
1981 return NT_STATUS_INVALID_PARAMETER;
1984 /* Finally marshall the blob. */
1986 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1987 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1988 (unsigned int)NTLMSSP_SIG_SIZE));
1989 data_blob_free(&auth_blob);
1990 return NT_STATUS_NO_MEMORY;
1993 data_blob_free(&auth_blob);
1994 return NT_STATUS_OK;
1997 /*******************************************************************
1998 Create and add the schannel sign/seal auth header and data.
1999 ********************************************************************/
2001 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2003 uint32 ss_padding_len,
2004 prs_struct *outgoing_pdu)
2006 RPC_HDR_AUTH auth_info;
2007 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2008 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2009 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2014 return NT_STATUS_INVALID_PARAMETER;
2017 /* Init and marshall the auth header. */
2018 init_rpc_hdr_auth(&auth_info,
2019 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2020 cli->auth->auth_level,
2022 1 /* context id. */);
2024 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2025 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2026 return NT_STATUS_NO_MEMORY;
2029 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2032 switch (cli->auth->auth_level) {
2033 case DCERPC_AUTH_LEVEL_PRIVACY:
2034 status = netsec_outgoing_packet(sas,
2041 case DCERPC_AUTH_LEVEL_INTEGRITY:
2042 status = netsec_outgoing_packet(sas,
2050 status = NT_STATUS_INTERNAL_ERROR;
2054 if (!NT_STATUS_IS_OK(status)) {
2055 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2056 nt_errstr(status)));
2060 if (DEBUGLEVEL >= 10) {
2061 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2064 /* Finally marshall the blob. */
2065 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2066 return NT_STATUS_NO_MEMORY;
2069 return NT_STATUS_OK;
2072 /*******************************************************************
2073 Calculate how much data we're going to send in this packet, also
2074 work out any sign/seal padding length.
2075 ********************************************************************/
2077 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2081 uint32 *p_ss_padding)
2083 uint32 data_space, data_len;
2086 if ((data_left > 0) && (sys_random() % 2)) {
2087 data_left = MAX(data_left/2, 1);
2091 switch (cli->auth->auth_level) {
2092 case DCERPC_AUTH_LEVEL_NONE:
2093 case DCERPC_AUTH_LEVEL_CONNECT:
2094 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2095 data_len = MIN(data_space, data_left);
2098 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2101 case DCERPC_AUTH_LEVEL_INTEGRITY:
2102 case DCERPC_AUTH_LEVEL_PRIVACY:
2103 /* Treat the same for all authenticated rpc requests. */
2104 switch(cli->auth->auth_type) {
2105 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2106 case PIPE_AUTH_TYPE_NTLMSSP:
2107 *p_auth_len = NTLMSSP_SIG_SIZE;
2109 case PIPE_AUTH_TYPE_SCHANNEL:
2110 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2113 smb_panic("bad auth type");
2117 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2118 RPC_HDR_AUTH_LEN - *p_auth_len;
2120 data_len = MIN(data_space, data_left);
2123 *p_ss_padding = 8 - (data_len % 8);
2125 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2126 data_len + *p_ss_padding + /* data plus padding. */
2127 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2131 smb_panic("bad auth level");
2137 /*******************************************************************
2139 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2140 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2141 and deals with signing/sealing details.
2142 ********************************************************************/
2144 struct rpc_api_pipe_req_state {
2145 struct event_context *ev;
2146 struct rpc_pipe_client *cli;
2149 prs_struct *req_data;
2150 uint32_t req_data_sent;
2151 prs_struct outgoing_frag;
2152 prs_struct reply_pdu;
2155 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2157 prs_mem_free(&s->outgoing_frag);
2158 prs_mem_free(&s->reply_pdu);
2162 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2163 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2164 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2165 bool *is_last_frag);
2167 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2168 struct event_context *ev,
2169 struct rpc_pipe_client *cli,
2171 prs_struct *req_data)
2173 struct tevent_req *req, *subreq;
2174 struct rpc_api_pipe_req_state *state;
2178 req = tevent_req_create(mem_ctx, &state,
2179 struct rpc_api_pipe_req_state);
2185 state->op_num = op_num;
2186 state->req_data = req_data;
2187 state->req_data_sent = 0;
2188 state->call_id = get_rpc_call_id();
2190 if (cli->max_xmit_frag
2191 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2192 /* Server is screwed up ! */
2193 status = NT_STATUS_INVALID_PARAMETER;
2197 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2199 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2204 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2206 status = prepare_next_frag(state, &is_last_frag);
2207 if (!NT_STATUS_IS_OK(status)) {
2212 subreq = rpc_api_pipe_send(state, ev, state->cli,
2213 &state->outgoing_frag,
2214 DCERPC_PKT_RESPONSE);
2215 if (subreq == NULL) {
2218 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2220 subreq = rpc_write_send(
2221 state, ev, cli->transport,
2222 (uint8_t *)prs_data_p(&state->outgoing_frag),
2223 prs_offset(&state->outgoing_frag));
2224 if (subreq == NULL) {
2227 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2233 tevent_req_nterror(req, status);
2234 return tevent_req_post(req, ev);
2240 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2244 RPC_HDR_REQ hdr_req;
2245 uint32_t data_sent_thistime;
2249 uint32_t ss_padding;
2251 char pad[8] = { 0, };
2254 data_left = prs_offset(state->req_data) - state->req_data_sent;
2256 data_sent_thistime = calculate_data_len_tosend(
2257 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2259 if (state->req_data_sent == 0) {
2260 flags = DCERPC_PFC_FLAG_FIRST;
2263 if (data_sent_thistime == data_left) {
2264 flags |= DCERPC_PFC_FLAG_LAST;
2267 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2268 return NT_STATUS_NO_MEMORY;
2271 /* Create and marshall the header and request header. */
2272 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2275 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2276 return NT_STATUS_NO_MEMORY;
2279 /* Create the rpc request RPC_HDR_REQ */
2280 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2283 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2284 &state->outgoing_frag, 0)) {
2285 return NT_STATUS_NO_MEMORY;
2288 /* Copy in the data, plus any ss padding. */
2289 if (!prs_append_some_prs_data(&state->outgoing_frag,
2290 state->req_data, state->req_data_sent,
2291 data_sent_thistime)) {
2292 return NT_STATUS_NO_MEMORY;
2295 /* Copy the sign/seal padding data. */
2296 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2297 return NT_STATUS_NO_MEMORY;
2300 /* Generate any auth sign/seal and add the auth footer. */
2301 switch (state->cli->auth->auth_type) {
2302 case PIPE_AUTH_TYPE_NONE:
2303 status = NT_STATUS_OK;
2305 case PIPE_AUTH_TYPE_NTLMSSP:
2306 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2307 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2308 &state->outgoing_frag);
2310 case PIPE_AUTH_TYPE_SCHANNEL:
2311 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2312 &state->outgoing_frag);
2315 status = NT_STATUS_INVALID_PARAMETER;
2319 state->req_data_sent += data_sent_thistime;
2320 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2325 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2327 struct tevent_req *req = tevent_req_callback_data(
2328 subreq, struct tevent_req);
2329 struct rpc_api_pipe_req_state *state = tevent_req_data(
2330 req, struct rpc_api_pipe_req_state);
2334 status = rpc_write_recv(subreq);
2335 TALLOC_FREE(subreq);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 tevent_req_nterror(req, status);
2341 status = prepare_next_frag(state, &is_last_frag);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 tevent_req_nterror(req, status);
2348 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2349 &state->outgoing_frag,
2350 DCERPC_PKT_RESPONSE);
2351 if (tevent_req_nomem(subreq, req)) {
2354 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2356 subreq = rpc_write_send(
2358 state->cli->transport,
2359 (uint8_t *)prs_data_p(&state->outgoing_frag),
2360 prs_offset(&state->outgoing_frag));
2361 if (tevent_req_nomem(subreq, req)) {
2364 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2369 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2371 struct tevent_req *req = tevent_req_callback_data(
2372 subreq, struct tevent_req);
2373 struct rpc_api_pipe_req_state *state = tevent_req_data(
2374 req, struct rpc_api_pipe_req_state);
2377 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2378 TALLOC_FREE(subreq);
2379 if (!NT_STATUS_IS_OK(status)) {
2380 tevent_req_nterror(req, status);
2383 tevent_req_done(req);
2386 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2387 prs_struct *reply_pdu)
2389 struct rpc_api_pipe_req_state *state = tevent_req_data(
2390 req, struct rpc_api_pipe_req_state);
2393 if (tevent_req_is_nterror(req, &status)) {
2395 * We always have to initialize to reply pdu, even if there is
2396 * none. The rpccli_* caller routines expect this.
2398 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2402 *reply_pdu = state->reply_pdu;
2403 reply_pdu->mem_ctx = mem_ctx;
2406 * Prevent state->req_pdu from being freed in
2407 * rpc_api_pipe_req_state_destructor()
2409 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2411 return NT_STATUS_OK;
2415 /****************************************************************************
2416 Set the handle state.
2417 ****************************************************************************/
2419 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2420 const char *pipe_name, uint16 device_state)
2422 bool state_set = False;
2424 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2425 char *rparam = NULL;
2427 uint32 rparam_len, rdata_len;
2429 if (pipe_name == NULL)
2432 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2433 cli->fnum, pipe_name, device_state));
2435 /* create parameters: device state */
2436 SSVAL(param, 0, device_state);
2438 /* create setup parameters. */
2440 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2442 /* send the data on \PIPE\ */
2443 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2444 setup, 2, 0, /* setup, length, max */
2445 param, 2, 0, /* param, length, max */
2446 NULL, 0, 1024, /* data, length, max */
2447 &rparam, &rparam_len, /* return param, length */
2448 &rdata, &rdata_len)) /* return data, length */
2450 DEBUG(5, ("Set Handle state: return OK\n"));
2461 /****************************************************************************
2462 Check the rpc bind acknowledge response.
2463 ****************************************************************************/
2465 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2466 const struct ndr_syntax_id *transfer)
2468 if ( hdr_ba->addr.len == 0) {
2469 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2472 /* check the transfer syntax */
2473 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2474 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2475 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2479 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2480 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2481 hdr_ba->res.num_results, hdr_ba->res.reason));
2484 DEBUG(5,("check_bind_response: accepted!\n"));
2488 /*******************************************************************
2489 Creates a DCE/RPC bind authentication response.
2490 This is the packet that is sent back to the server once we
2491 have received a BIND-ACK, to finish the third leg of
2492 the authentication handshake.
2493 ********************************************************************/
2495 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2497 enum pipe_auth_type auth_type,
2498 enum dcerpc_AuthLevel auth_level,
2499 DATA_BLOB *pauth_blob,
2500 prs_struct *rpc_out)
2503 RPC_HDR_AUTH hdr_auth;
2506 /* Create the request RPC_HDR */
2507 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2508 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2509 pauth_blob->length );
2512 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2513 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2514 return NT_STATUS_NO_MEMORY;
2518 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2519 about padding - shouldn't this pad to length 8 ? JRA.
2522 /* 4 bytes padding. */
2523 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2524 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2525 return NT_STATUS_NO_MEMORY;
2528 /* Create the request RPC_HDR_AUTHA */
2529 init_rpc_hdr_auth(&hdr_auth,
2530 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2533 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2534 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2535 return NT_STATUS_NO_MEMORY;
2539 * Append the auth data to the outgoing buffer.
2542 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2543 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2544 return NT_STATUS_NO_MEMORY;
2547 return NT_STATUS_OK;
2550 /*******************************************************************
2551 Creates a DCE/RPC bind alter context authentication request which
2552 may contain a spnego auth blobl
2553 ********************************************************************/
2555 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2556 const struct ndr_syntax_id *abstract,
2557 const struct ndr_syntax_id *transfer,
2558 enum dcerpc_AuthLevel auth_level,
2559 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2560 prs_struct *rpc_out)
2562 RPC_HDR_AUTH hdr_auth;
2563 prs_struct auth_info;
2564 NTSTATUS ret = NT_STATUS_OK;
2566 ZERO_STRUCT(hdr_auth);
2567 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2568 return NT_STATUS_NO_MEMORY;
2570 /* We may change the pad length before marshalling. */
2571 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2573 if (pauth_blob->length) {
2574 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2575 prs_mem_free(&auth_info);
2576 return NT_STATUS_NO_MEMORY;
2580 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2587 prs_mem_free(&auth_info);
2591 /****************************************************************************
2593 ****************************************************************************/
2595 struct rpc_pipe_bind_state {
2596 struct event_context *ev;
2597 struct rpc_pipe_client *cli;
2599 uint32_t rpc_call_id;
2602 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2604 prs_mem_free(&state->rpc_out);
2608 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2609 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2610 struct rpc_pipe_bind_state *state,
2611 struct rpc_hdr_info *phdr,
2612 prs_struct *reply_pdu);
2613 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2614 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2615 struct rpc_pipe_bind_state *state,
2616 struct rpc_hdr_info *phdr,
2617 prs_struct *reply_pdu);
2618 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2620 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2621 struct event_context *ev,
2622 struct rpc_pipe_client *cli,
2623 struct cli_pipe_auth_data *auth)
2625 struct tevent_req *req, *subreq;
2626 struct rpc_pipe_bind_state *state;
2629 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2634 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2635 rpccli_pipe_txt(talloc_tos(), cli),
2636 (unsigned int)auth->auth_type,
2637 (unsigned int)auth->auth_level ));
2641 state->rpc_call_id = get_rpc_call_id();
2643 prs_init_empty(&state->rpc_out, state, MARSHALL);
2644 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2646 cli->auth = talloc_move(cli, &auth);
2648 /* Marshall the outgoing data. */
2649 status = create_rpc_bind_req(cli, &state->rpc_out,
2651 &cli->abstract_syntax,
2652 &cli->transfer_syntax,
2653 cli->auth->auth_type,
2654 cli->auth->auth_level);
2656 if (!NT_STATUS_IS_OK(status)) {
2660 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2661 DCERPC_PKT_BIND_ACK);
2662 if (subreq == NULL) {
2665 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2669 tevent_req_nterror(req, status);
2670 return tevent_req_post(req, ev);
2676 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2678 struct tevent_req *req = tevent_req_callback_data(
2679 subreq, struct tevent_req);
2680 struct rpc_pipe_bind_state *state = tevent_req_data(
2681 req, struct rpc_pipe_bind_state);
2682 prs_struct reply_pdu;
2683 struct rpc_hdr_info hdr;
2684 struct rpc_hdr_ba_info hdr_ba;
2687 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2688 TALLOC_FREE(subreq);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2691 rpccli_pipe_txt(talloc_tos(), state->cli),
2692 nt_errstr(status)));
2693 tevent_req_nterror(req, status);
2697 /* Unmarshall the RPC header */
2698 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2699 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2700 prs_mem_free(&reply_pdu);
2701 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2705 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2706 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2708 prs_mem_free(&reply_pdu);
2709 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2713 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2714 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2715 prs_mem_free(&reply_pdu);
2716 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2720 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2721 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2724 * For authenticated binds we may need to do 3 or 4 leg binds.
2727 switch(state->cli->auth->auth_type) {
2729 case PIPE_AUTH_TYPE_NONE:
2730 case PIPE_AUTH_TYPE_SCHANNEL:
2731 /* Bind complete. */
2732 prs_mem_free(&reply_pdu);
2733 tevent_req_done(req);
2736 case PIPE_AUTH_TYPE_NTLMSSP:
2737 /* Need to send AUTH3 packet - no reply. */
2738 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2740 prs_mem_free(&reply_pdu);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 tevent_req_nterror(req, status);
2746 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2747 /* Need to send alter context request and reply. */
2748 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2750 prs_mem_free(&reply_pdu);
2751 if (!NT_STATUS_IS_OK(status)) {
2752 tevent_req_nterror(req, status);
2756 case PIPE_AUTH_TYPE_KRB5:
2760 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2761 (unsigned int)state->cli->auth->auth_type));
2762 prs_mem_free(&reply_pdu);
2763 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2767 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2768 struct rpc_pipe_bind_state *state,
2769 struct rpc_hdr_info *phdr,
2770 prs_struct *reply_pdu)
2772 DATA_BLOB server_response = data_blob_null;
2773 DATA_BLOB client_reply = data_blob_null;
2774 struct rpc_hdr_auth_info hdr_auth;
2775 struct tevent_req *subreq;
2778 if ((phdr->auth_len == 0)
2779 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2780 return NT_STATUS_INVALID_PARAMETER;
2783 if (!prs_set_offset(
2785 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2786 return NT_STATUS_INVALID_PARAMETER;
2789 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2790 return NT_STATUS_INVALID_PARAMETER;
2793 /* TODO - check auth_type/auth_level match. */
2795 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2796 prs_copy_data_out((char *)server_response.data, reply_pdu,
2799 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2800 server_response, &client_reply);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2804 "blob failed: %s.\n", nt_errstr(status)));
2808 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2810 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2811 state->cli->auth->auth_type,
2812 state->cli->auth->auth_level,
2813 &client_reply, &state->rpc_out);
2814 data_blob_free(&client_reply);
2816 if (!NT_STATUS_IS_OK(status)) {
2820 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2821 (uint8_t *)prs_data_p(&state->rpc_out),
2822 prs_offset(&state->rpc_out));
2823 if (subreq == NULL) {
2824 return NT_STATUS_NO_MEMORY;
2826 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2827 return NT_STATUS_OK;
2830 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2832 struct tevent_req *req = tevent_req_callback_data(
2833 subreq, struct tevent_req);
2836 status = rpc_write_recv(subreq);
2837 TALLOC_FREE(subreq);
2838 if (!NT_STATUS_IS_OK(status)) {
2839 tevent_req_nterror(req, status);
2842 tevent_req_done(req);
2845 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2846 struct rpc_pipe_bind_state *state,
2847 struct rpc_hdr_info *phdr,
2848 prs_struct *reply_pdu)
2850 DATA_BLOB server_spnego_response = data_blob_null;
2851 DATA_BLOB server_ntlm_response = data_blob_null;
2852 DATA_BLOB client_reply = data_blob_null;
2853 DATA_BLOB tmp_blob = data_blob_null;
2854 RPC_HDR_AUTH hdr_auth;
2855 struct tevent_req *subreq;
2858 if ((phdr->auth_len == 0)
2859 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2860 return NT_STATUS_INVALID_PARAMETER;
2863 /* Process the returned NTLMSSP blob first. */
2864 if (!prs_set_offset(
2866 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2867 return NT_STATUS_INVALID_PARAMETER;
2870 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2871 return NT_STATUS_INVALID_PARAMETER;
2874 server_spnego_response = data_blob(NULL, phdr->auth_len);
2875 prs_copy_data_out((char *)server_spnego_response.data,
2876 reply_pdu, phdr->auth_len);
2879 * The server might give us back two challenges - tmp_blob is for the
2882 if (!spnego_parse_challenge(server_spnego_response,
2883 &server_ntlm_response, &tmp_blob)) {
2884 data_blob_free(&server_spnego_response);
2885 data_blob_free(&server_ntlm_response);
2886 data_blob_free(&tmp_blob);
2887 return NT_STATUS_INVALID_PARAMETER;
2890 /* We're finished with the server spnego response and the tmp_blob. */
2891 data_blob_free(&server_spnego_response);
2892 data_blob_free(&tmp_blob);
2894 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2895 server_ntlm_response, &client_reply);
2897 /* Finished with the server_ntlm response */
2898 data_blob_free(&server_ntlm_response);
2900 if (!NT_STATUS_IS_OK(status)) {
2901 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2902 "using server blob failed.\n"));
2903 data_blob_free(&client_reply);
2907 /* SPNEGO wrap the client reply. */
2908 tmp_blob = spnego_gen_auth(client_reply);
2909 data_blob_free(&client_reply);
2910 client_reply = tmp_blob;
2911 tmp_blob = data_blob_null;
2913 /* Now prepare the alter context pdu. */
2914 prs_init_empty(&state->rpc_out, state, MARSHALL);
2916 status = create_rpc_alter_context(state->rpc_call_id,
2917 &state->cli->abstract_syntax,
2918 &state->cli->transfer_syntax,
2919 state->cli->auth->auth_level,
2922 data_blob_free(&client_reply);
2924 if (!NT_STATUS_IS_OK(status)) {
2928 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2929 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2930 if (subreq == NULL) {
2931 return NT_STATUS_NO_MEMORY;
2933 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2934 return NT_STATUS_OK;
2937 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2939 struct tevent_req *req = tevent_req_callback_data(
2940 subreq, struct tevent_req);
2941 struct rpc_pipe_bind_state *state = tevent_req_data(
2942 req, struct rpc_pipe_bind_state);
2943 DATA_BLOB server_spnego_response = data_blob_null;
2944 DATA_BLOB tmp_blob = data_blob_null;
2945 prs_struct reply_pdu;
2946 struct rpc_hdr_info hdr;
2947 struct rpc_hdr_auth_info hdr_auth;
2950 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2951 TALLOC_FREE(subreq);
2952 if (!NT_STATUS_IS_OK(status)) {
2953 tevent_req_nterror(req, status);
2957 /* Get the auth blob from the reply. */
2958 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2959 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2960 "unmarshall RPC_HDR.\n"));
2961 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2965 if (!prs_set_offset(
2967 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2968 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2972 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2973 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2977 server_spnego_response = data_blob(NULL, hdr.auth_len);
2978 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2981 /* Check we got a valid auth response. */
2982 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2983 OID_NTLMSSP, &tmp_blob)) {
2984 data_blob_free(&server_spnego_response);
2985 data_blob_free(&tmp_blob);
2986 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2990 data_blob_free(&server_spnego_response);
2991 data_blob_free(&tmp_blob);
2993 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2994 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2995 tevent_req_done(req);
2998 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3000 return tevent_req_simple_recv_ntstatus(req);
3003 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3004 struct cli_pipe_auth_data *auth)
3006 TALLOC_CTX *frame = talloc_stackframe();
3007 struct event_context *ev;
3008 struct tevent_req *req;
3009 NTSTATUS status = NT_STATUS_OK;
3011 ev = event_context_init(frame);
3013 status = NT_STATUS_NO_MEMORY;
3017 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3019 status = NT_STATUS_NO_MEMORY;
3023 if (!tevent_req_poll(req, ev)) {
3024 status = map_nt_error_from_unix(errno);
3028 status = rpc_pipe_bind_recv(req);
3034 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3035 unsigned int timeout)
3037 struct cli_state *cli;
3039 if (rpc_cli->transport->transport == NCACN_NP) {
3040 cli = rpc_pipe_np_smb_conn(rpc_cli);
3044 return cli_set_timeout(cli, timeout);
3047 if (rpc_cli->transport->transport == NCACN_IP_TCP ||
3048 rpc_cli->transport->transport == NCALRPC) {
3049 return rpccli_set_sock_timeout(rpc_cli, timeout);
3052 if (rpc_cli->transport->transport == NCACN_INTERNAL) {
3053 cli = rpc_pipe_smbd_smb_conn(rpc_cli);
3057 return cli_set_timeout(cli, timeout);
3063 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3065 struct cli_state *cli;
3067 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3068 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3069 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3073 cli = rpc_pipe_np_smb_conn(rpc_cli);
3077 E_md4hash(cli->password ? cli->password : "", nt_hash);
3081 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3082 struct cli_pipe_auth_data **presult)
3084 struct cli_pipe_auth_data *result;
3086 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3087 if (result == NULL) {
3088 return NT_STATUS_NO_MEMORY;
3091 result->auth_type = PIPE_AUTH_TYPE_NONE;
3092 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3094 result->user_name = talloc_strdup(result, "");
3095 result->domain = talloc_strdup(result, "");
3096 if ((result->user_name == NULL) || (result->domain == NULL)) {
3097 TALLOC_FREE(result);
3098 return NT_STATUS_NO_MEMORY;
3102 return NT_STATUS_OK;
3105 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3107 ntlmssp_end(&auth->a_u.ntlmssp_state);
3111 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3112 enum pipe_auth_type auth_type,
3113 enum dcerpc_AuthLevel auth_level,
3115 const char *username,
3116 const char *password,
3117 struct cli_pipe_auth_data **presult)
3119 struct cli_pipe_auth_data *result;
3122 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3123 if (result == NULL) {
3124 return NT_STATUS_NO_MEMORY;
3127 result->auth_type = auth_type;
3128 result->auth_level = auth_level;
3130 result->user_name = talloc_strdup(result, username);
3131 result->domain = talloc_strdup(result, domain);
3132 if ((result->user_name == NULL) || (result->domain == NULL)) {
3133 status = NT_STATUS_NO_MEMORY;
3137 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3138 if (!NT_STATUS_IS_OK(status)) {
3142 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3144 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3145 if (!NT_STATUS_IS_OK(status)) {
3149 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3150 if (!NT_STATUS_IS_OK(status)) {
3154 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3155 if (!NT_STATUS_IS_OK(status)) {
3160 * Turn off sign+seal to allow selected auth level to turn it back on.
3162 result->a_u.ntlmssp_state->neg_flags &=
3163 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3165 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3166 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3167 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3168 result->a_u.ntlmssp_state->neg_flags
3169 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3173 return NT_STATUS_OK;
3176 TALLOC_FREE(result);
3180 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3181 enum dcerpc_AuthLevel auth_level,
3182 struct netlogon_creds_CredentialState *creds,
3183 struct cli_pipe_auth_data **presult)
3185 struct cli_pipe_auth_data *result;
3187 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3188 if (result == NULL) {
3189 return NT_STATUS_NO_MEMORY;
3192 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3193 result->auth_level = auth_level;
3195 result->user_name = talloc_strdup(result, "");
3196 result->domain = talloc_strdup(result, domain);
3197 if ((result->user_name == NULL) || (result->domain == NULL)) {
3201 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3202 if (result->a_u.schannel_auth == NULL) {
3206 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3207 result->a_u.schannel_auth->seq_num = 0;
3208 result->a_u.schannel_auth->initiator = true;
3209 result->a_u.schannel_auth->creds = creds;
3212 return NT_STATUS_OK;
3215 TALLOC_FREE(result);
3216 return NT_STATUS_NO_MEMORY;
3220 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3222 data_blob_free(&auth->session_key);
3227 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3228 enum dcerpc_AuthLevel auth_level,
3229 const char *service_princ,
3230 const char *username,
3231 const char *password,
3232 struct cli_pipe_auth_data **presult)
3235 struct cli_pipe_auth_data *result;
3237 if ((username != NULL) && (password != NULL)) {
3238 int ret = kerberos_kinit_password(username, password, 0, NULL);
3240 return NT_STATUS_ACCESS_DENIED;
3244 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3245 if (result == NULL) {
3246 return NT_STATUS_NO_MEMORY;
3249 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3250 result->auth_level = auth_level;
3253 * Username / domain need fixing!
3255 result->user_name = talloc_strdup(result, "");
3256 result->domain = talloc_strdup(result, "");
3257 if ((result->user_name == NULL) || (result->domain == NULL)) {
3261 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3262 result, struct kerberos_auth_struct);
3263 if (result->a_u.kerberos_auth == NULL) {
3266 talloc_set_destructor(result->a_u.kerberos_auth,
3267 cli_auth_kerberos_data_destructor);
3269 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3270 result, service_princ);
3271 if (result->a_u.kerberos_auth->service_principal == NULL) {
3276 return NT_STATUS_OK;
3279 TALLOC_FREE(result);
3280 return NT_STATUS_NO_MEMORY;
3282 return NT_STATUS_NOT_SUPPORTED;
3287 * Create an rpc pipe client struct, connecting to a tcp port.
3289 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3291 const struct ndr_syntax_id *abstract_syntax,
3292 struct rpc_pipe_client **presult)
3294 struct rpc_pipe_client *result;
3295 struct sockaddr_storage addr;
3299 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3300 if (result == NULL) {
3301 return NT_STATUS_NO_MEMORY;
3304 result->abstract_syntax = *abstract_syntax;
3305 result->transfer_syntax = ndr_transfer_syntax;
3306 result->dispatch = cli_do_rpc_ndr;
3307 result->dispatch_send = cli_do_rpc_ndr_send;
3308 result->dispatch_recv = cli_do_rpc_ndr_recv;
3310 result->desthost = talloc_strdup(result, host);
3311 result->srv_name_slash = talloc_asprintf_strupper_m(
3312 result, "\\\\%s", result->desthost);
3313 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3314 status = NT_STATUS_NO_MEMORY;
3318 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3319 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3321 if (!resolve_name(host, &addr, 0, false)) {
3322 status = NT_STATUS_NOT_FOUND;
3326 status = open_socket_out(&addr, port, 60, &fd);
3327 if (!NT_STATUS_IS_OK(status)) {
3330 set_socket_options(fd, lp_socket_options());
3332 status = rpc_transport_sock_init(result, fd, &result->transport);
3333 if (!NT_STATUS_IS_OK(status)) {
3338 result->transport->transport = NCACN_IP_TCP;
3341 return NT_STATUS_OK;
3344 TALLOC_FREE(result);
3349 * Determine the tcp port on which a dcerpc interface is listening
3350 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3353 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3354 const struct ndr_syntax_id *abstract_syntax,
3358 struct rpc_pipe_client *epm_pipe = NULL;
3359 struct cli_pipe_auth_data *auth = NULL;
3360 struct dcerpc_binding *map_binding = NULL;
3361 struct dcerpc_binding *res_binding = NULL;
3362 struct epm_twr_t *map_tower = NULL;
3363 struct epm_twr_t *res_towers = NULL;
3364 struct policy_handle *entry_handle = NULL;
3365 uint32_t num_towers = 0;
3366 uint32_t max_towers = 1;
3367 struct epm_twr_p_t towers;
3368 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3370 if (pport == NULL) {
3371 status = NT_STATUS_INVALID_PARAMETER;
3375 /* open the connection to the endpoint mapper */
3376 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3377 &ndr_table_epmapper.syntax_id,
3380 if (!NT_STATUS_IS_OK(status)) {
3384 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3385 if (!NT_STATUS_IS_OK(status)) {
3389 status = rpc_pipe_bind(epm_pipe, auth);
3390 if (!NT_STATUS_IS_OK(status)) {
3394 /* create tower for asking the epmapper */
3396 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3397 if (map_binding == NULL) {
3398 status = NT_STATUS_NO_MEMORY;
3402 map_binding->transport = NCACN_IP_TCP;
3403 map_binding->object = *abstract_syntax;
3404 map_binding->host = host; /* needed? */
3405 map_binding->endpoint = "0"; /* correct? needed? */
3407 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3408 if (map_tower == NULL) {
3409 status = NT_STATUS_NO_MEMORY;
3413 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3414 &(map_tower->tower));
3415 if (!NT_STATUS_IS_OK(status)) {
3419 /* allocate further parameters for the epm_Map call */
3421 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3422 if (res_towers == NULL) {
3423 status = NT_STATUS_NO_MEMORY;
3426 towers.twr = res_towers;
3428 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3429 if (entry_handle == NULL) {
3430 status = NT_STATUS_NO_MEMORY;
3434 /* ask the endpoint mapper for the port */
3436 status = rpccli_epm_Map(epm_pipe,
3438 CONST_DISCARD(struct GUID *,
3439 &(abstract_syntax->uuid)),
3446 if (!NT_STATUS_IS_OK(status)) {
3450 if (num_towers != 1) {
3451 status = NT_STATUS_UNSUCCESSFUL;
3455 /* extract the port from the answer */
3457 status = dcerpc_binding_from_tower(tmp_ctx,
3458 &(towers.twr->tower),
3460 if (!NT_STATUS_IS_OK(status)) {
3464 /* are further checks here necessary? */
3465 if (res_binding->transport != NCACN_IP_TCP) {
3466 status = NT_STATUS_UNSUCCESSFUL;
3470 *pport = (uint16_t)atoi(res_binding->endpoint);
3473 TALLOC_FREE(tmp_ctx);
3478 * Create a rpc pipe client struct, connecting to a host via tcp.
3479 * The port is determined by asking the endpoint mapper on the given
3482 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3483 const struct ndr_syntax_id *abstract_syntax,
3484 struct rpc_pipe_client **presult)
3489 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3490 if (!NT_STATUS_IS_OK(status)) {
3494 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3495 abstract_syntax, presult);
3498 /********************************************************************
3499 Create a rpc pipe client struct, connecting to a unix domain socket
3500 ********************************************************************/
3501 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3502 const struct ndr_syntax_id *abstract_syntax,
3503 struct rpc_pipe_client **presult)
3505 struct rpc_pipe_client *result;
3506 struct sockaddr_un addr;
3510 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3511 if (result == NULL) {
3512 return NT_STATUS_NO_MEMORY;
3515 result->abstract_syntax = *abstract_syntax;
3516 result->transfer_syntax = ndr_transfer_syntax;
3517 result->dispatch = cli_do_rpc_ndr;
3518 result->dispatch_send = cli_do_rpc_ndr_send;
3519 result->dispatch_recv = cli_do_rpc_ndr_recv;
3521 result->desthost = get_myname(result);
3522 result->srv_name_slash = talloc_asprintf_strupper_m(
3523 result, "\\\\%s", result->desthost);
3524 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3525 status = NT_STATUS_NO_MEMORY;
3529 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3530 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3532 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3534 status = map_nt_error_from_unix(errno);
3539 addr.sun_family = AF_UNIX;
3540 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3542 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3543 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3546 return map_nt_error_from_unix(errno);
3549 status = rpc_transport_sock_init(result, fd, &result->transport);
3550 if (!NT_STATUS_IS_OK(status)) {
3555 result->transport->transport = NCALRPC;
3558 return NT_STATUS_OK;
3561 TALLOC_FREE(result);
3565 struct rpc_pipe_client_np_ref {
3566 struct cli_state *cli;
3567 struct rpc_pipe_client *pipe;
3570 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3572 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3576 /****************************************************************************
3577 Open a named pipe over SMB to a remote server.
3579 * CAVEAT CALLER OF THIS FUNCTION:
3580 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3581 * so be sure that this function is called AFTER any structure (vs pointer)
3582 * assignment of the cli. In particular, libsmbclient does structure
3583 * assignments of cli, which invalidates the data in the returned
3584 * rpc_pipe_client if this function is called before the structure assignment
3587 ****************************************************************************/
3589 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3590 const struct ndr_syntax_id *abstract_syntax,
3591 struct rpc_pipe_client **presult)
3593 struct rpc_pipe_client *result;
3595 struct rpc_pipe_client_np_ref *np_ref;
3597 /* sanity check to protect against crashes */
3600 return NT_STATUS_INVALID_HANDLE;
3603 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3604 if (result == NULL) {
3605 return NT_STATUS_NO_MEMORY;
3608 result->abstract_syntax = *abstract_syntax;
3609 result->transfer_syntax = ndr_transfer_syntax;
3610 result->dispatch = cli_do_rpc_ndr;
3611 result->dispatch_send = cli_do_rpc_ndr_send;
3612 result->dispatch_recv = cli_do_rpc_ndr_recv;
3613 result->desthost = talloc_strdup(result, cli->desthost);
3614 result->srv_name_slash = talloc_asprintf_strupper_m(
3615 result, "\\\\%s", result->desthost);
3617 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3618 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3620 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3621 TALLOC_FREE(result);
3622 return NT_STATUS_NO_MEMORY;
3625 status = rpc_transport_np_init(result, cli, abstract_syntax,
3626 &result->transport);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 TALLOC_FREE(result);
3632 result->transport->transport = NCACN_NP;
3634 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3635 if (np_ref == NULL) {
3636 TALLOC_FREE(result);
3637 return NT_STATUS_NO_MEMORY;
3640 np_ref->pipe = result;
3642 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3643 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3646 return NT_STATUS_OK;
3649 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3650 struct rpc_cli_smbd_conn *conn,
3651 const struct ndr_syntax_id *syntax,
3652 struct rpc_pipe_client **presult)
3654 struct rpc_pipe_client *result;
3655 struct cli_pipe_auth_data *auth;
3658 result = talloc(mem_ctx, struct rpc_pipe_client);
3659 if (result == NULL) {
3660 return NT_STATUS_NO_MEMORY;
3662 result->abstract_syntax = *syntax;
3663 result->transfer_syntax = ndr_transfer_syntax;
3664 result->dispatch = cli_do_rpc_ndr;
3665 result->dispatch_send = cli_do_rpc_ndr_send;
3666 result->dispatch_recv = cli_do_rpc_ndr_recv;
3667 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3668 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3670 result->desthost = talloc_strdup(result, global_myname());
3671 result->srv_name_slash = talloc_asprintf_strupper_m(
3672 result, "\\\\%s", global_myname());
3673 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3674 TALLOC_FREE(result);
3675 return NT_STATUS_NO_MEMORY;
3678 status = rpc_transport_smbd_init(result, conn, syntax,
3679 &result->transport);
3680 if (!NT_STATUS_IS_OK(status)) {
3681 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3682 nt_errstr(status)));
3683 TALLOC_FREE(result);
3687 status = rpccli_anon_bind_data(result, &auth);
3688 if (!NT_STATUS_IS_OK(status)) {
3689 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3690 nt_errstr(status)));
3691 TALLOC_FREE(result);
3695 status = rpc_pipe_bind(result, auth);
3696 if (!NT_STATUS_IS_OK(status)) {
3697 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3698 TALLOC_FREE(result);
3702 result->transport->transport = NCACN_INTERNAL;
3705 return NT_STATUS_OK;
3708 /****************************************************************************
3709 Open a pipe to a remote server.
3710 ****************************************************************************/
3712 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3713 enum dcerpc_transport_t transport,
3714 const struct ndr_syntax_id *interface,
3715 struct rpc_pipe_client **presult)
3717 switch (transport) {
3719 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3722 return rpc_pipe_open_np(cli, interface, presult);
3724 return NT_STATUS_NOT_IMPLEMENTED;
3728 /****************************************************************************
3729 Open a named pipe to an SMB server and bind anonymously.
3730 ****************************************************************************/
3732 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3733 enum dcerpc_transport_t transport,
3734 const struct ndr_syntax_id *interface,
3735 struct rpc_pipe_client **presult)
3737 struct rpc_pipe_client *result;
3738 struct cli_pipe_auth_data *auth;
3741 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3742 if (!NT_STATUS_IS_OK(status)) {
3746 status = rpccli_anon_bind_data(result, &auth);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3749 nt_errstr(status)));
3750 TALLOC_FREE(result);
3755 * This is a bit of an abstraction violation due to the fact that an
3756 * anonymous bind on an authenticated SMB inherits the user/domain
3757 * from the enclosing SMB creds
3760 TALLOC_FREE(auth->user_name);
3761 TALLOC_FREE(auth->domain);
3763 auth->user_name = talloc_strdup(auth, cli->user_name);
3764 auth->domain = talloc_strdup(auth, cli->domain);
3765 auth->user_session_key = data_blob_talloc(auth,
3766 cli->user_session_key.data,
3767 cli->user_session_key.length);
3769 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3770 TALLOC_FREE(result);
3771 return NT_STATUS_NO_MEMORY;
3774 status = rpc_pipe_bind(result, auth);
3775 if (!NT_STATUS_IS_OK(status)) {
3777 if (ndr_syntax_id_equal(interface,
3778 &ndr_table_dssetup.syntax_id)) {
3779 /* non AD domains just don't have this pipe, avoid
3780 * level 0 statement in that case - gd */
3783 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3784 "%s failed with error %s\n",
3785 get_pipe_name_from_syntax(talloc_tos(), interface),
3786 nt_errstr(status) ));
3787 TALLOC_FREE(result);
3791 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3792 "%s and bound anonymously.\n",
3793 get_pipe_name_from_syntax(talloc_tos(), interface),
3797 return NT_STATUS_OK;
3800 /****************************************************************************
3801 ****************************************************************************/
3803 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3804 const struct ndr_syntax_id *interface,
3805 struct rpc_pipe_client **presult)
3807 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3808 interface, presult);
3811 /****************************************************************************
3812 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3813 ****************************************************************************/
3815 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3816 const struct ndr_syntax_id *interface,
3817 enum dcerpc_transport_t transport,
3818 enum pipe_auth_type auth_type,
3819 enum dcerpc_AuthLevel auth_level,
3821 const char *username,
3822 const char *password,
3823 struct rpc_pipe_client **presult)
3825 struct rpc_pipe_client *result;
3826 struct cli_pipe_auth_data *auth;
3829 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3830 if (!NT_STATUS_IS_OK(status)) {
3834 status = rpccli_ntlmssp_bind_data(
3835 result, auth_type, auth_level, domain, username,
3837 if (!NT_STATUS_IS_OK(status)) {
3838 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3839 nt_errstr(status)));
3843 status = rpc_pipe_bind(result, auth);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3846 nt_errstr(status) ));
3850 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3851 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3852 get_pipe_name_from_syntax(talloc_tos(), interface),
3853 cli->desthost, domain, username ));
3856 return NT_STATUS_OK;
3860 TALLOC_FREE(result);
3864 /****************************************************************************
3866 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3867 ****************************************************************************/
3869 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3870 const struct ndr_syntax_id *interface,
3871 enum dcerpc_transport_t transport,
3872 enum dcerpc_AuthLevel auth_level,
3874 const char *username,
3875 const char *password,
3876 struct rpc_pipe_client **presult)
3878 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3881 PIPE_AUTH_TYPE_NTLMSSP,
3889 /****************************************************************************
3891 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3892 ****************************************************************************/
3894 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3895 const struct ndr_syntax_id *interface,
3896 enum dcerpc_transport_t transport,
3897 enum dcerpc_AuthLevel auth_level,
3899 const char *username,
3900 const char *password,
3901 struct rpc_pipe_client **presult)
3903 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3906 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3914 /****************************************************************************
3915 Get a the schannel session key out of an already opened netlogon pipe.
3916 ****************************************************************************/
3917 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3918 struct cli_state *cli,
3922 enum netr_SchannelType sec_chan_type = 0;
3923 unsigned char machine_pwd[16];
3924 const char *machine_account;
3927 /* Get the machine account credentials from secrets.tdb. */
3928 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3931 DEBUG(0, ("get_schannel_session_key: could not fetch "
3932 "trust account password for domain '%s'\n",
3934 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3937 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3938 cli->desthost, /* server name */
3939 domain, /* domain */
3940 global_myname(), /* client name */
3941 machine_account, /* machine account name */
3946 if (!NT_STATUS_IS_OK(status)) {
3947 DEBUG(3, ("get_schannel_session_key_common: "
3948 "rpccli_netlogon_setup_creds failed with result %s "
3949 "to server %s, domain %s, machine account %s.\n",
3950 nt_errstr(status), cli->desthost, domain,
3955 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3956 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3958 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3961 return NT_STATUS_OK;;
3964 /****************************************************************************
3965 Open a netlogon pipe and get the schannel session key.
3966 Now exposed to external callers.
3967 ****************************************************************************/
3970 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3973 struct rpc_pipe_client **presult)
3975 struct rpc_pipe_client *netlogon_pipe = NULL;
3978 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3980 if (!NT_STATUS_IS_OK(status)) {
3984 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3986 if (!NT_STATUS_IS_OK(status)) {
3987 TALLOC_FREE(netlogon_pipe);
3991 *presult = netlogon_pipe;
3992 return NT_STATUS_OK;
3995 /****************************************************************************
3997 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3998 using session_key. sign and seal.
4000 The *pdc will be stolen onto this new pipe
4001 ****************************************************************************/
4003 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4004 const struct ndr_syntax_id *interface,
4005 enum dcerpc_transport_t transport,
4006 enum dcerpc_AuthLevel auth_level,
4008 struct netlogon_creds_CredentialState **pdc,
4009 struct rpc_pipe_client **presult)
4011 struct rpc_pipe_client *result;
4012 struct cli_pipe_auth_data *auth;
4015 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4016 if (!NT_STATUS_IS_OK(status)) {
4020 status = rpccli_schannel_bind_data(result, domain, auth_level,
4022 if (!NT_STATUS_IS_OK(status)) {
4023 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4024 nt_errstr(status)));
4025 TALLOC_FREE(result);
4029 status = rpc_pipe_bind(result, auth);
4030 if (!NT_STATUS_IS_OK(status)) {
4031 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4032 "cli_rpc_pipe_bind failed with error %s\n",
4033 nt_errstr(status) ));
4034 TALLOC_FREE(result);
4039 * The credentials on a new netlogon pipe are the ones we are passed
4040 * in - reference them in
4042 result->dc = talloc_move(result, pdc);
4044 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4045 "for domain %s and bound using schannel.\n",
4046 get_pipe_name_from_syntax(talloc_tos(), interface),
4047 cli->desthost, domain ));
4050 return NT_STATUS_OK;
4053 /****************************************************************************
4054 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4055 Fetch the session key ourselves using a temporary netlogon pipe. This
4056 version uses an ntlmssp auth bound netlogon pipe to get the key.
4057 ****************************************************************************/
4059 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4061 const char *username,
4062 const char *password,
4064 struct rpc_pipe_client **presult)
4066 struct rpc_pipe_client *netlogon_pipe = NULL;
4069 status = cli_rpc_pipe_open_spnego_ntlmssp(
4070 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4071 DCERPC_AUTH_LEVEL_PRIVACY,
4072 domain, username, password, &netlogon_pipe);
4073 if (!NT_STATUS_IS_OK(status)) {
4077 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4079 if (!NT_STATUS_IS_OK(status)) {
4080 TALLOC_FREE(netlogon_pipe);
4084 *presult = netlogon_pipe;
4085 return NT_STATUS_OK;
4088 /****************************************************************************
4089 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4090 Fetch the session key ourselves using a temporary netlogon pipe. This version
4091 uses an ntlmssp bind to get the session key.
4092 ****************************************************************************/
4094 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4095 const struct ndr_syntax_id *interface,
4096 enum dcerpc_transport_t transport,
4097 enum dcerpc_AuthLevel auth_level,
4099 const char *username,
4100 const char *password,
4101 struct rpc_pipe_client **presult)
4103 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4104 struct rpc_pipe_client *netlogon_pipe = NULL;
4105 struct rpc_pipe_client *result = NULL;
4108 status = get_schannel_session_key_auth_ntlmssp(
4109 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4112 "key from server %s for domain %s.\n",
4113 cli->desthost, domain ));
4117 status = cli_rpc_pipe_open_schannel_with_key(
4118 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4121 /* Now we've bound using the session key we can close the netlog pipe. */
4122 TALLOC_FREE(netlogon_pipe);
4124 if (NT_STATUS_IS_OK(status)) {
4130 /****************************************************************************
4131 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4132 Fetch the session key ourselves using a temporary netlogon pipe.
4133 ****************************************************************************/
4135 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4136 const struct ndr_syntax_id *interface,
4137 enum dcerpc_transport_t transport,
4138 enum dcerpc_AuthLevel auth_level,
4140 struct rpc_pipe_client **presult)
4142 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4143 struct rpc_pipe_client *netlogon_pipe = NULL;
4144 struct rpc_pipe_client *result = NULL;
4147 status = get_schannel_session_key(cli, domain, &neg_flags,
4149 if (!NT_STATUS_IS_OK(status)) {
4150 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4151 "key from server %s for domain %s.\n",
4152 cli->desthost, domain ));
4156 status = cli_rpc_pipe_open_schannel_with_key(
4157 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4160 /* Now we've bound using the session key we can close the netlog pipe. */
4161 TALLOC_FREE(netlogon_pipe);
4163 if (NT_STATUS_IS_OK(status)) {
4170 /****************************************************************************
4171 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4172 The idea is this can be called with service_princ, username and password all
4173 NULL so long as the caller has a TGT.
4174 ****************************************************************************/
4176 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4177 const struct ndr_syntax_id *interface,
4178 enum dcerpc_AuthLevel auth_level,
4179 const char *service_princ,
4180 const char *username,
4181 const char *password,
4182 struct rpc_pipe_client **presult)
4185 struct rpc_pipe_client *result;
4186 struct cli_pipe_auth_data *auth;
4189 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4190 if (!NT_STATUS_IS_OK(status)) {
4194 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4195 username, password, &auth);
4196 if (!NT_STATUS_IS_OK(status)) {
4197 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4198 nt_errstr(status)));
4199 TALLOC_FREE(result);
4203 status = rpc_pipe_bind(result, auth);
4204 if (!NT_STATUS_IS_OK(status)) {
4205 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4206 "with error %s\n", nt_errstr(status)));
4207 TALLOC_FREE(result);
4212 return NT_STATUS_OK;
4214 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4215 return NT_STATUS_NOT_IMPLEMENTED;
4219 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4220 struct rpc_pipe_client *cli,
4221 DATA_BLOB *session_key)
4223 if (!session_key || !cli) {
4224 return NT_STATUS_INVALID_PARAMETER;
4228 return NT_STATUS_INVALID_PARAMETER;
4231 switch (cli->auth->auth_type) {
4232 case PIPE_AUTH_TYPE_SCHANNEL:
4233 *session_key = data_blob_talloc(mem_ctx,
4234 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4236 case PIPE_AUTH_TYPE_NTLMSSP:
4237 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4238 *session_key = data_blob_talloc(mem_ctx,
4239 cli->auth->a_u.ntlmssp_state->session_key.data,
4240 cli->auth->a_u.ntlmssp_state->session_key.length);
4242 case PIPE_AUTH_TYPE_KRB5:
4243 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4244 *session_key = data_blob_talloc(mem_ctx,
4245 cli->auth->a_u.kerberos_auth->session_key.data,
4246 cli->auth->a_u.kerberos_auth->session_key.length);
4248 case PIPE_AUTH_TYPE_NONE:
4249 *session_key = data_blob_talloc(mem_ctx,
4250 cli->auth->user_session_key.data,
4251 cli->auth->user_session_key.length);
4254 return NT_STATUS_NO_USER_SESSION_KEY;
4257 return NT_STATUS_OK;