s3-dcerpc: use dcerpc_pull_dcerpc_auth() in cli_pipe_verify_ntlmssp().
[Samba/vl.git] / source3 / rpc_client / cli_pipe.c
blob8f74488eb974594d5dd89d096459a1857e3d43c1
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
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/>.
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_samr.h"
26 #include "../librpc/gen_ndr/ndr_netlogon.h"
27 #include "../librpc/gen_ndr/ndr_srvsvc.h"
28 #include "../librpc/gen_ndr/ndr_wkssvc.h"
29 #include "../librpc/gen_ndr/ndr_winreg.h"
30 #include "../librpc/gen_ndr/ndr_spoolss.h"
31 #include "../librpc/gen_ndr/ndr_dfs.h"
32 #include "../librpc/gen_ndr/ndr_echo.h"
33 #include "../librpc/gen_ndr/ndr_initshutdown.h"
34 #include "../librpc/gen_ndr/ndr_svcctl.h"
35 #include "../librpc/gen_ndr/ndr_eventlog.h"
36 #include "../librpc/gen_ndr/ndr_ntsvcs.h"
37 #include "../librpc/gen_ndr/ndr_epmapper.h"
38 #include "../librpc/gen_ndr/ndr_drsuapi.h"
39 #include "../libcli/auth/schannel.h"
40 #include "../libcli/auth/spnego.h"
41 #include "smb_krb5.h"
42 #include "../libcli/auth/ntlmssp.h"
43 #include "rpc_client/cli_netlogon.h"
44 #include "librpc/gen_ndr/ndr_dcerpc.h"
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_RPC_CLI
49 static const char *get_pipe_name_from_iface(
50 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
52 int i;
53 const struct ndr_interface_string_array *ep = interface->endpoints;
54 char *p;
56 for (i=0; i<ep->count; i++) {
57 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
58 break;
61 if (i == ep->count) {
62 return NULL;
66 * extract the pipe name without \\pipe from for example
67 * ncacn_np:[\\pipe\\epmapper]
69 p = strchr(ep->names[i]+15, ']');
70 if (p == NULL) {
71 return "PIPE";
73 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
76 static const struct ndr_interface_table **interfaces;
78 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
80 int num_interfaces = talloc_array_length(interfaces);
81 const struct ndr_interface_table **tmp;
82 int i;
84 for (i=0; i<num_interfaces; i++) {
85 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
86 &interface->syntax_id)) {
87 return true;
91 tmp = talloc_realloc(NULL, interfaces,
92 const struct ndr_interface_table *,
93 num_interfaces + 1);
94 if (tmp == NULL) {
95 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
96 return false;
98 interfaces = tmp;
99 interfaces[num_interfaces] = interface;
100 return true;
103 static bool initialize_interfaces(void)
105 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
106 return false;
108 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
109 return false;
111 if (!smb_register_ndr_interface(&ndr_table_samr)) {
112 return false;
114 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
115 return false;
117 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
118 return false;
120 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
121 return false;
123 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
124 return false;
126 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
127 return false;
129 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
130 return false;
132 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
133 return false;
135 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
136 return false;
138 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
139 return false;
141 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
142 return false;
144 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
145 return false;
147 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
148 return false;
150 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
151 return false;
153 return true;
156 const struct ndr_interface_table *get_iface_from_syntax(
157 const struct ndr_syntax_id *syntax)
159 int num_interfaces;
160 int i;
162 if (interfaces == NULL) {
163 if (!initialize_interfaces()) {
164 return NULL;
167 num_interfaces = talloc_array_length(interfaces);
169 for (i=0; i<num_interfaces; i++) {
170 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
171 return interfaces[i];
175 return NULL;
178 /****************************************************************************
179 Return the pipe name from the interface.
180 ****************************************************************************/
182 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
183 const struct ndr_syntax_id *syntax)
185 const struct ndr_interface_table *interface;
186 char *guid_str;
187 const char *result;
189 interface = get_iface_from_syntax(syntax);
190 if (interface != NULL) {
191 result = get_pipe_name_from_iface(mem_ctx, interface);
192 if (result != NULL) {
193 return result;
198 * Here we should ask \\epmapper, but for now our code is only
199 * interested in the known pipes mentioned in pipe_names[]
202 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
203 if (guid_str == NULL) {
204 return NULL;
206 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
207 (int)syntax->if_version);
208 TALLOC_FREE(guid_str);
210 if (result == NULL) {
211 return "PIPE";
213 return result;
216 /********************************************************************
217 Map internal value to wire value.
218 ********************************************************************/
220 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
222 switch (auth_type) {
224 case PIPE_AUTH_TYPE_NONE:
225 return DCERPC_AUTH_TYPE_NONE;
227 case PIPE_AUTH_TYPE_NTLMSSP:
228 return DCERPC_AUTH_TYPE_NTLMSSP;
230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
231 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
232 return DCERPC_AUTH_TYPE_SPNEGO;
234 case PIPE_AUTH_TYPE_SCHANNEL:
235 return DCERPC_AUTH_TYPE_SCHANNEL;
237 case PIPE_AUTH_TYPE_KRB5:
238 return DCERPC_AUTH_TYPE_KRB5;
240 default:
241 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
242 "auth type %u\n",
243 (unsigned int)auth_type ));
244 break;
246 return -1;
249 /********************************************************************
250 Pipe description for a DEBUG
251 ********************************************************************/
252 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
253 struct rpc_pipe_client *cli)
255 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
256 if (result == NULL) {
257 return "pipe";
259 return result;
262 /********************************************************************
263 Rpc pipe call id.
264 ********************************************************************/
266 static uint32 get_rpc_call_id(void)
268 static uint32 call_id = 0;
269 return ++call_id;
273 * Realloc pdu to have a least "size" bytes
276 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
278 size_t extra_size;
280 if (prs_data_size(pdu) >= size) {
281 return true;
284 extra_size = size - prs_data_size(pdu);
286 if (!prs_force_grow(pdu, extra_size)) {
287 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
288 "%d bytes.\n", (int)extra_size));
289 return false;
292 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
293 (int)extra_size, prs_data_size(pdu)));
294 return true;
297 /*******************************************************************
298 *******************************************************************/
300 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
301 enum dcerpc_pkt_type ptype,
302 uint8_t pfc_flags,
303 uint16_t frag_length,
304 uint16_t auth_length,
305 uint32_t call_id,
306 union dcerpc_payload u,
307 DATA_BLOB *blob)
309 struct ncacn_packet r;
310 enum ndr_err_code ndr_err;
312 r.rpc_vers = 5;
313 r.rpc_vers_minor = 0;
314 r.ptype = ptype;
315 r.pfc_flags = pfc_flags;
316 r.drep[0] = DCERPC_DREP_LE;
317 r.drep[1] = 0;
318 r.drep[2] = 0;
319 r.drep[3] = 0;
320 r.frag_length = frag_length;
321 r.auth_length = auth_length;
322 r.call_id = call_id;
323 r.u = u;
325 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
326 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
328 return ndr_map_error2ntstatus(ndr_err);
331 if (DEBUGLEVEL >= 10) {
332 NDR_PRINT_DEBUG(ncacn_packet, &r);
335 return NT_STATUS_OK;
338 /*******************************************************************
339 *******************************************************************/
341 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
342 const DATA_BLOB *blob,
343 struct ncacn_packet *r)
345 enum ndr_err_code ndr_err;
347 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
348 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
350 return ndr_map_error2ntstatus(ndr_err);
353 if (DEBUGLEVEL >= 10) {
354 NDR_PRINT_DEBUG(ncacn_packet, r);
357 return NT_STATUS_OK;
360 /*******************************************************************
361 *******************************************************************/
363 NTSTATUS dcerpc_pull_ncacn_packet_header(TALLOC_CTX *mem_ctx,
364 const DATA_BLOB *blob,
365 struct ncacn_packet_header *r)
367 enum ndr_err_code ndr_err;
369 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
370 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet_header);
371 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
372 return ndr_map_error2ntstatus(ndr_err);
375 if (DEBUGLEVEL >= 10) {
376 NDR_PRINT_DEBUG(ncacn_packet_header, r);
379 return NT_STATUS_OK;
382 /*******************************************************************
383 ********************************************************************/
385 static NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
386 struct NL_AUTH_MESSAGE *r,
387 DATA_BLOB *blob)
389 enum ndr_err_code ndr_err;
391 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
392 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
393 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
394 return ndr_map_error2ntstatus(ndr_err);
397 if (DEBUGLEVEL >= 10) {
398 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
401 return NT_STATUS_OK;
404 /*******************************************************************
405 ********************************************************************/
407 static NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
408 const DATA_BLOB *blob,
409 struct dcerpc_auth *r)
411 enum ndr_err_code ndr_err;
413 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
414 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
415 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
416 return ndr_map_error2ntstatus(ndr_err);
419 if (DEBUGLEVEL >= 10) {
420 NDR_PRINT_DEBUG(dcerpc_auth, r);
423 return NT_STATUS_OK;
426 /*******************************************************************
427 Use SMBreadX to get rest of one fragment's worth of rpc data.
428 Reads the whole size or give an error message
429 ********************************************************************/
431 struct rpc_read_state {
432 struct event_context *ev;
433 struct rpc_cli_transport *transport;
434 uint8_t *data;
435 size_t size;
436 size_t num_read;
439 static void rpc_read_done(struct tevent_req *subreq);
441 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
442 struct event_context *ev,
443 struct rpc_cli_transport *transport,
444 uint8_t *data, size_t size)
446 struct tevent_req *req, *subreq;
447 struct rpc_read_state *state;
449 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
450 if (req == NULL) {
451 return NULL;
453 state->ev = ev;
454 state->transport = transport;
455 state->data = data;
456 state->size = size;
457 state->num_read = 0;
459 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
461 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
462 transport->priv);
463 if (subreq == NULL) {
464 goto fail;
466 tevent_req_set_callback(subreq, rpc_read_done, req);
467 return req;
469 fail:
470 TALLOC_FREE(req);
471 return NULL;
474 static void rpc_read_done(struct tevent_req *subreq)
476 struct tevent_req *req = tevent_req_callback_data(
477 subreq, struct tevent_req);
478 struct rpc_read_state *state = tevent_req_data(
479 req, struct rpc_read_state);
480 NTSTATUS status;
481 ssize_t received;
483 status = state->transport->read_recv(subreq, &received);
484 TALLOC_FREE(subreq);
485 if (!NT_STATUS_IS_OK(status)) {
486 tevent_req_nterror(req, status);
487 return;
490 state->num_read += received;
491 if (state->num_read == state->size) {
492 tevent_req_done(req);
493 return;
496 subreq = state->transport->read_send(state, state->ev,
497 state->data + state->num_read,
498 state->size - state->num_read,
499 state->transport->priv);
500 if (tevent_req_nomem(subreq, req)) {
501 return;
503 tevent_req_set_callback(subreq, rpc_read_done, req);
506 static NTSTATUS rpc_read_recv(struct tevent_req *req)
508 return tevent_req_simple_recv_ntstatus(req);
511 struct rpc_write_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
514 const uint8_t *data;
515 size_t size;
516 size_t num_written;
519 static void rpc_write_done(struct tevent_req *subreq);
521 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
522 struct event_context *ev,
523 struct rpc_cli_transport *transport,
524 const uint8_t *data, size_t size)
526 struct tevent_req *req, *subreq;
527 struct rpc_write_state *state;
529 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
530 if (req == NULL) {
531 return NULL;
533 state->ev = ev;
534 state->transport = transport;
535 state->data = data;
536 state->size = size;
537 state->num_written = 0;
539 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
541 subreq = transport->write_send(state, ev, data, size, transport->priv);
542 if (subreq == NULL) {
543 goto fail;
545 tevent_req_set_callback(subreq, rpc_write_done, req);
546 return req;
547 fail:
548 TALLOC_FREE(req);
549 return NULL;
552 static void rpc_write_done(struct tevent_req *subreq)
554 struct tevent_req *req = tevent_req_callback_data(
555 subreq, struct tevent_req);
556 struct rpc_write_state *state = tevent_req_data(
557 req, struct rpc_write_state);
558 NTSTATUS status;
559 ssize_t written;
561 status = state->transport->write_recv(subreq, &written);
562 TALLOC_FREE(subreq);
563 if (!NT_STATUS_IS_OK(status)) {
564 tevent_req_nterror(req, status);
565 return;
568 state->num_written += written;
570 if (state->num_written == state->size) {
571 tevent_req_done(req);
572 return;
575 subreq = state->transport->write_send(state, state->ev,
576 state->data + state->num_written,
577 state->size - state->num_written,
578 state->transport->priv);
579 if (tevent_req_nomem(subreq, req)) {
580 return;
582 tevent_req_set_callback(subreq, rpc_write_done, req);
585 static NTSTATUS rpc_write_recv(struct tevent_req *req)
587 return tevent_req_simple_recv_ntstatus(req);
591 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
592 struct ncacn_packet_header *prhdr,
593 prs_struct *pdu)
595 NTSTATUS status;
596 DATA_BLOB blob = data_blob_const(prs_data_p(pdu), prs_data_size(pdu));
599 * This next call sets the endian bit correctly in current_pdu. We
600 * will propagate this to rbuf later.
603 status = dcerpc_pull_ncacn_packet_header(cli, &blob, prhdr);
604 if (!NT_STATUS_IS_OK(status)) {
605 return status;
608 if (!prs_set_offset(pdu, prs_offset(pdu) + RPC_HEADER_LEN)) {
609 return NT_STATUS_BUFFER_TOO_SMALL;
612 if (UNMARSHALLING(pdu) && prhdr->drep[0] == 0) {
613 DEBUG(10,("parse_rpc_header: PDU data format is big-endian. Setting flag.\n"));
614 prs_set_endian_data(pdu, RPC_BIG_ENDIAN);
617 if (prhdr->frag_length > cli->max_recv_frag) {
618 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
619 " we only allow %d\n", (int)prhdr->frag_length,
620 (int)cli->max_recv_frag));
621 return NT_STATUS_BUFFER_TOO_SMALL;
624 return NT_STATUS_OK;
627 /****************************************************************************
628 Try and get a PDU's worth of data from current_pdu. If not, then read more
629 from the wire.
630 ****************************************************************************/
632 struct get_complete_frag_state {
633 struct event_context *ev;
634 struct rpc_pipe_client *cli;
635 struct ncacn_packet_header *prhdr;
636 prs_struct *pdu;
639 static void get_complete_frag_got_header(struct tevent_req *subreq);
640 static void get_complete_frag_got_rest(struct tevent_req *subreq);
642 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
643 struct event_context *ev,
644 struct rpc_pipe_client *cli,
645 struct ncacn_packet_header *prhdr,
646 prs_struct *pdu)
648 struct tevent_req *req, *subreq;
649 struct get_complete_frag_state *state;
650 uint32_t pdu_len;
651 NTSTATUS status;
653 req = tevent_req_create(mem_ctx, &state,
654 struct get_complete_frag_state);
655 if (req == NULL) {
656 return NULL;
658 state->ev = ev;
659 state->cli = cli;
660 state->prhdr = prhdr;
661 state->pdu = pdu;
663 pdu_len = prs_data_size(pdu);
664 if (pdu_len < RPC_HEADER_LEN) {
665 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
666 status = NT_STATUS_NO_MEMORY;
667 goto post_status;
669 subreq = rpc_read_send(
670 state, state->ev,
671 state->cli->transport,
672 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
673 RPC_HEADER_LEN - pdu_len);
674 if (subreq == NULL) {
675 status = NT_STATUS_NO_MEMORY;
676 goto post_status;
678 tevent_req_set_callback(subreq, get_complete_frag_got_header,
679 req);
680 return req;
683 status = parse_rpc_header(cli, prhdr, pdu);
684 if (!NT_STATUS_IS_OK(status)) {
685 goto post_status;
689 * Ensure we have frag_len bytes of data.
691 if (pdu_len < prhdr->frag_length) {
692 if (!rpc_grow_buffer(pdu, prhdr->frag_length)) {
693 status = NT_STATUS_NO_MEMORY;
694 goto post_status;
696 subreq = rpc_read_send(state, state->ev,
697 state->cli->transport,
698 (uint8_t *)(prs_data_p(pdu) + pdu_len),
699 prhdr->frag_length - pdu_len);
700 if (subreq == NULL) {
701 status = NT_STATUS_NO_MEMORY;
702 goto post_status;
704 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
705 req);
706 return req;
709 status = NT_STATUS_OK;
710 post_status:
711 if (NT_STATUS_IS_OK(status)) {
712 tevent_req_done(req);
713 } else {
714 tevent_req_nterror(req, status);
716 return tevent_req_post(req, ev);
719 static void get_complete_frag_got_header(struct tevent_req *subreq)
721 struct tevent_req *req = tevent_req_callback_data(
722 subreq, struct tevent_req);
723 struct get_complete_frag_state *state = tevent_req_data(
724 req, struct get_complete_frag_state);
725 NTSTATUS status;
727 status = rpc_read_recv(subreq);
728 TALLOC_FREE(subreq);
729 if (!NT_STATUS_IS_OK(status)) {
730 tevent_req_nterror(req, status);
731 return;
734 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
735 if (!NT_STATUS_IS_OK(status)) {
736 tevent_req_nterror(req, status);
737 return;
740 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_length)) {
741 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
742 return;
746 * We're here in this piece of code because we've read exactly
747 * RPC_HEADER_LEN bytes into state->pdu.
750 subreq = rpc_read_send(
751 state, state->ev, state->cli->transport,
752 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
753 state->prhdr->frag_length - RPC_HEADER_LEN);
754 if (tevent_req_nomem(subreq, req)) {
755 return;
757 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
760 static void get_complete_frag_got_rest(struct tevent_req *subreq)
762 struct tevent_req *req = tevent_req_callback_data(
763 subreq, struct tevent_req);
764 NTSTATUS status;
766 status = rpc_read_recv(subreq);
767 TALLOC_FREE(subreq);
768 if (!NT_STATUS_IS_OK(status)) {
769 tevent_req_nterror(req, status);
770 return;
772 tevent_req_done(req);
775 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
777 return tevent_req_simple_recv_ntstatus(req);
780 /****************************************************************************
781 NTLMSSP specific sign/seal.
782 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
783 In fact I should probably abstract these into identical pieces of code... JRA.
784 ****************************************************************************/
786 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
787 struct ncacn_packet_header *prhdr,
788 prs_struct *current_pdu,
789 uint8 *p_ss_padding_len)
791 struct dcerpc_auth auth_info;
792 uint32 save_offset = prs_offset(current_pdu);
793 uint32_t auth_len = prhdr->auth_length;
794 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
795 unsigned char *data = NULL;
796 size_t data_len;
797 unsigned char *full_packet_data = NULL;
798 size_t full_packet_data_len;
799 DATA_BLOB auth_blob;
800 DATA_BLOB blob;
801 NTSTATUS status;
803 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
804 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
805 return NT_STATUS_OK;
808 if (!ntlmssp_state) {
809 return NT_STATUS_INVALID_PARAMETER;
812 /* Ensure there's enough data for an authenticated response. */
813 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
814 prhdr->frag_length < RPC_HEADER_LEN +
815 RPC_HDR_RESP_LEN +
816 RPC_HDR_AUTH_LEN + auth_len) {
817 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
818 (unsigned int)auth_len ));
819 return NT_STATUS_BUFFER_TOO_SMALL;
823 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
824 * after the RPC header.
825 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
826 * functions as NTLMv2 checks the rpc headers also.
829 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
830 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
832 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
833 full_packet_data_len = prhdr->frag_length - auth_len;
835 /* Pull the auth header and the following data into a blob. */
836 /* NB. The offset of the auth_header is relative to the *end*
837 * of the packet, not the start. */
838 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
839 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
840 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
841 return NT_STATUS_BUFFER_TOO_SMALL;
844 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
845 prs_data_size(current_pdu) - prs_offset(current_pdu));
847 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
848 if (!NT_STATUS_IS_OK(status)) {
849 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
850 return status;
853 /* Ensure auth_pad_len fits into the packet. */
854 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
855 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
856 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
857 "too large (%u), auth_len (%u), frag_len = (%u).\n",
858 (unsigned int)auth_info.auth_pad_length,
859 (unsigned int)auth_len,
860 (unsigned int)prhdr->frag_length));
861 return NT_STATUS_BUFFER_TOO_SMALL;
865 auth_blob = auth_info.credentials;
867 switch (cli->auth->auth_level) {
868 case DCERPC_AUTH_LEVEL_PRIVACY:
869 /* Data is encrypted. */
870 status = ntlmssp_unseal_packet(ntlmssp_state,
871 data, data_len,
872 full_packet_data,
873 full_packet_data_len,
874 &auth_blob);
875 if (!NT_STATUS_IS_OK(status)) {
876 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
877 "packet from %s. Error was %s.\n",
878 rpccli_pipe_txt(talloc_tos(), cli),
879 nt_errstr(status) ));
880 return status;
882 break;
883 case DCERPC_AUTH_LEVEL_INTEGRITY:
884 /* Data is signed. */
885 status = ntlmssp_check_packet(ntlmssp_state,
886 data, data_len,
887 full_packet_data,
888 full_packet_data_len,
889 &auth_blob);
890 if (!NT_STATUS_IS_OK(status)) {
891 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
892 "packet from %s. Error was %s.\n",
893 rpccli_pipe_txt(talloc_tos(), cli),
894 nt_errstr(status) ));
895 return status;
897 break;
898 default:
899 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
900 "auth level %d\n", cli->auth->auth_level));
901 return NT_STATUS_INVALID_INFO_CLASS;
905 * Return the current pointer to the data offset.
908 if(!prs_set_offset(current_pdu, save_offset)) {
909 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
910 (unsigned int)save_offset ));
911 return NT_STATUS_BUFFER_TOO_SMALL;
915 * Remember the padding length. We must remove it from the real data
916 * stream once the sign/seal is done.
919 *p_ss_padding_len = auth_info.auth_pad_length;
921 return NT_STATUS_OK;
924 /****************************************************************************
925 schannel specific sign/seal.
926 ****************************************************************************/
928 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
929 struct ncacn_packet_header *prhdr,
930 prs_struct *current_pdu,
931 uint8 *p_ss_padding_len)
933 RPC_HDR_AUTH auth_info;
934 uint32_t auth_len = prhdr->auth_length;
935 uint32 save_offset = prs_offset(current_pdu);
936 struct schannel_state *schannel_auth =
937 cli->auth->a_u.schannel_auth;
938 uint8_t *data;
939 uint32 data_len;
940 DATA_BLOB blob;
941 NTSTATUS status;
943 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
944 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
945 return NT_STATUS_OK;
948 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
949 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
950 return NT_STATUS_INVALID_PARAMETER;
953 if (!schannel_auth) {
954 return NT_STATUS_INVALID_PARAMETER;
957 /* Ensure there's enough data for an authenticated response. */
958 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
959 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
960 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
961 (unsigned int)auth_len ));
962 return NT_STATUS_INVALID_PARAMETER;
965 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
967 /* Pull the auth header and the following data into a blob. */
968 /* NB. The offset of the auth_header is relative to the *end*
969 * of the packet, not the start. */
970 if(!prs_set_offset(current_pdu,
971 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
972 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
973 "offset to %u.\n",
974 (unsigned int)(prhdr->frag_length -
975 RPC_HDR_AUTH_LEN - auth_len) ));
976 return NT_STATUS_BUFFER_TOO_SMALL;
979 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
980 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
981 return NT_STATUS_BUFFER_TOO_SMALL;
984 /* Ensure auth_pad_len fits into the packet. */
985 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
986 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
987 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
988 "too large (%u), auth_len (%u), frag_len = (%u).\n",
989 (unsigned int)auth_info.auth_pad_len,
990 (unsigned int)auth_len,
991 (unsigned int)prhdr->frag_length));
992 return NT_STATUS_BUFFER_TOO_SMALL;
995 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
996 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
997 auth_info.auth_type));
998 return NT_STATUS_BUFFER_TOO_SMALL;
1001 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
1003 if (DEBUGLEVEL >= 10) {
1004 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1007 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1009 switch (cli->auth->auth_level) {
1010 case DCERPC_AUTH_LEVEL_PRIVACY:
1011 status = netsec_incoming_packet(schannel_auth,
1012 talloc_tos(),
1013 true,
1014 data,
1015 data_len,
1016 &blob);
1017 break;
1018 case DCERPC_AUTH_LEVEL_INTEGRITY:
1019 status = netsec_incoming_packet(schannel_auth,
1020 talloc_tos(),
1021 false,
1022 data,
1023 data_len,
1024 &blob);
1025 break;
1026 default:
1027 status = NT_STATUS_INTERNAL_ERROR;
1028 break;
1031 if (!NT_STATUS_IS_OK(status)) {
1032 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1033 "Connection to %s (%s).\n",
1034 rpccli_pipe_txt(talloc_tos(), cli),
1035 nt_errstr(status)));
1036 return NT_STATUS_INVALID_PARAMETER;
1040 * Return the current pointer to the data offset.
1043 if(!prs_set_offset(current_pdu, save_offset)) {
1044 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1045 (unsigned int)save_offset ));
1046 return NT_STATUS_BUFFER_TOO_SMALL;
1050 * Remember the padding length. We must remove it from the real data
1051 * stream once the sign/seal is done.
1054 *p_ss_padding_len = auth_info.auth_pad_len;
1056 return NT_STATUS_OK;
1059 /****************************************************************************
1060 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1061 ****************************************************************************/
1063 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1064 struct ncacn_packet_header *prhdr,
1065 prs_struct *current_pdu,
1066 uint8 *p_ss_padding_len)
1068 NTSTATUS ret = NT_STATUS_OK;
1070 /* Paranioa checks for auth_len. */
1071 if (prhdr->auth_length) {
1072 if (prhdr->auth_length > prhdr->frag_length) {
1073 return NT_STATUS_INVALID_PARAMETER;
1076 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1077 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1078 /* Integer wrap attempt. */
1079 return NT_STATUS_INVALID_PARAMETER;
1084 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1087 switch(cli->auth->auth_type) {
1088 case PIPE_AUTH_TYPE_NONE:
1089 if (prhdr->auth_length) {
1090 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1091 "Connection to %s - got non-zero "
1092 "auth len %u.\n",
1093 rpccli_pipe_txt(talloc_tos(), cli),
1094 (unsigned int)prhdr->auth_length));
1095 return NT_STATUS_INVALID_PARAMETER;
1097 break;
1099 case PIPE_AUTH_TYPE_NTLMSSP:
1100 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1101 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1102 if (!NT_STATUS_IS_OK(ret)) {
1103 return ret;
1105 break;
1107 case PIPE_AUTH_TYPE_SCHANNEL:
1108 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1109 if (!NT_STATUS_IS_OK(ret)) {
1110 return ret;
1112 break;
1114 case PIPE_AUTH_TYPE_KRB5:
1115 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1116 default:
1117 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1118 "to %s - unknown internal auth type %u.\n",
1119 rpccli_pipe_txt(talloc_tos(), cli),
1120 cli->auth->auth_type ));
1121 return NT_STATUS_INVALID_INFO_CLASS;
1124 return NT_STATUS_OK;
1127 /****************************************************************************
1128 Do basic authentication checks on an incoming pdu.
1129 ****************************************************************************/
1131 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1132 struct ncacn_packet_header *prhdr,
1133 prs_struct *current_pdu,
1134 uint8 expected_pkt_type,
1135 char **ppdata,
1136 uint32 *pdata_len,
1137 prs_struct *return_data)
1140 NTSTATUS ret = NT_STATUS_OK;
1141 uint32 current_pdu_len = prs_data_size(current_pdu);
1143 if (current_pdu_len != prhdr->frag_length) {
1144 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1145 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1146 return NT_STATUS_INVALID_PARAMETER;
1150 * Point the return values at the real data including the RPC
1151 * header. Just in case the caller wants it.
1153 *ppdata = prs_data_p(current_pdu);
1154 *pdata_len = current_pdu_len;
1156 /* Ensure we have the correct type. */
1157 switch (prhdr->ptype) {
1158 case DCERPC_PKT_ALTER_RESP:
1159 case DCERPC_PKT_BIND_ACK:
1161 /* Alter context and bind ack share the same packet definitions. */
1162 break;
1165 case DCERPC_PKT_RESPONSE:
1167 RPC_HDR_RESP rhdr_resp;
1168 uint8 ss_padding_len = 0;
1170 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1171 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1172 return NT_STATUS_BUFFER_TOO_SMALL;
1175 /* Here's where we deal with incoming sign/seal. */
1176 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1177 current_pdu, &ss_padding_len);
1178 if (!NT_STATUS_IS_OK(ret)) {
1179 return ret;
1182 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1183 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1185 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1186 return NT_STATUS_BUFFER_TOO_SMALL;
1189 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1191 /* Remember to remove the auth footer. */
1192 if (prhdr->auth_length) {
1193 /* We've already done integer wrap tests on auth_len in
1194 cli_pipe_validate_rpc_response(). */
1195 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1196 return NT_STATUS_BUFFER_TOO_SMALL;
1198 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1201 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1202 current_pdu_len, *pdata_len, ss_padding_len ));
1205 * If this is the first reply, and the allocation hint is reasonably, try and
1206 * set up the return_data parse_struct to the correct size.
1209 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1210 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1211 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1212 "too large to allocate\n",
1213 (unsigned int)rhdr_resp.alloc_hint ));
1214 return NT_STATUS_NO_MEMORY;
1218 break;
1221 case DCERPC_PKT_BIND_NAK:
1222 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1223 "received from %s!\n",
1224 rpccli_pipe_txt(talloc_tos(), cli)));
1225 /* Use this for now... */
1226 return NT_STATUS_NETWORK_ACCESS_DENIED;
1228 case DCERPC_PKT_FAULT:
1230 DATA_BLOB blob;
1231 struct ncacn_packet r;
1233 blob = data_blob_const(prs_data_p(current_pdu),
1234 prs_data_size(current_pdu));
1236 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1237 if (!NT_STATUS_IS_OK(ret)) {
1238 return ret;
1240 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1241 "code %s received from %s!\n",
1242 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1243 rpccli_pipe_txt(talloc_tos(), cli)));
1245 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1246 return NT_STATUS_UNSUCCESSFUL;
1247 } else {
1248 return NT_STATUS(r.u.fault.status);
1252 default:
1253 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1254 "from %s!\n",
1255 (unsigned int)prhdr->ptype,
1256 rpccli_pipe_txt(talloc_tos(), cli)));
1257 return NT_STATUS_INVALID_INFO_CLASS;
1260 if (prhdr->ptype != expected_pkt_type) {
1261 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1262 "got an unexpected RPC packet type - %u, not %u\n",
1263 rpccli_pipe_txt(talloc_tos(), cli),
1264 prhdr->ptype,
1265 expected_pkt_type));
1266 return NT_STATUS_INVALID_INFO_CLASS;
1269 /* Do this just before return - we don't want to modify any rpc header
1270 data before now as we may have needed to do cryptographic actions on
1271 it before. */
1273 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1274 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1275 "setting fragment first/last ON.\n"));
1276 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1279 return NT_STATUS_OK;
1282 /****************************************************************************
1283 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1284 Normally the frag_len and buffer size will match, but on the first trans
1285 reply there is a theoretical chance that buffer size > frag_len, so we must
1286 deal with that.
1287 ****************************************************************************/
1289 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1290 struct ncacn_packet_header *prhdr,
1291 prs_struct *current_pdu)
1293 uint32 current_pdu_len = prs_data_size(current_pdu);
1295 if (current_pdu_len < prhdr->frag_length) {
1296 return NT_STATUS_BUFFER_TOO_SMALL;
1299 /* Common case. */
1300 if (current_pdu_len == (uint32)prhdr->frag_length) {
1301 prs_mem_free(current_pdu);
1302 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1303 /* Make current_pdu dynamic with no memory. */
1304 prs_give_memory(current_pdu, 0, 0, True);
1305 return NT_STATUS_OK;
1309 * Oh no ! More data in buffer than we processed in current pdu.
1310 * Cheat. Move the data down and shrink the buffer.
1313 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1314 current_pdu_len - prhdr->frag_length);
1316 /* Remember to set the read offset back to zero. */
1317 prs_set_offset(current_pdu, 0);
1319 /* Shrink the buffer. */
1320 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1321 return NT_STATUS_BUFFER_TOO_SMALL;
1324 return NT_STATUS_OK;
1327 /****************************************************************************
1328 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1329 ****************************************************************************/
1331 struct cli_api_pipe_state {
1332 struct event_context *ev;
1333 struct rpc_cli_transport *transport;
1334 uint8_t *rdata;
1335 uint32_t rdata_len;
1338 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1339 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1340 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1342 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1343 struct event_context *ev,
1344 struct rpc_cli_transport *transport,
1345 uint8_t *data, size_t data_len,
1346 uint32_t max_rdata_len)
1348 struct tevent_req *req, *subreq;
1349 struct cli_api_pipe_state *state;
1350 NTSTATUS status;
1352 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1353 if (req == NULL) {
1354 return NULL;
1356 state->ev = ev;
1357 state->transport = transport;
1359 if (max_rdata_len < RPC_HEADER_LEN) {
1361 * For a RPC reply we always need at least RPC_HEADER_LEN
1362 * bytes. We check this here because we will receive
1363 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1365 status = NT_STATUS_INVALID_PARAMETER;
1366 goto post_status;
1369 if (transport->trans_send != NULL) {
1370 subreq = transport->trans_send(state, ev, data, data_len,
1371 max_rdata_len, transport->priv);
1372 if (subreq == NULL) {
1373 goto fail;
1375 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1376 return req;
1380 * If the transport does not provide a "trans" routine, i.e. for
1381 * example the ncacn_ip_tcp transport, do the write/read step here.
1384 subreq = rpc_write_send(state, ev, transport, data, data_len);
1385 if (subreq == NULL) {
1386 goto fail;
1388 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1389 return req;
1391 post_status:
1392 tevent_req_nterror(req, status);
1393 return tevent_req_post(req, ev);
1394 fail:
1395 TALLOC_FREE(req);
1396 return NULL;
1399 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1401 struct tevent_req *req = tevent_req_callback_data(
1402 subreq, struct tevent_req);
1403 struct cli_api_pipe_state *state = tevent_req_data(
1404 req, struct cli_api_pipe_state);
1405 NTSTATUS status;
1407 status = state->transport->trans_recv(subreq, state, &state->rdata,
1408 &state->rdata_len);
1409 TALLOC_FREE(subreq);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 tevent_req_nterror(req, status);
1412 return;
1414 tevent_req_done(req);
1417 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1419 struct tevent_req *req = tevent_req_callback_data(
1420 subreq, struct tevent_req);
1421 struct cli_api_pipe_state *state = tevent_req_data(
1422 req, struct cli_api_pipe_state);
1423 NTSTATUS status;
1425 status = rpc_write_recv(subreq);
1426 TALLOC_FREE(subreq);
1427 if (!NT_STATUS_IS_OK(status)) {
1428 tevent_req_nterror(req, status);
1429 return;
1432 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1433 if (tevent_req_nomem(state->rdata, req)) {
1434 return;
1438 * We don't need to use rpc_read_send here, the upper layer will cope
1439 * with a short read, transport->trans_send could also return less
1440 * than state->max_rdata_len.
1442 subreq = state->transport->read_send(state, state->ev, state->rdata,
1443 RPC_HEADER_LEN,
1444 state->transport->priv);
1445 if (tevent_req_nomem(subreq, req)) {
1446 return;
1448 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1451 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1453 struct tevent_req *req = tevent_req_callback_data(
1454 subreq, struct tevent_req);
1455 struct cli_api_pipe_state *state = tevent_req_data(
1456 req, struct cli_api_pipe_state);
1457 NTSTATUS status;
1458 ssize_t received;
1460 status = state->transport->read_recv(subreq, &received);
1461 TALLOC_FREE(subreq);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 tevent_req_nterror(req, status);
1464 return;
1466 state->rdata_len = received;
1467 tevent_req_done(req);
1470 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1471 uint8_t **prdata, uint32_t *prdata_len)
1473 struct cli_api_pipe_state *state = tevent_req_data(
1474 req, struct cli_api_pipe_state);
1475 NTSTATUS status;
1477 if (tevent_req_is_nterror(req, &status)) {
1478 return status;
1481 *prdata = talloc_move(mem_ctx, &state->rdata);
1482 *prdata_len = state->rdata_len;
1483 return NT_STATUS_OK;
1486 /****************************************************************************
1487 Send data on an rpc pipe via trans. The prs_struct data must be the last
1488 pdu fragment of an NDR data stream.
1490 Receive response data from an rpc pipe, which may be large...
1492 Read the first fragment: unfortunately have to use SMBtrans for the first
1493 bit, then SMBreadX for subsequent bits.
1495 If first fragment received also wasn't the last fragment, continue
1496 getting fragments until we _do_ receive the last fragment.
1498 Request/Response PDU's look like the following...
1500 |<------------------PDU len----------------------------------------------->|
1501 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1503 +------------+-----------------+-------------+---------------+-------------+
1504 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1505 +------------+-----------------+-------------+---------------+-------------+
1507 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1508 signing & sealing being negotiated.
1510 ****************************************************************************/
1512 struct rpc_api_pipe_state {
1513 struct event_context *ev;
1514 struct rpc_pipe_client *cli;
1515 uint8_t expected_pkt_type;
1517 prs_struct incoming_frag;
1518 struct ncacn_packet_header rhdr;
1520 prs_struct incoming_pdu; /* Incoming reply */
1521 uint32_t incoming_pdu_offset;
1524 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1525 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1527 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1528 struct event_context *ev,
1529 struct rpc_pipe_client *cli,
1530 prs_struct *data, /* Outgoing PDU */
1531 uint8_t expected_pkt_type)
1533 struct tevent_req *req, *subreq;
1534 struct rpc_api_pipe_state *state;
1535 uint16_t max_recv_frag;
1536 NTSTATUS status;
1538 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1539 if (req == NULL) {
1540 return NULL;
1542 state->ev = ev;
1543 state->cli = cli;
1544 state->expected_pkt_type = expected_pkt_type;
1545 state->incoming_pdu_offset = 0;
1547 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1549 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1550 /* Make incoming_pdu dynamic with no memory. */
1551 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1554 * Ensure we're not sending too much.
1556 if (prs_offset(data) > cli->max_xmit_frag) {
1557 status = NT_STATUS_INVALID_PARAMETER;
1558 goto post_status;
1561 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1563 max_recv_frag = cli->max_recv_frag;
1565 #if 0
1566 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1567 #endif
1569 subreq = cli_api_pipe_send(state, ev, cli->transport,
1570 (uint8_t *)prs_data_p(data),
1571 prs_offset(data), max_recv_frag);
1572 if (subreq == NULL) {
1573 goto fail;
1575 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1576 return req;
1578 post_status:
1579 tevent_req_nterror(req, status);
1580 return tevent_req_post(req, ev);
1581 fail:
1582 TALLOC_FREE(req);
1583 return NULL;
1586 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1588 struct tevent_req *req = tevent_req_callback_data(
1589 subreq, struct tevent_req);
1590 struct rpc_api_pipe_state *state = tevent_req_data(
1591 req, struct rpc_api_pipe_state);
1592 NTSTATUS status;
1593 uint8_t *rdata = NULL;
1594 uint32_t rdata_len = 0;
1596 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1597 TALLOC_FREE(subreq);
1598 if (!NT_STATUS_IS_OK(status)) {
1599 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1600 tevent_req_nterror(req, status);
1601 return;
1604 if (rdata == NULL) {
1605 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1606 rpccli_pipe_txt(talloc_tos(), state->cli)));
1607 tevent_req_done(req);
1608 return;
1612 * This is equivalent to a talloc_steal - gives rdata to
1613 * the prs_struct state->incoming_frag.
1615 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1616 rdata = NULL;
1618 /* Ensure we have enough data for a pdu. */
1619 subreq = get_complete_frag_send(state, state->ev, state->cli,
1620 &state->rhdr, &state->incoming_frag);
1621 if (tevent_req_nomem(subreq, req)) {
1622 return;
1624 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1627 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1629 struct tevent_req *req = tevent_req_callback_data(
1630 subreq, struct tevent_req);
1631 struct rpc_api_pipe_state *state = tevent_req_data(
1632 req, struct rpc_api_pipe_state);
1633 NTSTATUS status;
1634 char *rdata = NULL;
1635 uint32_t rdata_len = 0;
1637 status = get_complete_frag_recv(subreq);
1638 TALLOC_FREE(subreq);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 DEBUG(5, ("get_complete_frag failed: %s\n",
1641 nt_errstr(status)));
1642 tevent_req_nterror(req, status);
1643 return;
1646 status = cli_pipe_validate_current_pdu(
1647 state->cli, &state->rhdr, &state->incoming_frag,
1648 state->expected_pkt_type, &rdata, &rdata_len,
1649 &state->incoming_pdu);
1651 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1652 (unsigned)prs_data_size(&state->incoming_frag),
1653 (unsigned)state->incoming_pdu_offset,
1654 nt_errstr(status)));
1656 if (!NT_STATUS_IS_OK(status)) {
1657 tevent_req_nterror(req, status);
1658 return;
1661 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1662 && (state->rhdr.drep[0] == 0)) {
1664 * Set the data type correctly for big-endian data on the
1665 * first packet.
1667 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1668 "big-endian.\n",
1669 rpccli_pipe_txt(talloc_tos(), state->cli)));
1670 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1673 * Check endianness on subsequent packets.
1675 if (state->incoming_frag.bigendian_data
1676 != state->incoming_pdu.bigendian_data) {
1677 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1678 "%s\n",
1679 state->incoming_pdu.bigendian_data?"big":"little",
1680 state->incoming_frag.bigendian_data?"big":"little"));
1681 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1682 return;
1685 /* Now copy the data portion out of the pdu into rbuf. */
1686 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1687 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1688 return;
1691 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1692 rdata, (size_t)rdata_len);
1693 state->incoming_pdu_offset += rdata_len;
1695 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1696 &state->incoming_frag);
1697 if (!NT_STATUS_IS_OK(status)) {
1698 tevent_req_nterror(req, status);
1699 return;
1702 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1703 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1704 rpccli_pipe_txt(talloc_tos(), state->cli),
1705 (unsigned)prs_data_size(&state->incoming_pdu)));
1706 tevent_req_done(req);
1707 return;
1710 subreq = get_complete_frag_send(state, state->ev, state->cli,
1711 &state->rhdr, &state->incoming_frag);
1712 if (tevent_req_nomem(subreq, req)) {
1713 return;
1715 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1718 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1719 prs_struct *reply_pdu)
1721 struct rpc_api_pipe_state *state = tevent_req_data(
1722 req, struct rpc_api_pipe_state);
1723 NTSTATUS status;
1725 if (tevent_req_is_nterror(req, &status)) {
1726 return status;
1729 *reply_pdu = state->incoming_pdu;
1730 reply_pdu->mem_ctx = mem_ctx;
1733 * Prevent state->incoming_pdu from being freed
1734 * when state is freed.
1736 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1737 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1739 return NT_STATUS_OK;
1742 /*******************************************************************
1743 ********************************************************************/
1745 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1746 enum dcerpc_AuthType auth_type,
1747 enum dcerpc_AuthLevel auth_level,
1748 uint8_t auth_pad_length,
1749 uint32_t auth_context_id,
1750 const DATA_BLOB *credentials,
1751 DATA_BLOB *blob)
1753 struct dcerpc_auth r;
1754 enum ndr_err_code ndr_err;
1756 r.auth_type = auth_type;
1757 r.auth_level = auth_level;
1758 r.auth_pad_length = auth_pad_length;
1759 r.auth_reserved = 0;
1760 r.auth_context_id = auth_context_id;
1761 r.credentials = *credentials;
1763 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1764 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1765 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1766 return ndr_map_error2ntstatus(ndr_err);
1769 if (DEBUGLEVEL >= 10) {
1770 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1773 return NT_STATUS_OK;
1776 /*******************************************************************
1777 Creates krb5 auth bind.
1778 ********************************************************************/
1780 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1781 enum dcerpc_AuthLevel auth_level,
1782 DATA_BLOB *auth_info)
1784 #ifdef HAVE_KRB5
1785 int ret;
1786 NTSTATUS status;
1787 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1788 DATA_BLOB tkt = data_blob_null;
1789 DATA_BLOB tkt_wrapped = data_blob_null;
1791 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1792 a->service_principal ));
1794 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1796 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1797 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1799 if (ret) {
1800 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1801 "failed with %s\n",
1802 a->service_principal,
1803 error_message(ret) ));
1805 data_blob_free(&tkt);
1806 return NT_STATUS_INVALID_PARAMETER;
1809 /* wrap that up in a nice GSS-API wrapping */
1810 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1812 data_blob_free(&tkt);
1814 status = dcerpc_push_dcerpc_auth(cli,
1815 DCERPC_AUTH_TYPE_KRB5,
1816 auth_level,
1817 0, /* auth_pad_length */
1818 1, /* auth_context_id */
1819 &tkt_wrapped,
1820 auth_info);
1821 if (!NT_STATUS_IS_OK(status)) {
1822 data_blob_free(&tkt_wrapped);
1823 return status;
1826 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1827 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1829 return NT_STATUS_OK;
1830 #else
1831 return NT_STATUS_INVALID_PARAMETER;
1832 #endif
1835 /*******************************************************************
1836 Creates SPNEGO NTLMSSP auth bind.
1837 ********************************************************************/
1839 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1840 enum dcerpc_AuthLevel auth_level,
1841 DATA_BLOB *auth_info)
1843 NTSTATUS status;
1844 DATA_BLOB null_blob = data_blob_null;
1845 DATA_BLOB request = data_blob_null;
1846 DATA_BLOB spnego_msg = data_blob_null;
1848 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1849 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1850 null_blob,
1851 &request);
1853 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1854 data_blob_free(&request);
1855 return status;
1858 /* Wrap this in SPNEGO. */
1859 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1861 data_blob_free(&request);
1863 status = dcerpc_push_dcerpc_auth(cli,
1864 DCERPC_AUTH_TYPE_SPNEGO,
1865 auth_level,
1866 0, /* auth_pad_length */
1867 1, /* auth_context_id */
1868 &spnego_msg,
1869 auth_info);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 data_blob_free(&spnego_msg);
1872 return status;
1875 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1876 dump_data(5, spnego_msg.data, spnego_msg.length);
1878 return NT_STATUS_OK;
1881 /*******************************************************************
1882 Creates NTLMSSP auth bind.
1883 ********************************************************************/
1885 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1886 enum dcerpc_AuthLevel auth_level,
1887 DATA_BLOB *auth_info)
1889 NTSTATUS status;
1890 DATA_BLOB null_blob = data_blob_null;
1891 DATA_BLOB request = data_blob_null;
1893 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1894 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1895 null_blob,
1896 &request);
1898 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1899 data_blob_free(&request);
1900 return status;
1903 status = dcerpc_push_dcerpc_auth(cli,
1904 DCERPC_AUTH_TYPE_NTLMSSP,
1905 auth_level,
1906 0, /* auth_pad_length */
1907 1, /* auth_context_id */
1908 &request,
1909 auth_info);
1910 if (!NT_STATUS_IS_OK(status)) {
1911 data_blob_free(&request);
1912 return status;
1915 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1916 dump_data(5, request.data, request.length);
1918 return NT_STATUS_OK;
1921 /*******************************************************************
1922 Creates schannel auth bind.
1923 ********************************************************************/
1925 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1926 enum dcerpc_AuthLevel auth_level,
1927 DATA_BLOB *auth_info)
1929 NTSTATUS status;
1930 struct NL_AUTH_MESSAGE r;
1931 DATA_BLOB schannel_blob;
1933 /* Use lp_workgroup() if domain not specified */
1935 if (!cli->auth->domain || !cli->auth->domain[0]) {
1936 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1937 if (cli->auth->domain == NULL) {
1938 return NT_STATUS_NO_MEMORY;
1943 * Now marshall the data into the auth parse_struct.
1946 r.MessageType = NL_NEGOTIATE_REQUEST;
1947 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1948 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1949 r.oem_netbios_domain.a = cli->auth->domain;
1950 r.oem_netbios_computer.a = global_myname();
1952 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1953 if (!NT_STATUS_IS_OK(status)) {
1954 return status;
1957 status = dcerpc_push_dcerpc_auth(cli,
1958 DCERPC_AUTH_TYPE_SCHANNEL,
1959 auth_level,
1960 0, /* auth_pad_length */
1961 1, /* auth_context_id */
1962 &schannel_blob,
1963 auth_info);
1964 if (!NT_STATUS_IS_OK(status)) {
1965 return status;
1968 return NT_STATUS_OK;
1971 /*******************************************************************
1972 ********************************************************************/
1974 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1975 const struct ndr_syntax_id *abstract_syntax,
1976 const struct ndr_syntax_id *transfer_syntax,
1977 struct dcerpc_ctx_list **ctx_list_p)
1979 struct dcerpc_ctx_list *ctx_list;
1981 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1982 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1984 ctx_list[0].context_id = 0;
1985 ctx_list[0].num_transfer_syntaxes = 1;
1986 ctx_list[0].abstract_syntax = *abstract_syntax;
1987 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1988 struct ndr_syntax_id,
1989 ctx_list[0].num_transfer_syntaxes);
1990 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1991 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1993 *ctx_list_p = ctx_list;
1995 return NT_STATUS_OK;
1998 /*******************************************************************
1999 Creates the internals of a DCE/RPC bind request or alter context PDU.
2000 ********************************************************************/
2002 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2003 prs_struct *rpc_out,
2004 uint32 rpc_call_id,
2005 const struct ndr_syntax_id *abstract,
2006 const struct ndr_syntax_id *transfer,
2007 const DATA_BLOB *auth_info)
2009 uint16 auth_len = auth_info->length;
2010 uint16 frag_len = 0;
2011 NTSTATUS status;
2012 union dcerpc_payload u;
2013 DATA_BLOB blob;
2014 struct dcerpc_ctx_list *ctx_list;
2016 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2017 &ctx_list);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 return status;
2022 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2023 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2024 u.bind.assoc_group_id = 0x0;
2025 u.bind.num_contexts = 1;
2026 u.bind.ctx_list = ctx_list;
2027 u.bind.auth_info = *auth_info;
2029 /* Start building the frag length. */
2030 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
2032 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2033 ptype,
2034 DCERPC_PFC_FLAG_FIRST |
2035 DCERPC_PFC_FLAG_LAST,
2036 frag_len,
2037 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2038 rpc_call_id,
2040 &blob);
2041 if (!NT_STATUS_IS_OK(status)) {
2042 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2043 return status;
2046 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2047 return NT_STATUS_NO_MEMORY;
2050 return NT_STATUS_OK;
2053 /*******************************************************************
2054 Creates a DCE/RPC bind request.
2055 ********************************************************************/
2057 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2058 prs_struct *rpc_out,
2059 uint32 rpc_call_id,
2060 const struct ndr_syntax_id *abstract,
2061 const struct ndr_syntax_id *transfer,
2062 enum pipe_auth_type auth_type,
2063 enum dcerpc_AuthLevel auth_level)
2065 DATA_BLOB auth_info = data_blob_null;
2066 NTSTATUS ret = NT_STATUS_OK;
2068 switch (auth_type) {
2069 case PIPE_AUTH_TYPE_SCHANNEL:
2070 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2071 if (!NT_STATUS_IS_OK(ret)) {
2072 return ret;
2074 break;
2076 case PIPE_AUTH_TYPE_NTLMSSP:
2077 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2078 if (!NT_STATUS_IS_OK(ret)) {
2079 return ret;
2081 break;
2083 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2084 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2085 if (!NT_STATUS_IS_OK(ret)) {
2086 return ret;
2088 break;
2090 case PIPE_AUTH_TYPE_KRB5:
2091 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2092 if (!NT_STATUS_IS_OK(ret)) {
2093 return ret;
2095 break;
2097 case PIPE_AUTH_TYPE_NONE:
2098 break;
2100 default:
2101 /* "Can't" happen. */
2102 return NT_STATUS_INVALID_INFO_CLASS;
2105 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2106 rpc_out,
2107 rpc_call_id,
2108 abstract,
2109 transfer,
2110 &auth_info);
2111 return ret;
2114 /*******************************************************************
2115 Create and add the NTLMSSP sign/seal auth header and data.
2116 ********************************************************************/
2118 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2119 RPC_HDR *phdr,
2120 uint32 ss_padding_len,
2121 prs_struct *outgoing_pdu)
2123 RPC_HDR_AUTH auth_info;
2124 NTSTATUS status;
2125 DATA_BLOB auth_blob = data_blob_null;
2126 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2127 TALLOC_CTX *frame;
2129 if (!cli->auth->a_u.ntlmssp_state) {
2130 return NT_STATUS_INVALID_PARAMETER;
2133 frame = talloc_stackframe();
2135 /* Init and marshall the auth header. */
2136 init_rpc_hdr_auth(&auth_info,
2137 map_pipe_auth_type_to_rpc_auth_type(
2138 cli->auth->auth_type),
2139 cli->auth->auth_level,
2140 ss_padding_len,
2141 1 /* context id. */);
2143 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2144 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2145 talloc_free(frame);
2146 return NT_STATUS_NO_MEMORY;
2149 switch (cli->auth->auth_level) {
2150 case DCERPC_AUTH_LEVEL_PRIVACY:
2151 /* Data portion is encrypted. */
2152 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2153 frame,
2154 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2155 data_and_pad_len,
2156 (unsigned char *)prs_data_p(outgoing_pdu),
2157 (size_t)prs_offset(outgoing_pdu),
2158 &auth_blob);
2159 if (!NT_STATUS_IS_OK(status)) {
2160 talloc_free(frame);
2161 return status;
2163 break;
2165 case DCERPC_AUTH_LEVEL_INTEGRITY:
2166 /* Data is signed. */
2167 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2168 frame,
2169 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2170 data_and_pad_len,
2171 (unsigned char *)prs_data_p(outgoing_pdu),
2172 (size_t)prs_offset(outgoing_pdu),
2173 &auth_blob);
2174 if (!NT_STATUS_IS_OK(status)) {
2175 talloc_free(frame);
2176 return status;
2178 break;
2180 default:
2181 /* Can't happen. */
2182 smb_panic("bad auth level");
2183 /* Notreached. */
2184 return NT_STATUS_INVALID_PARAMETER;
2187 /* Finally marshall the blob. */
2189 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2190 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2191 (unsigned int)NTLMSSP_SIG_SIZE));
2192 talloc_free(frame);
2193 return NT_STATUS_NO_MEMORY;
2196 talloc_free(frame);
2197 return NT_STATUS_OK;
2200 /*******************************************************************
2201 Create and add the schannel sign/seal auth header and data.
2202 ********************************************************************/
2204 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2205 RPC_HDR *phdr,
2206 uint32 ss_padding_len,
2207 prs_struct *outgoing_pdu)
2209 RPC_HDR_AUTH auth_info;
2210 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2211 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2212 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2213 DATA_BLOB blob;
2214 NTSTATUS status;
2216 if (!sas) {
2217 return NT_STATUS_INVALID_PARAMETER;
2220 /* Init and marshall the auth header. */
2221 init_rpc_hdr_auth(&auth_info,
2222 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2223 cli->auth->auth_level,
2224 ss_padding_len,
2225 1 /* context id. */);
2227 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2228 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2229 return NT_STATUS_NO_MEMORY;
2232 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2233 sas->seq_num));
2235 switch (cli->auth->auth_level) {
2236 case DCERPC_AUTH_LEVEL_PRIVACY:
2237 status = netsec_outgoing_packet(sas,
2238 talloc_tos(),
2239 true,
2240 (uint8_t *)data_p,
2241 data_and_pad_len,
2242 &blob);
2243 break;
2244 case DCERPC_AUTH_LEVEL_INTEGRITY:
2245 status = netsec_outgoing_packet(sas,
2246 talloc_tos(),
2247 false,
2248 (uint8_t *)data_p,
2249 data_and_pad_len,
2250 &blob);
2251 break;
2252 default:
2253 status = NT_STATUS_INTERNAL_ERROR;
2254 break;
2257 if (!NT_STATUS_IS_OK(status)) {
2258 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2259 nt_errstr(status)));
2260 return status;
2263 if (DEBUGLEVEL >= 10) {
2264 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2267 /* Finally marshall the blob. */
2268 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2269 return NT_STATUS_NO_MEMORY;
2272 return NT_STATUS_OK;
2275 /*******************************************************************
2276 Calculate how much data we're going to send in this packet, also
2277 work out any sign/seal padding length.
2278 ********************************************************************/
2280 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2281 uint32 data_left,
2282 uint16 *p_frag_len,
2283 uint16 *p_auth_len,
2284 uint32 *p_ss_padding)
2286 uint32 data_space, data_len;
2288 #if 0
2289 if ((data_left > 0) && (sys_random() % 2)) {
2290 data_left = MAX(data_left/2, 1);
2292 #endif
2294 switch (cli->auth->auth_level) {
2295 case DCERPC_AUTH_LEVEL_NONE:
2296 case DCERPC_AUTH_LEVEL_CONNECT:
2297 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2298 data_len = MIN(data_space, data_left);
2299 *p_ss_padding = 0;
2300 *p_auth_len = 0;
2301 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2302 return data_len;
2304 case DCERPC_AUTH_LEVEL_INTEGRITY:
2305 case DCERPC_AUTH_LEVEL_PRIVACY:
2306 /* Treat the same for all authenticated rpc requests. */
2307 switch(cli->auth->auth_type) {
2308 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2309 case PIPE_AUTH_TYPE_NTLMSSP:
2310 *p_auth_len = NTLMSSP_SIG_SIZE;
2311 break;
2312 case PIPE_AUTH_TYPE_SCHANNEL:
2313 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2314 break;
2315 default:
2316 smb_panic("bad auth type");
2317 break;
2320 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2321 RPC_HDR_AUTH_LEN - *p_auth_len;
2323 data_len = MIN(data_space, data_left);
2324 *p_ss_padding = 0;
2325 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2326 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2328 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2329 data_len + *p_ss_padding + /* data plus padding. */
2330 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2331 return data_len;
2333 default:
2334 smb_panic("bad auth level");
2335 /* Notreached. */
2336 return 0;
2340 /*******************************************************************
2341 External interface.
2342 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2343 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2344 and deals with signing/sealing details.
2345 ********************************************************************/
2347 struct rpc_api_pipe_req_state {
2348 struct event_context *ev;
2349 struct rpc_pipe_client *cli;
2350 uint8_t op_num;
2351 uint32_t call_id;
2352 prs_struct *req_data;
2353 uint32_t req_data_sent;
2354 prs_struct outgoing_frag;
2355 prs_struct reply_pdu;
2358 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2359 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2360 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2361 bool *is_last_frag);
2363 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2364 struct event_context *ev,
2365 struct rpc_pipe_client *cli,
2366 uint8_t op_num,
2367 prs_struct *req_data)
2369 struct tevent_req *req, *subreq;
2370 struct rpc_api_pipe_req_state *state;
2371 NTSTATUS status;
2372 bool is_last_frag;
2374 req = tevent_req_create(mem_ctx, &state,
2375 struct rpc_api_pipe_req_state);
2376 if (req == NULL) {
2377 return NULL;
2379 state->ev = ev;
2380 state->cli = cli;
2381 state->op_num = op_num;
2382 state->req_data = req_data;
2383 state->req_data_sent = 0;
2384 state->call_id = get_rpc_call_id();
2386 if (cli->max_xmit_frag
2387 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2388 /* Server is screwed up ! */
2389 status = NT_STATUS_INVALID_PARAMETER;
2390 goto post_status;
2393 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2395 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2396 state, MARSHALL)) {
2397 goto fail;
2400 status = prepare_next_frag(state, &is_last_frag);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 goto post_status;
2405 if (is_last_frag) {
2406 subreq = rpc_api_pipe_send(state, ev, state->cli,
2407 &state->outgoing_frag,
2408 DCERPC_PKT_RESPONSE);
2409 if (subreq == NULL) {
2410 goto fail;
2412 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2413 } else {
2414 subreq = rpc_write_send(
2415 state, ev, cli->transport,
2416 (uint8_t *)prs_data_p(&state->outgoing_frag),
2417 prs_offset(&state->outgoing_frag));
2418 if (subreq == NULL) {
2419 goto fail;
2421 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2422 req);
2424 return req;
2426 post_status:
2427 tevent_req_nterror(req, status);
2428 return tevent_req_post(req, ev);
2429 fail:
2430 TALLOC_FREE(req);
2431 return NULL;
2434 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2435 bool *is_last_frag)
2437 RPC_HDR hdr;
2438 RPC_HDR_REQ hdr_req;
2439 uint32_t data_sent_thistime;
2440 uint16_t auth_len;
2441 uint16_t frag_len;
2442 uint8_t flags = 0;
2443 uint32_t ss_padding;
2444 uint32_t data_left;
2445 char pad[8] = { 0, };
2446 NTSTATUS status;
2448 data_left = prs_offset(state->req_data) - state->req_data_sent;
2450 data_sent_thistime = calculate_data_len_tosend(
2451 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2453 if (state->req_data_sent == 0) {
2454 flags = DCERPC_PFC_FLAG_FIRST;
2457 if (data_sent_thistime == data_left) {
2458 flags |= DCERPC_PFC_FLAG_LAST;
2461 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2462 return NT_STATUS_NO_MEMORY;
2465 /* Create and marshall the header and request header. */
2466 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2467 auth_len);
2469 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2470 return NT_STATUS_NO_MEMORY;
2473 /* Create the rpc request RPC_HDR_REQ */
2474 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2475 state->op_num);
2477 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2478 &state->outgoing_frag, 0)) {
2479 return NT_STATUS_NO_MEMORY;
2482 /* Copy in the data, plus any ss padding. */
2483 if (!prs_append_some_prs_data(&state->outgoing_frag,
2484 state->req_data, state->req_data_sent,
2485 data_sent_thistime)) {
2486 return NT_STATUS_NO_MEMORY;
2489 /* Copy the sign/seal padding data. */
2490 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2491 return NT_STATUS_NO_MEMORY;
2494 /* Generate any auth sign/seal and add the auth footer. */
2495 switch (state->cli->auth->auth_type) {
2496 case PIPE_AUTH_TYPE_NONE:
2497 status = NT_STATUS_OK;
2498 break;
2499 case PIPE_AUTH_TYPE_NTLMSSP:
2500 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2501 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2502 &state->outgoing_frag);
2503 break;
2504 case PIPE_AUTH_TYPE_SCHANNEL:
2505 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2506 &state->outgoing_frag);
2507 break;
2508 default:
2509 status = NT_STATUS_INVALID_PARAMETER;
2510 break;
2513 state->req_data_sent += data_sent_thistime;
2514 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2516 return status;
2519 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2521 struct tevent_req *req = tevent_req_callback_data(
2522 subreq, struct tevent_req);
2523 struct rpc_api_pipe_req_state *state = tevent_req_data(
2524 req, struct rpc_api_pipe_req_state);
2525 NTSTATUS status;
2526 bool is_last_frag;
2528 status = rpc_write_recv(subreq);
2529 TALLOC_FREE(subreq);
2530 if (!NT_STATUS_IS_OK(status)) {
2531 tevent_req_nterror(req, status);
2532 return;
2535 status = prepare_next_frag(state, &is_last_frag);
2536 if (!NT_STATUS_IS_OK(status)) {
2537 tevent_req_nterror(req, status);
2538 return;
2541 if (is_last_frag) {
2542 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2543 &state->outgoing_frag,
2544 DCERPC_PKT_RESPONSE);
2545 if (tevent_req_nomem(subreq, req)) {
2546 return;
2548 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2549 } else {
2550 subreq = rpc_write_send(
2551 state, state->ev,
2552 state->cli->transport,
2553 (uint8_t *)prs_data_p(&state->outgoing_frag),
2554 prs_offset(&state->outgoing_frag));
2555 if (tevent_req_nomem(subreq, req)) {
2556 return;
2558 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2559 req);
2563 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2565 struct tevent_req *req = tevent_req_callback_data(
2566 subreq, struct tevent_req);
2567 struct rpc_api_pipe_req_state *state = tevent_req_data(
2568 req, struct rpc_api_pipe_req_state);
2569 NTSTATUS status;
2571 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2572 TALLOC_FREE(subreq);
2573 if (!NT_STATUS_IS_OK(status)) {
2574 tevent_req_nterror(req, status);
2575 return;
2577 tevent_req_done(req);
2580 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2581 prs_struct *reply_pdu)
2583 struct rpc_api_pipe_req_state *state = tevent_req_data(
2584 req, struct rpc_api_pipe_req_state);
2585 NTSTATUS status;
2587 if (tevent_req_is_nterror(req, &status)) {
2589 * We always have to initialize to reply pdu, even if there is
2590 * none. The rpccli_* caller routines expect this.
2592 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2593 return status;
2596 *reply_pdu = state->reply_pdu;
2597 reply_pdu->mem_ctx = mem_ctx;
2600 * Prevent state->req_pdu from being freed
2601 * when state is freed.
2603 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2604 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2606 return NT_STATUS_OK;
2609 #if 0
2610 /****************************************************************************
2611 Set the handle state.
2612 ****************************************************************************/
2614 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2615 const char *pipe_name, uint16 device_state)
2617 bool state_set = False;
2618 char param[2];
2619 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2620 char *rparam = NULL;
2621 char *rdata = NULL;
2622 uint32 rparam_len, rdata_len;
2624 if (pipe_name == NULL)
2625 return False;
2627 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2628 cli->fnum, pipe_name, device_state));
2630 /* create parameters: device state */
2631 SSVAL(param, 0, device_state);
2633 /* create setup parameters. */
2634 setup[0] = 0x0001;
2635 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2637 /* send the data on \PIPE\ */
2638 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2639 setup, 2, 0, /* setup, length, max */
2640 param, 2, 0, /* param, length, max */
2641 NULL, 0, 1024, /* data, length, max */
2642 &rparam, &rparam_len, /* return param, length */
2643 &rdata, &rdata_len)) /* return data, length */
2645 DEBUG(5, ("Set Handle state: return OK\n"));
2646 state_set = True;
2649 SAFE_FREE(rparam);
2650 SAFE_FREE(rdata);
2652 return state_set;
2654 #endif
2656 /****************************************************************************
2657 Check the rpc bind acknowledge response.
2658 ****************************************************************************/
2660 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2661 const struct ndr_syntax_id *transfer)
2663 if ( hdr_ba->addr.len == 0) {
2664 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2667 /* check the transfer syntax */
2668 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2669 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2670 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2671 return False;
2674 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2675 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2676 hdr_ba->res.num_results, hdr_ba->res.reason));
2679 DEBUG(5,("check_bind_response: accepted!\n"));
2680 return True;
2683 /*******************************************************************
2684 Creates a DCE/RPC bind authentication response.
2685 This is the packet that is sent back to the server once we
2686 have received a BIND-ACK, to finish the third leg of
2687 the authentication handshake.
2688 ********************************************************************/
2690 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2691 uint32 rpc_call_id,
2692 enum pipe_auth_type auth_type,
2693 enum dcerpc_AuthLevel auth_level,
2694 DATA_BLOB *pauth_blob,
2695 prs_struct *rpc_out)
2697 RPC_HDR hdr;
2698 RPC_HDR_AUTH hdr_auth;
2699 uint32 pad = 0;
2701 /* Create the request RPC_HDR */
2702 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2703 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2704 pauth_blob->length );
2706 /* Marshall it. */
2707 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2708 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2709 return NT_STATUS_NO_MEMORY;
2713 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2714 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2717 /* 4 bytes padding. */
2718 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2719 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2720 return NT_STATUS_NO_MEMORY;
2723 /* Create the request RPC_HDR_AUTHA */
2724 init_rpc_hdr_auth(&hdr_auth,
2725 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2726 auth_level, 0, 1);
2728 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2729 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2730 return NT_STATUS_NO_MEMORY;
2734 * Append the auth data to the outgoing buffer.
2737 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2738 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2739 return NT_STATUS_NO_MEMORY;
2742 return NT_STATUS_OK;
2745 /*******************************************************************
2746 Creates a DCE/RPC bind alter context authentication request which
2747 may contain a spnego auth blobl
2748 ********************************************************************/
2750 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2751 const struct ndr_syntax_id *abstract,
2752 const struct ndr_syntax_id *transfer,
2753 enum dcerpc_AuthLevel auth_level,
2754 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2755 prs_struct *rpc_out)
2757 DATA_BLOB auth_info;
2758 NTSTATUS status;
2760 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2761 DCERPC_AUTH_TYPE_SPNEGO,
2762 auth_level,
2763 0, /* auth_pad_length */
2764 1, /* auth_context_id */
2765 pauth_blob,
2766 &auth_info);
2767 if (!NT_STATUS_IS_OK(status)) {
2768 return status;
2772 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2773 rpc_out,
2774 rpc_call_id,
2775 abstract,
2776 transfer,
2777 &auth_info);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 return status;
2782 return status;
2785 /****************************************************************************
2786 Do an rpc bind.
2787 ****************************************************************************/
2789 struct rpc_pipe_bind_state {
2790 struct event_context *ev;
2791 struct rpc_pipe_client *cli;
2792 prs_struct rpc_out;
2793 uint32_t rpc_call_id;
2796 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2797 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2798 struct rpc_pipe_bind_state *state,
2799 struct rpc_hdr_info *phdr,
2800 prs_struct *reply_pdu);
2801 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2802 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2803 struct rpc_pipe_bind_state *state,
2804 struct rpc_hdr_info *phdr,
2805 prs_struct *reply_pdu);
2806 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2808 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2809 struct event_context *ev,
2810 struct rpc_pipe_client *cli,
2811 struct cli_pipe_auth_data *auth)
2813 struct tevent_req *req, *subreq;
2814 struct rpc_pipe_bind_state *state;
2815 NTSTATUS status;
2817 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2818 if (req == NULL) {
2819 return NULL;
2822 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2823 rpccli_pipe_txt(talloc_tos(), cli),
2824 (unsigned int)auth->auth_type,
2825 (unsigned int)auth->auth_level ));
2827 state->ev = ev;
2828 state->cli = cli;
2829 state->rpc_call_id = get_rpc_call_id();
2831 prs_init_empty(&state->rpc_out, state, MARSHALL);
2833 cli->auth = talloc_move(cli, &auth);
2835 /* Marshall the outgoing data. */
2836 status = create_rpc_bind_req(cli, &state->rpc_out,
2837 state->rpc_call_id,
2838 &cli->abstract_syntax,
2839 &cli->transfer_syntax,
2840 cli->auth->auth_type,
2841 cli->auth->auth_level);
2843 if (!NT_STATUS_IS_OK(status)) {
2844 goto post_status;
2847 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2848 DCERPC_PKT_BIND_ACK);
2849 if (subreq == NULL) {
2850 goto fail;
2852 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2853 return req;
2855 post_status:
2856 tevent_req_nterror(req, status);
2857 return tevent_req_post(req, ev);
2858 fail:
2859 TALLOC_FREE(req);
2860 return NULL;
2863 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2865 struct tevent_req *req = tevent_req_callback_data(
2866 subreq, struct tevent_req);
2867 struct rpc_pipe_bind_state *state = tevent_req_data(
2868 req, struct rpc_pipe_bind_state);
2869 prs_struct reply_pdu;
2870 struct rpc_hdr_info hdr;
2871 struct rpc_hdr_ba_info hdr_ba;
2872 NTSTATUS status;
2874 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2875 TALLOC_FREE(subreq);
2876 if (!NT_STATUS_IS_OK(status)) {
2877 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2878 rpccli_pipe_txt(talloc_tos(), state->cli),
2879 nt_errstr(status)));
2880 tevent_req_nterror(req, status);
2881 return;
2884 /* Unmarshall the RPC header */
2885 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2886 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2887 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2888 return;
2891 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2892 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2893 "RPC_HDR_BA.\n"));
2894 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2895 return;
2898 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2899 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2900 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2901 return;
2904 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2905 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2908 * For authenticated binds we may need to do 3 or 4 leg binds.
2911 switch(state->cli->auth->auth_type) {
2913 case PIPE_AUTH_TYPE_NONE:
2914 case PIPE_AUTH_TYPE_SCHANNEL:
2915 /* Bind complete. */
2916 tevent_req_done(req);
2917 break;
2919 case PIPE_AUTH_TYPE_NTLMSSP:
2920 /* Need to send AUTH3 packet - no reply. */
2921 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2922 &reply_pdu);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 tevent_req_nterror(req, status);
2926 break;
2928 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2929 /* Need to send alter context request and reply. */
2930 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2931 &reply_pdu);
2932 if (!NT_STATUS_IS_OK(status)) {
2933 tevent_req_nterror(req, status);
2935 break;
2937 case PIPE_AUTH_TYPE_KRB5:
2938 /* */
2940 default:
2941 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2942 (unsigned int)state->cli->auth->auth_type));
2943 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2947 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2948 struct rpc_pipe_bind_state *state,
2949 struct rpc_hdr_info *phdr,
2950 prs_struct *reply_pdu)
2952 DATA_BLOB server_response = data_blob_null;
2953 DATA_BLOB client_reply = data_blob_null;
2954 struct rpc_hdr_auth_info hdr_auth;
2955 struct tevent_req *subreq;
2956 NTSTATUS status;
2958 if ((phdr->auth_len == 0)
2959 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2960 return NT_STATUS_INVALID_PARAMETER;
2963 if (!prs_set_offset(
2964 reply_pdu,
2965 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2966 return NT_STATUS_INVALID_PARAMETER;
2969 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2970 return NT_STATUS_INVALID_PARAMETER;
2973 /* TODO - check auth_type/auth_level match. */
2975 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2976 prs_copy_data_out((char *)server_response.data, reply_pdu,
2977 phdr->auth_len);
2979 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2980 server_response, &client_reply);
2982 if (!NT_STATUS_IS_OK(status)) {
2983 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2984 "blob failed: %s.\n", nt_errstr(status)));
2985 return status;
2988 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2990 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2991 state->cli->auth->auth_type,
2992 state->cli->auth->auth_level,
2993 &client_reply, &state->rpc_out);
2994 data_blob_free(&client_reply);
2996 if (!NT_STATUS_IS_OK(status)) {
2997 return status;
3000 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3001 (uint8_t *)prs_data_p(&state->rpc_out),
3002 prs_offset(&state->rpc_out));
3003 if (subreq == NULL) {
3004 return NT_STATUS_NO_MEMORY;
3006 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3007 return NT_STATUS_OK;
3010 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3012 struct tevent_req *req = tevent_req_callback_data(
3013 subreq, struct tevent_req);
3014 NTSTATUS status;
3016 status = rpc_write_recv(subreq);
3017 TALLOC_FREE(subreq);
3018 if (!NT_STATUS_IS_OK(status)) {
3019 tevent_req_nterror(req, status);
3020 return;
3022 tevent_req_done(req);
3025 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3026 struct rpc_pipe_bind_state *state,
3027 struct rpc_hdr_info *phdr,
3028 prs_struct *reply_pdu)
3030 DATA_BLOB server_spnego_response = data_blob_null;
3031 DATA_BLOB server_ntlm_response = data_blob_null;
3032 DATA_BLOB client_reply = data_blob_null;
3033 DATA_BLOB tmp_blob = data_blob_null;
3034 RPC_HDR_AUTH hdr_auth;
3035 struct tevent_req *subreq;
3036 NTSTATUS status;
3038 if ((phdr->auth_len == 0)
3039 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
3040 return NT_STATUS_INVALID_PARAMETER;
3043 /* Process the returned NTLMSSP blob first. */
3044 if (!prs_set_offset(
3045 reply_pdu,
3046 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3047 return NT_STATUS_INVALID_PARAMETER;
3050 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3051 return NT_STATUS_INVALID_PARAMETER;
3054 server_spnego_response = data_blob(NULL, phdr->auth_len);
3055 prs_copy_data_out((char *)server_spnego_response.data,
3056 reply_pdu, phdr->auth_len);
3059 * The server might give us back two challenges - tmp_blob is for the
3060 * second.
3062 if (!spnego_parse_challenge(server_spnego_response,
3063 &server_ntlm_response, &tmp_blob)) {
3064 data_blob_free(&server_spnego_response);
3065 data_blob_free(&server_ntlm_response);
3066 data_blob_free(&tmp_blob);
3067 return NT_STATUS_INVALID_PARAMETER;
3070 /* We're finished with the server spnego response and the tmp_blob. */
3071 data_blob_free(&server_spnego_response);
3072 data_blob_free(&tmp_blob);
3074 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3075 server_ntlm_response, &client_reply);
3077 /* Finished with the server_ntlm response */
3078 data_blob_free(&server_ntlm_response);
3080 if (!NT_STATUS_IS_OK(status)) {
3081 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3082 "using server blob failed.\n"));
3083 data_blob_free(&client_reply);
3084 return status;
3087 /* SPNEGO wrap the client reply. */
3088 tmp_blob = spnego_gen_auth(client_reply);
3089 data_blob_free(&client_reply);
3090 client_reply = tmp_blob;
3091 tmp_blob = data_blob_null;
3093 /* Now prepare the alter context pdu. */
3094 prs_init_empty(&state->rpc_out, state, MARSHALL);
3096 status = create_rpc_alter_context(state->rpc_call_id,
3097 &state->cli->abstract_syntax,
3098 &state->cli->transfer_syntax,
3099 state->cli->auth->auth_level,
3100 &client_reply,
3101 &state->rpc_out);
3102 data_blob_free(&client_reply);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 return status;
3108 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3109 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3110 if (subreq == NULL) {
3111 return NT_STATUS_NO_MEMORY;
3113 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3114 return NT_STATUS_OK;
3117 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3119 struct tevent_req *req = tevent_req_callback_data(
3120 subreq, struct tevent_req);
3121 struct rpc_pipe_bind_state *state = tevent_req_data(
3122 req, struct rpc_pipe_bind_state);
3123 DATA_BLOB server_spnego_response = data_blob_null;
3124 DATA_BLOB tmp_blob = data_blob_null;
3125 prs_struct reply_pdu;
3126 struct rpc_hdr_info hdr;
3127 struct rpc_hdr_auth_info hdr_auth;
3128 NTSTATUS status;
3130 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3131 TALLOC_FREE(subreq);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 tevent_req_nterror(req, status);
3134 return;
3137 /* Get the auth blob from the reply. */
3138 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3139 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3140 "unmarshall RPC_HDR.\n"));
3141 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3142 return;
3145 if (!prs_set_offset(
3146 &reply_pdu,
3147 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3148 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3149 return;
3152 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3153 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3154 return;
3157 server_spnego_response = data_blob(NULL, hdr.auth_len);
3158 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3159 hdr.auth_len);
3161 /* Check we got a valid auth response. */
3162 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3163 OID_NTLMSSP, &tmp_blob)) {
3164 data_blob_free(&server_spnego_response);
3165 data_blob_free(&tmp_blob);
3166 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3167 return;
3170 data_blob_free(&server_spnego_response);
3171 data_blob_free(&tmp_blob);
3173 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3174 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3175 tevent_req_done(req);
3178 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3180 return tevent_req_simple_recv_ntstatus(req);
3183 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3184 struct cli_pipe_auth_data *auth)
3186 TALLOC_CTX *frame = talloc_stackframe();
3187 struct event_context *ev;
3188 struct tevent_req *req;
3189 NTSTATUS status = NT_STATUS_OK;
3191 ev = event_context_init(frame);
3192 if (ev == NULL) {
3193 status = NT_STATUS_NO_MEMORY;
3194 goto fail;
3197 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3198 if (req == NULL) {
3199 status = NT_STATUS_NO_MEMORY;
3200 goto fail;
3203 if (!tevent_req_poll(req, ev)) {
3204 status = map_nt_error_from_unix(errno);
3205 goto fail;
3208 status = rpc_pipe_bind_recv(req);
3209 fail:
3210 TALLOC_FREE(frame);
3211 return status;
3214 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3216 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3217 unsigned int timeout)
3219 unsigned int old;
3221 if (rpc_cli->transport == NULL) {
3222 return RPCCLI_DEFAULT_TIMEOUT;
3225 if (rpc_cli->transport->set_timeout == NULL) {
3226 return RPCCLI_DEFAULT_TIMEOUT;
3229 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3230 if (old == 0) {
3231 return RPCCLI_DEFAULT_TIMEOUT;
3234 return old;
3237 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3239 if (rpc_cli == NULL) {
3240 return false;
3243 if (rpc_cli->transport == NULL) {
3244 return false;
3247 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3250 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3252 struct cli_state *cli;
3254 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3255 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3256 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3257 return true;
3260 cli = rpc_pipe_np_smb_conn(rpc_cli);
3261 if (cli == NULL) {
3262 return false;
3264 E_md4hash(cli->password ? cli->password : "", nt_hash);
3265 return true;
3268 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3269 struct cli_pipe_auth_data **presult)
3271 struct cli_pipe_auth_data *result;
3273 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3274 if (result == NULL) {
3275 return NT_STATUS_NO_MEMORY;
3278 result->auth_type = PIPE_AUTH_TYPE_NONE;
3279 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3281 result->user_name = talloc_strdup(result, "");
3282 result->domain = talloc_strdup(result, "");
3283 if ((result->user_name == NULL) || (result->domain == NULL)) {
3284 TALLOC_FREE(result);
3285 return NT_STATUS_NO_MEMORY;
3288 *presult = result;
3289 return NT_STATUS_OK;
3292 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3294 ntlmssp_end(&auth->a_u.ntlmssp_state);
3295 return 0;
3298 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3299 enum pipe_auth_type auth_type,
3300 enum dcerpc_AuthLevel auth_level,
3301 const char *domain,
3302 const char *username,
3303 const char *password,
3304 struct cli_pipe_auth_data **presult)
3306 struct cli_pipe_auth_data *result;
3307 NTSTATUS status;
3309 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3310 if (result == NULL) {
3311 return NT_STATUS_NO_MEMORY;
3314 result->auth_type = auth_type;
3315 result->auth_level = auth_level;
3317 result->user_name = talloc_strdup(result, username);
3318 result->domain = talloc_strdup(result, domain);
3319 if ((result->user_name == NULL) || (result->domain == NULL)) {
3320 status = NT_STATUS_NO_MEMORY;
3321 goto fail;
3324 status = ntlmssp_client_start(NULL,
3325 global_myname(),
3326 lp_workgroup(),
3327 lp_client_ntlmv2_auth(),
3328 &result->a_u.ntlmssp_state);
3329 if (!NT_STATUS_IS_OK(status)) {
3330 goto fail;
3333 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3335 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 goto fail;
3340 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 goto fail;
3345 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3346 if (!NT_STATUS_IS_OK(status)) {
3347 goto fail;
3351 * Turn off sign+seal to allow selected auth level to turn it back on.
3353 result->a_u.ntlmssp_state->neg_flags &=
3354 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3356 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3357 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3358 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3359 result->a_u.ntlmssp_state->neg_flags
3360 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3363 *presult = result;
3364 return NT_STATUS_OK;
3366 fail:
3367 TALLOC_FREE(result);
3368 return status;
3371 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3372 enum dcerpc_AuthLevel auth_level,
3373 struct netlogon_creds_CredentialState *creds,
3374 struct cli_pipe_auth_data **presult)
3376 struct cli_pipe_auth_data *result;
3378 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3379 if (result == NULL) {
3380 return NT_STATUS_NO_MEMORY;
3383 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3384 result->auth_level = auth_level;
3386 result->user_name = talloc_strdup(result, "");
3387 result->domain = talloc_strdup(result, domain);
3388 if ((result->user_name == NULL) || (result->domain == NULL)) {
3389 goto fail;
3392 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3393 if (result->a_u.schannel_auth == NULL) {
3394 goto fail;
3397 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3398 result->a_u.schannel_auth->seq_num = 0;
3399 result->a_u.schannel_auth->initiator = true;
3400 result->a_u.schannel_auth->creds = creds;
3402 *presult = result;
3403 return NT_STATUS_OK;
3405 fail:
3406 TALLOC_FREE(result);
3407 return NT_STATUS_NO_MEMORY;
3410 #ifdef HAVE_KRB5
3411 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3413 data_blob_free(&auth->session_key);
3414 return 0;
3416 #endif
3418 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3419 enum dcerpc_AuthLevel auth_level,
3420 const char *service_princ,
3421 const char *username,
3422 const char *password,
3423 struct cli_pipe_auth_data **presult)
3425 #ifdef HAVE_KRB5
3426 struct cli_pipe_auth_data *result;
3428 if ((username != NULL) && (password != NULL)) {
3429 int ret = kerberos_kinit_password(username, password, 0, NULL);
3430 if (ret != 0) {
3431 return NT_STATUS_ACCESS_DENIED;
3435 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3436 if (result == NULL) {
3437 return NT_STATUS_NO_MEMORY;
3440 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3441 result->auth_level = auth_level;
3444 * Username / domain need fixing!
3446 result->user_name = talloc_strdup(result, "");
3447 result->domain = talloc_strdup(result, "");
3448 if ((result->user_name == NULL) || (result->domain == NULL)) {
3449 goto fail;
3452 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3453 result, struct kerberos_auth_struct);
3454 if (result->a_u.kerberos_auth == NULL) {
3455 goto fail;
3457 talloc_set_destructor(result->a_u.kerberos_auth,
3458 cli_auth_kerberos_data_destructor);
3460 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3461 result, service_princ);
3462 if (result->a_u.kerberos_auth->service_principal == NULL) {
3463 goto fail;
3466 *presult = result;
3467 return NT_STATUS_OK;
3469 fail:
3470 TALLOC_FREE(result);
3471 return NT_STATUS_NO_MEMORY;
3472 #else
3473 return NT_STATUS_NOT_SUPPORTED;
3474 #endif
3478 * Create an rpc pipe client struct, connecting to a tcp port.
3480 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3481 uint16_t port,
3482 const struct ndr_syntax_id *abstract_syntax,
3483 struct rpc_pipe_client **presult)
3485 struct rpc_pipe_client *result;
3486 struct sockaddr_storage addr;
3487 NTSTATUS status;
3488 int fd;
3490 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3491 if (result == NULL) {
3492 return NT_STATUS_NO_MEMORY;
3495 result->abstract_syntax = *abstract_syntax;
3496 result->transfer_syntax = ndr_transfer_syntax;
3497 result->dispatch = cli_do_rpc_ndr;
3498 result->dispatch_send = cli_do_rpc_ndr_send;
3499 result->dispatch_recv = cli_do_rpc_ndr_recv;
3501 result->desthost = talloc_strdup(result, host);
3502 result->srv_name_slash = talloc_asprintf_strupper_m(
3503 result, "\\\\%s", result->desthost);
3504 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3505 status = NT_STATUS_NO_MEMORY;
3506 goto fail;
3509 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3510 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3512 if (!resolve_name(host, &addr, 0, false)) {
3513 status = NT_STATUS_NOT_FOUND;
3514 goto fail;
3517 status = open_socket_out(&addr, port, 60, &fd);
3518 if (!NT_STATUS_IS_OK(status)) {
3519 goto fail;
3521 set_socket_options(fd, lp_socket_options());
3523 status = rpc_transport_sock_init(result, fd, &result->transport);
3524 if (!NT_STATUS_IS_OK(status)) {
3525 close(fd);
3526 goto fail;
3529 result->transport->transport = NCACN_IP_TCP;
3531 *presult = result;
3532 return NT_STATUS_OK;
3534 fail:
3535 TALLOC_FREE(result);
3536 return status;
3540 * Determine the tcp port on which a dcerpc interface is listening
3541 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3542 * target host.
3544 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3545 const struct ndr_syntax_id *abstract_syntax,
3546 uint16_t *pport)
3548 NTSTATUS status;
3549 struct rpc_pipe_client *epm_pipe = NULL;
3550 struct cli_pipe_auth_data *auth = NULL;
3551 struct dcerpc_binding *map_binding = NULL;
3552 struct dcerpc_binding *res_binding = NULL;
3553 struct epm_twr_t *map_tower = NULL;
3554 struct epm_twr_t *res_towers = NULL;
3555 struct policy_handle *entry_handle = NULL;
3556 uint32_t num_towers = 0;
3557 uint32_t max_towers = 1;
3558 struct epm_twr_p_t towers;
3559 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3561 if (pport == NULL) {
3562 status = NT_STATUS_INVALID_PARAMETER;
3563 goto done;
3566 /* open the connection to the endpoint mapper */
3567 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3568 &ndr_table_epmapper.syntax_id,
3569 &epm_pipe);
3571 if (!NT_STATUS_IS_OK(status)) {
3572 goto done;
3575 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 goto done;
3580 status = rpc_pipe_bind(epm_pipe, auth);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 goto done;
3585 /* create tower for asking the epmapper */
3587 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3588 if (map_binding == NULL) {
3589 status = NT_STATUS_NO_MEMORY;
3590 goto done;
3593 map_binding->transport = NCACN_IP_TCP;
3594 map_binding->object = *abstract_syntax;
3595 map_binding->host = host; /* needed? */
3596 map_binding->endpoint = "0"; /* correct? needed? */
3598 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3599 if (map_tower == NULL) {
3600 status = NT_STATUS_NO_MEMORY;
3601 goto done;
3604 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3605 &(map_tower->tower));
3606 if (!NT_STATUS_IS_OK(status)) {
3607 goto done;
3610 /* allocate further parameters for the epm_Map call */
3612 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3613 if (res_towers == NULL) {
3614 status = NT_STATUS_NO_MEMORY;
3615 goto done;
3617 towers.twr = res_towers;
3619 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3620 if (entry_handle == NULL) {
3621 status = NT_STATUS_NO_MEMORY;
3622 goto done;
3625 /* ask the endpoint mapper for the port */
3627 status = rpccli_epm_Map(epm_pipe,
3628 tmp_ctx,
3629 CONST_DISCARD(struct GUID *,
3630 &(abstract_syntax->uuid)),
3631 map_tower,
3632 entry_handle,
3633 max_towers,
3634 &num_towers,
3635 &towers);
3637 if (!NT_STATUS_IS_OK(status)) {
3638 goto done;
3641 if (num_towers != 1) {
3642 status = NT_STATUS_UNSUCCESSFUL;
3643 goto done;
3646 /* extract the port from the answer */
3648 status = dcerpc_binding_from_tower(tmp_ctx,
3649 &(towers.twr->tower),
3650 &res_binding);
3651 if (!NT_STATUS_IS_OK(status)) {
3652 goto done;
3655 /* are further checks here necessary? */
3656 if (res_binding->transport != NCACN_IP_TCP) {
3657 status = NT_STATUS_UNSUCCESSFUL;
3658 goto done;
3661 *pport = (uint16_t)atoi(res_binding->endpoint);
3663 done:
3664 TALLOC_FREE(tmp_ctx);
3665 return status;
3669 * Create a rpc pipe client struct, connecting to a host via tcp.
3670 * The port is determined by asking the endpoint mapper on the given
3671 * host.
3673 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3674 const struct ndr_syntax_id *abstract_syntax,
3675 struct rpc_pipe_client **presult)
3677 NTSTATUS status;
3678 uint16_t port = 0;
3680 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 return status;
3685 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3686 abstract_syntax, presult);
3689 /********************************************************************
3690 Create a rpc pipe client struct, connecting to a unix domain socket
3691 ********************************************************************/
3692 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3693 const struct ndr_syntax_id *abstract_syntax,
3694 struct rpc_pipe_client **presult)
3696 struct rpc_pipe_client *result;
3697 struct sockaddr_un addr;
3698 NTSTATUS status;
3699 int fd;
3701 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3702 if (result == NULL) {
3703 return NT_STATUS_NO_MEMORY;
3706 result->abstract_syntax = *abstract_syntax;
3707 result->transfer_syntax = ndr_transfer_syntax;
3708 result->dispatch = cli_do_rpc_ndr;
3709 result->dispatch_send = cli_do_rpc_ndr_send;
3710 result->dispatch_recv = cli_do_rpc_ndr_recv;
3712 result->desthost = get_myname(result);
3713 result->srv_name_slash = talloc_asprintf_strupper_m(
3714 result, "\\\\%s", result->desthost);
3715 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3716 status = NT_STATUS_NO_MEMORY;
3717 goto fail;
3720 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3721 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3723 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3724 if (fd == -1) {
3725 status = map_nt_error_from_unix(errno);
3726 goto fail;
3729 ZERO_STRUCT(addr);
3730 addr.sun_family = AF_UNIX;
3731 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3733 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3734 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3735 strerror(errno)));
3736 close(fd);
3737 return map_nt_error_from_unix(errno);
3740 status = rpc_transport_sock_init(result, fd, &result->transport);
3741 if (!NT_STATUS_IS_OK(status)) {
3742 close(fd);
3743 goto fail;
3746 result->transport->transport = NCALRPC;
3748 *presult = result;
3749 return NT_STATUS_OK;
3751 fail:
3752 TALLOC_FREE(result);
3753 return status;
3756 struct rpc_pipe_client_np_ref {
3757 struct cli_state *cli;
3758 struct rpc_pipe_client *pipe;
3761 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3763 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3764 return 0;
3767 /****************************************************************************
3768 Open a named pipe over SMB to a remote server.
3770 * CAVEAT CALLER OF THIS FUNCTION:
3771 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3772 * so be sure that this function is called AFTER any structure (vs pointer)
3773 * assignment of the cli. In particular, libsmbclient does structure
3774 * assignments of cli, which invalidates the data in the returned
3775 * rpc_pipe_client if this function is called before the structure assignment
3776 * of cli.
3778 ****************************************************************************/
3780 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3781 const struct ndr_syntax_id *abstract_syntax,
3782 struct rpc_pipe_client **presult)
3784 struct rpc_pipe_client *result;
3785 NTSTATUS status;
3786 struct rpc_pipe_client_np_ref *np_ref;
3788 /* sanity check to protect against crashes */
3790 if ( !cli ) {
3791 return NT_STATUS_INVALID_HANDLE;
3794 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3795 if (result == NULL) {
3796 return NT_STATUS_NO_MEMORY;
3799 result->abstract_syntax = *abstract_syntax;
3800 result->transfer_syntax = ndr_transfer_syntax;
3801 result->dispatch = cli_do_rpc_ndr;
3802 result->dispatch_send = cli_do_rpc_ndr_send;
3803 result->dispatch_recv = cli_do_rpc_ndr_recv;
3804 result->desthost = talloc_strdup(result, cli->desthost);
3805 result->srv_name_slash = talloc_asprintf_strupper_m(
3806 result, "\\\\%s", result->desthost);
3808 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3809 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3811 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3812 TALLOC_FREE(result);
3813 return NT_STATUS_NO_MEMORY;
3816 status = rpc_transport_np_init(result, cli, abstract_syntax,
3817 &result->transport);
3818 if (!NT_STATUS_IS_OK(status)) {
3819 TALLOC_FREE(result);
3820 return status;
3823 result->transport->transport = NCACN_NP;
3825 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3826 if (np_ref == NULL) {
3827 TALLOC_FREE(result);
3828 return NT_STATUS_NO_MEMORY;
3830 np_ref->cli = cli;
3831 np_ref->pipe = result;
3833 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3834 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3836 *presult = result;
3837 return NT_STATUS_OK;
3840 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3841 struct rpc_cli_smbd_conn *conn,
3842 const struct ndr_syntax_id *syntax,
3843 struct rpc_pipe_client **presult)
3845 struct rpc_pipe_client *result;
3846 struct cli_pipe_auth_data *auth;
3847 NTSTATUS status;
3849 result = talloc(mem_ctx, struct rpc_pipe_client);
3850 if (result == NULL) {
3851 return NT_STATUS_NO_MEMORY;
3853 result->abstract_syntax = *syntax;
3854 result->transfer_syntax = ndr_transfer_syntax;
3855 result->dispatch = cli_do_rpc_ndr;
3856 result->dispatch_send = cli_do_rpc_ndr_send;
3857 result->dispatch_recv = cli_do_rpc_ndr_recv;
3858 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3859 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3861 result->desthost = talloc_strdup(result, global_myname());
3862 result->srv_name_slash = talloc_asprintf_strupper_m(
3863 result, "\\\\%s", global_myname());
3864 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3865 TALLOC_FREE(result);
3866 return NT_STATUS_NO_MEMORY;
3869 status = rpc_transport_smbd_init(result, conn, syntax,
3870 &result->transport);
3871 if (!NT_STATUS_IS_OK(status)) {
3872 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3873 nt_errstr(status)));
3874 TALLOC_FREE(result);
3875 return status;
3878 status = rpccli_anon_bind_data(result, &auth);
3879 if (!NT_STATUS_IS_OK(status)) {
3880 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3881 nt_errstr(status)));
3882 TALLOC_FREE(result);
3883 return status;
3886 status = rpc_pipe_bind(result, auth);
3887 if (!NT_STATUS_IS_OK(status)) {
3888 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3889 TALLOC_FREE(result);
3890 return status;
3893 result->transport->transport = NCACN_INTERNAL;
3895 *presult = result;
3896 return NT_STATUS_OK;
3899 /****************************************************************************
3900 Open a pipe to a remote server.
3901 ****************************************************************************/
3903 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3904 enum dcerpc_transport_t transport,
3905 const struct ndr_syntax_id *interface,
3906 struct rpc_pipe_client **presult)
3908 switch (transport) {
3909 case NCACN_IP_TCP:
3910 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3911 presult);
3912 case NCACN_NP:
3913 return rpc_pipe_open_np(cli, interface, presult);
3914 default:
3915 return NT_STATUS_NOT_IMPLEMENTED;
3919 /****************************************************************************
3920 Open a named pipe to an SMB server and bind anonymously.
3921 ****************************************************************************/
3923 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3924 enum dcerpc_transport_t transport,
3925 const struct ndr_syntax_id *interface,
3926 struct rpc_pipe_client **presult)
3928 struct rpc_pipe_client *result;
3929 struct cli_pipe_auth_data *auth;
3930 NTSTATUS status;
3932 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 return status;
3937 status = rpccli_anon_bind_data(result, &auth);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3940 nt_errstr(status)));
3941 TALLOC_FREE(result);
3942 return status;
3946 * This is a bit of an abstraction violation due to the fact that an
3947 * anonymous bind on an authenticated SMB inherits the user/domain
3948 * from the enclosing SMB creds
3951 TALLOC_FREE(auth->user_name);
3952 TALLOC_FREE(auth->domain);
3954 auth->user_name = talloc_strdup(auth, cli->user_name);
3955 auth->domain = talloc_strdup(auth, cli->domain);
3956 auth->user_session_key = data_blob_talloc(auth,
3957 cli->user_session_key.data,
3958 cli->user_session_key.length);
3960 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3961 TALLOC_FREE(result);
3962 return NT_STATUS_NO_MEMORY;
3965 status = rpc_pipe_bind(result, auth);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 int lvl = 0;
3968 if (ndr_syntax_id_equal(interface,
3969 &ndr_table_dssetup.syntax_id)) {
3970 /* non AD domains just don't have this pipe, avoid
3971 * level 0 statement in that case - gd */
3972 lvl = 3;
3974 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3975 "%s failed with error %s\n",
3976 get_pipe_name_from_syntax(talloc_tos(), interface),
3977 nt_errstr(status) ));
3978 TALLOC_FREE(result);
3979 return status;
3982 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3983 "%s and bound anonymously.\n",
3984 get_pipe_name_from_syntax(talloc_tos(), interface),
3985 cli->desthost));
3987 *presult = result;
3988 return NT_STATUS_OK;
3991 /****************************************************************************
3992 ****************************************************************************/
3994 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3995 const struct ndr_syntax_id *interface,
3996 struct rpc_pipe_client **presult)
3998 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3999 interface, presult);
4002 /****************************************************************************
4003 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4004 ****************************************************************************/
4006 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4007 const struct ndr_syntax_id *interface,
4008 enum dcerpc_transport_t transport,
4009 enum pipe_auth_type auth_type,
4010 enum dcerpc_AuthLevel auth_level,
4011 const char *domain,
4012 const char *username,
4013 const char *password,
4014 struct rpc_pipe_client **presult)
4016 struct rpc_pipe_client *result;
4017 struct cli_pipe_auth_data *auth;
4018 NTSTATUS status;
4020 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4021 if (!NT_STATUS_IS_OK(status)) {
4022 return status;
4025 status = rpccli_ntlmssp_bind_data(
4026 result, auth_type, auth_level, domain, username,
4027 password, &auth);
4028 if (!NT_STATUS_IS_OK(status)) {
4029 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4030 nt_errstr(status)));
4031 goto err;
4034 status = rpc_pipe_bind(result, auth);
4035 if (!NT_STATUS_IS_OK(status)) {
4036 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4037 nt_errstr(status) ));
4038 goto err;
4041 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4042 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4043 get_pipe_name_from_syntax(talloc_tos(), interface),
4044 cli->desthost, domain, username ));
4046 *presult = result;
4047 return NT_STATUS_OK;
4049 err:
4051 TALLOC_FREE(result);
4052 return status;
4055 /****************************************************************************
4056 External interface.
4057 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4058 ****************************************************************************/
4060 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4061 const struct ndr_syntax_id *interface,
4062 enum dcerpc_transport_t transport,
4063 enum dcerpc_AuthLevel auth_level,
4064 const char *domain,
4065 const char *username,
4066 const char *password,
4067 struct rpc_pipe_client **presult)
4069 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4070 interface,
4071 transport,
4072 PIPE_AUTH_TYPE_NTLMSSP,
4073 auth_level,
4074 domain,
4075 username,
4076 password,
4077 presult);
4080 /****************************************************************************
4081 External interface.
4082 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4083 ****************************************************************************/
4085 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4086 const struct ndr_syntax_id *interface,
4087 enum dcerpc_transport_t transport,
4088 enum dcerpc_AuthLevel auth_level,
4089 const char *domain,
4090 const char *username,
4091 const char *password,
4092 struct rpc_pipe_client **presult)
4094 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4095 interface,
4096 transport,
4097 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4098 auth_level,
4099 domain,
4100 username,
4101 password,
4102 presult);
4105 /****************************************************************************
4106 Get a the schannel session key out of an already opened netlogon pipe.
4107 ****************************************************************************/
4108 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4109 struct cli_state *cli,
4110 const char *domain,
4111 uint32 *pneg_flags)
4113 enum netr_SchannelType sec_chan_type = 0;
4114 unsigned char machine_pwd[16];
4115 const char *machine_account;
4116 NTSTATUS status;
4118 /* Get the machine account credentials from secrets.tdb. */
4119 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4120 &sec_chan_type))
4122 DEBUG(0, ("get_schannel_session_key: could not fetch "
4123 "trust account password for domain '%s'\n",
4124 domain));
4125 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4128 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4129 cli->desthost, /* server name */
4130 domain, /* domain */
4131 global_myname(), /* client name */
4132 machine_account, /* machine account name */
4133 machine_pwd,
4134 sec_chan_type,
4135 pneg_flags);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 DEBUG(3, ("get_schannel_session_key_common: "
4139 "rpccli_netlogon_setup_creds failed with result %s "
4140 "to server %s, domain %s, machine account %s.\n",
4141 nt_errstr(status), cli->desthost, domain,
4142 machine_account ));
4143 return status;
4146 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4147 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4148 cli->desthost));
4149 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4152 return NT_STATUS_OK;;
4155 /****************************************************************************
4156 Open a netlogon pipe and get the schannel session key.
4157 Now exposed to external callers.
4158 ****************************************************************************/
4161 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4162 const char *domain,
4163 uint32 *pneg_flags,
4164 struct rpc_pipe_client **presult)
4166 struct rpc_pipe_client *netlogon_pipe = NULL;
4167 NTSTATUS status;
4169 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4170 &netlogon_pipe);
4171 if (!NT_STATUS_IS_OK(status)) {
4172 return status;
4175 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4176 pneg_flags);
4177 if (!NT_STATUS_IS_OK(status)) {
4178 TALLOC_FREE(netlogon_pipe);
4179 return status;
4182 *presult = netlogon_pipe;
4183 return NT_STATUS_OK;
4186 /****************************************************************************
4187 External interface.
4188 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4189 using session_key. sign and seal.
4191 The *pdc will be stolen onto this new pipe
4192 ****************************************************************************/
4194 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4195 const struct ndr_syntax_id *interface,
4196 enum dcerpc_transport_t transport,
4197 enum dcerpc_AuthLevel auth_level,
4198 const char *domain,
4199 struct netlogon_creds_CredentialState **pdc,
4200 struct rpc_pipe_client **presult)
4202 struct rpc_pipe_client *result;
4203 struct cli_pipe_auth_data *auth;
4204 NTSTATUS status;
4206 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4207 if (!NT_STATUS_IS_OK(status)) {
4208 return status;
4211 status = rpccli_schannel_bind_data(result, domain, auth_level,
4212 *pdc, &auth);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4215 nt_errstr(status)));
4216 TALLOC_FREE(result);
4217 return status;
4220 status = rpc_pipe_bind(result, auth);
4221 if (!NT_STATUS_IS_OK(status)) {
4222 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4223 "cli_rpc_pipe_bind failed with error %s\n",
4224 nt_errstr(status) ));
4225 TALLOC_FREE(result);
4226 return status;
4230 * The credentials on a new netlogon pipe are the ones we are passed
4231 * in - reference them in
4233 result->dc = talloc_move(result, pdc);
4235 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4236 "for domain %s and bound using schannel.\n",
4237 get_pipe_name_from_syntax(talloc_tos(), interface),
4238 cli->desthost, domain ));
4240 *presult = result;
4241 return NT_STATUS_OK;
4244 /****************************************************************************
4245 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4246 Fetch the session key ourselves using a temporary netlogon pipe. This
4247 version uses an ntlmssp auth bound netlogon pipe to get the key.
4248 ****************************************************************************/
4250 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4251 const char *domain,
4252 const char *username,
4253 const char *password,
4254 uint32 *pneg_flags,
4255 struct rpc_pipe_client **presult)
4257 struct rpc_pipe_client *netlogon_pipe = NULL;
4258 NTSTATUS status;
4260 status = cli_rpc_pipe_open_spnego_ntlmssp(
4261 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4262 DCERPC_AUTH_LEVEL_PRIVACY,
4263 domain, username, password, &netlogon_pipe);
4264 if (!NT_STATUS_IS_OK(status)) {
4265 return status;
4268 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4269 pneg_flags);
4270 if (!NT_STATUS_IS_OK(status)) {
4271 TALLOC_FREE(netlogon_pipe);
4272 return status;
4275 *presult = netlogon_pipe;
4276 return NT_STATUS_OK;
4279 /****************************************************************************
4280 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4281 Fetch the session key ourselves using a temporary netlogon pipe. This version
4282 uses an ntlmssp bind to get the session key.
4283 ****************************************************************************/
4285 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4286 const struct ndr_syntax_id *interface,
4287 enum dcerpc_transport_t transport,
4288 enum dcerpc_AuthLevel auth_level,
4289 const char *domain,
4290 const char *username,
4291 const char *password,
4292 struct rpc_pipe_client **presult)
4294 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4295 struct rpc_pipe_client *netlogon_pipe = NULL;
4296 struct rpc_pipe_client *result = NULL;
4297 NTSTATUS status;
4299 status = get_schannel_session_key_auth_ntlmssp(
4300 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4301 if (!NT_STATUS_IS_OK(status)) {
4302 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4303 "key from server %s for domain %s.\n",
4304 cli->desthost, domain ));
4305 return status;
4308 status = cli_rpc_pipe_open_schannel_with_key(
4309 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4310 &result);
4312 /* Now we've bound using the session key we can close the netlog pipe. */
4313 TALLOC_FREE(netlogon_pipe);
4315 if (NT_STATUS_IS_OK(status)) {
4316 *presult = result;
4318 return status;
4321 /****************************************************************************
4322 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4323 Fetch the session key ourselves using a temporary netlogon pipe.
4324 ****************************************************************************/
4326 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4327 const struct ndr_syntax_id *interface,
4328 enum dcerpc_transport_t transport,
4329 enum dcerpc_AuthLevel auth_level,
4330 const char *domain,
4331 struct rpc_pipe_client **presult)
4333 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4334 struct rpc_pipe_client *netlogon_pipe = NULL;
4335 struct rpc_pipe_client *result = NULL;
4336 NTSTATUS status;
4338 status = get_schannel_session_key(cli, domain, &neg_flags,
4339 &netlogon_pipe);
4340 if (!NT_STATUS_IS_OK(status)) {
4341 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4342 "key from server %s for domain %s.\n",
4343 cli->desthost, domain ));
4344 return status;
4347 status = cli_rpc_pipe_open_schannel_with_key(
4348 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4349 &result);
4351 /* Now we've bound using the session key we can close the netlog pipe. */
4352 TALLOC_FREE(netlogon_pipe);
4354 if (NT_STATUS_IS_OK(status)) {
4355 *presult = result;
4358 return status;
4361 /****************************************************************************
4362 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4363 The idea is this can be called with service_princ, username and password all
4364 NULL so long as the caller has a TGT.
4365 ****************************************************************************/
4367 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4368 const struct ndr_syntax_id *interface,
4369 enum dcerpc_AuthLevel auth_level,
4370 const char *service_princ,
4371 const char *username,
4372 const char *password,
4373 struct rpc_pipe_client **presult)
4375 #ifdef HAVE_KRB5
4376 struct rpc_pipe_client *result;
4377 struct cli_pipe_auth_data *auth;
4378 NTSTATUS status;
4380 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4381 if (!NT_STATUS_IS_OK(status)) {
4382 return status;
4385 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4386 username, password, &auth);
4387 if (!NT_STATUS_IS_OK(status)) {
4388 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4389 nt_errstr(status)));
4390 TALLOC_FREE(result);
4391 return status;
4394 status = rpc_pipe_bind(result, auth);
4395 if (!NT_STATUS_IS_OK(status)) {
4396 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4397 "with error %s\n", nt_errstr(status)));
4398 TALLOC_FREE(result);
4399 return status;
4402 *presult = result;
4403 return NT_STATUS_OK;
4404 #else
4405 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4406 return NT_STATUS_NOT_IMPLEMENTED;
4407 #endif
4410 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4411 struct rpc_pipe_client *cli,
4412 DATA_BLOB *session_key)
4414 if (!session_key || !cli) {
4415 return NT_STATUS_INVALID_PARAMETER;
4418 if (!cli->auth) {
4419 return NT_STATUS_INVALID_PARAMETER;
4422 switch (cli->auth->auth_type) {
4423 case PIPE_AUTH_TYPE_SCHANNEL:
4424 *session_key = data_blob_talloc(mem_ctx,
4425 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4426 break;
4427 case PIPE_AUTH_TYPE_NTLMSSP:
4428 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4429 *session_key = data_blob_talloc(mem_ctx,
4430 cli->auth->a_u.ntlmssp_state->session_key.data,
4431 cli->auth->a_u.ntlmssp_state->session_key.length);
4432 break;
4433 case PIPE_AUTH_TYPE_KRB5:
4434 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4435 *session_key = data_blob_talloc(mem_ctx,
4436 cli->auth->a_u.kerberos_auth->session_key.data,
4437 cli->auth->a_u.kerberos_auth->session_key.length);
4438 break;
4439 case PIPE_AUTH_TYPE_NONE:
4440 *session_key = data_blob_talloc(mem_ctx,
4441 cli->auth->user_session_key.data,
4442 cli->auth->user_session_key.length);
4443 break;
4444 default:
4445 return NT_STATUS_NO_USER_SESSION_KEY;
4448 return NT_STATUS_OK;