s4-ldb: cope better with corruption of tdb records
[Samba/aatanasov.git] / source3 / rpc_client / cli_pipe.c
blobfebf7878158e74f906f6d1ffa3b4f7fe106642c9
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_CLI
30 /*******************************************************************
31 interface/version dce/rpc pipe identification
32 ********************************************************************/
34 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
35 #define PIPE_SAMR "\\PIPE\\samr"
36 #define PIPE_WINREG "\\PIPE\\winreg"
37 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
38 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
39 #define PIPE_NTLSA "\\PIPE\\ntlsa"
40 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
41 #define PIPE_LSASS "\\PIPE\\lsass"
42 #define PIPE_LSARPC "\\PIPE\\lsarpc"
43 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
44 #define PIPE_NETDFS "\\PIPE\\netdfs"
45 #define PIPE_ECHO "\\PIPE\\rpcecho"
46 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
47 #define PIPE_EPM "\\PIPE\\epmapper"
48 #define PIPE_SVCCTL "\\PIPE\\svcctl"
49 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
50 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
51 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
54 * IMPORTANT!! If you update this structure, make sure to
55 * update the index #defines in smb.h.
58 static const struct pipe_id_info {
59 /* the names appear not to matter: the syntaxes _do_ matter */
61 const char *client_pipe;
62 const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
63 } pipe_names [] =
65 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
66 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
67 { PIPE_SAMR, &ndr_table_samr.syntax_id },
68 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
69 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
70 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
71 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
72 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
73 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
74 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
75 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
76 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
77 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
78 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
79 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
80 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
81 { NULL, NULL }
84 /****************************************************************************
85 Return the pipe name from the interface.
86 ****************************************************************************/
88 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
90 char *guid_str;
91 const char *result;
92 int i;
93 for (i = 0; pipe_names[i].client_pipe; i++) {
94 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
95 interface)) {
96 return &pipe_names[i].client_pipe[5];
101 * Here we should ask \\epmapper, but for now our code is only
102 * interested in the known pipes mentioned in pipe_names[]
105 guid_str = GUID_string(talloc_tos(), &interface->uuid);
106 if (guid_str == NULL) {
107 return NULL;
109 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
110 (int)interface->if_version);
111 TALLOC_FREE(guid_str);
113 if (result == NULL) {
114 return "PIPE";
116 return result;
119 /********************************************************************
120 Map internal value to wire value.
121 ********************************************************************/
123 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
125 switch (auth_type) {
127 case PIPE_AUTH_TYPE_NONE:
128 return DCERPC_AUTH_TYPE_NONE;
130 case PIPE_AUTH_TYPE_NTLMSSP:
131 return DCERPC_AUTH_TYPE_NTLMSSP;
133 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
134 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
135 return DCERPC_AUTH_TYPE_SPNEGO;
137 case PIPE_AUTH_TYPE_SCHANNEL:
138 return DCERPC_AUTH_TYPE_SCHANNEL;
140 case PIPE_AUTH_TYPE_KRB5:
141 return DCERPC_AUTH_TYPE_KRB5;
143 default:
144 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
145 "auth type %u\n",
146 (unsigned int)auth_type ));
147 break;
149 return -1;
152 /********************************************************************
153 Pipe description for a DEBUG
154 ********************************************************************/
155 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
156 struct rpc_pipe_client *cli)
158 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
159 if (result == NULL) {
160 return "pipe";
162 return result;
165 /********************************************************************
166 Rpc pipe call id.
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
172 return ++call_id;
176 * Realloc pdu to have a least "size" bytes
179 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
181 size_t extra_size;
183 if (prs_data_size(pdu) >= size) {
184 return true;
187 extra_size = size - prs_data_size(pdu);
189 if (!prs_force_grow(pdu, extra_size)) {
190 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
191 "%d bytes.\n", (int)extra_size));
192 return false;
195 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
196 (int)extra_size, prs_data_size(pdu)));
197 return true;
201 /*******************************************************************
202 Use SMBreadX to get rest of one fragment's worth of rpc data.
203 Reads the whole size or give an error message
204 ********************************************************************/
206 struct rpc_read_state {
207 struct event_context *ev;
208 struct rpc_cli_transport *transport;
209 uint8_t *data;
210 size_t size;
211 size_t num_read;
214 static void rpc_read_done(struct tevent_req *subreq);
216 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
217 struct event_context *ev,
218 struct rpc_cli_transport *transport,
219 uint8_t *data, size_t size)
221 struct tevent_req *req, *subreq;
222 struct rpc_read_state *state;
224 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
225 if (req == NULL) {
226 return NULL;
228 state->ev = ev;
229 state->transport = transport;
230 state->data = data;
231 state->size = size;
232 state->num_read = 0;
234 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
236 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
237 transport->priv);
238 if (subreq == NULL) {
239 goto fail;
241 tevent_req_set_callback(subreq, rpc_read_done, req);
242 return req;
244 fail:
245 TALLOC_FREE(req);
246 return NULL;
249 static void rpc_read_done(struct tevent_req *subreq)
251 struct tevent_req *req = tevent_req_callback_data(
252 subreq, struct tevent_req);
253 struct rpc_read_state *state = tevent_req_data(
254 req, struct rpc_read_state);
255 NTSTATUS status;
256 ssize_t received;
258 status = state->transport->read_recv(subreq, &received);
259 TALLOC_FREE(subreq);
260 if (!NT_STATUS_IS_OK(status)) {
261 tevent_req_nterror(req, status);
262 return;
265 state->num_read += received;
266 if (state->num_read == state->size) {
267 tevent_req_done(req);
268 return;
271 subreq = state->transport->read_send(state, state->ev,
272 state->data + state->num_read,
273 state->size - state->num_read,
274 state->transport->priv);
275 if (tevent_req_nomem(subreq, req)) {
276 return;
278 tevent_req_set_callback(subreq, rpc_read_done, req);
281 static NTSTATUS rpc_read_recv(struct tevent_req *req)
283 return tevent_req_simple_recv_ntstatus(req);
286 struct rpc_write_state {
287 struct event_context *ev;
288 struct rpc_cli_transport *transport;
289 const uint8_t *data;
290 size_t size;
291 size_t num_written;
294 static void rpc_write_done(struct tevent_req *subreq);
296 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
297 struct event_context *ev,
298 struct rpc_cli_transport *transport,
299 const uint8_t *data, size_t size)
301 struct tevent_req *req, *subreq;
302 struct rpc_write_state *state;
304 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
305 if (req == NULL) {
306 return NULL;
308 state->ev = ev;
309 state->transport = transport;
310 state->data = data;
311 state->size = size;
312 state->num_written = 0;
314 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
316 subreq = transport->write_send(state, ev, data, size, transport->priv);
317 if (subreq == NULL) {
318 goto fail;
320 tevent_req_set_callback(subreq, rpc_write_done, req);
321 return req;
322 fail:
323 TALLOC_FREE(req);
324 return NULL;
327 static void rpc_write_done(struct tevent_req *subreq)
329 struct tevent_req *req = tevent_req_callback_data(
330 subreq, struct tevent_req);
331 struct rpc_write_state *state = tevent_req_data(
332 req, struct rpc_write_state);
333 NTSTATUS status;
334 ssize_t written;
336 status = state->transport->write_recv(subreq, &written);
337 TALLOC_FREE(subreq);
338 if (!NT_STATUS_IS_OK(status)) {
339 tevent_req_nterror(req, status);
340 return;
343 state->num_written += written;
345 if (state->num_written == state->size) {
346 tevent_req_done(req);
347 return;
350 subreq = state->transport->write_send(state, state->ev,
351 state->data + state->num_written,
352 state->size - state->num_written,
353 state->transport->priv);
354 if (tevent_req_nomem(subreq, req)) {
355 return;
357 tevent_req_set_callback(subreq, rpc_write_done, req);
360 static NTSTATUS rpc_write_recv(struct tevent_req *req)
362 return tevent_req_simple_recv_ntstatus(req);
366 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
367 struct rpc_hdr_info *prhdr,
368 prs_struct *pdu)
371 * This next call sets the endian bit correctly in current_pdu. We
372 * will propagate this to rbuf later.
375 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
376 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
377 return NT_STATUS_BUFFER_TOO_SMALL;
380 if (prhdr->frag_len > cli->max_recv_frag) {
381 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
382 " we only allow %d\n", (int)prhdr->frag_len,
383 (int)cli->max_recv_frag));
384 return NT_STATUS_BUFFER_TOO_SMALL;
387 return NT_STATUS_OK;
390 /****************************************************************************
391 Try and get a PDU's worth of data from current_pdu. If not, then read more
392 from the wire.
393 ****************************************************************************/
395 struct get_complete_frag_state {
396 struct event_context *ev;
397 struct rpc_pipe_client *cli;
398 struct rpc_hdr_info *prhdr;
399 prs_struct *pdu;
402 static void get_complete_frag_got_header(struct tevent_req *subreq);
403 static void get_complete_frag_got_rest(struct tevent_req *subreq);
405 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
406 struct event_context *ev,
407 struct rpc_pipe_client *cli,
408 struct rpc_hdr_info *prhdr,
409 prs_struct *pdu)
411 struct tevent_req *req, *subreq;
412 struct get_complete_frag_state *state;
413 uint32_t pdu_len;
414 NTSTATUS status;
416 req = tevent_req_create(mem_ctx, &state,
417 struct get_complete_frag_state);
418 if (req == NULL) {
419 return NULL;
421 state->ev = ev;
422 state->cli = cli;
423 state->prhdr = prhdr;
424 state->pdu = pdu;
426 pdu_len = prs_data_size(pdu);
427 if (pdu_len < RPC_HEADER_LEN) {
428 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
429 status = NT_STATUS_NO_MEMORY;
430 goto post_status;
432 subreq = rpc_read_send(
433 state, state->ev,
434 state->cli->transport,
435 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
436 RPC_HEADER_LEN - pdu_len);
437 if (subreq == NULL) {
438 status = NT_STATUS_NO_MEMORY;
439 goto post_status;
441 tevent_req_set_callback(subreq, get_complete_frag_got_header,
442 req);
443 return req;
446 status = parse_rpc_header(cli, prhdr, pdu);
447 if (!NT_STATUS_IS_OK(status)) {
448 goto post_status;
452 * Ensure we have frag_len bytes of data.
454 if (pdu_len < prhdr->frag_len) {
455 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
456 status = NT_STATUS_NO_MEMORY;
457 goto post_status;
459 subreq = rpc_read_send(state, state->ev,
460 state->cli->transport,
461 (uint8_t *)(prs_data_p(pdu) + pdu_len),
462 prhdr->frag_len - pdu_len);
463 if (subreq == NULL) {
464 status = NT_STATUS_NO_MEMORY;
465 goto post_status;
467 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
468 req);
469 return req;
472 status = NT_STATUS_OK;
473 post_status:
474 if (NT_STATUS_IS_OK(status)) {
475 tevent_req_done(req);
476 } else {
477 tevent_req_nterror(req, status);
479 return tevent_req_post(req, ev);
482 static void get_complete_frag_got_header(struct tevent_req *subreq)
484 struct tevent_req *req = tevent_req_callback_data(
485 subreq, struct tevent_req);
486 struct get_complete_frag_state *state = tevent_req_data(
487 req, struct get_complete_frag_state);
488 NTSTATUS status;
490 status = rpc_read_recv(subreq);
491 TALLOC_FREE(subreq);
492 if (!NT_STATUS_IS_OK(status)) {
493 tevent_req_nterror(req, status);
494 return;
497 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
498 if (!NT_STATUS_IS_OK(status)) {
499 tevent_req_nterror(req, status);
500 return;
503 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
504 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
505 return;
509 * We're here in this piece of code because we've read exactly
510 * RPC_HEADER_LEN bytes into state->pdu.
513 subreq = rpc_read_send(
514 state, state->ev, state->cli->transport,
515 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
516 state->prhdr->frag_len - RPC_HEADER_LEN);
517 if (tevent_req_nomem(subreq, req)) {
518 return;
520 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
523 static void get_complete_frag_got_rest(struct tevent_req *subreq)
525 struct tevent_req *req = tevent_req_callback_data(
526 subreq, struct tevent_req);
527 NTSTATUS status;
529 status = rpc_read_recv(subreq);
530 TALLOC_FREE(subreq);
531 if (!NT_STATUS_IS_OK(status)) {
532 tevent_req_nterror(req, status);
533 return;
535 tevent_req_done(req);
538 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
540 return tevent_req_simple_recv_ntstatus(req);
543 /****************************************************************************
544 NTLMSSP specific sign/seal.
545 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
546 In fact I should probably abstract these into identical pieces of code... JRA.
547 ****************************************************************************/
549 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
550 prs_struct *current_pdu,
551 uint8 *p_ss_padding_len)
553 RPC_HDR_AUTH auth_info;
554 uint32 save_offset = prs_offset(current_pdu);
555 uint32 auth_len = prhdr->auth_len;
556 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
557 unsigned char *data = NULL;
558 size_t data_len;
559 unsigned char *full_packet_data = NULL;
560 size_t full_packet_data_len;
561 DATA_BLOB auth_blob;
562 NTSTATUS status;
564 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
565 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
566 return NT_STATUS_OK;
569 if (!ntlmssp_state) {
570 return NT_STATUS_INVALID_PARAMETER;
573 /* Ensure there's enough data for an authenticated response. */
574 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
575 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
576 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
577 (unsigned int)auth_len ));
578 return NT_STATUS_BUFFER_TOO_SMALL;
582 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
583 * after the RPC header.
584 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
585 * functions as NTLMv2 checks the rpc headers also.
588 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
589 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
591 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
592 full_packet_data_len = prhdr->frag_len - auth_len;
594 /* Pull the auth header and the following data into a blob. */
595 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
596 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
597 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
598 return NT_STATUS_BUFFER_TOO_SMALL;
601 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
602 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
603 return NT_STATUS_BUFFER_TOO_SMALL;
606 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
607 auth_blob.length = auth_len;
609 switch (cli->auth->auth_level) {
610 case DCERPC_AUTH_LEVEL_PRIVACY:
611 /* Data is encrypted. */
612 status = ntlmssp_unseal_packet(ntlmssp_state,
613 data, data_len,
614 full_packet_data,
615 full_packet_data_len,
616 &auth_blob);
617 if (!NT_STATUS_IS_OK(status)) {
618 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
619 "packet from %s. Error was %s.\n",
620 rpccli_pipe_txt(debug_ctx(), cli),
621 nt_errstr(status) ));
622 return status;
624 break;
625 case DCERPC_AUTH_LEVEL_INTEGRITY:
626 /* Data is signed. */
627 status = ntlmssp_check_packet(ntlmssp_state,
628 data, data_len,
629 full_packet_data,
630 full_packet_data_len,
631 &auth_blob);
632 if (!NT_STATUS_IS_OK(status)) {
633 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
634 "packet from %s. Error was %s.\n",
635 rpccli_pipe_txt(debug_ctx(), cli),
636 nt_errstr(status) ));
637 return status;
639 break;
640 default:
641 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
642 "auth level %d\n", cli->auth->auth_level));
643 return NT_STATUS_INVALID_INFO_CLASS;
647 * Return the current pointer to the data offset.
650 if(!prs_set_offset(current_pdu, save_offset)) {
651 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
652 (unsigned int)save_offset ));
653 return NT_STATUS_BUFFER_TOO_SMALL;
657 * Remember the padding length. We must remove it from the real data
658 * stream once the sign/seal is done.
661 *p_ss_padding_len = auth_info.auth_pad_len;
663 return NT_STATUS_OK;
666 /****************************************************************************
667 schannel specific sign/seal.
668 ****************************************************************************/
670 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
671 prs_struct *current_pdu,
672 uint8 *p_ss_padding_len)
674 RPC_HDR_AUTH auth_info;
675 struct NL_AUTH_SIGNATURE schannel_chk;
676 uint32 auth_len = prhdr->auth_len;
677 uint32 save_offset = prs_offset(current_pdu);
678 struct schannel_state *schannel_auth =
679 cli->auth->a_u.schannel_auth;
680 uint32 data_len;
681 enum ndr_err_code ndr_err;
682 DATA_BLOB blob;
683 NTSTATUS status;
685 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
686 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
687 return NT_STATUS_OK;
690 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
691 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
692 return NT_STATUS_INVALID_PARAMETER;
695 if (!schannel_auth) {
696 return NT_STATUS_INVALID_PARAMETER;
699 /* Ensure there's enough data for an authenticated response. */
700 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
701 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
702 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
703 (unsigned int)auth_len ));
704 return NT_STATUS_INVALID_PARAMETER;
707 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
709 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
710 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
711 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
712 return NT_STATUS_BUFFER_TOO_SMALL;
715 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
716 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
717 return NT_STATUS_BUFFER_TOO_SMALL;
720 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
721 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
722 auth_info.auth_type));
723 return NT_STATUS_BUFFER_TOO_SMALL;
726 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
728 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &schannel_chk,
729 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_SIGNATURE);
730 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
731 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
732 return ndr_map_error2ntstatus(ndr_err);
735 if (DEBUGLEVEL >= 10) {
736 NDR_PRINT_DEBUG(NL_AUTH_SIGNATURE, &schannel_chk);
739 switch (cli->auth->auth_level) {
740 case DCERPC_AUTH_LEVEL_PRIVACY:
741 status = schannel_unseal_packet(schannel_auth,
742 talloc_tos(),
743 (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
744 data_len,
745 &blob);
746 break;
747 case DCERPC_AUTH_LEVEL_INTEGRITY:
748 status = schannel_check_packet(schannel_auth,
749 talloc_tos(),
750 (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
751 data_len,
752 &blob);
753 break;
754 default:
755 status = NT_STATUS_INTERNAL_ERROR;
756 break;
759 if (!NT_STATUS_IS_OK(status)) {
760 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
761 "Connection to %s (%s).\n",
762 rpccli_pipe_txt(debug_ctx(), cli),
763 nt_errstr(status)));
764 return NT_STATUS_INVALID_PARAMETER;
768 * Return the current pointer to the data offset.
771 if(!prs_set_offset(current_pdu, save_offset)) {
772 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
773 (unsigned int)save_offset ));
774 return NT_STATUS_BUFFER_TOO_SMALL;
778 * Remember the padding length. We must remove it from the real data
779 * stream once the sign/seal is done.
782 *p_ss_padding_len = auth_info.auth_pad_len;
784 return NT_STATUS_OK;
787 /****************************************************************************
788 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
789 ****************************************************************************/
791 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
792 prs_struct *current_pdu,
793 uint8 *p_ss_padding_len)
795 NTSTATUS ret = NT_STATUS_OK;
797 /* Paranioa checks for auth_len. */
798 if (prhdr->auth_len) {
799 if (prhdr->auth_len > prhdr->frag_len) {
800 return NT_STATUS_INVALID_PARAMETER;
803 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
804 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
805 /* Integer wrap attempt. */
806 return NT_STATUS_INVALID_PARAMETER;
811 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
814 switch(cli->auth->auth_type) {
815 case PIPE_AUTH_TYPE_NONE:
816 if (prhdr->auth_len) {
817 DEBUG(3, ("cli_pipe_validate_rpc_response: "
818 "Connection to %s - got non-zero "
819 "auth len %u.\n",
820 rpccli_pipe_txt(debug_ctx(), cli),
821 (unsigned int)prhdr->auth_len ));
822 return NT_STATUS_INVALID_PARAMETER;
824 break;
826 case PIPE_AUTH_TYPE_NTLMSSP:
827 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
828 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
829 if (!NT_STATUS_IS_OK(ret)) {
830 return ret;
832 break;
834 case PIPE_AUTH_TYPE_SCHANNEL:
835 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
836 if (!NT_STATUS_IS_OK(ret)) {
837 return ret;
839 break;
841 case PIPE_AUTH_TYPE_KRB5:
842 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
843 default:
844 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
845 "to %s - unknown internal auth type %u.\n",
846 rpccli_pipe_txt(debug_ctx(), cli),
847 cli->auth->auth_type ));
848 return NT_STATUS_INVALID_INFO_CLASS;
851 return NT_STATUS_OK;
854 /****************************************************************************
855 Do basic authentication checks on an incoming pdu.
856 ****************************************************************************/
858 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
859 prs_struct *current_pdu,
860 uint8 expected_pkt_type,
861 char **ppdata,
862 uint32 *pdata_len,
863 prs_struct *return_data)
866 NTSTATUS ret = NT_STATUS_OK;
867 uint32 current_pdu_len = prs_data_size(current_pdu);
869 if (current_pdu_len != prhdr->frag_len) {
870 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
871 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
872 return NT_STATUS_INVALID_PARAMETER;
876 * Point the return values at the real data including the RPC
877 * header. Just in case the caller wants it.
879 *ppdata = prs_data_p(current_pdu);
880 *pdata_len = current_pdu_len;
882 /* Ensure we have the correct type. */
883 switch (prhdr->pkt_type) {
884 case RPC_ALTCONTRESP:
885 case RPC_BINDACK:
887 /* Alter context and bind ack share the same packet definitions. */
888 break;
891 case RPC_RESPONSE:
893 RPC_HDR_RESP rhdr_resp;
894 uint8 ss_padding_len = 0;
896 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
897 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
898 return NT_STATUS_BUFFER_TOO_SMALL;
901 /* Here's where we deal with incoming sign/seal. */
902 ret = cli_pipe_validate_rpc_response(cli, prhdr,
903 current_pdu, &ss_padding_len);
904 if (!NT_STATUS_IS_OK(ret)) {
905 return ret;
908 /* Point the return values at the NDR data. Remember to remove any ss padding. */
909 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
911 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
912 return NT_STATUS_BUFFER_TOO_SMALL;
915 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
917 /* Remember to remove the auth footer. */
918 if (prhdr->auth_len) {
919 /* We've already done integer wrap tests on auth_len in
920 cli_pipe_validate_rpc_response(). */
921 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
922 return NT_STATUS_BUFFER_TOO_SMALL;
924 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
927 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
928 current_pdu_len, *pdata_len, ss_padding_len ));
931 * If this is the first reply, and the allocation hint is reasonably, try and
932 * set up the return_data parse_struct to the correct size.
935 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
936 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
937 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
938 "too large to allocate\n",
939 (unsigned int)rhdr_resp.alloc_hint ));
940 return NT_STATUS_NO_MEMORY;
944 break;
947 case RPC_BINDNACK:
948 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
949 "received from %s!\n",
950 rpccli_pipe_txt(debug_ctx(), cli)));
951 /* Use this for now... */
952 return NT_STATUS_NETWORK_ACCESS_DENIED;
954 case RPC_FAULT:
956 RPC_HDR_RESP rhdr_resp;
957 RPC_HDR_FAULT fault_resp;
959 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
960 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
961 return NT_STATUS_BUFFER_TOO_SMALL;
964 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
965 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
966 return NT_STATUS_BUFFER_TOO_SMALL;
969 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
970 "code %s received from %s!\n",
971 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
972 rpccli_pipe_txt(debug_ctx(), cli)));
973 if (NT_STATUS_IS_OK(fault_resp.status)) {
974 return NT_STATUS_UNSUCCESSFUL;
975 } else {
976 return fault_resp.status;
980 default:
981 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
982 "from %s!\n",
983 (unsigned int)prhdr->pkt_type,
984 rpccli_pipe_txt(debug_ctx(), cli)));
985 return NT_STATUS_INVALID_INFO_CLASS;
988 if (prhdr->pkt_type != expected_pkt_type) {
989 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
990 "got an unexpected RPC packet type - %u, not %u\n",
991 rpccli_pipe_txt(debug_ctx(), cli),
992 prhdr->pkt_type,
993 expected_pkt_type));
994 return NT_STATUS_INVALID_INFO_CLASS;
997 /* Do this just before return - we don't want to modify any rpc header
998 data before now as we may have needed to do cryptographic actions on
999 it before. */
1001 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
1002 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1003 "setting fragment first/last ON.\n"));
1004 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
1007 return NT_STATUS_OK;
1010 /****************************************************************************
1011 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1012 Normally the frag_len and buffer size will match, but on the first trans
1013 reply there is a theoretical chance that buffer size > frag_len, so we must
1014 deal with that.
1015 ****************************************************************************/
1017 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1019 uint32 current_pdu_len = prs_data_size(current_pdu);
1021 if (current_pdu_len < prhdr->frag_len) {
1022 return NT_STATUS_BUFFER_TOO_SMALL;
1025 /* Common case. */
1026 if (current_pdu_len == (uint32)prhdr->frag_len) {
1027 prs_mem_free(current_pdu);
1028 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1029 /* Make current_pdu dynamic with no memory. */
1030 prs_give_memory(current_pdu, 0, 0, True);
1031 return NT_STATUS_OK;
1035 * Oh no ! More data in buffer than we processed in current pdu.
1036 * Cheat. Move the data down and shrink the buffer.
1039 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1040 current_pdu_len - prhdr->frag_len);
1042 /* Remember to set the read offset back to zero. */
1043 prs_set_offset(current_pdu, 0);
1045 /* Shrink the buffer. */
1046 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1047 return NT_STATUS_BUFFER_TOO_SMALL;
1050 return NT_STATUS_OK;
1053 /****************************************************************************
1054 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1055 ****************************************************************************/
1057 struct cli_api_pipe_state {
1058 struct event_context *ev;
1059 struct rpc_cli_transport *transport;
1060 uint8_t *rdata;
1061 uint32_t rdata_len;
1064 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1065 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1066 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1068 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1069 struct event_context *ev,
1070 struct rpc_cli_transport *transport,
1071 uint8_t *data, size_t data_len,
1072 uint32_t max_rdata_len)
1074 struct tevent_req *req, *subreq;
1075 struct cli_api_pipe_state *state;
1076 NTSTATUS status;
1078 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1079 if (req == NULL) {
1080 return NULL;
1082 state->ev = ev;
1083 state->transport = transport;
1085 if (max_rdata_len < RPC_HEADER_LEN) {
1087 * For a RPC reply we always need at least RPC_HEADER_LEN
1088 * bytes. We check this here because we will receive
1089 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1091 status = NT_STATUS_INVALID_PARAMETER;
1092 goto post_status;
1095 if (transport->trans_send != NULL) {
1096 subreq = transport->trans_send(state, ev, data, data_len,
1097 max_rdata_len, transport->priv);
1098 if (subreq == NULL) {
1099 goto fail;
1101 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1102 return req;
1106 * If the transport does not provide a "trans" routine, i.e. for
1107 * example the ncacn_ip_tcp transport, do the write/read step here.
1110 subreq = rpc_write_send(state, ev, transport, data, data_len);
1111 if (subreq == NULL) {
1112 goto fail;
1114 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1115 return req;
1117 status = NT_STATUS_INVALID_PARAMETER;
1119 post_status:
1120 tevent_req_nterror(req, status);
1121 return tevent_req_post(req, ev);
1122 fail:
1123 TALLOC_FREE(req);
1124 return NULL;
1127 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1129 struct tevent_req *req = tevent_req_callback_data(
1130 subreq, struct tevent_req);
1131 struct cli_api_pipe_state *state = tevent_req_data(
1132 req, struct cli_api_pipe_state);
1133 NTSTATUS status;
1135 status = state->transport->trans_recv(subreq, state, &state->rdata,
1136 &state->rdata_len);
1137 TALLOC_FREE(subreq);
1138 if (!NT_STATUS_IS_OK(status)) {
1139 tevent_req_nterror(req, status);
1140 return;
1142 tevent_req_done(req);
1145 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1147 struct tevent_req *req = tevent_req_callback_data(
1148 subreq, struct tevent_req);
1149 struct cli_api_pipe_state *state = tevent_req_data(
1150 req, struct cli_api_pipe_state);
1151 NTSTATUS status;
1153 status = rpc_write_recv(subreq);
1154 TALLOC_FREE(subreq);
1155 if (!NT_STATUS_IS_OK(status)) {
1156 tevent_req_nterror(req, status);
1157 return;
1160 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1161 if (tevent_req_nomem(state->rdata, req)) {
1162 return;
1166 * We don't need to use rpc_read_send here, the upper layer will cope
1167 * with a short read, transport->trans_send could also return less
1168 * than state->max_rdata_len.
1170 subreq = state->transport->read_send(state, state->ev, state->rdata,
1171 RPC_HEADER_LEN,
1172 state->transport->priv);
1173 if (tevent_req_nomem(subreq, req)) {
1174 return;
1176 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1179 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1181 struct tevent_req *req = tevent_req_callback_data(
1182 subreq, struct tevent_req);
1183 struct cli_api_pipe_state *state = tevent_req_data(
1184 req, struct cli_api_pipe_state);
1185 NTSTATUS status;
1186 ssize_t received;
1188 status = state->transport->read_recv(subreq, &received);
1189 TALLOC_FREE(subreq);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 tevent_req_nterror(req, status);
1192 return;
1194 state->rdata_len = received;
1195 tevent_req_done(req);
1198 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1199 uint8_t **prdata, uint32_t *prdata_len)
1201 struct cli_api_pipe_state *state = tevent_req_data(
1202 req, struct cli_api_pipe_state);
1203 NTSTATUS status;
1205 if (tevent_req_is_nterror(req, &status)) {
1206 return status;
1209 *prdata = talloc_move(mem_ctx, &state->rdata);
1210 *prdata_len = state->rdata_len;
1211 return NT_STATUS_OK;
1214 /****************************************************************************
1215 Send data on an rpc pipe via trans. The prs_struct data must be the last
1216 pdu fragment of an NDR data stream.
1218 Receive response data from an rpc pipe, which may be large...
1220 Read the first fragment: unfortunately have to use SMBtrans for the first
1221 bit, then SMBreadX for subsequent bits.
1223 If first fragment received also wasn't the last fragment, continue
1224 getting fragments until we _do_ receive the last fragment.
1226 Request/Response PDU's look like the following...
1228 |<------------------PDU len----------------------------------------------->|
1229 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1231 +------------+-----------------+-------------+---------------+-------------+
1232 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1233 +------------+-----------------+-------------+---------------+-------------+
1235 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1236 signing & sealing being negotiated.
1238 ****************************************************************************/
1240 struct rpc_api_pipe_state {
1241 struct event_context *ev;
1242 struct rpc_pipe_client *cli;
1243 uint8_t expected_pkt_type;
1245 prs_struct incoming_frag;
1246 struct rpc_hdr_info rhdr;
1248 prs_struct incoming_pdu; /* Incoming reply */
1249 uint32_t incoming_pdu_offset;
1252 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1254 prs_mem_free(&state->incoming_frag);
1255 prs_mem_free(&state->incoming_pdu);
1256 return 0;
1259 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1260 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1262 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1263 struct event_context *ev,
1264 struct rpc_pipe_client *cli,
1265 prs_struct *data, /* Outgoing PDU */
1266 uint8_t expected_pkt_type)
1268 struct tevent_req *req, *subreq;
1269 struct rpc_api_pipe_state *state;
1270 uint16_t max_recv_frag;
1271 NTSTATUS status;
1273 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1274 if (req == NULL) {
1275 return NULL;
1277 state->ev = ev;
1278 state->cli = cli;
1279 state->expected_pkt_type = expected_pkt_type;
1280 state->incoming_pdu_offset = 0;
1282 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1284 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1285 /* Make incoming_pdu dynamic with no memory. */
1286 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1288 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1291 * Ensure we're not sending too much.
1293 if (prs_offset(data) > cli->max_xmit_frag) {
1294 status = NT_STATUS_INVALID_PARAMETER;
1295 goto post_status;
1298 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1300 max_recv_frag = cli->max_recv_frag;
1302 #ifdef DEVELOPER
1303 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1304 #endif
1306 subreq = cli_api_pipe_send(state, ev, cli->transport,
1307 (uint8_t *)prs_data_p(data),
1308 prs_offset(data), max_recv_frag);
1309 if (subreq == NULL) {
1310 goto fail;
1312 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1313 return req;
1315 post_status:
1316 tevent_req_nterror(req, status);
1317 return tevent_req_post(req, ev);
1318 fail:
1319 TALLOC_FREE(req);
1320 return NULL;
1323 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1325 struct tevent_req *req = tevent_req_callback_data(
1326 subreq, struct tevent_req);
1327 struct rpc_api_pipe_state *state = tevent_req_data(
1328 req, struct rpc_api_pipe_state);
1329 NTSTATUS status;
1330 uint8_t *rdata = NULL;
1331 uint32_t rdata_len = 0;
1332 char *rdata_copy;
1334 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1335 TALLOC_FREE(subreq);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1338 tevent_req_nterror(req, status);
1339 return;
1342 if (rdata == NULL) {
1343 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1344 rpccli_pipe_txt(debug_ctx(), state->cli)));
1345 tevent_req_done(req);
1346 return;
1350 * Give the memory received from cli_trans as dynamic to the current
1351 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1352 * :-(
1354 rdata_copy = (char *)memdup(rdata, rdata_len);
1355 TALLOC_FREE(rdata);
1356 if (tevent_req_nomem(rdata_copy, req)) {
1357 return;
1359 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1361 /* Ensure we have enough data for a pdu. */
1362 subreq = get_complete_frag_send(state, state->ev, state->cli,
1363 &state->rhdr, &state->incoming_frag);
1364 if (tevent_req_nomem(subreq, req)) {
1365 return;
1367 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1370 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1372 struct tevent_req *req = tevent_req_callback_data(
1373 subreq, struct tevent_req);
1374 struct rpc_api_pipe_state *state = tevent_req_data(
1375 req, struct rpc_api_pipe_state);
1376 NTSTATUS status;
1377 char *rdata = NULL;
1378 uint32_t rdata_len = 0;
1380 status = get_complete_frag_recv(subreq);
1381 TALLOC_FREE(subreq);
1382 if (!NT_STATUS_IS_OK(status)) {
1383 DEBUG(5, ("get_complete_frag failed: %s\n",
1384 nt_errstr(status)));
1385 tevent_req_nterror(req, status);
1386 return;
1389 status = cli_pipe_validate_current_pdu(
1390 state->cli, &state->rhdr, &state->incoming_frag,
1391 state->expected_pkt_type, &rdata, &rdata_len,
1392 &state->incoming_pdu);
1394 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1395 (unsigned)prs_data_size(&state->incoming_frag),
1396 (unsigned)state->incoming_pdu_offset,
1397 nt_errstr(status)));
1399 if (!NT_STATUS_IS_OK(status)) {
1400 tevent_req_nterror(req, status);
1401 return;
1404 if ((state->rhdr.flags & RPC_FLG_FIRST)
1405 && (state->rhdr.pack_type[0] == 0)) {
1407 * Set the data type correctly for big-endian data on the
1408 * first packet.
1410 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1411 "big-endian.\n",
1412 rpccli_pipe_txt(debug_ctx(), state->cli)));
1413 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1416 * Check endianness on subsequent packets.
1418 if (state->incoming_frag.bigendian_data
1419 != state->incoming_pdu.bigendian_data) {
1420 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1421 "%s\n",
1422 state->incoming_pdu.bigendian_data?"big":"little",
1423 state->incoming_frag.bigendian_data?"big":"little"));
1424 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1425 return;
1428 /* Now copy the data portion out of the pdu into rbuf. */
1429 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1430 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1431 return;
1434 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1435 rdata, (size_t)rdata_len);
1436 state->incoming_pdu_offset += rdata_len;
1438 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1439 &state->incoming_frag);
1440 if (!NT_STATUS_IS_OK(status)) {
1441 tevent_req_nterror(req, status);
1442 return;
1445 if (state->rhdr.flags & RPC_FLG_LAST) {
1446 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1447 rpccli_pipe_txt(debug_ctx(), state->cli),
1448 (unsigned)prs_data_size(&state->incoming_pdu)));
1449 tevent_req_done(req);
1450 return;
1453 subreq = get_complete_frag_send(state, state->ev, state->cli,
1454 &state->rhdr, &state->incoming_frag);
1455 if (tevent_req_nomem(subreq, req)) {
1456 return;
1458 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1461 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1462 prs_struct *reply_pdu)
1464 struct rpc_api_pipe_state *state = tevent_req_data(
1465 req, struct rpc_api_pipe_state);
1466 NTSTATUS status;
1468 if (tevent_req_is_nterror(req, &status)) {
1469 return status;
1472 *reply_pdu = state->incoming_pdu;
1473 reply_pdu->mem_ctx = mem_ctx;
1476 * Prevent state->incoming_pdu from being freed in
1477 * rpc_api_pipe_state_destructor()
1479 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1481 return NT_STATUS_OK;
1484 /*******************************************************************
1485 Creates krb5 auth bind.
1486 ********************************************************************/
1488 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1489 enum dcerpc_AuthLevel auth_level,
1490 RPC_HDR_AUTH *pauth_out,
1491 prs_struct *auth_data)
1493 #ifdef HAVE_KRB5
1494 int ret;
1495 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1496 DATA_BLOB tkt = data_blob_null;
1497 DATA_BLOB tkt_wrapped = data_blob_null;
1499 /* We may change the pad length before marshalling. */
1500 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1502 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1503 a->service_principal ));
1505 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1507 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1508 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1510 if (ret) {
1511 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1512 "failed with %s\n",
1513 a->service_principal,
1514 error_message(ret) ));
1516 data_blob_free(&tkt);
1517 prs_mem_free(auth_data);
1518 return NT_STATUS_INVALID_PARAMETER;
1521 /* wrap that up in a nice GSS-API wrapping */
1522 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1524 data_blob_free(&tkt);
1526 /* Auth len in the rpc header doesn't include auth_header. */
1527 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1528 data_blob_free(&tkt_wrapped);
1529 prs_mem_free(auth_data);
1530 return NT_STATUS_NO_MEMORY;
1533 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1534 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1536 data_blob_free(&tkt_wrapped);
1537 return NT_STATUS_OK;
1538 #else
1539 return NT_STATUS_INVALID_PARAMETER;
1540 #endif
1543 /*******************************************************************
1544 Creates SPNEGO NTLMSSP auth bind.
1545 ********************************************************************/
1547 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1548 enum dcerpc_AuthLevel auth_level,
1549 RPC_HDR_AUTH *pauth_out,
1550 prs_struct *auth_data)
1552 NTSTATUS nt_status;
1553 DATA_BLOB null_blob = data_blob_null;
1554 DATA_BLOB request = data_blob_null;
1555 DATA_BLOB spnego_msg = data_blob_null;
1557 /* We may change the pad length before marshalling. */
1558 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1560 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1561 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1562 null_blob,
1563 &request);
1565 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1566 data_blob_free(&request);
1567 prs_mem_free(auth_data);
1568 return nt_status;
1571 /* Wrap this in SPNEGO. */
1572 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1574 data_blob_free(&request);
1576 /* Auth len in the rpc header doesn't include auth_header. */
1577 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1578 data_blob_free(&spnego_msg);
1579 prs_mem_free(auth_data);
1580 return NT_STATUS_NO_MEMORY;
1583 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1584 dump_data(5, spnego_msg.data, spnego_msg.length);
1586 data_blob_free(&spnego_msg);
1587 return NT_STATUS_OK;
1590 /*******************************************************************
1591 Creates NTLMSSP auth bind.
1592 ********************************************************************/
1594 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1595 enum dcerpc_AuthLevel auth_level,
1596 RPC_HDR_AUTH *pauth_out,
1597 prs_struct *auth_data)
1599 NTSTATUS nt_status;
1600 DATA_BLOB null_blob = data_blob_null;
1601 DATA_BLOB request = data_blob_null;
1603 /* We may change the pad length before marshalling. */
1604 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1606 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1607 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1608 null_blob,
1609 &request);
1611 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1612 data_blob_free(&request);
1613 prs_mem_free(auth_data);
1614 return nt_status;
1617 /* Auth len in the rpc header doesn't include auth_header. */
1618 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1619 data_blob_free(&request);
1620 prs_mem_free(auth_data);
1621 return NT_STATUS_NO_MEMORY;
1624 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1625 dump_data(5, request.data, request.length);
1627 data_blob_free(&request);
1628 return NT_STATUS_OK;
1631 /*******************************************************************
1632 Creates schannel auth bind.
1633 ********************************************************************/
1635 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1636 enum dcerpc_AuthLevel auth_level,
1637 RPC_HDR_AUTH *pauth_out,
1638 prs_struct *auth_data)
1640 struct NL_AUTH_MESSAGE r;
1641 enum ndr_err_code ndr_err;
1642 DATA_BLOB blob;
1644 /* We may change the pad length before marshalling. */
1645 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1647 /* Use lp_workgroup() if domain not specified */
1649 if (!cli->auth->domain || !cli->auth->domain[0]) {
1650 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1651 if (cli->auth->domain == NULL) {
1652 return NT_STATUS_NO_MEMORY;
1657 * Now marshall the data into the auth parse_struct.
1660 r.MessageType = NL_NEGOTIATE_REQUEST;
1661 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1662 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1663 r.oem_netbios_domain.a = cli->auth->domain;
1664 r.oem_netbios_computer.a = global_myname();
1666 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1667 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1668 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1669 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1670 prs_mem_free(auth_data);
1671 return ndr_map_error2ntstatus(ndr_err);
1674 if (DEBUGLEVEL >= 10) {
1675 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1678 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1680 prs_mem_free(auth_data);
1681 return NT_STATUS_NO_MEMORY;
1684 return NT_STATUS_OK;
1687 /*******************************************************************
1688 Creates the internals of a DCE/RPC bind request or alter context PDU.
1689 ********************************************************************/
1691 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1692 prs_struct *rpc_out,
1693 uint32 rpc_call_id,
1694 const struct ndr_syntax_id *abstract,
1695 const struct ndr_syntax_id *transfer,
1696 RPC_HDR_AUTH *phdr_auth,
1697 prs_struct *pauth_info)
1699 RPC_HDR hdr;
1700 RPC_HDR_RB hdr_rb;
1701 RPC_CONTEXT rpc_ctx;
1702 uint16 auth_len = prs_offset(pauth_info);
1703 uint8 ss_padding_len = 0;
1704 uint16 frag_len = 0;
1706 /* create the RPC context. */
1707 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1709 /* create the bind request RPC_HDR_RB */
1710 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1712 /* Start building the frag length. */
1713 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1715 /* Do we need to pad ? */
1716 if (auth_len) {
1717 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1718 if (data_len % 8) {
1719 ss_padding_len = 8 - (data_len % 8);
1720 phdr_auth->auth_pad_len = ss_padding_len;
1722 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1725 /* Create the request RPC_HDR */
1726 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1728 /* Marshall the RPC header */
1729 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1730 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1731 return NT_STATUS_NO_MEMORY;
1734 /* Marshall the bind request data */
1735 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1736 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1737 return NT_STATUS_NO_MEMORY;
1741 * Grow the outgoing buffer to store any auth info.
1744 if(auth_len != 0) {
1745 if (ss_padding_len) {
1746 char pad[8];
1747 memset(pad, '\0', 8);
1748 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1749 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1750 return NT_STATUS_NO_MEMORY;
1754 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1755 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1756 return NT_STATUS_NO_MEMORY;
1760 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1761 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1762 return NT_STATUS_NO_MEMORY;
1766 return NT_STATUS_OK;
1769 /*******************************************************************
1770 Creates a DCE/RPC bind request.
1771 ********************************************************************/
1773 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1774 prs_struct *rpc_out,
1775 uint32 rpc_call_id,
1776 const struct ndr_syntax_id *abstract,
1777 const struct ndr_syntax_id *transfer,
1778 enum pipe_auth_type auth_type,
1779 enum dcerpc_AuthLevel auth_level)
1781 RPC_HDR_AUTH hdr_auth;
1782 prs_struct auth_info;
1783 NTSTATUS ret = NT_STATUS_OK;
1785 ZERO_STRUCT(hdr_auth);
1786 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1787 return NT_STATUS_NO_MEMORY;
1789 switch (auth_type) {
1790 case PIPE_AUTH_TYPE_SCHANNEL:
1791 ret = create_schannel_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_NTLMSSP:
1799 ret = create_ntlmssp_auth_rpc_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_SPNEGO_NTLMSSP:
1807 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1808 if (!NT_STATUS_IS_OK(ret)) {
1809 prs_mem_free(&auth_info);
1810 return ret;
1812 break;
1814 case PIPE_AUTH_TYPE_KRB5:
1815 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1816 if (!NT_STATUS_IS_OK(ret)) {
1817 prs_mem_free(&auth_info);
1818 return ret;
1820 break;
1822 case PIPE_AUTH_TYPE_NONE:
1823 break;
1825 default:
1826 /* "Can't" happen. */
1827 return NT_STATUS_INVALID_INFO_CLASS;
1830 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1831 rpc_out,
1832 rpc_call_id,
1833 abstract,
1834 transfer,
1835 &hdr_auth,
1836 &auth_info);
1838 prs_mem_free(&auth_info);
1839 return ret;
1842 /*******************************************************************
1843 Create and add the NTLMSSP sign/seal auth header and data.
1844 ********************************************************************/
1846 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1847 RPC_HDR *phdr,
1848 uint32 ss_padding_len,
1849 prs_struct *outgoing_pdu)
1851 RPC_HDR_AUTH auth_info;
1852 NTSTATUS status;
1853 DATA_BLOB auth_blob = data_blob_null;
1854 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1856 if (!cli->auth->a_u.ntlmssp_state) {
1857 return NT_STATUS_INVALID_PARAMETER;
1860 /* Init and marshall the auth header. */
1861 init_rpc_hdr_auth(&auth_info,
1862 map_pipe_auth_type_to_rpc_auth_type(
1863 cli->auth->auth_type),
1864 cli->auth->auth_level,
1865 ss_padding_len,
1866 1 /* context id. */);
1868 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1869 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1870 data_blob_free(&auth_blob);
1871 return NT_STATUS_NO_MEMORY;
1874 switch (cli->auth->auth_level) {
1875 case DCERPC_AUTH_LEVEL_PRIVACY:
1876 /* Data portion is encrypted. */
1877 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1878 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1879 data_and_pad_len,
1880 (unsigned char *)prs_data_p(outgoing_pdu),
1881 (size_t)prs_offset(outgoing_pdu),
1882 &auth_blob);
1883 if (!NT_STATUS_IS_OK(status)) {
1884 data_blob_free(&auth_blob);
1885 return status;
1887 break;
1889 case DCERPC_AUTH_LEVEL_INTEGRITY:
1890 /* Data is signed. */
1891 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1892 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1893 data_and_pad_len,
1894 (unsigned char *)prs_data_p(outgoing_pdu),
1895 (size_t)prs_offset(outgoing_pdu),
1896 &auth_blob);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 data_blob_free(&auth_blob);
1899 return status;
1901 break;
1903 default:
1904 /* Can't happen. */
1905 smb_panic("bad auth level");
1906 /* Notreached. */
1907 return NT_STATUS_INVALID_PARAMETER;
1910 /* Finally marshall the blob. */
1912 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1913 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1914 (unsigned int)NTLMSSP_SIG_SIZE));
1915 data_blob_free(&auth_blob);
1916 return NT_STATUS_NO_MEMORY;
1919 data_blob_free(&auth_blob);
1920 return NT_STATUS_OK;
1923 /*******************************************************************
1924 Create and add the schannel sign/seal auth header and data.
1925 ********************************************************************/
1927 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1928 RPC_HDR *phdr,
1929 uint32 ss_padding_len,
1930 prs_struct *outgoing_pdu)
1932 RPC_HDR_AUTH auth_info;
1933 struct NL_AUTH_SIGNATURE verf;
1934 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1935 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1936 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1937 enum ndr_err_code ndr_err;
1938 DATA_BLOB blob;
1939 NTSTATUS status;
1941 if (!sas) {
1942 return NT_STATUS_INVALID_PARAMETER;
1945 /* Init and marshall the auth header. */
1946 init_rpc_hdr_auth(&auth_info,
1947 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1948 cli->auth->auth_level,
1949 ss_padding_len,
1950 1 /* context id. */);
1952 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1953 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1954 return NT_STATUS_NO_MEMORY;
1957 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1958 sas->seq_num));
1960 switch (cli->auth->auth_level) {
1961 case DCERPC_AUTH_LEVEL_PRIVACY:
1962 status = schannel_seal_packet(sas,
1963 talloc_tos(),
1964 (uint8_t *)data_p,
1965 data_and_pad_len,
1966 &blob);
1967 break;
1968 case DCERPC_AUTH_LEVEL_INTEGRITY:
1969 status = schannel_sign_packet(sas,
1970 talloc_tos(),
1971 (uint8_t *)data_p,
1972 data_and_pad_len,
1973 &blob);
1974 break;
1975 default:
1976 status = NT_STATUS_INTERNAL_ERROR;
1977 break;
1980 if (!NT_STATUS_IS_OK(status)) {
1981 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1982 nt_errstr(status)));
1983 return status;
1985 #if 0
1986 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &verf,
1987 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_SIGNATURE);
1988 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1989 return ndr_map_error2ntstatus(ndr_err);
1992 if (DEBUGLEVEL >= 10) {
1993 NDR_PRINT_DEBUG(NL_AUTH_SIGNATURE, &verf);
1995 #endif
1996 /* Finally marshall the blob. */
1997 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
1998 return NT_STATUS_NO_MEMORY;
2001 return NT_STATUS_OK;
2004 /*******************************************************************
2005 Calculate how much data we're going to send in this packet, also
2006 work out any sign/seal padding length.
2007 ********************************************************************/
2009 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2010 uint32 data_left,
2011 uint16 *p_frag_len,
2012 uint16 *p_auth_len,
2013 uint32 *p_ss_padding)
2015 uint32 data_space, data_len;
2017 #ifdef DEVELOPER
2018 if ((data_left > 0) && (sys_random() % 2)) {
2019 data_left = MAX(data_left/2, 1);
2021 #endif
2023 switch (cli->auth->auth_level) {
2024 case DCERPC_AUTH_LEVEL_NONE:
2025 case DCERPC_AUTH_LEVEL_CONNECT:
2026 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2027 data_len = MIN(data_space, data_left);
2028 *p_ss_padding = 0;
2029 *p_auth_len = 0;
2030 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2031 return data_len;
2033 case DCERPC_AUTH_LEVEL_INTEGRITY:
2034 case DCERPC_AUTH_LEVEL_PRIVACY:
2035 /* Treat the same for all authenticated rpc requests. */
2036 switch(cli->auth->auth_type) {
2037 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2038 case PIPE_AUTH_TYPE_NTLMSSP:
2039 *p_auth_len = NTLMSSP_SIG_SIZE;
2040 break;
2041 case PIPE_AUTH_TYPE_SCHANNEL:
2042 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2043 break;
2044 default:
2045 smb_panic("bad auth type");
2046 break;
2049 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2050 RPC_HDR_AUTH_LEN - *p_auth_len;
2052 data_len = MIN(data_space, data_left);
2053 *p_ss_padding = 0;
2054 if (data_len % 8) {
2055 *p_ss_padding = 8 - (data_len % 8);
2057 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2058 data_len + *p_ss_padding + /* data plus padding. */
2059 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2060 return data_len;
2062 default:
2063 smb_panic("bad auth level");
2064 /* Notreached. */
2065 return 0;
2069 /*******************************************************************
2070 External interface.
2071 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2072 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2073 and deals with signing/sealing details.
2074 ********************************************************************/
2076 struct rpc_api_pipe_req_state {
2077 struct event_context *ev;
2078 struct rpc_pipe_client *cli;
2079 uint8_t op_num;
2080 uint32_t call_id;
2081 prs_struct *req_data;
2082 uint32_t req_data_sent;
2083 prs_struct outgoing_frag;
2084 prs_struct reply_pdu;
2087 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2089 prs_mem_free(&s->outgoing_frag);
2090 prs_mem_free(&s->reply_pdu);
2091 return 0;
2094 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2095 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2096 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2097 bool *is_last_frag);
2099 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2100 struct event_context *ev,
2101 struct rpc_pipe_client *cli,
2102 uint8_t op_num,
2103 prs_struct *req_data)
2105 struct tevent_req *req, *subreq;
2106 struct rpc_api_pipe_req_state *state;
2107 NTSTATUS status;
2108 bool is_last_frag;
2110 req = tevent_req_create(mem_ctx, &state,
2111 struct rpc_api_pipe_req_state);
2112 if (req == NULL) {
2113 return NULL;
2115 state->ev = ev;
2116 state->cli = cli;
2117 state->op_num = op_num;
2118 state->req_data = req_data;
2119 state->req_data_sent = 0;
2120 state->call_id = get_rpc_call_id();
2122 if (cli->max_xmit_frag
2123 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2124 /* Server is screwed up ! */
2125 status = NT_STATUS_INVALID_PARAMETER;
2126 goto post_status;
2129 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2131 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2132 state, MARSHALL)) {
2133 goto fail;
2136 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2138 status = prepare_next_frag(state, &is_last_frag);
2139 if (!NT_STATUS_IS_OK(status)) {
2140 goto post_status;
2143 if (is_last_frag) {
2144 subreq = rpc_api_pipe_send(state, ev, state->cli,
2145 &state->outgoing_frag,
2146 RPC_RESPONSE);
2147 if (subreq == NULL) {
2148 goto fail;
2150 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2151 } else {
2152 subreq = rpc_write_send(
2153 state, ev, cli->transport,
2154 (uint8_t *)prs_data_p(&state->outgoing_frag),
2155 prs_offset(&state->outgoing_frag));
2156 if (subreq == NULL) {
2157 goto fail;
2159 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2160 req);
2162 return req;
2164 post_status:
2165 tevent_req_nterror(req, status);
2166 return tevent_req_post(req, ev);
2167 fail:
2168 TALLOC_FREE(req);
2169 return NULL;
2172 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2173 bool *is_last_frag)
2175 RPC_HDR hdr;
2176 RPC_HDR_REQ hdr_req;
2177 uint32_t data_sent_thistime;
2178 uint16_t auth_len;
2179 uint16_t frag_len;
2180 uint8_t flags = 0;
2181 uint32_t ss_padding;
2182 uint32_t data_left;
2183 char pad[8] = { 0, };
2184 NTSTATUS status;
2186 data_left = prs_offset(state->req_data) - state->req_data_sent;
2188 data_sent_thistime = calculate_data_len_tosend(
2189 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2191 if (state->req_data_sent == 0) {
2192 flags = RPC_FLG_FIRST;
2195 if (data_sent_thistime == data_left) {
2196 flags |= RPC_FLG_LAST;
2199 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2200 return NT_STATUS_NO_MEMORY;
2203 /* Create and marshall the header and request header. */
2204 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2205 auth_len);
2207 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2208 return NT_STATUS_NO_MEMORY;
2211 /* Create the rpc request RPC_HDR_REQ */
2212 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2213 state->op_num);
2215 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2216 &state->outgoing_frag, 0)) {
2217 return NT_STATUS_NO_MEMORY;
2220 /* Copy in the data, plus any ss padding. */
2221 if (!prs_append_some_prs_data(&state->outgoing_frag,
2222 state->req_data, state->req_data_sent,
2223 data_sent_thistime)) {
2224 return NT_STATUS_NO_MEMORY;
2227 /* Copy the sign/seal padding data. */
2228 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2229 return NT_STATUS_NO_MEMORY;
2232 /* Generate any auth sign/seal and add the auth footer. */
2233 switch (state->cli->auth->auth_type) {
2234 case PIPE_AUTH_TYPE_NONE:
2235 status = NT_STATUS_OK;
2236 break;
2237 case PIPE_AUTH_TYPE_NTLMSSP:
2238 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2239 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2240 &state->outgoing_frag);
2241 break;
2242 case PIPE_AUTH_TYPE_SCHANNEL:
2243 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2244 &state->outgoing_frag);
2245 break;
2246 default:
2247 status = NT_STATUS_INVALID_PARAMETER;
2248 break;
2251 state->req_data_sent += data_sent_thistime;
2252 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2254 return status;
2257 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2259 struct tevent_req *req = tevent_req_callback_data(
2260 subreq, struct tevent_req);
2261 struct rpc_api_pipe_req_state *state = tevent_req_data(
2262 req, struct rpc_api_pipe_req_state);
2263 NTSTATUS status;
2264 bool is_last_frag;
2266 status = rpc_write_recv(subreq);
2267 TALLOC_FREE(subreq);
2268 if (!NT_STATUS_IS_OK(status)) {
2269 tevent_req_nterror(req, status);
2270 return;
2273 status = prepare_next_frag(state, &is_last_frag);
2274 if (!NT_STATUS_IS_OK(status)) {
2275 tevent_req_nterror(req, status);
2276 return;
2279 if (is_last_frag) {
2280 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2281 &state->outgoing_frag,
2282 RPC_RESPONSE);
2283 if (tevent_req_nomem(subreq, req)) {
2284 return;
2286 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2287 } else {
2288 subreq = rpc_write_send(
2289 state, state->ev,
2290 state->cli->transport,
2291 (uint8_t *)prs_data_p(&state->outgoing_frag),
2292 prs_offset(&state->outgoing_frag));
2293 if (tevent_req_nomem(subreq, req)) {
2294 return;
2296 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2297 req);
2301 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2303 struct tevent_req *req = tevent_req_callback_data(
2304 subreq, struct tevent_req);
2305 struct rpc_api_pipe_req_state *state = tevent_req_data(
2306 req, struct rpc_api_pipe_req_state);
2307 NTSTATUS status;
2309 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2310 TALLOC_FREE(subreq);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 tevent_req_nterror(req, status);
2313 return;
2315 tevent_req_done(req);
2318 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2319 prs_struct *reply_pdu)
2321 struct rpc_api_pipe_req_state *state = tevent_req_data(
2322 req, struct rpc_api_pipe_req_state);
2323 NTSTATUS status;
2325 if (tevent_req_is_nterror(req, &status)) {
2327 * We always have to initialize to reply pdu, even if there is
2328 * none. The rpccli_* caller routines expect this.
2330 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2331 return status;
2334 *reply_pdu = state->reply_pdu;
2335 reply_pdu->mem_ctx = mem_ctx;
2338 * Prevent state->req_pdu from being freed in
2339 * rpc_api_pipe_req_state_destructor()
2341 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2343 return NT_STATUS_OK;
2346 #if 0
2347 /****************************************************************************
2348 Set the handle state.
2349 ****************************************************************************/
2351 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2352 const char *pipe_name, uint16 device_state)
2354 bool state_set = False;
2355 char param[2];
2356 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2357 char *rparam = NULL;
2358 char *rdata = NULL;
2359 uint32 rparam_len, rdata_len;
2361 if (pipe_name == NULL)
2362 return False;
2364 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2365 cli->fnum, pipe_name, device_state));
2367 /* create parameters: device state */
2368 SSVAL(param, 0, device_state);
2370 /* create setup parameters. */
2371 setup[0] = 0x0001;
2372 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2374 /* send the data on \PIPE\ */
2375 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2376 setup, 2, 0, /* setup, length, max */
2377 param, 2, 0, /* param, length, max */
2378 NULL, 0, 1024, /* data, length, max */
2379 &rparam, &rparam_len, /* return param, length */
2380 &rdata, &rdata_len)) /* return data, length */
2382 DEBUG(5, ("Set Handle state: return OK\n"));
2383 state_set = True;
2386 SAFE_FREE(rparam);
2387 SAFE_FREE(rdata);
2389 return state_set;
2391 #endif
2393 /****************************************************************************
2394 Check the rpc bind acknowledge response.
2395 ****************************************************************************/
2397 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2398 const struct ndr_syntax_id *transfer)
2400 if ( hdr_ba->addr.len == 0) {
2401 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2404 /* check the transfer syntax */
2405 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2406 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2407 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2408 return False;
2411 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2412 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2413 hdr_ba->res.num_results, hdr_ba->res.reason));
2416 DEBUG(5,("check_bind_response: accepted!\n"));
2417 return True;
2420 /*******************************************************************
2421 Creates a DCE/RPC bind authentication response.
2422 This is the packet that is sent back to the server once we
2423 have received a BIND-ACK, to finish the third leg of
2424 the authentication handshake.
2425 ********************************************************************/
2427 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2428 uint32 rpc_call_id,
2429 enum pipe_auth_type auth_type,
2430 enum dcerpc_AuthLevel auth_level,
2431 DATA_BLOB *pauth_blob,
2432 prs_struct *rpc_out)
2434 RPC_HDR hdr;
2435 RPC_HDR_AUTH hdr_auth;
2436 uint32 pad = 0;
2438 /* Create the request RPC_HDR */
2439 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2440 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2441 pauth_blob->length );
2443 /* Marshall it. */
2444 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2445 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2446 return NT_STATUS_NO_MEMORY;
2450 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2451 about padding - shouldn't this pad to length 8 ? JRA.
2454 /* 4 bytes padding. */
2455 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2456 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2457 return NT_STATUS_NO_MEMORY;
2460 /* Create the request RPC_HDR_AUTHA */
2461 init_rpc_hdr_auth(&hdr_auth,
2462 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2463 auth_level, 0, 1);
2465 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2466 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2467 return NT_STATUS_NO_MEMORY;
2471 * Append the auth data to the outgoing buffer.
2474 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2475 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2476 return NT_STATUS_NO_MEMORY;
2479 return NT_STATUS_OK;
2482 /*******************************************************************
2483 Creates a DCE/RPC bind alter context authentication request which
2484 may contain a spnego auth blobl
2485 ********************************************************************/
2487 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2488 const struct ndr_syntax_id *abstract,
2489 const struct ndr_syntax_id *transfer,
2490 enum dcerpc_AuthLevel auth_level,
2491 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2492 prs_struct *rpc_out)
2494 RPC_HDR_AUTH hdr_auth;
2495 prs_struct auth_info;
2496 NTSTATUS ret = NT_STATUS_OK;
2498 ZERO_STRUCT(hdr_auth);
2499 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2500 return NT_STATUS_NO_MEMORY;
2502 /* We may change the pad length before marshalling. */
2503 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2505 if (pauth_blob->length) {
2506 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2507 prs_mem_free(&auth_info);
2508 return NT_STATUS_NO_MEMORY;
2512 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2513 rpc_out,
2514 rpc_call_id,
2515 abstract,
2516 transfer,
2517 &hdr_auth,
2518 &auth_info);
2519 prs_mem_free(&auth_info);
2520 return ret;
2523 /****************************************************************************
2524 Do an rpc bind.
2525 ****************************************************************************/
2527 struct rpc_pipe_bind_state {
2528 struct event_context *ev;
2529 struct rpc_pipe_client *cli;
2530 prs_struct rpc_out;
2531 uint32_t rpc_call_id;
2534 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2536 prs_mem_free(&state->rpc_out);
2537 return 0;
2540 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2541 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2542 struct rpc_pipe_bind_state *state,
2543 struct rpc_hdr_info *phdr,
2544 prs_struct *reply_pdu);
2545 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2546 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2547 struct rpc_pipe_bind_state *state,
2548 struct rpc_hdr_info *phdr,
2549 prs_struct *reply_pdu);
2550 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2552 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2553 struct event_context *ev,
2554 struct rpc_pipe_client *cli,
2555 struct cli_pipe_auth_data *auth)
2557 struct tevent_req *req, *subreq;
2558 struct rpc_pipe_bind_state *state;
2559 NTSTATUS status;
2561 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2562 if (req == NULL) {
2563 return NULL;
2566 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2567 rpccli_pipe_txt(debug_ctx(), cli),
2568 (unsigned int)auth->auth_type,
2569 (unsigned int)auth->auth_level ));
2571 state->ev = ev;
2572 state->cli = cli;
2573 state->rpc_call_id = get_rpc_call_id();
2575 prs_init_empty(&state->rpc_out, state, MARSHALL);
2576 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2578 cli->auth = talloc_move(cli, &auth);
2580 /* Marshall the outgoing data. */
2581 status = create_rpc_bind_req(cli, &state->rpc_out,
2582 state->rpc_call_id,
2583 &cli->abstract_syntax,
2584 &cli->transfer_syntax,
2585 cli->auth->auth_type,
2586 cli->auth->auth_level);
2588 if (!NT_STATUS_IS_OK(status)) {
2589 goto post_status;
2592 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2593 RPC_BINDACK);
2594 if (subreq == NULL) {
2595 goto fail;
2597 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2598 return req;
2600 post_status:
2601 tevent_req_nterror(req, status);
2602 return tevent_req_post(req, ev);
2603 fail:
2604 TALLOC_FREE(req);
2605 return NULL;
2608 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2610 struct tevent_req *req = tevent_req_callback_data(
2611 subreq, struct tevent_req);
2612 struct rpc_pipe_bind_state *state = tevent_req_data(
2613 req, struct rpc_pipe_bind_state);
2614 prs_struct reply_pdu;
2615 struct rpc_hdr_info hdr;
2616 struct rpc_hdr_ba_info hdr_ba;
2617 NTSTATUS status;
2619 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2620 TALLOC_FREE(subreq);
2621 if (!NT_STATUS_IS_OK(status)) {
2622 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2623 rpccli_pipe_txt(debug_ctx(), state->cli),
2624 nt_errstr(status)));
2625 tevent_req_nterror(req, status);
2626 return;
2629 /* Unmarshall the RPC header */
2630 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2631 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2632 prs_mem_free(&reply_pdu);
2633 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2634 return;
2637 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2638 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2639 "RPC_HDR_BA.\n"));
2640 prs_mem_free(&reply_pdu);
2641 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2642 return;
2645 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2646 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2647 prs_mem_free(&reply_pdu);
2648 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2649 return;
2652 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2653 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2656 * For authenticated binds we may need to do 3 or 4 leg binds.
2659 switch(state->cli->auth->auth_type) {
2661 case PIPE_AUTH_TYPE_NONE:
2662 case PIPE_AUTH_TYPE_SCHANNEL:
2663 /* Bind complete. */
2664 prs_mem_free(&reply_pdu);
2665 tevent_req_done(req);
2666 break;
2668 case PIPE_AUTH_TYPE_NTLMSSP:
2669 /* Need to send AUTH3 packet - no reply. */
2670 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2671 &reply_pdu);
2672 prs_mem_free(&reply_pdu);
2673 if (!NT_STATUS_IS_OK(status)) {
2674 tevent_req_nterror(req, status);
2676 break;
2678 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2679 /* Need to send alter context request and reply. */
2680 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2681 &reply_pdu);
2682 prs_mem_free(&reply_pdu);
2683 if (!NT_STATUS_IS_OK(status)) {
2684 tevent_req_nterror(req, status);
2686 break;
2688 case PIPE_AUTH_TYPE_KRB5:
2689 /* */
2691 default:
2692 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2693 (unsigned int)state->cli->auth->auth_type));
2694 prs_mem_free(&reply_pdu);
2695 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2699 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2700 struct rpc_pipe_bind_state *state,
2701 struct rpc_hdr_info *phdr,
2702 prs_struct *reply_pdu)
2704 DATA_BLOB server_response = data_blob_null;
2705 DATA_BLOB client_reply = data_blob_null;
2706 struct rpc_hdr_auth_info hdr_auth;
2707 struct tevent_req *subreq;
2708 NTSTATUS status;
2710 if ((phdr->auth_len == 0)
2711 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2712 return NT_STATUS_INVALID_PARAMETER;
2715 if (!prs_set_offset(
2716 reply_pdu,
2717 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2718 return NT_STATUS_INVALID_PARAMETER;
2721 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2722 return NT_STATUS_INVALID_PARAMETER;
2725 /* TODO - check auth_type/auth_level match. */
2727 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2728 prs_copy_data_out((char *)server_response.data, reply_pdu,
2729 phdr->auth_len);
2731 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2732 server_response, &client_reply);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2736 "blob failed: %s.\n", nt_errstr(status)));
2737 return status;
2740 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2742 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2743 state->cli->auth->auth_type,
2744 state->cli->auth->auth_level,
2745 &client_reply, &state->rpc_out);
2746 data_blob_free(&client_reply);
2748 if (!NT_STATUS_IS_OK(status)) {
2749 return status;
2752 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2753 (uint8_t *)prs_data_p(&state->rpc_out),
2754 prs_offset(&state->rpc_out));
2755 if (subreq == NULL) {
2756 return NT_STATUS_NO_MEMORY;
2758 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2759 return NT_STATUS_OK;
2762 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2764 struct tevent_req *req = tevent_req_callback_data(
2765 subreq, struct tevent_req);
2766 NTSTATUS status;
2768 status = rpc_write_recv(subreq);
2769 TALLOC_FREE(subreq);
2770 if (!NT_STATUS_IS_OK(status)) {
2771 tevent_req_nterror(req, status);
2772 return;
2774 tevent_req_done(req);
2777 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2778 struct rpc_pipe_bind_state *state,
2779 struct rpc_hdr_info *phdr,
2780 prs_struct *reply_pdu)
2782 DATA_BLOB server_spnego_response = data_blob_null;
2783 DATA_BLOB server_ntlm_response = data_blob_null;
2784 DATA_BLOB client_reply = data_blob_null;
2785 DATA_BLOB tmp_blob = data_blob_null;
2786 RPC_HDR_AUTH hdr_auth;
2787 struct tevent_req *subreq;
2788 NTSTATUS status;
2790 if ((phdr->auth_len == 0)
2791 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2792 return NT_STATUS_INVALID_PARAMETER;
2795 /* Process the returned NTLMSSP blob first. */
2796 if (!prs_set_offset(
2797 reply_pdu,
2798 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2799 return NT_STATUS_INVALID_PARAMETER;
2802 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2803 return NT_STATUS_INVALID_PARAMETER;
2806 server_spnego_response = data_blob(NULL, phdr->auth_len);
2807 prs_copy_data_out((char *)server_spnego_response.data,
2808 reply_pdu, phdr->auth_len);
2811 * The server might give us back two challenges - tmp_blob is for the
2812 * second.
2814 if (!spnego_parse_challenge(server_spnego_response,
2815 &server_ntlm_response, &tmp_blob)) {
2816 data_blob_free(&server_spnego_response);
2817 data_blob_free(&server_ntlm_response);
2818 data_blob_free(&tmp_blob);
2819 return NT_STATUS_INVALID_PARAMETER;
2822 /* We're finished with the server spnego response and the tmp_blob. */
2823 data_blob_free(&server_spnego_response);
2824 data_blob_free(&tmp_blob);
2826 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2827 server_ntlm_response, &client_reply);
2829 /* Finished with the server_ntlm response */
2830 data_blob_free(&server_ntlm_response);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2834 "using server blob failed.\n"));
2835 data_blob_free(&client_reply);
2836 return status;
2839 /* SPNEGO wrap the client reply. */
2840 tmp_blob = spnego_gen_auth(client_reply);
2841 data_blob_free(&client_reply);
2842 client_reply = tmp_blob;
2843 tmp_blob = data_blob_null;
2845 /* Now prepare the alter context pdu. */
2846 prs_init_empty(&state->rpc_out, state, MARSHALL);
2848 status = create_rpc_alter_context(state->rpc_call_id,
2849 &state->cli->abstract_syntax,
2850 &state->cli->transfer_syntax,
2851 state->cli->auth->auth_level,
2852 &client_reply,
2853 &state->rpc_out);
2854 data_blob_free(&client_reply);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 return status;
2860 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2861 &state->rpc_out, RPC_ALTCONTRESP);
2862 if (subreq == NULL) {
2863 return NT_STATUS_NO_MEMORY;
2865 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2866 return NT_STATUS_OK;
2869 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2871 struct tevent_req *req = tevent_req_callback_data(
2872 subreq, struct tevent_req);
2873 struct rpc_pipe_bind_state *state = tevent_req_data(
2874 req, struct rpc_pipe_bind_state);
2875 DATA_BLOB server_spnego_response = data_blob_null;
2876 DATA_BLOB tmp_blob = data_blob_null;
2877 prs_struct reply_pdu;
2878 struct rpc_hdr_info hdr;
2879 struct rpc_hdr_auth_info hdr_auth;
2880 NTSTATUS status;
2882 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2883 TALLOC_FREE(subreq);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 tevent_req_nterror(req, status);
2886 return;
2889 /* Get the auth blob from the reply. */
2890 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2891 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2892 "unmarshall RPC_HDR.\n"));
2893 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2894 return;
2897 if (!prs_set_offset(
2898 &reply_pdu,
2899 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2900 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2901 return;
2904 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2905 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2906 return;
2909 server_spnego_response = data_blob(NULL, hdr.auth_len);
2910 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2911 hdr.auth_len);
2913 /* Check we got a valid auth response. */
2914 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2915 OID_NTLMSSP, &tmp_blob)) {
2916 data_blob_free(&server_spnego_response);
2917 data_blob_free(&tmp_blob);
2918 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2919 return;
2922 data_blob_free(&server_spnego_response);
2923 data_blob_free(&tmp_blob);
2925 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2926 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2927 tevent_req_done(req);
2930 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2932 return tevent_req_simple_recv_ntstatus(req);
2935 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2936 struct cli_pipe_auth_data *auth)
2938 TALLOC_CTX *frame = talloc_stackframe();
2939 struct event_context *ev;
2940 struct tevent_req *req;
2941 NTSTATUS status = NT_STATUS_OK;
2943 ev = event_context_init(frame);
2944 if (ev == NULL) {
2945 status = NT_STATUS_NO_MEMORY;
2946 goto fail;
2949 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2950 if (req == NULL) {
2951 status = NT_STATUS_NO_MEMORY;
2952 goto fail;
2955 if (!tevent_req_poll(req, ev)) {
2956 status = map_nt_error_from_unix(errno);
2957 goto fail;
2960 status = rpc_pipe_bind_recv(req);
2961 fail:
2962 TALLOC_FREE(frame);
2963 return status;
2966 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2967 unsigned int timeout)
2969 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2971 if (cli == NULL) {
2972 return 0;
2974 return cli_set_timeout(cli, timeout);
2977 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2979 struct cli_state *cli;
2981 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2982 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2983 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2984 return true;
2987 cli = rpc_pipe_np_smb_conn(rpc_cli);
2988 if (cli == NULL) {
2989 return false;
2991 E_md4hash(cli->password ? cli->password : "", nt_hash);
2992 return true;
2995 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2996 struct cli_pipe_auth_data **presult)
2998 struct cli_pipe_auth_data *result;
3000 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3001 if (result == NULL) {
3002 return NT_STATUS_NO_MEMORY;
3005 result->auth_type = PIPE_AUTH_TYPE_NONE;
3006 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3008 result->user_name = talloc_strdup(result, "");
3009 result->domain = talloc_strdup(result, "");
3010 if ((result->user_name == NULL) || (result->domain == NULL)) {
3011 TALLOC_FREE(result);
3012 return NT_STATUS_NO_MEMORY;
3015 *presult = result;
3016 return NT_STATUS_OK;
3019 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3021 ntlmssp_end(&auth->a_u.ntlmssp_state);
3022 return 0;
3025 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3026 enum pipe_auth_type auth_type,
3027 enum dcerpc_AuthLevel auth_level,
3028 const char *domain,
3029 const char *username,
3030 const char *password,
3031 struct cli_pipe_auth_data **presult)
3033 struct cli_pipe_auth_data *result;
3034 NTSTATUS status;
3036 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3037 if (result == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3041 result->auth_type = auth_type;
3042 result->auth_level = auth_level;
3044 result->user_name = talloc_strdup(result, username);
3045 result->domain = talloc_strdup(result, domain);
3046 if ((result->user_name == NULL) || (result->domain == NULL)) {
3047 status = NT_STATUS_NO_MEMORY;
3048 goto fail;
3051 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 goto fail;
3056 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3058 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3059 if (!NT_STATUS_IS_OK(status)) {
3060 goto fail;
3063 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3064 if (!NT_STATUS_IS_OK(status)) {
3065 goto fail;
3068 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3069 if (!NT_STATUS_IS_OK(status)) {
3070 goto fail;
3074 * Turn off sign+seal to allow selected auth level to turn it back on.
3076 result->a_u.ntlmssp_state->neg_flags &=
3077 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3079 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3080 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3081 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3082 result->a_u.ntlmssp_state->neg_flags
3083 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3086 *presult = result;
3087 return NT_STATUS_OK;
3089 fail:
3090 TALLOC_FREE(result);
3091 return status;
3094 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3095 enum dcerpc_AuthLevel auth_level,
3096 struct netlogon_creds_CredentialState *creds,
3097 struct cli_pipe_auth_data **presult)
3099 struct cli_pipe_auth_data *result;
3101 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3102 if (result == NULL) {
3103 return NT_STATUS_NO_MEMORY;
3106 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3107 result->auth_level = auth_level;
3109 result->user_name = talloc_strdup(result, "");
3110 result->domain = talloc_strdup(result, domain);
3111 if ((result->user_name == NULL) || (result->domain == NULL)) {
3112 goto fail;
3115 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3116 if (result->a_u.schannel_auth == NULL) {
3117 goto fail;
3120 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3121 result->a_u.schannel_auth->seq_num = 0;
3122 result->a_u.schannel_auth->initiator = true;
3123 result->a_u.schannel_auth->creds = creds;
3125 *presult = result;
3126 return NT_STATUS_OK;
3128 fail:
3129 TALLOC_FREE(result);
3130 return NT_STATUS_NO_MEMORY;
3133 #ifdef HAVE_KRB5
3134 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3136 data_blob_free(&auth->session_key);
3137 return 0;
3139 #endif
3141 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3142 enum dcerpc_AuthLevel auth_level,
3143 const char *service_princ,
3144 const char *username,
3145 const char *password,
3146 struct cli_pipe_auth_data **presult)
3148 #ifdef HAVE_KRB5
3149 struct cli_pipe_auth_data *result;
3151 if ((username != NULL) && (password != NULL)) {
3152 int ret = kerberos_kinit_password(username, password, 0, NULL);
3153 if (ret != 0) {
3154 return NT_STATUS_ACCESS_DENIED;
3158 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3159 if (result == NULL) {
3160 return NT_STATUS_NO_MEMORY;
3163 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3164 result->auth_level = auth_level;
3167 * Username / domain need fixing!
3169 result->user_name = talloc_strdup(result, "");
3170 result->domain = talloc_strdup(result, "");
3171 if ((result->user_name == NULL) || (result->domain == NULL)) {
3172 goto fail;
3175 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3176 result, struct kerberos_auth_struct);
3177 if (result->a_u.kerberos_auth == NULL) {
3178 goto fail;
3180 talloc_set_destructor(result->a_u.kerberos_auth,
3181 cli_auth_kerberos_data_destructor);
3183 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3184 result, service_princ);
3185 if (result->a_u.kerberos_auth->service_principal == NULL) {
3186 goto fail;
3189 *presult = result;
3190 return NT_STATUS_OK;
3192 fail:
3193 TALLOC_FREE(result);
3194 return NT_STATUS_NO_MEMORY;
3195 #else
3196 return NT_STATUS_NOT_SUPPORTED;
3197 #endif
3201 * Create an rpc pipe client struct, connecting to a tcp port.
3203 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3204 uint16_t port,
3205 const struct ndr_syntax_id *abstract_syntax,
3206 struct rpc_pipe_client **presult)
3208 struct rpc_pipe_client *result;
3209 struct sockaddr_storage addr;
3210 NTSTATUS status;
3211 int fd;
3213 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3214 if (result == NULL) {
3215 return NT_STATUS_NO_MEMORY;
3218 result->abstract_syntax = *abstract_syntax;
3219 result->transfer_syntax = ndr_transfer_syntax;
3220 result->dispatch = cli_do_rpc_ndr;
3221 result->dispatch_send = cli_do_rpc_ndr_send;
3222 result->dispatch_recv = cli_do_rpc_ndr_recv;
3224 result->desthost = talloc_strdup(result, host);
3225 result->srv_name_slash = talloc_asprintf_strupper_m(
3226 result, "\\\\%s", result->desthost);
3227 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3228 status = NT_STATUS_NO_MEMORY;
3229 goto fail;
3232 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3233 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3235 if (!resolve_name(host, &addr, 0, false)) {
3236 status = NT_STATUS_NOT_FOUND;
3237 goto fail;
3240 status = open_socket_out(&addr, port, 60, &fd);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 goto fail;
3244 set_socket_options(fd, lp_socket_options());
3246 status = rpc_transport_sock_init(result, fd, &result->transport);
3247 if (!NT_STATUS_IS_OK(status)) {
3248 close(fd);
3249 goto fail;
3252 result->transport->transport = NCACN_IP_TCP;
3254 *presult = result;
3255 return NT_STATUS_OK;
3257 fail:
3258 TALLOC_FREE(result);
3259 return status;
3263 * Determine the tcp port on which a dcerpc interface is listening
3264 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3265 * target host.
3267 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3268 const struct ndr_syntax_id *abstract_syntax,
3269 uint16_t *pport)
3271 NTSTATUS status;
3272 struct rpc_pipe_client *epm_pipe = NULL;
3273 struct cli_pipe_auth_data *auth = NULL;
3274 struct dcerpc_binding *map_binding = NULL;
3275 struct dcerpc_binding *res_binding = NULL;
3276 struct epm_twr_t *map_tower = NULL;
3277 struct epm_twr_t *res_towers = NULL;
3278 struct policy_handle *entry_handle = NULL;
3279 uint32_t num_towers = 0;
3280 uint32_t max_towers = 1;
3281 struct epm_twr_p_t towers;
3282 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3284 if (pport == NULL) {
3285 status = NT_STATUS_INVALID_PARAMETER;
3286 goto done;
3289 /* open the connection to the endpoint mapper */
3290 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3291 &ndr_table_epmapper.syntax_id,
3292 &epm_pipe);
3294 if (!NT_STATUS_IS_OK(status)) {
3295 goto done;
3298 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 goto done;
3303 status = rpc_pipe_bind(epm_pipe, auth);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 goto done;
3308 /* create tower for asking the epmapper */
3310 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3311 if (map_binding == NULL) {
3312 status = NT_STATUS_NO_MEMORY;
3313 goto done;
3316 map_binding->transport = NCACN_IP_TCP;
3317 map_binding->object = *abstract_syntax;
3318 map_binding->host = host; /* needed? */
3319 map_binding->endpoint = "0"; /* correct? needed? */
3321 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3322 if (map_tower == NULL) {
3323 status = NT_STATUS_NO_MEMORY;
3324 goto done;
3327 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3328 &(map_tower->tower));
3329 if (!NT_STATUS_IS_OK(status)) {
3330 goto done;
3333 /* allocate further parameters for the epm_Map call */
3335 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3336 if (res_towers == NULL) {
3337 status = NT_STATUS_NO_MEMORY;
3338 goto done;
3340 towers.twr = res_towers;
3342 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3343 if (entry_handle == NULL) {
3344 status = NT_STATUS_NO_MEMORY;
3345 goto done;
3348 /* ask the endpoint mapper for the port */
3350 status = rpccli_epm_Map(epm_pipe,
3351 tmp_ctx,
3352 CONST_DISCARD(struct GUID *,
3353 &(abstract_syntax->uuid)),
3354 map_tower,
3355 entry_handle,
3356 max_towers,
3357 &num_towers,
3358 &towers);
3360 if (!NT_STATUS_IS_OK(status)) {
3361 goto done;
3364 if (num_towers != 1) {
3365 status = NT_STATUS_UNSUCCESSFUL;
3366 goto done;
3369 /* extract the port from the answer */
3371 status = dcerpc_binding_from_tower(tmp_ctx,
3372 &(towers.twr->tower),
3373 &res_binding);
3374 if (!NT_STATUS_IS_OK(status)) {
3375 goto done;
3378 /* are further checks here necessary? */
3379 if (res_binding->transport != NCACN_IP_TCP) {
3380 status = NT_STATUS_UNSUCCESSFUL;
3381 goto done;
3384 *pport = (uint16_t)atoi(res_binding->endpoint);
3386 done:
3387 TALLOC_FREE(tmp_ctx);
3388 return status;
3392 * Create a rpc pipe client struct, connecting to a host via tcp.
3393 * The port is determined by asking the endpoint mapper on the given
3394 * host.
3396 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3397 const struct ndr_syntax_id *abstract_syntax,
3398 struct rpc_pipe_client **presult)
3400 NTSTATUS status;
3401 uint16_t port = 0;
3403 *presult = NULL;
3405 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 goto done;
3410 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3411 abstract_syntax, presult);
3413 done:
3414 return status;
3417 /********************************************************************
3418 Create a rpc pipe client struct, connecting to a unix domain socket
3419 ********************************************************************/
3420 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3421 const struct ndr_syntax_id *abstract_syntax,
3422 struct rpc_pipe_client **presult)
3424 struct rpc_pipe_client *result;
3425 struct sockaddr_un addr;
3426 NTSTATUS status;
3427 int fd;
3429 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3430 if (result == NULL) {
3431 return NT_STATUS_NO_MEMORY;
3434 result->abstract_syntax = *abstract_syntax;
3435 result->transfer_syntax = ndr_transfer_syntax;
3436 result->dispatch = cli_do_rpc_ndr;
3437 result->dispatch_send = cli_do_rpc_ndr_send;
3438 result->dispatch_recv = cli_do_rpc_ndr_recv;
3440 result->desthost = get_myname(result);
3441 result->srv_name_slash = talloc_asprintf_strupper_m(
3442 result, "\\\\%s", result->desthost);
3443 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3444 status = NT_STATUS_NO_MEMORY;
3445 goto fail;
3448 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3449 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3451 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3452 if (fd == -1) {
3453 status = map_nt_error_from_unix(errno);
3454 goto fail;
3457 ZERO_STRUCT(addr);
3458 addr.sun_family = AF_UNIX;
3459 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3461 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3462 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3463 strerror(errno)));
3464 close(fd);
3465 return map_nt_error_from_unix(errno);
3468 status = rpc_transport_sock_init(result, fd, &result->transport);
3469 if (!NT_STATUS_IS_OK(status)) {
3470 close(fd);
3471 goto fail;
3474 result->transport->transport = NCALRPC;
3476 *presult = result;
3477 return NT_STATUS_OK;
3479 fail:
3480 TALLOC_FREE(result);
3481 return status;
3484 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3486 struct cli_state *cli;
3488 cli = rpc_pipe_np_smb_conn(p);
3489 if (cli != NULL) {
3490 DLIST_REMOVE(cli->pipe_list, p);
3492 return 0;
3495 /****************************************************************************
3496 Open a named pipe over SMB to a remote server.
3498 * CAVEAT CALLER OF THIS FUNCTION:
3499 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3500 * so be sure that this function is called AFTER any structure (vs pointer)
3501 * assignment of the cli. In particular, libsmbclient does structure
3502 * assignments of cli, which invalidates the data in the returned
3503 * rpc_pipe_client if this function is called before the structure assignment
3504 * of cli.
3506 ****************************************************************************/
3508 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3509 const struct ndr_syntax_id *abstract_syntax,
3510 struct rpc_pipe_client **presult)
3512 struct rpc_pipe_client *result;
3513 NTSTATUS status;
3515 /* sanity check to protect against crashes */
3517 if ( !cli ) {
3518 return NT_STATUS_INVALID_HANDLE;
3521 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3522 if (result == NULL) {
3523 return NT_STATUS_NO_MEMORY;
3526 result->abstract_syntax = *abstract_syntax;
3527 result->transfer_syntax = ndr_transfer_syntax;
3528 result->dispatch = cli_do_rpc_ndr;
3529 result->dispatch_send = cli_do_rpc_ndr_send;
3530 result->dispatch_recv = cli_do_rpc_ndr_recv;
3531 result->desthost = talloc_strdup(result, cli->desthost);
3532 result->srv_name_slash = talloc_asprintf_strupper_m(
3533 result, "\\\\%s", result->desthost);
3535 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3536 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3538 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3539 TALLOC_FREE(result);
3540 return NT_STATUS_NO_MEMORY;
3543 status = rpc_transport_np_init(result, cli, abstract_syntax,
3544 &result->transport);
3545 if (!NT_STATUS_IS_OK(status)) {
3546 TALLOC_FREE(result);
3547 return status;
3550 result->transport->transport = NCACN_NP;
3552 DLIST_ADD(cli->pipe_list, result);
3553 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3555 *presult = result;
3556 return NT_STATUS_OK;
3559 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3560 struct rpc_cli_smbd_conn *conn,
3561 const struct ndr_syntax_id *syntax,
3562 struct rpc_pipe_client **presult)
3564 struct rpc_pipe_client *result;
3565 struct cli_pipe_auth_data *auth;
3566 NTSTATUS status;
3568 result = talloc(mem_ctx, struct rpc_pipe_client);
3569 if (result == NULL) {
3570 return NT_STATUS_NO_MEMORY;
3572 result->abstract_syntax = *syntax;
3573 result->transfer_syntax = ndr_transfer_syntax;
3574 result->dispatch = cli_do_rpc_ndr;
3575 result->dispatch_send = cli_do_rpc_ndr_send;
3576 result->dispatch_recv = cli_do_rpc_ndr_recv;
3577 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3578 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3580 result->desthost = talloc_strdup(result, global_myname());
3581 result->srv_name_slash = talloc_asprintf_strupper_m(
3582 result, "\\\\%s", global_myname());
3583 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3584 TALLOC_FREE(result);
3585 return NT_STATUS_NO_MEMORY;
3588 status = rpc_transport_smbd_init(result, conn, syntax,
3589 &result->transport);
3590 if (!NT_STATUS_IS_OK(status)) {
3591 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3592 nt_errstr(status)));
3593 TALLOC_FREE(result);
3594 return status;
3597 status = rpccli_anon_bind_data(result, &auth);
3598 if (!NT_STATUS_IS_OK(status)) {
3599 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3600 nt_errstr(status)));
3601 TALLOC_FREE(result);
3602 return status;
3605 status = rpc_pipe_bind(result, auth);
3606 if (!NT_STATUS_IS_OK(status)) {
3607 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3608 TALLOC_FREE(result);
3609 return status;
3612 result->transport->transport = NCACN_INTERNAL;
3614 *presult = result;
3615 return NT_STATUS_OK;
3618 /****************************************************************************
3619 Open a pipe to a remote server.
3620 ****************************************************************************/
3622 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3623 enum dcerpc_transport_t transport,
3624 const struct ndr_syntax_id *interface,
3625 struct rpc_pipe_client **presult)
3627 switch (transport) {
3628 case NCACN_IP_TCP:
3629 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3630 presult);
3631 case NCACN_NP:
3632 return rpc_pipe_open_np(cli, interface, presult);
3633 default:
3634 return NT_STATUS_NOT_IMPLEMENTED;
3638 /****************************************************************************
3639 Open a named pipe to an SMB server and bind anonymously.
3640 ****************************************************************************/
3642 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3643 enum dcerpc_transport_t transport,
3644 const struct ndr_syntax_id *interface,
3645 struct rpc_pipe_client **presult)
3647 struct rpc_pipe_client *result;
3648 struct cli_pipe_auth_data *auth;
3649 NTSTATUS status;
3651 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3652 if (!NT_STATUS_IS_OK(status)) {
3653 return status;
3656 status = rpccli_anon_bind_data(result, &auth);
3657 if (!NT_STATUS_IS_OK(status)) {
3658 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3659 nt_errstr(status)));
3660 TALLOC_FREE(result);
3661 return status;
3665 * This is a bit of an abstraction violation due to the fact that an
3666 * anonymous bind on an authenticated SMB inherits the user/domain
3667 * from the enclosing SMB creds
3670 TALLOC_FREE(auth->user_name);
3671 TALLOC_FREE(auth->domain);
3673 auth->user_name = talloc_strdup(auth, cli->user_name);
3674 auth->domain = talloc_strdup(auth, cli->domain);
3675 auth->user_session_key = data_blob_talloc(auth,
3676 cli->user_session_key.data,
3677 cli->user_session_key.length);
3679 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3680 TALLOC_FREE(result);
3681 return NT_STATUS_NO_MEMORY;
3684 status = rpc_pipe_bind(result, auth);
3685 if (!NT_STATUS_IS_OK(status)) {
3686 int lvl = 0;
3687 if (ndr_syntax_id_equal(interface,
3688 &ndr_table_dssetup.syntax_id)) {
3689 /* non AD domains just don't have this pipe, avoid
3690 * level 0 statement in that case - gd */
3691 lvl = 3;
3693 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3694 "%s failed with error %s\n",
3695 get_pipe_name_from_iface(interface),
3696 nt_errstr(status) ));
3697 TALLOC_FREE(result);
3698 return status;
3701 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3702 "%s and bound anonymously.\n",
3703 get_pipe_name_from_iface(interface), cli->desthost));
3705 *presult = result;
3706 return NT_STATUS_OK;
3709 /****************************************************************************
3710 ****************************************************************************/
3712 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3713 const struct ndr_syntax_id *interface,
3714 struct rpc_pipe_client **presult)
3716 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3717 interface, presult);
3720 /****************************************************************************
3721 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3722 ****************************************************************************/
3724 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3725 const struct ndr_syntax_id *interface,
3726 enum dcerpc_transport_t transport,
3727 enum pipe_auth_type auth_type,
3728 enum dcerpc_AuthLevel auth_level,
3729 const char *domain,
3730 const char *username,
3731 const char *password,
3732 struct rpc_pipe_client **presult)
3734 struct rpc_pipe_client *result;
3735 struct cli_pipe_auth_data *auth;
3736 NTSTATUS status;
3738 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3739 if (!NT_STATUS_IS_OK(status)) {
3740 return status;
3743 status = rpccli_ntlmssp_bind_data(
3744 result, auth_type, auth_level, domain, username,
3745 password, &auth);
3746 if (!NT_STATUS_IS_OK(status)) {
3747 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3748 nt_errstr(status)));
3749 goto err;
3752 status = rpc_pipe_bind(result, auth);
3753 if (!NT_STATUS_IS_OK(status)) {
3754 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3755 nt_errstr(status) ));
3756 goto err;
3759 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3760 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3761 get_pipe_name_from_iface(interface), cli->desthost, domain,
3762 username ));
3764 *presult = result;
3765 return NT_STATUS_OK;
3767 err:
3769 TALLOC_FREE(result);
3770 return status;
3773 /****************************************************************************
3774 External interface.
3775 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3776 ****************************************************************************/
3778 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3779 const struct ndr_syntax_id *interface,
3780 enum dcerpc_transport_t transport,
3781 enum dcerpc_AuthLevel auth_level,
3782 const char *domain,
3783 const char *username,
3784 const char *password,
3785 struct rpc_pipe_client **presult)
3787 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3788 interface,
3789 transport,
3790 PIPE_AUTH_TYPE_NTLMSSP,
3791 auth_level,
3792 domain,
3793 username,
3794 password,
3795 presult);
3798 /****************************************************************************
3799 External interface.
3800 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3801 ****************************************************************************/
3803 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3804 const struct ndr_syntax_id *interface,
3805 enum dcerpc_transport_t transport,
3806 enum dcerpc_AuthLevel auth_level,
3807 const char *domain,
3808 const char *username,
3809 const char *password,
3810 struct rpc_pipe_client **presult)
3812 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3813 interface,
3814 transport,
3815 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3816 auth_level,
3817 domain,
3818 username,
3819 password,
3820 presult);
3823 /****************************************************************************
3824 Get a the schannel session key out of an already opened netlogon pipe.
3825 ****************************************************************************/
3826 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3827 struct cli_state *cli,
3828 const char *domain,
3829 uint32 *pneg_flags)
3831 uint32 sec_chan_type = 0;
3832 unsigned char machine_pwd[16];
3833 const char *machine_account;
3834 NTSTATUS status;
3836 /* Get the machine account credentials from secrets.tdb. */
3837 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3838 &sec_chan_type))
3840 DEBUG(0, ("get_schannel_session_key: could not fetch "
3841 "trust account password for domain '%s'\n",
3842 domain));
3843 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3846 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3847 cli->desthost, /* server name */
3848 domain, /* domain */
3849 global_myname(), /* client name */
3850 machine_account, /* machine account name */
3851 machine_pwd,
3852 sec_chan_type,
3853 pneg_flags);
3855 if (!NT_STATUS_IS_OK(status)) {
3856 DEBUG(3, ("get_schannel_session_key_common: "
3857 "rpccli_netlogon_setup_creds failed with result %s "
3858 "to server %s, domain %s, machine account %s.\n",
3859 nt_errstr(status), cli->desthost, domain,
3860 machine_account ));
3861 return status;
3864 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3865 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3866 cli->desthost));
3867 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3870 return NT_STATUS_OK;;
3873 /****************************************************************************
3874 Open a netlogon pipe and get the schannel session key.
3875 Now exposed to external callers.
3876 ****************************************************************************/
3879 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3880 const char *domain,
3881 uint32 *pneg_flags,
3882 struct rpc_pipe_client **presult)
3884 struct rpc_pipe_client *netlogon_pipe = NULL;
3885 NTSTATUS status;
3887 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3888 &netlogon_pipe);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 return status;
3893 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3894 pneg_flags);
3895 if (!NT_STATUS_IS_OK(status)) {
3896 TALLOC_FREE(netlogon_pipe);
3897 return status;
3900 *presult = netlogon_pipe;
3901 return NT_STATUS_OK;
3904 /****************************************************************************
3905 External interface.
3906 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3907 using session_key. sign and seal.
3909 The *pdc will be stolen onto this new pipe
3910 ****************************************************************************/
3912 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3913 const struct ndr_syntax_id *interface,
3914 enum dcerpc_transport_t transport,
3915 enum dcerpc_AuthLevel auth_level,
3916 const char *domain,
3917 struct netlogon_creds_CredentialState **pdc,
3918 struct rpc_pipe_client **presult)
3920 struct rpc_pipe_client *result;
3921 struct cli_pipe_auth_data *auth;
3922 NTSTATUS status;
3924 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3925 if (!NT_STATUS_IS_OK(status)) {
3926 return status;
3929 status = rpccli_schannel_bind_data(result, domain, auth_level,
3930 *pdc, &auth);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3933 nt_errstr(status)));
3934 TALLOC_FREE(result);
3935 return status;
3938 status = rpc_pipe_bind(result, auth);
3939 if (!NT_STATUS_IS_OK(status)) {
3940 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3941 "cli_rpc_pipe_bind failed with error %s\n",
3942 nt_errstr(status) ));
3943 TALLOC_FREE(result);
3944 return status;
3948 * The credentials on a new netlogon pipe are the ones we are passed
3949 * in - reference them in
3951 result->dc = talloc_move(result, pdc);
3952 if (result->dc == NULL) {
3953 DEBUG(0, ("talloc reference failed\n"));
3954 TALLOC_FREE(result);
3955 return NT_STATUS_NO_MEMORY;
3958 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3959 "for domain %s and bound using schannel.\n",
3960 get_pipe_name_from_iface(interface),
3961 cli->desthost, domain ));
3963 *presult = result;
3964 return NT_STATUS_OK;
3967 /****************************************************************************
3968 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3969 Fetch the session key ourselves using a temporary netlogon pipe. This
3970 version uses an ntlmssp auth bound netlogon pipe to get the key.
3971 ****************************************************************************/
3973 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3974 const char *domain,
3975 const char *username,
3976 const char *password,
3977 uint32 *pneg_flags,
3978 struct rpc_pipe_client **presult)
3980 struct rpc_pipe_client *netlogon_pipe = NULL;
3981 NTSTATUS status;
3983 status = cli_rpc_pipe_open_spnego_ntlmssp(
3984 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3985 DCERPC_AUTH_LEVEL_PRIVACY,
3986 domain, username, password, &netlogon_pipe);
3987 if (!NT_STATUS_IS_OK(status)) {
3988 return status;
3991 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3992 pneg_flags);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 TALLOC_FREE(netlogon_pipe);
3995 return status;
3998 *presult = netlogon_pipe;
3999 return NT_STATUS_OK;
4002 /****************************************************************************
4003 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4004 Fetch the session key ourselves using a temporary netlogon pipe. This version
4005 uses an ntlmssp bind to get the session key.
4006 ****************************************************************************/
4008 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4009 const struct ndr_syntax_id *interface,
4010 enum dcerpc_transport_t transport,
4011 enum dcerpc_AuthLevel auth_level,
4012 const char *domain,
4013 const char *username,
4014 const char *password,
4015 struct rpc_pipe_client **presult)
4017 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4018 struct rpc_pipe_client *netlogon_pipe = NULL;
4019 struct rpc_pipe_client *result = NULL;
4020 NTSTATUS status;
4022 status = get_schannel_session_key_auth_ntlmssp(
4023 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4024 if (!NT_STATUS_IS_OK(status)) {
4025 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4026 "key from server %s for domain %s.\n",
4027 cli->desthost, domain ));
4028 return status;
4031 status = cli_rpc_pipe_open_schannel_with_key(
4032 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4033 &result);
4035 /* Now we've bound using the session key we can close the netlog pipe. */
4036 TALLOC_FREE(netlogon_pipe);
4038 if (NT_STATUS_IS_OK(status)) {
4039 *presult = result;
4041 return status;
4044 /****************************************************************************
4045 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4046 Fetch the session key ourselves using a temporary netlogon pipe.
4047 ****************************************************************************/
4049 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4050 const struct ndr_syntax_id *interface,
4051 enum dcerpc_transport_t transport,
4052 enum dcerpc_AuthLevel auth_level,
4053 const char *domain,
4054 struct rpc_pipe_client **presult)
4056 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4057 struct rpc_pipe_client *netlogon_pipe = NULL;
4058 struct rpc_pipe_client *result = NULL;
4059 NTSTATUS status;
4061 status = get_schannel_session_key(cli, domain, &neg_flags,
4062 &netlogon_pipe);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4065 "key from server %s for domain %s.\n",
4066 cli->desthost, domain ));
4067 return status;
4070 status = cli_rpc_pipe_open_schannel_with_key(
4071 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4072 &result);
4074 /* Now we've bound using the session key we can close the netlog pipe. */
4075 TALLOC_FREE(netlogon_pipe);
4077 if (NT_STATUS_IS_OK(status)) {
4078 *presult = result;
4081 return NT_STATUS_OK;
4084 /****************************************************************************
4085 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4086 The idea is this can be called with service_princ, username and password all
4087 NULL so long as the caller has a TGT.
4088 ****************************************************************************/
4090 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4091 const struct ndr_syntax_id *interface,
4092 enum dcerpc_AuthLevel auth_level,
4093 const char *service_princ,
4094 const char *username,
4095 const char *password,
4096 struct rpc_pipe_client **presult)
4098 #ifdef HAVE_KRB5
4099 struct rpc_pipe_client *result;
4100 struct cli_pipe_auth_data *auth;
4101 NTSTATUS status;
4103 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 return status;
4108 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4109 username, password, &auth);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4112 nt_errstr(status)));
4113 TALLOC_FREE(result);
4114 return status;
4117 status = rpc_pipe_bind(result, auth);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4120 "with error %s\n", nt_errstr(status)));
4121 TALLOC_FREE(result);
4122 return status;
4125 *presult = result;
4126 return NT_STATUS_OK;
4127 #else
4128 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4129 return NT_STATUS_NOT_IMPLEMENTED;
4130 #endif
4133 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4134 struct rpc_pipe_client *cli,
4135 DATA_BLOB *session_key)
4137 if (!session_key || !cli) {
4138 return NT_STATUS_INVALID_PARAMETER;
4141 if (!cli->auth) {
4142 return NT_STATUS_INVALID_PARAMETER;
4145 switch (cli->auth->auth_type) {
4146 case PIPE_AUTH_TYPE_SCHANNEL:
4147 *session_key = data_blob_talloc(mem_ctx,
4148 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4149 break;
4150 case PIPE_AUTH_TYPE_NTLMSSP:
4151 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4152 *session_key = data_blob_talloc(mem_ctx,
4153 cli->auth->a_u.ntlmssp_state->session_key.data,
4154 cli->auth->a_u.ntlmssp_state->session_key.length);
4155 break;
4156 case PIPE_AUTH_TYPE_KRB5:
4157 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4158 *session_key = data_blob_talloc(mem_ctx,
4159 cli->auth->a_u.kerberos_auth->session_key.data,
4160 cli->auth->a_u.kerberos_auth->session_key.length);
4161 break;
4162 case PIPE_AUTH_TYPE_NONE:
4163 *session_key = data_blob_talloc(mem_ctx,
4164 cli->auth->user_session_key.data,
4165 cli->auth->user_session_key.length);
4166 break;
4167 default:
4168 return NT_STATUS_NO_USER_SESSION_KEY;
4171 return NT_STATUS_OK;