Merge branch 'master' of /home/tridge/samba/git/combined
[Samba/aatanasov.git] / source3 / rpc_client / cli_pipe.c
blob5392d1f78feda92ea4ab40c3a8f9eea786c60fcb
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
26 #include "../libcli/auth/spnego.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_CLI
31 /*******************************************************************
32 interface/version dce/rpc pipe identification
33 ********************************************************************/
35 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
36 #define PIPE_SAMR "\\PIPE\\samr"
37 #define PIPE_WINREG "\\PIPE\\winreg"
38 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
39 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
40 #define PIPE_NTLSA "\\PIPE\\ntlsa"
41 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
42 #define PIPE_LSASS "\\PIPE\\lsass"
43 #define PIPE_LSARPC "\\PIPE\\lsarpc"
44 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
45 #define PIPE_NETDFS "\\PIPE\\netdfs"
46 #define PIPE_ECHO "\\PIPE\\rpcecho"
47 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
48 #define PIPE_EPM "\\PIPE\\epmapper"
49 #define PIPE_SVCCTL "\\PIPE\\svcctl"
50 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
51 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
52 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
55 * IMPORTANT!! If you update this structure, make sure to
56 * update the index #defines in smb.h.
59 static const struct pipe_id_info {
60 /* the names appear not to matter: the syntaxes _do_ matter */
62 const char *client_pipe;
63 const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
64 } pipe_names [] =
66 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
67 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
68 { PIPE_SAMR, &ndr_table_samr.syntax_id },
69 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
70 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
71 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
72 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
73 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
74 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
75 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
76 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
77 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
78 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
79 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
80 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
81 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
82 { NULL, NULL }
85 /****************************************************************************
86 Return the pipe name from the interface.
87 ****************************************************************************/
89 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
91 char *guid_str;
92 const char *result;
93 int i;
94 for (i = 0; pipe_names[i].client_pipe; i++) {
95 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
96 interface)) {
97 return &pipe_names[i].client_pipe[5];
102 * Here we should ask \\epmapper, but for now our code is only
103 * interested in the known pipes mentioned in pipe_names[]
106 guid_str = GUID_string(talloc_tos(), &interface->uuid);
107 if (guid_str == NULL) {
108 return NULL;
110 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
111 (int)interface->if_version);
112 TALLOC_FREE(guid_str);
114 if (result == NULL) {
115 return "PIPE";
117 return result;
120 /********************************************************************
121 Map internal value to wire value.
122 ********************************************************************/
124 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
126 switch (auth_type) {
128 case PIPE_AUTH_TYPE_NONE:
129 return DCERPC_AUTH_TYPE_NONE;
131 case PIPE_AUTH_TYPE_NTLMSSP:
132 return DCERPC_AUTH_TYPE_NTLMSSP;
134 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
135 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
136 return DCERPC_AUTH_TYPE_SPNEGO;
138 case PIPE_AUTH_TYPE_SCHANNEL:
139 return DCERPC_AUTH_TYPE_SCHANNEL;
141 case PIPE_AUTH_TYPE_KRB5:
142 return DCERPC_AUTH_TYPE_KRB5;
144 default:
145 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
146 "auth type %u\n",
147 (unsigned int)auth_type ));
148 break;
150 return -1;
153 /********************************************************************
154 Pipe description for a DEBUG
155 ********************************************************************/
156 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
157 struct rpc_pipe_client *cli)
159 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
160 if (result == NULL) {
161 return "pipe";
163 return result;
166 /********************************************************************
167 Rpc pipe call id.
168 ********************************************************************/
170 static uint32 get_rpc_call_id(void)
172 static uint32 call_id = 0;
173 return ++call_id;
177 * Realloc pdu to have a least "size" bytes
180 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
182 size_t extra_size;
184 if (prs_data_size(pdu) >= size) {
185 return true;
188 extra_size = size - prs_data_size(pdu);
190 if (!prs_force_grow(pdu, extra_size)) {
191 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
192 "%d bytes.\n", (int)extra_size));
193 return false;
196 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
197 (int)extra_size, prs_data_size(pdu)));
198 return true;
202 /*******************************************************************
203 Use SMBreadX to get rest of one fragment's worth of rpc data.
204 Reads the whole size or give an error message
205 ********************************************************************/
207 struct rpc_read_state {
208 struct event_context *ev;
209 struct rpc_cli_transport *transport;
210 uint8_t *data;
211 size_t size;
212 size_t num_read;
215 static void rpc_read_done(struct tevent_req *subreq);
217 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
218 struct event_context *ev,
219 struct rpc_cli_transport *transport,
220 uint8_t *data, size_t size)
222 struct tevent_req *req, *subreq;
223 struct rpc_read_state *state;
225 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
226 if (req == NULL) {
227 return NULL;
229 state->ev = ev;
230 state->transport = transport;
231 state->data = data;
232 state->size = size;
233 state->num_read = 0;
235 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
237 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
238 transport->priv);
239 if (subreq == NULL) {
240 goto fail;
242 tevent_req_set_callback(subreq, rpc_read_done, req);
243 return req;
245 fail:
246 TALLOC_FREE(req);
247 return NULL;
250 static void rpc_read_done(struct tevent_req *subreq)
252 struct tevent_req *req = tevent_req_callback_data(
253 subreq, struct tevent_req);
254 struct rpc_read_state *state = tevent_req_data(
255 req, struct rpc_read_state);
256 NTSTATUS status;
257 ssize_t received;
259 status = state->transport->read_recv(subreq, &received);
260 TALLOC_FREE(subreq);
261 if (!NT_STATUS_IS_OK(status)) {
262 tevent_req_nterror(req, status);
263 return;
266 state->num_read += received;
267 if (state->num_read == state->size) {
268 tevent_req_done(req);
269 return;
272 subreq = state->transport->read_send(state, state->ev,
273 state->data + state->num_read,
274 state->size - state->num_read,
275 state->transport->priv);
276 if (tevent_req_nomem(subreq, req)) {
277 return;
279 tevent_req_set_callback(subreq, rpc_read_done, req);
282 static NTSTATUS rpc_read_recv(struct tevent_req *req)
284 return tevent_req_simple_recv_ntstatus(req);
287 struct rpc_write_state {
288 struct event_context *ev;
289 struct rpc_cli_transport *transport;
290 const uint8_t *data;
291 size_t size;
292 size_t num_written;
295 static void rpc_write_done(struct tevent_req *subreq);
297 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
298 struct event_context *ev,
299 struct rpc_cli_transport *transport,
300 const uint8_t *data, size_t size)
302 struct tevent_req *req, *subreq;
303 struct rpc_write_state *state;
305 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
306 if (req == NULL) {
307 return NULL;
309 state->ev = ev;
310 state->transport = transport;
311 state->data = data;
312 state->size = size;
313 state->num_written = 0;
315 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
317 subreq = transport->write_send(state, ev, data, size, transport->priv);
318 if (subreq == NULL) {
319 goto fail;
321 tevent_req_set_callback(subreq, rpc_write_done, req);
322 return req;
323 fail:
324 TALLOC_FREE(req);
325 return NULL;
328 static void rpc_write_done(struct tevent_req *subreq)
330 struct tevent_req *req = tevent_req_callback_data(
331 subreq, struct tevent_req);
332 struct rpc_write_state *state = tevent_req_data(
333 req, struct rpc_write_state);
334 NTSTATUS status;
335 ssize_t written;
337 status = state->transport->write_recv(subreq, &written);
338 TALLOC_FREE(subreq);
339 if (!NT_STATUS_IS_OK(status)) {
340 tevent_req_nterror(req, status);
341 return;
344 state->num_written += written;
346 if (state->num_written == state->size) {
347 tevent_req_done(req);
348 return;
351 subreq = state->transport->write_send(state, state->ev,
352 state->data + state->num_written,
353 state->size - state->num_written,
354 state->transport->priv);
355 if (tevent_req_nomem(subreq, req)) {
356 return;
358 tevent_req_set_callback(subreq, rpc_write_done, req);
361 static NTSTATUS rpc_write_recv(struct tevent_req *req)
363 return tevent_req_simple_recv_ntstatus(req);
367 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
368 struct rpc_hdr_info *prhdr,
369 prs_struct *pdu)
372 * This next call sets the endian bit correctly in current_pdu. We
373 * will propagate this to rbuf later.
376 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
377 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
378 return NT_STATUS_BUFFER_TOO_SMALL;
381 if (prhdr->frag_len > cli->max_recv_frag) {
382 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
383 " we only allow %d\n", (int)prhdr->frag_len,
384 (int)cli->max_recv_frag));
385 return NT_STATUS_BUFFER_TOO_SMALL;
388 return NT_STATUS_OK;
391 /****************************************************************************
392 Try and get a PDU's worth of data from current_pdu. If not, then read more
393 from the wire.
394 ****************************************************************************/
396 struct get_complete_frag_state {
397 struct event_context *ev;
398 struct rpc_pipe_client *cli;
399 struct rpc_hdr_info *prhdr;
400 prs_struct *pdu;
403 static void get_complete_frag_got_header(struct tevent_req *subreq);
404 static void get_complete_frag_got_rest(struct tevent_req *subreq);
406 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
407 struct event_context *ev,
408 struct rpc_pipe_client *cli,
409 struct rpc_hdr_info *prhdr,
410 prs_struct *pdu)
412 struct tevent_req *req, *subreq;
413 struct get_complete_frag_state *state;
414 uint32_t pdu_len;
415 NTSTATUS status;
417 req = tevent_req_create(mem_ctx, &state,
418 struct get_complete_frag_state);
419 if (req == NULL) {
420 return NULL;
422 state->ev = ev;
423 state->cli = cli;
424 state->prhdr = prhdr;
425 state->pdu = pdu;
427 pdu_len = prs_data_size(pdu);
428 if (pdu_len < RPC_HEADER_LEN) {
429 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
430 status = NT_STATUS_NO_MEMORY;
431 goto post_status;
433 subreq = rpc_read_send(
434 state, state->ev,
435 state->cli->transport,
436 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
437 RPC_HEADER_LEN - pdu_len);
438 if (subreq == NULL) {
439 status = NT_STATUS_NO_MEMORY;
440 goto post_status;
442 tevent_req_set_callback(subreq, get_complete_frag_got_header,
443 req);
444 return req;
447 status = parse_rpc_header(cli, prhdr, pdu);
448 if (!NT_STATUS_IS_OK(status)) {
449 goto post_status;
453 * Ensure we have frag_len bytes of data.
455 if (pdu_len < prhdr->frag_len) {
456 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
457 status = NT_STATUS_NO_MEMORY;
458 goto post_status;
460 subreq = rpc_read_send(state, state->ev,
461 state->cli->transport,
462 (uint8_t *)(prs_data_p(pdu) + pdu_len),
463 prhdr->frag_len - pdu_len);
464 if (subreq == NULL) {
465 status = NT_STATUS_NO_MEMORY;
466 goto post_status;
468 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
469 req);
470 return req;
473 status = NT_STATUS_OK;
474 post_status:
475 if (NT_STATUS_IS_OK(status)) {
476 tevent_req_done(req);
477 } else {
478 tevent_req_nterror(req, status);
480 return tevent_req_post(req, ev);
483 static void get_complete_frag_got_header(struct tevent_req *subreq)
485 struct tevent_req *req = tevent_req_callback_data(
486 subreq, struct tevent_req);
487 struct get_complete_frag_state *state = tevent_req_data(
488 req, struct get_complete_frag_state);
489 NTSTATUS status;
491 status = rpc_read_recv(subreq);
492 TALLOC_FREE(subreq);
493 if (!NT_STATUS_IS_OK(status)) {
494 tevent_req_nterror(req, status);
495 return;
498 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
499 if (!NT_STATUS_IS_OK(status)) {
500 tevent_req_nterror(req, status);
501 return;
504 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
505 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
506 return;
510 * We're here in this piece of code because we've read exactly
511 * RPC_HEADER_LEN bytes into state->pdu.
514 subreq = rpc_read_send(
515 state, state->ev, state->cli->transport,
516 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
517 state->prhdr->frag_len - RPC_HEADER_LEN);
518 if (tevent_req_nomem(subreq, req)) {
519 return;
521 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
524 static void get_complete_frag_got_rest(struct tevent_req *subreq)
526 struct tevent_req *req = tevent_req_callback_data(
527 subreq, struct tevent_req);
528 NTSTATUS status;
530 status = rpc_read_recv(subreq);
531 TALLOC_FREE(subreq);
532 if (!NT_STATUS_IS_OK(status)) {
533 tevent_req_nterror(req, status);
534 return;
536 tevent_req_done(req);
539 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
541 return tevent_req_simple_recv_ntstatus(req);
544 /****************************************************************************
545 NTLMSSP specific sign/seal.
546 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
547 In fact I should probably abstract these into identical pieces of code... JRA.
548 ****************************************************************************/
550 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
551 prs_struct *current_pdu,
552 uint8 *p_ss_padding_len)
554 RPC_HDR_AUTH auth_info;
555 uint32 save_offset = prs_offset(current_pdu);
556 uint32 auth_len = prhdr->auth_len;
557 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
558 unsigned char *data = NULL;
559 size_t data_len;
560 unsigned char *full_packet_data = NULL;
561 size_t full_packet_data_len;
562 DATA_BLOB auth_blob;
563 NTSTATUS status;
565 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
566 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
567 return NT_STATUS_OK;
570 if (!ntlmssp_state) {
571 return NT_STATUS_INVALID_PARAMETER;
574 /* Ensure there's enough data for an authenticated response. */
575 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
576 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
577 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
578 (unsigned int)auth_len ));
579 return NT_STATUS_BUFFER_TOO_SMALL;
583 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
584 * after the RPC header.
585 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
586 * functions as NTLMv2 checks the rpc headers also.
589 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
590 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
592 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
593 full_packet_data_len = prhdr->frag_len - auth_len;
595 /* Pull the auth header and the following data into a blob. */
596 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
597 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
598 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
599 return NT_STATUS_BUFFER_TOO_SMALL;
602 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
603 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
604 return NT_STATUS_BUFFER_TOO_SMALL;
607 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
608 auth_blob.length = auth_len;
610 switch (cli->auth->auth_level) {
611 case DCERPC_AUTH_LEVEL_PRIVACY:
612 /* Data is encrypted. */
613 status = ntlmssp_unseal_packet(ntlmssp_state,
614 data, data_len,
615 full_packet_data,
616 full_packet_data_len,
617 &auth_blob);
618 if (!NT_STATUS_IS_OK(status)) {
619 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
620 "packet from %s. Error was %s.\n",
621 rpccli_pipe_txt(debug_ctx(), cli),
622 nt_errstr(status) ));
623 return status;
625 break;
626 case DCERPC_AUTH_LEVEL_INTEGRITY:
627 /* Data is signed. */
628 status = ntlmssp_check_packet(ntlmssp_state,
629 data, data_len,
630 full_packet_data,
631 full_packet_data_len,
632 &auth_blob);
633 if (!NT_STATUS_IS_OK(status)) {
634 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
635 "packet from %s. Error was %s.\n",
636 rpccli_pipe_txt(debug_ctx(), cli),
637 nt_errstr(status) ));
638 return status;
640 break;
641 default:
642 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
643 "auth level %d\n", cli->auth->auth_level));
644 return NT_STATUS_INVALID_INFO_CLASS;
648 * Return the current pointer to the data offset.
651 if(!prs_set_offset(current_pdu, save_offset)) {
652 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
653 (unsigned int)save_offset ));
654 return NT_STATUS_BUFFER_TOO_SMALL;
658 * Remember the padding length. We must remove it from the real data
659 * stream once the sign/seal is done.
662 *p_ss_padding_len = auth_info.auth_pad_len;
664 return NT_STATUS_OK;
667 /****************************************************************************
668 schannel specific sign/seal.
669 ****************************************************************************/
671 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
672 prs_struct *current_pdu,
673 uint8 *p_ss_padding_len)
675 RPC_HDR_AUTH auth_info;
676 uint32 auth_len = prhdr->auth_len;
677 uint32 save_offset = prs_offset(current_pdu);
678 struct schannel_state *schannel_auth =
679 cli->auth->a_u.schannel_auth;
680 uint8_t *data;
681 uint32 data_len;
682 DATA_BLOB blob;
683 NTSTATUS status;
685 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
686 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
687 return NT_STATUS_OK;
690 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
691 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
692 return NT_STATUS_INVALID_PARAMETER;
695 if (!schannel_auth) {
696 return NT_STATUS_INVALID_PARAMETER;
699 /* Ensure there's enough data for an authenticated response. */
700 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
701 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
702 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
703 (unsigned int)auth_len ));
704 return NT_STATUS_INVALID_PARAMETER;
707 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
709 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
710 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
711 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
712 return NT_STATUS_BUFFER_TOO_SMALL;
715 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
716 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
717 return NT_STATUS_BUFFER_TOO_SMALL;
720 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
721 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
722 auth_info.auth_type));
723 return NT_STATUS_BUFFER_TOO_SMALL;
726 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
728 if (DEBUGLEVEL >= 10) {
729 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
732 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
734 switch (cli->auth->auth_level) {
735 case DCERPC_AUTH_LEVEL_PRIVACY:
736 status = netsec_incoming_packet(schannel_auth,
737 talloc_tos(),
738 true,
739 data,
740 data_len,
741 &blob);
742 break;
743 case DCERPC_AUTH_LEVEL_INTEGRITY:
744 status = netsec_incoming_packet(schannel_auth,
745 talloc_tos(),
746 false,
747 data,
748 data_len,
749 &blob);
750 break;
751 default:
752 status = NT_STATUS_INTERNAL_ERROR;
753 break;
756 if (!NT_STATUS_IS_OK(status)) {
757 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
758 "Connection to %s (%s).\n",
759 rpccli_pipe_txt(debug_ctx(), cli),
760 nt_errstr(status)));
761 return NT_STATUS_INVALID_PARAMETER;
765 * Return the current pointer to the data offset.
768 if(!prs_set_offset(current_pdu, save_offset)) {
769 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
770 (unsigned int)save_offset ));
771 return NT_STATUS_BUFFER_TOO_SMALL;
775 * Remember the padding length. We must remove it from the real data
776 * stream once the sign/seal is done.
779 *p_ss_padding_len = auth_info.auth_pad_len;
781 return NT_STATUS_OK;
784 /****************************************************************************
785 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
786 ****************************************************************************/
788 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
789 prs_struct *current_pdu,
790 uint8 *p_ss_padding_len)
792 NTSTATUS ret = NT_STATUS_OK;
794 /* Paranioa checks for auth_len. */
795 if (prhdr->auth_len) {
796 if (prhdr->auth_len > prhdr->frag_len) {
797 return NT_STATUS_INVALID_PARAMETER;
800 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
801 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
802 /* Integer wrap attempt. */
803 return NT_STATUS_INVALID_PARAMETER;
808 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
811 switch(cli->auth->auth_type) {
812 case PIPE_AUTH_TYPE_NONE:
813 if (prhdr->auth_len) {
814 DEBUG(3, ("cli_pipe_validate_rpc_response: "
815 "Connection to %s - got non-zero "
816 "auth len %u.\n",
817 rpccli_pipe_txt(debug_ctx(), cli),
818 (unsigned int)prhdr->auth_len ));
819 return NT_STATUS_INVALID_PARAMETER;
821 break;
823 case PIPE_AUTH_TYPE_NTLMSSP:
824 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
825 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
826 if (!NT_STATUS_IS_OK(ret)) {
827 return ret;
829 break;
831 case PIPE_AUTH_TYPE_SCHANNEL:
832 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
833 if (!NT_STATUS_IS_OK(ret)) {
834 return ret;
836 break;
838 case PIPE_AUTH_TYPE_KRB5:
839 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
840 default:
841 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
842 "to %s - unknown internal auth type %u.\n",
843 rpccli_pipe_txt(debug_ctx(), cli),
844 cli->auth->auth_type ));
845 return NT_STATUS_INVALID_INFO_CLASS;
848 return NT_STATUS_OK;
851 /****************************************************************************
852 Do basic authentication checks on an incoming pdu.
853 ****************************************************************************/
855 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
856 prs_struct *current_pdu,
857 uint8 expected_pkt_type,
858 char **ppdata,
859 uint32 *pdata_len,
860 prs_struct *return_data)
863 NTSTATUS ret = NT_STATUS_OK;
864 uint32 current_pdu_len = prs_data_size(current_pdu);
866 if (current_pdu_len != prhdr->frag_len) {
867 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
868 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
869 return NT_STATUS_INVALID_PARAMETER;
873 * Point the return values at the real data including the RPC
874 * header. Just in case the caller wants it.
876 *ppdata = prs_data_p(current_pdu);
877 *pdata_len = current_pdu_len;
879 /* Ensure we have the correct type. */
880 switch (prhdr->pkt_type) {
881 case DCERPC_PKT_ALTER_RESP:
882 case DCERPC_PKT_BIND_ACK:
884 /* Alter context and bind ack share the same packet definitions. */
885 break;
888 case DCERPC_PKT_RESPONSE:
890 RPC_HDR_RESP rhdr_resp;
891 uint8 ss_padding_len = 0;
893 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
894 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
895 return NT_STATUS_BUFFER_TOO_SMALL;
898 /* Here's where we deal with incoming sign/seal. */
899 ret = cli_pipe_validate_rpc_response(cli, prhdr,
900 current_pdu, &ss_padding_len);
901 if (!NT_STATUS_IS_OK(ret)) {
902 return ret;
905 /* Point the return values at the NDR data. Remember to remove any ss padding. */
906 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
908 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
909 return NT_STATUS_BUFFER_TOO_SMALL;
912 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
914 /* Remember to remove the auth footer. */
915 if (prhdr->auth_len) {
916 /* We've already done integer wrap tests on auth_len in
917 cli_pipe_validate_rpc_response(). */
918 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
919 return NT_STATUS_BUFFER_TOO_SMALL;
921 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
924 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
925 current_pdu_len, *pdata_len, ss_padding_len ));
928 * If this is the first reply, and the allocation hint is reasonably, try and
929 * set up the return_data parse_struct to the correct size.
932 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
933 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
934 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
935 "too large to allocate\n",
936 (unsigned int)rhdr_resp.alloc_hint ));
937 return NT_STATUS_NO_MEMORY;
941 break;
944 case DCERPC_PKT_BIND_NAK:
945 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
946 "received from %s!\n",
947 rpccli_pipe_txt(debug_ctx(), cli)));
948 /* Use this for now... */
949 return NT_STATUS_NETWORK_ACCESS_DENIED;
951 case DCERPC_PKT_FAULT:
953 RPC_HDR_RESP rhdr_resp;
954 RPC_HDR_FAULT fault_resp;
956 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
957 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
958 return NT_STATUS_BUFFER_TOO_SMALL;
961 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
962 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
963 return NT_STATUS_BUFFER_TOO_SMALL;
966 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
967 "code %s received from %s!\n",
968 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
969 rpccli_pipe_txt(debug_ctx(), cli)));
970 if (NT_STATUS_IS_OK(fault_resp.status)) {
971 return NT_STATUS_UNSUCCESSFUL;
972 } else {
973 return fault_resp.status;
977 default:
978 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
979 "from %s!\n",
980 (unsigned int)prhdr->pkt_type,
981 rpccli_pipe_txt(debug_ctx(), cli)));
982 return NT_STATUS_INVALID_INFO_CLASS;
985 if (prhdr->pkt_type != expected_pkt_type) {
986 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
987 "got an unexpected RPC packet type - %u, not %u\n",
988 rpccli_pipe_txt(debug_ctx(), cli),
989 prhdr->pkt_type,
990 expected_pkt_type));
991 return NT_STATUS_INVALID_INFO_CLASS;
994 /* Do this just before return - we don't want to modify any rpc header
995 data before now as we may have needed to do cryptographic actions on
996 it before. */
998 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
999 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1000 "setting fragment first/last ON.\n"));
1001 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1004 return NT_STATUS_OK;
1007 /****************************************************************************
1008 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1009 Normally the frag_len and buffer size will match, but on the first trans
1010 reply there is a theoretical chance that buffer size > frag_len, so we must
1011 deal with that.
1012 ****************************************************************************/
1014 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1016 uint32 current_pdu_len = prs_data_size(current_pdu);
1018 if (current_pdu_len < prhdr->frag_len) {
1019 return NT_STATUS_BUFFER_TOO_SMALL;
1022 /* Common case. */
1023 if (current_pdu_len == (uint32)prhdr->frag_len) {
1024 prs_mem_free(current_pdu);
1025 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1026 /* Make current_pdu dynamic with no memory. */
1027 prs_give_memory(current_pdu, 0, 0, True);
1028 return NT_STATUS_OK;
1032 * Oh no ! More data in buffer than we processed in current pdu.
1033 * Cheat. Move the data down and shrink the buffer.
1036 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1037 current_pdu_len - prhdr->frag_len);
1039 /* Remember to set the read offset back to zero. */
1040 prs_set_offset(current_pdu, 0);
1042 /* Shrink the buffer. */
1043 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1044 return NT_STATUS_BUFFER_TOO_SMALL;
1047 return NT_STATUS_OK;
1050 /****************************************************************************
1051 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1052 ****************************************************************************/
1054 struct cli_api_pipe_state {
1055 struct event_context *ev;
1056 struct rpc_cli_transport *transport;
1057 uint8_t *rdata;
1058 uint32_t rdata_len;
1061 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1062 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1063 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1065 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1066 struct event_context *ev,
1067 struct rpc_cli_transport *transport,
1068 uint8_t *data, size_t data_len,
1069 uint32_t max_rdata_len)
1071 struct tevent_req *req, *subreq;
1072 struct cli_api_pipe_state *state;
1073 NTSTATUS status;
1075 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1076 if (req == NULL) {
1077 return NULL;
1079 state->ev = ev;
1080 state->transport = transport;
1082 if (max_rdata_len < RPC_HEADER_LEN) {
1084 * For a RPC reply we always need at least RPC_HEADER_LEN
1085 * bytes. We check this here because we will receive
1086 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1088 status = NT_STATUS_INVALID_PARAMETER;
1089 goto post_status;
1092 if (transport->trans_send != NULL) {
1093 subreq = transport->trans_send(state, ev, data, data_len,
1094 max_rdata_len, transport->priv);
1095 if (subreq == NULL) {
1096 goto fail;
1098 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1099 return req;
1103 * If the transport does not provide a "trans" routine, i.e. for
1104 * example the ncacn_ip_tcp transport, do the write/read step here.
1107 subreq = rpc_write_send(state, ev, transport, data, data_len);
1108 if (subreq == NULL) {
1109 goto fail;
1111 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1112 return req;
1114 status = NT_STATUS_INVALID_PARAMETER;
1116 post_status:
1117 tevent_req_nterror(req, status);
1118 return tevent_req_post(req, ev);
1119 fail:
1120 TALLOC_FREE(req);
1121 return NULL;
1124 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1126 struct tevent_req *req = tevent_req_callback_data(
1127 subreq, struct tevent_req);
1128 struct cli_api_pipe_state *state = tevent_req_data(
1129 req, struct cli_api_pipe_state);
1130 NTSTATUS status;
1132 status = state->transport->trans_recv(subreq, state, &state->rdata,
1133 &state->rdata_len);
1134 TALLOC_FREE(subreq);
1135 if (!NT_STATUS_IS_OK(status)) {
1136 tevent_req_nterror(req, status);
1137 return;
1139 tevent_req_done(req);
1142 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1144 struct tevent_req *req = tevent_req_callback_data(
1145 subreq, struct tevent_req);
1146 struct cli_api_pipe_state *state = tevent_req_data(
1147 req, struct cli_api_pipe_state);
1148 NTSTATUS status;
1150 status = rpc_write_recv(subreq);
1151 TALLOC_FREE(subreq);
1152 if (!NT_STATUS_IS_OK(status)) {
1153 tevent_req_nterror(req, status);
1154 return;
1157 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1158 if (tevent_req_nomem(state->rdata, req)) {
1159 return;
1163 * We don't need to use rpc_read_send here, the upper layer will cope
1164 * with a short read, transport->trans_send could also return less
1165 * than state->max_rdata_len.
1167 subreq = state->transport->read_send(state, state->ev, state->rdata,
1168 RPC_HEADER_LEN,
1169 state->transport->priv);
1170 if (tevent_req_nomem(subreq, req)) {
1171 return;
1173 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1176 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1178 struct tevent_req *req = tevent_req_callback_data(
1179 subreq, struct tevent_req);
1180 struct cli_api_pipe_state *state = tevent_req_data(
1181 req, struct cli_api_pipe_state);
1182 NTSTATUS status;
1183 ssize_t received;
1185 status = state->transport->read_recv(subreq, &received);
1186 TALLOC_FREE(subreq);
1187 if (!NT_STATUS_IS_OK(status)) {
1188 tevent_req_nterror(req, status);
1189 return;
1191 state->rdata_len = received;
1192 tevent_req_done(req);
1195 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1196 uint8_t **prdata, uint32_t *prdata_len)
1198 struct cli_api_pipe_state *state = tevent_req_data(
1199 req, struct cli_api_pipe_state);
1200 NTSTATUS status;
1202 if (tevent_req_is_nterror(req, &status)) {
1203 return status;
1206 *prdata = talloc_move(mem_ctx, &state->rdata);
1207 *prdata_len = state->rdata_len;
1208 return NT_STATUS_OK;
1211 /****************************************************************************
1212 Send data on an rpc pipe via trans. The prs_struct data must be the last
1213 pdu fragment of an NDR data stream.
1215 Receive response data from an rpc pipe, which may be large...
1217 Read the first fragment: unfortunately have to use SMBtrans for the first
1218 bit, then SMBreadX for subsequent bits.
1220 If first fragment received also wasn't the last fragment, continue
1221 getting fragments until we _do_ receive the last fragment.
1223 Request/Response PDU's look like the following...
1225 |<------------------PDU len----------------------------------------------->|
1226 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1228 +------------+-----------------+-------------+---------------+-------------+
1229 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1230 +------------+-----------------+-------------+---------------+-------------+
1232 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1233 signing & sealing being negotiated.
1235 ****************************************************************************/
1237 struct rpc_api_pipe_state {
1238 struct event_context *ev;
1239 struct rpc_pipe_client *cli;
1240 uint8_t expected_pkt_type;
1242 prs_struct incoming_frag;
1243 struct rpc_hdr_info rhdr;
1245 prs_struct incoming_pdu; /* Incoming reply */
1246 uint32_t incoming_pdu_offset;
1249 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1251 prs_mem_free(&state->incoming_frag);
1252 prs_mem_free(&state->incoming_pdu);
1253 return 0;
1256 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1257 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1259 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1260 struct event_context *ev,
1261 struct rpc_pipe_client *cli,
1262 prs_struct *data, /* Outgoing PDU */
1263 uint8_t expected_pkt_type)
1265 struct tevent_req *req, *subreq;
1266 struct rpc_api_pipe_state *state;
1267 uint16_t max_recv_frag;
1268 NTSTATUS status;
1270 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1271 if (req == NULL) {
1272 return NULL;
1274 state->ev = ev;
1275 state->cli = cli;
1276 state->expected_pkt_type = expected_pkt_type;
1277 state->incoming_pdu_offset = 0;
1279 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1281 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1282 /* Make incoming_pdu dynamic with no memory. */
1283 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1285 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1288 * Ensure we're not sending too much.
1290 if (prs_offset(data) > cli->max_xmit_frag) {
1291 status = NT_STATUS_INVALID_PARAMETER;
1292 goto post_status;
1295 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1297 max_recv_frag = cli->max_recv_frag;
1299 #ifdef DEVELOPER
1300 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1301 #endif
1303 subreq = cli_api_pipe_send(state, ev, cli->transport,
1304 (uint8_t *)prs_data_p(data),
1305 prs_offset(data), max_recv_frag);
1306 if (subreq == NULL) {
1307 goto fail;
1309 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1310 return req;
1312 post_status:
1313 tevent_req_nterror(req, status);
1314 return tevent_req_post(req, ev);
1315 fail:
1316 TALLOC_FREE(req);
1317 return NULL;
1320 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1322 struct tevent_req *req = tevent_req_callback_data(
1323 subreq, struct tevent_req);
1324 struct rpc_api_pipe_state *state = tevent_req_data(
1325 req, struct rpc_api_pipe_state);
1326 NTSTATUS status;
1327 uint8_t *rdata = NULL;
1328 uint32_t rdata_len = 0;
1329 char *rdata_copy;
1331 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1332 TALLOC_FREE(subreq);
1333 if (!NT_STATUS_IS_OK(status)) {
1334 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1335 tevent_req_nterror(req, status);
1336 return;
1339 if (rdata == NULL) {
1340 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1341 rpccli_pipe_txt(debug_ctx(), state->cli)));
1342 tevent_req_done(req);
1343 return;
1347 * Give the memory received from cli_trans as dynamic to the current
1348 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1349 * :-(
1351 rdata_copy = (char *)memdup(rdata, rdata_len);
1352 TALLOC_FREE(rdata);
1353 if (tevent_req_nomem(rdata_copy, req)) {
1354 return;
1356 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1358 /* Ensure we have enough data for a pdu. */
1359 subreq = get_complete_frag_send(state, state->ev, state->cli,
1360 &state->rhdr, &state->incoming_frag);
1361 if (tevent_req_nomem(subreq, req)) {
1362 return;
1364 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1367 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1369 struct tevent_req *req = tevent_req_callback_data(
1370 subreq, struct tevent_req);
1371 struct rpc_api_pipe_state *state = tevent_req_data(
1372 req, struct rpc_api_pipe_state);
1373 NTSTATUS status;
1374 char *rdata = NULL;
1375 uint32_t rdata_len = 0;
1377 status = get_complete_frag_recv(subreq);
1378 TALLOC_FREE(subreq);
1379 if (!NT_STATUS_IS_OK(status)) {
1380 DEBUG(5, ("get_complete_frag failed: %s\n",
1381 nt_errstr(status)));
1382 tevent_req_nterror(req, status);
1383 return;
1386 status = cli_pipe_validate_current_pdu(
1387 state->cli, &state->rhdr, &state->incoming_frag,
1388 state->expected_pkt_type, &rdata, &rdata_len,
1389 &state->incoming_pdu);
1391 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1392 (unsigned)prs_data_size(&state->incoming_frag),
1393 (unsigned)state->incoming_pdu_offset,
1394 nt_errstr(status)));
1396 if (!NT_STATUS_IS_OK(status)) {
1397 tevent_req_nterror(req, status);
1398 return;
1401 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1402 && (state->rhdr.pack_type[0] == 0)) {
1404 * Set the data type correctly for big-endian data on the
1405 * first packet.
1407 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1408 "big-endian.\n",
1409 rpccli_pipe_txt(debug_ctx(), state->cli)));
1410 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1413 * Check endianness on subsequent packets.
1415 if (state->incoming_frag.bigendian_data
1416 != state->incoming_pdu.bigendian_data) {
1417 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1418 "%s\n",
1419 state->incoming_pdu.bigendian_data?"big":"little",
1420 state->incoming_frag.bigendian_data?"big":"little"));
1421 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1422 return;
1425 /* Now copy the data portion out of the pdu into rbuf. */
1426 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1427 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1428 return;
1431 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1432 rdata, (size_t)rdata_len);
1433 state->incoming_pdu_offset += rdata_len;
1435 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1436 &state->incoming_frag);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 tevent_req_nterror(req, status);
1439 return;
1442 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1443 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1444 rpccli_pipe_txt(debug_ctx(), state->cli),
1445 (unsigned)prs_data_size(&state->incoming_pdu)));
1446 tevent_req_done(req);
1447 return;
1450 subreq = get_complete_frag_send(state, state->ev, state->cli,
1451 &state->rhdr, &state->incoming_frag);
1452 if (tevent_req_nomem(subreq, req)) {
1453 return;
1455 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1458 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1459 prs_struct *reply_pdu)
1461 struct rpc_api_pipe_state *state = tevent_req_data(
1462 req, struct rpc_api_pipe_state);
1463 NTSTATUS status;
1465 if (tevent_req_is_nterror(req, &status)) {
1466 return status;
1469 *reply_pdu = state->incoming_pdu;
1470 reply_pdu->mem_ctx = mem_ctx;
1473 * Prevent state->incoming_pdu from being freed in
1474 * rpc_api_pipe_state_destructor()
1476 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1478 return NT_STATUS_OK;
1481 /*******************************************************************
1482 Creates krb5 auth bind.
1483 ********************************************************************/
1485 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1486 enum dcerpc_AuthLevel auth_level,
1487 RPC_HDR_AUTH *pauth_out,
1488 prs_struct *auth_data)
1490 #ifdef HAVE_KRB5
1491 int ret;
1492 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1493 DATA_BLOB tkt = data_blob_null;
1494 DATA_BLOB tkt_wrapped = data_blob_null;
1496 /* We may change the pad length before marshalling. */
1497 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1499 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1500 a->service_principal ));
1502 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1504 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1505 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1507 if (ret) {
1508 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1509 "failed with %s\n",
1510 a->service_principal,
1511 error_message(ret) ));
1513 data_blob_free(&tkt);
1514 prs_mem_free(auth_data);
1515 return NT_STATUS_INVALID_PARAMETER;
1518 /* wrap that up in a nice GSS-API wrapping */
1519 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1521 data_blob_free(&tkt);
1523 /* Auth len in the rpc header doesn't include auth_header. */
1524 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1525 data_blob_free(&tkt_wrapped);
1526 prs_mem_free(auth_data);
1527 return NT_STATUS_NO_MEMORY;
1530 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1531 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1533 data_blob_free(&tkt_wrapped);
1534 return NT_STATUS_OK;
1535 #else
1536 return NT_STATUS_INVALID_PARAMETER;
1537 #endif
1540 /*******************************************************************
1541 Creates SPNEGO NTLMSSP auth bind.
1542 ********************************************************************/
1544 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1545 enum dcerpc_AuthLevel auth_level,
1546 RPC_HDR_AUTH *pauth_out,
1547 prs_struct *auth_data)
1549 NTSTATUS nt_status;
1550 DATA_BLOB null_blob = data_blob_null;
1551 DATA_BLOB request = data_blob_null;
1552 DATA_BLOB spnego_msg = data_blob_null;
1554 /* We may change the pad length before marshalling. */
1555 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1557 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1558 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1559 null_blob,
1560 &request);
1562 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1563 data_blob_free(&request);
1564 prs_mem_free(auth_data);
1565 return nt_status;
1568 /* Wrap this in SPNEGO. */
1569 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1571 data_blob_free(&request);
1573 /* Auth len in the rpc header doesn't include auth_header. */
1574 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1575 data_blob_free(&spnego_msg);
1576 prs_mem_free(auth_data);
1577 return NT_STATUS_NO_MEMORY;
1580 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1581 dump_data(5, spnego_msg.data, spnego_msg.length);
1583 data_blob_free(&spnego_msg);
1584 return NT_STATUS_OK;
1587 /*******************************************************************
1588 Creates NTLMSSP auth bind.
1589 ********************************************************************/
1591 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1592 enum dcerpc_AuthLevel auth_level,
1593 RPC_HDR_AUTH *pauth_out,
1594 prs_struct *auth_data)
1596 NTSTATUS nt_status;
1597 DATA_BLOB null_blob = data_blob_null;
1598 DATA_BLOB request = data_blob_null;
1600 /* We may change the pad length before marshalling. */
1601 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1603 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1604 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1605 null_blob,
1606 &request);
1608 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1609 data_blob_free(&request);
1610 prs_mem_free(auth_data);
1611 return nt_status;
1614 /* Auth len in the rpc header doesn't include auth_header. */
1615 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1616 data_blob_free(&request);
1617 prs_mem_free(auth_data);
1618 return NT_STATUS_NO_MEMORY;
1621 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1622 dump_data(5, request.data, request.length);
1624 data_blob_free(&request);
1625 return NT_STATUS_OK;
1628 /*******************************************************************
1629 Creates schannel auth bind.
1630 ********************************************************************/
1632 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1633 enum dcerpc_AuthLevel auth_level,
1634 RPC_HDR_AUTH *pauth_out,
1635 prs_struct *auth_data)
1637 struct NL_AUTH_MESSAGE r;
1638 enum ndr_err_code ndr_err;
1639 DATA_BLOB blob;
1641 /* We may change the pad length before marshalling. */
1642 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1644 /* Use lp_workgroup() if domain not specified */
1646 if (!cli->auth->domain || !cli->auth->domain[0]) {
1647 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1648 if (cli->auth->domain == NULL) {
1649 return NT_STATUS_NO_MEMORY;
1654 * Now marshall the data into the auth parse_struct.
1657 r.MessageType = NL_NEGOTIATE_REQUEST;
1658 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1659 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1660 r.oem_netbios_domain.a = cli->auth->domain;
1661 r.oem_netbios_computer.a = global_myname();
1663 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1664 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1665 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1666 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1667 prs_mem_free(auth_data);
1668 return ndr_map_error2ntstatus(ndr_err);
1671 if (DEBUGLEVEL >= 10) {
1672 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1675 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1677 prs_mem_free(auth_data);
1678 return NT_STATUS_NO_MEMORY;
1681 return NT_STATUS_OK;
1684 /*******************************************************************
1685 Creates the internals of a DCE/RPC bind request or alter context PDU.
1686 ********************************************************************/
1688 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1689 prs_struct *rpc_out,
1690 uint32 rpc_call_id,
1691 const struct ndr_syntax_id *abstract,
1692 const struct ndr_syntax_id *transfer,
1693 RPC_HDR_AUTH *phdr_auth,
1694 prs_struct *pauth_info)
1696 RPC_HDR hdr;
1697 RPC_HDR_RB hdr_rb;
1698 RPC_CONTEXT rpc_ctx;
1699 uint16 auth_len = prs_offset(pauth_info);
1700 uint8 ss_padding_len = 0;
1701 uint16 frag_len = 0;
1703 /* create the RPC context. */
1704 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1706 /* create the bind request RPC_HDR_RB */
1707 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1709 /* Start building the frag length. */
1710 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1712 /* Do we need to pad ? */
1713 if (auth_len) {
1714 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1715 if (data_len % 8) {
1716 ss_padding_len = 8 - (data_len % 8);
1717 phdr_auth->auth_pad_len = ss_padding_len;
1719 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1722 /* Create the request RPC_HDR */
1723 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1725 /* Marshall the RPC header */
1726 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1727 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1728 return NT_STATUS_NO_MEMORY;
1731 /* Marshall the bind request data */
1732 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1733 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1734 return NT_STATUS_NO_MEMORY;
1738 * Grow the outgoing buffer to store any auth info.
1741 if(auth_len != 0) {
1742 if (ss_padding_len) {
1743 char pad[8];
1744 memset(pad, '\0', 8);
1745 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1746 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1747 return NT_STATUS_NO_MEMORY;
1751 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1752 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1753 return NT_STATUS_NO_MEMORY;
1757 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1758 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1759 return NT_STATUS_NO_MEMORY;
1763 return NT_STATUS_OK;
1766 /*******************************************************************
1767 Creates a DCE/RPC bind request.
1768 ********************************************************************/
1770 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1771 prs_struct *rpc_out,
1772 uint32 rpc_call_id,
1773 const struct ndr_syntax_id *abstract,
1774 const struct ndr_syntax_id *transfer,
1775 enum pipe_auth_type auth_type,
1776 enum dcerpc_AuthLevel auth_level)
1778 RPC_HDR_AUTH hdr_auth;
1779 prs_struct auth_info;
1780 NTSTATUS ret = NT_STATUS_OK;
1782 ZERO_STRUCT(hdr_auth);
1783 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1784 return NT_STATUS_NO_MEMORY;
1786 switch (auth_type) {
1787 case PIPE_AUTH_TYPE_SCHANNEL:
1788 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1789 if (!NT_STATUS_IS_OK(ret)) {
1790 prs_mem_free(&auth_info);
1791 return ret;
1793 break;
1795 case PIPE_AUTH_TYPE_NTLMSSP:
1796 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1797 if (!NT_STATUS_IS_OK(ret)) {
1798 prs_mem_free(&auth_info);
1799 return ret;
1801 break;
1803 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1804 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1805 if (!NT_STATUS_IS_OK(ret)) {
1806 prs_mem_free(&auth_info);
1807 return ret;
1809 break;
1811 case PIPE_AUTH_TYPE_KRB5:
1812 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1813 if (!NT_STATUS_IS_OK(ret)) {
1814 prs_mem_free(&auth_info);
1815 return ret;
1817 break;
1819 case PIPE_AUTH_TYPE_NONE:
1820 break;
1822 default:
1823 /* "Can't" happen. */
1824 return NT_STATUS_INVALID_INFO_CLASS;
1827 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1828 rpc_out,
1829 rpc_call_id,
1830 abstract,
1831 transfer,
1832 &hdr_auth,
1833 &auth_info);
1835 prs_mem_free(&auth_info);
1836 return ret;
1839 /*******************************************************************
1840 Create and add the NTLMSSP sign/seal auth header and data.
1841 ********************************************************************/
1843 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1844 RPC_HDR *phdr,
1845 uint32 ss_padding_len,
1846 prs_struct *outgoing_pdu)
1848 RPC_HDR_AUTH auth_info;
1849 NTSTATUS status;
1850 DATA_BLOB auth_blob = data_blob_null;
1851 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1853 if (!cli->auth->a_u.ntlmssp_state) {
1854 return NT_STATUS_INVALID_PARAMETER;
1857 /* Init and marshall the auth header. */
1858 init_rpc_hdr_auth(&auth_info,
1859 map_pipe_auth_type_to_rpc_auth_type(
1860 cli->auth->auth_type),
1861 cli->auth->auth_level,
1862 ss_padding_len,
1863 1 /* context id. */);
1865 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1866 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1867 data_blob_free(&auth_blob);
1868 return NT_STATUS_NO_MEMORY;
1871 switch (cli->auth->auth_level) {
1872 case DCERPC_AUTH_LEVEL_PRIVACY:
1873 /* Data portion is encrypted. */
1874 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1875 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1876 data_and_pad_len,
1877 (unsigned char *)prs_data_p(outgoing_pdu),
1878 (size_t)prs_offset(outgoing_pdu),
1879 &auth_blob);
1880 if (!NT_STATUS_IS_OK(status)) {
1881 data_blob_free(&auth_blob);
1882 return status;
1884 break;
1886 case DCERPC_AUTH_LEVEL_INTEGRITY:
1887 /* Data is signed. */
1888 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1889 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1890 data_and_pad_len,
1891 (unsigned char *)prs_data_p(outgoing_pdu),
1892 (size_t)prs_offset(outgoing_pdu),
1893 &auth_blob);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 data_blob_free(&auth_blob);
1896 return status;
1898 break;
1900 default:
1901 /* Can't happen. */
1902 smb_panic("bad auth level");
1903 /* Notreached. */
1904 return NT_STATUS_INVALID_PARAMETER;
1907 /* Finally marshall the blob. */
1909 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1910 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1911 (unsigned int)NTLMSSP_SIG_SIZE));
1912 data_blob_free(&auth_blob);
1913 return NT_STATUS_NO_MEMORY;
1916 data_blob_free(&auth_blob);
1917 return NT_STATUS_OK;
1920 /*******************************************************************
1921 Create and add the schannel sign/seal auth header and data.
1922 ********************************************************************/
1924 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1925 RPC_HDR *phdr,
1926 uint32 ss_padding_len,
1927 prs_struct *outgoing_pdu)
1929 RPC_HDR_AUTH auth_info;
1930 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1931 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1932 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1933 DATA_BLOB blob;
1934 NTSTATUS status;
1936 if (!sas) {
1937 return NT_STATUS_INVALID_PARAMETER;
1940 /* Init and marshall the auth header. */
1941 init_rpc_hdr_auth(&auth_info,
1942 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1943 cli->auth->auth_level,
1944 ss_padding_len,
1945 1 /* context id. */);
1947 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1948 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1949 return NT_STATUS_NO_MEMORY;
1952 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1953 sas->seq_num));
1955 switch (cli->auth->auth_level) {
1956 case DCERPC_AUTH_LEVEL_PRIVACY:
1957 status = netsec_outgoing_packet(sas,
1958 talloc_tos(),
1959 true,
1960 (uint8_t *)data_p,
1961 data_and_pad_len,
1962 &blob);
1963 break;
1964 case DCERPC_AUTH_LEVEL_INTEGRITY:
1965 status = netsec_outgoing_packet(sas,
1966 talloc_tos(),
1967 false,
1968 (uint8_t *)data_p,
1969 data_and_pad_len,
1970 &blob);
1971 break;
1972 default:
1973 status = NT_STATUS_INTERNAL_ERROR;
1974 break;
1977 if (!NT_STATUS_IS_OK(status)) {
1978 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1979 nt_errstr(status)));
1980 return status;
1983 if (DEBUGLEVEL >= 10) {
1984 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1987 /* Finally marshall the blob. */
1988 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
1989 return NT_STATUS_NO_MEMORY;
1992 return NT_STATUS_OK;
1995 /*******************************************************************
1996 Calculate how much data we're going to send in this packet, also
1997 work out any sign/seal padding length.
1998 ********************************************************************/
2000 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2001 uint32 data_left,
2002 uint16 *p_frag_len,
2003 uint16 *p_auth_len,
2004 uint32 *p_ss_padding)
2006 uint32 data_space, data_len;
2008 #ifdef DEVELOPER
2009 if ((data_left > 0) && (sys_random() % 2)) {
2010 data_left = MAX(data_left/2, 1);
2012 #endif
2014 switch (cli->auth->auth_level) {
2015 case DCERPC_AUTH_LEVEL_NONE:
2016 case DCERPC_AUTH_LEVEL_CONNECT:
2017 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2018 data_len = MIN(data_space, data_left);
2019 *p_ss_padding = 0;
2020 *p_auth_len = 0;
2021 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2022 return data_len;
2024 case DCERPC_AUTH_LEVEL_INTEGRITY:
2025 case DCERPC_AUTH_LEVEL_PRIVACY:
2026 /* Treat the same for all authenticated rpc requests. */
2027 switch(cli->auth->auth_type) {
2028 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2029 case PIPE_AUTH_TYPE_NTLMSSP:
2030 *p_auth_len = NTLMSSP_SIG_SIZE;
2031 break;
2032 case PIPE_AUTH_TYPE_SCHANNEL:
2033 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2034 break;
2035 default:
2036 smb_panic("bad auth type");
2037 break;
2040 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2041 RPC_HDR_AUTH_LEN - *p_auth_len;
2043 data_len = MIN(data_space, data_left);
2044 *p_ss_padding = 0;
2045 if (data_len % 8) {
2046 *p_ss_padding = 8 - (data_len % 8);
2048 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2049 data_len + *p_ss_padding + /* data plus padding. */
2050 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2051 return data_len;
2053 default:
2054 smb_panic("bad auth level");
2055 /* Notreached. */
2056 return 0;
2060 /*******************************************************************
2061 External interface.
2062 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2063 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2064 and deals with signing/sealing details.
2065 ********************************************************************/
2067 struct rpc_api_pipe_req_state {
2068 struct event_context *ev;
2069 struct rpc_pipe_client *cli;
2070 uint8_t op_num;
2071 uint32_t call_id;
2072 prs_struct *req_data;
2073 uint32_t req_data_sent;
2074 prs_struct outgoing_frag;
2075 prs_struct reply_pdu;
2078 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2080 prs_mem_free(&s->outgoing_frag);
2081 prs_mem_free(&s->reply_pdu);
2082 return 0;
2085 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2086 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2087 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2088 bool *is_last_frag);
2090 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2091 struct event_context *ev,
2092 struct rpc_pipe_client *cli,
2093 uint8_t op_num,
2094 prs_struct *req_data)
2096 struct tevent_req *req, *subreq;
2097 struct rpc_api_pipe_req_state *state;
2098 NTSTATUS status;
2099 bool is_last_frag;
2101 req = tevent_req_create(mem_ctx, &state,
2102 struct rpc_api_pipe_req_state);
2103 if (req == NULL) {
2104 return NULL;
2106 state->ev = ev;
2107 state->cli = cli;
2108 state->op_num = op_num;
2109 state->req_data = req_data;
2110 state->req_data_sent = 0;
2111 state->call_id = get_rpc_call_id();
2113 if (cli->max_xmit_frag
2114 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2115 /* Server is screwed up ! */
2116 status = NT_STATUS_INVALID_PARAMETER;
2117 goto post_status;
2120 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2122 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2123 state, MARSHALL)) {
2124 goto fail;
2127 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2129 status = prepare_next_frag(state, &is_last_frag);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 goto post_status;
2134 if (is_last_frag) {
2135 subreq = rpc_api_pipe_send(state, ev, state->cli,
2136 &state->outgoing_frag,
2137 DCERPC_PKT_RESPONSE);
2138 if (subreq == NULL) {
2139 goto fail;
2141 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2142 } else {
2143 subreq = rpc_write_send(
2144 state, ev, cli->transport,
2145 (uint8_t *)prs_data_p(&state->outgoing_frag),
2146 prs_offset(&state->outgoing_frag));
2147 if (subreq == NULL) {
2148 goto fail;
2150 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2151 req);
2153 return req;
2155 post_status:
2156 tevent_req_nterror(req, status);
2157 return tevent_req_post(req, ev);
2158 fail:
2159 TALLOC_FREE(req);
2160 return NULL;
2163 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2164 bool *is_last_frag)
2166 RPC_HDR hdr;
2167 RPC_HDR_REQ hdr_req;
2168 uint32_t data_sent_thistime;
2169 uint16_t auth_len;
2170 uint16_t frag_len;
2171 uint8_t flags = 0;
2172 uint32_t ss_padding;
2173 uint32_t data_left;
2174 char pad[8] = { 0, };
2175 NTSTATUS status;
2177 data_left = prs_offset(state->req_data) - state->req_data_sent;
2179 data_sent_thistime = calculate_data_len_tosend(
2180 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2182 if (state->req_data_sent == 0) {
2183 flags = DCERPC_PFC_FLAG_FIRST;
2186 if (data_sent_thistime == data_left) {
2187 flags |= DCERPC_PFC_FLAG_LAST;
2190 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2191 return NT_STATUS_NO_MEMORY;
2194 /* Create and marshall the header and request header. */
2195 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2196 auth_len);
2198 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2199 return NT_STATUS_NO_MEMORY;
2202 /* Create the rpc request RPC_HDR_REQ */
2203 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2204 state->op_num);
2206 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2207 &state->outgoing_frag, 0)) {
2208 return NT_STATUS_NO_MEMORY;
2211 /* Copy in the data, plus any ss padding. */
2212 if (!prs_append_some_prs_data(&state->outgoing_frag,
2213 state->req_data, state->req_data_sent,
2214 data_sent_thistime)) {
2215 return NT_STATUS_NO_MEMORY;
2218 /* Copy the sign/seal padding data. */
2219 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2220 return NT_STATUS_NO_MEMORY;
2223 /* Generate any auth sign/seal and add the auth footer. */
2224 switch (state->cli->auth->auth_type) {
2225 case PIPE_AUTH_TYPE_NONE:
2226 status = NT_STATUS_OK;
2227 break;
2228 case PIPE_AUTH_TYPE_NTLMSSP:
2229 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2230 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2231 &state->outgoing_frag);
2232 break;
2233 case PIPE_AUTH_TYPE_SCHANNEL:
2234 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2235 &state->outgoing_frag);
2236 break;
2237 default:
2238 status = NT_STATUS_INVALID_PARAMETER;
2239 break;
2242 state->req_data_sent += data_sent_thistime;
2243 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2245 return status;
2248 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2250 struct tevent_req *req = tevent_req_callback_data(
2251 subreq, struct tevent_req);
2252 struct rpc_api_pipe_req_state *state = tevent_req_data(
2253 req, struct rpc_api_pipe_req_state);
2254 NTSTATUS status;
2255 bool is_last_frag;
2257 status = rpc_write_recv(subreq);
2258 TALLOC_FREE(subreq);
2259 if (!NT_STATUS_IS_OK(status)) {
2260 tevent_req_nterror(req, status);
2261 return;
2264 status = prepare_next_frag(state, &is_last_frag);
2265 if (!NT_STATUS_IS_OK(status)) {
2266 tevent_req_nterror(req, status);
2267 return;
2270 if (is_last_frag) {
2271 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2272 &state->outgoing_frag,
2273 DCERPC_PKT_RESPONSE);
2274 if (tevent_req_nomem(subreq, req)) {
2275 return;
2277 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2278 } else {
2279 subreq = rpc_write_send(
2280 state, state->ev,
2281 state->cli->transport,
2282 (uint8_t *)prs_data_p(&state->outgoing_frag),
2283 prs_offset(&state->outgoing_frag));
2284 if (tevent_req_nomem(subreq, req)) {
2285 return;
2287 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2288 req);
2292 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2294 struct tevent_req *req = tevent_req_callback_data(
2295 subreq, struct tevent_req);
2296 struct rpc_api_pipe_req_state *state = tevent_req_data(
2297 req, struct rpc_api_pipe_req_state);
2298 NTSTATUS status;
2300 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2301 TALLOC_FREE(subreq);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 tevent_req_nterror(req, status);
2304 return;
2306 tevent_req_done(req);
2309 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2310 prs_struct *reply_pdu)
2312 struct rpc_api_pipe_req_state *state = tevent_req_data(
2313 req, struct rpc_api_pipe_req_state);
2314 NTSTATUS status;
2316 if (tevent_req_is_nterror(req, &status)) {
2318 * We always have to initialize to reply pdu, even if there is
2319 * none. The rpccli_* caller routines expect this.
2321 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2322 return status;
2325 *reply_pdu = state->reply_pdu;
2326 reply_pdu->mem_ctx = mem_ctx;
2329 * Prevent state->req_pdu from being freed in
2330 * rpc_api_pipe_req_state_destructor()
2332 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2334 return NT_STATUS_OK;
2337 #if 0
2338 /****************************************************************************
2339 Set the handle state.
2340 ****************************************************************************/
2342 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2343 const char *pipe_name, uint16 device_state)
2345 bool state_set = False;
2346 char param[2];
2347 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2348 char *rparam = NULL;
2349 char *rdata = NULL;
2350 uint32 rparam_len, rdata_len;
2352 if (pipe_name == NULL)
2353 return False;
2355 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2356 cli->fnum, pipe_name, device_state));
2358 /* create parameters: device state */
2359 SSVAL(param, 0, device_state);
2361 /* create setup parameters. */
2362 setup[0] = 0x0001;
2363 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2365 /* send the data on \PIPE\ */
2366 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2367 setup, 2, 0, /* setup, length, max */
2368 param, 2, 0, /* param, length, max */
2369 NULL, 0, 1024, /* data, length, max */
2370 &rparam, &rparam_len, /* return param, length */
2371 &rdata, &rdata_len)) /* return data, length */
2373 DEBUG(5, ("Set Handle state: return OK\n"));
2374 state_set = True;
2377 SAFE_FREE(rparam);
2378 SAFE_FREE(rdata);
2380 return state_set;
2382 #endif
2384 /****************************************************************************
2385 Check the rpc bind acknowledge response.
2386 ****************************************************************************/
2388 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2389 const struct ndr_syntax_id *transfer)
2391 if ( hdr_ba->addr.len == 0) {
2392 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2395 /* check the transfer syntax */
2396 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2397 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2398 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2399 return False;
2402 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2403 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2404 hdr_ba->res.num_results, hdr_ba->res.reason));
2407 DEBUG(5,("check_bind_response: accepted!\n"));
2408 return True;
2411 /*******************************************************************
2412 Creates a DCE/RPC bind authentication response.
2413 This is the packet that is sent back to the server once we
2414 have received a BIND-ACK, to finish the third leg of
2415 the authentication handshake.
2416 ********************************************************************/
2418 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2419 uint32 rpc_call_id,
2420 enum pipe_auth_type auth_type,
2421 enum dcerpc_AuthLevel auth_level,
2422 DATA_BLOB *pauth_blob,
2423 prs_struct *rpc_out)
2425 RPC_HDR hdr;
2426 RPC_HDR_AUTH hdr_auth;
2427 uint32 pad = 0;
2429 /* Create the request RPC_HDR */
2430 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2431 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2432 pauth_blob->length );
2434 /* Marshall it. */
2435 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2436 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2437 return NT_STATUS_NO_MEMORY;
2441 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2442 about padding - shouldn't this pad to length 8 ? JRA.
2445 /* 4 bytes padding. */
2446 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2447 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2448 return NT_STATUS_NO_MEMORY;
2451 /* Create the request RPC_HDR_AUTHA */
2452 init_rpc_hdr_auth(&hdr_auth,
2453 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2454 auth_level, 0, 1);
2456 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2457 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2458 return NT_STATUS_NO_MEMORY;
2462 * Append the auth data to the outgoing buffer.
2465 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2466 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2467 return NT_STATUS_NO_MEMORY;
2470 return NT_STATUS_OK;
2473 /*******************************************************************
2474 Creates a DCE/RPC bind alter context authentication request which
2475 may contain a spnego auth blobl
2476 ********************************************************************/
2478 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2479 const struct ndr_syntax_id *abstract,
2480 const struct ndr_syntax_id *transfer,
2481 enum dcerpc_AuthLevel auth_level,
2482 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2483 prs_struct *rpc_out)
2485 RPC_HDR_AUTH hdr_auth;
2486 prs_struct auth_info;
2487 NTSTATUS ret = NT_STATUS_OK;
2489 ZERO_STRUCT(hdr_auth);
2490 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2491 return NT_STATUS_NO_MEMORY;
2493 /* We may change the pad length before marshalling. */
2494 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2496 if (pauth_blob->length) {
2497 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2498 prs_mem_free(&auth_info);
2499 return NT_STATUS_NO_MEMORY;
2503 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2504 rpc_out,
2505 rpc_call_id,
2506 abstract,
2507 transfer,
2508 &hdr_auth,
2509 &auth_info);
2510 prs_mem_free(&auth_info);
2511 return ret;
2514 /****************************************************************************
2515 Do an rpc bind.
2516 ****************************************************************************/
2518 struct rpc_pipe_bind_state {
2519 struct event_context *ev;
2520 struct rpc_pipe_client *cli;
2521 prs_struct rpc_out;
2522 uint32_t rpc_call_id;
2525 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2527 prs_mem_free(&state->rpc_out);
2528 return 0;
2531 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2532 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2533 struct rpc_pipe_bind_state *state,
2534 struct rpc_hdr_info *phdr,
2535 prs_struct *reply_pdu);
2536 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2537 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2538 struct rpc_pipe_bind_state *state,
2539 struct rpc_hdr_info *phdr,
2540 prs_struct *reply_pdu);
2541 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2543 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2544 struct event_context *ev,
2545 struct rpc_pipe_client *cli,
2546 struct cli_pipe_auth_data *auth)
2548 struct tevent_req *req, *subreq;
2549 struct rpc_pipe_bind_state *state;
2550 NTSTATUS status;
2552 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2553 if (req == NULL) {
2554 return NULL;
2557 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2558 rpccli_pipe_txt(debug_ctx(), cli),
2559 (unsigned int)auth->auth_type,
2560 (unsigned int)auth->auth_level ));
2562 state->ev = ev;
2563 state->cli = cli;
2564 state->rpc_call_id = get_rpc_call_id();
2566 prs_init_empty(&state->rpc_out, state, MARSHALL);
2567 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2569 cli->auth = talloc_move(cli, &auth);
2571 /* Marshall the outgoing data. */
2572 status = create_rpc_bind_req(cli, &state->rpc_out,
2573 state->rpc_call_id,
2574 &cli->abstract_syntax,
2575 &cli->transfer_syntax,
2576 cli->auth->auth_type,
2577 cli->auth->auth_level);
2579 if (!NT_STATUS_IS_OK(status)) {
2580 goto post_status;
2583 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2584 DCERPC_PKT_BIND_ACK);
2585 if (subreq == NULL) {
2586 goto fail;
2588 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2589 return req;
2591 post_status:
2592 tevent_req_nterror(req, status);
2593 return tevent_req_post(req, ev);
2594 fail:
2595 TALLOC_FREE(req);
2596 return NULL;
2599 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2601 struct tevent_req *req = tevent_req_callback_data(
2602 subreq, struct tevent_req);
2603 struct rpc_pipe_bind_state *state = tevent_req_data(
2604 req, struct rpc_pipe_bind_state);
2605 prs_struct reply_pdu;
2606 struct rpc_hdr_info hdr;
2607 struct rpc_hdr_ba_info hdr_ba;
2608 NTSTATUS status;
2610 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2611 TALLOC_FREE(subreq);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2614 rpccli_pipe_txt(debug_ctx(), state->cli),
2615 nt_errstr(status)));
2616 tevent_req_nterror(req, status);
2617 return;
2620 /* Unmarshall the RPC header */
2621 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2622 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2623 prs_mem_free(&reply_pdu);
2624 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2625 return;
2628 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2629 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2630 "RPC_HDR_BA.\n"));
2631 prs_mem_free(&reply_pdu);
2632 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2633 return;
2636 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2637 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2638 prs_mem_free(&reply_pdu);
2639 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2640 return;
2643 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2644 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2647 * For authenticated binds we may need to do 3 or 4 leg binds.
2650 switch(state->cli->auth->auth_type) {
2652 case PIPE_AUTH_TYPE_NONE:
2653 case PIPE_AUTH_TYPE_SCHANNEL:
2654 /* Bind complete. */
2655 prs_mem_free(&reply_pdu);
2656 tevent_req_done(req);
2657 break;
2659 case PIPE_AUTH_TYPE_NTLMSSP:
2660 /* Need to send AUTH3 packet - no reply. */
2661 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2662 &reply_pdu);
2663 prs_mem_free(&reply_pdu);
2664 if (!NT_STATUS_IS_OK(status)) {
2665 tevent_req_nterror(req, status);
2667 break;
2669 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2670 /* Need to send alter context request and reply. */
2671 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2672 &reply_pdu);
2673 prs_mem_free(&reply_pdu);
2674 if (!NT_STATUS_IS_OK(status)) {
2675 tevent_req_nterror(req, status);
2677 break;
2679 case PIPE_AUTH_TYPE_KRB5:
2680 /* */
2682 default:
2683 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2684 (unsigned int)state->cli->auth->auth_type));
2685 prs_mem_free(&reply_pdu);
2686 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2690 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2691 struct rpc_pipe_bind_state *state,
2692 struct rpc_hdr_info *phdr,
2693 prs_struct *reply_pdu)
2695 DATA_BLOB server_response = data_blob_null;
2696 DATA_BLOB client_reply = data_blob_null;
2697 struct rpc_hdr_auth_info hdr_auth;
2698 struct tevent_req *subreq;
2699 NTSTATUS status;
2701 if ((phdr->auth_len == 0)
2702 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2703 return NT_STATUS_INVALID_PARAMETER;
2706 if (!prs_set_offset(
2707 reply_pdu,
2708 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2709 return NT_STATUS_INVALID_PARAMETER;
2712 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2713 return NT_STATUS_INVALID_PARAMETER;
2716 /* TODO - check auth_type/auth_level match. */
2718 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2719 prs_copy_data_out((char *)server_response.data, reply_pdu,
2720 phdr->auth_len);
2722 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2723 server_response, &client_reply);
2725 if (!NT_STATUS_IS_OK(status)) {
2726 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2727 "blob failed: %s.\n", nt_errstr(status)));
2728 return status;
2731 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2733 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2734 state->cli->auth->auth_type,
2735 state->cli->auth->auth_level,
2736 &client_reply, &state->rpc_out);
2737 data_blob_free(&client_reply);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 return status;
2743 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2744 (uint8_t *)prs_data_p(&state->rpc_out),
2745 prs_offset(&state->rpc_out));
2746 if (subreq == NULL) {
2747 return NT_STATUS_NO_MEMORY;
2749 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2750 return NT_STATUS_OK;
2753 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2755 struct tevent_req *req = tevent_req_callback_data(
2756 subreq, struct tevent_req);
2757 NTSTATUS status;
2759 status = rpc_write_recv(subreq);
2760 TALLOC_FREE(subreq);
2761 if (!NT_STATUS_IS_OK(status)) {
2762 tevent_req_nterror(req, status);
2763 return;
2765 tevent_req_done(req);
2768 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2769 struct rpc_pipe_bind_state *state,
2770 struct rpc_hdr_info *phdr,
2771 prs_struct *reply_pdu)
2773 DATA_BLOB server_spnego_response = data_blob_null;
2774 DATA_BLOB server_ntlm_response = data_blob_null;
2775 DATA_BLOB client_reply = data_blob_null;
2776 DATA_BLOB tmp_blob = data_blob_null;
2777 RPC_HDR_AUTH hdr_auth;
2778 struct tevent_req *subreq;
2779 NTSTATUS status;
2781 if ((phdr->auth_len == 0)
2782 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2783 return NT_STATUS_INVALID_PARAMETER;
2786 /* Process the returned NTLMSSP blob first. */
2787 if (!prs_set_offset(
2788 reply_pdu,
2789 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2790 return NT_STATUS_INVALID_PARAMETER;
2793 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2794 return NT_STATUS_INVALID_PARAMETER;
2797 server_spnego_response = data_blob(NULL, phdr->auth_len);
2798 prs_copy_data_out((char *)server_spnego_response.data,
2799 reply_pdu, phdr->auth_len);
2802 * The server might give us back two challenges - tmp_blob is for the
2803 * second.
2805 if (!spnego_parse_challenge(server_spnego_response,
2806 &server_ntlm_response, &tmp_blob)) {
2807 data_blob_free(&server_spnego_response);
2808 data_blob_free(&server_ntlm_response);
2809 data_blob_free(&tmp_blob);
2810 return NT_STATUS_INVALID_PARAMETER;
2813 /* We're finished with the server spnego response and the tmp_blob. */
2814 data_blob_free(&server_spnego_response);
2815 data_blob_free(&tmp_blob);
2817 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2818 server_ntlm_response, &client_reply);
2820 /* Finished with the server_ntlm response */
2821 data_blob_free(&server_ntlm_response);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2825 "using server blob failed.\n"));
2826 data_blob_free(&client_reply);
2827 return status;
2830 /* SPNEGO wrap the client reply. */
2831 tmp_blob = spnego_gen_auth(client_reply);
2832 data_blob_free(&client_reply);
2833 client_reply = tmp_blob;
2834 tmp_blob = data_blob_null;
2836 /* Now prepare the alter context pdu. */
2837 prs_init_empty(&state->rpc_out, state, MARSHALL);
2839 status = create_rpc_alter_context(state->rpc_call_id,
2840 &state->cli->abstract_syntax,
2841 &state->cli->transfer_syntax,
2842 state->cli->auth->auth_level,
2843 &client_reply,
2844 &state->rpc_out);
2845 data_blob_free(&client_reply);
2847 if (!NT_STATUS_IS_OK(status)) {
2848 return status;
2851 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2852 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2853 if (subreq == NULL) {
2854 return NT_STATUS_NO_MEMORY;
2856 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2857 return NT_STATUS_OK;
2860 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2862 struct tevent_req *req = tevent_req_callback_data(
2863 subreq, struct tevent_req);
2864 struct rpc_pipe_bind_state *state = tevent_req_data(
2865 req, struct rpc_pipe_bind_state);
2866 DATA_BLOB server_spnego_response = data_blob_null;
2867 DATA_BLOB tmp_blob = data_blob_null;
2868 prs_struct reply_pdu;
2869 struct rpc_hdr_info hdr;
2870 struct rpc_hdr_auth_info hdr_auth;
2871 NTSTATUS status;
2873 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2874 TALLOC_FREE(subreq);
2875 if (!NT_STATUS_IS_OK(status)) {
2876 tevent_req_nterror(req, status);
2877 return;
2880 /* Get the auth blob from the reply. */
2881 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2882 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2883 "unmarshall RPC_HDR.\n"));
2884 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2885 return;
2888 if (!prs_set_offset(
2889 &reply_pdu,
2890 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2891 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2892 return;
2895 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2896 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2897 return;
2900 server_spnego_response = data_blob(NULL, hdr.auth_len);
2901 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2902 hdr.auth_len);
2904 /* Check we got a valid auth response. */
2905 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2906 OID_NTLMSSP, &tmp_blob)) {
2907 data_blob_free(&server_spnego_response);
2908 data_blob_free(&tmp_blob);
2909 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2910 return;
2913 data_blob_free(&server_spnego_response);
2914 data_blob_free(&tmp_blob);
2916 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2917 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2918 tevent_req_done(req);
2921 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2923 return tevent_req_simple_recv_ntstatus(req);
2926 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2927 struct cli_pipe_auth_data *auth)
2929 TALLOC_CTX *frame = talloc_stackframe();
2930 struct event_context *ev;
2931 struct tevent_req *req;
2932 NTSTATUS status = NT_STATUS_OK;
2934 ev = event_context_init(frame);
2935 if (ev == NULL) {
2936 status = NT_STATUS_NO_MEMORY;
2937 goto fail;
2940 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2941 if (req == NULL) {
2942 status = NT_STATUS_NO_MEMORY;
2943 goto fail;
2946 if (!tevent_req_poll(req, ev)) {
2947 status = map_nt_error_from_unix(errno);
2948 goto fail;
2951 status = rpc_pipe_bind_recv(req);
2952 fail:
2953 TALLOC_FREE(frame);
2954 return status;
2957 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2958 unsigned int timeout)
2960 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2962 if (cli == NULL) {
2963 return 0;
2965 return cli_set_timeout(cli, timeout);
2968 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2970 struct cli_state *cli;
2972 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2973 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2974 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2975 return true;
2978 cli = rpc_pipe_np_smb_conn(rpc_cli);
2979 if (cli == NULL) {
2980 return false;
2982 E_md4hash(cli->password ? cli->password : "", nt_hash);
2983 return true;
2986 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2987 struct cli_pipe_auth_data **presult)
2989 struct cli_pipe_auth_data *result;
2991 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2992 if (result == NULL) {
2993 return NT_STATUS_NO_MEMORY;
2996 result->auth_type = PIPE_AUTH_TYPE_NONE;
2997 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2999 result->user_name = talloc_strdup(result, "");
3000 result->domain = talloc_strdup(result, "");
3001 if ((result->user_name == NULL) || (result->domain == NULL)) {
3002 TALLOC_FREE(result);
3003 return NT_STATUS_NO_MEMORY;
3006 *presult = result;
3007 return NT_STATUS_OK;
3010 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3012 ntlmssp_end(&auth->a_u.ntlmssp_state);
3013 return 0;
3016 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3017 enum pipe_auth_type auth_type,
3018 enum dcerpc_AuthLevel auth_level,
3019 const char *domain,
3020 const char *username,
3021 const char *password,
3022 struct cli_pipe_auth_data **presult)
3024 struct cli_pipe_auth_data *result;
3025 NTSTATUS status;
3027 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3028 if (result == NULL) {
3029 return NT_STATUS_NO_MEMORY;
3032 result->auth_type = auth_type;
3033 result->auth_level = auth_level;
3035 result->user_name = talloc_strdup(result, username);
3036 result->domain = talloc_strdup(result, domain);
3037 if ((result->user_name == NULL) || (result->domain == NULL)) {
3038 status = NT_STATUS_NO_MEMORY;
3039 goto fail;
3042 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 goto fail;
3047 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3049 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 goto fail;
3054 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 goto fail;
3059 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 goto fail;
3065 * Turn off sign+seal to allow selected auth level to turn it back on.
3067 result->a_u.ntlmssp_state->neg_flags &=
3068 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3070 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3071 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3072 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3073 result->a_u.ntlmssp_state->neg_flags
3074 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3077 *presult = result;
3078 return NT_STATUS_OK;
3080 fail:
3081 TALLOC_FREE(result);
3082 return status;
3085 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3086 enum dcerpc_AuthLevel auth_level,
3087 struct netlogon_creds_CredentialState *creds,
3088 struct cli_pipe_auth_data **presult)
3090 struct cli_pipe_auth_data *result;
3092 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3093 if (result == NULL) {
3094 return NT_STATUS_NO_MEMORY;
3097 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3098 result->auth_level = auth_level;
3100 result->user_name = talloc_strdup(result, "");
3101 result->domain = talloc_strdup(result, domain);
3102 if ((result->user_name == NULL) || (result->domain == NULL)) {
3103 goto fail;
3106 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3107 if (result->a_u.schannel_auth == NULL) {
3108 goto fail;
3111 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3112 result->a_u.schannel_auth->seq_num = 0;
3113 result->a_u.schannel_auth->initiator = true;
3114 result->a_u.schannel_auth->creds = creds;
3116 *presult = result;
3117 return NT_STATUS_OK;
3119 fail:
3120 TALLOC_FREE(result);
3121 return NT_STATUS_NO_MEMORY;
3124 #ifdef HAVE_KRB5
3125 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3127 data_blob_free(&auth->session_key);
3128 return 0;
3130 #endif
3132 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3133 enum dcerpc_AuthLevel auth_level,
3134 const char *service_princ,
3135 const char *username,
3136 const char *password,
3137 struct cli_pipe_auth_data **presult)
3139 #ifdef HAVE_KRB5
3140 struct cli_pipe_auth_data *result;
3142 if ((username != NULL) && (password != NULL)) {
3143 int ret = kerberos_kinit_password(username, password, 0, NULL);
3144 if (ret != 0) {
3145 return NT_STATUS_ACCESS_DENIED;
3149 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3150 if (result == NULL) {
3151 return NT_STATUS_NO_MEMORY;
3154 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3155 result->auth_level = auth_level;
3158 * Username / domain need fixing!
3160 result->user_name = talloc_strdup(result, "");
3161 result->domain = talloc_strdup(result, "");
3162 if ((result->user_name == NULL) || (result->domain == NULL)) {
3163 goto fail;
3166 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3167 result, struct kerberos_auth_struct);
3168 if (result->a_u.kerberos_auth == NULL) {
3169 goto fail;
3171 talloc_set_destructor(result->a_u.kerberos_auth,
3172 cli_auth_kerberos_data_destructor);
3174 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3175 result, service_princ);
3176 if (result->a_u.kerberos_auth->service_principal == NULL) {
3177 goto fail;
3180 *presult = result;
3181 return NT_STATUS_OK;
3183 fail:
3184 TALLOC_FREE(result);
3185 return NT_STATUS_NO_MEMORY;
3186 #else
3187 return NT_STATUS_NOT_SUPPORTED;
3188 #endif
3192 * Create an rpc pipe client struct, connecting to a tcp port.
3194 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3195 uint16_t port,
3196 const struct ndr_syntax_id *abstract_syntax,
3197 struct rpc_pipe_client **presult)
3199 struct rpc_pipe_client *result;
3200 struct sockaddr_storage addr;
3201 NTSTATUS status;
3202 int fd;
3204 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3205 if (result == NULL) {
3206 return NT_STATUS_NO_MEMORY;
3209 result->abstract_syntax = *abstract_syntax;
3210 result->transfer_syntax = ndr_transfer_syntax;
3211 result->dispatch = cli_do_rpc_ndr;
3212 result->dispatch_send = cli_do_rpc_ndr_send;
3213 result->dispatch_recv = cli_do_rpc_ndr_recv;
3215 result->desthost = talloc_strdup(result, host);
3216 result->srv_name_slash = talloc_asprintf_strupper_m(
3217 result, "\\\\%s", result->desthost);
3218 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3219 status = NT_STATUS_NO_MEMORY;
3220 goto fail;
3223 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3224 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3226 if (!resolve_name(host, &addr, 0, false)) {
3227 status = NT_STATUS_NOT_FOUND;
3228 goto fail;
3231 status = open_socket_out(&addr, port, 60, &fd);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 goto fail;
3235 set_socket_options(fd, lp_socket_options());
3237 status = rpc_transport_sock_init(result, fd, &result->transport);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 close(fd);
3240 goto fail;
3243 result->transport->transport = NCACN_IP_TCP;
3245 *presult = result;
3246 return NT_STATUS_OK;
3248 fail:
3249 TALLOC_FREE(result);
3250 return status;
3254 * Determine the tcp port on which a dcerpc interface is listening
3255 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3256 * target host.
3258 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3259 const struct ndr_syntax_id *abstract_syntax,
3260 uint16_t *pport)
3262 NTSTATUS status;
3263 struct rpc_pipe_client *epm_pipe = NULL;
3264 struct cli_pipe_auth_data *auth = NULL;
3265 struct dcerpc_binding *map_binding = NULL;
3266 struct dcerpc_binding *res_binding = NULL;
3267 struct epm_twr_t *map_tower = NULL;
3268 struct epm_twr_t *res_towers = NULL;
3269 struct policy_handle *entry_handle = NULL;
3270 uint32_t num_towers = 0;
3271 uint32_t max_towers = 1;
3272 struct epm_twr_p_t towers;
3273 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3275 if (pport == NULL) {
3276 status = NT_STATUS_INVALID_PARAMETER;
3277 goto done;
3280 /* open the connection to the endpoint mapper */
3281 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3282 &ndr_table_epmapper.syntax_id,
3283 &epm_pipe);
3285 if (!NT_STATUS_IS_OK(status)) {
3286 goto done;
3289 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3290 if (!NT_STATUS_IS_OK(status)) {
3291 goto done;
3294 status = rpc_pipe_bind(epm_pipe, auth);
3295 if (!NT_STATUS_IS_OK(status)) {
3296 goto done;
3299 /* create tower for asking the epmapper */
3301 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3302 if (map_binding == NULL) {
3303 status = NT_STATUS_NO_MEMORY;
3304 goto done;
3307 map_binding->transport = NCACN_IP_TCP;
3308 map_binding->object = *abstract_syntax;
3309 map_binding->host = host; /* needed? */
3310 map_binding->endpoint = "0"; /* correct? needed? */
3312 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3313 if (map_tower == NULL) {
3314 status = NT_STATUS_NO_MEMORY;
3315 goto done;
3318 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3319 &(map_tower->tower));
3320 if (!NT_STATUS_IS_OK(status)) {
3321 goto done;
3324 /* allocate further parameters for the epm_Map call */
3326 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3327 if (res_towers == NULL) {
3328 status = NT_STATUS_NO_MEMORY;
3329 goto done;
3331 towers.twr = res_towers;
3333 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3334 if (entry_handle == NULL) {
3335 status = NT_STATUS_NO_MEMORY;
3336 goto done;
3339 /* ask the endpoint mapper for the port */
3341 status = rpccli_epm_Map(epm_pipe,
3342 tmp_ctx,
3343 CONST_DISCARD(struct GUID *,
3344 &(abstract_syntax->uuid)),
3345 map_tower,
3346 entry_handle,
3347 max_towers,
3348 &num_towers,
3349 &towers);
3351 if (!NT_STATUS_IS_OK(status)) {
3352 goto done;
3355 if (num_towers != 1) {
3356 status = NT_STATUS_UNSUCCESSFUL;
3357 goto done;
3360 /* extract the port from the answer */
3362 status = dcerpc_binding_from_tower(tmp_ctx,
3363 &(towers.twr->tower),
3364 &res_binding);
3365 if (!NT_STATUS_IS_OK(status)) {
3366 goto done;
3369 /* are further checks here necessary? */
3370 if (res_binding->transport != NCACN_IP_TCP) {
3371 status = NT_STATUS_UNSUCCESSFUL;
3372 goto done;
3375 *pport = (uint16_t)atoi(res_binding->endpoint);
3377 done:
3378 TALLOC_FREE(tmp_ctx);
3379 return status;
3383 * Create a rpc pipe client struct, connecting to a host via tcp.
3384 * The port is determined by asking the endpoint mapper on the given
3385 * host.
3387 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3388 const struct ndr_syntax_id *abstract_syntax,
3389 struct rpc_pipe_client **presult)
3391 NTSTATUS status;
3392 uint16_t port = 0;
3394 *presult = NULL;
3396 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3397 if (!NT_STATUS_IS_OK(status)) {
3398 goto done;
3401 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3402 abstract_syntax, presult);
3404 done:
3405 return status;
3408 /********************************************************************
3409 Create a rpc pipe client struct, connecting to a unix domain socket
3410 ********************************************************************/
3411 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3412 const struct ndr_syntax_id *abstract_syntax,
3413 struct rpc_pipe_client **presult)
3415 struct rpc_pipe_client *result;
3416 struct sockaddr_un addr;
3417 NTSTATUS status;
3418 int fd;
3420 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3421 if (result == NULL) {
3422 return NT_STATUS_NO_MEMORY;
3425 result->abstract_syntax = *abstract_syntax;
3426 result->transfer_syntax = ndr_transfer_syntax;
3427 result->dispatch = cli_do_rpc_ndr;
3428 result->dispatch_send = cli_do_rpc_ndr_send;
3429 result->dispatch_recv = cli_do_rpc_ndr_recv;
3431 result->desthost = get_myname(result);
3432 result->srv_name_slash = talloc_asprintf_strupper_m(
3433 result, "\\\\%s", result->desthost);
3434 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3435 status = NT_STATUS_NO_MEMORY;
3436 goto fail;
3439 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3440 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3442 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3443 if (fd == -1) {
3444 status = map_nt_error_from_unix(errno);
3445 goto fail;
3448 ZERO_STRUCT(addr);
3449 addr.sun_family = AF_UNIX;
3450 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3452 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3453 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3454 strerror(errno)));
3455 close(fd);
3456 return map_nt_error_from_unix(errno);
3459 status = rpc_transport_sock_init(result, fd, &result->transport);
3460 if (!NT_STATUS_IS_OK(status)) {
3461 close(fd);
3462 goto fail;
3465 result->transport->transport = NCALRPC;
3467 *presult = result;
3468 return NT_STATUS_OK;
3470 fail:
3471 TALLOC_FREE(result);
3472 return status;
3475 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3477 struct cli_state *cli;
3479 cli = rpc_pipe_np_smb_conn(p);
3480 if (cli != NULL) {
3481 DLIST_REMOVE(cli->pipe_list, p);
3483 return 0;
3486 /****************************************************************************
3487 Open a named pipe over SMB to a remote server.
3489 * CAVEAT CALLER OF THIS FUNCTION:
3490 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3491 * so be sure that this function is called AFTER any structure (vs pointer)
3492 * assignment of the cli. In particular, libsmbclient does structure
3493 * assignments of cli, which invalidates the data in the returned
3494 * rpc_pipe_client if this function is called before the structure assignment
3495 * of cli.
3497 ****************************************************************************/
3499 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3500 const struct ndr_syntax_id *abstract_syntax,
3501 struct rpc_pipe_client **presult)
3503 struct rpc_pipe_client *result;
3504 NTSTATUS status;
3506 /* sanity check to protect against crashes */
3508 if ( !cli ) {
3509 return NT_STATUS_INVALID_HANDLE;
3512 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3513 if (result == NULL) {
3514 return NT_STATUS_NO_MEMORY;
3517 result->abstract_syntax = *abstract_syntax;
3518 result->transfer_syntax = ndr_transfer_syntax;
3519 result->dispatch = cli_do_rpc_ndr;
3520 result->dispatch_send = cli_do_rpc_ndr_send;
3521 result->dispatch_recv = cli_do_rpc_ndr_recv;
3522 result->desthost = talloc_strdup(result, cli->desthost);
3523 result->srv_name_slash = talloc_asprintf_strupper_m(
3524 result, "\\\\%s", result->desthost);
3526 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3527 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3529 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3530 TALLOC_FREE(result);
3531 return NT_STATUS_NO_MEMORY;
3534 status = rpc_transport_np_init(result, cli, abstract_syntax,
3535 &result->transport);
3536 if (!NT_STATUS_IS_OK(status)) {
3537 TALLOC_FREE(result);
3538 return status;
3541 result->transport->transport = NCACN_NP;
3543 DLIST_ADD(cli->pipe_list, result);
3544 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3546 *presult = result;
3547 return NT_STATUS_OK;
3550 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3551 struct rpc_cli_smbd_conn *conn,
3552 const struct ndr_syntax_id *syntax,
3553 struct rpc_pipe_client **presult)
3555 struct rpc_pipe_client *result;
3556 struct cli_pipe_auth_data *auth;
3557 NTSTATUS status;
3559 result = talloc(mem_ctx, struct rpc_pipe_client);
3560 if (result == NULL) {
3561 return NT_STATUS_NO_MEMORY;
3563 result->abstract_syntax = *syntax;
3564 result->transfer_syntax = ndr_transfer_syntax;
3565 result->dispatch = cli_do_rpc_ndr;
3566 result->dispatch_send = cli_do_rpc_ndr_send;
3567 result->dispatch_recv = cli_do_rpc_ndr_recv;
3568 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3569 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3571 result->desthost = talloc_strdup(result, global_myname());
3572 result->srv_name_slash = talloc_asprintf_strupper_m(
3573 result, "\\\\%s", global_myname());
3574 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3575 TALLOC_FREE(result);
3576 return NT_STATUS_NO_MEMORY;
3579 status = rpc_transport_smbd_init(result, conn, syntax,
3580 &result->transport);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3583 nt_errstr(status)));
3584 TALLOC_FREE(result);
3585 return status;
3588 status = rpccli_anon_bind_data(result, &auth);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3591 nt_errstr(status)));
3592 TALLOC_FREE(result);
3593 return status;
3596 status = rpc_pipe_bind(result, auth);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3599 TALLOC_FREE(result);
3600 return status;
3603 result->transport->transport = NCACN_INTERNAL;
3605 *presult = result;
3606 return NT_STATUS_OK;
3609 /****************************************************************************
3610 Open a pipe to a remote server.
3611 ****************************************************************************/
3613 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3614 enum dcerpc_transport_t transport,
3615 const struct ndr_syntax_id *interface,
3616 struct rpc_pipe_client **presult)
3618 switch (transport) {
3619 case NCACN_IP_TCP:
3620 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3621 presult);
3622 case NCACN_NP:
3623 return rpc_pipe_open_np(cli, interface, presult);
3624 default:
3625 return NT_STATUS_NOT_IMPLEMENTED;
3629 /****************************************************************************
3630 Open a named pipe to an SMB server and bind anonymously.
3631 ****************************************************************************/
3633 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3634 enum dcerpc_transport_t transport,
3635 const struct ndr_syntax_id *interface,
3636 struct rpc_pipe_client **presult)
3638 struct rpc_pipe_client *result;
3639 struct cli_pipe_auth_data *auth;
3640 NTSTATUS status;
3642 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3643 if (!NT_STATUS_IS_OK(status)) {
3644 return status;
3647 status = rpccli_anon_bind_data(result, &auth);
3648 if (!NT_STATUS_IS_OK(status)) {
3649 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3650 nt_errstr(status)));
3651 TALLOC_FREE(result);
3652 return status;
3656 * This is a bit of an abstraction violation due to the fact that an
3657 * anonymous bind on an authenticated SMB inherits the user/domain
3658 * from the enclosing SMB creds
3661 TALLOC_FREE(auth->user_name);
3662 TALLOC_FREE(auth->domain);
3664 auth->user_name = talloc_strdup(auth, cli->user_name);
3665 auth->domain = talloc_strdup(auth, cli->domain);
3666 auth->user_session_key = data_blob_talloc(auth,
3667 cli->user_session_key.data,
3668 cli->user_session_key.length);
3670 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3671 TALLOC_FREE(result);
3672 return NT_STATUS_NO_MEMORY;
3675 status = rpc_pipe_bind(result, auth);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 int lvl = 0;
3678 if (ndr_syntax_id_equal(interface,
3679 &ndr_table_dssetup.syntax_id)) {
3680 /* non AD domains just don't have this pipe, avoid
3681 * level 0 statement in that case - gd */
3682 lvl = 3;
3684 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3685 "%s failed with error %s\n",
3686 get_pipe_name_from_iface(interface),
3687 nt_errstr(status) ));
3688 TALLOC_FREE(result);
3689 return status;
3692 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3693 "%s and bound anonymously.\n",
3694 get_pipe_name_from_iface(interface), cli->desthost));
3696 *presult = result;
3697 return NT_STATUS_OK;
3700 /****************************************************************************
3701 ****************************************************************************/
3703 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3704 const struct ndr_syntax_id *interface,
3705 struct rpc_pipe_client **presult)
3707 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3708 interface, presult);
3711 /****************************************************************************
3712 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3713 ****************************************************************************/
3715 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3716 const struct ndr_syntax_id *interface,
3717 enum dcerpc_transport_t transport,
3718 enum pipe_auth_type auth_type,
3719 enum dcerpc_AuthLevel auth_level,
3720 const char *domain,
3721 const char *username,
3722 const char *password,
3723 struct rpc_pipe_client **presult)
3725 struct rpc_pipe_client *result;
3726 struct cli_pipe_auth_data *auth;
3727 NTSTATUS status;
3729 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3730 if (!NT_STATUS_IS_OK(status)) {
3731 return status;
3734 status = rpccli_ntlmssp_bind_data(
3735 result, auth_type, auth_level, domain, username,
3736 password, &auth);
3737 if (!NT_STATUS_IS_OK(status)) {
3738 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3739 nt_errstr(status)));
3740 goto err;
3743 status = rpc_pipe_bind(result, auth);
3744 if (!NT_STATUS_IS_OK(status)) {
3745 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3746 nt_errstr(status) ));
3747 goto err;
3750 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3751 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3752 get_pipe_name_from_iface(interface), cli->desthost, domain,
3753 username ));
3755 *presult = result;
3756 return NT_STATUS_OK;
3758 err:
3760 TALLOC_FREE(result);
3761 return status;
3764 /****************************************************************************
3765 External interface.
3766 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3767 ****************************************************************************/
3769 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3770 const struct ndr_syntax_id *interface,
3771 enum dcerpc_transport_t transport,
3772 enum dcerpc_AuthLevel auth_level,
3773 const char *domain,
3774 const char *username,
3775 const char *password,
3776 struct rpc_pipe_client **presult)
3778 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3779 interface,
3780 transport,
3781 PIPE_AUTH_TYPE_NTLMSSP,
3782 auth_level,
3783 domain,
3784 username,
3785 password,
3786 presult);
3789 /****************************************************************************
3790 External interface.
3791 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3792 ****************************************************************************/
3794 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3795 const struct ndr_syntax_id *interface,
3796 enum dcerpc_transport_t transport,
3797 enum dcerpc_AuthLevel auth_level,
3798 const char *domain,
3799 const char *username,
3800 const char *password,
3801 struct rpc_pipe_client **presult)
3803 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3804 interface,
3805 transport,
3806 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3807 auth_level,
3808 domain,
3809 username,
3810 password,
3811 presult);
3814 /****************************************************************************
3815 Get a the schannel session key out of an already opened netlogon pipe.
3816 ****************************************************************************/
3817 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3818 struct cli_state *cli,
3819 const char *domain,
3820 uint32 *pneg_flags)
3822 uint32 sec_chan_type = 0;
3823 unsigned char machine_pwd[16];
3824 const char *machine_account;
3825 NTSTATUS status;
3827 /* Get the machine account credentials from secrets.tdb. */
3828 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3829 &sec_chan_type))
3831 DEBUG(0, ("get_schannel_session_key: could not fetch "
3832 "trust account password for domain '%s'\n",
3833 domain));
3834 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3837 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3838 cli->desthost, /* server name */
3839 domain, /* domain */
3840 global_myname(), /* client name */
3841 machine_account, /* machine account name */
3842 machine_pwd,
3843 sec_chan_type,
3844 pneg_flags);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 DEBUG(3, ("get_schannel_session_key_common: "
3848 "rpccli_netlogon_setup_creds failed with result %s "
3849 "to server %s, domain %s, machine account %s.\n",
3850 nt_errstr(status), cli->desthost, domain,
3851 machine_account ));
3852 return status;
3855 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3856 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3857 cli->desthost));
3858 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3861 return NT_STATUS_OK;;
3864 /****************************************************************************
3865 Open a netlogon pipe and get the schannel session key.
3866 Now exposed to external callers.
3867 ****************************************************************************/
3870 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3871 const char *domain,
3872 uint32 *pneg_flags,
3873 struct rpc_pipe_client **presult)
3875 struct rpc_pipe_client *netlogon_pipe = NULL;
3876 NTSTATUS status;
3878 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3879 &netlogon_pipe);
3880 if (!NT_STATUS_IS_OK(status)) {
3881 return status;
3884 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3885 pneg_flags);
3886 if (!NT_STATUS_IS_OK(status)) {
3887 TALLOC_FREE(netlogon_pipe);
3888 return status;
3891 *presult = netlogon_pipe;
3892 return NT_STATUS_OK;
3895 /****************************************************************************
3896 External interface.
3897 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3898 using session_key. sign and seal.
3900 The *pdc will be stolen onto this new pipe
3901 ****************************************************************************/
3903 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3904 const struct ndr_syntax_id *interface,
3905 enum dcerpc_transport_t transport,
3906 enum dcerpc_AuthLevel auth_level,
3907 const char *domain,
3908 struct netlogon_creds_CredentialState **pdc,
3909 struct rpc_pipe_client **presult)
3911 struct rpc_pipe_client *result;
3912 struct cli_pipe_auth_data *auth;
3913 NTSTATUS status;
3915 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 return status;
3920 status = rpccli_schannel_bind_data(result, domain, auth_level,
3921 *pdc, &auth);
3922 if (!NT_STATUS_IS_OK(status)) {
3923 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3924 nt_errstr(status)));
3925 TALLOC_FREE(result);
3926 return status;
3929 status = rpc_pipe_bind(result, auth);
3930 if (!NT_STATUS_IS_OK(status)) {
3931 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3932 "cli_rpc_pipe_bind failed with error %s\n",
3933 nt_errstr(status) ));
3934 TALLOC_FREE(result);
3935 return status;
3939 * The credentials on a new netlogon pipe are the ones we are passed
3940 * in - reference them in
3942 result->dc = talloc_move(result, pdc);
3943 if (result->dc == NULL) {
3944 DEBUG(0, ("talloc reference failed\n"));
3945 TALLOC_FREE(result);
3946 return NT_STATUS_NO_MEMORY;
3949 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3950 "for domain %s and bound using schannel.\n",
3951 get_pipe_name_from_iface(interface),
3952 cli->desthost, domain ));
3954 *presult = result;
3955 return NT_STATUS_OK;
3958 /****************************************************************************
3959 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3960 Fetch the session key ourselves using a temporary netlogon pipe. This
3961 version uses an ntlmssp auth bound netlogon pipe to get the key.
3962 ****************************************************************************/
3964 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3965 const char *domain,
3966 const char *username,
3967 const char *password,
3968 uint32 *pneg_flags,
3969 struct rpc_pipe_client **presult)
3971 struct rpc_pipe_client *netlogon_pipe = NULL;
3972 NTSTATUS status;
3974 status = cli_rpc_pipe_open_spnego_ntlmssp(
3975 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3976 DCERPC_AUTH_LEVEL_PRIVACY,
3977 domain, username, password, &netlogon_pipe);
3978 if (!NT_STATUS_IS_OK(status)) {
3979 return status;
3982 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3983 pneg_flags);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 TALLOC_FREE(netlogon_pipe);
3986 return status;
3989 *presult = netlogon_pipe;
3990 return NT_STATUS_OK;
3993 /****************************************************************************
3994 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3995 Fetch the session key ourselves using a temporary netlogon pipe. This version
3996 uses an ntlmssp bind to get the session key.
3997 ****************************************************************************/
3999 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4000 const struct ndr_syntax_id *interface,
4001 enum dcerpc_transport_t transport,
4002 enum dcerpc_AuthLevel auth_level,
4003 const char *domain,
4004 const char *username,
4005 const char *password,
4006 struct rpc_pipe_client **presult)
4008 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4009 struct rpc_pipe_client *netlogon_pipe = NULL;
4010 struct rpc_pipe_client *result = NULL;
4011 NTSTATUS status;
4013 status = get_schannel_session_key_auth_ntlmssp(
4014 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4015 if (!NT_STATUS_IS_OK(status)) {
4016 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4017 "key from server %s for domain %s.\n",
4018 cli->desthost, domain ));
4019 return status;
4022 status = cli_rpc_pipe_open_schannel_with_key(
4023 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4024 &result);
4026 /* Now we've bound using the session key we can close the netlog pipe. */
4027 TALLOC_FREE(netlogon_pipe);
4029 if (NT_STATUS_IS_OK(status)) {
4030 *presult = result;
4032 return status;
4035 /****************************************************************************
4036 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4037 Fetch the session key ourselves using a temporary netlogon pipe.
4038 ****************************************************************************/
4040 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4041 const struct ndr_syntax_id *interface,
4042 enum dcerpc_transport_t transport,
4043 enum dcerpc_AuthLevel auth_level,
4044 const char *domain,
4045 struct rpc_pipe_client **presult)
4047 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4048 struct rpc_pipe_client *netlogon_pipe = NULL;
4049 struct rpc_pipe_client *result = NULL;
4050 NTSTATUS status;
4052 status = get_schannel_session_key(cli, domain, &neg_flags,
4053 &netlogon_pipe);
4054 if (!NT_STATUS_IS_OK(status)) {
4055 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4056 "key from server %s for domain %s.\n",
4057 cli->desthost, domain ));
4058 return status;
4061 status = cli_rpc_pipe_open_schannel_with_key(
4062 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4063 &result);
4065 /* Now we've bound using the session key we can close the netlog pipe. */
4066 TALLOC_FREE(netlogon_pipe);
4068 if (NT_STATUS_IS_OK(status)) {
4069 *presult = result;
4072 return NT_STATUS_OK;
4075 /****************************************************************************
4076 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4077 The idea is this can be called with service_princ, username and password all
4078 NULL so long as the caller has a TGT.
4079 ****************************************************************************/
4081 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4082 const struct ndr_syntax_id *interface,
4083 enum dcerpc_AuthLevel auth_level,
4084 const char *service_princ,
4085 const char *username,
4086 const char *password,
4087 struct rpc_pipe_client **presult)
4089 #ifdef HAVE_KRB5
4090 struct rpc_pipe_client *result;
4091 struct cli_pipe_auth_data *auth;
4092 NTSTATUS status;
4094 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4095 if (!NT_STATUS_IS_OK(status)) {
4096 return status;
4099 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4100 username, password, &auth);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4103 nt_errstr(status)));
4104 TALLOC_FREE(result);
4105 return status;
4108 status = rpc_pipe_bind(result, auth);
4109 if (!NT_STATUS_IS_OK(status)) {
4110 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4111 "with error %s\n", nt_errstr(status)));
4112 TALLOC_FREE(result);
4113 return status;
4116 *presult = result;
4117 return NT_STATUS_OK;
4118 #else
4119 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4120 return NT_STATUS_NOT_IMPLEMENTED;
4121 #endif
4124 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4125 struct rpc_pipe_client *cli,
4126 DATA_BLOB *session_key)
4128 if (!session_key || !cli) {
4129 return NT_STATUS_INVALID_PARAMETER;
4132 if (!cli->auth) {
4133 return NT_STATUS_INVALID_PARAMETER;
4136 switch (cli->auth->auth_type) {
4137 case PIPE_AUTH_TYPE_SCHANNEL:
4138 *session_key = data_blob_talloc(mem_ctx,
4139 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4140 break;
4141 case PIPE_AUTH_TYPE_NTLMSSP:
4142 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4143 *session_key = data_blob_talloc(mem_ctx,
4144 cli->auth->a_u.ntlmssp_state->session_key.data,
4145 cli->auth->a_u.ntlmssp_state->session_key.length);
4146 break;
4147 case PIPE_AUTH_TYPE_KRB5:
4148 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4149 *session_key = data_blob_talloc(mem_ctx,
4150 cli->auth->a_u.kerberos_auth->session_key.data,
4151 cli->auth->a_u.kerberos_auth->session_key.length);
4152 break;
4153 case PIPE_AUTH_TYPE_NONE:
4154 *session_key = data_blob_talloc(mem_ctx,
4155 cli->auth->user_session_key.data,
4156 cli->auth->user_session_key.length);
4157 break;
4158 default:
4159 return NT_STATUS_NO_USER_SESSION_KEY;
4162 return NT_STATUS_OK;