tdb: allow reads after prepare commit
[Samba/aatanasov.git] / source3 / rpc_client / cli_pipe.c
bloba667a9fb13afb9c4a968c8beb8b03e0ee1edf391
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_CLI
28 /*******************************************************************
29 interface/version dce/rpc pipe identification
30 ********************************************************************/
32 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
33 #define PIPE_SAMR "\\PIPE\\samr"
34 #define PIPE_WINREG "\\PIPE\\winreg"
35 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
36 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
37 #define PIPE_NTLSA "\\PIPE\\ntlsa"
38 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
39 #define PIPE_LSASS "\\PIPE\\lsass"
40 #define PIPE_LSARPC "\\PIPE\\lsarpc"
41 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
42 #define PIPE_NETDFS "\\PIPE\\netdfs"
43 #define PIPE_ECHO "\\PIPE\\rpcecho"
44 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
45 #define PIPE_EPM "\\PIPE\\epmapper"
46 #define PIPE_SVCCTL "\\PIPE\\svcctl"
47 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
48 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
49 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
52 * IMPORTANT!! If you update this structure, make sure to
53 * update the index #defines in smb.h.
56 static const struct pipe_id_info {
57 /* the names appear not to matter: the syntaxes _do_ matter */
59 const char *client_pipe;
60 const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
61 } pipe_names [] =
63 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
64 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
65 { PIPE_SAMR, &ndr_table_samr.syntax_id },
66 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
67 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
68 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
69 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
70 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
71 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
72 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
73 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
74 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
75 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
76 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
77 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
78 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
79 { NULL, NULL }
82 /****************************************************************************
83 Return the pipe name from the interface.
84 ****************************************************************************/
86 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
88 char *guid_str;
89 const char *result;
90 int i;
91 for (i = 0; pipe_names[i].client_pipe; i++) {
92 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
93 interface)) {
94 return &pipe_names[i].client_pipe[5];
99 * Here we should ask \\epmapper, but for now our code is only
100 * interested in the known pipes mentioned in pipe_names[]
103 guid_str = GUID_string(talloc_tos(), &interface->uuid);
104 if (guid_str == NULL) {
105 return NULL;
107 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
108 (int)interface->if_version);
109 TALLOC_FREE(guid_str);
111 if (result == NULL) {
112 return "PIPE";
114 return result;
117 /********************************************************************
118 Map internal value to wire value.
119 ********************************************************************/
121 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
123 switch (auth_type) {
125 case PIPE_AUTH_TYPE_NONE:
126 return DCERPC_AUTH_TYPE_NONE;
128 case PIPE_AUTH_TYPE_NTLMSSP:
129 return DCERPC_AUTH_TYPE_NTLMSSP;
131 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
132 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
133 return DCERPC_AUTH_TYPE_SPNEGO;
135 case PIPE_AUTH_TYPE_SCHANNEL:
136 return DCERPC_AUTH_TYPE_SCHANNEL;
138 case PIPE_AUTH_TYPE_KRB5:
139 return DCERPC_AUTH_TYPE_KRB5;
141 default:
142 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
143 "auth type %u\n",
144 (unsigned int)auth_type ));
145 break;
147 return -1;
150 /********************************************************************
151 Pipe description for a DEBUG
152 ********************************************************************/
153 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
154 struct rpc_pipe_client *cli)
156 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
157 if (result == NULL) {
158 return "pipe";
160 return result;
163 /********************************************************************
164 Rpc pipe call id.
165 ********************************************************************/
167 static uint32 get_rpc_call_id(void)
169 static uint32 call_id = 0;
170 return ++call_id;
174 * Realloc pdu to have a least "size" bytes
177 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
179 size_t extra_size;
181 if (prs_data_size(pdu) >= size) {
182 return true;
185 extra_size = size - prs_data_size(pdu);
187 if (!prs_force_grow(pdu, extra_size)) {
188 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
189 "%d bytes.\n", (int)extra_size));
190 return false;
193 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
194 (int)extra_size, prs_data_size(pdu)));
195 return true;
199 /*******************************************************************
200 Use SMBreadX to get rest of one fragment's worth of rpc data.
201 Reads the whole size or give an error message
202 ********************************************************************/
204 struct rpc_read_state {
205 struct event_context *ev;
206 struct rpc_cli_transport *transport;
207 uint8_t *data;
208 size_t size;
209 size_t num_read;
212 static void rpc_read_done(struct tevent_req *subreq);
214 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
215 struct event_context *ev,
216 struct rpc_cli_transport *transport,
217 uint8_t *data, size_t size)
219 struct tevent_req *req, *subreq;
220 struct rpc_read_state *state;
222 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
223 if (req == NULL) {
224 return NULL;
226 state->ev = ev;
227 state->transport = transport;
228 state->data = data;
229 state->size = size;
230 state->num_read = 0;
232 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
234 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
235 transport->priv);
236 if (subreq == NULL) {
237 goto fail;
239 tevent_req_set_callback(subreq, rpc_read_done, req);
240 return req;
242 fail:
243 TALLOC_FREE(req);
244 return NULL;
247 static void rpc_read_done(struct tevent_req *subreq)
249 struct tevent_req *req = tevent_req_callback_data(
250 subreq, 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 tevent_req_set_callback(subreq, rpc_read_done, req);
279 static NTSTATUS rpc_read_recv(struct tevent_req *req)
281 return tevent_req_simple_recv_ntstatus(req);
284 struct rpc_write_state {
285 struct event_context *ev;
286 struct rpc_cli_transport *transport;
287 const uint8_t *data;
288 size_t size;
289 size_t num_written;
292 static void rpc_write_done(struct tevent_req *subreq);
294 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
295 struct event_context *ev,
296 struct rpc_cli_transport *transport,
297 const uint8_t *data, size_t size)
299 struct tevent_req *req, *subreq;
300 struct rpc_write_state *state;
302 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
303 if (req == NULL) {
304 return NULL;
306 state->ev = ev;
307 state->transport = transport;
308 state->data = data;
309 state->size = size;
310 state->num_written = 0;
312 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
314 subreq = transport->write_send(state, ev, data, size, transport->priv);
315 if (subreq == NULL) {
316 goto fail;
318 tevent_req_set_callback(subreq, rpc_write_done, req);
319 return req;
320 fail:
321 TALLOC_FREE(req);
322 return NULL;
325 static void rpc_write_done(struct tevent_req *subreq)
327 struct tevent_req *req = tevent_req_callback_data(
328 subreq, struct tevent_req);
329 struct rpc_write_state *state = tevent_req_data(
330 req, struct rpc_write_state);
331 NTSTATUS status;
332 ssize_t written;
334 status = state->transport->write_recv(subreq, &written);
335 TALLOC_FREE(subreq);
336 if (!NT_STATUS_IS_OK(status)) {
337 tevent_req_nterror(req, status);
338 return;
341 state->num_written += written;
343 if (state->num_written == state->size) {
344 tevent_req_done(req);
345 return;
348 subreq = state->transport->write_send(state, state->ev,
349 state->data + state->num_written,
350 state->size - state->num_written,
351 state->transport->priv);
352 if (tevent_req_nomem(subreq, req)) {
353 return;
355 tevent_req_set_callback(subreq, rpc_write_done, req);
358 static NTSTATUS rpc_write_recv(struct tevent_req *req)
360 return tevent_req_simple_recv_ntstatus(req);
364 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
365 struct rpc_hdr_info *prhdr,
366 prs_struct *pdu)
369 * This next call sets the endian bit correctly in current_pdu. We
370 * will propagate this to rbuf later.
373 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
374 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
375 return NT_STATUS_BUFFER_TOO_SMALL;
378 if (prhdr->frag_len > cli->max_recv_frag) {
379 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
380 " we only allow %d\n", (int)prhdr->frag_len,
381 (int)cli->max_recv_frag));
382 return NT_STATUS_BUFFER_TOO_SMALL;
385 return NT_STATUS_OK;
388 /****************************************************************************
389 Try and get a PDU's worth of data from current_pdu. If not, then read more
390 from the wire.
391 ****************************************************************************/
393 struct get_complete_frag_state {
394 struct event_context *ev;
395 struct rpc_pipe_client *cli;
396 struct rpc_hdr_info *prhdr;
397 prs_struct *pdu;
400 static void get_complete_frag_got_header(struct tevent_req *subreq);
401 static void get_complete_frag_got_rest(struct tevent_req *subreq);
403 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
404 struct event_context *ev,
405 struct rpc_pipe_client *cli,
406 struct rpc_hdr_info *prhdr,
407 prs_struct *pdu)
409 struct tevent_req *req, *subreq;
410 struct get_complete_frag_state *state;
411 uint32_t pdu_len;
412 NTSTATUS status;
414 req = tevent_req_create(mem_ctx, &state,
415 struct get_complete_frag_state);
416 if (req == NULL) {
417 return NULL;
419 state->ev = ev;
420 state->cli = cli;
421 state->prhdr = prhdr;
422 state->pdu = pdu;
424 pdu_len = prs_data_size(pdu);
425 if (pdu_len < RPC_HEADER_LEN) {
426 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
427 status = NT_STATUS_NO_MEMORY;
428 goto post_status;
430 subreq = rpc_read_send(
431 state, state->ev,
432 state->cli->transport,
433 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
434 RPC_HEADER_LEN - pdu_len);
435 if (subreq == NULL) {
436 status = NT_STATUS_NO_MEMORY;
437 goto post_status;
439 tevent_req_set_callback(subreq, get_complete_frag_got_header,
440 req);
441 return req;
444 status = parse_rpc_header(cli, prhdr, pdu);
445 if (!NT_STATUS_IS_OK(status)) {
446 goto post_status;
450 * Ensure we have frag_len bytes of data.
452 if (pdu_len < prhdr->frag_len) {
453 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
454 status = NT_STATUS_NO_MEMORY;
455 goto post_status;
457 subreq = rpc_read_send(state, state->ev,
458 state->cli->transport,
459 (uint8_t *)(prs_data_p(pdu) + pdu_len),
460 prhdr->frag_len - pdu_len);
461 if (subreq == NULL) {
462 status = NT_STATUS_NO_MEMORY;
463 goto post_status;
465 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
466 req);
467 return req;
470 status = NT_STATUS_OK;
471 post_status:
472 if (NT_STATUS_IS_OK(status)) {
473 tevent_req_done(req);
474 } else {
475 tevent_req_nterror(req, status);
477 return tevent_req_post(req, ev);
480 static void get_complete_frag_got_header(struct tevent_req *subreq)
482 struct tevent_req *req = tevent_req_callback_data(
483 subreq, struct tevent_req);
484 struct get_complete_frag_state *state = tevent_req_data(
485 req, struct get_complete_frag_state);
486 NTSTATUS status;
488 status = rpc_read_recv(subreq);
489 TALLOC_FREE(subreq);
490 if (!NT_STATUS_IS_OK(status)) {
491 tevent_req_nterror(req, status);
492 return;
495 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
496 if (!NT_STATUS_IS_OK(status)) {
497 tevent_req_nterror(req, status);
498 return;
501 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
502 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
503 return;
507 * We're here in this piece of code because we've read exactly
508 * RPC_HEADER_LEN bytes into state->pdu.
511 subreq = rpc_read_send(
512 state, state->ev, state->cli->transport,
513 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
514 state->prhdr->frag_len - RPC_HEADER_LEN);
515 if (tevent_req_nomem(subreq, req)) {
516 return;
518 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
521 static void get_complete_frag_got_rest(struct tevent_req *subreq)
523 struct tevent_req *req = tevent_req_callback_data(
524 subreq, struct tevent_req);
525 NTSTATUS status;
527 status = rpc_read_recv(subreq);
528 TALLOC_FREE(subreq);
529 if (!NT_STATUS_IS_OK(status)) {
530 tevent_req_nterror(req, status);
531 return;
533 tevent_req_done(req);
536 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
538 return tevent_req_simple_recv_ntstatus(req);
541 /****************************************************************************
542 NTLMSSP specific sign/seal.
543 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
544 In fact I should probably abstract these into identical pieces of code... JRA.
545 ****************************************************************************/
547 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
548 prs_struct *current_pdu,
549 uint8 *p_ss_padding_len)
551 RPC_HDR_AUTH auth_info;
552 uint32 save_offset = prs_offset(current_pdu);
553 uint32 auth_len = prhdr->auth_len;
554 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
555 unsigned char *data = NULL;
556 size_t data_len;
557 unsigned char *full_packet_data = NULL;
558 size_t full_packet_data_len;
559 DATA_BLOB auth_blob;
560 NTSTATUS status;
562 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
563 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
564 return NT_STATUS_OK;
567 if (!ntlmssp_state) {
568 return NT_STATUS_INVALID_PARAMETER;
571 /* Ensure there's enough data for an authenticated response. */
572 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
573 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
574 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
575 (unsigned int)auth_len ));
576 return NT_STATUS_BUFFER_TOO_SMALL;
580 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
581 * after the RPC header.
582 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
583 * functions as NTLMv2 checks the rpc headers also.
586 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
587 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
589 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
590 full_packet_data_len = prhdr->frag_len - auth_len;
592 /* Pull the auth header and the following data into a blob. */
593 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
594 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
595 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
596 return NT_STATUS_BUFFER_TOO_SMALL;
599 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
600 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
601 return NT_STATUS_BUFFER_TOO_SMALL;
604 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
605 auth_blob.length = auth_len;
607 switch (cli->auth->auth_level) {
608 case DCERPC_AUTH_LEVEL_PRIVACY:
609 /* Data is encrypted. */
610 status = ntlmssp_unseal_packet(ntlmssp_state,
611 data, data_len,
612 full_packet_data,
613 full_packet_data_len,
614 &auth_blob);
615 if (!NT_STATUS_IS_OK(status)) {
616 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
617 "packet from %s. Error was %s.\n",
618 rpccli_pipe_txt(debug_ctx(), cli),
619 nt_errstr(status) ));
620 return status;
622 break;
623 case DCERPC_AUTH_LEVEL_INTEGRITY:
624 /* Data is signed. */
625 status = ntlmssp_check_packet(ntlmssp_state,
626 data, data_len,
627 full_packet_data,
628 full_packet_data_len,
629 &auth_blob);
630 if (!NT_STATUS_IS_OK(status)) {
631 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
632 "packet from %s. Error was %s.\n",
633 rpccli_pipe_txt(debug_ctx(), cli),
634 nt_errstr(status) ));
635 return status;
637 break;
638 default:
639 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
640 "auth level %d\n", cli->auth->auth_level));
641 return NT_STATUS_INVALID_INFO_CLASS;
645 * Return the current pointer to the data offset.
648 if(!prs_set_offset(current_pdu, save_offset)) {
649 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
650 (unsigned int)save_offset ));
651 return NT_STATUS_BUFFER_TOO_SMALL;
655 * Remember the padding length. We must remove it from the real data
656 * stream once the sign/seal is done.
659 *p_ss_padding_len = auth_info.auth_pad_len;
661 return NT_STATUS_OK;
664 /****************************************************************************
665 schannel specific sign/seal.
666 ****************************************************************************/
668 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
669 prs_struct *current_pdu,
670 uint8 *p_ss_padding_len)
672 RPC_HDR_AUTH auth_info;
673 struct NL_AUTH_SIGNATURE schannel_chk;
674 uint32 auth_len = prhdr->auth_len;
675 uint32 save_offset = prs_offset(current_pdu);
676 struct schannel_auth_struct *schannel_auth =
677 cli->auth->a_u.schannel_auth;
678 uint32 data_len;
679 enum ndr_err_code ndr_err;
680 DATA_BLOB blob;
682 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
683 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
684 return NT_STATUS_OK;
687 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
688 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
689 return NT_STATUS_INVALID_PARAMETER;
692 if (!schannel_auth) {
693 return NT_STATUS_INVALID_PARAMETER;
696 /* Ensure there's enough data for an authenticated response. */
697 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
698 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
699 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
700 (unsigned int)auth_len ));
701 return NT_STATUS_INVALID_PARAMETER;
704 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
706 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
707 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
708 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
709 return NT_STATUS_BUFFER_TOO_SMALL;
712 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
713 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
714 return NT_STATUS_BUFFER_TOO_SMALL;
717 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
718 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
719 auth_info.auth_type));
720 return NT_STATUS_BUFFER_TOO_SMALL;
723 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), data_len);
725 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &schannel_chk,
726 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_SIGNATURE);
727 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
728 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
729 return ndr_map_error2ntstatus(ndr_err);
732 if (DEBUGLEVEL >= 10) {
733 NDR_PRINT_DEBUG(NL_AUTH_SIGNATURE, &schannel_chk);
736 if (!schannel_decode(schannel_auth,
737 cli->auth->auth_level,
738 SENDER_IS_ACCEPTOR,
739 &schannel_chk,
740 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
741 data_len)) {
742 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
743 "Connection to %s.\n",
744 rpccli_pipe_txt(debug_ctx(), cli)));
745 return NT_STATUS_INVALID_PARAMETER;
748 /* The sequence number gets incremented on both send and receive. */
749 schannel_auth->seq_num++;
752 * Return the current pointer to the data offset.
755 if(!prs_set_offset(current_pdu, save_offset)) {
756 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
757 (unsigned int)save_offset ));
758 return NT_STATUS_BUFFER_TOO_SMALL;
762 * Remember the padding length. We must remove it from the real data
763 * stream once the sign/seal is done.
766 *p_ss_padding_len = auth_info.auth_pad_len;
768 return NT_STATUS_OK;
771 /****************************************************************************
772 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
773 ****************************************************************************/
775 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
776 prs_struct *current_pdu,
777 uint8 *p_ss_padding_len)
779 NTSTATUS ret = NT_STATUS_OK;
781 /* Paranioa checks for auth_len. */
782 if (prhdr->auth_len) {
783 if (prhdr->auth_len > prhdr->frag_len) {
784 return NT_STATUS_INVALID_PARAMETER;
787 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
788 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
789 /* Integer wrap attempt. */
790 return NT_STATUS_INVALID_PARAMETER;
795 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
798 switch(cli->auth->auth_type) {
799 case PIPE_AUTH_TYPE_NONE:
800 if (prhdr->auth_len) {
801 DEBUG(3, ("cli_pipe_validate_rpc_response: "
802 "Connection to %s - got non-zero "
803 "auth len %u.\n",
804 rpccli_pipe_txt(debug_ctx(), cli),
805 (unsigned int)prhdr->auth_len ));
806 return NT_STATUS_INVALID_PARAMETER;
808 break;
810 case PIPE_AUTH_TYPE_NTLMSSP:
811 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
812 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
813 if (!NT_STATUS_IS_OK(ret)) {
814 return ret;
816 break;
818 case PIPE_AUTH_TYPE_SCHANNEL:
819 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
820 if (!NT_STATUS_IS_OK(ret)) {
821 return ret;
823 break;
825 case PIPE_AUTH_TYPE_KRB5:
826 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
827 default:
828 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
829 "to %s - unknown internal auth type %u.\n",
830 rpccli_pipe_txt(debug_ctx(), cli),
831 cli->auth->auth_type ));
832 return NT_STATUS_INVALID_INFO_CLASS;
835 return NT_STATUS_OK;
838 /****************************************************************************
839 Do basic authentication checks on an incoming pdu.
840 ****************************************************************************/
842 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
843 prs_struct *current_pdu,
844 uint8 expected_pkt_type,
845 char **ppdata,
846 uint32 *pdata_len,
847 prs_struct *return_data)
850 NTSTATUS ret = NT_STATUS_OK;
851 uint32 current_pdu_len = prs_data_size(current_pdu);
853 if (current_pdu_len != prhdr->frag_len) {
854 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
855 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
856 return NT_STATUS_INVALID_PARAMETER;
860 * Point the return values at the real data including the RPC
861 * header. Just in case the caller wants it.
863 *ppdata = prs_data_p(current_pdu);
864 *pdata_len = current_pdu_len;
866 /* Ensure we have the correct type. */
867 switch (prhdr->pkt_type) {
868 case RPC_ALTCONTRESP:
869 case RPC_BINDACK:
871 /* Alter context and bind ack share the same packet definitions. */
872 break;
875 case RPC_RESPONSE:
877 RPC_HDR_RESP rhdr_resp;
878 uint8 ss_padding_len = 0;
880 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
881 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
882 return NT_STATUS_BUFFER_TOO_SMALL;
885 /* Here's where we deal with incoming sign/seal. */
886 ret = cli_pipe_validate_rpc_response(cli, prhdr,
887 current_pdu, &ss_padding_len);
888 if (!NT_STATUS_IS_OK(ret)) {
889 return ret;
892 /* Point the return values at the NDR data. Remember to remove any ss padding. */
893 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
895 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
896 return NT_STATUS_BUFFER_TOO_SMALL;
899 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
901 /* Remember to remove the auth footer. */
902 if (prhdr->auth_len) {
903 /* We've already done integer wrap tests on auth_len in
904 cli_pipe_validate_rpc_response(). */
905 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
906 return NT_STATUS_BUFFER_TOO_SMALL;
908 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
911 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
912 current_pdu_len, *pdata_len, ss_padding_len ));
915 * If this is the first reply, and the allocation hint is reasonably, try and
916 * set up the return_data parse_struct to the correct size.
919 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
920 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
921 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
922 "too large to allocate\n",
923 (unsigned int)rhdr_resp.alloc_hint ));
924 return NT_STATUS_NO_MEMORY;
928 break;
931 case RPC_BINDNACK:
932 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
933 "received from %s!\n",
934 rpccli_pipe_txt(debug_ctx(), cli)));
935 /* Use this for now... */
936 return NT_STATUS_NETWORK_ACCESS_DENIED;
938 case RPC_FAULT:
940 RPC_HDR_RESP rhdr_resp;
941 RPC_HDR_FAULT fault_resp;
943 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
944 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
945 return NT_STATUS_BUFFER_TOO_SMALL;
948 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
949 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
950 return NT_STATUS_BUFFER_TOO_SMALL;
953 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
954 "code %s received from %s!\n",
955 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
956 rpccli_pipe_txt(debug_ctx(), cli)));
957 if (NT_STATUS_IS_OK(fault_resp.status)) {
958 return NT_STATUS_UNSUCCESSFUL;
959 } else {
960 return fault_resp.status;
964 default:
965 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
966 "from %s!\n",
967 (unsigned int)prhdr->pkt_type,
968 rpccli_pipe_txt(debug_ctx(), cli)));
969 return NT_STATUS_INVALID_INFO_CLASS;
972 if (prhdr->pkt_type != expected_pkt_type) {
973 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
974 "got an unexpected RPC packet type - %u, not %u\n",
975 rpccli_pipe_txt(debug_ctx(), cli),
976 prhdr->pkt_type,
977 expected_pkt_type));
978 return NT_STATUS_INVALID_INFO_CLASS;
981 /* Do this just before return - we don't want to modify any rpc header
982 data before now as we may have needed to do cryptographic actions on
983 it before. */
985 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
986 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
987 "setting fragment first/last ON.\n"));
988 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
991 return NT_STATUS_OK;
994 /****************************************************************************
995 Ensure we eat the just processed pdu from the current_pdu prs_struct.
996 Normally the frag_len and buffer size will match, but on the first trans
997 reply there is a theoretical chance that buffer size > frag_len, so we must
998 deal with that.
999 ****************************************************************************/
1001 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1003 uint32 current_pdu_len = prs_data_size(current_pdu);
1005 if (current_pdu_len < prhdr->frag_len) {
1006 return NT_STATUS_BUFFER_TOO_SMALL;
1009 /* Common case. */
1010 if (current_pdu_len == (uint32)prhdr->frag_len) {
1011 prs_mem_free(current_pdu);
1012 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1013 /* Make current_pdu dynamic with no memory. */
1014 prs_give_memory(current_pdu, 0, 0, True);
1015 return NT_STATUS_OK;
1019 * Oh no ! More data in buffer than we processed in current pdu.
1020 * Cheat. Move the data down and shrink the buffer.
1023 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1024 current_pdu_len - prhdr->frag_len);
1026 /* Remember to set the read offset back to zero. */
1027 prs_set_offset(current_pdu, 0);
1029 /* Shrink the buffer. */
1030 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1031 return NT_STATUS_BUFFER_TOO_SMALL;
1034 return NT_STATUS_OK;
1037 /****************************************************************************
1038 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1039 ****************************************************************************/
1041 struct cli_api_pipe_state {
1042 struct event_context *ev;
1043 struct rpc_cli_transport *transport;
1044 uint8_t *rdata;
1045 uint32_t rdata_len;
1048 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1049 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1050 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1052 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1053 struct event_context *ev,
1054 struct rpc_cli_transport *transport,
1055 uint8_t *data, size_t data_len,
1056 uint32_t max_rdata_len)
1058 struct tevent_req *req, *subreq;
1059 struct cli_api_pipe_state *state;
1060 NTSTATUS status;
1062 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1063 if (req == NULL) {
1064 return NULL;
1066 state->ev = ev;
1067 state->transport = transport;
1069 if (max_rdata_len < RPC_HEADER_LEN) {
1071 * For a RPC reply we always need at least RPC_HEADER_LEN
1072 * bytes. We check this here because we will receive
1073 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1075 status = NT_STATUS_INVALID_PARAMETER;
1076 goto post_status;
1079 if (transport->trans_send != NULL) {
1080 subreq = transport->trans_send(state, ev, data, data_len,
1081 max_rdata_len, transport->priv);
1082 if (subreq == NULL) {
1083 goto fail;
1085 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1086 return req;
1090 * If the transport does not provide a "trans" routine, i.e. for
1091 * example the ncacn_ip_tcp transport, do the write/read step here.
1094 subreq = rpc_write_send(state, ev, transport, data, data_len);
1095 if (subreq == NULL) {
1096 goto fail;
1098 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1099 return req;
1101 status = NT_STATUS_INVALID_PARAMETER;
1103 post_status:
1104 tevent_req_nterror(req, status);
1105 return tevent_req_post(req, ev);
1106 fail:
1107 TALLOC_FREE(req);
1108 return NULL;
1111 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1113 struct tevent_req *req = tevent_req_callback_data(
1114 subreq, struct tevent_req);
1115 struct cli_api_pipe_state *state = tevent_req_data(
1116 req, struct cli_api_pipe_state);
1117 NTSTATUS status;
1119 status = state->transport->trans_recv(subreq, state, &state->rdata,
1120 &state->rdata_len);
1121 TALLOC_FREE(subreq);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 tevent_req_nterror(req, status);
1124 return;
1126 tevent_req_done(req);
1129 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1131 struct tevent_req *req = tevent_req_callback_data(
1132 subreq, struct tevent_req);
1133 struct cli_api_pipe_state *state = tevent_req_data(
1134 req, struct cli_api_pipe_state);
1135 NTSTATUS status;
1137 status = rpc_write_recv(subreq);
1138 TALLOC_FREE(subreq);
1139 if (!NT_STATUS_IS_OK(status)) {
1140 tevent_req_nterror(req, status);
1141 return;
1144 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1145 if (tevent_req_nomem(state->rdata, req)) {
1146 return;
1150 * We don't need to use rpc_read_send here, the upper layer will cope
1151 * with a short read, transport->trans_send could also return less
1152 * than state->max_rdata_len.
1154 subreq = state->transport->read_send(state, state->ev, state->rdata,
1155 RPC_HEADER_LEN,
1156 state->transport->priv);
1157 if (tevent_req_nomem(subreq, req)) {
1158 return;
1160 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1163 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1165 struct tevent_req *req = tevent_req_callback_data(
1166 subreq, struct tevent_req);
1167 struct cli_api_pipe_state *state = tevent_req_data(
1168 req, struct cli_api_pipe_state);
1169 NTSTATUS status;
1170 ssize_t received;
1172 status = state->transport->read_recv(subreq, &received);
1173 TALLOC_FREE(subreq);
1174 if (!NT_STATUS_IS_OK(status)) {
1175 tevent_req_nterror(req, status);
1176 return;
1178 state->rdata_len = received;
1179 tevent_req_done(req);
1182 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1183 uint8_t **prdata, uint32_t *prdata_len)
1185 struct cli_api_pipe_state *state = tevent_req_data(
1186 req, struct cli_api_pipe_state);
1187 NTSTATUS status;
1189 if (tevent_req_is_nterror(req, &status)) {
1190 return status;
1193 *prdata = talloc_move(mem_ctx, &state->rdata);
1194 *prdata_len = state->rdata_len;
1195 return NT_STATUS_OK;
1198 /****************************************************************************
1199 Send data on an rpc pipe via trans. The prs_struct data must be the last
1200 pdu fragment of an NDR data stream.
1202 Receive response data from an rpc pipe, which may be large...
1204 Read the first fragment: unfortunately have to use SMBtrans for the first
1205 bit, then SMBreadX for subsequent bits.
1207 If first fragment received also wasn't the last fragment, continue
1208 getting fragments until we _do_ receive the last fragment.
1210 Request/Response PDU's look like the following...
1212 |<------------------PDU len----------------------------------------------->|
1213 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1215 +------------+-----------------+-------------+---------------+-------------+
1216 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1217 +------------+-----------------+-------------+---------------+-------------+
1219 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1220 signing & sealing being negotiated.
1222 ****************************************************************************/
1224 struct rpc_api_pipe_state {
1225 struct event_context *ev;
1226 struct rpc_pipe_client *cli;
1227 uint8_t expected_pkt_type;
1229 prs_struct incoming_frag;
1230 struct rpc_hdr_info rhdr;
1232 prs_struct incoming_pdu; /* Incoming reply */
1233 uint32_t incoming_pdu_offset;
1236 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1238 prs_mem_free(&state->incoming_frag);
1239 prs_mem_free(&state->incoming_pdu);
1240 return 0;
1243 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1244 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1246 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1247 struct event_context *ev,
1248 struct rpc_pipe_client *cli,
1249 prs_struct *data, /* Outgoing PDU */
1250 uint8_t expected_pkt_type)
1252 struct tevent_req *req, *subreq;
1253 struct rpc_api_pipe_state *state;
1254 uint16_t max_recv_frag;
1255 NTSTATUS status;
1257 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1258 if (req == NULL) {
1259 return NULL;
1261 state->ev = ev;
1262 state->cli = cli;
1263 state->expected_pkt_type = expected_pkt_type;
1264 state->incoming_pdu_offset = 0;
1266 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1268 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1269 /* Make incoming_pdu dynamic with no memory. */
1270 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1272 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1275 * Ensure we're not sending too much.
1277 if (prs_offset(data) > cli->max_xmit_frag) {
1278 status = NT_STATUS_INVALID_PARAMETER;
1279 goto post_status;
1282 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1284 max_recv_frag = cli->max_recv_frag;
1286 #ifdef DEVELOPER
1287 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1288 #endif
1290 subreq = cli_api_pipe_send(state, ev, cli->transport,
1291 (uint8_t *)prs_data_p(data),
1292 prs_offset(data), max_recv_frag);
1293 if (subreq == NULL) {
1294 goto fail;
1296 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1297 return req;
1299 post_status:
1300 tevent_req_nterror(req, status);
1301 return tevent_req_post(req, ev);
1302 fail:
1303 TALLOC_FREE(req);
1304 return NULL;
1307 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1309 struct tevent_req *req = tevent_req_callback_data(
1310 subreq, struct tevent_req);
1311 struct rpc_api_pipe_state *state = tevent_req_data(
1312 req, struct rpc_api_pipe_state);
1313 NTSTATUS status;
1314 uint8_t *rdata = NULL;
1315 uint32_t rdata_len = 0;
1316 char *rdata_copy;
1318 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1319 TALLOC_FREE(subreq);
1320 if (!NT_STATUS_IS_OK(status)) {
1321 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1322 tevent_req_nterror(req, status);
1323 return;
1326 if (rdata == NULL) {
1327 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1328 rpccli_pipe_txt(debug_ctx(), state->cli)));
1329 tevent_req_done(req);
1330 return;
1334 * Give the memory received from cli_trans as dynamic to the current
1335 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1336 * :-(
1338 rdata_copy = (char *)memdup(rdata, rdata_len);
1339 TALLOC_FREE(rdata);
1340 if (tevent_req_nomem(rdata_copy, req)) {
1341 return;
1343 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1345 /* Ensure we have enough data for a pdu. */
1346 subreq = get_complete_frag_send(state, state->ev, state->cli,
1347 &state->rhdr, &state->incoming_frag);
1348 if (tevent_req_nomem(subreq, req)) {
1349 return;
1351 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1354 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1356 struct tevent_req *req = tevent_req_callback_data(
1357 subreq, struct tevent_req);
1358 struct rpc_api_pipe_state *state = tevent_req_data(
1359 req, struct rpc_api_pipe_state);
1360 NTSTATUS status;
1361 char *rdata = NULL;
1362 uint32_t rdata_len = 0;
1364 status = get_complete_frag_recv(subreq);
1365 TALLOC_FREE(subreq);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 DEBUG(5, ("get_complete_frag failed: %s\n",
1368 nt_errstr(status)));
1369 tevent_req_nterror(req, status);
1370 return;
1373 status = cli_pipe_validate_current_pdu(
1374 state->cli, &state->rhdr, &state->incoming_frag,
1375 state->expected_pkt_type, &rdata, &rdata_len,
1376 &state->incoming_pdu);
1378 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1379 (unsigned)prs_data_size(&state->incoming_frag),
1380 (unsigned)state->incoming_pdu_offset,
1381 nt_errstr(status)));
1383 if (!NT_STATUS_IS_OK(status)) {
1384 tevent_req_nterror(req, status);
1385 return;
1388 if ((state->rhdr.flags & RPC_FLG_FIRST)
1389 && (state->rhdr.pack_type[0] == 0)) {
1391 * Set the data type correctly for big-endian data on the
1392 * first packet.
1394 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1395 "big-endian.\n",
1396 rpccli_pipe_txt(debug_ctx(), state->cli)));
1397 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1400 * Check endianness on subsequent packets.
1402 if (state->incoming_frag.bigendian_data
1403 != state->incoming_pdu.bigendian_data) {
1404 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1405 "%s\n",
1406 state->incoming_pdu.bigendian_data?"big":"little",
1407 state->incoming_frag.bigendian_data?"big":"little"));
1408 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1409 return;
1412 /* Now copy the data portion out of the pdu into rbuf. */
1413 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1414 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1415 return;
1418 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1419 rdata, (size_t)rdata_len);
1420 state->incoming_pdu_offset += rdata_len;
1422 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1423 &state->incoming_frag);
1424 if (!NT_STATUS_IS_OK(status)) {
1425 tevent_req_nterror(req, status);
1426 return;
1429 if (state->rhdr.flags & RPC_FLG_LAST) {
1430 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1431 rpccli_pipe_txt(debug_ctx(), state->cli),
1432 (unsigned)prs_data_size(&state->incoming_pdu)));
1433 tevent_req_done(req);
1434 return;
1437 subreq = get_complete_frag_send(state, state->ev, state->cli,
1438 &state->rhdr, &state->incoming_frag);
1439 if (tevent_req_nomem(subreq, req)) {
1440 return;
1442 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1445 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1446 prs_struct *reply_pdu)
1448 struct rpc_api_pipe_state *state = tevent_req_data(
1449 req, struct rpc_api_pipe_state);
1450 NTSTATUS status;
1452 if (tevent_req_is_nterror(req, &status)) {
1453 return status;
1456 *reply_pdu = state->incoming_pdu;
1457 reply_pdu->mem_ctx = mem_ctx;
1460 * Prevent state->incoming_pdu from being freed in
1461 * rpc_api_pipe_state_destructor()
1463 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1465 return NT_STATUS_OK;
1468 /*******************************************************************
1469 Creates krb5 auth bind.
1470 ********************************************************************/
1472 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1473 enum dcerpc_AuthLevel auth_level,
1474 RPC_HDR_AUTH *pauth_out,
1475 prs_struct *auth_data)
1477 #ifdef HAVE_KRB5
1478 int ret;
1479 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1480 DATA_BLOB tkt = data_blob_null;
1481 DATA_BLOB tkt_wrapped = data_blob_null;
1483 /* We may change the pad length before marshalling. */
1484 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1486 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1487 a->service_principal ));
1489 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1491 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1492 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1494 if (ret) {
1495 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1496 "failed with %s\n",
1497 a->service_principal,
1498 error_message(ret) ));
1500 data_blob_free(&tkt);
1501 prs_mem_free(auth_data);
1502 return NT_STATUS_INVALID_PARAMETER;
1505 /* wrap that up in a nice GSS-API wrapping */
1506 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1508 data_blob_free(&tkt);
1510 /* Auth len in the rpc header doesn't include auth_header. */
1511 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1512 data_blob_free(&tkt_wrapped);
1513 prs_mem_free(auth_data);
1514 return NT_STATUS_NO_MEMORY;
1517 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1518 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1520 data_blob_free(&tkt_wrapped);
1521 return NT_STATUS_OK;
1522 #else
1523 return NT_STATUS_INVALID_PARAMETER;
1524 #endif
1527 /*******************************************************************
1528 Creates SPNEGO NTLMSSP auth bind.
1529 ********************************************************************/
1531 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1532 enum dcerpc_AuthLevel auth_level,
1533 RPC_HDR_AUTH *pauth_out,
1534 prs_struct *auth_data)
1536 NTSTATUS nt_status;
1537 DATA_BLOB null_blob = data_blob_null;
1538 DATA_BLOB request = data_blob_null;
1539 DATA_BLOB spnego_msg = data_blob_null;
1541 /* We may change the pad length before marshalling. */
1542 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1544 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1545 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1546 null_blob,
1547 &request);
1549 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1550 data_blob_free(&request);
1551 prs_mem_free(auth_data);
1552 return nt_status;
1555 /* Wrap this in SPNEGO. */
1556 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1558 data_blob_free(&request);
1560 /* Auth len in the rpc header doesn't include auth_header. */
1561 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1562 data_blob_free(&spnego_msg);
1563 prs_mem_free(auth_data);
1564 return NT_STATUS_NO_MEMORY;
1567 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1568 dump_data(5, spnego_msg.data, spnego_msg.length);
1570 data_blob_free(&spnego_msg);
1571 return NT_STATUS_OK;
1574 /*******************************************************************
1575 Creates NTLMSSP auth bind.
1576 ********************************************************************/
1578 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1579 enum dcerpc_AuthLevel auth_level,
1580 RPC_HDR_AUTH *pauth_out,
1581 prs_struct *auth_data)
1583 NTSTATUS nt_status;
1584 DATA_BLOB null_blob = data_blob_null;
1585 DATA_BLOB request = data_blob_null;
1587 /* We may change the pad length before marshalling. */
1588 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1590 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1591 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1592 null_blob,
1593 &request);
1595 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1596 data_blob_free(&request);
1597 prs_mem_free(auth_data);
1598 return nt_status;
1601 /* Auth len in the rpc header doesn't include auth_header. */
1602 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1603 data_blob_free(&request);
1604 prs_mem_free(auth_data);
1605 return NT_STATUS_NO_MEMORY;
1608 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1609 dump_data(5, request.data, request.length);
1611 data_blob_free(&request);
1612 return NT_STATUS_OK;
1615 /*******************************************************************
1616 Creates schannel auth bind.
1617 ********************************************************************/
1619 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1620 enum dcerpc_AuthLevel auth_level,
1621 RPC_HDR_AUTH *pauth_out,
1622 prs_struct *auth_data)
1624 struct NL_AUTH_MESSAGE r;
1625 enum ndr_err_code ndr_err;
1626 DATA_BLOB blob;
1628 /* We may change the pad length before marshalling. */
1629 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1631 /* Use lp_workgroup() if domain not specified */
1633 if (!cli->auth->domain || !cli->auth->domain[0]) {
1634 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1635 if (cli->auth->domain == NULL) {
1636 return NT_STATUS_NO_MEMORY;
1641 * Now marshall the data into the auth parse_struct.
1644 r.MessageType = NL_NEGOTIATE_REQUEST;
1645 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1646 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1647 r.oem_netbios_domain.a = cli->auth->domain;
1648 r.oem_netbios_computer.a = global_myname();
1650 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1651 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1652 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1653 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1654 prs_mem_free(auth_data);
1655 return ndr_map_error2ntstatus(ndr_err);
1658 if (DEBUGLEVEL >= 10) {
1659 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1662 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1664 prs_mem_free(auth_data);
1665 return NT_STATUS_NO_MEMORY;
1668 return NT_STATUS_OK;
1671 /*******************************************************************
1672 Creates the internals of a DCE/RPC bind request or alter context PDU.
1673 ********************************************************************/
1675 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1676 prs_struct *rpc_out,
1677 uint32 rpc_call_id,
1678 const struct ndr_syntax_id *abstract,
1679 const struct ndr_syntax_id *transfer,
1680 RPC_HDR_AUTH *phdr_auth,
1681 prs_struct *pauth_info)
1683 RPC_HDR hdr;
1684 RPC_HDR_RB hdr_rb;
1685 RPC_CONTEXT rpc_ctx;
1686 uint16 auth_len = prs_offset(pauth_info);
1687 uint8 ss_padding_len = 0;
1688 uint16 frag_len = 0;
1690 /* create the RPC context. */
1691 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1693 /* create the bind request RPC_HDR_RB */
1694 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1696 /* Start building the frag length. */
1697 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1699 /* Do we need to pad ? */
1700 if (auth_len) {
1701 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1702 if (data_len % 8) {
1703 ss_padding_len = 8 - (data_len % 8);
1704 phdr_auth->auth_pad_len = ss_padding_len;
1706 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1709 /* Create the request RPC_HDR */
1710 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1712 /* Marshall the RPC header */
1713 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1714 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1715 return NT_STATUS_NO_MEMORY;
1718 /* Marshall the bind request data */
1719 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1720 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1721 return NT_STATUS_NO_MEMORY;
1725 * Grow the outgoing buffer to store any auth info.
1728 if(auth_len != 0) {
1729 if (ss_padding_len) {
1730 char pad[8];
1731 memset(pad, '\0', 8);
1732 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1733 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1734 return NT_STATUS_NO_MEMORY;
1738 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1739 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1740 return NT_STATUS_NO_MEMORY;
1744 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1745 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1746 return NT_STATUS_NO_MEMORY;
1750 return NT_STATUS_OK;
1753 /*******************************************************************
1754 Creates a DCE/RPC bind request.
1755 ********************************************************************/
1757 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1758 prs_struct *rpc_out,
1759 uint32 rpc_call_id,
1760 const struct ndr_syntax_id *abstract,
1761 const struct ndr_syntax_id *transfer,
1762 enum pipe_auth_type auth_type,
1763 enum dcerpc_AuthLevel auth_level)
1765 RPC_HDR_AUTH hdr_auth;
1766 prs_struct auth_info;
1767 NTSTATUS ret = NT_STATUS_OK;
1769 ZERO_STRUCT(hdr_auth);
1770 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1771 return NT_STATUS_NO_MEMORY;
1773 switch (auth_type) {
1774 case PIPE_AUTH_TYPE_SCHANNEL:
1775 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1776 if (!NT_STATUS_IS_OK(ret)) {
1777 prs_mem_free(&auth_info);
1778 return ret;
1780 break;
1782 case PIPE_AUTH_TYPE_NTLMSSP:
1783 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1784 if (!NT_STATUS_IS_OK(ret)) {
1785 prs_mem_free(&auth_info);
1786 return ret;
1788 break;
1790 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1791 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1792 if (!NT_STATUS_IS_OK(ret)) {
1793 prs_mem_free(&auth_info);
1794 return ret;
1796 break;
1798 case PIPE_AUTH_TYPE_KRB5:
1799 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1800 if (!NT_STATUS_IS_OK(ret)) {
1801 prs_mem_free(&auth_info);
1802 return ret;
1804 break;
1806 case PIPE_AUTH_TYPE_NONE:
1807 break;
1809 default:
1810 /* "Can't" happen. */
1811 return NT_STATUS_INVALID_INFO_CLASS;
1814 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1815 rpc_out,
1816 rpc_call_id,
1817 abstract,
1818 transfer,
1819 &hdr_auth,
1820 &auth_info);
1822 prs_mem_free(&auth_info);
1823 return ret;
1826 /*******************************************************************
1827 Create and add the NTLMSSP sign/seal auth header and data.
1828 ********************************************************************/
1830 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1831 RPC_HDR *phdr,
1832 uint32 ss_padding_len,
1833 prs_struct *outgoing_pdu)
1835 RPC_HDR_AUTH auth_info;
1836 NTSTATUS status;
1837 DATA_BLOB auth_blob = data_blob_null;
1838 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1840 if (!cli->auth->a_u.ntlmssp_state) {
1841 return NT_STATUS_INVALID_PARAMETER;
1844 /* Init and marshall the auth header. */
1845 init_rpc_hdr_auth(&auth_info,
1846 map_pipe_auth_type_to_rpc_auth_type(
1847 cli->auth->auth_type),
1848 cli->auth->auth_level,
1849 ss_padding_len,
1850 1 /* context id. */);
1852 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1853 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1854 data_blob_free(&auth_blob);
1855 return NT_STATUS_NO_MEMORY;
1858 switch (cli->auth->auth_level) {
1859 case DCERPC_AUTH_LEVEL_PRIVACY:
1860 /* Data portion is encrypted. */
1861 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1862 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1863 data_and_pad_len,
1864 (unsigned char *)prs_data_p(outgoing_pdu),
1865 (size_t)prs_offset(outgoing_pdu),
1866 &auth_blob);
1867 if (!NT_STATUS_IS_OK(status)) {
1868 data_blob_free(&auth_blob);
1869 return status;
1871 break;
1873 case DCERPC_AUTH_LEVEL_INTEGRITY:
1874 /* Data is signed. */
1875 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1876 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1877 data_and_pad_len,
1878 (unsigned char *)prs_data_p(outgoing_pdu),
1879 (size_t)prs_offset(outgoing_pdu),
1880 &auth_blob);
1881 if (!NT_STATUS_IS_OK(status)) {
1882 data_blob_free(&auth_blob);
1883 return status;
1885 break;
1887 default:
1888 /* Can't happen. */
1889 smb_panic("bad auth level");
1890 /* Notreached. */
1891 return NT_STATUS_INVALID_PARAMETER;
1894 /* Finally marshall the blob. */
1896 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1897 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1898 (unsigned int)NTLMSSP_SIG_SIZE));
1899 data_blob_free(&auth_blob);
1900 return NT_STATUS_NO_MEMORY;
1903 data_blob_free(&auth_blob);
1904 return NT_STATUS_OK;
1907 /*******************************************************************
1908 Create and add the schannel sign/seal auth header and data.
1909 ********************************************************************/
1911 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1912 RPC_HDR *phdr,
1913 uint32 ss_padding_len,
1914 prs_struct *outgoing_pdu)
1916 RPC_HDR_AUTH auth_info;
1917 struct NL_AUTH_SIGNATURE verf;
1918 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1919 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1920 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1921 enum ndr_err_code ndr_err;
1922 DATA_BLOB blob;
1924 if (!sas) {
1925 return NT_STATUS_INVALID_PARAMETER;
1928 /* Init and marshall the auth header. */
1929 init_rpc_hdr_auth(&auth_info,
1930 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1931 cli->auth->auth_level,
1932 ss_padding_len,
1933 1 /* context id. */);
1935 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1936 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1937 return NT_STATUS_NO_MEMORY;
1940 switch (cli->auth->auth_level) {
1941 case DCERPC_AUTH_LEVEL_PRIVACY:
1942 case DCERPC_AUTH_LEVEL_INTEGRITY:
1943 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1944 sas->seq_num));
1946 schannel_encode(sas,
1947 cli->auth->auth_level,
1948 SENDER_IS_INITIATOR,
1949 &verf,
1950 data_p,
1951 data_and_pad_len);
1953 sas->seq_num++;
1954 break;
1956 default:
1957 /* Can't happen. */
1958 smb_panic("bad auth level");
1959 /* Notreached. */
1960 return NT_STATUS_INVALID_PARAMETER;
1963 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &verf,
1964 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_SIGNATURE);
1965 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1966 return ndr_map_error2ntstatus(ndr_err);
1969 if (DEBUGLEVEL >= 10) {
1970 NDR_PRINT_DEBUG(NL_AUTH_SIGNATURE, &verf);
1973 /* Finally marshall the blob. */
1974 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
1975 return NT_STATUS_NO_MEMORY;
1978 return NT_STATUS_OK;
1981 /*******************************************************************
1982 Calculate how much data we're going to send in this packet, also
1983 work out any sign/seal padding length.
1984 ********************************************************************/
1986 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1987 uint32 data_left,
1988 uint16 *p_frag_len,
1989 uint16 *p_auth_len,
1990 uint32 *p_ss_padding)
1992 uint32 data_space, data_len;
1994 #ifdef DEVELOPER
1995 if ((data_left > 0) && (sys_random() % 2)) {
1996 data_left = MAX(data_left/2, 1);
1998 #endif
2000 switch (cli->auth->auth_level) {
2001 case DCERPC_AUTH_LEVEL_NONE:
2002 case DCERPC_AUTH_LEVEL_CONNECT:
2003 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2004 data_len = MIN(data_space, data_left);
2005 *p_ss_padding = 0;
2006 *p_auth_len = 0;
2007 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2008 return data_len;
2010 case DCERPC_AUTH_LEVEL_INTEGRITY:
2011 case DCERPC_AUTH_LEVEL_PRIVACY:
2012 /* Treat the same for all authenticated rpc requests. */
2013 switch(cli->auth->auth_type) {
2014 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2015 case PIPE_AUTH_TYPE_NTLMSSP:
2016 *p_auth_len = NTLMSSP_SIG_SIZE;
2017 break;
2018 case PIPE_AUTH_TYPE_SCHANNEL:
2019 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2020 break;
2021 default:
2022 smb_panic("bad auth type");
2023 break;
2026 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2027 RPC_HDR_AUTH_LEN - *p_auth_len;
2029 data_len = MIN(data_space, data_left);
2030 *p_ss_padding = 0;
2031 if (data_len % 8) {
2032 *p_ss_padding = 8 - (data_len % 8);
2034 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2035 data_len + *p_ss_padding + /* data plus padding. */
2036 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2037 return data_len;
2039 default:
2040 smb_panic("bad auth level");
2041 /* Notreached. */
2042 return 0;
2046 /*******************************************************************
2047 External interface.
2048 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2049 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2050 and deals with signing/sealing details.
2051 ********************************************************************/
2053 struct rpc_api_pipe_req_state {
2054 struct event_context *ev;
2055 struct rpc_pipe_client *cli;
2056 uint8_t op_num;
2057 uint32_t call_id;
2058 prs_struct *req_data;
2059 uint32_t req_data_sent;
2060 prs_struct outgoing_frag;
2061 prs_struct reply_pdu;
2064 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2066 prs_mem_free(&s->outgoing_frag);
2067 prs_mem_free(&s->reply_pdu);
2068 return 0;
2071 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2072 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2073 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2074 bool *is_last_frag);
2076 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2077 struct event_context *ev,
2078 struct rpc_pipe_client *cli,
2079 uint8_t op_num,
2080 prs_struct *req_data)
2082 struct tevent_req *req, *subreq;
2083 struct rpc_api_pipe_req_state *state;
2084 NTSTATUS status;
2085 bool is_last_frag;
2087 req = tevent_req_create(mem_ctx, &state,
2088 struct rpc_api_pipe_req_state);
2089 if (req == NULL) {
2090 return NULL;
2092 state->ev = ev;
2093 state->cli = cli;
2094 state->op_num = op_num;
2095 state->req_data = req_data;
2096 state->req_data_sent = 0;
2097 state->call_id = get_rpc_call_id();
2099 if (cli->max_xmit_frag
2100 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2101 /* Server is screwed up ! */
2102 status = NT_STATUS_INVALID_PARAMETER;
2103 goto post_status;
2106 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2108 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2109 state, MARSHALL)) {
2110 goto fail;
2113 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2115 status = prepare_next_frag(state, &is_last_frag);
2116 if (!NT_STATUS_IS_OK(status)) {
2117 goto post_status;
2120 if (is_last_frag) {
2121 subreq = rpc_api_pipe_send(state, ev, state->cli,
2122 &state->outgoing_frag,
2123 RPC_RESPONSE);
2124 if (subreq == NULL) {
2125 goto fail;
2127 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2128 } else {
2129 subreq = rpc_write_send(
2130 state, ev, cli->transport,
2131 (uint8_t *)prs_data_p(&state->outgoing_frag),
2132 prs_offset(&state->outgoing_frag));
2133 if (subreq == NULL) {
2134 goto fail;
2136 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2137 req);
2139 return req;
2141 post_status:
2142 tevent_req_nterror(req, status);
2143 return tevent_req_post(req, ev);
2144 fail:
2145 TALLOC_FREE(req);
2146 return NULL;
2149 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2150 bool *is_last_frag)
2152 RPC_HDR hdr;
2153 RPC_HDR_REQ hdr_req;
2154 uint32_t data_sent_thistime;
2155 uint16_t auth_len;
2156 uint16_t frag_len;
2157 uint8_t flags = 0;
2158 uint32_t ss_padding;
2159 uint32_t data_left;
2160 char pad[8] = { 0, };
2161 NTSTATUS status;
2163 data_left = prs_offset(state->req_data) - state->req_data_sent;
2165 data_sent_thistime = calculate_data_len_tosend(
2166 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2168 if (state->req_data_sent == 0) {
2169 flags = RPC_FLG_FIRST;
2172 if (data_sent_thistime == data_left) {
2173 flags |= RPC_FLG_LAST;
2176 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2177 return NT_STATUS_NO_MEMORY;
2180 /* Create and marshall the header and request header. */
2181 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2182 auth_len);
2184 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2185 return NT_STATUS_NO_MEMORY;
2188 /* Create the rpc request RPC_HDR_REQ */
2189 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2190 state->op_num);
2192 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2193 &state->outgoing_frag, 0)) {
2194 return NT_STATUS_NO_MEMORY;
2197 /* Copy in the data, plus any ss padding. */
2198 if (!prs_append_some_prs_data(&state->outgoing_frag,
2199 state->req_data, state->req_data_sent,
2200 data_sent_thistime)) {
2201 return NT_STATUS_NO_MEMORY;
2204 /* Copy the sign/seal padding data. */
2205 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2206 return NT_STATUS_NO_MEMORY;
2209 /* Generate any auth sign/seal and add the auth footer. */
2210 switch (state->cli->auth->auth_type) {
2211 case PIPE_AUTH_TYPE_NONE:
2212 status = NT_STATUS_OK;
2213 break;
2214 case PIPE_AUTH_TYPE_NTLMSSP:
2215 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2216 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2217 &state->outgoing_frag);
2218 break;
2219 case PIPE_AUTH_TYPE_SCHANNEL:
2220 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2221 &state->outgoing_frag);
2222 break;
2223 default:
2224 status = NT_STATUS_INVALID_PARAMETER;
2225 break;
2228 state->req_data_sent += data_sent_thistime;
2229 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2231 return status;
2234 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2236 struct tevent_req *req = tevent_req_callback_data(
2237 subreq, struct tevent_req);
2238 struct rpc_api_pipe_req_state *state = tevent_req_data(
2239 req, struct rpc_api_pipe_req_state);
2240 NTSTATUS status;
2241 bool is_last_frag;
2243 status = rpc_write_recv(subreq);
2244 TALLOC_FREE(subreq);
2245 if (!NT_STATUS_IS_OK(status)) {
2246 tevent_req_nterror(req, status);
2247 return;
2250 status = prepare_next_frag(state, &is_last_frag);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 tevent_req_nterror(req, status);
2253 return;
2256 if (is_last_frag) {
2257 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2258 &state->outgoing_frag,
2259 RPC_RESPONSE);
2260 if (tevent_req_nomem(subreq, req)) {
2261 return;
2263 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2264 } else {
2265 subreq = rpc_write_send(
2266 state, state->ev,
2267 state->cli->transport,
2268 (uint8_t *)prs_data_p(&state->outgoing_frag),
2269 prs_offset(&state->outgoing_frag));
2270 if (tevent_req_nomem(subreq, req)) {
2271 return;
2273 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2274 req);
2278 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2280 struct tevent_req *req = tevent_req_callback_data(
2281 subreq, struct tevent_req);
2282 struct rpc_api_pipe_req_state *state = tevent_req_data(
2283 req, struct rpc_api_pipe_req_state);
2284 NTSTATUS status;
2286 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2287 TALLOC_FREE(subreq);
2288 if (!NT_STATUS_IS_OK(status)) {
2289 tevent_req_nterror(req, status);
2290 return;
2292 tevent_req_done(req);
2295 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2296 prs_struct *reply_pdu)
2298 struct rpc_api_pipe_req_state *state = tevent_req_data(
2299 req, struct rpc_api_pipe_req_state);
2300 NTSTATUS status;
2302 if (tevent_req_is_nterror(req, &status)) {
2304 * We always have to initialize to reply pdu, even if there is
2305 * none. The rpccli_* caller routines expect this.
2307 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2308 return status;
2311 *reply_pdu = state->reply_pdu;
2312 reply_pdu->mem_ctx = mem_ctx;
2315 * Prevent state->req_pdu from being freed in
2316 * rpc_api_pipe_req_state_destructor()
2318 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2320 return NT_STATUS_OK;
2323 #if 0
2324 /****************************************************************************
2325 Set the handle state.
2326 ****************************************************************************/
2328 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2329 const char *pipe_name, uint16 device_state)
2331 bool state_set = False;
2332 char param[2];
2333 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2334 char *rparam = NULL;
2335 char *rdata = NULL;
2336 uint32 rparam_len, rdata_len;
2338 if (pipe_name == NULL)
2339 return False;
2341 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2342 cli->fnum, pipe_name, device_state));
2344 /* create parameters: device state */
2345 SSVAL(param, 0, device_state);
2347 /* create setup parameters. */
2348 setup[0] = 0x0001;
2349 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2351 /* send the data on \PIPE\ */
2352 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2353 setup, 2, 0, /* setup, length, max */
2354 param, 2, 0, /* param, length, max */
2355 NULL, 0, 1024, /* data, length, max */
2356 &rparam, &rparam_len, /* return param, length */
2357 &rdata, &rdata_len)) /* return data, length */
2359 DEBUG(5, ("Set Handle state: return OK\n"));
2360 state_set = True;
2363 SAFE_FREE(rparam);
2364 SAFE_FREE(rdata);
2366 return state_set;
2368 #endif
2370 /****************************************************************************
2371 Check the rpc bind acknowledge response.
2372 ****************************************************************************/
2374 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2375 const struct ndr_syntax_id *transfer)
2377 if ( hdr_ba->addr.len == 0) {
2378 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2381 /* check the transfer syntax */
2382 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2383 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2384 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2385 return False;
2388 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2389 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2390 hdr_ba->res.num_results, hdr_ba->res.reason));
2393 DEBUG(5,("check_bind_response: accepted!\n"));
2394 return True;
2397 /*******************************************************************
2398 Creates a DCE/RPC bind authentication response.
2399 This is the packet that is sent back to the server once we
2400 have received a BIND-ACK, to finish the third leg of
2401 the authentication handshake.
2402 ********************************************************************/
2404 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2405 uint32 rpc_call_id,
2406 enum pipe_auth_type auth_type,
2407 enum dcerpc_AuthLevel auth_level,
2408 DATA_BLOB *pauth_blob,
2409 prs_struct *rpc_out)
2411 RPC_HDR hdr;
2412 RPC_HDR_AUTH hdr_auth;
2413 uint32 pad = 0;
2415 /* Create the request RPC_HDR */
2416 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2417 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2418 pauth_blob->length );
2420 /* Marshall it. */
2421 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2422 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2423 return NT_STATUS_NO_MEMORY;
2427 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2428 about padding - shouldn't this pad to length 8 ? JRA.
2431 /* 4 bytes padding. */
2432 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2433 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2434 return NT_STATUS_NO_MEMORY;
2437 /* Create the request RPC_HDR_AUTHA */
2438 init_rpc_hdr_auth(&hdr_auth,
2439 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2440 auth_level, 0, 1);
2442 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2443 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2444 return NT_STATUS_NO_MEMORY;
2448 * Append the auth data to the outgoing buffer.
2451 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2452 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2453 return NT_STATUS_NO_MEMORY;
2456 return NT_STATUS_OK;
2459 /*******************************************************************
2460 Creates a DCE/RPC bind alter context authentication request which
2461 may contain a spnego auth blobl
2462 ********************************************************************/
2464 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2465 const struct ndr_syntax_id *abstract,
2466 const struct ndr_syntax_id *transfer,
2467 enum dcerpc_AuthLevel auth_level,
2468 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2469 prs_struct *rpc_out)
2471 RPC_HDR_AUTH hdr_auth;
2472 prs_struct auth_info;
2473 NTSTATUS ret = NT_STATUS_OK;
2475 ZERO_STRUCT(hdr_auth);
2476 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2477 return NT_STATUS_NO_MEMORY;
2479 /* We may change the pad length before marshalling. */
2480 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2482 if (pauth_blob->length) {
2483 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2484 prs_mem_free(&auth_info);
2485 return NT_STATUS_NO_MEMORY;
2489 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2490 rpc_out,
2491 rpc_call_id,
2492 abstract,
2493 transfer,
2494 &hdr_auth,
2495 &auth_info);
2496 prs_mem_free(&auth_info);
2497 return ret;
2500 /****************************************************************************
2501 Do an rpc bind.
2502 ****************************************************************************/
2504 struct rpc_pipe_bind_state {
2505 struct event_context *ev;
2506 struct rpc_pipe_client *cli;
2507 prs_struct rpc_out;
2508 uint32_t rpc_call_id;
2511 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2513 prs_mem_free(&state->rpc_out);
2514 return 0;
2517 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2518 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2519 struct rpc_pipe_bind_state *state,
2520 struct rpc_hdr_info *phdr,
2521 prs_struct *reply_pdu);
2522 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2523 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2524 struct rpc_pipe_bind_state *state,
2525 struct rpc_hdr_info *phdr,
2526 prs_struct *reply_pdu);
2527 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2529 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2530 struct event_context *ev,
2531 struct rpc_pipe_client *cli,
2532 struct cli_pipe_auth_data *auth)
2534 struct tevent_req *req, *subreq;
2535 struct rpc_pipe_bind_state *state;
2536 NTSTATUS status;
2538 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2539 if (req == NULL) {
2540 return NULL;
2543 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2544 rpccli_pipe_txt(debug_ctx(), cli),
2545 (unsigned int)auth->auth_type,
2546 (unsigned int)auth->auth_level ));
2548 state->ev = ev;
2549 state->cli = cli;
2550 state->rpc_call_id = get_rpc_call_id();
2552 prs_init_empty(&state->rpc_out, state, MARSHALL);
2553 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2555 cli->auth = talloc_move(cli, &auth);
2557 /* Marshall the outgoing data. */
2558 status = create_rpc_bind_req(cli, &state->rpc_out,
2559 state->rpc_call_id,
2560 &cli->abstract_syntax,
2561 &cli->transfer_syntax,
2562 cli->auth->auth_type,
2563 cli->auth->auth_level);
2565 if (!NT_STATUS_IS_OK(status)) {
2566 goto post_status;
2569 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2570 RPC_BINDACK);
2571 if (subreq == NULL) {
2572 goto fail;
2574 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2575 return req;
2577 post_status:
2578 tevent_req_nterror(req, status);
2579 return tevent_req_post(req, ev);
2580 fail:
2581 TALLOC_FREE(req);
2582 return NULL;
2585 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2587 struct tevent_req *req = tevent_req_callback_data(
2588 subreq, struct tevent_req);
2589 struct rpc_pipe_bind_state *state = tevent_req_data(
2590 req, struct rpc_pipe_bind_state);
2591 prs_struct reply_pdu;
2592 struct rpc_hdr_info hdr;
2593 struct rpc_hdr_ba_info hdr_ba;
2594 NTSTATUS status;
2596 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2597 TALLOC_FREE(subreq);
2598 if (!NT_STATUS_IS_OK(status)) {
2599 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2600 rpccli_pipe_txt(debug_ctx(), state->cli),
2601 nt_errstr(status)));
2602 tevent_req_nterror(req, status);
2603 return;
2606 /* Unmarshall the RPC header */
2607 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2608 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2609 prs_mem_free(&reply_pdu);
2610 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2611 return;
2614 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2615 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2616 "RPC_HDR_BA.\n"));
2617 prs_mem_free(&reply_pdu);
2618 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2619 return;
2622 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2623 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2624 prs_mem_free(&reply_pdu);
2625 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2626 return;
2629 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2630 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2633 * For authenticated binds we may need to do 3 or 4 leg binds.
2636 switch(state->cli->auth->auth_type) {
2638 case PIPE_AUTH_TYPE_NONE:
2639 case PIPE_AUTH_TYPE_SCHANNEL:
2640 /* Bind complete. */
2641 prs_mem_free(&reply_pdu);
2642 tevent_req_done(req);
2643 break;
2645 case PIPE_AUTH_TYPE_NTLMSSP:
2646 /* Need to send AUTH3 packet - no reply. */
2647 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2648 &reply_pdu);
2649 prs_mem_free(&reply_pdu);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 tevent_req_nterror(req, status);
2653 break;
2655 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2656 /* Need to send alter context request and reply. */
2657 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2658 &reply_pdu);
2659 prs_mem_free(&reply_pdu);
2660 if (!NT_STATUS_IS_OK(status)) {
2661 tevent_req_nterror(req, status);
2663 break;
2665 case PIPE_AUTH_TYPE_KRB5:
2666 /* */
2668 default:
2669 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2670 (unsigned int)state->cli->auth->auth_type));
2671 prs_mem_free(&reply_pdu);
2672 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2676 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2677 struct rpc_pipe_bind_state *state,
2678 struct rpc_hdr_info *phdr,
2679 prs_struct *reply_pdu)
2681 DATA_BLOB server_response = data_blob_null;
2682 DATA_BLOB client_reply = data_blob_null;
2683 struct rpc_hdr_auth_info hdr_auth;
2684 struct tevent_req *subreq;
2685 NTSTATUS status;
2687 if ((phdr->auth_len == 0)
2688 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2689 return NT_STATUS_INVALID_PARAMETER;
2692 if (!prs_set_offset(
2693 reply_pdu,
2694 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2695 return NT_STATUS_INVALID_PARAMETER;
2698 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2699 return NT_STATUS_INVALID_PARAMETER;
2702 /* TODO - check auth_type/auth_level match. */
2704 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2705 prs_copy_data_out((char *)server_response.data, reply_pdu,
2706 phdr->auth_len);
2708 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2709 server_response, &client_reply);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2713 "blob failed: %s.\n", nt_errstr(status)));
2714 return status;
2717 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2719 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2720 state->cli->auth->auth_type,
2721 state->cli->auth->auth_level,
2722 &client_reply, &state->rpc_out);
2723 data_blob_free(&client_reply);
2725 if (!NT_STATUS_IS_OK(status)) {
2726 return status;
2729 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2730 (uint8_t *)prs_data_p(&state->rpc_out),
2731 prs_offset(&state->rpc_out));
2732 if (subreq == NULL) {
2733 return NT_STATUS_NO_MEMORY;
2735 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2736 return NT_STATUS_OK;
2739 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2741 struct tevent_req *req = tevent_req_callback_data(
2742 subreq, struct tevent_req);
2743 NTSTATUS status;
2745 status = rpc_write_recv(subreq);
2746 TALLOC_FREE(subreq);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 tevent_req_nterror(req, status);
2749 return;
2751 tevent_req_done(req);
2754 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2755 struct rpc_pipe_bind_state *state,
2756 struct rpc_hdr_info *phdr,
2757 prs_struct *reply_pdu)
2759 DATA_BLOB server_spnego_response = data_blob_null;
2760 DATA_BLOB server_ntlm_response = data_blob_null;
2761 DATA_BLOB client_reply = data_blob_null;
2762 DATA_BLOB tmp_blob = data_blob_null;
2763 RPC_HDR_AUTH hdr_auth;
2764 struct tevent_req *subreq;
2765 NTSTATUS status;
2767 if ((phdr->auth_len == 0)
2768 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2769 return NT_STATUS_INVALID_PARAMETER;
2772 /* Process the returned NTLMSSP blob first. */
2773 if (!prs_set_offset(
2774 reply_pdu,
2775 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2776 return NT_STATUS_INVALID_PARAMETER;
2779 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2780 return NT_STATUS_INVALID_PARAMETER;
2783 server_spnego_response = data_blob(NULL, phdr->auth_len);
2784 prs_copy_data_out((char *)server_spnego_response.data,
2785 reply_pdu, phdr->auth_len);
2788 * The server might give us back two challenges - tmp_blob is for the
2789 * second.
2791 if (!spnego_parse_challenge(server_spnego_response,
2792 &server_ntlm_response, &tmp_blob)) {
2793 data_blob_free(&server_spnego_response);
2794 data_blob_free(&server_ntlm_response);
2795 data_blob_free(&tmp_blob);
2796 return NT_STATUS_INVALID_PARAMETER;
2799 /* We're finished with the server spnego response and the tmp_blob. */
2800 data_blob_free(&server_spnego_response);
2801 data_blob_free(&tmp_blob);
2803 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2804 server_ntlm_response, &client_reply);
2806 /* Finished with the server_ntlm response */
2807 data_blob_free(&server_ntlm_response);
2809 if (!NT_STATUS_IS_OK(status)) {
2810 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2811 "using server blob failed.\n"));
2812 data_blob_free(&client_reply);
2813 return status;
2816 /* SPNEGO wrap the client reply. */
2817 tmp_blob = spnego_gen_auth(client_reply);
2818 data_blob_free(&client_reply);
2819 client_reply = tmp_blob;
2820 tmp_blob = data_blob_null;
2822 /* Now prepare the alter context pdu. */
2823 prs_init_empty(&state->rpc_out, state, MARSHALL);
2825 status = create_rpc_alter_context(state->rpc_call_id,
2826 &state->cli->abstract_syntax,
2827 &state->cli->transfer_syntax,
2828 state->cli->auth->auth_level,
2829 &client_reply,
2830 &state->rpc_out);
2831 data_blob_free(&client_reply);
2833 if (!NT_STATUS_IS_OK(status)) {
2834 return status;
2837 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2838 &state->rpc_out, RPC_ALTCONTRESP);
2839 if (subreq == NULL) {
2840 return NT_STATUS_NO_MEMORY;
2842 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2843 return NT_STATUS_OK;
2846 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2848 struct tevent_req *req = tevent_req_callback_data(
2849 subreq, struct tevent_req);
2850 struct rpc_pipe_bind_state *state = tevent_req_data(
2851 req, struct rpc_pipe_bind_state);
2852 DATA_BLOB server_spnego_response = data_blob_null;
2853 DATA_BLOB tmp_blob = data_blob_null;
2854 prs_struct reply_pdu;
2855 struct rpc_hdr_info hdr;
2856 struct rpc_hdr_auth_info hdr_auth;
2857 NTSTATUS status;
2859 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2860 TALLOC_FREE(subreq);
2861 if (!NT_STATUS_IS_OK(status)) {
2862 tevent_req_nterror(req, status);
2863 return;
2866 /* Get the auth blob from the reply. */
2867 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2868 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2869 "unmarshall RPC_HDR.\n"));
2870 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2871 return;
2874 if (!prs_set_offset(
2875 &reply_pdu,
2876 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2877 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2878 return;
2881 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2882 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2883 return;
2886 server_spnego_response = data_blob(NULL, hdr.auth_len);
2887 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2888 hdr.auth_len);
2890 /* Check we got a valid auth response. */
2891 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2892 OID_NTLMSSP, &tmp_blob)) {
2893 data_blob_free(&server_spnego_response);
2894 data_blob_free(&tmp_blob);
2895 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2896 return;
2899 data_blob_free(&server_spnego_response);
2900 data_blob_free(&tmp_blob);
2902 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2903 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2904 tevent_req_done(req);
2907 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2909 return tevent_req_simple_recv_ntstatus(req);
2912 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2913 struct cli_pipe_auth_data *auth)
2915 TALLOC_CTX *frame = talloc_stackframe();
2916 struct event_context *ev;
2917 struct tevent_req *req;
2918 NTSTATUS status = NT_STATUS_OK;
2920 ev = event_context_init(frame);
2921 if (ev == NULL) {
2922 status = NT_STATUS_NO_MEMORY;
2923 goto fail;
2926 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2927 if (req == NULL) {
2928 status = NT_STATUS_NO_MEMORY;
2929 goto fail;
2932 if (!tevent_req_poll(req, ev)) {
2933 status = map_nt_error_from_unix(errno);
2934 goto fail;
2937 status = rpc_pipe_bind_recv(req);
2938 fail:
2939 TALLOC_FREE(frame);
2940 return status;
2943 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2944 unsigned int timeout)
2946 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2948 if (cli == NULL) {
2949 return 0;
2951 return cli_set_timeout(cli, timeout);
2954 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2956 struct cli_state *cli;
2958 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2959 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2960 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2961 return true;
2964 cli = rpc_pipe_np_smb_conn(rpc_cli);
2965 if (cli == NULL) {
2966 return false;
2968 E_md4hash(cli->password ? cli->password : "", nt_hash);
2969 return true;
2972 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2973 struct cli_pipe_auth_data **presult)
2975 struct cli_pipe_auth_data *result;
2977 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2978 if (result == NULL) {
2979 return NT_STATUS_NO_MEMORY;
2982 result->auth_type = PIPE_AUTH_TYPE_NONE;
2983 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2985 result->user_name = talloc_strdup(result, "");
2986 result->domain = talloc_strdup(result, "");
2987 if ((result->user_name == NULL) || (result->domain == NULL)) {
2988 TALLOC_FREE(result);
2989 return NT_STATUS_NO_MEMORY;
2992 *presult = result;
2993 return NT_STATUS_OK;
2996 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2998 ntlmssp_end(&auth->a_u.ntlmssp_state);
2999 return 0;
3002 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3003 enum pipe_auth_type auth_type,
3004 enum dcerpc_AuthLevel auth_level,
3005 const char *domain,
3006 const char *username,
3007 const char *password,
3008 struct cli_pipe_auth_data **presult)
3010 struct cli_pipe_auth_data *result;
3011 NTSTATUS status;
3013 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3014 if (result == NULL) {
3015 return NT_STATUS_NO_MEMORY;
3018 result->auth_type = auth_type;
3019 result->auth_level = auth_level;
3021 result->user_name = talloc_strdup(result, username);
3022 result->domain = talloc_strdup(result, domain);
3023 if ((result->user_name == NULL) || (result->domain == NULL)) {
3024 status = NT_STATUS_NO_MEMORY;
3025 goto fail;
3028 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 goto fail;
3033 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3035 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 goto fail;
3040 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3041 if (!NT_STATUS_IS_OK(status)) {
3042 goto fail;
3045 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 goto fail;
3051 * Turn off sign+seal to allow selected auth level to turn it back on.
3053 result->a_u.ntlmssp_state->neg_flags &=
3054 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3056 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3057 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3058 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3059 result->a_u.ntlmssp_state->neg_flags
3060 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3063 *presult = result;
3064 return NT_STATUS_OK;
3066 fail:
3067 TALLOC_FREE(result);
3068 return status;
3071 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3072 enum dcerpc_AuthLevel auth_level,
3073 const uint8_t sess_key[16],
3074 struct cli_pipe_auth_data **presult)
3076 struct cli_pipe_auth_data *result;
3078 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3079 if (result == NULL) {
3080 return NT_STATUS_NO_MEMORY;
3083 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3084 result->auth_level = auth_level;
3086 result->user_name = talloc_strdup(result, "");
3087 result->domain = talloc_strdup(result, domain);
3088 if ((result->user_name == NULL) || (result->domain == NULL)) {
3089 goto fail;
3092 result->a_u.schannel_auth = talloc(result,
3093 struct schannel_auth_struct);
3094 if (result->a_u.schannel_auth == NULL) {
3095 goto fail;
3098 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3099 sizeof(result->a_u.schannel_auth->sess_key));
3100 result->a_u.schannel_auth->seq_num = 0;
3102 *presult = result;
3103 return NT_STATUS_OK;
3105 fail:
3106 TALLOC_FREE(result);
3107 return NT_STATUS_NO_MEMORY;
3110 #ifdef HAVE_KRB5
3111 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3113 data_blob_free(&auth->session_key);
3114 return 0;
3116 #endif
3118 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3119 enum dcerpc_AuthLevel auth_level,
3120 const char *service_princ,
3121 const char *username,
3122 const char *password,
3123 struct cli_pipe_auth_data **presult)
3125 #ifdef HAVE_KRB5
3126 struct cli_pipe_auth_data *result;
3128 if ((username != NULL) && (password != NULL)) {
3129 int ret = kerberos_kinit_password(username, password, 0, NULL);
3130 if (ret != 0) {
3131 return NT_STATUS_ACCESS_DENIED;
3135 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3136 if (result == NULL) {
3137 return NT_STATUS_NO_MEMORY;
3140 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3141 result->auth_level = auth_level;
3144 * Username / domain need fixing!
3146 result->user_name = talloc_strdup(result, "");
3147 result->domain = talloc_strdup(result, "");
3148 if ((result->user_name == NULL) || (result->domain == NULL)) {
3149 goto fail;
3152 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3153 result, struct kerberos_auth_struct);
3154 if (result->a_u.kerberos_auth == NULL) {
3155 goto fail;
3157 talloc_set_destructor(result->a_u.kerberos_auth,
3158 cli_auth_kerberos_data_destructor);
3160 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3161 result, service_princ);
3162 if (result->a_u.kerberos_auth->service_principal == NULL) {
3163 goto fail;
3166 *presult = result;
3167 return NT_STATUS_OK;
3169 fail:
3170 TALLOC_FREE(result);
3171 return NT_STATUS_NO_MEMORY;
3172 #else
3173 return NT_STATUS_NOT_SUPPORTED;
3174 #endif
3178 * Create an rpc pipe client struct, connecting to a tcp port.
3180 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3181 uint16_t port,
3182 const struct ndr_syntax_id *abstract_syntax,
3183 struct rpc_pipe_client **presult)
3185 struct rpc_pipe_client *result;
3186 struct sockaddr_storage addr;
3187 NTSTATUS status;
3188 int fd;
3190 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3191 if (result == NULL) {
3192 return NT_STATUS_NO_MEMORY;
3195 result->abstract_syntax = *abstract_syntax;
3196 result->transfer_syntax = ndr_transfer_syntax;
3197 result->dispatch = cli_do_rpc_ndr;
3198 result->dispatch_send = cli_do_rpc_ndr_send;
3199 result->dispatch_recv = cli_do_rpc_ndr_recv;
3201 result->desthost = talloc_strdup(result, host);
3202 result->srv_name_slash = talloc_asprintf_strupper_m(
3203 result, "\\\\%s", result->desthost);
3204 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3205 status = NT_STATUS_NO_MEMORY;
3206 goto fail;
3209 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3210 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3212 if (!resolve_name(host, &addr, 0, false)) {
3213 status = NT_STATUS_NOT_FOUND;
3214 goto fail;
3217 status = open_socket_out(&addr, port, 60, &fd);
3218 if (!NT_STATUS_IS_OK(status)) {
3219 goto fail;
3221 set_socket_options(fd, lp_socket_options());
3223 status = rpc_transport_sock_init(result, fd, &result->transport);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 close(fd);
3226 goto fail;
3229 result->transport->transport = NCACN_IP_TCP;
3231 *presult = result;
3232 return NT_STATUS_OK;
3234 fail:
3235 TALLOC_FREE(result);
3236 return status;
3240 * Determine the tcp port on which a dcerpc interface is listening
3241 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3242 * target host.
3244 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3245 const struct ndr_syntax_id *abstract_syntax,
3246 uint16_t *pport)
3248 NTSTATUS status;
3249 struct rpc_pipe_client *epm_pipe = NULL;
3250 struct cli_pipe_auth_data *auth = NULL;
3251 struct dcerpc_binding *map_binding = NULL;
3252 struct dcerpc_binding *res_binding = NULL;
3253 struct epm_twr_t *map_tower = NULL;
3254 struct epm_twr_t *res_towers = NULL;
3255 struct policy_handle *entry_handle = NULL;
3256 uint32_t num_towers = 0;
3257 uint32_t max_towers = 1;
3258 struct epm_twr_p_t towers;
3259 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3261 if (pport == NULL) {
3262 status = NT_STATUS_INVALID_PARAMETER;
3263 goto done;
3266 /* open the connection to the endpoint mapper */
3267 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3268 &ndr_table_epmapper.syntax_id,
3269 &epm_pipe);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 goto done;
3275 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 goto done;
3280 status = rpc_pipe_bind(epm_pipe, auth);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 goto done;
3285 /* create tower for asking the epmapper */
3287 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3288 if (map_binding == NULL) {
3289 status = NT_STATUS_NO_MEMORY;
3290 goto done;
3293 map_binding->transport = NCACN_IP_TCP;
3294 map_binding->object = *abstract_syntax;
3295 map_binding->host = host; /* needed? */
3296 map_binding->endpoint = "0"; /* correct? needed? */
3298 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3299 if (map_tower == NULL) {
3300 status = NT_STATUS_NO_MEMORY;
3301 goto done;
3304 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3305 &(map_tower->tower));
3306 if (!NT_STATUS_IS_OK(status)) {
3307 goto done;
3310 /* allocate further parameters for the epm_Map call */
3312 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3313 if (res_towers == NULL) {
3314 status = NT_STATUS_NO_MEMORY;
3315 goto done;
3317 towers.twr = res_towers;
3319 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3320 if (entry_handle == NULL) {
3321 status = NT_STATUS_NO_MEMORY;
3322 goto done;
3325 /* ask the endpoint mapper for the port */
3327 status = rpccli_epm_Map(epm_pipe,
3328 tmp_ctx,
3329 CONST_DISCARD(struct GUID *,
3330 &(abstract_syntax->uuid)),
3331 map_tower,
3332 entry_handle,
3333 max_towers,
3334 &num_towers,
3335 &towers);
3337 if (!NT_STATUS_IS_OK(status)) {
3338 goto done;
3341 if (num_towers != 1) {
3342 status = NT_STATUS_UNSUCCESSFUL;
3343 goto done;
3346 /* extract the port from the answer */
3348 status = dcerpc_binding_from_tower(tmp_ctx,
3349 &(towers.twr->tower),
3350 &res_binding);
3351 if (!NT_STATUS_IS_OK(status)) {
3352 goto done;
3355 /* are further checks here necessary? */
3356 if (res_binding->transport != NCACN_IP_TCP) {
3357 status = NT_STATUS_UNSUCCESSFUL;
3358 goto done;
3361 *pport = (uint16_t)atoi(res_binding->endpoint);
3363 done:
3364 TALLOC_FREE(tmp_ctx);
3365 return status;
3369 * Create a rpc pipe client struct, connecting to a host via tcp.
3370 * The port is determined by asking the endpoint mapper on the given
3371 * host.
3373 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3374 const struct ndr_syntax_id *abstract_syntax,
3375 struct rpc_pipe_client **presult)
3377 NTSTATUS status;
3378 uint16_t port = 0;
3380 *presult = NULL;
3382 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 goto done;
3387 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3388 abstract_syntax, presult);
3390 done:
3391 return status;
3394 /********************************************************************
3395 Create a rpc pipe client struct, connecting to a unix domain socket
3396 ********************************************************************/
3397 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3398 const struct ndr_syntax_id *abstract_syntax,
3399 struct rpc_pipe_client **presult)
3401 struct rpc_pipe_client *result;
3402 struct sockaddr_un addr;
3403 NTSTATUS status;
3404 int fd;
3406 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3407 if (result == NULL) {
3408 return NT_STATUS_NO_MEMORY;
3411 result->abstract_syntax = *abstract_syntax;
3412 result->transfer_syntax = ndr_transfer_syntax;
3413 result->dispatch = cli_do_rpc_ndr;
3414 result->dispatch_send = cli_do_rpc_ndr_send;
3415 result->dispatch_recv = cli_do_rpc_ndr_recv;
3417 result->desthost = get_myname(result);
3418 result->srv_name_slash = talloc_asprintf_strupper_m(
3419 result, "\\\\%s", result->desthost);
3420 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3421 status = NT_STATUS_NO_MEMORY;
3422 goto fail;
3425 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3426 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3428 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3429 if (fd == -1) {
3430 status = map_nt_error_from_unix(errno);
3431 goto fail;
3434 ZERO_STRUCT(addr);
3435 addr.sun_family = AF_UNIX;
3436 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3438 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3439 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3440 strerror(errno)));
3441 close(fd);
3442 return map_nt_error_from_unix(errno);
3445 status = rpc_transport_sock_init(result, fd, &result->transport);
3446 if (!NT_STATUS_IS_OK(status)) {
3447 close(fd);
3448 goto fail;
3451 result->transport->transport = NCALRPC;
3453 *presult = result;
3454 return NT_STATUS_OK;
3456 fail:
3457 TALLOC_FREE(result);
3458 return status;
3461 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3463 struct cli_state *cli;
3465 cli = rpc_pipe_np_smb_conn(p);
3466 if (cli != NULL) {
3467 DLIST_REMOVE(cli->pipe_list, p);
3469 return 0;
3472 /****************************************************************************
3473 Open a named pipe over SMB to a remote server.
3475 * CAVEAT CALLER OF THIS FUNCTION:
3476 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3477 * so be sure that this function is called AFTER any structure (vs pointer)
3478 * assignment of the cli. In particular, libsmbclient does structure
3479 * assignments of cli, which invalidates the data in the returned
3480 * rpc_pipe_client if this function is called before the structure assignment
3481 * of cli.
3483 ****************************************************************************/
3485 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3486 const struct ndr_syntax_id *abstract_syntax,
3487 struct rpc_pipe_client **presult)
3489 struct rpc_pipe_client *result;
3490 NTSTATUS status;
3492 /* sanity check to protect against crashes */
3494 if ( !cli ) {
3495 return NT_STATUS_INVALID_HANDLE;
3498 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3499 if (result == NULL) {
3500 return NT_STATUS_NO_MEMORY;
3503 result->abstract_syntax = *abstract_syntax;
3504 result->transfer_syntax = ndr_transfer_syntax;
3505 result->dispatch = cli_do_rpc_ndr;
3506 result->dispatch_send = cli_do_rpc_ndr_send;
3507 result->dispatch_recv = cli_do_rpc_ndr_recv;
3508 result->desthost = talloc_strdup(result, cli->desthost);
3509 result->srv_name_slash = talloc_asprintf_strupper_m(
3510 result, "\\\\%s", result->desthost);
3512 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3513 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3515 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3516 TALLOC_FREE(result);
3517 return NT_STATUS_NO_MEMORY;
3520 status = rpc_transport_np_init(result, cli, abstract_syntax,
3521 &result->transport);
3522 if (!NT_STATUS_IS_OK(status)) {
3523 TALLOC_FREE(result);
3524 return status;
3527 result->transport->transport = NCACN_NP;
3529 DLIST_ADD(cli->pipe_list, result);
3530 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3532 *presult = result;
3533 return NT_STATUS_OK;
3536 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3537 struct rpc_cli_smbd_conn *conn,
3538 const struct ndr_syntax_id *syntax,
3539 struct rpc_pipe_client **presult)
3541 struct rpc_pipe_client *result;
3542 struct cli_pipe_auth_data *auth;
3543 NTSTATUS status;
3545 result = talloc(mem_ctx, struct rpc_pipe_client);
3546 if (result == NULL) {
3547 return NT_STATUS_NO_MEMORY;
3549 result->abstract_syntax = *syntax;
3550 result->transfer_syntax = ndr_transfer_syntax;
3551 result->dispatch = cli_do_rpc_ndr;
3552 result->dispatch_send = cli_do_rpc_ndr_send;
3553 result->dispatch_recv = cli_do_rpc_ndr_recv;
3554 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3555 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3557 result->desthost = talloc_strdup(result, global_myname());
3558 result->srv_name_slash = talloc_asprintf_strupper_m(
3559 result, "\\\\%s", global_myname());
3560 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3561 TALLOC_FREE(result);
3562 return NT_STATUS_NO_MEMORY;
3565 status = rpc_transport_smbd_init(result, conn, syntax,
3566 &result->transport);
3567 if (!NT_STATUS_IS_OK(status)) {
3568 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3569 nt_errstr(status)));
3570 TALLOC_FREE(result);
3571 return status;
3574 status = rpccli_anon_bind_data(result, &auth);
3575 if (!NT_STATUS_IS_OK(status)) {
3576 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3577 nt_errstr(status)));
3578 TALLOC_FREE(result);
3579 return status;
3582 status = rpc_pipe_bind(result, auth);
3583 if (!NT_STATUS_IS_OK(status)) {
3584 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3585 TALLOC_FREE(result);
3586 return status;
3589 result->transport->transport = NCACN_INTERNAL;
3591 *presult = result;
3592 return NT_STATUS_OK;
3595 /****************************************************************************
3596 Open a pipe to a remote server.
3597 ****************************************************************************/
3599 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3600 enum dcerpc_transport_t transport,
3601 const struct ndr_syntax_id *interface,
3602 struct rpc_pipe_client **presult)
3604 switch (transport) {
3605 case NCACN_IP_TCP:
3606 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3607 presult);
3608 case NCACN_NP:
3609 return rpc_pipe_open_np(cli, interface, presult);
3610 default:
3611 return NT_STATUS_NOT_IMPLEMENTED;
3615 /****************************************************************************
3616 Open a named pipe to an SMB server and bind anonymously.
3617 ****************************************************************************/
3619 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3620 enum dcerpc_transport_t transport,
3621 const struct ndr_syntax_id *interface,
3622 struct rpc_pipe_client **presult)
3624 struct rpc_pipe_client *result;
3625 struct cli_pipe_auth_data *auth;
3626 NTSTATUS status;
3628 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3629 if (!NT_STATUS_IS_OK(status)) {
3630 return status;
3633 status = rpccli_anon_bind_data(result, &auth);
3634 if (!NT_STATUS_IS_OK(status)) {
3635 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3636 nt_errstr(status)));
3637 TALLOC_FREE(result);
3638 return status;
3642 * This is a bit of an abstraction violation due to the fact that an
3643 * anonymous bind on an authenticated SMB inherits the user/domain
3644 * from the enclosing SMB creds
3647 TALLOC_FREE(auth->user_name);
3648 TALLOC_FREE(auth->domain);
3650 auth->user_name = talloc_strdup(auth, cli->user_name);
3651 auth->domain = talloc_strdup(auth, cli->domain);
3652 auth->user_session_key = data_blob_talloc(auth,
3653 cli->user_session_key.data,
3654 cli->user_session_key.length);
3656 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3657 TALLOC_FREE(result);
3658 return NT_STATUS_NO_MEMORY;
3661 status = rpc_pipe_bind(result, auth);
3662 if (!NT_STATUS_IS_OK(status)) {
3663 int lvl = 0;
3664 if (ndr_syntax_id_equal(interface,
3665 &ndr_table_dssetup.syntax_id)) {
3666 /* non AD domains just don't have this pipe, avoid
3667 * level 0 statement in that case - gd */
3668 lvl = 3;
3670 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3671 "%s failed with error %s\n",
3672 get_pipe_name_from_iface(interface),
3673 nt_errstr(status) ));
3674 TALLOC_FREE(result);
3675 return status;
3678 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3679 "%s and bound anonymously.\n",
3680 get_pipe_name_from_iface(interface), cli->desthost));
3682 *presult = result;
3683 return NT_STATUS_OK;
3686 /****************************************************************************
3687 ****************************************************************************/
3689 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3690 const struct ndr_syntax_id *interface,
3691 struct rpc_pipe_client **presult)
3693 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3694 interface, presult);
3697 /****************************************************************************
3698 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3699 ****************************************************************************/
3701 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3702 const struct ndr_syntax_id *interface,
3703 enum dcerpc_transport_t transport,
3704 enum pipe_auth_type auth_type,
3705 enum dcerpc_AuthLevel auth_level,
3706 const char *domain,
3707 const char *username,
3708 const char *password,
3709 struct rpc_pipe_client **presult)
3711 struct rpc_pipe_client *result;
3712 struct cli_pipe_auth_data *auth;
3713 NTSTATUS status;
3715 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3716 if (!NT_STATUS_IS_OK(status)) {
3717 return status;
3720 status = rpccli_ntlmssp_bind_data(
3721 result, auth_type, auth_level, domain, username,
3722 password, &auth);
3723 if (!NT_STATUS_IS_OK(status)) {
3724 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3725 nt_errstr(status)));
3726 goto err;
3729 status = rpc_pipe_bind(result, auth);
3730 if (!NT_STATUS_IS_OK(status)) {
3731 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3732 nt_errstr(status) ));
3733 goto err;
3736 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3737 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3738 get_pipe_name_from_iface(interface), cli->desthost, domain,
3739 username ));
3741 *presult = result;
3742 return NT_STATUS_OK;
3744 err:
3746 TALLOC_FREE(result);
3747 return status;
3750 /****************************************************************************
3751 External interface.
3752 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3753 ****************************************************************************/
3755 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3756 const struct ndr_syntax_id *interface,
3757 enum dcerpc_transport_t transport,
3758 enum dcerpc_AuthLevel auth_level,
3759 const char *domain,
3760 const char *username,
3761 const char *password,
3762 struct rpc_pipe_client **presult)
3764 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3765 interface,
3766 transport,
3767 PIPE_AUTH_TYPE_NTLMSSP,
3768 auth_level,
3769 domain,
3770 username,
3771 password,
3772 presult);
3775 /****************************************************************************
3776 External interface.
3777 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3778 ****************************************************************************/
3780 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3781 const struct ndr_syntax_id *interface,
3782 enum dcerpc_transport_t transport,
3783 enum dcerpc_AuthLevel auth_level,
3784 const char *domain,
3785 const char *username,
3786 const char *password,
3787 struct rpc_pipe_client **presult)
3789 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3790 interface,
3791 transport,
3792 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3793 auth_level,
3794 domain,
3795 username,
3796 password,
3797 presult);
3800 /****************************************************************************
3801 Get a the schannel session key out of an already opened netlogon pipe.
3802 ****************************************************************************/
3803 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3804 struct cli_state *cli,
3805 const char *domain,
3806 uint32 *pneg_flags)
3808 uint32 sec_chan_type = 0;
3809 unsigned char machine_pwd[16];
3810 const char *machine_account;
3811 NTSTATUS status;
3813 /* Get the machine account credentials from secrets.tdb. */
3814 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3815 &sec_chan_type))
3817 DEBUG(0, ("get_schannel_session_key: could not fetch "
3818 "trust account password for domain '%s'\n",
3819 domain));
3820 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3823 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3824 cli->desthost, /* server name */
3825 domain, /* domain */
3826 global_myname(), /* client name */
3827 machine_account, /* machine account name */
3828 machine_pwd,
3829 sec_chan_type,
3830 pneg_flags);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 DEBUG(3, ("get_schannel_session_key_common: "
3834 "rpccli_netlogon_setup_creds failed with result %s "
3835 "to server %s, domain %s, machine account %s.\n",
3836 nt_errstr(status), cli->desthost, domain,
3837 machine_account ));
3838 return status;
3841 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3842 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3843 cli->desthost));
3844 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3847 return NT_STATUS_OK;;
3850 /****************************************************************************
3851 Open a netlogon pipe and get the schannel session key.
3852 Now exposed to external callers.
3853 ****************************************************************************/
3856 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3857 const char *domain,
3858 uint32 *pneg_flags,
3859 struct rpc_pipe_client **presult)
3861 struct rpc_pipe_client *netlogon_pipe = NULL;
3862 NTSTATUS status;
3864 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3865 &netlogon_pipe);
3866 if (!NT_STATUS_IS_OK(status)) {
3867 return status;
3870 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3871 pneg_flags);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 TALLOC_FREE(netlogon_pipe);
3874 return status;
3877 *presult = netlogon_pipe;
3878 return NT_STATUS_OK;
3881 /****************************************************************************
3882 External interface.
3883 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3884 using session_key. sign and seal.
3886 The *pdc will be stolen onto this new pipe
3887 ****************************************************************************/
3889 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3890 const struct ndr_syntax_id *interface,
3891 enum dcerpc_transport_t transport,
3892 enum dcerpc_AuthLevel auth_level,
3893 const char *domain,
3894 struct netlogon_creds_CredentialState **pdc,
3895 struct rpc_pipe_client **presult)
3897 struct rpc_pipe_client *result;
3898 struct cli_pipe_auth_data *auth;
3899 NTSTATUS status;
3901 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3902 if (!NT_STATUS_IS_OK(status)) {
3903 return status;
3906 status = rpccli_schannel_bind_data(result, domain, auth_level,
3907 (*pdc)->session_key, &auth);
3908 if (!NT_STATUS_IS_OK(status)) {
3909 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3910 nt_errstr(status)));
3911 TALLOC_FREE(result);
3912 return status;
3915 status = rpc_pipe_bind(result, auth);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3918 "cli_rpc_pipe_bind failed with error %s\n",
3919 nt_errstr(status) ));
3920 TALLOC_FREE(result);
3921 return status;
3925 * The credentials on a new netlogon pipe are the ones we are passed
3926 * in - reference them in
3928 result->dc = talloc_move(result, pdc);
3929 if (result->dc == NULL) {
3930 DEBUG(0, ("talloc reference failed\n"));
3931 TALLOC_FREE(result);
3932 return NT_STATUS_NO_MEMORY;
3935 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3936 "for domain %s and bound using schannel.\n",
3937 get_pipe_name_from_iface(interface),
3938 cli->desthost, domain ));
3940 *presult = result;
3941 return NT_STATUS_OK;
3944 /****************************************************************************
3945 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3946 Fetch the session key ourselves using a temporary netlogon pipe. This
3947 version uses an ntlmssp auth bound netlogon pipe to get the key.
3948 ****************************************************************************/
3950 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3951 const char *domain,
3952 const char *username,
3953 const char *password,
3954 uint32 *pneg_flags,
3955 struct rpc_pipe_client **presult)
3957 struct rpc_pipe_client *netlogon_pipe = NULL;
3958 NTSTATUS status;
3960 status = cli_rpc_pipe_open_spnego_ntlmssp(
3961 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3962 DCERPC_AUTH_LEVEL_PRIVACY,
3963 domain, username, password, &netlogon_pipe);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 return status;
3968 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3969 pneg_flags);
3970 if (!NT_STATUS_IS_OK(status)) {
3971 TALLOC_FREE(netlogon_pipe);
3972 return status;
3975 *presult = netlogon_pipe;
3976 return NT_STATUS_OK;
3979 /****************************************************************************
3980 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3981 Fetch the session key ourselves using a temporary netlogon pipe. This version
3982 uses an ntlmssp bind to get the session key.
3983 ****************************************************************************/
3985 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3986 const struct ndr_syntax_id *interface,
3987 enum dcerpc_transport_t transport,
3988 enum dcerpc_AuthLevel auth_level,
3989 const char *domain,
3990 const char *username,
3991 const char *password,
3992 struct rpc_pipe_client **presult)
3994 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3995 struct rpc_pipe_client *netlogon_pipe = NULL;
3996 struct rpc_pipe_client *result = NULL;
3997 NTSTATUS status;
3999 status = get_schannel_session_key_auth_ntlmssp(
4000 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4003 "key from server %s for domain %s.\n",
4004 cli->desthost, domain ));
4005 return status;
4008 status = cli_rpc_pipe_open_schannel_with_key(
4009 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4010 &result);
4012 /* Now we've bound using the session key we can close the netlog pipe. */
4013 TALLOC_FREE(netlogon_pipe);
4015 if (NT_STATUS_IS_OK(status)) {
4016 *presult = result;
4018 return status;
4021 /****************************************************************************
4022 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4023 Fetch the session key ourselves using a temporary netlogon pipe.
4024 ****************************************************************************/
4026 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4027 const struct ndr_syntax_id *interface,
4028 enum dcerpc_transport_t transport,
4029 enum dcerpc_AuthLevel auth_level,
4030 const char *domain,
4031 struct rpc_pipe_client **presult)
4033 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4034 struct rpc_pipe_client *netlogon_pipe = NULL;
4035 struct rpc_pipe_client *result = NULL;
4036 NTSTATUS status;
4038 status = get_schannel_session_key(cli, domain, &neg_flags,
4039 &netlogon_pipe);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4042 "key from server %s for domain %s.\n",
4043 cli->desthost, domain ));
4044 return status;
4047 status = cli_rpc_pipe_open_schannel_with_key(
4048 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4049 &result);
4051 /* Now we've bound using the session key we can close the netlog pipe. */
4052 TALLOC_FREE(netlogon_pipe);
4054 if (NT_STATUS_IS_OK(status)) {
4055 *presult = result;
4058 return NT_STATUS_OK;
4061 /****************************************************************************
4062 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4063 The idea is this can be called with service_princ, username and password all
4064 NULL so long as the caller has a TGT.
4065 ****************************************************************************/
4067 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4068 const struct ndr_syntax_id *interface,
4069 enum dcerpc_AuthLevel auth_level,
4070 const char *service_princ,
4071 const char *username,
4072 const char *password,
4073 struct rpc_pipe_client **presult)
4075 #ifdef HAVE_KRB5
4076 struct rpc_pipe_client *result;
4077 struct cli_pipe_auth_data *auth;
4078 NTSTATUS status;
4080 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 return status;
4085 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4086 username, password, &auth);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4089 nt_errstr(status)));
4090 TALLOC_FREE(result);
4091 return status;
4094 status = rpc_pipe_bind(result, auth);
4095 if (!NT_STATUS_IS_OK(status)) {
4096 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4097 "with error %s\n", nt_errstr(status)));
4098 TALLOC_FREE(result);
4099 return status;
4102 *presult = result;
4103 return NT_STATUS_OK;
4104 #else
4105 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4106 return NT_STATUS_NOT_IMPLEMENTED;
4107 #endif
4110 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4111 struct rpc_pipe_client *cli,
4112 DATA_BLOB *session_key)
4114 if (!session_key || !cli) {
4115 return NT_STATUS_INVALID_PARAMETER;
4118 if (!cli->auth) {
4119 return NT_STATUS_INVALID_PARAMETER;
4122 switch (cli->auth->auth_type) {
4123 case PIPE_AUTH_TYPE_SCHANNEL:
4124 *session_key = data_blob_talloc(mem_ctx,
4125 cli->auth->a_u.schannel_auth->sess_key, 16);
4126 break;
4127 case PIPE_AUTH_TYPE_NTLMSSP:
4128 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4129 *session_key = data_blob_talloc(mem_ctx,
4130 cli->auth->a_u.ntlmssp_state->session_key.data,
4131 cli->auth->a_u.ntlmssp_state->session_key.length);
4132 break;
4133 case PIPE_AUTH_TYPE_KRB5:
4134 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4135 *session_key = data_blob_talloc(mem_ctx,
4136 cli->auth->a_u.kerberos_auth->session_key.data,
4137 cli->auth->a_u.kerberos_auth->session_key.length);
4138 break;
4139 case PIPE_AUTH_TYPE_NONE:
4140 *session_key = data_blob_talloc(mem_ctx,
4141 cli->auth->user_session_key.data,
4142 cli->auth->user_session_key.length);
4143 break;
4144 default:
4145 return NT_STATUS_NO_USER_SESSION_KEY;
4148 return NT_STATUS_OK;