Convert rpc_api_pipe to tevent_req
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_pipe.c
blobb87c8a6815539dca6d7e3d25beeeae650a36395f
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
59 } pipe_names [] =
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
77 { NULL, NULL }
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
86 char *guid_str;
87 const char *result;
88 int i;
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
91 interface)) {
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
101 guid_str = GUID_string(talloc_tos(), &interface->uuid);
102 if (guid_str == NULL) {
103 return NULL;
105 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
106 (int)interface->if_version);
107 TALLOC_FREE(guid_str);
109 if (result == NULL) {
110 return "PIPE";
112 return result;
115 /********************************************************************
116 Map internal value to wire value.
117 ********************************************************************/
119 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
121 switch (auth_type) {
123 case PIPE_AUTH_TYPE_NONE:
124 return RPC_ANONYMOUS_AUTH_TYPE;
126 case PIPE_AUTH_TYPE_NTLMSSP:
127 return RPC_NTLMSSP_AUTH_TYPE;
129 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
130 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
131 return RPC_SPNEGO_AUTH_TYPE;
133 case PIPE_AUTH_TYPE_SCHANNEL:
134 return RPC_SCHANNEL_AUTH_TYPE;
136 case PIPE_AUTH_TYPE_KRB5:
137 return RPC_KRB5_AUTH_TYPE;
139 default:
140 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
141 "auth type %u\n",
142 (unsigned int)auth_type ));
143 break;
145 return -1;
148 /********************************************************************
149 Pipe description for a DEBUG
150 ********************************************************************/
151 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
152 struct rpc_pipe_client *cli)
154 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
155 if (result == NULL) {
156 return "pipe";
158 return result;
161 /********************************************************************
162 Rpc pipe call id.
163 ********************************************************************/
165 static uint32 get_rpc_call_id(void)
167 static uint32 call_id = 0;
168 return ++call_id;
172 * Realloc pdu to have a least "size" bytes
175 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
177 size_t extra_size;
179 if (prs_data_size(pdu) >= size) {
180 return true;
183 extra_size = size - prs_data_size(pdu);
185 if (!prs_force_grow(pdu, extra_size)) {
186 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
187 "%d bytes.\n", (int)extra_size));
188 return false;
191 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
192 (int)extra_size, prs_data_size(pdu)));
193 return true;
197 /*******************************************************************
198 Use SMBreadX to get rest of one fragment's worth of rpc data.
199 Reads the whole size or give an error message
200 ********************************************************************/
202 struct rpc_read_state {
203 struct event_context *ev;
204 struct rpc_cli_transport *transport;
205 uint8_t *data;
206 size_t size;
207 size_t num_read;
210 static void rpc_read_done(struct async_req *subreq);
212 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
213 struct event_context *ev,
214 struct rpc_cli_transport *transport,
215 uint8_t *data, size_t size)
217 struct tevent_req *req;
218 struct async_req *subreq;
219 struct rpc_read_state *state;
221 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
222 if (req == NULL) {
223 return NULL;
225 state->ev = ev;
226 state->transport = transport;
227 state->data = data;
228 state->size = size;
229 state->num_read = 0;
231 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
233 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
234 transport->priv);
235 if (subreq == NULL) {
236 goto fail;
238 subreq->async.fn = rpc_read_done;
239 subreq->async.priv = req;
240 return req;
242 fail:
243 TALLOC_FREE(req);
244 return NULL;
247 static void rpc_read_done(struct async_req *subreq)
249 struct tevent_req *req = talloc_get_type_abort(
250 subreq->async.priv, struct tevent_req);
251 struct rpc_read_state *state = tevent_req_data(
252 req, struct rpc_read_state);
253 NTSTATUS status;
254 ssize_t received;
256 status = state->transport->read_recv(subreq, &received);
257 TALLOC_FREE(subreq);
258 if (!NT_STATUS_IS_OK(status)) {
259 tevent_req_nterror(req, status);
260 return;
263 state->num_read += received;
264 if (state->num_read == state->size) {
265 tevent_req_done(req);
266 return;
269 subreq = state->transport->read_send(state, state->ev,
270 state->data + state->num_read,
271 state->size - state->num_read,
272 state->transport->priv);
273 if (tevent_req_nomem(subreq, req)) {
274 return;
276 subreq->async.fn = rpc_read_done;
277 subreq->async.priv = req;
280 static NTSTATUS rpc_read_recv(struct tevent_req *req)
282 return tevent_req_simple_recv_ntstatus(req);
285 struct rpc_write_state {
286 struct event_context *ev;
287 struct rpc_cli_transport *transport;
288 const uint8_t *data;
289 size_t size;
290 size_t num_written;
293 static void rpc_write_done(struct async_req *subreq);
295 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
296 struct event_context *ev,
297 struct rpc_cli_transport *transport,
298 const uint8_t *data, size_t size)
300 struct tevent_req *req;
301 struct async_req *subreq;
302 struct rpc_write_state *state;
304 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
305 if (req == NULL) {
306 return NULL;
308 state->ev = ev;
309 state->transport = transport;
310 state->data = data;
311 state->size = size;
312 state->num_written = 0;
314 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
316 subreq = transport->write_send(state, ev, data, size, transport->priv);
317 if (subreq == NULL) {
318 goto fail;
320 subreq->async.fn = rpc_write_done;
321 subreq->async.priv = req;
322 return req;
323 fail:
324 TALLOC_FREE(req);
325 return NULL;
328 static void rpc_write_done(struct async_req *subreq)
330 struct tevent_req *req = talloc_get_type_abort(
331 subreq->async.priv, 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 subreq->async.fn = rpc_write_done;
359 subreq->async.priv = req;
362 static NTSTATUS rpc_write_recv(struct tevent_req *req)
364 return tevent_req_simple_recv_ntstatus(req);
368 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
369 struct rpc_hdr_info *prhdr,
370 prs_struct *pdu)
373 * This next call sets the endian bit correctly in current_pdu. We
374 * will propagate this to rbuf later.
377 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
378 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
379 return NT_STATUS_BUFFER_TOO_SMALL;
382 if (prhdr->frag_len > cli->max_recv_frag) {
383 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
384 " we only allow %d\n", (int)prhdr->frag_len,
385 (int)cli->max_recv_frag));
386 return NT_STATUS_BUFFER_TOO_SMALL;
389 return NT_STATUS_OK;
392 /****************************************************************************
393 Try and get a PDU's worth of data from current_pdu. If not, then read more
394 from the wire.
395 ****************************************************************************/
397 struct get_complete_frag_state {
398 struct event_context *ev;
399 struct rpc_pipe_client *cli;
400 struct rpc_hdr_info *prhdr;
401 prs_struct *pdu;
404 static void get_complete_frag_got_header(struct tevent_req *subreq);
405 static void get_complete_frag_got_rest(struct tevent_req *subreq);
407 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
408 struct event_context *ev,
409 struct rpc_pipe_client *cli,
410 struct rpc_hdr_info *prhdr,
411 prs_struct *pdu)
413 struct tevent_req *req, *subreq;
414 struct get_complete_frag_state *state;
415 uint32_t pdu_len;
416 NTSTATUS status;
418 req = tevent_req_create(mem_ctx, &state,
419 struct get_complete_frag_state);
420 if (req == NULL) {
421 return NULL;
423 state->ev = ev;
424 state->cli = cli;
425 state->prhdr = prhdr;
426 state->pdu = pdu;
428 pdu_len = prs_data_size(pdu);
429 if (pdu_len < RPC_HEADER_LEN) {
430 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
431 status = NT_STATUS_NO_MEMORY;
432 goto post_status;
434 subreq = rpc_read_send(
435 state, state->ev,
436 state->cli->transport,
437 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
438 RPC_HEADER_LEN - pdu_len);
439 if (subreq == NULL) {
440 status = NT_STATUS_NO_MEMORY;
441 goto post_status;
443 tevent_req_set_callback(subreq, get_complete_frag_got_header,
444 req);
445 return req;
448 status = parse_rpc_header(cli, prhdr, pdu);
449 if (!NT_STATUS_IS_OK(status)) {
450 goto post_status;
454 * Ensure we have frag_len bytes of data.
456 if (pdu_len < prhdr->frag_len) {
457 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
458 status = NT_STATUS_NO_MEMORY;
459 goto post_status;
461 subreq = rpc_read_send(state, state->ev,
462 state->cli->transport,
463 (uint8_t *)(prs_data_p(pdu) + pdu_len),
464 prhdr->frag_len - pdu_len);
465 if (subreq == NULL) {
466 status = NT_STATUS_NO_MEMORY;
467 goto post_status;
469 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
470 req);
471 return req;
474 status = NT_STATUS_OK;
475 post_status:
476 if (NT_STATUS_IS_OK(status)) {
477 tevent_req_done(req);
478 } else {
479 tevent_req_nterror(req, status);
481 return tevent_req_post(req, ev);
484 static void get_complete_frag_got_header(struct tevent_req *subreq)
486 struct tevent_req *req = tevent_req_callback_data(
487 subreq, struct tevent_req);
488 struct get_complete_frag_state *state = tevent_req_data(
489 req, struct get_complete_frag_state);
490 NTSTATUS status;
492 status = rpc_read_recv(subreq);
493 TALLOC_FREE(subreq);
494 if (!NT_STATUS_IS_OK(status)) {
495 tevent_req_nterror(req, status);
496 return;
499 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
500 if (!NT_STATUS_IS_OK(status)) {
501 tevent_req_nterror(req, status);
502 return;
505 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
506 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
507 return;
511 * We're here in this piece of code because we've read exactly
512 * RPC_HEADER_LEN bytes into state->pdu.
515 subreq = rpc_read_send(
516 state, state->ev, state->cli->transport,
517 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
518 state->prhdr->frag_len - RPC_HEADER_LEN);
519 if (tevent_req_nomem(subreq, req)) {
520 return;
522 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
525 static void get_complete_frag_got_rest(struct tevent_req *subreq)
527 struct tevent_req *req = tevent_req_callback_data(
528 subreq, struct tevent_req);
529 NTSTATUS status;
531 status = rpc_read_recv(subreq);
532 TALLOC_FREE(subreq);
533 if (!NT_STATUS_IS_OK(status)) {
534 tevent_req_nterror(req, status);
535 return;
537 tevent_req_done(req);
540 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
542 return tevent_req_simple_recv_ntstatus(req);
545 /****************************************************************************
546 NTLMSSP specific sign/seal.
547 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
548 In fact I should probably abstract these into identical pieces of code... JRA.
549 ****************************************************************************/
551 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
552 prs_struct *current_pdu,
553 uint8 *p_ss_padding_len)
555 RPC_HDR_AUTH auth_info;
556 uint32 save_offset = prs_offset(current_pdu);
557 uint32 auth_len = prhdr->auth_len;
558 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
559 unsigned char *data = NULL;
560 size_t data_len;
561 unsigned char *full_packet_data = NULL;
562 size_t full_packet_data_len;
563 DATA_BLOB auth_blob;
564 NTSTATUS status;
566 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
567 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
568 return NT_STATUS_OK;
571 if (!ntlmssp_state) {
572 return NT_STATUS_INVALID_PARAMETER;
575 /* Ensure there's enough data for an authenticated response. */
576 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
577 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
578 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
579 (unsigned int)auth_len ));
580 return NT_STATUS_BUFFER_TOO_SMALL;
584 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
585 * after the RPC header.
586 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
587 * functions as NTLMv2 checks the rpc headers also.
590 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
591 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
593 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
594 full_packet_data_len = prhdr->frag_len - auth_len;
596 /* Pull the auth header and the following data into a blob. */
597 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
598 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
599 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
600 return NT_STATUS_BUFFER_TOO_SMALL;
603 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
604 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
605 return NT_STATUS_BUFFER_TOO_SMALL;
608 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
609 auth_blob.length = auth_len;
611 switch (cli->auth->auth_level) {
612 case PIPE_AUTH_LEVEL_PRIVACY:
613 /* Data is encrypted. */
614 status = ntlmssp_unseal_packet(ntlmssp_state,
615 data, data_len,
616 full_packet_data,
617 full_packet_data_len,
618 &auth_blob);
619 if (!NT_STATUS_IS_OK(status)) {
620 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
621 "packet from %s. Error was %s.\n",
622 rpccli_pipe_txt(debug_ctx(), cli),
623 nt_errstr(status) ));
624 return status;
626 break;
627 case PIPE_AUTH_LEVEL_INTEGRITY:
628 /* Data is signed. */
629 status = ntlmssp_check_packet(ntlmssp_state,
630 data, data_len,
631 full_packet_data,
632 full_packet_data_len,
633 &auth_blob);
634 if (!NT_STATUS_IS_OK(status)) {
635 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
636 "packet from %s. Error was %s.\n",
637 rpccli_pipe_txt(debug_ctx(), cli),
638 nt_errstr(status) ));
639 return status;
641 break;
642 default:
643 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
644 "auth level %d\n", cli->auth->auth_level));
645 return NT_STATUS_INVALID_INFO_CLASS;
649 * Return the current pointer to the data offset.
652 if(!prs_set_offset(current_pdu, save_offset)) {
653 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
654 (unsigned int)save_offset ));
655 return NT_STATUS_BUFFER_TOO_SMALL;
659 * Remember the padding length. We must remove it from the real data
660 * stream once the sign/seal is done.
663 *p_ss_padding_len = auth_info.auth_pad_len;
665 return NT_STATUS_OK;
668 /****************************************************************************
669 schannel specific sign/seal.
670 ****************************************************************************/
672 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
673 prs_struct *current_pdu,
674 uint8 *p_ss_padding_len)
676 RPC_HDR_AUTH auth_info;
677 RPC_AUTH_SCHANNEL_CHK schannel_chk;
678 uint32 auth_len = prhdr->auth_len;
679 uint32 save_offset = prs_offset(current_pdu);
680 struct schannel_auth_struct *schannel_auth =
681 cli->auth->a_u.schannel_auth;
682 uint32 data_len;
684 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
685 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
686 return NT_STATUS_OK;
689 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
690 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
691 return NT_STATUS_INVALID_PARAMETER;
694 if (!schannel_auth) {
695 return NT_STATUS_INVALID_PARAMETER;
698 /* Ensure there's enough data for an authenticated response. */
699 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
700 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
701 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
702 (unsigned int)auth_len ));
703 return NT_STATUS_INVALID_PARAMETER;
706 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
708 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
709 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
710 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
711 return NT_STATUS_BUFFER_TOO_SMALL;
714 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
715 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
716 return NT_STATUS_BUFFER_TOO_SMALL;
719 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
720 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
721 auth_info.auth_type));
722 return NT_STATUS_BUFFER_TOO_SMALL;
725 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
726 &schannel_chk, current_pdu, 0)) {
727 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
728 return NT_STATUS_BUFFER_TOO_SMALL;
731 if (!schannel_decode(schannel_auth,
732 cli->auth->auth_level,
733 SENDER_IS_ACCEPTOR,
734 &schannel_chk,
735 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
736 data_len)) {
737 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
738 "Connection to %s.\n",
739 rpccli_pipe_txt(debug_ctx(), cli)));
740 return NT_STATUS_INVALID_PARAMETER;
743 /* The sequence number gets incremented on both send and receive. */
744 schannel_auth->seq_num++;
747 * Return the current pointer to the data offset.
750 if(!prs_set_offset(current_pdu, save_offset)) {
751 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
752 (unsigned int)save_offset ));
753 return NT_STATUS_BUFFER_TOO_SMALL;
757 * Remember the padding length. We must remove it from the real data
758 * stream once the sign/seal is done.
761 *p_ss_padding_len = auth_info.auth_pad_len;
763 return NT_STATUS_OK;
766 /****************************************************************************
767 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
768 ****************************************************************************/
770 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
771 prs_struct *current_pdu,
772 uint8 *p_ss_padding_len)
774 NTSTATUS ret = NT_STATUS_OK;
776 /* Paranioa checks for auth_len. */
777 if (prhdr->auth_len) {
778 if (prhdr->auth_len > prhdr->frag_len) {
779 return NT_STATUS_INVALID_PARAMETER;
782 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
783 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
784 /* Integer wrap attempt. */
785 return NT_STATUS_INVALID_PARAMETER;
790 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
793 switch(cli->auth->auth_type) {
794 case PIPE_AUTH_TYPE_NONE:
795 if (prhdr->auth_len) {
796 DEBUG(3, ("cli_pipe_validate_rpc_response: "
797 "Connection to %s - got non-zero "
798 "auth len %u.\n",
799 rpccli_pipe_txt(debug_ctx(), cli),
800 (unsigned int)prhdr->auth_len ));
801 return NT_STATUS_INVALID_PARAMETER;
803 break;
805 case PIPE_AUTH_TYPE_NTLMSSP:
806 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
807 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
808 if (!NT_STATUS_IS_OK(ret)) {
809 return ret;
811 break;
813 case PIPE_AUTH_TYPE_SCHANNEL:
814 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
815 if (!NT_STATUS_IS_OK(ret)) {
816 return ret;
818 break;
820 case PIPE_AUTH_TYPE_KRB5:
821 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
822 default:
823 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
824 "to %s - unknown internal auth type %u.\n",
825 rpccli_pipe_txt(debug_ctx(), cli),
826 cli->auth->auth_type ));
827 return NT_STATUS_INVALID_INFO_CLASS;
830 return NT_STATUS_OK;
833 /****************************************************************************
834 Do basic authentication checks on an incoming pdu.
835 ****************************************************************************/
837 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
838 prs_struct *current_pdu,
839 uint8 expected_pkt_type,
840 char **ppdata,
841 uint32 *pdata_len,
842 prs_struct *return_data)
845 NTSTATUS ret = NT_STATUS_OK;
846 uint32 current_pdu_len = prs_data_size(current_pdu);
848 if (current_pdu_len != prhdr->frag_len) {
849 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
850 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
851 return NT_STATUS_INVALID_PARAMETER;
855 * Point the return values at the real data including the RPC
856 * header. Just in case the caller wants it.
858 *ppdata = prs_data_p(current_pdu);
859 *pdata_len = current_pdu_len;
861 /* Ensure we have the correct type. */
862 switch (prhdr->pkt_type) {
863 case RPC_ALTCONTRESP:
864 case RPC_BINDACK:
866 /* Alter context and bind ack share the same packet definitions. */
867 break;
870 case RPC_RESPONSE:
872 RPC_HDR_RESP rhdr_resp;
873 uint8 ss_padding_len = 0;
875 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
876 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
877 return NT_STATUS_BUFFER_TOO_SMALL;
880 /* Here's where we deal with incoming sign/seal. */
881 ret = cli_pipe_validate_rpc_response(cli, prhdr,
882 current_pdu, &ss_padding_len);
883 if (!NT_STATUS_IS_OK(ret)) {
884 return ret;
887 /* Point the return values at the NDR data. Remember to remove any ss padding. */
888 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
890 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
891 return NT_STATUS_BUFFER_TOO_SMALL;
894 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
896 /* Remember to remove the auth footer. */
897 if (prhdr->auth_len) {
898 /* We've already done integer wrap tests on auth_len in
899 cli_pipe_validate_rpc_response(). */
900 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
901 return NT_STATUS_BUFFER_TOO_SMALL;
903 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
906 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
907 current_pdu_len, *pdata_len, ss_padding_len ));
910 * If this is the first reply, and the allocation hint is reasonably, try and
911 * set up the return_data parse_struct to the correct size.
914 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
915 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
916 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
917 "too large to allocate\n",
918 (unsigned int)rhdr_resp.alloc_hint ));
919 return NT_STATUS_NO_MEMORY;
923 break;
926 case RPC_BINDNACK:
927 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
928 "received from %s!\n",
929 rpccli_pipe_txt(debug_ctx(), cli)));
930 /* Use this for now... */
931 return NT_STATUS_NETWORK_ACCESS_DENIED;
933 case RPC_FAULT:
935 RPC_HDR_RESP rhdr_resp;
936 RPC_HDR_FAULT fault_resp;
938 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
939 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
940 return NT_STATUS_BUFFER_TOO_SMALL;
943 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
944 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
945 return NT_STATUS_BUFFER_TOO_SMALL;
948 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
949 "code %s received from %s!\n",
950 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
951 rpccli_pipe_txt(debug_ctx(), cli)));
952 if (NT_STATUS_IS_OK(fault_resp.status)) {
953 return NT_STATUS_UNSUCCESSFUL;
954 } else {
955 return fault_resp.status;
959 default:
960 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
961 "from %s!\n",
962 (unsigned int)prhdr->pkt_type,
963 rpccli_pipe_txt(debug_ctx(), cli)));
964 return NT_STATUS_INVALID_INFO_CLASS;
967 if (prhdr->pkt_type != expected_pkt_type) {
968 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
969 "got an unexpected RPC packet type - %u, not %u\n",
970 rpccli_pipe_txt(debug_ctx(), cli),
971 prhdr->pkt_type,
972 expected_pkt_type));
973 return NT_STATUS_INVALID_INFO_CLASS;
976 /* Do this just before return - we don't want to modify any rpc header
977 data before now as we may have needed to do cryptographic actions on
978 it before. */
980 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
981 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
982 "setting fragment first/last ON.\n"));
983 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
986 return NT_STATUS_OK;
989 /****************************************************************************
990 Ensure we eat the just processed pdu from the current_pdu prs_struct.
991 Normally the frag_len and buffer size will match, but on the first trans
992 reply there is a theoretical chance that buffer size > frag_len, so we must
993 deal with that.
994 ****************************************************************************/
996 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
998 uint32 current_pdu_len = prs_data_size(current_pdu);
1000 if (current_pdu_len < prhdr->frag_len) {
1001 return NT_STATUS_BUFFER_TOO_SMALL;
1004 /* Common case. */
1005 if (current_pdu_len == (uint32)prhdr->frag_len) {
1006 prs_mem_free(current_pdu);
1007 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1008 /* Make current_pdu dynamic with no memory. */
1009 prs_give_memory(current_pdu, 0, 0, True);
1010 return NT_STATUS_OK;
1014 * Oh no ! More data in buffer than we processed in current pdu.
1015 * Cheat. Move the data down and shrink the buffer.
1018 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1019 current_pdu_len - prhdr->frag_len);
1021 /* Remember to set the read offset back to zero. */
1022 prs_set_offset(current_pdu, 0);
1024 /* Shrink the buffer. */
1025 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1026 return NT_STATUS_BUFFER_TOO_SMALL;
1029 return NT_STATUS_OK;
1032 /****************************************************************************
1033 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1034 ****************************************************************************/
1036 struct cli_api_pipe_state {
1037 struct event_context *ev;
1038 struct rpc_cli_transport *transport;
1039 uint8_t *rdata;
1040 uint32_t rdata_len;
1043 static void cli_api_pipe_trans_done(struct async_req *subreq);
1044 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1045 static void cli_api_pipe_read_done(struct async_req *subreq);
1047 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1048 struct event_context *ev,
1049 struct rpc_cli_transport *transport,
1050 uint8_t *data, size_t data_len,
1051 uint32_t max_rdata_len)
1053 struct tevent_req *req;
1054 struct async_req *subreq;
1055 struct tevent_req *subreq2;
1056 struct cli_api_pipe_state *state;
1057 NTSTATUS status;
1059 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1060 if (req == NULL) {
1061 return NULL;
1063 state->ev = ev;
1064 state->transport = transport;
1066 if (max_rdata_len < RPC_HEADER_LEN) {
1068 * For a RPC reply we always need at least RPC_HEADER_LEN
1069 * bytes. We check this here because we will receive
1070 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1072 status = NT_STATUS_INVALID_PARAMETER;
1073 goto post_status;
1076 if (transport->trans_send != NULL) {
1077 subreq = transport->trans_send(state, ev, data, data_len,
1078 max_rdata_len, transport->priv);
1079 if (subreq == NULL) {
1080 status = NT_STATUS_NO_MEMORY;
1081 goto post_status;
1083 subreq->async.fn = cli_api_pipe_trans_done;
1084 subreq->async.priv = req;
1085 return req;
1089 * If the transport does not provide a "trans" routine, i.e. for
1090 * example the ncacn_ip_tcp transport, do the write/read step here.
1093 subreq2 = rpc_write_send(state, ev, transport, data, data_len);
1094 if (subreq2 == NULL) {
1095 goto fail;
1097 tevent_req_set_callback(subreq2, cli_api_pipe_write_done, req);
1098 return req;
1100 status = NT_STATUS_INVALID_PARAMETER;
1102 post_status:
1103 if (NT_STATUS_IS_OK(status)) {
1104 tevent_req_done(req);
1105 } else {
1106 tevent_req_nterror(req, status);
1108 return tevent_req_post(req, ev);
1109 fail:
1110 TALLOC_FREE(req);
1111 return NULL;
1114 static void cli_api_pipe_trans_done(struct async_req *subreq)
1116 struct tevent_req *req = talloc_get_type_abort(
1117 subreq->async.priv, struct tevent_req);
1118 struct cli_api_pipe_state *state = tevent_req_data(
1119 req, struct cli_api_pipe_state);
1120 NTSTATUS status;
1122 status = state->transport->trans_recv(subreq, state, &state->rdata,
1123 &state->rdata_len);
1124 TALLOC_FREE(subreq);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 tevent_req_nterror(req, status);
1127 return;
1129 tevent_req_done(req);
1132 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1134 struct tevent_req *req = tevent_req_callback_data(
1135 subreq, struct tevent_req);
1136 struct cli_api_pipe_state *state = tevent_req_data(
1137 req, struct cli_api_pipe_state);
1138 struct async_req *subreq2;
1139 NTSTATUS status;
1141 status = rpc_write_recv(subreq);
1142 TALLOC_FREE(subreq);
1143 if (!NT_STATUS_IS_OK(status)) {
1144 tevent_req_nterror(req, status);
1145 return;
1148 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1149 if (tevent_req_nomem(state->rdata, req)) {
1150 return;
1154 * We don't need to use rpc_read_send here, the upper layer will cope
1155 * with a short read, transport->trans_send could also return less
1156 * than state->max_rdata_len.
1158 subreq2 = state->transport->read_send(state, state->ev, state->rdata,
1159 RPC_HEADER_LEN,
1160 state->transport->priv);
1161 if (tevent_req_nomem(subreq2, req)) {
1162 return;
1164 subreq2->async.fn = cli_api_pipe_read_done;
1165 subreq2->async.priv = req;
1168 static void cli_api_pipe_read_done(struct async_req *subreq)
1170 struct tevent_req *req = talloc_get_type_abort(
1171 subreq->async.priv, struct tevent_req);
1172 struct cli_api_pipe_state *state = tevent_req_data(
1173 req, struct cli_api_pipe_state);
1174 NTSTATUS status;
1175 ssize_t received;
1177 status = state->transport->read_recv(subreq, &received);
1178 TALLOC_FREE(subreq);
1179 if (!NT_STATUS_IS_OK(status)) {
1180 tevent_req_nterror(req, status);
1181 return;
1183 state->rdata_len = received;
1184 tevent_req_done(req);
1187 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1188 uint8_t **prdata, uint32_t *prdata_len)
1190 struct cli_api_pipe_state *state = tevent_req_data(
1191 req, struct cli_api_pipe_state);
1192 NTSTATUS status;
1194 if (tevent_req_is_nterror(req, &status)) {
1195 return status;
1198 *prdata = talloc_move(mem_ctx, &state->rdata);
1199 *prdata_len = state->rdata_len;
1200 return NT_STATUS_OK;
1203 /****************************************************************************
1204 Send data on an rpc pipe via trans. The prs_struct data must be the last
1205 pdu fragment of an NDR data stream.
1207 Receive response data from an rpc pipe, which may be large...
1209 Read the first fragment: unfortunately have to use SMBtrans for the first
1210 bit, then SMBreadX for subsequent bits.
1212 If first fragment received also wasn't the last fragment, continue
1213 getting fragments until we _do_ receive the last fragment.
1215 Request/Response PDU's look like the following...
1217 |<------------------PDU len----------------------------------------------->|
1218 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1220 +------------+-----------------+-------------+---------------+-------------+
1221 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1222 +------------+-----------------+-------------+---------------+-------------+
1224 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1225 signing & sealing being negotiated.
1227 ****************************************************************************/
1229 struct rpc_api_pipe_state {
1230 struct event_context *ev;
1231 struct rpc_pipe_client *cli;
1232 uint8_t expected_pkt_type;
1234 prs_struct incoming_frag;
1235 struct rpc_hdr_info rhdr;
1237 prs_struct incoming_pdu; /* Incoming reply */
1238 uint32_t incoming_pdu_offset;
1241 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1243 prs_mem_free(&state->incoming_frag);
1244 prs_mem_free(&state->incoming_pdu);
1245 return 0;
1248 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1249 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1251 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1252 struct event_context *ev,
1253 struct rpc_pipe_client *cli,
1254 prs_struct *data, /* Outgoing PDU */
1255 uint8_t expected_pkt_type)
1257 struct tevent_req *req, *subreq;
1258 struct rpc_api_pipe_state *state;
1259 uint16_t max_recv_frag;
1260 NTSTATUS status;
1262 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1263 if (req == NULL) {
1264 return NULL;
1266 state->ev = ev;
1267 state->cli = cli;
1268 state->expected_pkt_type = expected_pkt_type;
1269 state->incoming_pdu_offset = 0;
1271 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1273 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1274 /* Make incoming_pdu dynamic with no memory. */
1275 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1277 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1280 * Ensure we're not sending too much.
1282 if (prs_offset(data) > cli->max_xmit_frag) {
1283 status = NT_STATUS_INVALID_PARAMETER;
1284 goto post_status;
1287 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1289 max_recv_frag = cli->max_recv_frag;
1291 #ifdef DEVELOPER
1292 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1293 #endif
1295 subreq = cli_api_pipe_send(state, ev, cli->transport,
1296 (uint8_t *)prs_data_p(data),
1297 prs_offset(data), max_recv_frag);
1298 if (subreq == NULL) {
1299 goto fail;
1301 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1302 return req;
1304 post_status:
1305 tevent_req_nterror(req, status);
1306 return tevent_req_post(req, ev);
1307 fail:
1308 TALLOC_FREE(req);
1309 return NULL;
1312 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1314 struct tevent_req *req = tevent_req_callback_data(
1315 subreq, struct tevent_req);
1316 struct rpc_api_pipe_state *state = tevent_req_data(
1317 req, struct rpc_api_pipe_state);
1318 NTSTATUS status;
1319 uint8_t *rdata = NULL;
1320 uint32_t rdata_len = 0;
1321 char *rdata_copy;
1323 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1324 TALLOC_FREE(subreq);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1327 tevent_req_nterror(req, status);
1328 return;
1331 if (rdata == NULL) {
1332 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1333 rpccli_pipe_txt(debug_ctx(), state->cli)));
1334 tevent_req_done(req);
1335 return;
1339 * Give the memory received from cli_trans as dynamic to the current
1340 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1341 * :-(
1343 rdata_copy = (char *)memdup(rdata, rdata_len);
1344 TALLOC_FREE(rdata);
1345 if (tevent_req_nomem(rdata_copy, req)) {
1346 return;
1348 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1350 /* Ensure we have enough data for a pdu. */
1351 subreq = get_complete_frag_send(state, state->ev, state->cli,
1352 &state->rhdr, &state->incoming_frag);
1353 if (tevent_req_nomem(subreq, req)) {
1354 return;
1356 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1359 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1361 struct tevent_req *req = tevent_req_callback_data(
1362 subreq, struct tevent_req);
1363 struct rpc_api_pipe_state *state = tevent_req_data(
1364 req, struct rpc_api_pipe_state);
1365 NTSTATUS status;
1366 char *rdata = NULL;
1367 uint32_t rdata_len = 0;
1369 status = get_complete_frag_recv(subreq);
1370 TALLOC_FREE(subreq);
1371 if (!NT_STATUS_IS_OK(status)) {
1372 DEBUG(5, ("get_complete_frag failed: %s\n",
1373 nt_errstr(status)));
1374 tevent_req_nterror(req, status);
1375 return;
1378 status = cli_pipe_validate_current_pdu(
1379 state->cli, &state->rhdr, &state->incoming_frag,
1380 state->expected_pkt_type, &rdata, &rdata_len,
1381 &state->incoming_pdu);
1383 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1384 (unsigned)prs_data_size(&state->incoming_frag),
1385 (unsigned)state->incoming_pdu_offset,
1386 nt_errstr(status)));
1388 if (!NT_STATUS_IS_OK(status)) {
1389 tevent_req_nterror(req, status);
1390 return;
1393 if ((state->rhdr.flags & RPC_FLG_FIRST)
1394 && (state->rhdr.pack_type[0] == 0)) {
1396 * Set the data type correctly for big-endian data on the
1397 * first packet.
1399 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1400 "big-endian.\n",
1401 rpccli_pipe_txt(debug_ctx(), state->cli)));
1402 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1405 * Check endianness on subsequent packets.
1407 if (state->incoming_frag.bigendian_data
1408 != state->incoming_pdu.bigendian_data) {
1409 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1410 "%s\n",
1411 state->incoming_pdu.bigendian_data?"big":"little",
1412 state->incoming_frag.bigendian_data?"big":"little"));
1413 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1414 return;
1417 /* Now copy the data portion out of the pdu into rbuf. */
1418 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1419 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1420 return;
1423 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1424 rdata, (size_t)rdata_len);
1425 state->incoming_pdu_offset += rdata_len;
1427 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1428 &state->incoming_frag);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 tevent_req_nterror(req, status);
1431 return;
1434 if (state->rhdr.flags & RPC_FLG_LAST) {
1435 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1436 rpccli_pipe_txt(debug_ctx(), state->cli),
1437 (unsigned)prs_data_size(&state->incoming_pdu)));
1438 tevent_req_done(req);
1439 return;
1442 subreq = get_complete_frag_send(state, state->ev, state->cli,
1443 &state->rhdr, &state->incoming_frag);
1444 if (tevent_req_nomem(subreq, req)) {
1445 return;
1447 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1450 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1451 prs_struct *reply_pdu)
1453 struct rpc_api_pipe_state *state = tevent_req_data(
1454 req, struct rpc_api_pipe_state);
1455 NTSTATUS status;
1457 if (tevent_req_is_nterror(req, &status)) {
1458 return status;
1461 *reply_pdu = state->incoming_pdu;
1462 reply_pdu->mem_ctx = mem_ctx;
1465 * Prevent state->incoming_pdu from being freed in
1466 * rpc_api_pipe_state_destructor()
1468 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1470 return NT_STATUS_OK;
1473 /*******************************************************************
1474 Creates krb5 auth bind.
1475 ********************************************************************/
1477 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1478 enum pipe_auth_level auth_level,
1479 RPC_HDR_AUTH *pauth_out,
1480 prs_struct *auth_data)
1482 #ifdef HAVE_KRB5
1483 int ret;
1484 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1485 DATA_BLOB tkt = data_blob_null;
1486 DATA_BLOB tkt_wrapped = data_blob_null;
1488 /* We may change the pad length before marshalling. */
1489 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1491 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1492 a->service_principal ));
1494 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1496 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1497 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1499 if (ret) {
1500 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1501 "failed with %s\n",
1502 a->service_principal,
1503 error_message(ret) ));
1505 data_blob_free(&tkt);
1506 prs_mem_free(auth_data);
1507 return NT_STATUS_INVALID_PARAMETER;
1510 /* wrap that up in a nice GSS-API wrapping */
1511 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1513 data_blob_free(&tkt);
1515 /* Auth len in the rpc header doesn't include auth_header. */
1516 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1517 data_blob_free(&tkt_wrapped);
1518 prs_mem_free(auth_data);
1519 return NT_STATUS_NO_MEMORY;
1522 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1523 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1525 data_blob_free(&tkt_wrapped);
1526 return NT_STATUS_OK;
1527 #else
1528 return NT_STATUS_INVALID_PARAMETER;
1529 #endif
1532 /*******************************************************************
1533 Creates SPNEGO NTLMSSP auth bind.
1534 ********************************************************************/
1536 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1537 enum pipe_auth_level auth_level,
1538 RPC_HDR_AUTH *pauth_out,
1539 prs_struct *auth_data)
1541 NTSTATUS nt_status;
1542 DATA_BLOB null_blob = data_blob_null;
1543 DATA_BLOB request = data_blob_null;
1544 DATA_BLOB spnego_msg = data_blob_null;
1546 /* We may change the pad length before marshalling. */
1547 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1549 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1550 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1551 null_blob,
1552 &request);
1554 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1555 data_blob_free(&request);
1556 prs_mem_free(auth_data);
1557 return nt_status;
1560 /* Wrap this in SPNEGO. */
1561 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1563 data_blob_free(&request);
1565 /* Auth len in the rpc header doesn't include auth_header. */
1566 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1567 data_blob_free(&spnego_msg);
1568 prs_mem_free(auth_data);
1569 return NT_STATUS_NO_MEMORY;
1572 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1573 dump_data(5, spnego_msg.data, spnego_msg.length);
1575 data_blob_free(&spnego_msg);
1576 return NT_STATUS_OK;
1579 /*******************************************************************
1580 Creates NTLMSSP auth bind.
1581 ********************************************************************/
1583 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1584 enum pipe_auth_level auth_level,
1585 RPC_HDR_AUTH *pauth_out,
1586 prs_struct *auth_data)
1588 NTSTATUS nt_status;
1589 DATA_BLOB null_blob = data_blob_null;
1590 DATA_BLOB request = data_blob_null;
1592 /* We may change the pad length before marshalling. */
1593 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1595 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1596 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1597 null_blob,
1598 &request);
1600 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1601 data_blob_free(&request);
1602 prs_mem_free(auth_data);
1603 return nt_status;
1606 /* Auth len in the rpc header doesn't include auth_header. */
1607 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1608 data_blob_free(&request);
1609 prs_mem_free(auth_data);
1610 return NT_STATUS_NO_MEMORY;
1613 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1614 dump_data(5, request.data, request.length);
1616 data_blob_free(&request);
1617 return NT_STATUS_OK;
1620 /*******************************************************************
1621 Creates schannel auth bind.
1622 ********************************************************************/
1624 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1625 enum pipe_auth_level auth_level,
1626 RPC_HDR_AUTH *pauth_out,
1627 prs_struct *auth_data)
1629 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1631 /* We may change the pad length before marshalling. */
1632 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1634 /* Use lp_workgroup() if domain not specified */
1636 if (!cli->auth->domain || !cli->auth->domain[0]) {
1637 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1638 if (cli->auth->domain == NULL) {
1639 return NT_STATUS_NO_MEMORY;
1643 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1644 global_myname());
1647 * Now marshall the data into the auth parse_struct.
1650 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1651 &schannel_neg, auth_data, 0)) {
1652 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1653 prs_mem_free(auth_data);
1654 return NT_STATUS_NO_MEMORY;
1657 return NT_STATUS_OK;
1660 /*******************************************************************
1661 Creates the internals of a DCE/RPC bind request or alter context PDU.
1662 ********************************************************************/
1664 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1665 prs_struct *rpc_out,
1666 uint32 rpc_call_id,
1667 const RPC_IFACE *abstract,
1668 const RPC_IFACE *transfer,
1669 RPC_HDR_AUTH *phdr_auth,
1670 prs_struct *pauth_info)
1672 RPC_HDR hdr;
1673 RPC_HDR_RB hdr_rb;
1674 RPC_CONTEXT rpc_ctx;
1675 uint16 auth_len = prs_offset(pauth_info);
1676 uint8 ss_padding_len = 0;
1677 uint16 frag_len = 0;
1679 /* create the RPC context. */
1680 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1682 /* create the bind request RPC_HDR_RB */
1683 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1685 /* Start building the frag length. */
1686 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1688 /* Do we need to pad ? */
1689 if (auth_len) {
1690 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1691 if (data_len % 8) {
1692 ss_padding_len = 8 - (data_len % 8);
1693 phdr_auth->auth_pad_len = ss_padding_len;
1695 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1698 /* Create the request RPC_HDR */
1699 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1701 /* Marshall the RPC header */
1702 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1703 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1704 return NT_STATUS_NO_MEMORY;
1707 /* Marshall the bind request data */
1708 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1709 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1710 return NT_STATUS_NO_MEMORY;
1714 * Grow the outgoing buffer to store any auth info.
1717 if(auth_len != 0) {
1718 if (ss_padding_len) {
1719 char pad[8];
1720 memset(pad, '\0', 8);
1721 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1722 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1723 return NT_STATUS_NO_MEMORY;
1727 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1728 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1729 return NT_STATUS_NO_MEMORY;
1733 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1734 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1735 return NT_STATUS_NO_MEMORY;
1739 return NT_STATUS_OK;
1742 /*******************************************************************
1743 Creates a DCE/RPC bind request.
1744 ********************************************************************/
1746 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1747 prs_struct *rpc_out,
1748 uint32 rpc_call_id,
1749 const RPC_IFACE *abstract,
1750 const RPC_IFACE *transfer,
1751 enum pipe_auth_type auth_type,
1752 enum pipe_auth_level auth_level)
1754 RPC_HDR_AUTH hdr_auth;
1755 prs_struct auth_info;
1756 NTSTATUS ret = NT_STATUS_OK;
1758 ZERO_STRUCT(hdr_auth);
1759 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1760 return NT_STATUS_NO_MEMORY;
1762 switch (auth_type) {
1763 case PIPE_AUTH_TYPE_SCHANNEL:
1764 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1765 if (!NT_STATUS_IS_OK(ret)) {
1766 prs_mem_free(&auth_info);
1767 return ret;
1769 break;
1771 case PIPE_AUTH_TYPE_NTLMSSP:
1772 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1773 if (!NT_STATUS_IS_OK(ret)) {
1774 prs_mem_free(&auth_info);
1775 return ret;
1777 break;
1779 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1780 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1781 if (!NT_STATUS_IS_OK(ret)) {
1782 prs_mem_free(&auth_info);
1783 return ret;
1785 break;
1787 case PIPE_AUTH_TYPE_KRB5:
1788 ret = create_krb5_auth_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_NONE:
1796 break;
1798 default:
1799 /* "Can't" happen. */
1800 return NT_STATUS_INVALID_INFO_CLASS;
1803 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1804 rpc_out,
1805 rpc_call_id,
1806 abstract,
1807 transfer,
1808 &hdr_auth,
1809 &auth_info);
1811 prs_mem_free(&auth_info);
1812 return ret;
1815 /*******************************************************************
1816 Create and add the NTLMSSP sign/seal auth header and data.
1817 ********************************************************************/
1819 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1820 RPC_HDR *phdr,
1821 uint32 ss_padding_len,
1822 prs_struct *outgoing_pdu)
1824 RPC_HDR_AUTH auth_info;
1825 NTSTATUS status;
1826 DATA_BLOB auth_blob = data_blob_null;
1827 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1829 if (!cli->auth->a_u.ntlmssp_state) {
1830 return NT_STATUS_INVALID_PARAMETER;
1833 /* Init and marshall the auth header. */
1834 init_rpc_hdr_auth(&auth_info,
1835 map_pipe_auth_type_to_rpc_auth_type(
1836 cli->auth->auth_type),
1837 cli->auth->auth_level,
1838 ss_padding_len,
1839 1 /* context id. */);
1841 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1842 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1843 data_blob_free(&auth_blob);
1844 return NT_STATUS_NO_MEMORY;
1847 switch (cli->auth->auth_level) {
1848 case PIPE_AUTH_LEVEL_PRIVACY:
1849 /* Data portion is encrypted. */
1850 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1851 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1852 data_and_pad_len,
1853 (unsigned char *)prs_data_p(outgoing_pdu),
1854 (size_t)prs_offset(outgoing_pdu),
1855 &auth_blob);
1856 if (!NT_STATUS_IS_OK(status)) {
1857 data_blob_free(&auth_blob);
1858 return status;
1860 break;
1862 case PIPE_AUTH_LEVEL_INTEGRITY:
1863 /* Data is signed. */
1864 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1865 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1866 data_and_pad_len,
1867 (unsigned char *)prs_data_p(outgoing_pdu),
1868 (size_t)prs_offset(outgoing_pdu),
1869 &auth_blob);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 data_blob_free(&auth_blob);
1872 return status;
1874 break;
1876 default:
1877 /* Can't happen. */
1878 smb_panic("bad auth level");
1879 /* Notreached. */
1880 return NT_STATUS_INVALID_PARAMETER;
1883 /* Finally marshall the blob. */
1885 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1886 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1887 (unsigned int)NTLMSSP_SIG_SIZE));
1888 data_blob_free(&auth_blob);
1889 return NT_STATUS_NO_MEMORY;
1892 data_blob_free(&auth_blob);
1893 return NT_STATUS_OK;
1896 /*******************************************************************
1897 Create and add the schannel sign/seal auth header and data.
1898 ********************************************************************/
1900 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1901 RPC_HDR *phdr,
1902 uint32 ss_padding_len,
1903 prs_struct *outgoing_pdu)
1905 RPC_HDR_AUTH auth_info;
1906 RPC_AUTH_SCHANNEL_CHK verf;
1907 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1908 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1909 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1911 if (!sas) {
1912 return NT_STATUS_INVALID_PARAMETER;
1915 /* Init and marshall the auth header. */
1916 init_rpc_hdr_auth(&auth_info,
1917 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1918 cli->auth->auth_level,
1919 ss_padding_len,
1920 1 /* context id. */);
1922 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1923 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1924 return NT_STATUS_NO_MEMORY;
1927 switch (cli->auth->auth_level) {
1928 case PIPE_AUTH_LEVEL_PRIVACY:
1929 case PIPE_AUTH_LEVEL_INTEGRITY:
1930 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1931 sas->seq_num));
1933 schannel_encode(sas,
1934 cli->auth->auth_level,
1935 SENDER_IS_INITIATOR,
1936 &verf,
1937 data_p,
1938 data_and_pad_len);
1940 sas->seq_num++;
1941 break;
1943 default:
1944 /* Can't happen. */
1945 smb_panic("bad auth level");
1946 /* Notreached. */
1947 return NT_STATUS_INVALID_PARAMETER;
1950 /* Finally marshall the blob. */
1951 smb_io_rpc_auth_schannel_chk("",
1952 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1953 &verf,
1954 outgoing_pdu,
1957 return NT_STATUS_OK;
1960 /*******************************************************************
1961 Calculate how much data we're going to send in this packet, also
1962 work out any sign/seal padding length.
1963 ********************************************************************/
1965 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1966 uint32 data_left,
1967 uint16 *p_frag_len,
1968 uint16 *p_auth_len,
1969 uint32 *p_ss_padding)
1971 uint32 data_space, data_len;
1973 #ifdef DEVELOPER
1974 if ((data_left > 0) && (sys_random() % 2)) {
1975 data_left = MAX(data_left/2, 1);
1977 #endif
1979 switch (cli->auth->auth_level) {
1980 case PIPE_AUTH_LEVEL_NONE:
1981 case PIPE_AUTH_LEVEL_CONNECT:
1982 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1983 data_len = MIN(data_space, data_left);
1984 *p_ss_padding = 0;
1985 *p_auth_len = 0;
1986 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1987 return data_len;
1989 case PIPE_AUTH_LEVEL_INTEGRITY:
1990 case PIPE_AUTH_LEVEL_PRIVACY:
1991 /* Treat the same for all authenticated rpc requests. */
1992 switch(cli->auth->auth_type) {
1993 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1994 case PIPE_AUTH_TYPE_NTLMSSP:
1995 *p_auth_len = NTLMSSP_SIG_SIZE;
1996 break;
1997 case PIPE_AUTH_TYPE_SCHANNEL:
1998 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1999 break;
2000 default:
2001 smb_panic("bad auth type");
2002 break;
2005 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2006 RPC_HDR_AUTH_LEN - *p_auth_len;
2008 data_len = MIN(data_space, data_left);
2009 *p_ss_padding = 0;
2010 if (data_len % 8) {
2011 *p_ss_padding = 8 - (data_len % 8);
2013 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2014 data_len + *p_ss_padding + /* data plus padding. */
2015 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2016 return data_len;
2018 default:
2019 smb_panic("bad auth level");
2020 /* Notreached. */
2021 return 0;
2025 /*******************************************************************
2026 External interface.
2027 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2028 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2029 and deals with signing/sealing details.
2030 ********************************************************************/
2032 struct rpc_api_pipe_req_state {
2033 struct event_context *ev;
2034 struct rpc_pipe_client *cli;
2035 uint8_t op_num;
2036 uint32_t call_id;
2037 prs_struct *req_data;
2038 uint32_t req_data_sent;
2039 prs_struct outgoing_frag;
2040 prs_struct reply_pdu;
2043 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2045 prs_mem_free(&s->outgoing_frag);
2046 prs_mem_free(&s->reply_pdu);
2047 return 0;
2050 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2051 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2052 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2053 bool *is_last_frag);
2055 struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2056 struct event_context *ev,
2057 struct rpc_pipe_client *cli,
2058 uint8_t op_num,
2059 prs_struct *req_data)
2061 struct async_req *result;
2062 struct tevent_req *subreq;
2063 struct rpc_api_pipe_req_state *state;
2064 NTSTATUS status;
2065 bool is_last_frag;
2067 if (!async_req_setup(mem_ctx, &result, &state,
2068 struct rpc_api_pipe_req_state)) {
2069 return NULL;
2071 state->ev = ev;
2072 state->cli = cli;
2073 state->op_num = op_num;
2074 state->req_data = req_data;
2075 state->req_data_sent = 0;
2076 state->call_id = get_rpc_call_id();
2078 if (cli->max_xmit_frag
2079 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2080 /* Server is screwed up ! */
2081 status = NT_STATUS_INVALID_PARAMETER;
2082 goto post_status;
2085 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2087 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2088 state, MARSHALL)) {
2089 goto fail;
2092 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2094 status = prepare_next_frag(state, &is_last_frag);
2095 if (!NT_STATUS_IS_OK(status)) {
2096 goto post_status;
2099 if (is_last_frag) {
2100 subreq = rpc_api_pipe_send(state, ev, state->cli,
2101 &state->outgoing_frag,
2102 RPC_RESPONSE);
2103 if (subreq == NULL) {
2104 goto fail;
2106 tevent_req_set_callback(subreq, rpc_api_pipe_req_done,
2107 result);
2108 } else {
2109 subreq = rpc_write_send(
2110 state, ev, cli->transport,
2111 (uint8_t *)prs_data_p(&state->outgoing_frag),
2112 prs_offset(&state->outgoing_frag));
2113 if (subreq == NULL) {
2114 goto fail;
2116 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2117 result);
2119 return result;
2121 post_status:
2122 if (async_post_ntstatus(result, ev, status)) {
2123 return result;
2125 fail:
2126 TALLOC_FREE(result);
2127 return NULL;
2130 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2131 bool *is_last_frag)
2133 RPC_HDR hdr;
2134 RPC_HDR_REQ hdr_req;
2135 uint32_t data_sent_thistime;
2136 uint16_t auth_len;
2137 uint16_t frag_len;
2138 uint8_t flags = 0;
2139 uint32_t ss_padding;
2140 uint32_t data_left;
2141 char pad[8] = { 0, };
2142 NTSTATUS status;
2144 data_left = prs_offset(state->req_data) - state->req_data_sent;
2146 data_sent_thistime = calculate_data_len_tosend(
2147 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2149 if (state->req_data_sent == 0) {
2150 flags = RPC_FLG_FIRST;
2153 if (data_sent_thistime == data_left) {
2154 flags |= RPC_FLG_LAST;
2157 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2158 return NT_STATUS_NO_MEMORY;
2161 /* Create and marshall the header and request header. */
2162 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2163 auth_len);
2165 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2166 return NT_STATUS_NO_MEMORY;
2169 /* Create the rpc request RPC_HDR_REQ */
2170 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2171 state->op_num);
2173 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2174 &state->outgoing_frag, 0)) {
2175 return NT_STATUS_NO_MEMORY;
2178 /* Copy in the data, plus any ss padding. */
2179 if (!prs_append_some_prs_data(&state->outgoing_frag,
2180 state->req_data, state->req_data_sent,
2181 data_sent_thistime)) {
2182 return NT_STATUS_NO_MEMORY;
2185 /* Copy the sign/seal padding data. */
2186 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2187 return NT_STATUS_NO_MEMORY;
2190 /* Generate any auth sign/seal and add the auth footer. */
2191 switch (state->cli->auth->auth_type) {
2192 case PIPE_AUTH_TYPE_NONE:
2193 status = NT_STATUS_OK;
2194 break;
2195 case PIPE_AUTH_TYPE_NTLMSSP:
2196 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2197 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2198 &state->outgoing_frag);
2199 break;
2200 case PIPE_AUTH_TYPE_SCHANNEL:
2201 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2202 &state->outgoing_frag);
2203 break;
2204 default:
2205 status = NT_STATUS_INVALID_PARAMETER;
2206 break;
2209 state->req_data_sent += data_sent_thistime;
2210 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2212 return status;
2215 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2217 struct async_req *req = tevent_req_callback_data(
2218 subreq, struct async_req);
2219 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2220 req->private_data, struct rpc_api_pipe_req_state);
2221 NTSTATUS status;
2222 bool is_last_frag;
2224 status = rpc_write_recv(subreq);
2225 TALLOC_FREE(subreq);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 async_req_nterror(req, status);
2228 return;
2231 status = prepare_next_frag(state, &is_last_frag);
2232 if (!NT_STATUS_IS_OK(status)) {
2233 async_req_nterror(req, status);
2234 return;
2237 if (is_last_frag) {
2238 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2239 &state->outgoing_frag,
2240 RPC_RESPONSE);
2241 if (async_req_nomem(subreq, req)) {
2242 return;
2244 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2245 } else {
2246 subreq = rpc_write_send(
2247 state, state->ev,
2248 state->cli->transport,
2249 (uint8_t *)prs_data_p(&state->outgoing_frag),
2250 prs_offset(&state->outgoing_frag));
2251 if (async_req_nomem(subreq, req)) {
2252 return;
2254 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2255 req);
2259 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2261 struct async_req *req = tevent_req_callback_data(
2262 subreq, struct async_req);
2263 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2264 req->private_data, struct rpc_api_pipe_req_state);
2265 NTSTATUS status;
2267 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2268 TALLOC_FREE(subreq);
2269 if (!NT_STATUS_IS_OK(status)) {
2270 async_req_nterror(req, status);
2271 return;
2273 async_req_done(req);
2276 NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
2277 prs_struct *reply_pdu)
2279 struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
2280 req->private_data, struct rpc_api_pipe_req_state);
2281 NTSTATUS status;
2283 if (async_req_is_nterror(req, &status)) {
2285 * We always have to initialize to reply pdu, even if there is
2286 * none. The rpccli_* caller routines expect this.
2288 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2289 return status;
2292 *reply_pdu = state->reply_pdu;
2293 reply_pdu->mem_ctx = mem_ctx;
2296 * Prevent state->req_pdu from being freed in
2297 * rpc_api_pipe_req_state_destructor()
2299 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2301 return NT_STATUS_OK;
2304 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
2305 uint8 op_num,
2306 prs_struct *in_data,
2307 prs_struct *out_data)
2309 TALLOC_CTX *frame = talloc_stackframe();
2310 struct event_context *ev;
2311 struct async_req *req;
2312 NTSTATUS status = NT_STATUS_NO_MEMORY;
2314 ev = event_context_init(frame);
2315 if (ev == NULL) {
2316 goto fail;
2319 req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
2320 if (req == NULL) {
2321 goto fail;
2324 while (req->state < ASYNC_REQ_DONE) {
2325 event_loop_once(ev);
2328 status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
2329 fail:
2330 TALLOC_FREE(frame);
2331 return status;
2334 #if 0
2335 /****************************************************************************
2336 Set the handle state.
2337 ****************************************************************************/
2339 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2340 const char *pipe_name, uint16 device_state)
2342 bool state_set = False;
2343 char param[2];
2344 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2345 char *rparam = NULL;
2346 char *rdata = NULL;
2347 uint32 rparam_len, rdata_len;
2349 if (pipe_name == NULL)
2350 return False;
2352 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2353 cli->fnum, pipe_name, device_state));
2355 /* create parameters: device state */
2356 SSVAL(param, 0, device_state);
2358 /* create setup parameters. */
2359 setup[0] = 0x0001;
2360 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2362 /* send the data on \PIPE\ */
2363 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2364 setup, 2, 0, /* setup, length, max */
2365 param, 2, 0, /* param, length, max */
2366 NULL, 0, 1024, /* data, length, max */
2367 &rparam, &rparam_len, /* return param, length */
2368 &rdata, &rdata_len)) /* return data, length */
2370 DEBUG(5, ("Set Handle state: return OK\n"));
2371 state_set = True;
2374 SAFE_FREE(rparam);
2375 SAFE_FREE(rdata);
2377 return state_set;
2379 #endif
2381 /****************************************************************************
2382 Check the rpc bind acknowledge response.
2383 ****************************************************************************/
2385 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2387 if ( hdr_ba->addr.len == 0) {
2388 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2391 /* check the transfer syntax */
2392 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2393 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2394 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2395 return False;
2398 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2399 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2400 hdr_ba->res.num_results, hdr_ba->res.reason));
2403 DEBUG(5,("check_bind_response: accepted!\n"));
2404 return True;
2407 /*******************************************************************
2408 Creates a DCE/RPC bind authentication response.
2409 This is the packet that is sent back to the server once we
2410 have received a BIND-ACK, to finish the third leg of
2411 the authentication handshake.
2412 ********************************************************************/
2414 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2415 uint32 rpc_call_id,
2416 enum pipe_auth_type auth_type,
2417 enum pipe_auth_level auth_level,
2418 DATA_BLOB *pauth_blob,
2419 prs_struct *rpc_out)
2421 RPC_HDR hdr;
2422 RPC_HDR_AUTH hdr_auth;
2423 uint32 pad = 0;
2425 /* Create the request RPC_HDR */
2426 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2427 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2428 pauth_blob->length );
2430 /* Marshall it. */
2431 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2432 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2433 return NT_STATUS_NO_MEMORY;
2437 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2438 about padding - shouldn't this pad to length 8 ? JRA.
2441 /* 4 bytes padding. */
2442 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2443 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2444 return NT_STATUS_NO_MEMORY;
2447 /* Create the request RPC_HDR_AUTHA */
2448 init_rpc_hdr_auth(&hdr_auth,
2449 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2450 auth_level, 0, 1);
2452 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2453 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2454 return NT_STATUS_NO_MEMORY;
2458 * Append the auth data to the outgoing buffer.
2461 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2462 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2463 return NT_STATUS_NO_MEMORY;
2466 return NT_STATUS_OK;
2469 /*******************************************************************
2470 Creates a DCE/RPC bind alter context authentication request which
2471 may contain a spnego auth blobl
2472 ********************************************************************/
2474 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2475 const RPC_IFACE *abstract,
2476 const RPC_IFACE *transfer,
2477 enum pipe_auth_level auth_level,
2478 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2479 prs_struct *rpc_out)
2481 RPC_HDR_AUTH hdr_auth;
2482 prs_struct auth_info;
2483 NTSTATUS ret = NT_STATUS_OK;
2485 ZERO_STRUCT(hdr_auth);
2486 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2487 return NT_STATUS_NO_MEMORY;
2489 /* We may change the pad length before marshalling. */
2490 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2492 if (pauth_blob->length) {
2493 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2494 prs_mem_free(&auth_info);
2495 return NT_STATUS_NO_MEMORY;
2499 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2500 rpc_out,
2501 rpc_call_id,
2502 abstract,
2503 transfer,
2504 &hdr_auth,
2505 &auth_info);
2506 prs_mem_free(&auth_info);
2507 return ret;
2510 /****************************************************************************
2511 Do an rpc bind.
2512 ****************************************************************************/
2514 struct rpc_pipe_bind_state {
2515 struct event_context *ev;
2516 struct rpc_pipe_client *cli;
2517 prs_struct rpc_out;
2518 uint32_t rpc_call_id;
2521 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2523 prs_mem_free(&state->rpc_out);
2524 return 0;
2527 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2528 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2529 struct rpc_pipe_bind_state *state,
2530 struct rpc_hdr_info *phdr,
2531 prs_struct *reply_pdu);
2532 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2533 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2534 struct rpc_pipe_bind_state *state,
2535 struct rpc_hdr_info *phdr,
2536 prs_struct *reply_pdu);
2537 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2539 struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2540 struct event_context *ev,
2541 struct rpc_pipe_client *cli,
2542 struct cli_pipe_auth_data *auth)
2544 struct async_req *result;
2545 struct tevent_req *subreq;
2546 struct rpc_pipe_bind_state *state;
2547 NTSTATUS status;
2549 if (!async_req_setup(mem_ctx, &result, &state,
2550 struct rpc_pipe_bind_state)) {
2551 return NULL;
2554 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2555 rpccli_pipe_txt(debug_ctx(), cli),
2556 (unsigned int)auth->auth_type,
2557 (unsigned int)auth->auth_level ));
2559 state->ev = ev;
2560 state->cli = cli;
2561 state->rpc_call_id = get_rpc_call_id();
2563 prs_init_empty(&state->rpc_out, state, MARSHALL);
2564 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2566 cli->auth = talloc_move(cli, &auth);
2568 /* Marshall the outgoing data. */
2569 status = create_rpc_bind_req(cli, &state->rpc_out,
2570 state->rpc_call_id,
2571 &cli->abstract_syntax,
2572 &cli->transfer_syntax,
2573 cli->auth->auth_type,
2574 cli->auth->auth_level);
2576 if (!NT_STATUS_IS_OK(status)) {
2577 goto post_status;
2580 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2581 RPC_BINDACK);
2582 if (subreq == NULL) {
2583 goto fail;
2585 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, result);
2586 return result;
2588 post_status:
2589 if (async_post_ntstatus(result, ev, status)) {
2590 return result;
2592 fail:
2593 TALLOC_FREE(result);
2594 return NULL;
2597 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2599 struct async_req *req = tevent_req_callback_data(
2600 subreq, struct async_req);
2601 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2602 req->private_data, struct rpc_pipe_bind_state);
2603 prs_struct reply_pdu;
2604 struct rpc_hdr_info hdr;
2605 struct rpc_hdr_ba_info hdr_ba;
2606 NTSTATUS status;
2608 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2609 TALLOC_FREE(subreq);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2612 rpccli_pipe_txt(debug_ctx(), state->cli),
2613 nt_errstr(status)));
2614 async_req_nterror(req, status);
2615 return;
2618 /* Unmarshall the RPC header */
2619 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2620 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2621 prs_mem_free(&reply_pdu);
2622 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2623 return;
2626 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2627 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2628 "RPC_HDR_BA.\n"));
2629 prs_mem_free(&reply_pdu);
2630 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2631 return;
2634 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2635 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2636 prs_mem_free(&reply_pdu);
2637 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2638 return;
2641 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2642 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2645 * For authenticated binds we may need to do 3 or 4 leg binds.
2648 switch(state->cli->auth->auth_type) {
2650 case PIPE_AUTH_TYPE_NONE:
2651 case PIPE_AUTH_TYPE_SCHANNEL:
2652 /* Bind complete. */
2653 prs_mem_free(&reply_pdu);
2654 async_req_done(req);
2655 break;
2657 case PIPE_AUTH_TYPE_NTLMSSP:
2658 /* Need to send AUTH3 packet - no reply. */
2659 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2660 &reply_pdu);
2661 prs_mem_free(&reply_pdu);
2662 if (!NT_STATUS_IS_OK(status)) {
2663 async_req_nterror(req, status);
2665 break;
2667 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2668 /* Need to send alter context request and reply. */
2669 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2670 &reply_pdu);
2671 prs_mem_free(&reply_pdu);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 async_req_nterror(req, status);
2675 break;
2677 case PIPE_AUTH_TYPE_KRB5:
2678 /* */
2680 default:
2681 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2682 (unsigned int)state->cli->auth->auth_type));
2683 prs_mem_free(&reply_pdu);
2684 async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2688 static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
2689 struct rpc_pipe_bind_state *state,
2690 struct rpc_hdr_info *phdr,
2691 prs_struct *reply_pdu)
2693 DATA_BLOB server_response = data_blob_null;
2694 DATA_BLOB client_reply = data_blob_null;
2695 struct rpc_hdr_auth_info hdr_auth;
2696 struct tevent_req *subreq;
2697 NTSTATUS status;
2699 if ((phdr->auth_len == 0)
2700 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2701 return NT_STATUS_INVALID_PARAMETER;
2704 if (!prs_set_offset(
2705 reply_pdu,
2706 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2707 return NT_STATUS_INVALID_PARAMETER;
2710 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2711 return NT_STATUS_INVALID_PARAMETER;
2714 /* TODO - check auth_type/auth_level match. */
2716 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2717 prs_copy_data_out((char *)server_response.data, reply_pdu,
2718 phdr->auth_len);
2720 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2721 server_response, &client_reply);
2723 if (!NT_STATUS_IS_OK(status)) {
2724 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2725 "blob failed: %s.\n", nt_errstr(status)));
2726 return status;
2729 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2731 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2732 state->cli->auth->auth_type,
2733 state->cli->auth->auth_level,
2734 &client_reply, &state->rpc_out);
2735 data_blob_free(&client_reply);
2737 if (!NT_STATUS_IS_OK(status)) {
2738 return status;
2741 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2742 (uint8_t *)prs_data_p(&state->rpc_out),
2743 prs_offset(&state->rpc_out));
2744 if (subreq == NULL) {
2745 return NT_STATUS_NO_MEMORY;
2747 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2748 return NT_STATUS_OK;
2751 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2753 struct async_req *req = tevent_req_callback_data(
2754 subreq, struct async_req);
2755 NTSTATUS status;
2757 status = rpc_write_recv(subreq);
2758 TALLOC_FREE(subreq);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 async_req_nterror(req, status);
2761 return;
2763 async_req_done(req);
2766 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
2767 struct rpc_pipe_bind_state *state,
2768 struct rpc_hdr_info *phdr,
2769 prs_struct *reply_pdu)
2771 DATA_BLOB server_spnego_response = data_blob_null;
2772 DATA_BLOB server_ntlm_response = data_blob_null;
2773 DATA_BLOB client_reply = data_blob_null;
2774 DATA_BLOB tmp_blob = data_blob_null;
2775 RPC_HDR_AUTH hdr_auth;
2776 struct tevent_req *subreq;
2777 NTSTATUS status;
2779 if ((phdr->auth_len == 0)
2780 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2781 return NT_STATUS_INVALID_PARAMETER;
2784 /* Process the returned NTLMSSP blob first. */
2785 if (!prs_set_offset(
2786 reply_pdu,
2787 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2788 return NT_STATUS_INVALID_PARAMETER;
2791 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2792 return NT_STATUS_INVALID_PARAMETER;
2795 server_spnego_response = data_blob(NULL, phdr->auth_len);
2796 prs_copy_data_out((char *)server_spnego_response.data,
2797 reply_pdu, phdr->auth_len);
2800 * The server might give us back two challenges - tmp_blob is for the
2801 * second.
2803 if (!spnego_parse_challenge(server_spnego_response,
2804 &server_ntlm_response, &tmp_blob)) {
2805 data_blob_free(&server_spnego_response);
2806 data_blob_free(&server_ntlm_response);
2807 data_blob_free(&tmp_blob);
2808 return NT_STATUS_INVALID_PARAMETER;
2811 /* We're finished with the server spnego response and the tmp_blob. */
2812 data_blob_free(&server_spnego_response);
2813 data_blob_free(&tmp_blob);
2815 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2816 server_ntlm_response, &client_reply);
2818 /* Finished with the server_ntlm response */
2819 data_blob_free(&server_ntlm_response);
2821 if (!NT_STATUS_IS_OK(status)) {
2822 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2823 "using server blob failed.\n"));
2824 data_blob_free(&client_reply);
2825 return status;
2828 /* SPNEGO wrap the client reply. */
2829 tmp_blob = spnego_gen_auth(client_reply);
2830 data_blob_free(&client_reply);
2831 client_reply = tmp_blob;
2832 tmp_blob = data_blob_null;
2834 /* Now prepare the alter context pdu. */
2835 prs_init_empty(&state->rpc_out, state, MARSHALL);
2837 status = create_rpc_alter_context(state->rpc_call_id,
2838 &state->cli->abstract_syntax,
2839 &state->cli->transfer_syntax,
2840 state->cli->auth->auth_level,
2841 &client_reply,
2842 &state->rpc_out);
2843 data_blob_free(&client_reply);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 return status;
2849 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2850 &state->rpc_out, RPC_ALTCONTRESP);
2851 if (subreq == NULL) {
2852 return NT_STATUS_NO_MEMORY;
2854 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2855 return NT_STATUS_OK;
2858 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2860 struct async_req *req = tevent_req_callback_data(
2861 subreq, struct async_req);
2862 struct rpc_pipe_bind_state *state = talloc_get_type_abort(
2863 req->private_data, struct rpc_pipe_bind_state);
2864 DATA_BLOB server_spnego_response = data_blob_null;
2865 DATA_BLOB tmp_blob = data_blob_null;
2866 prs_struct reply_pdu;
2867 struct rpc_hdr_info hdr;
2868 struct rpc_hdr_auth_info hdr_auth;
2869 NTSTATUS status;
2871 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2872 TALLOC_FREE(subreq);
2873 if (!NT_STATUS_IS_OK(status)) {
2874 async_req_nterror(req, status);
2875 return;
2878 /* Get the auth blob from the reply. */
2879 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2880 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2881 "unmarshall RPC_HDR.\n"));
2882 async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2883 return;
2886 if (!prs_set_offset(
2887 &reply_pdu,
2888 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2889 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2890 return;
2893 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2894 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2895 return;
2898 server_spnego_response = data_blob(NULL, hdr.auth_len);
2899 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2900 hdr.auth_len);
2902 /* Check we got a valid auth response. */
2903 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2904 OID_NTLMSSP, &tmp_blob)) {
2905 data_blob_free(&server_spnego_response);
2906 data_blob_free(&tmp_blob);
2907 async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2908 return;
2911 data_blob_free(&server_spnego_response);
2912 data_blob_free(&tmp_blob);
2914 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2915 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2916 async_req_done(req);
2919 NTSTATUS rpc_pipe_bind_recv(struct async_req *req)
2921 return async_req_simple_recv_ntstatus(req);
2924 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2925 struct cli_pipe_auth_data *auth)
2927 TALLOC_CTX *frame = talloc_stackframe();
2928 struct event_context *ev;
2929 struct async_req *req;
2930 NTSTATUS status = NT_STATUS_NO_MEMORY;
2932 ev = event_context_init(frame);
2933 if (ev == NULL) {
2934 goto fail;
2937 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2938 if (req == NULL) {
2939 goto fail;
2942 while (req->state < ASYNC_REQ_DONE) {
2943 event_loop_once(ev);
2946 status = rpc_pipe_bind_recv(req);
2947 fail:
2948 TALLOC_FREE(frame);
2949 return status;
2952 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2953 unsigned int timeout)
2955 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2957 if (cli == NULL) {
2958 return 0;
2960 return cli_set_timeout(cli, timeout);
2963 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2965 struct cli_state *cli;
2967 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2968 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2969 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2970 return true;
2973 cli = rpc_pipe_np_smb_conn(rpc_cli);
2974 if (cli == NULL) {
2975 return false;
2977 E_md4hash(cli->password ? cli->password : "", nt_hash);
2978 return true;
2981 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2982 struct cli_pipe_auth_data **presult)
2984 struct cli_pipe_auth_data *result;
2986 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2987 if (result == NULL) {
2988 return NT_STATUS_NO_MEMORY;
2991 result->auth_type = PIPE_AUTH_TYPE_NONE;
2992 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2994 result->user_name = talloc_strdup(result, "");
2995 result->domain = talloc_strdup(result, "");
2996 if ((result->user_name == NULL) || (result->domain == NULL)) {
2997 TALLOC_FREE(result);
2998 return NT_STATUS_NO_MEMORY;
3001 *presult = result;
3002 return NT_STATUS_OK;
3005 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3007 ntlmssp_end(&auth->a_u.ntlmssp_state);
3008 return 0;
3011 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3012 enum pipe_auth_type auth_type,
3013 enum pipe_auth_level auth_level,
3014 const char *domain,
3015 const char *username,
3016 const char *password,
3017 struct cli_pipe_auth_data **presult)
3019 struct cli_pipe_auth_data *result;
3020 NTSTATUS status;
3022 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3023 if (result == NULL) {
3024 return NT_STATUS_NO_MEMORY;
3027 result->auth_type = auth_type;
3028 result->auth_level = auth_level;
3030 result->user_name = talloc_strdup(result, username);
3031 result->domain = talloc_strdup(result, domain);
3032 if ((result->user_name == NULL) || (result->domain == NULL)) {
3033 status = NT_STATUS_NO_MEMORY;
3034 goto fail;
3037 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3038 if (!NT_STATUS_IS_OK(status)) {
3039 goto fail;
3042 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3044 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3045 if (!NT_STATUS_IS_OK(status)) {
3046 goto fail;
3049 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 goto fail;
3054 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 goto fail;
3060 * Turn off sign+seal to allow selected auth level to turn it back on.
3062 result->a_u.ntlmssp_state->neg_flags &=
3063 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3065 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
3066 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3067 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
3068 result->a_u.ntlmssp_state->neg_flags
3069 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3072 *presult = result;
3073 return NT_STATUS_OK;
3075 fail:
3076 TALLOC_FREE(result);
3077 return status;
3080 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3081 enum pipe_auth_level auth_level,
3082 const uint8_t sess_key[16],
3083 struct cli_pipe_auth_data **presult)
3085 struct cli_pipe_auth_data *result;
3087 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3088 if (result == NULL) {
3089 return NT_STATUS_NO_MEMORY;
3092 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3093 result->auth_level = auth_level;
3095 result->user_name = talloc_strdup(result, "");
3096 result->domain = talloc_strdup(result, domain);
3097 if ((result->user_name == NULL) || (result->domain == NULL)) {
3098 goto fail;
3101 result->a_u.schannel_auth = talloc(result,
3102 struct schannel_auth_struct);
3103 if (result->a_u.schannel_auth == NULL) {
3104 goto fail;
3107 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3108 sizeof(result->a_u.schannel_auth->sess_key));
3109 result->a_u.schannel_auth->seq_num = 0;
3111 *presult = result;
3112 return NT_STATUS_OK;
3114 fail:
3115 TALLOC_FREE(result);
3116 return NT_STATUS_NO_MEMORY;
3119 #ifdef HAVE_KRB5
3120 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3122 data_blob_free(&auth->session_key);
3123 return 0;
3125 #endif
3127 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3128 enum pipe_auth_level auth_level,
3129 const char *service_princ,
3130 const char *username,
3131 const char *password,
3132 struct cli_pipe_auth_data **presult)
3134 #ifdef HAVE_KRB5
3135 struct cli_pipe_auth_data *result;
3137 if ((username != NULL) && (password != NULL)) {
3138 int ret = kerberos_kinit_password(username, password, 0, NULL);
3139 if (ret != 0) {
3140 return NT_STATUS_ACCESS_DENIED;
3144 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3145 if (result == NULL) {
3146 return NT_STATUS_NO_MEMORY;
3149 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3150 result->auth_level = auth_level;
3153 * Username / domain need fixing!
3155 result->user_name = talloc_strdup(result, "");
3156 result->domain = talloc_strdup(result, "");
3157 if ((result->user_name == NULL) || (result->domain == NULL)) {
3158 goto fail;
3161 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3162 result, struct kerberos_auth_struct);
3163 if (result->a_u.kerberos_auth == NULL) {
3164 goto fail;
3166 talloc_set_destructor(result->a_u.kerberos_auth,
3167 cli_auth_kerberos_data_destructor);
3169 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3170 result, service_princ);
3171 if (result->a_u.kerberos_auth->service_principal == NULL) {
3172 goto fail;
3175 *presult = result;
3176 return NT_STATUS_OK;
3178 fail:
3179 TALLOC_FREE(result);
3180 return NT_STATUS_NO_MEMORY;
3181 #else
3182 return NT_STATUS_NOT_SUPPORTED;
3183 #endif
3187 * Create an rpc pipe client struct, connecting to a tcp port.
3189 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3190 uint16_t port,
3191 const struct ndr_syntax_id *abstract_syntax,
3192 struct rpc_pipe_client **presult)
3194 struct rpc_pipe_client *result;
3195 struct sockaddr_storage addr;
3196 NTSTATUS status;
3197 int fd;
3199 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3200 if (result == NULL) {
3201 return NT_STATUS_NO_MEMORY;
3204 result->abstract_syntax = *abstract_syntax;
3205 result->transfer_syntax = ndr_transfer_syntax;
3206 result->dispatch = cli_do_rpc_ndr;
3208 result->desthost = talloc_strdup(result, host);
3209 result->srv_name_slash = talloc_asprintf_strupper_m(
3210 result, "\\\\%s", result->desthost);
3211 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3212 status = NT_STATUS_NO_MEMORY;
3213 goto fail;
3216 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3217 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3219 if (!resolve_name(host, &addr, 0)) {
3220 status = NT_STATUS_NOT_FOUND;
3221 goto fail;
3224 status = open_socket_out(&addr, port, 60, &fd);
3225 if (!NT_STATUS_IS_OK(status)) {
3226 goto fail;
3228 set_socket_options(fd, lp_socket_options());
3230 status = rpc_transport_sock_init(result, fd, &result->transport);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 close(fd);
3233 goto fail;
3236 *presult = result;
3237 return NT_STATUS_OK;
3239 fail:
3240 TALLOC_FREE(result);
3241 return status;
3245 * Determine the tcp port on which a dcerpc interface is listening
3246 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3247 * target host.
3249 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3250 const struct ndr_syntax_id *abstract_syntax,
3251 uint16_t *pport)
3253 NTSTATUS status;
3254 struct rpc_pipe_client *epm_pipe = NULL;
3255 struct cli_pipe_auth_data *auth = NULL;
3256 struct dcerpc_binding *map_binding = NULL;
3257 struct dcerpc_binding *res_binding = NULL;
3258 struct epm_twr_t *map_tower = NULL;
3259 struct epm_twr_t *res_towers = NULL;
3260 struct policy_handle *entry_handle = NULL;
3261 uint32_t num_towers = 0;
3262 uint32_t max_towers = 1;
3263 struct epm_twr_p_t towers;
3264 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3266 if (pport == NULL) {
3267 status = NT_STATUS_INVALID_PARAMETER;
3268 goto done;
3271 /* open the connection to the endpoint mapper */
3272 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3273 &ndr_table_epmapper.syntax_id,
3274 &epm_pipe);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 goto done;
3280 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 goto done;
3285 status = rpc_pipe_bind(epm_pipe, auth);
3286 if (!NT_STATUS_IS_OK(status)) {
3287 goto done;
3290 /* create tower for asking the epmapper */
3292 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3293 if (map_binding == NULL) {
3294 status = NT_STATUS_NO_MEMORY;
3295 goto done;
3298 map_binding->transport = NCACN_IP_TCP;
3299 map_binding->object = *abstract_syntax;
3300 map_binding->host = host; /* needed? */
3301 map_binding->endpoint = "0"; /* correct? needed? */
3303 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3304 if (map_tower == NULL) {
3305 status = NT_STATUS_NO_MEMORY;
3306 goto done;
3309 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3310 &(map_tower->tower));
3311 if (!NT_STATUS_IS_OK(status)) {
3312 goto done;
3315 /* allocate further parameters for the epm_Map call */
3317 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3318 if (res_towers == NULL) {
3319 status = NT_STATUS_NO_MEMORY;
3320 goto done;
3322 towers.twr = res_towers;
3324 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3325 if (entry_handle == NULL) {
3326 status = NT_STATUS_NO_MEMORY;
3327 goto done;
3330 /* ask the endpoint mapper for the port */
3332 status = rpccli_epm_Map(epm_pipe,
3333 tmp_ctx,
3334 CONST_DISCARD(struct GUID *,
3335 &(abstract_syntax->uuid)),
3336 map_tower,
3337 entry_handle,
3338 max_towers,
3339 &num_towers,
3340 &towers);
3342 if (!NT_STATUS_IS_OK(status)) {
3343 goto done;
3346 if (num_towers != 1) {
3347 status = NT_STATUS_UNSUCCESSFUL;
3348 goto done;
3351 /* extract the port from the answer */
3353 status = dcerpc_binding_from_tower(tmp_ctx,
3354 &(towers.twr->tower),
3355 &res_binding);
3356 if (!NT_STATUS_IS_OK(status)) {
3357 goto done;
3360 /* are further checks here necessary? */
3361 if (res_binding->transport != NCACN_IP_TCP) {
3362 status = NT_STATUS_UNSUCCESSFUL;
3363 goto done;
3366 *pport = (uint16_t)atoi(res_binding->endpoint);
3368 done:
3369 TALLOC_FREE(tmp_ctx);
3370 return status;
3374 * Create a rpc pipe client struct, connecting to a host via tcp.
3375 * The port is determined by asking the endpoint mapper on the given
3376 * host.
3378 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3379 const struct ndr_syntax_id *abstract_syntax,
3380 struct rpc_pipe_client **presult)
3382 NTSTATUS status;
3383 uint16_t port = 0;
3385 *presult = NULL;
3387 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3388 if (!NT_STATUS_IS_OK(status)) {
3389 goto done;
3392 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3393 abstract_syntax, presult);
3395 done:
3396 return status;
3399 /********************************************************************
3400 Create a rpc pipe client struct, connecting to a unix domain socket
3401 ********************************************************************/
3402 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3403 const struct ndr_syntax_id *abstract_syntax,
3404 struct rpc_pipe_client **presult)
3406 struct rpc_pipe_client *result;
3407 struct sockaddr_un addr;
3408 NTSTATUS status;
3409 int fd;
3411 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3412 if (result == NULL) {
3413 return NT_STATUS_NO_MEMORY;
3416 result->abstract_syntax = *abstract_syntax;
3417 result->transfer_syntax = ndr_transfer_syntax;
3418 result->dispatch = cli_do_rpc_ndr;
3420 result->desthost = get_myname(result);
3421 result->srv_name_slash = talloc_asprintf_strupper_m(
3422 result, "\\\\%s", result->desthost);
3423 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3424 status = NT_STATUS_NO_MEMORY;
3425 goto fail;
3428 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3429 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3431 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3432 if (fd == -1) {
3433 status = map_nt_error_from_unix(errno);
3434 goto fail;
3437 ZERO_STRUCT(addr);
3438 addr.sun_family = AF_UNIX;
3439 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3441 if (sys_connect(fd, (struct sockaddr *)&addr) == -1) {
3442 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3443 strerror(errno)));
3444 close(fd);
3445 return map_nt_error_from_unix(errno);
3448 status = rpc_transport_sock_init(result, fd, &result->transport);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 close(fd);
3451 goto fail;
3454 *presult = result;
3455 return NT_STATUS_OK;
3457 fail:
3458 TALLOC_FREE(result);
3459 return status;
3462 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3464 struct cli_state *cli;
3466 cli = rpc_pipe_np_smb_conn(p);
3467 if (cli != NULL) {
3468 DLIST_REMOVE(cli->pipe_list, p);
3470 return 0;
3473 /****************************************************************************
3474 Open a named pipe over SMB to a remote server.
3476 * CAVEAT CALLER OF THIS FUNCTION:
3477 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3478 * so be sure that this function is called AFTER any structure (vs pointer)
3479 * assignment of the cli. In particular, libsmbclient does structure
3480 * assignments of cli, which invalidates the data in the returned
3481 * rpc_pipe_client if this function is called before the structure assignment
3482 * of cli.
3484 ****************************************************************************/
3486 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3487 const struct ndr_syntax_id *abstract_syntax,
3488 struct rpc_pipe_client **presult)
3490 struct rpc_pipe_client *result;
3491 NTSTATUS status;
3493 /* sanity check to protect against crashes */
3495 if ( !cli ) {
3496 return NT_STATUS_INVALID_HANDLE;
3499 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3500 if (result == NULL) {
3501 return NT_STATUS_NO_MEMORY;
3504 result->abstract_syntax = *abstract_syntax;
3505 result->transfer_syntax = ndr_transfer_syntax;
3506 result->dispatch = cli_do_rpc_ndr;
3507 result->desthost = talloc_strdup(result, cli->desthost);
3508 result->srv_name_slash = talloc_asprintf_strupper_m(
3509 result, "\\\\%s", result->desthost);
3511 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3512 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3514 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3515 TALLOC_FREE(result);
3516 return NT_STATUS_NO_MEMORY;
3519 status = rpc_transport_np_init(result, cli, abstract_syntax,
3520 &result->transport);
3521 if (!NT_STATUS_IS_OK(status)) {
3522 TALLOC_FREE(result);
3523 return status;
3526 DLIST_ADD(cli->pipe_list, result);
3527 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3529 *presult = result;
3530 return NT_STATUS_OK;
3533 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3534 struct rpc_cli_smbd_conn *conn,
3535 const struct ndr_syntax_id *syntax,
3536 struct rpc_pipe_client **presult)
3538 struct rpc_pipe_client *result;
3539 struct cli_pipe_auth_data *auth;
3540 NTSTATUS status;
3542 result = talloc(mem_ctx, struct rpc_pipe_client);
3543 if (result == NULL) {
3544 return NT_STATUS_NO_MEMORY;
3546 result->abstract_syntax = *syntax;
3547 result->transfer_syntax = ndr_transfer_syntax;
3548 result->dispatch = cli_do_rpc_ndr;
3549 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3550 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3552 result->desthost = talloc_strdup(result, global_myname());
3553 result->srv_name_slash = talloc_asprintf_strupper_m(
3554 result, "\\\\%s", global_myname());
3555 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3556 TALLOC_FREE(result);
3557 return NT_STATUS_NO_MEMORY;
3560 status = rpc_transport_smbd_init(result, conn, syntax,
3561 &result->transport);
3562 if (!NT_STATUS_IS_OK(status)) {
3563 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3564 nt_errstr(status)));
3565 TALLOC_FREE(result);
3566 return status;
3569 status = rpccli_anon_bind_data(result, &auth);
3570 if (!NT_STATUS_IS_OK(status)) {
3571 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3572 nt_errstr(status)));
3573 TALLOC_FREE(result);
3574 return status;
3577 status = rpc_pipe_bind(result, auth);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3580 TALLOC_FREE(result);
3581 return status;
3584 *presult = result;
3585 return NT_STATUS_OK;
3588 /****************************************************************************
3589 Open a pipe to a remote server.
3590 ****************************************************************************/
3592 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3593 const struct ndr_syntax_id *interface,
3594 struct rpc_pipe_client **presult)
3596 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3598 * We should have a better way to figure out this drsuapi
3599 * speciality...
3601 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3602 presult);
3605 return rpc_pipe_open_np(cli, interface, presult);
3608 /****************************************************************************
3609 Open a named pipe to an SMB server and bind anonymously.
3610 ****************************************************************************/
3612 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3613 const struct ndr_syntax_id *interface,
3614 struct rpc_pipe_client **presult)
3616 struct rpc_pipe_client *result;
3617 struct cli_pipe_auth_data *auth;
3618 NTSTATUS status;
3620 status = cli_rpc_pipe_open(cli, interface, &result);
3621 if (!NT_STATUS_IS_OK(status)) {
3622 return status;
3625 status = rpccli_anon_bind_data(result, &auth);
3626 if (!NT_STATUS_IS_OK(status)) {
3627 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3628 nt_errstr(status)));
3629 TALLOC_FREE(result);
3630 return status;
3634 * This is a bit of an abstraction violation due to the fact that an
3635 * anonymous bind on an authenticated SMB inherits the user/domain
3636 * from the enclosing SMB creds
3639 TALLOC_FREE(auth->user_name);
3640 TALLOC_FREE(auth->domain);
3642 auth->user_name = talloc_strdup(auth, cli->user_name);
3643 auth->domain = talloc_strdup(auth, cli->domain);
3644 auth->user_session_key = data_blob_talloc(auth,
3645 cli->user_session_key.data,
3646 cli->user_session_key.length);
3648 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3649 TALLOC_FREE(result);
3650 return NT_STATUS_NO_MEMORY;
3653 status = rpc_pipe_bind(result, auth);
3654 if (!NT_STATUS_IS_OK(status)) {
3655 int lvl = 0;
3656 if (ndr_syntax_id_equal(interface,
3657 &ndr_table_dssetup.syntax_id)) {
3658 /* non AD domains just don't have this pipe, avoid
3659 * level 0 statement in that case - gd */
3660 lvl = 3;
3662 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3663 "%s failed with error %s\n",
3664 get_pipe_name_from_iface(interface),
3665 nt_errstr(status) ));
3666 TALLOC_FREE(result);
3667 return status;
3670 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3671 "%s and bound anonymously.\n",
3672 get_pipe_name_from_iface(interface), cli->desthost));
3674 *presult = result;
3675 return NT_STATUS_OK;
3678 /****************************************************************************
3679 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3680 ****************************************************************************/
3682 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3683 const struct ndr_syntax_id *interface,
3684 enum pipe_auth_type auth_type,
3685 enum pipe_auth_level auth_level,
3686 const char *domain,
3687 const char *username,
3688 const char *password,
3689 struct rpc_pipe_client **presult)
3691 struct rpc_pipe_client *result;
3692 struct cli_pipe_auth_data *auth;
3693 NTSTATUS status;
3695 status = cli_rpc_pipe_open(cli, interface, &result);
3696 if (!NT_STATUS_IS_OK(status)) {
3697 return status;
3700 status = rpccli_ntlmssp_bind_data(
3701 result, auth_type, auth_level, domain, username,
3702 password, &auth);
3703 if (!NT_STATUS_IS_OK(status)) {
3704 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3705 nt_errstr(status)));
3706 goto err;
3709 status = rpc_pipe_bind(result, auth);
3710 if (!NT_STATUS_IS_OK(status)) {
3711 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3712 nt_errstr(status) ));
3713 goto err;
3716 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3717 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3718 get_pipe_name_from_iface(interface), cli->desthost, domain,
3719 username ));
3721 *presult = result;
3722 return NT_STATUS_OK;
3724 err:
3726 TALLOC_FREE(result);
3727 return status;
3730 /****************************************************************************
3731 External interface.
3732 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3733 ****************************************************************************/
3735 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3736 const struct ndr_syntax_id *interface,
3737 enum pipe_auth_level auth_level,
3738 const char *domain,
3739 const char *username,
3740 const char *password,
3741 struct rpc_pipe_client **presult)
3743 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3744 interface,
3745 PIPE_AUTH_TYPE_NTLMSSP,
3746 auth_level,
3747 domain,
3748 username,
3749 password,
3750 presult);
3753 /****************************************************************************
3754 External interface.
3755 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3756 ****************************************************************************/
3758 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3759 const struct ndr_syntax_id *interface,
3760 enum pipe_auth_level auth_level,
3761 const char *domain,
3762 const char *username,
3763 const char *password,
3764 struct rpc_pipe_client **presult)
3766 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3767 interface,
3768 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3769 auth_level,
3770 domain,
3771 username,
3772 password,
3773 presult);
3776 /****************************************************************************
3777 Get a the schannel session key out of an already opened netlogon pipe.
3778 ****************************************************************************/
3779 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3780 struct cli_state *cli,
3781 const char *domain,
3782 uint32 *pneg_flags)
3784 uint32 sec_chan_type = 0;
3785 unsigned char machine_pwd[16];
3786 const char *machine_account;
3787 NTSTATUS status;
3789 /* Get the machine account credentials from secrets.tdb. */
3790 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3791 &sec_chan_type))
3793 DEBUG(0, ("get_schannel_session_key: could not fetch "
3794 "trust account password for domain '%s'\n",
3795 domain));
3796 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3799 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3800 cli->desthost, /* server name */
3801 domain, /* domain */
3802 global_myname(), /* client name */
3803 machine_account, /* machine account name */
3804 machine_pwd,
3805 sec_chan_type,
3806 pneg_flags);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(3, ("get_schannel_session_key_common: "
3810 "rpccli_netlogon_setup_creds failed with result %s "
3811 "to server %s, domain %s, machine account %s.\n",
3812 nt_errstr(status), cli->desthost, domain,
3813 machine_account ));
3814 return status;
3817 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3818 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3819 cli->desthost));
3820 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3823 return NT_STATUS_OK;;
3826 /****************************************************************************
3827 Open a netlogon pipe and get the schannel session key.
3828 Now exposed to external callers.
3829 ****************************************************************************/
3832 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3833 const char *domain,
3834 uint32 *pneg_flags,
3835 struct rpc_pipe_client **presult)
3837 struct rpc_pipe_client *netlogon_pipe = NULL;
3838 NTSTATUS status;
3840 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3841 &netlogon_pipe);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 return status;
3846 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3847 pneg_flags);
3848 if (!NT_STATUS_IS_OK(status)) {
3849 TALLOC_FREE(netlogon_pipe);
3850 return status;
3853 *presult = netlogon_pipe;
3854 return NT_STATUS_OK;
3857 /****************************************************************************
3858 External interface.
3859 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3860 using session_key. sign and seal.
3861 ****************************************************************************/
3863 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3864 const struct ndr_syntax_id *interface,
3865 enum pipe_auth_level auth_level,
3866 const char *domain,
3867 const struct dcinfo *pdc,
3868 struct rpc_pipe_client **presult)
3870 struct rpc_pipe_client *result;
3871 struct cli_pipe_auth_data *auth;
3872 NTSTATUS status;
3874 status = cli_rpc_pipe_open(cli, interface, &result);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 return status;
3879 status = rpccli_schannel_bind_data(result, domain, auth_level,
3880 pdc->sess_key, &auth);
3881 if (!NT_STATUS_IS_OK(status)) {
3882 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3883 nt_errstr(status)));
3884 TALLOC_FREE(result);
3885 return status;
3888 status = rpc_pipe_bind(result, auth);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3891 "cli_rpc_pipe_bind failed with error %s\n",
3892 nt_errstr(status) ));
3893 TALLOC_FREE(result);
3894 return status;
3898 * The credentials on a new netlogon pipe are the ones we are passed
3899 * in - copy them over.
3901 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3902 if (result->dc == NULL) {
3903 DEBUG(0, ("talloc failed\n"));
3904 TALLOC_FREE(result);
3905 return NT_STATUS_NO_MEMORY;
3908 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3909 "for domain %s and bound using schannel.\n",
3910 get_pipe_name_from_iface(interface),
3911 cli->desthost, domain ));
3913 *presult = result;
3914 return NT_STATUS_OK;
3917 /****************************************************************************
3918 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3919 Fetch the session key ourselves using a temporary netlogon pipe. This
3920 version uses an ntlmssp auth bound netlogon pipe to get the key.
3921 ****************************************************************************/
3923 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3924 const char *domain,
3925 const char *username,
3926 const char *password,
3927 uint32 *pneg_flags,
3928 struct rpc_pipe_client **presult)
3930 struct rpc_pipe_client *netlogon_pipe = NULL;
3931 NTSTATUS status;
3933 status = cli_rpc_pipe_open_spnego_ntlmssp(
3934 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3935 domain, username, password, &netlogon_pipe);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 return status;
3940 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3941 pneg_flags);
3942 if (!NT_STATUS_IS_OK(status)) {
3943 TALLOC_FREE(netlogon_pipe);
3944 return status;
3947 *presult = netlogon_pipe;
3948 return NT_STATUS_OK;
3951 /****************************************************************************
3952 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3953 Fetch the session key ourselves using a temporary netlogon pipe. This version
3954 uses an ntlmssp bind to get the session key.
3955 ****************************************************************************/
3957 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3958 const struct ndr_syntax_id *interface,
3959 enum pipe_auth_level auth_level,
3960 const char *domain,
3961 const char *username,
3962 const char *password,
3963 struct rpc_pipe_client **presult)
3965 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3966 struct rpc_pipe_client *netlogon_pipe = NULL;
3967 struct rpc_pipe_client *result = NULL;
3968 NTSTATUS status;
3970 status = get_schannel_session_key_auth_ntlmssp(
3971 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3974 "key from server %s for domain %s.\n",
3975 cli->desthost, domain ));
3976 return status;
3979 status = cli_rpc_pipe_open_schannel_with_key(
3980 cli, interface, auth_level, domain, netlogon_pipe->dc,
3981 &result);
3983 /* Now we've bound using the session key we can close the netlog pipe. */
3984 TALLOC_FREE(netlogon_pipe);
3986 if (NT_STATUS_IS_OK(status)) {
3987 *presult = result;
3989 return status;
3992 /****************************************************************************
3993 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3994 Fetch the session key ourselves using a temporary netlogon pipe.
3995 ****************************************************************************/
3997 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3998 const struct ndr_syntax_id *interface,
3999 enum pipe_auth_level auth_level,
4000 const char *domain,
4001 struct rpc_pipe_client **presult)
4003 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4004 struct rpc_pipe_client *netlogon_pipe = NULL;
4005 struct rpc_pipe_client *result = NULL;
4006 NTSTATUS status;
4008 status = get_schannel_session_key(cli, domain, &neg_flags,
4009 &netlogon_pipe);
4010 if (!NT_STATUS_IS_OK(status)) {
4011 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4012 "key from server %s for domain %s.\n",
4013 cli->desthost, domain ));
4014 return status;
4017 status = cli_rpc_pipe_open_schannel_with_key(
4018 cli, interface, auth_level, domain, netlogon_pipe->dc,
4019 &result);
4021 /* Now we've bound using the session key we can close the netlog pipe. */
4022 TALLOC_FREE(netlogon_pipe);
4024 if (NT_STATUS_IS_OK(status)) {
4025 *presult = result;
4028 return NT_STATUS_OK;
4031 /****************************************************************************
4032 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4033 The idea is this can be called with service_princ, username and password all
4034 NULL so long as the caller has a TGT.
4035 ****************************************************************************/
4037 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4038 const struct ndr_syntax_id *interface,
4039 enum pipe_auth_level auth_level,
4040 const char *service_princ,
4041 const char *username,
4042 const char *password,
4043 struct rpc_pipe_client **presult)
4045 #ifdef HAVE_KRB5
4046 struct rpc_pipe_client *result;
4047 struct cli_pipe_auth_data *auth;
4048 NTSTATUS status;
4050 status = cli_rpc_pipe_open(cli, interface, &result);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 return status;
4055 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4056 username, password, &auth);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4059 nt_errstr(status)));
4060 TALLOC_FREE(result);
4061 return status;
4064 status = rpc_pipe_bind(result, auth);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4067 "with error %s\n", nt_errstr(status)));
4068 TALLOC_FREE(result);
4069 return status;
4072 *presult = result;
4073 return NT_STATUS_OK;
4074 #else
4075 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4076 return NT_STATUS_NOT_IMPLEMENTED;
4077 #endif
4080 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4081 struct rpc_pipe_client *cli,
4082 DATA_BLOB *session_key)
4084 if (!session_key || !cli) {
4085 return NT_STATUS_INVALID_PARAMETER;
4088 if (!cli->auth) {
4089 return NT_STATUS_INVALID_PARAMETER;
4092 switch (cli->auth->auth_type) {
4093 case PIPE_AUTH_TYPE_SCHANNEL:
4094 *session_key = data_blob_talloc(mem_ctx,
4095 cli->auth->a_u.schannel_auth->sess_key, 16);
4096 break;
4097 case PIPE_AUTH_TYPE_NTLMSSP:
4098 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4099 *session_key = data_blob_talloc(mem_ctx,
4100 cli->auth->a_u.ntlmssp_state->session_key.data,
4101 cli->auth->a_u.ntlmssp_state->session_key.length);
4102 break;
4103 case PIPE_AUTH_TYPE_KRB5:
4104 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4105 *session_key = data_blob_talloc(mem_ctx,
4106 cli->auth->a_u.kerberos_auth->session_key.data,
4107 cli->auth->a_u.kerberos_auth->session_key.length);
4108 break;
4109 case PIPE_AUTH_TYPE_NONE:
4110 *session_key = data_blob_talloc(mem_ctx,
4111 cli->auth->user_session_key.data,
4112 cli->auth->user_session_key.length);
4113 break;
4114 default:
4115 return NT_STATUS_NO_USER_SESSION_KEY;
4118 return NT_STATUS_OK;