2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &syntax_spoolss },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
85 struct cli_state *cli,
86 const struct ndr_syntax_id *interface)
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
104 /********************************************************************
105 Map internal value to wire value.
106 ********************************************************************/
108 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
112 case PIPE_AUTH_TYPE_NONE:
113 return RPC_ANONYMOUS_AUTH_TYPE;
115 case PIPE_AUTH_TYPE_NTLMSSP:
116 return RPC_NTLMSSP_AUTH_TYPE;
118 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
119 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
120 return RPC_SPNEGO_AUTH_TYPE;
122 case PIPE_AUTH_TYPE_SCHANNEL:
123 return RPC_SCHANNEL_AUTH_TYPE;
125 case PIPE_AUTH_TYPE_KRB5:
126 return RPC_KRB5_AUTH_TYPE;
129 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
131 (unsigned int)auth_type ));
137 /********************************************************************
138 Pipe description for a DEBUG
139 ********************************************************************/
140 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
144 switch (cli->transport_type) {
146 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
149 cli->trans.np.pipe_name,
150 (unsigned int)(cli->trans.np.fnum));
153 case NCACN_UNIX_STREAM:
154 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
155 cli->desthost, cli->trans.sock.fd);
158 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
161 SMB_ASSERT(result != NULL);
165 /********************************************************************
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
176 * Realloc pdu to have a least "size" bytes
179 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
183 if (prs_data_size(pdu) >= size) {
187 extra_size = size - prs_data_size(pdu);
189 if (!prs_force_grow(pdu, extra_size)) {
190 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
191 "%d bytes.\n", (int)extra_size));
195 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
196 (int)extra_size, prs_data_size(pdu)));
201 /*******************************************************************
202 Use SMBreadX to get rest of one fragment's worth of rpc data.
203 Reads the whole size or give an error message
204 ********************************************************************/
206 struct rpc_read_state {
207 struct event_context *ev;
208 struct rpc_pipe_client *cli;
214 static void rpc_read_np_done(struct async_req *subreq);
215 static void rpc_read_sock_done(struct async_req *subreq);
217 static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx,
218 struct event_context *ev,
219 struct rpc_pipe_client *cli,
220 char *data, size_t size)
222 struct async_req *result, *subreq;
223 struct rpc_read_state *state;
225 result = async_req_new(mem_ctx);
226 if (result == NULL) {
229 state = talloc(result, struct rpc_read_state);
233 result->private_data = state;
241 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
243 if (cli->transport_type == NCACN_NP) {
244 subreq = cli_read_andx_send(
245 state, ev, cli->trans.np.cli,
246 cli->trans.np.fnum, 0, size);
247 if (subreq == NULL) {
248 DEBUG(10, ("cli_read_andx_send failed\n"));
251 subreq->async.fn = rpc_read_np_done;
252 subreq->async.priv = result;
256 if ((cli->transport_type == NCACN_IP_TCP)
257 || (cli->transport_type == NCACN_UNIX_STREAM)) {
258 subreq = recvall_send(state, ev, cli->trans.sock.fd,
260 if (subreq == NULL) {
261 DEBUG(10, ("recvall_send failed\n"));
264 subreq->async.fn = rpc_read_sock_done;
265 subreq->async.priv = result;
269 if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) {
277 static void rpc_read_np_done(struct async_req *subreq)
279 struct async_req *req = talloc_get_type_abort(
280 subreq->async.priv, struct async_req);
281 struct rpc_read_state *state = talloc_get_type_abort(
282 req->private_data, struct rpc_read_state);
287 status = cli_read_andx_recv(subreq, &received, &rcvbuf);
289 * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
292 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
293 status = NT_STATUS_OK;
295 if (!NT_STATUS_IS_OK(status)) {
297 async_req_error(req, status);
301 memcpy(state->data + state->num_read, rcvbuf, received);
304 state->num_read += received;
306 if (state->num_read == state->size) {
311 subreq = cli_read_andx_send(
312 state, state->ev, state->cli->trans.np.cli,
313 state->cli->trans.np.fnum, 0,
314 state->size - state->num_read);
316 if (async_req_nomem(subreq, req)) {
320 subreq->async.fn = rpc_read_np_done;
321 subreq->async.priv = req;
324 static void rpc_read_sock_done(struct async_req *subreq)
326 struct async_req *req = talloc_get_type_abort(
327 subreq->async.priv, struct async_req);
330 status = recvall_recv(subreq);
332 if (!NT_STATUS_IS_OK(status)) {
333 async_req_error(req, status);
340 static NTSTATUS rpc_read_recv(struct async_req *req)
342 return async_req_simple_recv(req);
345 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
346 struct rpc_hdr_info *prhdr,
350 * This next call sets the endian bit correctly in current_pdu. We
351 * will propagate this to rbuf later.
354 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
355 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
356 return NT_STATUS_BUFFER_TOO_SMALL;
359 if (prhdr->frag_len > cli->max_recv_frag) {
360 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
361 " we only allow %d\n", (int)prhdr->frag_len,
362 (int)cli->max_recv_frag));
363 return NT_STATUS_BUFFER_TOO_SMALL;
369 /****************************************************************************
370 Try and get a PDU's worth of data from current_pdu. If not, then read more
372 ****************************************************************************/
374 struct get_complete_pdu_state {
375 struct event_context *ev;
376 struct rpc_pipe_client *cli;
377 struct rpc_hdr_info *prhdr;
381 static void get_complete_pdu_got_header(struct async_req *subreq);
382 static void get_complete_pdu_got_rest(struct async_req *subreq);
384 static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx,
385 struct event_context *ev,
386 struct rpc_pipe_client *cli,
387 struct rpc_hdr_info *prhdr,
390 struct async_req *result, *subreq;
391 struct get_complete_pdu_state *state;
395 result = async_req_new(mem_ctx);
396 if (result == NULL) {
399 state = talloc(result, struct get_complete_pdu_state);
403 result->private_data = state;
407 state->prhdr = prhdr;
410 pdu_len = prs_data_size(pdu);
411 if (pdu_len < RPC_HEADER_LEN) {
412 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
413 status = NT_STATUS_NO_MEMORY;
416 subreq = rpc_read_send(state, state->ev, state->cli,
417 prs_data_p(state->pdu) + pdu_len,
418 RPC_HEADER_LEN - pdu_len);
419 if (subreq == NULL) {
420 status = NT_STATUS_NO_MEMORY;
423 subreq->async.fn = get_complete_pdu_got_header;
424 subreq->async.priv = result;
428 status = parse_rpc_header(cli, prhdr, pdu);
429 if (!NT_STATUS_IS_OK(status)) {
434 * Ensure we have frag_len bytes of data.
436 if (pdu_len < prhdr->frag_len) {
437 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
438 status = NT_STATUS_NO_MEMORY;
441 subreq = rpc_read_send(state, state->ev, state->cli,
442 prs_data_p(pdu) + pdu_len,
443 prhdr->frag_len - pdu_len);
444 if (subreq == NULL) {
445 status = NT_STATUS_NO_MEMORY;
448 subreq->async.fn = get_complete_pdu_got_rest;
449 subreq->async.priv = result;
453 status = NT_STATUS_OK;
455 if (async_post_status(result, ev, status)) {
463 static void get_complete_pdu_got_header(struct async_req *subreq)
465 struct async_req *req = talloc_get_type_abort(
466 subreq->async.priv, struct async_req);
467 struct get_complete_pdu_state *state = talloc_get_type_abort(
468 req->private_data, struct get_complete_pdu_state);
471 status = rpc_read_recv(subreq);
473 if (!NT_STATUS_IS_OK(status)) {
474 async_req_error(req, status);
478 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
479 if (!NT_STATUS_IS_OK(status)) {
480 async_req_error(req, status);
484 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
485 async_req_error(req, NT_STATUS_NO_MEMORY);
490 * We're here in this piece of code because we've read exactly
491 * RPC_HEADER_LEN bytes into state->pdu.
494 subreq = rpc_read_send(state, state->ev, state->cli,
495 prs_data_p(state->pdu) + RPC_HEADER_LEN,
496 state->prhdr->frag_len - RPC_HEADER_LEN);
497 if (async_req_nomem(subreq, req)) {
500 subreq->async.fn = get_complete_pdu_got_rest;
501 subreq->async.priv = req;
504 static void get_complete_pdu_got_rest(struct async_req *subreq)
506 struct async_req *req = talloc_get_type_abort(
507 subreq->async.priv, struct async_req);
510 status = rpc_read_recv(subreq);
512 if (!NT_STATUS_IS_OK(status)) {
513 async_req_error(req, status);
519 static NTSTATUS get_complete_pdu_recv(struct async_req *req)
521 return async_req_simple_recv(req);
524 static NTSTATUS get_complete_pdu(struct rpc_pipe_client *cli,
525 struct rpc_hdr_info *prhdr,
528 TALLOC_CTX *frame = talloc_stackframe();
529 struct event_context *ev;
530 struct async_req *req;
531 NTSTATUS status = NT_STATUS_NO_MEMORY;
533 ev = event_context_init(frame);
538 req = get_complete_pdu_send(frame, ev, cli, prhdr, pdu);
543 while (req->state < ASYNC_REQ_DONE) {
547 status = get_complete_pdu_recv(req);
553 /****************************************************************************
554 NTLMSSP specific sign/seal.
555 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
556 In fact I should probably abstract these into identical pieces of code... JRA.
557 ****************************************************************************/
559 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
560 prs_struct *current_pdu,
561 uint8 *p_ss_padding_len)
563 RPC_HDR_AUTH auth_info;
564 uint32 save_offset = prs_offset(current_pdu);
565 uint32 auth_len = prhdr->auth_len;
566 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
567 unsigned char *data = NULL;
569 unsigned char *full_packet_data = NULL;
570 size_t full_packet_data_len;
574 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
575 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
579 if (!ntlmssp_state) {
580 return NT_STATUS_INVALID_PARAMETER;
583 /* Ensure there's enough data for an authenticated response. */
584 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
585 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
586 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
587 (unsigned int)auth_len ));
588 return NT_STATUS_BUFFER_TOO_SMALL;
592 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
593 * after the RPC header.
594 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
595 * functions as NTLMv2 checks the rpc headers also.
598 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
599 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
601 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
602 full_packet_data_len = prhdr->frag_len - auth_len;
604 /* Pull the auth header and the following data into a blob. */
605 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
606 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
607 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
608 return NT_STATUS_BUFFER_TOO_SMALL;
611 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
612 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
613 return NT_STATUS_BUFFER_TOO_SMALL;
616 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
617 auth_blob.length = auth_len;
619 switch (cli->auth->auth_level) {
620 case PIPE_AUTH_LEVEL_PRIVACY:
621 /* Data is encrypted. */
622 status = ntlmssp_unseal_packet(ntlmssp_state,
625 full_packet_data_len,
627 if (!NT_STATUS_IS_OK(status)) {
628 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
629 "packet from %s. Error was %s.\n",
630 rpccli_pipe_txt(debug_ctx(), cli),
631 nt_errstr(status) ));
635 case PIPE_AUTH_LEVEL_INTEGRITY:
636 /* Data is signed. */
637 status = ntlmssp_check_packet(ntlmssp_state,
640 full_packet_data_len,
642 if (!NT_STATUS_IS_OK(status)) {
643 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
644 "packet from %s. Error was %s.\n",
645 rpccli_pipe_txt(debug_ctx(), cli),
646 nt_errstr(status) ));
651 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
652 "auth level %d\n", cli->auth->auth_level));
653 return NT_STATUS_INVALID_INFO_CLASS;
657 * Return the current pointer to the data offset.
660 if(!prs_set_offset(current_pdu, save_offset)) {
661 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
662 (unsigned int)save_offset ));
663 return NT_STATUS_BUFFER_TOO_SMALL;
667 * Remember the padding length. We must remove it from the real data
668 * stream once the sign/seal is done.
671 *p_ss_padding_len = auth_info.auth_pad_len;
676 /****************************************************************************
677 schannel specific sign/seal.
678 ****************************************************************************/
680 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
681 prs_struct *current_pdu,
682 uint8 *p_ss_padding_len)
684 RPC_HDR_AUTH auth_info;
685 RPC_AUTH_SCHANNEL_CHK schannel_chk;
686 uint32 auth_len = prhdr->auth_len;
687 uint32 save_offset = prs_offset(current_pdu);
688 struct schannel_auth_struct *schannel_auth =
689 cli->auth->a_u.schannel_auth;
692 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
693 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
697 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
698 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
699 return NT_STATUS_INVALID_PARAMETER;
702 if (!schannel_auth) {
703 return NT_STATUS_INVALID_PARAMETER;
706 /* Ensure there's enough data for an authenticated response. */
707 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
708 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
709 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
710 (unsigned int)auth_len ));
711 return NT_STATUS_INVALID_PARAMETER;
714 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
716 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
717 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
718 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
719 return NT_STATUS_BUFFER_TOO_SMALL;
722 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
723 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
724 return NT_STATUS_BUFFER_TOO_SMALL;
727 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
728 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
729 auth_info.auth_type));
730 return NT_STATUS_BUFFER_TOO_SMALL;
733 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
734 &schannel_chk, current_pdu, 0)) {
735 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
736 return NT_STATUS_BUFFER_TOO_SMALL;
739 if (!schannel_decode(schannel_auth,
740 cli->auth->auth_level,
743 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
745 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
746 "Connection to %s.\n",
747 rpccli_pipe_txt(debug_ctx(), cli)));
748 return NT_STATUS_INVALID_PARAMETER;
751 /* The sequence number gets incremented on both send and receive. */
752 schannel_auth->seq_num++;
755 * Return the current pointer to the data offset.
758 if(!prs_set_offset(current_pdu, save_offset)) {
759 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
760 (unsigned int)save_offset ));
761 return NT_STATUS_BUFFER_TOO_SMALL;
765 * Remember the padding length. We must remove it from the real data
766 * stream once the sign/seal is done.
769 *p_ss_padding_len = auth_info.auth_pad_len;
774 /****************************************************************************
775 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
776 ****************************************************************************/
778 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
779 prs_struct *current_pdu,
780 uint8 *p_ss_padding_len)
782 NTSTATUS ret = NT_STATUS_OK;
784 /* Paranioa checks for auth_len. */
785 if (prhdr->auth_len) {
786 if (prhdr->auth_len > prhdr->frag_len) {
787 return NT_STATUS_INVALID_PARAMETER;
790 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
791 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
792 /* Integer wrap attempt. */
793 return NT_STATUS_INVALID_PARAMETER;
798 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
801 switch(cli->auth->auth_type) {
802 case PIPE_AUTH_TYPE_NONE:
803 if (prhdr->auth_len) {
804 DEBUG(3, ("cli_pipe_validate_rpc_response: "
805 "Connection to %s - got non-zero "
807 rpccli_pipe_txt(debug_ctx(), cli),
808 (unsigned int)prhdr->auth_len ));
809 return NT_STATUS_INVALID_PARAMETER;
813 case PIPE_AUTH_TYPE_NTLMSSP:
814 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
815 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
816 if (!NT_STATUS_IS_OK(ret)) {
821 case PIPE_AUTH_TYPE_SCHANNEL:
822 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
823 if (!NT_STATUS_IS_OK(ret)) {
828 case PIPE_AUTH_TYPE_KRB5:
829 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
831 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
832 "to %s - unknown internal auth type %u.\n",
833 rpccli_pipe_txt(debug_ctx(), cli),
834 cli->auth->auth_type ));
835 return NT_STATUS_INVALID_INFO_CLASS;
841 /****************************************************************************
842 Do basic authentication checks on an incoming pdu.
843 ****************************************************************************/
845 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
846 prs_struct *current_pdu,
847 uint8 expected_pkt_type,
850 prs_struct *return_data)
853 NTSTATUS ret = NT_STATUS_OK;
854 uint32 current_pdu_len = prs_data_size(current_pdu);
856 if (current_pdu_len != prhdr->frag_len) {
857 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
858 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
859 return NT_STATUS_INVALID_PARAMETER;
863 * Point the return values at the real data including the RPC
864 * header. Just in case the caller wants it.
866 *ppdata = prs_data_p(current_pdu);
867 *pdata_len = current_pdu_len;
869 /* Ensure we have the correct type. */
870 switch (prhdr->pkt_type) {
871 case RPC_ALTCONTRESP:
874 /* Alter context and bind ack share the same packet definitions. */
880 RPC_HDR_RESP rhdr_resp;
881 uint8 ss_padding_len = 0;
883 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
884 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
885 return NT_STATUS_BUFFER_TOO_SMALL;
888 /* Here's where we deal with incoming sign/seal. */
889 ret = cli_pipe_validate_rpc_response(cli, prhdr,
890 current_pdu, &ss_padding_len);
891 if (!NT_STATUS_IS_OK(ret)) {
895 /* Point the return values at the NDR data. Remember to remove any ss padding. */
896 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
898 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
899 return NT_STATUS_BUFFER_TOO_SMALL;
902 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
904 /* Remember to remove the auth footer. */
905 if (prhdr->auth_len) {
906 /* We've already done integer wrap tests on auth_len in
907 cli_pipe_validate_rpc_response(). */
908 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
909 return NT_STATUS_BUFFER_TOO_SMALL;
911 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
914 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
915 current_pdu_len, *pdata_len, ss_padding_len ));
918 * If this is the first reply, and the allocation hint is reasonably, try and
919 * set up the return_data parse_struct to the correct size.
922 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
923 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
924 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
925 "too large to allocate\n",
926 (unsigned int)rhdr_resp.alloc_hint ));
927 return NT_STATUS_NO_MEMORY;
935 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
936 "received from %s!\n",
937 rpccli_pipe_txt(debug_ctx(), cli)));
938 /* Use this for now... */
939 return NT_STATUS_NETWORK_ACCESS_DENIED;
943 RPC_HDR_RESP rhdr_resp;
944 RPC_HDR_FAULT fault_resp;
946 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
947 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
948 return NT_STATUS_BUFFER_TOO_SMALL;
951 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
952 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
953 return NT_STATUS_BUFFER_TOO_SMALL;
956 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
957 "code %s received from %s!\n",
958 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
959 rpccli_pipe_txt(debug_ctx(), cli)));
960 if (NT_STATUS_IS_OK(fault_resp.status)) {
961 return NT_STATUS_UNSUCCESSFUL;
963 return fault_resp.status;
968 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
970 (unsigned int)prhdr->pkt_type,
971 rpccli_pipe_txt(debug_ctx(), cli)));
972 return NT_STATUS_INVALID_INFO_CLASS;
975 if (prhdr->pkt_type != expected_pkt_type) {
976 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
977 "got an unexpected RPC packet type - %u, not %u\n",
978 rpccli_pipe_txt(debug_ctx(), cli),
981 return NT_STATUS_INVALID_INFO_CLASS;
984 /* Do this just before return - we don't want to modify any rpc header
985 data before now as we may have needed to do cryptographic actions on
988 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
989 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
990 "setting fragment first/last ON.\n"));
991 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
997 /****************************************************************************
998 Ensure we eat the just processed pdu from the current_pdu prs_struct.
999 Normally the frag_len and buffer size will match, but on the first trans
1000 reply there is a theoretical chance that buffer size > frag_len, so we must
1002 ****************************************************************************/
1004 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1006 uint32 current_pdu_len = prs_data_size(current_pdu);
1008 if (current_pdu_len < prhdr->frag_len) {
1009 return NT_STATUS_BUFFER_TOO_SMALL;
1013 if (current_pdu_len == (uint32)prhdr->frag_len) {
1014 prs_mem_free(current_pdu);
1015 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1016 /* Make current_pdu dynamic with no memory. */
1017 prs_give_memory(current_pdu, 0, 0, True);
1018 return NT_STATUS_OK;
1022 * Oh no ! More data in buffer than we processed in current pdu.
1023 * Cheat. Move the data down and shrink the buffer.
1026 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1027 current_pdu_len - prhdr->frag_len);
1029 /* Remember to set the read offset back to zero. */
1030 prs_set_offset(current_pdu, 0);
1032 /* Shrink the buffer. */
1033 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1034 return NT_STATUS_BUFFER_TOO_SMALL;
1037 return NT_STATUS_OK;
1040 /****************************************************************************
1041 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1042 ****************************************************************************/
1044 struct cli_api_pipe_state {
1045 struct event_context *ev;
1046 struct rpc_pipe_client *cli;
1047 uint32_t max_rdata_len;
1052 static void cli_api_pipe_np_trans_done(struct async_req *subreq);
1053 static void cli_api_pipe_sock_send_done(struct async_req *subreq);
1054 static void cli_api_pipe_sock_read_done(struct async_req *subreq);
1056 static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1057 struct event_context *ev,
1058 struct rpc_pipe_client *cli,
1059 uint8_t *data, size_t data_len,
1060 uint32_t max_rdata_len)
1062 struct async_req *result, *subreq;
1063 struct cli_api_pipe_state *state;
1066 result = async_req_new(mem_ctx);
1067 if (result == NULL) {
1070 state = talloc(result, struct cli_api_pipe_state);
1071 if (state == NULL) {
1074 result->private_data = state;
1078 state->max_rdata_len = max_rdata_len;
1080 if (state->max_rdata_len < RPC_HEADER_LEN) {
1082 * For a RPC reply we always need at least RPC_HEADER_LEN
1083 * bytes. We check this here because we will receive
1084 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1086 status = NT_STATUS_INVALID_PARAMETER;
1090 if (cli->transport_type == NCACN_NP) {
1093 SSVAL(setup+0, 0, TRANSACT_DCERPCCMD);
1094 SSVAL(setup+1, 0, cli->trans.np.fnum);
1096 subreq = cli_trans_send(
1097 state, ev, cli->trans.np.cli, SMBtrans,
1098 "\\PIPE\\", 0, 0, 0, setup, 2, 0,
1099 NULL, 0, 0, data, data_len, max_rdata_len);
1100 if (subreq == NULL) {
1101 status = NT_STATUS_NO_MEMORY;
1104 subreq->async.fn = cli_api_pipe_np_trans_done;
1105 subreq->async.priv = result;
1109 if ((cli->transport_type == NCACN_IP_TCP)
1110 || (cli->transport_type == NCACN_UNIX_STREAM)) {
1111 subreq = sendall_send(state, ev, cli->trans.sock.fd,
1113 if (subreq == NULL) {
1114 status = NT_STATUS_NO_MEMORY;
1117 subreq->async.fn = cli_api_pipe_sock_send_done;
1118 subreq->async.priv = result;
1122 status = NT_STATUS_INVALID_PARAMETER;
1125 if (async_post_status(result, ev, status)) {
1129 TALLOC_FREE(result);
1133 static void cli_api_pipe_np_trans_done(struct async_req *subreq)
1135 struct async_req *req = talloc_get_type_abort(
1136 subreq->async.priv, struct async_req);
1137 struct cli_api_pipe_state *state = talloc_get_type_abort(
1138 req->private_data, struct cli_api_pipe_state);
1141 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
1142 &state->rdata, &state->rdata_len);
1143 TALLOC_FREE(subreq);
1144 if (!NT_STATUS_IS_OK(status)) {
1145 async_req_error(req, status);
1148 async_req_done(req);
1151 static void cli_api_pipe_sock_send_done(struct async_req *subreq)
1153 struct async_req *req = talloc_get_type_abort(
1154 subreq->async.priv, struct async_req);
1155 struct cli_api_pipe_state *state = talloc_get_type_abort(
1156 req->private_data, struct cli_api_pipe_state);
1159 status = sendall_recv(subreq);
1160 TALLOC_FREE(subreq);
1161 if (!NT_STATUS_IS_OK(status)) {
1162 async_req_error(req, status);
1166 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1167 if (async_req_nomem(state->rdata, req)) {
1170 state->rdata_len = RPC_HEADER_LEN;
1172 subreq = recvall_send(state, state->ev, state->cli->trans.sock.fd,
1173 state->rdata, RPC_HEADER_LEN, 0);
1174 if (async_req_nomem(subreq, req)) {
1177 subreq->async.fn = cli_api_pipe_sock_read_done;
1178 subreq->async.priv = req;
1181 static void cli_api_pipe_sock_read_done(struct async_req *subreq)
1183 struct async_req *req = talloc_get_type_abort(
1184 subreq->async.priv, struct async_req);
1187 status = recvall_recv(subreq);
1188 TALLOC_FREE(subreq);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 async_req_error(req, status);
1193 async_req_done(req);
1196 static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
1197 uint8_t **prdata, uint32_t *prdata_len)
1199 struct cli_api_pipe_state *state = talloc_get_type_abort(
1200 req->private_data, struct cli_api_pipe_state);
1203 if (async_req_is_error(req, &status)) {
1207 *prdata = talloc_move(mem_ctx, &state->rdata);
1208 *prdata_len = state->rdata_len;
1209 return NT_STATUS_OK;
1212 static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
1213 uint8_t *data, uint32_t data_len,
1214 uint32_t max_rdata_len,
1215 uint8_t **prdata, uint32_t *prdata_len)
1217 TALLOC_CTX *frame = talloc_stackframe();
1218 struct event_context *ev;
1219 struct async_req *req;
1220 NTSTATUS status = NT_STATUS_NO_MEMORY;
1222 ev = event_context_init(frame);
1227 req = cli_api_pipe_send(frame, ev, cli, data, data_len, max_rdata_len);
1232 while (req->state < ASYNC_REQ_DONE) {
1233 event_loop_once(ev);
1236 status = cli_api_pipe_recv(req, mem_ctx, prdata, prdata_len);
1242 /****************************************************************************
1243 Send data on an rpc pipe via trans. The prs_struct data must be the last
1244 pdu fragment of an NDR data stream.
1246 Receive response data from an rpc pipe, which may be large...
1248 Read the first fragment: unfortunately have to use SMBtrans for the first
1249 bit, then SMBreadX for subsequent bits.
1251 If first fragment received also wasn't the last fragment, continue
1252 getting fragments until we _do_ receive the last fragment.
1254 Request/Response PDU's look like the following...
1256 |<------------------PDU len----------------------------------------------->|
1257 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1259 +------------+-----------------+-------------+---------------+-------------+
1260 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1261 +------------+-----------------+-------------+---------------+-------------+
1263 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1264 signing & sealing being negotiated.
1266 ****************************************************************************/
1268 static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
1269 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
1270 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
1271 uint8 expected_pkt_type)
1274 uint32 data_len = prs_offset(data);
1275 uint8_t *rdata = NULL;
1276 uint8_t *rdata_copy;
1277 uint32_t rdata_len = 0;
1278 uint32 current_rbuf_offset = 0;
1279 prs_struct current_pdu;
1281 if (data_len > cli->max_xmit_frag) {
1282 /* Ensure we're not sending too much. */
1283 return NT_STATUS_INVALID_PARAMETER;
1286 /* Set up the current pdu parse struct. */
1287 prs_init_empty(¤t_pdu, talloc_tos(), UNMARSHALL);
1289 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1291 ret = cli_api_pipe(talloc_tos(), cli,
1292 (uint8_t *)prs_data_p(data), prs_offset(data),
1293 cli->max_recv_frag, &rdata, &rdata_len);
1294 if (!NT_STATUS_IS_OK(ret)) {
1295 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(ret)));
1299 if (rdata == NULL) {
1300 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1301 rpccli_pipe_txt(debug_ctx(), cli)));
1302 /* Yes - some calls can truely return no data... */
1303 prs_mem_free(¤t_pdu);
1304 return NT_STATUS_OK;
1308 * Give this memory as dynamic to the current pdu. Duplicating it
1309 * sucks, but prs_struct doesn't know about talloc :-(
1311 rdata_copy = (uint8_t *)memdup(rdata, rdata_len);
1313 if (rdata_copy == NULL) {
1314 prs_mem_free(¤t_pdu);
1315 return NT_STATUS_NO_MEMORY;
1317 prs_give_memory(¤t_pdu, (char *)rdata_copy, rdata_len, true);
1319 /* Initialize the incoming PDU */
1320 prs_init_empty(rbuf, mem_ctx, UNMARSHALL);
1322 /* Make rbuf dynamic with no memory. */
1323 prs_give_memory(rbuf, 0, 0, True);
1327 char *ret_data = NULL;
1328 uint32 ret_data_len = 0;
1330 /* Ensure we have enough data for a pdu. */
1331 ret = get_complete_pdu(cli, &rhdr, ¤t_pdu);
1332 if (!NT_STATUS_IS_OK(ret)) {
1336 /* We pass in rbuf here so if the alloc hint is set correctly
1337 we can set the output size and avoid reallocs. */
1339 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
1340 &ret_data, &ret_data_len, rbuf);
1342 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1343 prs_data_size(¤t_pdu), current_rbuf_offset ));
1345 if (!NT_STATUS_IS_OK(ret)) {
1349 if ((rhdr.flags & RPC_FLG_FIRST)) {
1350 if (rhdr.pack_type[0] == 0) {
1351 /* Set the data type correctly for big-endian data on the first packet. */
1352 DEBUG(10,("rpc_api_pipe: On %s "
1353 "PDU data format is big-endian.\n",
1354 rpccli_pipe_txt(debug_ctx(), cli)));
1356 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1358 /* Check endianness on subsequent packets. */
1359 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1360 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1361 rbuf->bigendian_data ? "big" : "little",
1362 current_pdu.bigendian_data ? "big" : "little" ));
1363 ret = NT_STATUS_INVALID_PARAMETER;
1369 /* Now copy the data portion out of the pdu into rbuf. */
1370 if (!prs_force_grow(rbuf, ret_data_len)) {
1371 ret = NT_STATUS_NO_MEMORY;
1374 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1375 current_rbuf_offset += ret_data_len;
1377 /* See if we've finished with all the data in current_pdu yet ? */
1378 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
1379 if (!NT_STATUS_IS_OK(ret)) {
1383 if (rhdr.flags & RPC_FLG_LAST) {
1384 break; /* We're done. */
1388 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1389 rpccli_pipe_txt(debug_ctx(), cli),
1390 (unsigned int)prs_data_size(rbuf) ));
1392 prs_mem_free(¤t_pdu);
1393 return NT_STATUS_OK;
1397 prs_mem_free(¤t_pdu);
1402 /*******************************************************************
1403 Creates krb5 auth bind.
1404 ********************************************************************/
1406 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1407 enum pipe_auth_level auth_level,
1408 RPC_HDR_AUTH *pauth_out,
1409 prs_struct *auth_data)
1413 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1414 DATA_BLOB tkt = data_blob_null;
1415 DATA_BLOB tkt_wrapped = data_blob_null;
1417 /* We may change the pad length before marshalling. */
1418 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1420 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1421 a->service_principal ));
1423 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1425 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1426 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1429 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1431 a->service_principal,
1432 error_message(ret) ));
1434 data_blob_free(&tkt);
1435 prs_mem_free(auth_data);
1436 return NT_STATUS_INVALID_PARAMETER;
1439 /* wrap that up in a nice GSS-API wrapping */
1440 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1442 data_blob_free(&tkt);
1444 /* Auth len in the rpc header doesn't include auth_header. */
1445 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1446 data_blob_free(&tkt_wrapped);
1447 prs_mem_free(auth_data);
1448 return NT_STATUS_NO_MEMORY;
1451 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1452 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1454 data_blob_free(&tkt_wrapped);
1455 return NT_STATUS_OK;
1457 return NT_STATUS_INVALID_PARAMETER;
1461 /*******************************************************************
1462 Creates SPNEGO NTLMSSP auth bind.
1463 ********************************************************************/
1465 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1466 enum pipe_auth_level auth_level,
1467 RPC_HDR_AUTH *pauth_out,
1468 prs_struct *auth_data)
1471 DATA_BLOB null_blob = data_blob_null;
1472 DATA_BLOB request = data_blob_null;
1473 DATA_BLOB spnego_msg = data_blob_null;
1475 /* We may change the pad length before marshalling. */
1476 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1478 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1479 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1483 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1484 data_blob_free(&request);
1485 prs_mem_free(auth_data);
1489 /* Wrap this in SPNEGO. */
1490 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1492 data_blob_free(&request);
1494 /* Auth len in the rpc header doesn't include auth_header. */
1495 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1496 data_blob_free(&spnego_msg);
1497 prs_mem_free(auth_data);
1498 return NT_STATUS_NO_MEMORY;
1501 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1502 dump_data(5, spnego_msg.data, spnego_msg.length);
1504 data_blob_free(&spnego_msg);
1505 return NT_STATUS_OK;
1508 /*******************************************************************
1509 Creates NTLMSSP auth bind.
1510 ********************************************************************/
1512 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1513 enum pipe_auth_level auth_level,
1514 RPC_HDR_AUTH *pauth_out,
1515 prs_struct *auth_data)
1518 DATA_BLOB null_blob = data_blob_null;
1519 DATA_BLOB request = data_blob_null;
1521 /* We may change the pad length before marshalling. */
1522 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1524 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1525 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1529 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1530 data_blob_free(&request);
1531 prs_mem_free(auth_data);
1535 /* Auth len in the rpc header doesn't include auth_header. */
1536 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1537 data_blob_free(&request);
1538 prs_mem_free(auth_data);
1539 return NT_STATUS_NO_MEMORY;
1542 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1543 dump_data(5, request.data, request.length);
1545 data_blob_free(&request);
1546 return NT_STATUS_OK;
1549 /*******************************************************************
1550 Creates schannel auth bind.
1551 ********************************************************************/
1553 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1554 enum pipe_auth_level auth_level,
1555 RPC_HDR_AUTH *pauth_out,
1556 prs_struct *auth_data)
1558 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1560 /* We may change the pad length before marshalling. */
1561 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1563 /* Use lp_workgroup() if domain not specified */
1565 if (!cli->auth->domain || !cli->auth->domain[0]) {
1566 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1567 if (cli->auth->domain == NULL) {
1568 return NT_STATUS_NO_MEMORY;
1572 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1576 * Now marshall the data into the auth parse_struct.
1579 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1580 &schannel_neg, auth_data, 0)) {
1581 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1582 prs_mem_free(auth_data);
1583 return NT_STATUS_NO_MEMORY;
1586 return NT_STATUS_OK;
1589 /*******************************************************************
1590 Creates the internals of a DCE/RPC bind request or alter context PDU.
1591 ********************************************************************/
1593 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1594 prs_struct *rpc_out,
1596 const RPC_IFACE *abstract,
1597 const RPC_IFACE *transfer,
1598 RPC_HDR_AUTH *phdr_auth,
1599 prs_struct *pauth_info)
1603 RPC_CONTEXT rpc_ctx;
1604 uint16 auth_len = prs_offset(pauth_info);
1605 uint8 ss_padding_len = 0;
1606 uint16 frag_len = 0;
1608 /* create the RPC context. */
1609 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1611 /* create the bind request RPC_HDR_RB */
1612 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1614 /* Start building the frag length. */
1615 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1617 /* Do we need to pad ? */
1619 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1621 ss_padding_len = 8 - (data_len % 8);
1622 phdr_auth->auth_pad_len = ss_padding_len;
1624 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1627 /* Create the request RPC_HDR */
1628 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1630 /* Marshall the RPC header */
1631 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1632 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1633 return NT_STATUS_NO_MEMORY;
1636 /* Marshall the bind request data */
1637 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1638 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1639 return NT_STATUS_NO_MEMORY;
1643 * Grow the outgoing buffer to store any auth info.
1647 if (ss_padding_len) {
1649 memset(pad, '\0', 8);
1650 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1651 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1652 return NT_STATUS_NO_MEMORY;
1656 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1657 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1658 return NT_STATUS_NO_MEMORY;
1662 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1663 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1664 return NT_STATUS_NO_MEMORY;
1668 return NT_STATUS_OK;
1671 /*******************************************************************
1672 Creates a DCE/RPC bind request.
1673 ********************************************************************/
1675 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1676 prs_struct *rpc_out,
1678 const RPC_IFACE *abstract,
1679 const RPC_IFACE *transfer,
1680 enum pipe_auth_type auth_type,
1681 enum pipe_auth_level auth_level)
1683 RPC_HDR_AUTH hdr_auth;
1684 prs_struct auth_info;
1685 NTSTATUS ret = NT_STATUS_OK;
1687 ZERO_STRUCT(hdr_auth);
1688 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1689 return NT_STATUS_NO_MEMORY;
1691 switch (auth_type) {
1692 case PIPE_AUTH_TYPE_SCHANNEL:
1693 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1694 if (!NT_STATUS_IS_OK(ret)) {
1695 prs_mem_free(&auth_info);
1700 case PIPE_AUTH_TYPE_NTLMSSP:
1701 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1702 if (!NT_STATUS_IS_OK(ret)) {
1703 prs_mem_free(&auth_info);
1708 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1709 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1710 if (!NT_STATUS_IS_OK(ret)) {
1711 prs_mem_free(&auth_info);
1716 case PIPE_AUTH_TYPE_KRB5:
1717 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1718 if (!NT_STATUS_IS_OK(ret)) {
1719 prs_mem_free(&auth_info);
1724 case PIPE_AUTH_TYPE_NONE:
1728 /* "Can't" happen. */
1729 return NT_STATUS_INVALID_INFO_CLASS;
1732 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1740 prs_mem_free(&auth_info);
1744 /*******************************************************************
1745 Create and add the NTLMSSP sign/seal auth header and data.
1746 ********************************************************************/
1748 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1750 uint32 ss_padding_len,
1751 prs_struct *outgoing_pdu)
1753 RPC_HDR_AUTH auth_info;
1755 DATA_BLOB auth_blob = data_blob_null;
1756 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1758 if (!cli->auth->a_u.ntlmssp_state) {
1759 return NT_STATUS_INVALID_PARAMETER;
1762 /* Init and marshall the auth header. */
1763 init_rpc_hdr_auth(&auth_info,
1764 map_pipe_auth_type_to_rpc_auth_type(
1765 cli->auth->auth_type),
1766 cli->auth->auth_level,
1768 1 /* context id. */);
1770 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1771 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1772 data_blob_free(&auth_blob);
1773 return NT_STATUS_NO_MEMORY;
1776 switch (cli->auth->auth_level) {
1777 case PIPE_AUTH_LEVEL_PRIVACY:
1778 /* Data portion is encrypted. */
1779 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1780 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1782 (unsigned char *)prs_data_p(outgoing_pdu),
1783 (size_t)prs_offset(outgoing_pdu),
1785 if (!NT_STATUS_IS_OK(status)) {
1786 data_blob_free(&auth_blob);
1791 case PIPE_AUTH_LEVEL_INTEGRITY:
1792 /* Data is signed. */
1793 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1794 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1796 (unsigned char *)prs_data_p(outgoing_pdu),
1797 (size_t)prs_offset(outgoing_pdu),
1799 if (!NT_STATUS_IS_OK(status)) {
1800 data_blob_free(&auth_blob);
1807 smb_panic("bad auth level");
1809 return NT_STATUS_INVALID_PARAMETER;
1812 /* Finally marshall the blob. */
1814 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1815 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1816 (unsigned int)NTLMSSP_SIG_SIZE));
1817 data_blob_free(&auth_blob);
1818 return NT_STATUS_NO_MEMORY;
1821 data_blob_free(&auth_blob);
1822 return NT_STATUS_OK;
1825 /*******************************************************************
1826 Create and add the schannel sign/seal auth header and data.
1827 ********************************************************************/
1829 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1831 uint32 ss_padding_len,
1832 prs_struct *outgoing_pdu)
1834 RPC_HDR_AUTH auth_info;
1835 RPC_AUTH_SCHANNEL_CHK verf;
1836 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1837 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1838 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1841 return NT_STATUS_INVALID_PARAMETER;
1844 /* Init and marshall the auth header. */
1845 init_rpc_hdr_auth(&auth_info,
1846 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1847 cli->auth->auth_level,
1849 1 /* context id. */);
1851 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1852 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1853 return NT_STATUS_NO_MEMORY;
1856 switch (cli->auth->auth_level) {
1857 case PIPE_AUTH_LEVEL_PRIVACY:
1858 case PIPE_AUTH_LEVEL_INTEGRITY:
1859 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1862 schannel_encode(sas,
1863 cli->auth->auth_level,
1864 SENDER_IS_INITIATOR,
1874 smb_panic("bad auth level");
1876 return NT_STATUS_INVALID_PARAMETER;
1879 /* Finally marshall the blob. */
1880 smb_io_rpc_auth_schannel_chk("",
1881 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1886 return NT_STATUS_OK;
1889 /*******************************************************************
1890 Calculate how much data we're going to send in this packet, also
1891 work out any sign/seal padding length.
1892 ********************************************************************/
1894 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1898 uint32 *p_ss_padding)
1900 uint32 data_space, data_len;
1902 switch (cli->auth->auth_level) {
1903 case PIPE_AUTH_LEVEL_NONE:
1904 case PIPE_AUTH_LEVEL_CONNECT:
1905 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1906 data_len = MIN(data_space, data_left);
1909 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1912 case PIPE_AUTH_LEVEL_INTEGRITY:
1913 case PIPE_AUTH_LEVEL_PRIVACY:
1914 /* Treat the same for all authenticated rpc requests. */
1915 switch(cli->auth->auth_type) {
1916 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1917 case PIPE_AUTH_TYPE_NTLMSSP:
1918 *p_auth_len = NTLMSSP_SIG_SIZE;
1920 case PIPE_AUTH_TYPE_SCHANNEL:
1921 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1924 smb_panic("bad auth type");
1928 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1929 RPC_HDR_AUTH_LEN - *p_auth_len;
1931 data_len = MIN(data_space, data_left);
1933 *p_ss_padding = 8 - (data_len % 8);
1935 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1936 data_len + *p_ss_padding + /* data plus padding. */
1937 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1941 smb_panic("bad auth level");
1947 /*******************************************************************
1949 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1950 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1951 and deals with signing/sealing details.
1952 ********************************************************************/
1954 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
1956 prs_struct *in_data,
1957 prs_struct *out_data)
1960 uint32 data_left = prs_offset(in_data);
1961 uint32 alloc_hint = prs_offset(in_data);
1962 uint32 data_sent_thistime = 0;
1963 uint32 current_data_offset = 0;
1964 uint32 call_id = get_rpc_call_id();
1966 prs_struct outgoing_pdu;
1968 memset(pad, '\0', 8);
1970 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1971 /* Server is screwed up ! */
1972 return NT_STATUS_INVALID_PARAMETER;
1975 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1976 return NT_STATUS_NO_MEMORY;
1980 RPC_HDR_REQ hdr_req;
1981 uint16 auth_len = 0;
1982 uint16 frag_len = 0;
1984 uint32 ss_padding = 0;
1985 ssize_t num_written;
1987 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1988 &frag_len, &auth_len, &ss_padding);
1990 if (current_data_offset == 0) {
1991 flags = RPC_FLG_FIRST;
1994 if (data_sent_thistime == data_left) {
1995 flags |= RPC_FLG_LAST;
1998 /* Create and marshall the header and request header. */
1999 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
2001 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
2002 prs_mem_free(&outgoing_pdu);
2003 return NT_STATUS_NO_MEMORY;
2006 /* Create the rpc request RPC_HDR_REQ */
2007 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
2009 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
2010 prs_mem_free(&outgoing_pdu);
2011 return NT_STATUS_NO_MEMORY;
2014 /* Copy in the data, plus any ss padding. */
2015 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
2016 prs_mem_free(&outgoing_pdu);
2017 return NT_STATUS_NO_MEMORY;
2020 /* Copy the sign/seal padding data. */
2022 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
2023 prs_mem_free(&outgoing_pdu);
2024 return NT_STATUS_NO_MEMORY;
2028 /* Generate any auth sign/seal and add the auth footer. */
2030 switch (cli->auth->auth_type) {
2031 case PIPE_AUTH_TYPE_NONE:
2033 case PIPE_AUTH_TYPE_NTLMSSP:
2034 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2035 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
2036 if (!NT_STATUS_IS_OK(ret)) {
2037 prs_mem_free(&outgoing_pdu);
2041 case PIPE_AUTH_TYPE_SCHANNEL:
2042 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
2043 if (!NT_STATUS_IS_OK(ret)) {
2044 prs_mem_free(&outgoing_pdu);
2049 smb_panic("bad auth type");
2050 break; /* notreached */
2054 /* Actually send the packet. */
2055 if (flags & RPC_FLG_LAST) {
2056 /* Last packet - send the data, get the reply and return. */
2057 ret = rpc_api_pipe(mem_ctx, cli, &outgoing_pdu,
2058 out_data, RPC_RESPONSE);
2059 prs_mem_free(&outgoing_pdu);
2061 if ((DEBUGLEVEL >= 50)
2062 && (cli->transport_type == NCACN_NP)) {
2063 char *dump_name = NULL;
2064 /* Also capture received data */
2065 if (asprintf(&dump_name, "%s/reply_%s_%d",
2066 get_dyn_LOGFILEBASE(),
2067 cli->trans.np.pipe_name, op_num) > 0) {
2068 prs_dump(dump_name, op_num, out_data);
2069 SAFE_FREE(dump_name);
2076 switch (cli->transport_type) {
2078 num_written = cli_write(cli->trans.np.cli,
2080 8, /* 8 means message mode. */
2081 prs_data_p(&outgoing_pdu),
2083 (size_t)hdr.frag_len);
2085 if (num_written != hdr.frag_len) {
2086 prs_mem_free(&outgoing_pdu);
2087 return cli_get_nt_error(cli->trans.np.cli);
2091 case NCACN_UNIX_STREAM:
2092 num_written = write_data(
2094 prs_data_p(&outgoing_pdu),
2095 (size_t)hdr.frag_len);
2096 if (num_written != hdr.frag_len) {
2098 status = map_nt_error_from_unix(errno);
2099 prs_mem_free(&outgoing_pdu);
2104 DEBUG(0, ("unknown transport type %d\n",
2105 cli->transport_type));
2106 return NT_STATUS_INTERNAL_ERROR;
2109 current_data_offset += data_sent_thistime;
2110 data_left -= data_sent_thistime;
2112 /* Reset the marshalling position back to zero. */
2113 if (!prs_set_offset(&outgoing_pdu, 0)) {
2114 prs_mem_free(&outgoing_pdu);
2115 return NT_STATUS_NO_MEMORY;
2120 /****************************************************************************
2121 Set the handle state.
2122 ****************************************************************************/
2124 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2125 const char *pipe_name, uint16 device_state)
2127 bool state_set = False;
2129 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2130 char *rparam = NULL;
2132 uint32 rparam_len, rdata_len;
2134 if (pipe_name == NULL)
2137 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2138 cli->fnum, pipe_name, device_state));
2140 /* create parameters: device state */
2141 SSVAL(param, 0, device_state);
2143 /* create setup parameters. */
2145 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2147 /* send the data on \PIPE\ */
2148 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2149 setup, 2, 0, /* setup, length, max */
2150 param, 2, 0, /* param, length, max */
2151 NULL, 0, 1024, /* data, length, max */
2152 &rparam, &rparam_len, /* return param, length */
2153 &rdata, &rdata_len)) /* return data, length */
2155 DEBUG(5, ("Set Handle state: return OK\n"));
2166 /****************************************************************************
2167 Check the rpc bind acknowledge response.
2168 ****************************************************************************/
2170 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2172 if ( hdr_ba->addr.len == 0) {
2173 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2176 /* check the transfer syntax */
2177 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2178 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2179 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2183 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2184 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2185 hdr_ba->res.num_results, hdr_ba->res.reason));
2188 DEBUG(5,("check_bind_response: accepted!\n"));
2192 /*******************************************************************
2193 Creates a DCE/RPC bind authentication response.
2194 This is the packet that is sent back to the server once we
2195 have received a BIND-ACK, to finish the third leg of
2196 the authentication handshake.
2197 ********************************************************************/
2199 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2201 enum pipe_auth_type auth_type,
2202 enum pipe_auth_level auth_level,
2203 DATA_BLOB *pauth_blob,
2204 prs_struct *rpc_out)
2207 RPC_HDR_AUTH hdr_auth;
2210 /* Create the request RPC_HDR */
2211 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2212 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2213 pauth_blob->length );
2216 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2217 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2218 return NT_STATUS_NO_MEMORY;
2222 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2223 about padding - shouldn't this pad to length 8 ? JRA.
2226 /* 4 bytes padding. */
2227 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2228 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2229 return NT_STATUS_NO_MEMORY;
2232 /* Create the request RPC_HDR_AUTHA */
2233 init_rpc_hdr_auth(&hdr_auth,
2234 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2237 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2238 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2239 return NT_STATUS_NO_MEMORY;
2243 * Append the auth data to the outgoing buffer.
2246 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2247 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2248 return NT_STATUS_NO_MEMORY;
2251 return NT_STATUS_OK;
2254 /****************************************************************************
2255 Create and send the third packet in an RPC auth.
2256 ****************************************************************************/
2258 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
2262 enum pipe_auth_type auth_type,
2263 enum pipe_auth_level auth_level)
2265 DATA_BLOB server_response = data_blob_null;
2266 DATA_BLOB client_reply = data_blob_null;
2267 RPC_HDR_AUTH hdr_auth;
2272 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2273 return NT_STATUS_INVALID_PARAMETER;
2276 /* Process the returned NTLMSSP blob first. */
2277 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2278 return NT_STATUS_INVALID_PARAMETER;
2281 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2282 return NT_STATUS_INVALID_PARAMETER;
2285 /* TODO - check auth_type/auth_level match. */
2287 server_response = data_blob(NULL, phdr->auth_len);
2288 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
2290 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2294 if (!NT_STATUS_IS_OK(nt_status)) {
2295 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
2296 data_blob_free(&server_response);
2300 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2302 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
2303 auth_type, auth_level,
2304 &client_reply, &rpc_out);
2306 if (!NT_STATUS_IS_OK(nt_status)) {
2307 prs_mem_free(&rpc_out);
2308 data_blob_free(&client_reply);
2309 data_blob_free(&server_response);
2313 switch (cli->transport_type) {
2315 /* 8 here is named pipe message mode. */
2316 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
2317 0x8, prs_data_p(&rpc_out), 0,
2318 (size_t)prs_offset(&rpc_out));
2321 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2322 nt_status = cli_get_nt_error(cli->trans.np.cli);
2325 case NCACN_UNIX_STREAM:
2326 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2327 (size_t)prs_offset(&rpc_out));
2328 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2329 nt_status = map_nt_error_from_unix(errno);
2333 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2334 return NT_STATUS_INTERNAL_ERROR;
2337 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2338 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2339 nt_errstr(nt_status)));
2340 prs_mem_free(&rpc_out);
2341 data_blob_free(&client_reply);
2342 data_blob_free(&server_response);
2346 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2347 rpccli_pipe_txt(debug_ctx(), cli)));
2349 prs_mem_free(&rpc_out);
2350 data_blob_free(&client_reply);
2351 data_blob_free(&server_response);
2352 return NT_STATUS_OK;
2355 /*******************************************************************
2356 Creates a DCE/RPC bind alter context authentication request which
2357 may contain a spnego auth blobl
2358 ********************************************************************/
2360 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2361 const RPC_IFACE *abstract,
2362 const RPC_IFACE *transfer,
2363 enum pipe_auth_level auth_level,
2364 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2365 prs_struct *rpc_out)
2367 RPC_HDR_AUTH hdr_auth;
2368 prs_struct auth_info;
2369 NTSTATUS ret = NT_STATUS_OK;
2371 ZERO_STRUCT(hdr_auth);
2372 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2373 return NT_STATUS_NO_MEMORY;
2375 /* We may change the pad length before marshalling. */
2376 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2378 if (pauth_blob->length) {
2379 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2380 prs_mem_free(&auth_info);
2381 return NT_STATUS_NO_MEMORY;
2385 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2392 prs_mem_free(&auth_info);
2396 /*******************************************************************
2397 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2398 and gets a response.
2399 ********************************************************************/
2401 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2405 const RPC_IFACE *abstract,
2406 const RPC_IFACE *transfer,
2407 enum pipe_auth_type auth_type,
2408 enum pipe_auth_level auth_level)
2410 DATA_BLOB server_spnego_response = data_blob_null;
2411 DATA_BLOB server_ntlm_response = data_blob_null;
2412 DATA_BLOB client_reply = data_blob_null;
2413 DATA_BLOB tmp_blob = data_blob_null;
2414 RPC_HDR_AUTH hdr_auth;
2418 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2419 return NT_STATUS_INVALID_PARAMETER;
2422 /* Process the returned NTLMSSP blob first. */
2423 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2424 return NT_STATUS_INVALID_PARAMETER;
2427 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2428 return NT_STATUS_INVALID_PARAMETER;
2431 server_spnego_response = data_blob(NULL, phdr->auth_len);
2432 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2434 /* The server might give us back two challenges - tmp_blob is for the second. */
2435 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2436 data_blob_free(&server_spnego_response);
2437 data_blob_free(&server_ntlm_response);
2438 data_blob_free(&tmp_blob);
2439 return NT_STATUS_INVALID_PARAMETER;
2442 /* We're finished with the server spnego response and the tmp_blob. */
2443 data_blob_free(&server_spnego_response);
2444 data_blob_free(&tmp_blob);
2446 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2447 server_ntlm_response,
2450 /* Finished with the server_ntlm response */
2451 data_blob_free(&server_ntlm_response);
2453 if (!NT_STATUS_IS_OK(nt_status)) {
2454 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2455 data_blob_free(&client_reply);
2459 /* SPNEGO wrap the client reply. */
2460 tmp_blob = spnego_gen_auth(client_reply);
2461 data_blob_free(&client_reply);
2462 client_reply = tmp_blob;
2463 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2465 /* Now prepare the alter context pdu. */
2466 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2468 nt_status = create_rpc_alter_context(rpc_call_id,
2475 data_blob_free(&client_reply);
2477 if (!NT_STATUS_IS_OK(nt_status)) {
2478 prs_mem_free(&rpc_out);
2482 /* Initialize the returning data struct. */
2485 nt_status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, rbuf,
2487 prs_mem_free(&rpc_out);
2488 if (!NT_STATUS_IS_OK(nt_status)) {
2492 /* Get the auth blob from the reply. */
2493 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2494 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2495 return NT_STATUS_BUFFER_TOO_SMALL;
2498 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2499 return NT_STATUS_INVALID_PARAMETER;
2502 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2503 return NT_STATUS_INVALID_PARAMETER;
2506 server_spnego_response = data_blob(NULL, phdr->auth_len);
2507 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2509 /* Check we got a valid auth response. */
2510 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2511 data_blob_free(&server_spnego_response);
2512 data_blob_free(&tmp_blob);
2513 return NT_STATUS_INVALID_PARAMETER;
2516 data_blob_free(&server_spnego_response);
2517 data_blob_free(&tmp_blob);
2519 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2520 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2522 return NT_STATUS_OK;
2525 /****************************************************************************
2527 ****************************************************************************/
2529 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2530 struct cli_pipe_auth_data *auth)
2539 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2540 rpccli_pipe_txt(debug_ctx(), cli),
2541 (unsigned int)auth->auth_type,
2542 (unsigned int)auth->auth_level ));
2544 cli->auth = talloc_move(cli, &auth);
2546 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2548 rpc_call_id = get_rpc_call_id();
2550 /* Marshall the outgoing data. */
2551 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2552 &cli->abstract_syntax,
2553 &cli->transfer_syntax,
2554 cli->auth->auth_type,
2555 cli->auth->auth_level);
2557 if (!NT_STATUS_IS_OK(status)) {
2558 prs_mem_free(&rpc_out);
2562 /* send data on \PIPE\. receive a response */
2563 status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, &rbuf, RPC_BINDACK);
2564 prs_mem_free(&rpc_out);
2565 if (!NT_STATUS_IS_OK(status)) {
2569 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2570 rpccli_pipe_txt(debug_ctx(), cli)));
2572 /* Unmarshall the RPC header */
2573 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2574 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2575 prs_mem_free(&rbuf);
2576 return NT_STATUS_BUFFER_TOO_SMALL;
2579 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2580 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2581 prs_mem_free(&rbuf);
2582 return NT_STATUS_BUFFER_TOO_SMALL;
2585 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2586 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2587 prs_mem_free(&rbuf);
2588 return NT_STATUS_BUFFER_TOO_SMALL;
2591 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2592 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2594 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2595 switch(cli->auth->auth_type) {
2597 case PIPE_AUTH_TYPE_NONE:
2598 case PIPE_AUTH_TYPE_SCHANNEL:
2599 /* Bind complete. */
2602 case PIPE_AUTH_TYPE_NTLMSSP:
2603 /* Need to send AUTH3 packet - no reply. */
2604 status = rpc_finish_auth3_bind(
2605 cli, &hdr, &rbuf, rpc_call_id,
2606 cli->auth->auth_type,
2607 cli->auth->auth_level);
2608 if (!NT_STATUS_IS_OK(status)) {
2609 prs_mem_free(&rbuf);
2614 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2615 /* Need to send alter context request and reply. */
2616 status = rpc_finish_spnego_ntlmssp_bind(
2617 cli, &hdr, &rbuf, rpc_call_id,
2618 &cli->abstract_syntax, &cli->transfer_syntax,
2619 cli->auth->auth_type, cli->auth->auth_level);
2620 if (!NT_STATUS_IS_OK(status)) {
2621 prs_mem_free(&rbuf);
2626 case PIPE_AUTH_TYPE_KRB5:
2630 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2631 "%u\n", (unsigned int)cli->auth->auth_type));
2632 prs_mem_free(&rbuf);
2633 return NT_STATUS_INVALID_INFO_CLASS;
2636 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2637 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2638 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2639 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2640 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2641 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2642 prs_mem_free(&rbuf);
2643 return NT_STATUS_INVALID_PARAMETER;
2646 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2647 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2648 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2649 prs_mem_free(&rbuf);
2650 return NT_STATUS_INVALID_PARAMETER;
2655 prs_mem_free(&rbuf);
2656 return NT_STATUS_OK;
2659 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2660 unsigned int timeout)
2662 return cli_set_timeout(cli->trans.np.cli, timeout);
2665 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2667 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2668 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2669 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2673 if (cli->transport_type == NCACN_NP) {
2674 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2681 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2683 if (p->transport_type == NCACN_NP) {
2684 return p->trans.np.cli;
2689 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2691 if (p->transport_type == NCACN_NP) {
2693 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2695 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2696 "pipe %s. Error was %s\n",
2697 rpccli_pipe_txt(debug_ctx(), p),
2698 cli_errstr(p->trans.np.cli)));
2701 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2702 rpccli_pipe_txt(debug_ctx(), p)));
2704 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2705 return ret ? -1 : 0;
2711 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2712 struct cli_pipe_auth_data **presult)
2714 struct cli_pipe_auth_data *result;
2716 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2717 if (result == NULL) {
2718 return NT_STATUS_NO_MEMORY;
2721 result->auth_type = PIPE_AUTH_TYPE_NONE;
2722 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2724 result->user_name = talloc_strdup(result, "");
2725 result->domain = talloc_strdup(result, "");
2726 if ((result->user_name == NULL) || (result->domain == NULL)) {
2727 TALLOC_FREE(result);
2728 return NT_STATUS_NO_MEMORY;
2732 return NT_STATUS_OK;
2735 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2737 ntlmssp_end(&auth->a_u.ntlmssp_state);
2741 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2742 enum pipe_auth_type auth_type,
2743 enum pipe_auth_level auth_level,
2745 const char *username,
2746 const char *password,
2747 struct cli_pipe_auth_data **presult)
2749 struct cli_pipe_auth_data *result;
2752 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2753 if (result == NULL) {
2754 return NT_STATUS_NO_MEMORY;
2757 result->auth_type = auth_type;
2758 result->auth_level = auth_level;
2760 result->user_name = talloc_strdup(result, username);
2761 result->domain = talloc_strdup(result, domain);
2762 if ((result->user_name == NULL) || (result->domain == NULL)) {
2763 status = NT_STATUS_NO_MEMORY;
2767 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2768 if (!NT_STATUS_IS_OK(status)) {
2772 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2774 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2775 if (!NT_STATUS_IS_OK(status)) {
2779 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2780 if (!NT_STATUS_IS_OK(status)) {
2784 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2785 if (!NT_STATUS_IS_OK(status)) {
2790 * Turn off sign+seal to allow selected auth level to turn it back on.
2792 result->a_u.ntlmssp_state->neg_flags &=
2793 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2795 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2796 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2797 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2798 result->a_u.ntlmssp_state->neg_flags
2799 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2803 return NT_STATUS_OK;
2806 TALLOC_FREE(result);
2810 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2811 enum pipe_auth_level auth_level,
2812 const uint8_t sess_key[16],
2813 struct cli_pipe_auth_data **presult)
2815 struct cli_pipe_auth_data *result;
2817 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2818 if (result == NULL) {
2819 return NT_STATUS_NO_MEMORY;
2822 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2823 result->auth_level = auth_level;
2825 result->user_name = talloc_strdup(result, "");
2826 result->domain = talloc_strdup(result, domain);
2827 if ((result->user_name == NULL) || (result->domain == NULL)) {
2831 result->a_u.schannel_auth = talloc(result,
2832 struct schannel_auth_struct);
2833 if (result->a_u.schannel_auth == NULL) {
2837 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2838 sizeof(result->a_u.schannel_auth->sess_key));
2839 result->a_u.schannel_auth->seq_num = 0;
2842 return NT_STATUS_OK;
2845 TALLOC_FREE(result);
2846 return NT_STATUS_NO_MEMORY;
2850 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2852 data_blob_free(&auth->session_key);
2857 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2858 enum pipe_auth_level auth_level,
2859 const char *service_princ,
2860 const char *username,
2861 const char *password,
2862 struct cli_pipe_auth_data **presult)
2865 struct cli_pipe_auth_data *result;
2867 if ((username != NULL) && (password != NULL)) {
2868 int ret = kerberos_kinit_password(username, password, 0, NULL);
2870 return NT_STATUS_ACCESS_DENIED;
2874 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2875 if (result == NULL) {
2876 return NT_STATUS_NO_MEMORY;
2879 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2880 result->auth_level = auth_level;
2883 * Username / domain need fixing!
2885 result->user_name = talloc_strdup(result, "");
2886 result->domain = talloc_strdup(result, "");
2887 if ((result->user_name == NULL) || (result->domain == NULL)) {
2891 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2892 result, struct kerberos_auth_struct);
2893 if (result->a_u.kerberos_auth == NULL) {
2896 talloc_set_destructor(result->a_u.kerberos_auth,
2897 cli_auth_kerberos_data_destructor);
2899 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2900 result, service_princ);
2901 if (result->a_u.kerberos_auth->service_principal == NULL) {
2906 return NT_STATUS_OK;
2909 TALLOC_FREE(result);
2910 return NT_STATUS_NO_MEMORY;
2912 return NT_STATUS_NOT_SUPPORTED;
2916 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2918 close(p->trans.sock.fd);
2923 * Create an rpc pipe client struct, connecting to a tcp port.
2925 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2927 const struct ndr_syntax_id *abstract_syntax,
2928 struct rpc_pipe_client **presult)
2930 struct rpc_pipe_client *result;
2931 struct sockaddr_storage addr;
2934 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2935 if (result == NULL) {
2936 return NT_STATUS_NO_MEMORY;
2939 result->transport_type = NCACN_IP_TCP;
2941 result->abstract_syntax = *abstract_syntax;
2942 result->transfer_syntax = ndr_transfer_syntax;
2944 result->desthost = talloc_strdup(result, host);
2945 result->srv_name_slash = talloc_asprintf_strupper_m(
2946 result, "\\\\%s", result->desthost);
2947 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2948 status = NT_STATUS_NO_MEMORY;
2952 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2953 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2955 if (!resolve_name(host, &addr, 0)) {
2956 status = NT_STATUS_NOT_FOUND;
2960 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2961 if (!NT_STATUS_IS_OK(status)) {
2965 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2968 return NT_STATUS_OK;
2971 TALLOC_FREE(result);
2976 * Determine the tcp port on which a dcerpc interface is listening
2977 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2980 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2981 const struct ndr_syntax_id *abstract_syntax,
2985 struct rpc_pipe_client *epm_pipe = NULL;
2986 struct cli_pipe_auth_data *auth = NULL;
2987 struct dcerpc_binding *map_binding = NULL;
2988 struct dcerpc_binding *res_binding = NULL;
2989 struct epm_twr_t *map_tower = NULL;
2990 struct epm_twr_t *res_towers = NULL;
2991 struct policy_handle *entry_handle = NULL;
2992 uint32_t num_towers = 0;
2993 uint32_t max_towers = 1;
2994 struct epm_twr_p_t towers;
2995 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2997 if (pport == NULL) {
2998 status = NT_STATUS_INVALID_PARAMETER;
3002 /* open the connection to the endpoint mapper */
3003 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3004 &ndr_table_epmapper.syntax_id,
3007 if (!NT_STATUS_IS_OK(status)) {
3011 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3012 if (!NT_STATUS_IS_OK(status)) {
3016 status = rpc_pipe_bind(epm_pipe, auth);
3017 if (!NT_STATUS_IS_OK(status)) {
3021 /* create tower for asking the epmapper */
3023 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3024 if (map_binding == NULL) {
3025 status = NT_STATUS_NO_MEMORY;
3029 map_binding->transport = NCACN_IP_TCP;
3030 map_binding->object = *abstract_syntax;
3031 map_binding->host = host; /* needed? */
3032 map_binding->endpoint = "0"; /* correct? needed? */
3034 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3035 if (map_tower == NULL) {
3036 status = NT_STATUS_NO_MEMORY;
3040 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3041 &(map_tower->tower));
3042 if (!NT_STATUS_IS_OK(status)) {
3046 /* allocate further parameters for the epm_Map call */
3048 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3049 if (res_towers == NULL) {
3050 status = NT_STATUS_NO_MEMORY;
3053 towers.twr = res_towers;
3055 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3056 if (entry_handle == NULL) {
3057 status = NT_STATUS_NO_MEMORY;
3061 /* ask the endpoint mapper for the port */
3063 status = rpccli_epm_Map(epm_pipe,
3065 CONST_DISCARD(struct GUID *,
3066 &(abstract_syntax->uuid)),
3073 if (!NT_STATUS_IS_OK(status)) {
3077 if (num_towers != 1) {
3078 status = NT_STATUS_UNSUCCESSFUL;
3082 /* extract the port from the answer */
3084 status = dcerpc_binding_from_tower(tmp_ctx,
3085 &(towers.twr->tower),
3087 if (!NT_STATUS_IS_OK(status)) {
3091 /* are further checks here necessary? */
3092 if (res_binding->transport != NCACN_IP_TCP) {
3093 status = NT_STATUS_UNSUCCESSFUL;
3097 *pport = (uint16_t)atoi(res_binding->endpoint);
3100 TALLOC_FREE(tmp_ctx);
3105 * Create a rpc pipe client struct, connecting to a host via tcp.
3106 * The port is determined by asking the endpoint mapper on the given
3109 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3110 const struct ndr_syntax_id *abstract_syntax,
3111 struct rpc_pipe_client **presult)
3118 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3119 if (!NT_STATUS_IS_OK(status)) {
3123 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3124 abstract_syntax, presult);
3130 /********************************************************************
3131 Create a rpc pipe client struct, connecting to a unix domain socket
3132 ********************************************************************/
3133 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3134 const struct ndr_syntax_id *abstract_syntax,
3135 struct rpc_pipe_client **presult)
3137 struct rpc_pipe_client *result;
3138 struct sockaddr_un addr;
3141 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3142 if (result == NULL) {
3143 return NT_STATUS_NO_MEMORY;
3146 result->transport_type = NCACN_UNIX_STREAM;
3148 result->abstract_syntax = *abstract_syntax;
3149 result->transfer_syntax = ndr_transfer_syntax;
3151 result->desthost = talloc_get_myname(result);
3152 result->srv_name_slash = talloc_asprintf_strupper_m(
3153 result, "\\\\%s", result->desthost);
3154 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3155 status = NT_STATUS_NO_MEMORY;
3159 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3160 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3162 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
3163 if (result->trans.sock.fd == -1) {
3164 status = map_nt_error_from_unix(errno);
3168 talloc_set_destructor(result, rpc_pipe_sock_destructor);
3171 addr.sun_family = AF_UNIX;
3172 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3174 if (sys_connect(result->trans.sock.fd,
3175 (struct sockaddr *)&addr) == -1) {
3176 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3178 close(result->trans.sock.fd);
3179 return map_nt_error_from_unix(errno);
3183 return NT_STATUS_OK;
3186 TALLOC_FREE(result);
3191 /****************************************************************************
3192 Open a named pipe over SMB to a remote server.
3194 * CAVEAT CALLER OF THIS FUNCTION:
3195 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3196 * so be sure that this function is called AFTER any structure (vs pointer)
3197 * assignment of the cli. In particular, libsmbclient does structure
3198 * assignments of cli, which invalidates the data in the returned
3199 * rpc_pipe_client if this function is called before the structure assignment
3202 ****************************************************************************/
3204 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3205 const struct ndr_syntax_id *abstract_syntax,
3206 struct rpc_pipe_client **presult)
3208 struct rpc_pipe_client *result;
3211 /* sanity check to protect against crashes */
3214 return NT_STATUS_INVALID_HANDLE;
3217 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3218 if (result == NULL) {
3219 return NT_STATUS_NO_MEMORY;
3222 result->transport_type = NCACN_NP;
3224 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
3225 result, cli, abstract_syntax);
3226 if (result->trans.np.pipe_name == NULL) {
3227 DEBUG(1, ("Could not find pipe for interface\n"));
3228 TALLOC_FREE(result);
3229 return NT_STATUS_INVALID_PARAMETER;
3232 result->trans.np.cli = cli;
3233 result->abstract_syntax = *abstract_syntax;
3234 result->transfer_syntax = ndr_transfer_syntax;
3235 result->desthost = talloc_strdup(result, cli->desthost);
3236 result->srv_name_slash = talloc_asprintf_strupper_m(
3237 result, "\\\\%s", result->desthost);
3239 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3240 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3242 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3243 TALLOC_FREE(result);
3244 return NT_STATUS_NO_MEMORY;
3247 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
3248 DESIRED_ACCESS_PIPE);
3250 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
3251 "to machine %s. Error was %s\n",
3252 result->trans.np.pipe_name, cli->desthost,
3254 TALLOC_FREE(result);
3255 return cli_get_nt_error(cli);
3258 result->trans.np.fnum = fnum;
3260 DLIST_ADD(cli->pipe_list, result);
3261 talloc_set_destructor(result, rpc_pipe_destructor);
3264 return NT_STATUS_OK;
3267 /****************************************************************************
3268 Open a pipe to a remote server.
3269 ****************************************************************************/
3271 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3272 const struct ndr_syntax_id *interface,
3273 struct rpc_pipe_client **presult)
3275 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3277 * We should have a better way to figure out this drsuapi
3280 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3284 return rpc_pipe_open_np(cli, interface, presult);
3287 /****************************************************************************
3288 Open a named pipe to an SMB server and bind anonymously.
3289 ****************************************************************************/
3291 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3292 const struct ndr_syntax_id *interface,
3293 struct rpc_pipe_client **presult)
3295 struct rpc_pipe_client *result;
3296 struct cli_pipe_auth_data *auth;
3299 status = cli_rpc_pipe_open(cli, interface, &result);
3300 if (!NT_STATUS_IS_OK(status)) {
3304 status = rpccli_anon_bind_data(result, &auth);
3305 if (!NT_STATUS_IS_OK(status)) {
3306 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3307 nt_errstr(status)));
3308 TALLOC_FREE(result);
3313 * This is a bit of an abstraction violation due to the fact that an
3314 * anonymous bind on an authenticated SMB inherits the user/domain
3315 * from the enclosing SMB creds
3318 TALLOC_FREE(auth->user_name);
3319 TALLOC_FREE(auth->domain);
3321 auth->user_name = talloc_strdup(auth, cli->user_name);
3322 auth->domain = talloc_strdup(auth, cli->domain);
3323 auth->user_session_key = data_blob_talloc(auth,
3324 cli->user_session_key.data,
3325 cli->user_session_key.length);
3327 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3328 TALLOC_FREE(result);
3329 return NT_STATUS_NO_MEMORY;
3332 status = rpc_pipe_bind(result, auth);
3333 if (!NT_STATUS_IS_OK(status)) {
3335 if (ndr_syntax_id_equal(interface,
3336 &ndr_table_dssetup.syntax_id)) {
3337 /* non AD domains just don't have this pipe, avoid
3338 * level 0 statement in that case - gd */
3341 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3342 "%s failed with error %s\n",
3343 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3345 nt_errstr(status) ));
3346 TALLOC_FREE(result);
3350 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3351 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3355 return NT_STATUS_OK;
3358 /****************************************************************************
3359 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3360 ****************************************************************************/
3362 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3363 const struct ndr_syntax_id *interface,
3364 enum pipe_auth_type auth_type,
3365 enum pipe_auth_level auth_level,
3367 const char *username,
3368 const char *password,
3369 struct rpc_pipe_client **presult)
3371 struct rpc_pipe_client *result;
3372 struct cli_pipe_auth_data *auth;
3375 status = cli_rpc_pipe_open(cli, interface, &result);
3376 if (!NT_STATUS_IS_OK(status)) {
3380 status = rpccli_ntlmssp_bind_data(
3381 result, auth_type, auth_level, domain, username,
3382 cli->pwd.null_pwd ? NULL : password, &auth);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3385 nt_errstr(status)));
3389 status = rpc_pipe_bind(result, auth);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3392 nt_errstr(status) ));
3396 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3397 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3398 result->trans.np.pipe_name, cli->desthost,
3399 domain, username ));
3402 return NT_STATUS_OK;
3406 TALLOC_FREE(result);
3410 /****************************************************************************
3412 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3413 ****************************************************************************/
3415 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3416 const struct ndr_syntax_id *interface,
3417 enum pipe_auth_level auth_level,
3419 const char *username,
3420 const char *password,
3421 struct rpc_pipe_client **presult)
3423 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3425 PIPE_AUTH_TYPE_NTLMSSP,
3433 /****************************************************************************
3435 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3436 ****************************************************************************/
3438 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3439 const struct ndr_syntax_id *interface,
3440 enum pipe_auth_level auth_level,
3442 const char *username,
3443 const char *password,
3444 struct rpc_pipe_client **presult)
3446 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3448 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3456 /****************************************************************************
3457 Get a the schannel session key out of an already opened netlogon pipe.
3458 ****************************************************************************/
3459 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3460 struct cli_state *cli,
3464 uint32 sec_chan_type = 0;
3465 unsigned char machine_pwd[16];
3466 const char *machine_account;
3469 /* Get the machine account credentials from secrets.tdb. */
3470 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3473 DEBUG(0, ("get_schannel_session_key: could not fetch "
3474 "trust account password for domain '%s'\n",
3476 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3479 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3480 cli->desthost, /* server name */
3481 domain, /* domain */
3482 global_myname(), /* client name */
3483 machine_account, /* machine account name */
3488 if (!NT_STATUS_IS_OK(status)) {
3489 DEBUG(3, ("get_schannel_session_key_common: "
3490 "rpccli_netlogon_setup_creds failed with result %s "
3491 "to server %s, domain %s, machine account %s.\n",
3492 nt_errstr(status), cli->desthost, domain,
3497 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3498 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3503 return NT_STATUS_OK;;
3506 /****************************************************************************
3507 Open a netlogon pipe and get the schannel session key.
3508 Now exposed to external callers.
3509 ****************************************************************************/
3512 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3515 struct rpc_pipe_client **presult)
3517 struct rpc_pipe_client *netlogon_pipe = NULL;
3520 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3522 if (!NT_STATUS_IS_OK(status)) {
3526 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3528 if (!NT_STATUS_IS_OK(status)) {
3529 TALLOC_FREE(netlogon_pipe);
3533 *presult = netlogon_pipe;
3534 return NT_STATUS_OK;
3537 /****************************************************************************
3539 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3540 using session_key. sign and seal.
3541 ****************************************************************************/
3543 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3544 const struct ndr_syntax_id *interface,
3545 enum pipe_auth_level auth_level,
3547 const struct dcinfo *pdc,
3548 struct rpc_pipe_client **presult)
3550 struct rpc_pipe_client *result;
3551 struct cli_pipe_auth_data *auth;
3554 status = cli_rpc_pipe_open(cli, interface, &result);
3555 if (!NT_STATUS_IS_OK(status)) {
3559 status = rpccli_schannel_bind_data(result, domain, auth_level,
3560 pdc->sess_key, &auth);
3561 if (!NT_STATUS_IS_OK(status)) {
3562 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3563 nt_errstr(status)));
3564 TALLOC_FREE(result);
3568 status = rpc_pipe_bind(result, auth);
3569 if (!NT_STATUS_IS_OK(status)) {
3570 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3571 "cli_rpc_pipe_bind failed with error %s\n",
3572 nt_errstr(status) ));
3573 TALLOC_FREE(result);
3578 * The credentials on a new netlogon pipe are the ones we are passed
3579 * in - copy them over.
3581 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3582 if (result->dc == NULL) {
3583 DEBUG(0, ("talloc failed\n"));
3584 TALLOC_FREE(result);
3585 return NT_STATUS_NO_MEMORY;
3588 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3590 "and bound using schannel.\n",
3591 result->trans.np.pipe_name, cli->desthost, domain ));
3594 return NT_STATUS_OK;
3597 /****************************************************************************
3598 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3599 Fetch the session key ourselves using a temporary netlogon pipe. This
3600 version uses an ntlmssp auth bound netlogon pipe to get the key.
3601 ****************************************************************************/
3603 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3605 const char *username,
3606 const char *password,
3608 struct rpc_pipe_client **presult)
3610 struct rpc_pipe_client *netlogon_pipe = NULL;
3613 status = cli_rpc_pipe_open_spnego_ntlmssp(
3614 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3615 domain, username, password, &netlogon_pipe);
3616 if (!NT_STATUS_IS_OK(status)) {
3620 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3622 if (!NT_STATUS_IS_OK(status)) {
3623 TALLOC_FREE(netlogon_pipe);
3627 *presult = netlogon_pipe;
3628 return NT_STATUS_OK;
3631 /****************************************************************************
3632 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3633 Fetch the session key ourselves using a temporary netlogon pipe. This version
3634 uses an ntlmssp bind to get the session key.
3635 ****************************************************************************/
3637 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3638 const struct ndr_syntax_id *interface,
3639 enum pipe_auth_level auth_level,
3641 const char *username,
3642 const char *password,
3643 struct rpc_pipe_client **presult)
3645 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3646 struct rpc_pipe_client *netlogon_pipe = NULL;
3647 struct rpc_pipe_client *result = NULL;
3650 status = get_schannel_session_key_auth_ntlmssp(
3651 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3652 if (!NT_STATUS_IS_OK(status)) {
3653 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3654 "key from server %s for domain %s.\n",
3655 cli->desthost, domain ));
3659 status = cli_rpc_pipe_open_schannel_with_key(
3660 cli, interface, auth_level, domain, netlogon_pipe->dc,
3663 /* Now we've bound using the session key we can close the netlog pipe. */
3664 TALLOC_FREE(netlogon_pipe);
3666 if (NT_STATUS_IS_OK(status)) {
3672 /****************************************************************************
3673 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3674 Fetch the session key ourselves using a temporary netlogon pipe.
3675 ****************************************************************************/
3677 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3678 const struct ndr_syntax_id *interface,
3679 enum pipe_auth_level auth_level,
3681 struct rpc_pipe_client **presult)
3683 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3684 struct rpc_pipe_client *netlogon_pipe = NULL;
3685 struct rpc_pipe_client *result = NULL;
3688 status = get_schannel_session_key(cli, domain, &neg_flags,
3690 if (!NT_STATUS_IS_OK(status)) {
3691 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3692 "key from server %s for domain %s.\n",
3693 cli->desthost, domain ));
3697 status = cli_rpc_pipe_open_schannel_with_key(
3698 cli, interface, auth_level, domain, netlogon_pipe->dc,
3701 /* Now we've bound using the session key we can close the netlog pipe. */
3702 TALLOC_FREE(netlogon_pipe);
3704 if (NT_STATUS_IS_OK(status)) {
3708 return NT_STATUS_OK;
3711 /****************************************************************************
3712 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3713 The idea is this can be called with service_princ, username and password all
3714 NULL so long as the caller has a TGT.
3715 ****************************************************************************/
3717 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3718 const struct ndr_syntax_id *interface,
3719 enum pipe_auth_level auth_level,
3720 const char *service_princ,
3721 const char *username,
3722 const char *password,
3723 struct rpc_pipe_client **presult)
3726 struct rpc_pipe_client *result;
3727 struct cli_pipe_auth_data *auth;
3730 status = cli_rpc_pipe_open(cli, interface, &result);
3731 if (!NT_STATUS_IS_OK(status)) {
3735 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3736 username, password, &auth);
3737 if (!NT_STATUS_IS_OK(status)) {
3738 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3739 nt_errstr(status)));
3740 TALLOC_FREE(result);
3744 status = rpc_pipe_bind(result, auth);
3745 if (!NT_STATUS_IS_OK(status)) {
3746 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3747 "with error %s\n", nt_errstr(status)));
3748 TALLOC_FREE(result);
3753 return NT_STATUS_OK;
3755 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3756 return NT_STATUS_NOT_IMPLEMENTED;
3760 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3761 struct rpc_pipe_client *cli,
3762 DATA_BLOB *session_key)
3764 if (!session_key || !cli) {
3765 return NT_STATUS_INVALID_PARAMETER;
3769 return NT_STATUS_INVALID_PARAMETER;
3772 switch (cli->auth->auth_type) {
3773 case PIPE_AUTH_TYPE_SCHANNEL:
3774 *session_key = data_blob_talloc(mem_ctx,
3775 cli->auth->a_u.schannel_auth->sess_key, 16);
3777 case PIPE_AUTH_TYPE_NTLMSSP:
3778 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3779 *session_key = data_blob_talloc(mem_ctx,
3780 cli->auth->a_u.ntlmssp_state->session_key.data,
3781 cli->auth->a_u.ntlmssp_state->session_key.length);
3783 case PIPE_AUTH_TYPE_KRB5:
3784 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3785 *session_key = data_blob_talloc(mem_ctx,
3786 cli->auth->a_u.kerberos_auth->session_key.data,
3787 cli->auth->a_u.kerberos_auth->session_key.length);
3789 case PIPE_AUTH_TYPE_NONE:
3790 *session_key = data_blob_talloc(mem_ctx,
3791 cli->auth->user_session_key.data,
3792 cli->auth->user_session_key.length);
3795 return NT_STATUS_NO_USER_SESSION_KEY;
3798 return NT_STATUS_OK;