Fix a type-punned warning
[Samba/aatanasov.git] / source3 / rpc_client / cli_pipe.c
blob7d059e41c96416b50b09ede37d8768b5dd033fb4
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"
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_RPC_CLI
27 /*******************************************************************
28 interface/version dce/rpc pipe identification
29 ********************************************************************/
31 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
32 #define PIPE_SAMR "\\PIPE\\samr"
33 #define PIPE_WINREG "\\PIPE\\winreg"
34 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
35 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
36 #define PIPE_NTLSA "\\PIPE\\ntlsa"
37 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
38 #define PIPE_LSASS "\\PIPE\\lsass"
39 #define PIPE_LSARPC "\\PIPE\\lsarpc"
40 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
41 #define PIPE_NETDFS "\\PIPE\\netdfs"
42 #define PIPE_ECHO "\\PIPE\\rpcecho"
43 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
44 #define PIPE_EPM "\\PIPE\\epmapper"
45 #define PIPE_SVCCTL "\\PIPE\\svcctl"
46 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
47 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
48 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
51 * IMPORTANT!! If you update this structure, make sure to
52 * update the index #defines in smb.h.
55 static const struct pipe_id_info {
56 /* the names appear not to matter: the syntaxes _do_ matter */
58 const char *client_pipe;
59 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
60 } pipe_names [] =
62 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
63 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
64 { PIPE_SAMR, &ndr_table_samr.syntax_id },
65 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
66 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
67 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
68 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
69 { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
70 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
71 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
72 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
73 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
74 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
75 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
76 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
77 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
78 { NULL, NULL }
81 /****************************************************************************
82 Return the pipe name from the interface.
83 ****************************************************************************/
85 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
87 char *guid_str;
88 const char *result;
89 int i;
90 for (i = 0; pipe_names[i].client_pipe; i++) {
91 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
92 interface)) {
93 return &pipe_names[i].client_pipe[5];
98 * Here we should ask \\epmapper, but for now our code is only
99 * interested in the known pipes mentioned in pipe_names[]
102 guid_str = GUID_string(talloc_tos(), &interface->uuid);
103 if (guid_str == NULL) {
104 return NULL;
106 result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
107 (int)interface->if_version);
108 TALLOC_FREE(guid_str);
110 if (result == NULL) {
111 return "PIPE";
113 return result;
116 /********************************************************************
117 Map internal value to wire value.
118 ********************************************************************/
120 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
122 switch (auth_type) {
124 case PIPE_AUTH_TYPE_NONE:
125 return RPC_ANONYMOUS_AUTH_TYPE;
127 case PIPE_AUTH_TYPE_NTLMSSP:
128 return RPC_NTLMSSP_AUTH_TYPE;
130 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
131 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
132 return RPC_SPNEGO_AUTH_TYPE;
134 case PIPE_AUTH_TYPE_SCHANNEL:
135 return RPC_SCHANNEL_AUTH_TYPE;
137 case PIPE_AUTH_TYPE_KRB5:
138 return RPC_KRB5_AUTH_TYPE;
140 default:
141 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
142 "auth type %u\n",
143 (unsigned int)auth_type ));
144 break;
146 return -1;
149 /********************************************************************
150 Pipe description for a DEBUG
151 ********************************************************************/
152 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
153 struct rpc_pipe_client *cli)
155 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
156 if (result == NULL) {
157 return "pipe";
159 return result;
162 /********************************************************************
163 Rpc pipe call id.
164 ********************************************************************/
166 static uint32 get_rpc_call_id(void)
168 static uint32 call_id = 0;
169 return ++call_id;
173 * Realloc pdu to have a least "size" bytes
176 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
178 size_t extra_size;
180 if (prs_data_size(pdu) >= size) {
181 return true;
184 extra_size = size - prs_data_size(pdu);
186 if (!prs_force_grow(pdu, extra_size)) {
187 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
188 "%d bytes.\n", (int)extra_size));
189 return false;
192 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
193 (int)extra_size, prs_data_size(pdu)));
194 return true;
198 /*******************************************************************
199 Use SMBreadX to get rest of one fragment's worth of rpc data.
200 Reads the whole size or give an error message
201 ********************************************************************/
203 struct rpc_read_state {
204 struct event_context *ev;
205 struct rpc_cli_transport *transport;
206 uint8_t *data;
207 size_t size;
208 size_t num_read;
211 static void rpc_read_done(struct tevent_req *subreq);
213 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
214 struct event_context *ev,
215 struct rpc_cli_transport *transport,
216 uint8_t *data, size_t size)
218 struct tevent_req *req, *subreq;
219 struct rpc_read_state *state;
221 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
222 if (req == NULL) {
223 return NULL;
225 state->ev = ev;
226 state->transport = transport;
227 state->data = data;
228 state->size = size;
229 state->num_read = 0;
231 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
233 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
234 transport->priv);
235 if (subreq == NULL) {
236 goto fail;
238 tevent_req_set_callback(subreq, rpc_read_done, req);
239 return req;
241 fail:
242 TALLOC_FREE(req);
243 return NULL;
246 static void rpc_read_done(struct tevent_req *subreq)
248 struct tevent_req *req = tevent_req_callback_data(
249 subreq, struct tevent_req);
250 struct rpc_read_state *state = tevent_req_data(
251 req, struct rpc_read_state);
252 NTSTATUS status;
253 ssize_t received;
255 status = state->transport->read_recv(subreq, &received);
256 TALLOC_FREE(subreq);
257 if (!NT_STATUS_IS_OK(status)) {
258 tevent_req_nterror(req, status);
259 return;
262 state->num_read += received;
263 if (state->num_read == state->size) {
264 tevent_req_done(req);
265 return;
268 subreq = state->transport->read_send(state, state->ev,
269 state->data + state->num_read,
270 state->size - state->num_read,
271 state->transport->priv);
272 if (tevent_req_nomem(subreq, req)) {
273 return;
275 tevent_req_set_callback(subreq, rpc_read_done, req);
278 static NTSTATUS rpc_read_recv(struct tevent_req *req)
280 return tevent_req_simple_recv_ntstatus(req);
283 struct rpc_write_state {
284 struct event_context *ev;
285 struct rpc_cli_transport *transport;
286 const uint8_t *data;
287 size_t size;
288 size_t num_written;
291 static void rpc_write_done(struct tevent_req *subreq);
293 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
294 struct event_context *ev,
295 struct rpc_cli_transport *transport,
296 const uint8_t *data, size_t size)
298 struct tevent_req *req, *subreq;
299 struct rpc_write_state *state;
301 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
302 if (req == NULL) {
303 return NULL;
305 state->ev = ev;
306 state->transport = transport;
307 state->data = data;
308 state->size = size;
309 state->num_written = 0;
311 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
313 subreq = transport->write_send(state, ev, data, size, transport->priv);
314 if (subreq == NULL) {
315 goto fail;
317 tevent_req_set_callback(subreq, rpc_write_done, req);
318 return req;
319 fail:
320 TALLOC_FREE(req);
321 return NULL;
324 static void rpc_write_done(struct tevent_req *subreq)
326 struct tevent_req *req = tevent_req_callback_data(
327 subreq, struct tevent_req);
328 struct rpc_write_state *state = tevent_req_data(
329 req, struct rpc_write_state);
330 NTSTATUS status;
331 ssize_t written;
333 status = state->transport->write_recv(subreq, &written);
334 TALLOC_FREE(subreq);
335 if (!NT_STATUS_IS_OK(status)) {
336 tevent_req_nterror(req, status);
337 return;
340 state->num_written += written;
342 if (state->num_written == state->size) {
343 tevent_req_done(req);
344 return;
347 subreq = state->transport->write_send(state, state->ev,
348 state->data + state->num_written,
349 state->size - state->num_written,
350 state->transport->priv);
351 if (tevent_req_nomem(subreq, req)) {
352 return;
354 tevent_req_set_callback(subreq, rpc_write_done, req);
357 static NTSTATUS rpc_write_recv(struct tevent_req *req)
359 return tevent_req_simple_recv_ntstatus(req);
363 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
364 struct rpc_hdr_info *prhdr,
365 prs_struct *pdu)
368 * This next call sets the endian bit correctly in current_pdu. We
369 * will propagate this to rbuf later.
372 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
373 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
374 return NT_STATUS_BUFFER_TOO_SMALL;
377 if (prhdr->frag_len > cli->max_recv_frag) {
378 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
379 " we only allow %d\n", (int)prhdr->frag_len,
380 (int)cli->max_recv_frag));
381 return NT_STATUS_BUFFER_TOO_SMALL;
384 return NT_STATUS_OK;
387 /****************************************************************************
388 Try and get a PDU's worth of data from current_pdu. If not, then read more
389 from the wire.
390 ****************************************************************************/
392 struct get_complete_frag_state {
393 struct event_context *ev;
394 struct rpc_pipe_client *cli;
395 struct rpc_hdr_info *prhdr;
396 prs_struct *pdu;
399 static void get_complete_frag_got_header(struct tevent_req *subreq);
400 static void get_complete_frag_got_rest(struct tevent_req *subreq);
402 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
403 struct event_context *ev,
404 struct rpc_pipe_client *cli,
405 struct rpc_hdr_info *prhdr,
406 prs_struct *pdu)
408 struct tevent_req *req, *subreq;
409 struct get_complete_frag_state *state;
410 uint32_t pdu_len;
411 NTSTATUS status;
413 req = tevent_req_create(mem_ctx, &state,
414 struct get_complete_frag_state);
415 if (req == NULL) {
416 return NULL;
418 state->ev = ev;
419 state->cli = cli;
420 state->prhdr = prhdr;
421 state->pdu = pdu;
423 pdu_len = prs_data_size(pdu);
424 if (pdu_len < RPC_HEADER_LEN) {
425 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
426 status = NT_STATUS_NO_MEMORY;
427 goto post_status;
429 subreq = rpc_read_send(
430 state, state->ev,
431 state->cli->transport,
432 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
433 RPC_HEADER_LEN - pdu_len);
434 if (subreq == NULL) {
435 status = NT_STATUS_NO_MEMORY;
436 goto post_status;
438 tevent_req_set_callback(subreq, get_complete_frag_got_header,
439 req);
440 return req;
443 status = parse_rpc_header(cli, prhdr, pdu);
444 if (!NT_STATUS_IS_OK(status)) {
445 goto post_status;
449 * Ensure we have frag_len bytes of data.
451 if (pdu_len < prhdr->frag_len) {
452 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
453 status = NT_STATUS_NO_MEMORY;
454 goto post_status;
456 subreq = rpc_read_send(state, state->ev,
457 state->cli->transport,
458 (uint8_t *)(prs_data_p(pdu) + pdu_len),
459 prhdr->frag_len - pdu_len);
460 if (subreq == NULL) {
461 status = NT_STATUS_NO_MEMORY;
462 goto post_status;
464 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
465 req);
466 return req;
469 status = NT_STATUS_OK;
470 post_status:
471 if (NT_STATUS_IS_OK(status)) {
472 tevent_req_done(req);
473 } else {
474 tevent_req_nterror(req, status);
476 return tevent_req_post(req, ev);
479 static void get_complete_frag_got_header(struct tevent_req *subreq)
481 struct tevent_req *req = tevent_req_callback_data(
482 subreq, struct tevent_req);
483 struct get_complete_frag_state *state = tevent_req_data(
484 req, struct get_complete_frag_state);
485 NTSTATUS status;
487 status = rpc_read_recv(subreq);
488 TALLOC_FREE(subreq);
489 if (!NT_STATUS_IS_OK(status)) {
490 tevent_req_nterror(req, status);
491 return;
494 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
495 if (!NT_STATUS_IS_OK(status)) {
496 tevent_req_nterror(req, status);
497 return;
500 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
501 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
502 return;
506 * We're here in this piece of code because we've read exactly
507 * RPC_HEADER_LEN bytes into state->pdu.
510 subreq = rpc_read_send(
511 state, state->ev, state->cli->transport,
512 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
513 state->prhdr->frag_len - RPC_HEADER_LEN);
514 if (tevent_req_nomem(subreq, req)) {
515 return;
517 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
520 static void get_complete_frag_got_rest(struct tevent_req *subreq)
522 struct tevent_req *req = tevent_req_callback_data(
523 subreq, struct tevent_req);
524 NTSTATUS status;
526 status = rpc_read_recv(subreq);
527 TALLOC_FREE(subreq);
528 if (!NT_STATUS_IS_OK(status)) {
529 tevent_req_nterror(req, status);
530 return;
532 tevent_req_done(req);
535 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
537 return tevent_req_simple_recv_ntstatus(req);
540 /****************************************************************************
541 NTLMSSP specific sign/seal.
542 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
543 In fact I should probably abstract these into identical pieces of code... JRA.
544 ****************************************************************************/
546 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
547 prs_struct *current_pdu,
548 uint8 *p_ss_padding_len)
550 RPC_HDR_AUTH auth_info;
551 uint32 save_offset = prs_offset(current_pdu);
552 uint32 auth_len = prhdr->auth_len;
553 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
554 unsigned char *data = NULL;
555 size_t data_len;
556 unsigned char *full_packet_data = NULL;
557 size_t full_packet_data_len;
558 DATA_BLOB auth_blob;
559 NTSTATUS status;
561 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
562 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
563 return NT_STATUS_OK;
566 if (!ntlmssp_state) {
567 return NT_STATUS_INVALID_PARAMETER;
570 /* Ensure there's enough data for an authenticated response. */
571 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
572 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
573 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
574 (unsigned int)auth_len ));
575 return NT_STATUS_BUFFER_TOO_SMALL;
579 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
580 * after the RPC header.
581 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
582 * functions as NTLMv2 checks the rpc headers also.
585 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
586 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
588 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
589 full_packet_data_len = prhdr->frag_len - auth_len;
591 /* Pull the auth header and the following data into a blob. */
592 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
593 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
594 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
595 return NT_STATUS_BUFFER_TOO_SMALL;
598 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
599 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
600 return NT_STATUS_BUFFER_TOO_SMALL;
603 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
604 auth_blob.length = auth_len;
606 switch (cli->auth->auth_level) {
607 case PIPE_AUTH_LEVEL_PRIVACY:
608 /* Data is encrypted. */
609 status = ntlmssp_unseal_packet(ntlmssp_state,
610 data, data_len,
611 full_packet_data,
612 full_packet_data_len,
613 &auth_blob);
614 if (!NT_STATUS_IS_OK(status)) {
615 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
616 "packet from %s. Error was %s.\n",
617 rpccli_pipe_txt(debug_ctx(), cli),
618 nt_errstr(status) ));
619 return status;
621 break;
622 case PIPE_AUTH_LEVEL_INTEGRITY:
623 /* Data is signed. */
624 status = ntlmssp_check_packet(ntlmssp_state,
625 data, data_len,
626 full_packet_data,
627 full_packet_data_len,
628 &auth_blob);
629 if (!NT_STATUS_IS_OK(status)) {
630 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
631 "packet from %s. Error was %s.\n",
632 rpccli_pipe_txt(debug_ctx(), cli),
633 nt_errstr(status) ));
634 return status;
636 break;
637 default:
638 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
639 "auth level %d\n", cli->auth->auth_level));
640 return NT_STATUS_INVALID_INFO_CLASS;
644 * Return the current pointer to the data offset.
647 if(!prs_set_offset(current_pdu, save_offset)) {
648 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
649 (unsigned int)save_offset ));
650 return NT_STATUS_BUFFER_TOO_SMALL;
654 * Remember the padding length. We must remove it from the real data
655 * stream once the sign/seal is done.
658 *p_ss_padding_len = auth_info.auth_pad_len;
660 return NT_STATUS_OK;
663 /****************************************************************************
664 schannel specific sign/seal.
665 ****************************************************************************/
667 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
668 prs_struct *current_pdu,
669 uint8 *p_ss_padding_len)
671 RPC_HDR_AUTH auth_info;
672 RPC_AUTH_SCHANNEL_CHK schannel_chk;
673 uint32 auth_len = prhdr->auth_len;
674 uint32 save_offset = prs_offset(current_pdu);
675 struct schannel_auth_struct *schannel_auth =
676 cli->auth->a_u.schannel_auth;
677 uint32 data_len;
679 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
680 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
681 return NT_STATUS_OK;
684 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
685 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
686 return NT_STATUS_INVALID_PARAMETER;
689 if (!schannel_auth) {
690 return NT_STATUS_INVALID_PARAMETER;
693 /* Ensure there's enough data for an authenticated response. */
694 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
695 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
696 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
697 (unsigned int)auth_len ));
698 return NT_STATUS_INVALID_PARAMETER;
701 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
703 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
704 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
705 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
706 return NT_STATUS_BUFFER_TOO_SMALL;
709 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
710 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
711 return NT_STATUS_BUFFER_TOO_SMALL;
714 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
715 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
716 auth_info.auth_type));
717 return NT_STATUS_BUFFER_TOO_SMALL;
720 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
721 &schannel_chk, current_pdu, 0)) {
722 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
723 return NT_STATUS_BUFFER_TOO_SMALL;
726 if (!schannel_decode(schannel_auth,
727 cli->auth->auth_level,
728 SENDER_IS_ACCEPTOR,
729 &schannel_chk,
730 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
731 data_len)) {
732 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
733 "Connection to %s.\n",
734 rpccli_pipe_txt(debug_ctx(), cli)));
735 return NT_STATUS_INVALID_PARAMETER;
738 /* The sequence number gets incremented on both send and receive. */
739 schannel_auth->seq_num++;
742 * Return the current pointer to the data offset.
745 if(!prs_set_offset(current_pdu, save_offset)) {
746 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
747 (unsigned int)save_offset ));
748 return NT_STATUS_BUFFER_TOO_SMALL;
752 * Remember the padding length. We must remove it from the real data
753 * stream once the sign/seal is done.
756 *p_ss_padding_len = auth_info.auth_pad_len;
758 return NT_STATUS_OK;
761 /****************************************************************************
762 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
763 ****************************************************************************/
765 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
766 prs_struct *current_pdu,
767 uint8 *p_ss_padding_len)
769 NTSTATUS ret = NT_STATUS_OK;
771 /* Paranioa checks for auth_len. */
772 if (prhdr->auth_len) {
773 if (prhdr->auth_len > prhdr->frag_len) {
774 return NT_STATUS_INVALID_PARAMETER;
777 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
778 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
779 /* Integer wrap attempt. */
780 return NT_STATUS_INVALID_PARAMETER;
785 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
788 switch(cli->auth->auth_type) {
789 case PIPE_AUTH_TYPE_NONE:
790 if (prhdr->auth_len) {
791 DEBUG(3, ("cli_pipe_validate_rpc_response: "
792 "Connection to %s - got non-zero "
793 "auth len %u.\n",
794 rpccli_pipe_txt(debug_ctx(), cli),
795 (unsigned int)prhdr->auth_len ));
796 return NT_STATUS_INVALID_PARAMETER;
798 break;
800 case PIPE_AUTH_TYPE_NTLMSSP:
801 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
802 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
803 if (!NT_STATUS_IS_OK(ret)) {
804 return ret;
806 break;
808 case PIPE_AUTH_TYPE_SCHANNEL:
809 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
810 if (!NT_STATUS_IS_OK(ret)) {
811 return ret;
813 break;
815 case PIPE_AUTH_TYPE_KRB5:
816 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
817 default:
818 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
819 "to %s - unknown internal auth type %u.\n",
820 rpccli_pipe_txt(debug_ctx(), cli),
821 cli->auth->auth_type ));
822 return NT_STATUS_INVALID_INFO_CLASS;
825 return NT_STATUS_OK;
828 /****************************************************************************
829 Do basic authentication checks on an incoming pdu.
830 ****************************************************************************/
832 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
833 prs_struct *current_pdu,
834 uint8 expected_pkt_type,
835 char **ppdata,
836 uint32 *pdata_len,
837 prs_struct *return_data)
840 NTSTATUS ret = NT_STATUS_OK;
841 uint32 current_pdu_len = prs_data_size(current_pdu);
843 if (current_pdu_len != prhdr->frag_len) {
844 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
845 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
846 return NT_STATUS_INVALID_PARAMETER;
850 * Point the return values at the real data including the RPC
851 * header. Just in case the caller wants it.
853 *ppdata = prs_data_p(current_pdu);
854 *pdata_len = current_pdu_len;
856 /* Ensure we have the correct type. */
857 switch (prhdr->pkt_type) {
858 case RPC_ALTCONTRESP:
859 case RPC_BINDACK:
861 /* Alter context and bind ack share the same packet definitions. */
862 break;
865 case RPC_RESPONSE:
867 RPC_HDR_RESP rhdr_resp;
868 uint8 ss_padding_len = 0;
870 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
871 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
872 return NT_STATUS_BUFFER_TOO_SMALL;
875 /* Here's where we deal with incoming sign/seal. */
876 ret = cli_pipe_validate_rpc_response(cli, prhdr,
877 current_pdu, &ss_padding_len);
878 if (!NT_STATUS_IS_OK(ret)) {
879 return ret;
882 /* Point the return values at the NDR data. Remember to remove any ss padding. */
883 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
885 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
886 return NT_STATUS_BUFFER_TOO_SMALL;
889 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
891 /* Remember to remove the auth footer. */
892 if (prhdr->auth_len) {
893 /* We've already done integer wrap tests on auth_len in
894 cli_pipe_validate_rpc_response(). */
895 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
896 return NT_STATUS_BUFFER_TOO_SMALL;
898 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
901 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
902 current_pdu_len, *pdata_len, ss_padding_len ));
905 * If this is the first reply, and the allocation hint is reasonably, try and
906 * set up the return_data parse_struct to the correct size.
909 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
910 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
911 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
912 "too large to allocate\n",
913 (unsigned int)rhdr_resp.alloc_hint ));
914 return NT_STATUS_NO_MEMORY;
918 break;
921 case RPC_BINDNACK:
922 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
923 "received from %s!\n",
924 rpccli_pipe_txt(debug_ctx(), cli)));
925 /* Use this for now... */
926 return NT_STATUS_NETWORK_ACCESS_DENIED;
928 case RPC_FAULT:
930 RPC_HDR_RESP rhdr_resp;
931 RPC_HDR_FAULT fault_resp;
933 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
934 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
935 return NT_STATUS_BUFFER_TOO_SMALL;
938 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
939 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
940 return NT_STATUS_BUFFER_TOO_SMALL;
943 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
944 "code %s received from %s!\n",
945 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
946 rpccli_pipe_txt(debug_ctx(), cli)));
947 if (NT_STATUS_IS_OK(fault_resp.status)) {
948 return NT_STATUS_UNSUCCESSFUL;
949 } else {
950 return fault_resp.status;
954 default:
955 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
956 "from %s!\n",
957 (unsigned int)prhdr->pkt_type,
958 rpccli_pipe_txt(debug_ctx(), cli)));
959 return NT_STATUS_INVALID_INFO_CLASS;
962 if (prhdr->pkt_type != expected_pkt_type) {
963 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
964 "got an unexpected RPC packet type - %u, not %u\n",
965 rpccli_pipe_txt(debug_ctx(), cli),
966 prhdr->pkt_type,
967 expected_pkt_type));
968 return NT_STATUS_INVALID_INFO_CLASS;
971 /* Do this just before return - we don't want to modify any rpc header
972 data before now as we may have needed to do cryptographic actions on
973 it before. */
975 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
976 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
977 "setting fragment first/last ON.\n"));
978 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
981 return NT_STATUS_OK;
984 /****************************************************************************
985 Ensure we eat the just processed pdu from the current_pdu prs_struct.
986 Normally the frag_len and buffer size will match, but on the first trans
987 reply there is a theoretical chance that buffer size > frag_len, so we must
988 deal with that.
989 ****************************************************************************/
991 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
993 uint32 current_pdu_len = prs_data_size(current_pdu);
995 if (current_pdu_len < prhdr->frag_len) {
996 return NT_STATUS_BUFFER_TOO_SMALL;
999 /* Common case. */
1000 if (current_pdu_len == (uint32)prhdr->frag_len) {
1001 prs_mem_free(current_pdu);
1002 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1003 /* Make current_pdu dynamic with no memory. */
1004 prs_give_memory(current_pdu, 0, 0, True);
1005 return NT_STATUS_OK;
1009 * Oh no ! More data in buffer than we processed in current pdu.
1010 * Cheat. Move the data down and shrink the buffer.
1013 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1014 current_pdu_len - prhdr->frag_len);
1016 /* Remember to set the read offset back to zero. */
1017 prs_set_offset(current_pdu, 0);
1019 /* Shrink the buffer. */
1020 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1021 return NT_STATUS_BUFFER_TOO_SMALL;
1024 return NT_STATUS_OK;
1027 /****************************************************************************
1028 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1029 ****************************************************************************/
1031 struct cli_api_pipe_state {
1032 struct event_context *ev;
1033 struct rpc_cli_transport *transport;
1034 uint8_t *rdata;
1035 uint32_t rdata_len;
1038 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1039 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1040 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1042 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1043 struct event_context *ev,
1044 struct rpc_cli_transport *transport,
1045 uint8_t *data, size_t data_len,
1046 uint32_t max_rdata_len)
1048 struct tevent_req *req, *subreq;
1049 struct cli_api_pipe_state *state;
1050 NTSTATUS status;
1052 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1053 if (req == NULL) {
1054 return NULL;
1056 state->ev = ev;
1057 state->transport = transport;
1059 if (max_rdata_len < RPC_HEADER_LEN) {
1061 * For a RPC reply we always need at least RPC_HEADER_LEN
1062 * bytes. We check this here because we will receive
1063 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1065 status = NT_STATUS_INVALID_PARAMETER;
1066 goto post_status;
1069 if (transport->trans_send != NULL) {
1070 subreq = transport->trans_send(state, ev, data, data_len,
1071 max_rdata_len, transport->priv);
1072 if (subreq == NULL) {
1073 goto fail;
1075 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1076 return req;
1080 * If the transport does not provide a "trans" routine, i.e. for
1081 * example the ncacn_ip_tcp transport, do the write/read step here.
1084 subreq = rpc_write_send(state, ev, transport, data, data_len);
1085 if (subreq == NULL) {
1086 goto fail;
1088 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1089 return req;
1091 status = NT_STATUS_INVALID_PARAMETER;
1093 post_status:
1094 tevent_req_nterror(req, status);
1095 return tevent_req_post(req, ev);
1096 fail:
1097 TALLOC_FREE(req);
1098 return NULL;
1101 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1103 struct tevent_req *req = tevent_req_callback_data(
1104 subreq, struct tevent_req);
1105 struct cli_api_pipe_state *state = tevent_req_data(
1106 req, struct cli_api_pipe_state);
1107 NTSTATUS status;
1109 status = state->transport->trans_recv(subreq, state, &state->rdata,
1110 &state->rdata_len);
1111 TALLOC_FREE(subreq);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 tevent_req_nterror(req, status);
1114 return;
1116 tevent_req_done(req);
1119 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1121 struct tevent_req *req = tevent_req_callback_data(
1122 subreq, struct tevent_req);
1123 struct cli_api_pipe_state *state = tevent_req_data(
1124 req, struct cli_api_pipe_state);
1125 NTSTATUS status;
1127 status = rpc_write_recv(subreq);
1128 TALLOC_FREE(subreq);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 tevent_req_nterror(req, status);
1131 return;
1134 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1135 if (tevent_req_nomem(state->rdata, req)) {
1136 return;
1140 * We don't need to use rpc_read_send here, the upper layer will cope
1141 * with a short read, transport->trans_send could also return less
1142 * than state->max_rdata_len.
1144 subreq = state->transport->read_send(state, state->ev, state->rdata,
1145 RPC_HEADER_LEN,
1146 state->transport->priv);
1147 if (tevent_req_nomem(subreq, req)) {
1148 return;
1150 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1153 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1155 struct tevent_req *req = tevent_req_callback_data(
1156 subreq, struct tevent_req);
1157 struct cli_api_pipe_state *state = tevent_req_data(
1158 req, struct cli_api_pipe_state);
1159 NTSTATUS status;
1160 ssize_t received;
1162 status = state->transport->read_recv(subreq, &received);
1163 TALLOC_FREE(subreq);
1164 if (!NT_STATUS_IS_OK(status)) {
1165 tevent_req_nterror(req, status);
1166 return;
1168 state->rdata_len = received;
1169 tevent_req_done(req);
1172 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1173 uint8_t **prdata, uint32_t *prdata_len)
1175 struct cli_api_pipe_state *state = tevent_req_data(
1176 req, struct cli_api_pipe_state);
1177 NTSTATUS status;
1179 if (tevent_req_is_nterror(req, &status)) {
1180 return status;
1183 *prdata = talloc_move(mem_ctx, &state->rdata);
1184 *prdata_len = state->rdata_len;
1185 return NT_STATUS_OK;
1188 /****************************************************************************
1189 Send data on an rpc pipe via trans. The prs_struct data must be the last
1190 pdu fragment of an NDR data stream.
1192 Receive response data from an rpc pipe, which may be large...
1194 Read the first fragment: unfortunately have to use SMBtrans for the first
1195 bit, then SMBreadX for subsequent bits.
1197 If first fragment received also wasn't the last fragment, continue
1198 getting fragments until we _do_ receive the last fragment.
1200 Request/Response PDU's look like the following...
1202 |<------------------PDU len----------------------------------------------->|
1203 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1205 +------------+-----------------+-------------+---------------+-------------+
1206 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1207 +------------+-----------------+-------------+---------------+-------------+
1209 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1210 signing & sealing being negotiated.
1212 ****************************************************************************/
1214 struct rpc_api_pipe_state {
1215 struct event_context *ev;
1216 struct rpc_pipe_client *cli;
1217 uint8_t expected_pkt_type;
1219 prs_struct incoming_frag;
1220 struct rpc_hdr_info rhdr;
1222 prs_struct incoming_pdu; /* Incoming reply */
1223 uint32_t incoming_pdu_offset;
1226 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1228 prs_mem_free(&state->incoming_frag);
1229 prs_mem_free(&state->incoming_pdu);
1230 return 0;
1233 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1234 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1236 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1237 struct event_context *ev,
1238 struct rpc_pipe_client *cli,
1239 prs_struct *data, /* Outgoing PDU */
1240 uint8_t expected_pkt_type)
1242 struct tevent_req *req, *subreq;
1243 struct rpc_api_pipe_state *state;
1244 uint16_t max_recv_frag;
1245 NTSTATUS status;
1247 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1248 if (req == NULL) {
1249 return NULL;
1251 state->ev = ev;
1252 state->cli = cli;
1253 state->expected_pkt_type = expected_pkt_type;
1254 state->incoming_pdu_offset = 0;
1256 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1258 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1259 /* Make incoming_pdu dynamic with no memory. */
1260 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1262 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1265 * Ensure we're not sending too much.
1267 if (prs_offset(data) > cli->max_xmit_frag) {
1268 status = NT_STATUS_INVALID_PARAMETER;
1269 goto post_status;
1272 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1274 max_recv_frag = cli->max_recv_frag;
1276 #ifdef DEVELOPER
1277 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1278 #endif
1280 subreq = cli_api_pipe_send(state, ev, cli->transport,
1281 (uint8_t *)prs_data_p(data),
1282 prs_offset(data), max_recv_frag);
1283 if (subreq == NULL) {
1284 goto fail;
1286 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1287 return req;
1289 post_status:
1290 tevent_req_nterror(req, status);
1291 return tevent_req_post(req, ev);
1292 fail:
1293 TALLOC_FREE(req);
1294 return NULL;
1297 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1299 struct tevent_req *req = tevent_req_callback_data(
1300 subreq, struct tevent_req);
1301 struct rpc_api_pipe_state *state = tevent_req_data(
1302 req, struct rpc_api_pipe_state);
1303 NTSTATUS status;
1304 uint8_t *rdata = NULL;
1305 uint32_t rdata_len = 0;
1306 char *rdata_copy;
1308 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1309 TALLOC_FREE(subreq);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1312 tevent_req_nterror(req, status);
1313 return;
1316 if (rdata == NULL) {
1317 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1318 rpccli_pipe_txt(debug_ctx(), state->cli)));
1319 tevent_req_done(req);
1320 return;
1324 * Give the memory received from cli_trans as dynamic to the current
1325 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1326 * :-(
1328 rdata_copy = (char *)memdup(rdata, rdata_len);
1329 TALLOC_FREE(rdata);
1330 if (tevent_req_nomem(rdata_copy, req)) {
1331 return;
1333 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1335 /* Ensure we have enough data for a pdu. */
1336 subreq = get_complete_frag_send(state, state->ev, state->cli,
1337 &state->rhdr, &state->incoming_frag);
1338 if (tevent_req_nomem(subreq, req)) {
1339 return;
1341 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1344 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1346 struct tevent_req *req = tevent_req_callback_data(
1347 subreq, struct tevent_req);
1348 struct rpc_api_pipe_state *state = tevent_req_data(
1349 req, struct rpc_api_pipe_state);
1350 NTSTATUS status;
1351 char *rdata = NULL;
1352 uint32_t rdata_len = 0;
1354 status = get_complete_frag_recv(subreq);
1355 TALLOC_FREE(subreq);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 DEBUG(5, ("get_complete_frag failed: %s\n",
1358 nt_errstr(status)));
1359 tevent_req_nterror(req, status);
1360 return;
1363 status = cli_pipe_validate_current_pdu(
1364 state->cli, &state->rhdr, &state->incoming_frag,
1365 state->expected_pkt_type, &rdata, &rdata_len,
1366 &state->incoming_pdu);
1368 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1369 (unsigned)prs_data_size(&state->incoming_frag),
1370 (unsigned)state->incoming_pdu_offset,
1371 nt_errstr(status)));
1373 if (!NT_STATUS_IS_OK(status)) {
1374 tevent_req_nterror(req, status);
1375 return;
1378 if ((state->rhdr.flags & RPC_FLG_FIRST)
1379 && (state->rhdr.pack_type[0] == 0)) {
1381 * Set the data type correctly for big-endian data on the
1382 * first packet.
1384 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1385 "big-endian.\n",
1386 rpccli_pipe_txt(debug_ctx(), state->cli)));
1387 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1390 * Check endianness on subsequent packets.
1392 if (state->incoming_frag.bigendian_data
1393 != state->incoming_pdu.bigendian_data) {
1394 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1395 "%s\n",
1396 state->incoming_pdu.bigendian_data?"big":"little",
1397 state->incoming_frag.bigendian_data?"big":"little"));
1398 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1399 return;
1402 /* Now copy the data portion out of the pdu into rbuf. */
1403 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1404 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1405 return;
1408 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1409 rdata, (size_t)rdata_len);
1410 state->incoming_pdu_offset += rdata_len;
1412 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1413 &state->incoming_frag);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 tevent_req_nterror(req, status);
1416 return;
1419 if (state->rhdr.flags & RPC_FLG_LAST) {
1420 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1421 rpccli_pipe_txt(debug_ctx(), state->cli),
1422 (unsigned)prs_data_size(&state->incoming_pdu)));
1423 tevent_req_done(req);
1424 return;
1427 subreq = get_complete_frag_send(state, state->ev, state->cli,
1428 &state->rhdr, &state->incoming_frag);
1429 if (tevent_req_nomem(subreq, req)) {
1430 return;
1432 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1435 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1436 prs_struct *reply_pdu)
1438 struct rpc_api_pipe_state *state = tevent_req_data(
1439 req, struct rpc_api_pipe_state);
1440 NTSTATUS status;
1442 if (tevent_req_is_nterror(req, &status)) {
1443 return status;
1446 *reply_pdu = state->incoming_pdu;
1447 reply_pdu->mem_ctx = mem_ctx;
1450 * Prevent state->incoming_pdu from being freed in
1451 * rpc_api_pipe_state_destructor()
1453 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1455 return NT_STATUS_OK;
1458 /*******************************************************************
1459 Creates krb5 auth bind.
1460 ********************************************************************/
1462 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1463 enum pipe_auth_level auth_level,
1464 RPC_HDR_AUTH *pauth_out,
1465 prs_struct *auth_data)
1467 #ifdef HAVE_KRB5
1468 int ret;
1469 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1470 DATA_BLOB tkt = data_blob_null;
1471 DATA_BLOB tkt_wrapped = data_blob_null;
1473 /* We may change the pad length before marshalling. */
1474 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1476 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1477 a->service_principal ));
1479 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1481 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1482 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1484 if (ret) {
1485 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1486 "failed with %s\n",
1487 a->service_principal,
1488 error_message(ret) ));
1490 data_blob_free(&tkt);
1491 prs_mem_free(auth_data);
1492 return NT_STATUS_INVALID_PARAMETER;
1495 /* wrap that up in a nice GSS-API wrapping */
1496 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1498 data_blob_free(&tkt);
1500 /* Auth len in the rpc header doesn't include auth_header. */
1501 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1502 data_blob_free(&tkt_wrapped);
1503 prs_mem_free(auth_data);
1504 return NT_STATUS_NO_MEMORY;
1507 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1508 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1510 data_blob_free(&tkt_wrapped);
1511 return NT_STATUS_OK;
1512 #else
1513 return NT_STATUS_INVALID_PARAMETER;
1514 #endif
1517 /*******************************************************************
1518 Creates SPNEGO NTLMSSP auth bind.
1519 ********************************************************************/
1521 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1522 enum pipe_auth_level auth_level,
1523 RPC_HDR_AUTH *pauth_out,
1524 prs_struct *auth_data)
1526 NTSTATUS nt_status;
1527 DATA_BLOB null_blob = data_blob_null;
1528 DATA_BLOB request = data_blob_null;
1529 DATA_BLOB spnego_msg = data_blob_null;
1531 /* We may change the pad length before marshalling. */
1532 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1534 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1535 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1536 null_blob,
1537 &request);
1539 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1540 data_blob_free(&request);
1541 prs_mem_free(auth_data);
1542 return nt_status;
1545 /* Wrap this in SPNEGO. */
1546 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1548 data_blob_free(&request);
1550 /* Auth len in the rpc header doesn't include auth_header. */
1551 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1552 data_blob_free(&spnego_msg);
1553 prs_mem_free(auth_data);
1554 return NT_STATUS_NO_MEMORY;
1557 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1558 dump_data(5, spnego_msg.data, spnego_msg.length);
1560 data_blob_free(&spnego_msg);
1561 return NT_STATUS_OK;
1564 /*******************************************************************
1565 Creates NTLMSSP auth bind.
1566 ********************************************************************/
1568 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1569 enum pipe_auth_level auth_level,
1570 RPC_HDR_AUTH *pauth_out,
1571 prs_struct *auth_data)
1573 NTSTATUS nt_status;
1574 DATA_BLOB null_blob = data_blob_null;
1575 DATA_BLOB request = data_blob_null;
1577 /* We may change the pad length before marshalling. */
1578 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1580 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1581 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1582 null_blob,
1583 &request);
1585 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1586 data_blob_free(&request);
1587 prs_mem_free(auth_data);
1588 return nt_status;
1591 /* Auth len in the rpc header doesn't include auth_header. */
1592 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1593 data_blob_free(&request);
1594 prs_mem_free(auth_data);
1595 return NT_STATUS_NO_MEMORY;
1598 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1599 dump_data(5, request.data, request.length);
1601 data_blob_free(&request);
1602 return NT_STATUS_OK;
1605 /*******************************************************************
1606 Creates schannel auth bind.
1607 ********************************************************************/
1609 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1610 enum pipe_auth_level auth_level,
1611 RPC_HDR_AUTH *pauth_out,
1612 prs_struct *auth_data)
1614 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1616 /* We may change the pad length before marshalling. */
1617 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1619 /* Use lp_workgroup() if domain not specified */
1621 if (!cli->auth->domain || !cli->auth->domain[0]) {
1622 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1623 if (cli->auth->domain == NULL) {
1624 return NT_STATUS_NO_MEMORY;
1628 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1629 global_myname());
1632 * Now marshall the data into the auth parse_struct.
1635 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1636 &schannel_neg, auth_data, 0)) {
1637 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1638 prs_mem_free(auth_data);
1639 return NT_STATUS_NO_MEMORY;
1642 return NT_STATUS_OK;
1645 /*******************************************************************
1646 Creates the internals of a DCE/RPC bind request or alter context PDU.
1647 ********************************************************************/
1649 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1650 prs_struct *rpc_out,
1651 uint32 rpc_call_id,
1652 const RPC_IFACE *abstract,
1653 const RPC_IFACE *transfer,
1654 RPC_HDR_AUTH *phdr_auth,
1655 prs_struct *pauth_info)
1657 RPC_HDR hdr;
1658 RPC_HDR_RB hdr_rb;
1659 RPC_CONTEXT rpc_ctx;
1660 uint16 auth_len = prs_offset(pauth_info);
1661 uint8 ss_padding_len = 0;
1662 uint16 frag_len = 0;
1664 /* create the RPC context. */
1665 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1667 /* create the bind request RPC_HDR_RB */
1668 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1670 /* Start building the frag length. */
1671 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1673 /* Do we need to pad ? */
1674 if (auth_len) {
1675 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1676 if (data_len % 8) {
1677 ss_padding_len = 8 - (data_len % 8);
1678 phdr_auth->auth_pad_len = ss_padding_len;
1680 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1683 /* Create the request RPC_HDR */
1684 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1686 /* Marshall the RPC header */
1687 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1688 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1689 return NT_STATUS_NO_MEMORY;
1692 /* Marshall the bind request data */
1693 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1694 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1695 return NT_STATUS_NO_MEMORY;
1699 * Grow the outgoing buffer to store any auth info.
1702 if(auth_len != 0) {
1703 if (ss_padding_len) {
1704 char pad[8];
1705 memset(pad, '\0', 8);
1706 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1707 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1708 return NT_STATUS_NO_MEMORY;
1712 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1713 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1714 return NT_STATUS_NO_MEMORY;
1718 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1719 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1720 return NT_STATUS_NO_MEMORY;
1724 return NT_STATUS_OK;
1727 /*******************************************************************
1728 Creates a DCE/RPC bind request.
1729 ********************************************************************/
1731 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1732 prs_struct *rpc_out,
1733 uint32 rpc_call_id,
1734 const RPC_IFACE *abstract,
1735 const RPC_IFACE *transfer,
1736 enum pipe_auth_type auth_type,
1737 enum pipe_auth_level auth_level)
1739 RPC_HDR_AUTH hdr_auth;
1740 prs_struct auth_info;
1741 NTSTATUS ret = NT_STATUS_OK;
1743 ZERO_STRUCT(hdr_auth);
1744 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1745 return NT_STATUS_NO_MEMORY;
1747 switch (auth_type) {
1748 case PIPE_AUTH_TYPE_SCHANNEL:
1749 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1750 if (!NT_STATUS_IS_OK(ret)) {
1751 prs_mem_free(&auth_info);
1752 return ret;
1754 break;
1756 case PIPE_AUTH_TYPE_NTLMSSP:
1757 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1758 if (!NT_STATUS_IS_OK(ret)) {
1759 prs_mem_free(&auth_info);
1760 return ret;
1762 break;
1764 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1765 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1766 if (!NT_STATUS_IS_OK(ret)) {
1767 prs_mem_free(&auth_info);
1768 return ret;
1770 break;
1772 case PIPE_AUTH_TYPE_KRB5:
1773 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1774 if (!NT_STATUS_IS_OK(ret)) {
1775 prs_mem_free(&auth_info);
1776 return ret;
1778 break;
1780 case PIPE_AUTH_TYPE_NONE:
1781 break;
1783 default:
1784 /* "Can't" happen. */
1785 return NT_STATUS_INVALID_INFO_CLASS;
1788 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1789 rpc_out,
1790 rpc_call_id,
1791 abstract,
1792 transfer,
1793 &hdr_auth,
1794 &auth_info);
1796 prs_mem_free(&auth_info);
1797 return ret;
1800 /*******************************************************************
1801 Create and add the NTLMSSP sign/seal auth header and data.
1802 ********************************************************************/
1804 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1805 RPC_HDR *phdr,
1806 uint32 ss_padding_len,
1807 prs_struct *outgoing_pdu)
1809 RPC_HDR_AUTH auth_info;
1810 NTSTATUS status;
1811 DATA_BLOB auth_blob = data_blob_null;
1812 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1814 if (!cli->auth->a_u.ntlmssp_state) {
1815 return NT_STATUS_INVALID_PARAMETER;
1818 /* Init and marshall the auth header. */
1819 init_rpc_hdr_auth(&auth_info,
1820 map_pipe_auth_type_to_rpc_auth_type(
1821 cli->auth->auth_type),
1822 cli->auth->auth_level,
1823 ss_padding_len,
1824 1 /* context id. */);
1826 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1827 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1828 data_blob_free(&auth_blob);
1829 return NT_STATUS_NO_MEMORY;
1832 switch (cli->auth->auth_level) {
1833 case PIPE_AUTH_LEVEL_PRIVACY:
1834 /* Data portion is encrypted. */
1835 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1836 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1837 data_and_pad_len,
1838 (unsigned char *)prs_data_p(outgoing_pdu),
1839 (size_t)prs_offset(outgoing_pdu),
1840 &auth_blob);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 data_blob_free(&auth_blob);
1843 return status;
1845 break;
1847 case PIPE_AUTH_LEVEL_INTEGRITY:
1848 /* Data is signed. */
1849 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1850 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1851 data_and_pad_len,
1852 (unsigned char *)prs_data_p(outgoing_pdu),
1853 (size_t)prs_offset(outgoing_pdu),
1854 &auth_blob);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 data_blob_free(&auth_blob);
1857 return status;
1859 break;
1861 default:
1862 /* Can't happen. */
1863 smb_panic("bad auth level");
1864 /* Notreached. */
1865 return NT_STATUS_INVALID_PARAMETER;
1868 /* Finally marshall the blob. */
1870 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1871 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1872 (unsigned int)NTLMSSP_SIG_SIZE));
1873 data_blob_free(&auth_blob);
1874 return NT_STATUS_NO_MEMORY;
1877 data_blob_free(&auth_blob);
1878 return NT_STATUS_OK;
1881 /*******************************************************************
1882 Create and add the schannel sign/seal auth header and data.
1883 ********************************************************************/
1885 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1886 RPC_HDR *phdr,
1887 uint32 ss_padding_len,
1888 prs_struct *outgoing_pdu)
1890 RPC_HDR_AUTH auth_info;
1891 RPC_AUTH_SCHANNEL_CHK verf;
1892 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1893 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1894 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1896 if (!sas) {
1897 return NT_STATUS_INVALID_PARAMETER;
1900 /* Init and marshall the auth header. */
1901 init_rpc_hdr_auth(&auth_info,
1902 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1903 cli->auth->auth_level,
1904 ss_padding_len,
1905 1 /* context id. */);
1907 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1908 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1909 return NT_STATUS_NO_MEMORY;
1912 switch (cli->auth->auth_level) {
1913 case PIPE_AUTH_LEVEL_PRIVACY:
1914 case PIPE_AUTH_LEVEL_INTEGRITY:
1915 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1916 sas->seq_num));
1918 schannel_encode(sas,
1919 cli->auth->auth_level,
1920 SENDER_IS_INITIATOR,
1921 &verf,
1922 data_p,
1923 data_and_pad_len);
1925 sas->seq_num++;
1926 break;
1928 default:
1929 /* Can't happen. */
1930 smb_panic("bad auth level");
1931 /* Notreached. */
1932 return NT_STATUS_INVALID_PARAMETER;
1935 /* Finally marshall the blob. */
1936 smb_io_rpc_auth_schannel_chk("",
1937 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1938 &verf,
1939 outgoing_pdu,
1942 return NT_STATUS_OK;
1945 /*******************************************************************
1946 Calculate how much data we're going to send in this packet, also
1947 work out any sign/seal padding length.
1948 ********************************************************************/
1950 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1951 uint32 data_left,
1952 uint16 *p_frag_len,
1953 uint16 *p_auth_len,
1954 uint32 *p_ss_padding)
1956 uint32 data_space, data_len;
1958 #ifdef DEVELOPER
1959 if ((data_left > 0) && (sys_random() % 2)) {
1960 data_left = MAX(data_left/2, 1);
1962 #endif
1964 switch (cli->auth->auth_level) {
1965 case PIPE_AUTH_LEVEL_NONE:
1966 case PIPE_AUTH_LEVEL_CONNECT:
1967 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1968 data_len = MIN(data_space, data_left);
1969 *p_ss_padding = 0;
1970 *p_auth_len = 0;
1971 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1972 return data_len;
1974 case PIPE_AUTH_LEVEL_INTEGRITY:
1975 case PIPE_AUTH_LEVEL_PRIVACY:
1976 /* Treat the same for all authenticated rpc requests. */
1977 switch(cli->auth->auth_type) {
1978 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1979 case PIPE_AUTH_TYPE_NTLMSSP:
1980 *p_auth_len = NTLMSSP_SIG_SIZE;
1981 break;
1982 case PIPE_AUTH_TYPE_SCHANNEL:
1983 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1984 break;
1985 default:
1986 smb_panic("bad auth type");
1987 break;
1990 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1991 RPC_HDR_AUTH_LEN - *p_auth_len;
1993 data_len = MIN(data_space, data_left);
1994 *p_ss_padding = 0;
1995 if (data_len % 8) {
1996 *p_ss_padding = 8 - (data_len % 8);
1998 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1999 data_len + *p_ss_padding + /* data plus padding. */
2000 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2001 return data_len;
2003 default:
2004 smb_panic("bad auth level");
2005 /* Notreached. */
2006 return 0;
2010 /*******************************************************************
2011 External interface.
2012 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2013 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2014 and deals with signing/sealing details.
2015 ********************************************************************/
2017 struct rpc_api_pipe_req_state {
2018 struct event_context *ev;
2019 struct rpc_pipe_client *cli;
2020 uint8_t op_num;
2021 uint32_t call_id;
2022 prs_struct *req_data;
2023 uint32_t req_data_sent;
2024 prs_struct outgoing_frag;
2025 prs_struct reply_pdu;
2028 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2030 prs_mem_free(&s->outgoing_frag);
2031 prs_mem_free(&s->reply_pdu);
2032 return 0;
2035 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2036 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2037 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2038 bool *is_last_frag);
2040 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2041 struct event_context *ev,
2042 struct rpc_pipe_client *cli,
2043 uint8_t op_num,
2044 prs_struct *req_data)
2046 struct tevent_req *req, *subreq;
2047 struct rpc_api_pipe_req_state *state;
2048 NTSTATUS status;
2049 bool is_last_frag;
2051 req = tevent_req_create(mem_ctx, &state,
2052 struct rpc_api_pipe_req_state);
2053 if (req == NULL) {
2054 return NULL;
2056 state->ev = ev;
2057 state->cli = cli;
2058 state->op_num = op_num;
2059 state->req_data = req_data;
2060 state->req_data_sent = 0;
2061 state->call_id = get_rpc_call_id();
2063 if (cli->max_xmit_frag
2064 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2065 /* Server is screwed up ! */
2066 status = NT_STATUS_INVALID_PARAMETER;
2067 goto post_status;
2070 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2072 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2073 state, MARSHALL)) {
2074 goto fail;
2077 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2079 status = prepare_next_frag(state, &is_last_frag);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 goto post_status;
2084 if (is_last_frag) {
2085 subreq = rpc_api_pipe_send(state, ev, state->cli,
2086 &state->outgoing_frag,
2087 RPC_RESPONSE);
2088 if (subreq == NULL) {
2089 goto fail;
2091 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2092 } else {
2093 subreq = rpc_write_send(
2094 state, ev, cli->transport,
2095 (uint8_t *)prs_data_p(&state->outgoing_frag),
2096 prs_offset(&state->outgoing_frag));
2097 if (subreq == NULL) {
2098 goto fail;
2100 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2101 req);
2103 return req;
2105 post_status:
2106 tevent_req_nterror(req, status);
2107 return tevent_req_post(req, ev);
2108 fail:
2109 TALLOC_FREE(req);
2110 return NULL;
2113 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2114 bool *is_last_frag)
2116 RPC_HDR hdr;
2117 RPC_HDR_REQ hdr_req;
2118 uint32_t data_sent_thistime;
2119 uint16_t auth_len;
2120 uint16_t frag_len;
2121 uint8_t flags = 0;
2122 uint32_t ss_padding;
2123 uint32_t data_left;
2124 char pad[8] = { 0, };
2125 NTSTATUS status;
2127 data_left = prs_offset(state->req_data) - state->req_data_sent;
2129 data_sent_thistime = calculate_data_len_tosend(
2130 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2132 if (state->req_data_sent == 0) {
2133 flags = RPC_FLG_FIRST;
2136 if (data_sent_thistime == data_left) {
2137 flags |= RPC_FLG_LAST;
2140 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2141 return NT_STATUS_NO_MEMORY;
2144 /* Create and marshall the header and request header. */
2145 init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len,
2146 auth_len);
2148 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2149 return NT_STATUS_NO_MEMORY;
2152 /* Create the rpc request RPC_HDR_REQ */
2153 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2154 state->op_num);
2156 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2157 &state->outgoing_frag, 0)) {
2158 return NT_STATUS_NO_MEMORY;
2161 /* Copy in the data, plus any ss padding. */
2162 if (!prs_append_some_prs_data(&state->outgoing_frag,
2163 state->req_data, state->req_data_sent,
2164 data_sent_thistime)) {
2165 return NT_STATUS_NO_MEMORY;
2168 /* Copy the sign/seal padding data. */
2169 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2170 return NT_STATUS_NO_MEMORY;
2173 /* Generate any auth sign/seal and add the auth footer. */
2174 switch (state->cli->auth->auth_type) {
2175 case PIPE_AUTH_TYPE_NONE:
2176 status = NT_STATUS_OK;
2177 break;
2178 case PIPE_AUTH_TYPE_NTLMSSP:
2179 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2180 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2181 &state->outgoing_frag);
2182 break;
2183 case PIPE_AUTH_TYPE_SCHANNEL:
2184 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2185 &state->outgoing_frag);
2186 break;
2187 default:
2188 status = NT_STATUS_INVALID_PARAMETER;
2189 break;
2192 state->req_data_sent += data_sent_thistime;
2193 *is_last_frag = ((flags & RPC_FLG_LAST) != 0);
2195 return status;
2198 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2200 struct tevent_req *req = tevent_req_callback_data(
2201 subreq, struct tevent_req);
2202 struct rpc_api_pipe_req_state *state = tevent_req_data(
2203 req, struct rpc_api_pipe_req_state);
2204 NTSTATUS status;
2205 bool is_last_frag;
2207 status = rpc_write_recv(subreq);
2208 TALLOC_FREE(subreq);
2209 if (!NT_STATUS_IS_OK(status)) {
2210 tevent_req_nterror(req, status);
2211 return;
2214 status = prepare_next_frag(state, &is_last_frag);
2215 if (!NT_STATUS_IS_OK(status)) {
2216 tevent_req_nterror(req, status);
2217 return;
2220 if (is_last_frag) {
2221 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2222 &state->outgoing_frag,
2223 RPC_RESPONSE);
2224 if (tevent_req_nomem(subreq, req)) {
2225 return;
2227 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2228 } else {
2229 subreq = rpc_write_send(
2230 state, state->ev,
2231 state->cli->transport,
2232 (uint8_t *)prs_data_p(&state->outgoing_frag),
2233 prs_offset(&state->outgoing_frag));
2234 if (tevent_req_nomem(subreq, req)) {
2235 return;
2237 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2238 req);
2242 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2244 struct tevent_req *req = tevent_req_callback_data(
2245 subreq, struct tevent_req);
2246 struct rpc_api_pipe_req_state *state = tevent_req_data(
2247 req, struct rpc_api_pipe_req_state);
2248 NTSTATUS status;
2250 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2251 TALLOC_FREE(subreq);
2252 if (!NT_STATUS_IS_OK(status)) {
2253 tevent_req_nterror(req, status);
2254 return;
2256 tevent_req_done(req);
2259 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2260 prs_struct *reply_pdu)
2262 struct rpc_api_pipe_req_state *state = tevent_req_data(
2263 req, struct rpc_api_pipe_req_state);
2264 NTSTATUS status;
2266 if (tevent_req_is_nterror(req, &status)) {
2268 * We always have to initialize to reply pdu, even if there is
2269 * none. The rpccli_* caller routines expect this.
2271 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2272 return status;
2275 *reply_pdu = state->reply_pdu;
2276 reply_pdu->mem_ctx = mem_ctx;
2279 * Prevent state->req_pdu from being freed in
2280 * rpc_api_pipe_req_state_destructor()
2282 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2284 return NT_STATUS_OK;
2287 NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
2288 uint8 op_num,
2289 prs_struct *in_data,
2290 prs_struct *out_data)
2292 TALLOC_CTX *frame = talloc_stackframe();
2293 struct event_context *ev;
2294 struct tevent_req *req;
2295 NTSTATUS status = NT_STATUS_OK;
2297 ev = event_context_init(frame);
2298 if (ev == NULL) {
2299 status = NT_STATUS_NO_MEMORY;
2300 goto fail;
2303 req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
2304 if (req == NULL) {
2305 status = NT_STATUS_NO_MEMORY;
2306 goto fail;
2309 if (!tevent_req_poll(req, ev)) {
2310 status = map_nt_error_from_unix(errno);
2311 goto fail;
2314 status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
2315 fail:
2316 TALLOC_FREE(frame);
2317 return status;
2320 #if 0
2321 /****************************************************************************
2322 Set the handle state.
2323 ****************************************************************************/
2325 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2326 const char *pipe_name, uint16 device_state)
2328 bool state_set = False;
2329 char param[2];
2330 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2331 char *rparam = NULL;
2332 char *rdata = NULL;
2333 uint32 rparam_len, rdata_len;
2335 if (pipe_name == NULL)
2336 return False;
2338 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2339 cli->fnum, pipe_name, device_state));
2341 /* create parameters: device state */
2342 SSVAL(param, 0, device_state);
2344 /* create setup parameters. */
2345 setup[0] = 0x0001;
2346 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2348 /* send the data on \PIPE\ */
2349 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2350 setup, 2, 0, /* setup, length, max */
2351 param, 2, 0, /* param, length, max */
2352 NULL, 0, 1024, /* data, length, max */
2353 &rparam, &rparam_len, /* return param, length */
2354 &rdata, &rdata_len)) /* return data, length */
2356 DEBUG(5, ("Set Handle state: return OK\n"));
2357 state_set = True;
2360 SAFE_FREE(rparam);
2361 SAFE_FREE(rdata);
2363 return state_set;
2365 #endif
2367 /****************************************************************************
2368 Check the rpc bind acknowledge response.
2369 ****************************************************************************/
2371 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
2373 if ( hdr_ba->addr.len == 0) {
2374 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2377 /* check the transfer syntax */
2378 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2379 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2380 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2381 return False;
2384 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2385 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2386 hdr_ba->res.num_results, hdr_ba->res.reason));
2389 DEBUG(5,("check_bind_response: accepted!\n"));
2390 return True;
2393 /*******************************************************************
2394 Creates a DCE/RPC bind authentication response.
2395 This is the packet that is sent back to the server once we
2396 have received a BIND-ACK, to finish the third leg of
2397 the authentication handshake.
2398 ********************************************************************/
2400 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2401 uint32 rpc_call_id,
2402 enum pipe_auth_type auth_type,
2403 enum pipe_auth_level auth_level,
2404 DATA_BLOB *pauth_blob,
2405 prs_struct *rpc_out)
2407 RPC_HDR hdr;
2408 RPC_HDR_AUTH hdr_auth;
2409 uint32 pad = 0;
2411 /* Create the request RPC_HDR */
2412 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
2413 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2414 pauth_blob->length );
2416 /* Marshall it. */
2417 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2418 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2419 return NT_STATUS_NO_MEMORY;
2423 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2424 about padding - shouldn't this pad to length 8 ? JRA.
2427 /* 4 bytes padding. */
2428 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2429 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2430 return NT_STATUS_NO_MEMORY;
2433 /* Create the request RPC_HDR_AUTHA */
2434 init_rpc_hdr_auth(&hdr_auth,
2435 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2436 auth_level, 0, 1);
2438 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2439 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2440 return NT_STATUS_NO_MEMORY;
2444 * Append the auth data to the outgoing buffer.
2447 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2448 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2449 return NT_STATUS_NO_MEMORY;
2452 return NT_STATUS_OK;
2455 /*******************************************************************
2456 Creates a DCE/RPC bind alter context authentication request which
2457 may contain a spnego auth blobl
2458 ********************************************************************/
2460 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2461 const RPC_IFACE *abstract,
2462 const RPC_IFACE *transfer,
2463 enum pipe_auth_level auth_level,
2464 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2465 prs_struct *rpc_out)
2467 RPC_HDR_AUTH hdr_auth;
2468 prs_struct auth_info;
2469 NTSTATUS ret = NT_STATUS_OK;
2471 ZERO_STRUCT(hdr_auth);
2472 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2473 return NT_STATUS_NO_MEMORY;
2475 /* We may change the pad length before marshalling. */
2476 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2478 if (pauth_blob->length) {
2479 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2480 prs_mem_free(&auth_info);
2481 return NT_STATUS_NO_MEMORY;
2485 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2486 rpc_out,
2487 rpc_call_id,
2488 abstract,
2489 transfer,
2490 &hdr_auth,
2491 &auth_info);
2492 prs_mem_free(&auth_info);
2493 return ret;
2496 /****************************************************************************
2497 Do an rpc bind.
2498 ****************************************************************************/
2500 struct rpc_pipe_bind_state {
2501 struct event_context *ev;
2502 struct rpc_pipe_client *cli;
2503 prs_struct rpc_out;
2504 uint32_t rpc_call_id;
2507 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2509 prs_mem_free(&state->rpc_out);
2510 return 0;
2513 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2514 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2515 struct rpc_pipe_bind_state *state,
2516 struct rpc_hdr_info *phdr,
2517 prs_struct *reply_pdu);
2518 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2519 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2520 struct rpc_pipe_bind_state *state,
2521 struct rpc_hdr_info *phdr,
2522 prs_struct *reply_pdu);
2523 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2525 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2526 struct event_context *ev,
2527 struct rpc_pipe_client *cli,
2528 struct cli_pipe_auth_data *auth)
2530 struct tevent_req *req, *subreq;
2531 struct rpc_pipe_bind_state *state;
2532 NTSTATUS status;
2534 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2535 if (req == NULL) {
2536 return NULL;
2539 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2540 rpccli_pipe_txt(debug_ctx(), cli),
2541 (unsigned int)auth->auth_type,
2542 (unsigned int)auth->auth_level ));
2544 state->ev = ev;
2545 state->cli = cli;
2546 state->rpc_call_id = get_rpc_call_id();
2548 prs_init_empty(&state->rpc_out, state, MARSHALL);
2549 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2551 cli->auth = talloc_move(cli, &auth);
2553 /* Marshall the outgoing data. */
2554 status = create_rpc_bind_req(cli, &state->rpc_out,
2555 state->rpc_call_id,
2556 &cli->abstract_syntax,
2557 &cli->transfer_syntax,
2558 cli->auth->auth_type,
2559 cli->auth->auth_level);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 goto post_status;
2565 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2566 RPC_BINDACK);
2567 if (subreq == NULL) {
2568 goto fail;
2570 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2571 return req;
2573 post_status:
2574 tevent_req_nterror(req, status);
2575 return tevent_req_post(req, ev);
2576 fail:
2577 TALLOC_FREE(req);
2578 return NULL;
2581 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2583 struct tevent_req *req = tevent_req_callback_data(
2584 subreq, struct tevent_req);
2585 struct rpc_pipe_bind_state *state = tevent_req_data(
2586 req, struct rpc_pipe_bind_state);
2587 prs_struct reply_pdu;
2588 struct rpc_hdr_info hdr;
2589 struct rpc_hdr_ba_info hdr_ba;
2590 NTSTATUS status;
2592 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2593 TALLOC_FREE(subreq);
2594 if (!NT_STATUS_IS_OK(status)) {
2595 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2596 rpccli_pipe_txt(debug_ctx(), state->cli),
2597 nt_errstr(status)));
2598 tevent_req_nterror(req, status);
2599 return;
2602 /* Unmarshall the RPC header */
2603 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2604 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2605 prs_mem_free(&reply_pdu);
2606 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2607 return;
2610 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2611 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2612 "RPC_HDR_BA.\n"));
2613 prs_mem_free(&reply_pdu);
2614 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2615 return;
2618 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2619 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2620 prs_mem_free(&reply_pdu);
2621 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2622 return;
2625 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2626 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2629 * For authenticated binds we may need to do 3 or 4 leg binds.
2632 switch(state->cli->auth->auth_type) {
2634 case PIPE_AUTH_TYPE_NONE:
2635 case PIPE_AUTH_TYPE_SCHANNEL:
2636 /* Bind complete. */
2637 prs_mem_free(&reply_pdu);
2638 tevent_req_done(req);
2639 break;
2641 case PIPE_AUTH_TYPE_NTLMSSP:
2642 /* Need to send AUTH3 packet - no reply. */
2643 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2644 &reply_pdu);
2645 prs_mem_free(&reply_pdu);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 tevent_req_nterror(req, status);
2649 break;
2651 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2652 /* Need to send alter context request and reply. */
2653 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2654 &reply_pdu);
2655 prs_mem_free(&reply_pdu);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 tevent_req_nterror(req, status);
2659 break;
2661 case PIPE_AUTH_TYPE_KRB5:
2662 /* */
2664 default:
2665 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2666 (unsigned int)state->cli->auth->auth_type));
2667 prs_mem_free(&reply_pdu);
2668 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2672 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2673 struct rpc_pipe_bind_state *state,
2674 struct rpc_hdr_info *phdr,
2675 prs_struct *reply_pdu)
2677 DATA_BLOB server_response = data_blob_null;
2678 DATA_BLOB client_reply = data_blob_null;
2679 struct rpc_hdr_auth_info hdr_auth;
2680 struct tevent_req *subreq;
2681 NTSTATUS status;
2683 if ((phdr->auth_len == 0)
2684 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2685 return NT_STATUS_INVALID_PARAMETER;
2688 if (!prs_set_offset(
2689 reply_pdu,
2690 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2691 return NT_STATUS_INVALID_PARAMETER;
2694 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2695 return NT_STATUS_INVALID_PARAMETER;
2698 /* TODO - check auth_type/auth_level match. */
2700 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2701 prs_copy_data_out((char *)server_response.data, reply_pdu,
2702 phdr->auth_len);
2704 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2705 server_response, &client_reply);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2709 "blob failed: %s.\n", nt_errstr(status)));
2710 return status;
2713 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2715 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2716 state->cli->auth->auth_type,
2717 state->cli->auth->auth_level,
2718 &client_reply, &state->rpc_out);
2719 data_blob_free(&client_reply);
2721 if (!NT_STATUS_IS_OK(status)) {
2722 return status;
2725 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2726 (uint8_t *)prs_data_p(&state->rpc_out),
2727 prs_offset(&state->rpc_out));
2728 if (subreq == NULL) {
2729 return NT_STATUS_NO_MEMORY;
2731 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2732 return NT_STATUS_OK;
2735 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2737 struct tevent_req *req = tevent_req_callback_data(
2738 subreq, struct tevent_req);
2739 NTSTATUS status;
2741 status = rpc_write_recv(subreq);
2742 TALLOC_FREE(subreq);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 tevent_req_nterror(req, status);
2745 return;
2747 tevent_req_done(req);
2750 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2751 struct rpc_pipe_bind_state *state,
2752 struct rpc_hdr_info *phdr,
2753 prs_struct *reply_pdu)
2755 DATA_BLOB server_spnego_response = data_blob_null;
2756 DATA_BLOB server_ntlm_response = data_blob_null;
2757 DATA_BLOB client_reply = data_blob_null;
2758 DATA_BLOB tmp_blob = data_blob_null;
2759 RPC_HDR_AUTH hdr_auth;
2760 struct tevent_req *subreq;
2761 NTSTATUS status;
2763 if ((phdr->auth_len == 0)
2764 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2765 return NT_STATUS_INVALID_PARAMETER;
2768 /* Process the returned NTLMSSP blob first. */
2769 if (!prs_set_offset(
2770 reply_pdu,
2771 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2772 return NT_STATUS_INVALID_PARAMETER;
2775 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2776 return NT_STATUS_INVALID_PARAMETER;
2779 server_spnego_response = data_blob(NULL, phdr->auth_len);
2780 prs_copy_data_out((char *)server_spnego_response.data,
2781 reply_pdu, phdr->auth_len);
2784 * The server might give us back two challenges - tmp_blob is for the
2785 * second.
2787 if (!spnego_parse_challenge(server_spnego_response,
2788 &server_ntlm_response, &tmp_blob)) {
2789 data_blob_free(&server_spnego_response);
2790 data_blob_free(&server_ntlm_response);
2791 data_blob_free(&tmp_blob);
2792 return NT_STATUS_INVALID_PARAMETER;
2795 /* We're finished with the server spnego response and the tmp_blob. */
2796 data_blob_free(&server_spnego_response);
2797 data_blob_free(&tmp_blob);
2799 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2800 server_ntlm_response, &client_reply);
2802 /* Finished with the server_ntlm response */
2803 data_blob_free(&server_ntlm_response);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2807 "using server blob failed.\n"));
2808 data_blob_free(&client_reply);
2809 return status;
2812 /* SPNEGO wrap the client reply. */
2813 tmp_blob = spnego_gen_auth(client_reply);
2814 data_blob_free(&client_reply);
2815 client_reply = tmp_blob;
2816 tmp_blob = data_blob_null;
2818 /* Now prepare the alter context pdu. */
2819 prs_init_empty(&state->rpc_out, state, MARSHALL);
2821 status = create_rpc_alter_context(state->rpc_call_id,
2822 &state->cli->abstract_syntax,
2823 &state->cli->transfer_syntax,
2824 state->cli->auth->auth_level,
2825 &client_reply,
2826 &state->rpc_out);
2827 data_blob_free(&client_reply);
2829 if (!NT_STATUS_IS_OK(status)) {
2830 return status;
2833 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2834 &state->rpc_out, RPC_ALTCONTRESP);
2835 if (subreq == NULL) {
2836 return NT_STATUS_NO_MEMORY;
2838 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2839 return NT_STATUS_OK;
2842 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2844 struct tevent_req *req = tevent_req_callback_data(
2845 subreq, struct tevent_req);
2846 struct rpc_pipe_bind_state *state = tevent_req_data(
2847 req, struct rpc_pipe_bind_state);
2848 DATA_BLOB server_spnego_response = data_blob_null;
2849 DATA_BLOB tmp_blob = data_blob_null;
2850 prs_struct reply_pdu;
2851 struct rpc_hdr_info hdr;
2852 struct rpc_hdr_auth_info hdr_auth;
2853 NTSTATUS status;
2855 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2856 TALLOC_FREE(subreq);
2857 if (!NT_STATUS_IS_OK(status)) {
2858 tevent_req_nterror(req, status);
2859 return;
2862 /* Get the auth blob from the reply. */
2863 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2864 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2865 "unmarshall RPC_HDR.\n"));
2866 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2867 return;
2870 if (!prs_set_offset(
2871 &reply_pdu,
2872 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2873 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2874 return;
2877 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2878 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2879 return;
2882 server_spnego_response = data_blob(NULL, hdr.auth_len);
2883 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2884 hdr.auth_len);
2886 /* Check we got a valid auth response. */
2887 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2888 OID_NTLMSSP, &tmp_blob)) {
2889 data_blob_free(&server_spnego_response);
2890 data_blob_free(&tmp_blob);
2891 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2892 return;
2895 data_blob_free(&server_spnego_response);
2896 data_blob_free(&tmp_blob);
2898 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2899 "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2900 tevent_req_done(req);
2903 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2905 return tevent_req_simple_recv_ntstatus(req);
2908 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2909 struct cli_pipe_auth_data *auth)
2911 TALLOC_CTX *frame = talloc_stackframe();
2912 struct event_context *ev;
2913 struct tevent_req *req;
2914 NTSTATUS status = NT_STATUS_OK;
2916 ev = event_context_init(frame);
2917 if (ev == NULL) {
2918 status = NT_STATUS_NO_MEMORY;
2919 goto fail;
2922 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2923 if (req == NULL) {
2924 status = NT_STATUS_NO_MEMORY;
2925 goto fail;
2928 if (!tevent_req_poll(req, ev)) {
2929 status = map_nt_error_from_unix(errno);
2930 goto fail;
2933 status = rpc_pipe_bind_recv(req);
2934 fail:
2935 TALLOC_FREE(frame);
2936 return status;
2939 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2940 unsigned int timeout)
2942 struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2944 if (cli == NULL) {
2945 return 0;
2947 return cli_set_timeout(cli, timeout);
2950 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2952 struct cli_state *cli;
2954 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2955 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2956 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2957 return true;
2960 cli = rpc_pipe_np_smb_conn(rpc_cli);
2961 if (cli == NULL) {
2962 return false;
2964 E_md4hash(cli->password ? cli->password : "", nt_hash);
2965 return true;
2968 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2969 struct cli_pipe_auth_data **presult)
2971 struct cli_pipe_auth_data *result;
2973 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2974 if (result == NULL) {
2975 return NT_STATUS_NO_MEMORY;
2978 result->auth_type = PIPE_AUTH_TYPE_NONE;
2979 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2981 result->user_name = talloc_strdup(result, "");
2982 result->domain = talloc_strdup(result, "");
2983 if ((result->user_name == NULL) || (result->domain == NULL)) {
2984 TALLOC_FREE(result);
2985 return NT_STATUS_NO_MEMORY;
2988 *presult = result;
2989 return NT_STATUS_OK;
2992 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2994 ntlmssp_end(&auth->a_u.ntlmssp_state);
2995 return 0;
2998 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2999 enum pipe_auth_type auth_type,
3000 enum pipe_auth_level auth_level,
3001 const char *domain,
3002 const char *username,
3003 const char *password,
3004 struct cli_pipe_auth_data **presult)
3006 struct cli_pipe_auth_data *result;
3007 NTSTATUS status;
3009 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3010 if (result == NULL) {
3011 return NT_STATUS_NO_MEMORY;
3014 result->auth_type = auth_type;
3015 result->auth_level = auth_level;
3017 result->user_name = talloc_strdup(result, username);
3018 result->domain = talloc_strdup(result, domain);
3019 if ((result->user_name == NULL) || (result->domain == NULL)) {
3020 status = NT_STATUS_NO_MEMORY;
3021 goto fail;
3024 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3025 if (!NT_STATUS_IS_OK(status)) {
3026 goto fail;
3029 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3031 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3032 if (!NT_STATUS_IS_OK(status)) {
3033 goto fail;
3036 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3037 if (!NT_STATUS_IS_OK(status)) {
3038 goto fail;
3041 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3042 if (!NT_STATUS_IS_OK(status)) {
3043 goto fail;
3047 * Turn off sign+seal to allow selected auth level to turn it back on.
3049 result->a_u.ntlmssp_state->neg_flags &=
3050 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3052 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
3053 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3054 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
3055 result->a_u.ntlmssp_state->neg_flags
3056 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3059 *presult = result;
3060 return NT_STATUS_OK;
3062 fail:
3063 TALLOC_FREE(result);
3064 return status;
3067 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3068 enum pipe_auth_level auth_level,
3069 const uint8_t sess_key[16],
3070 struct cli_pipe_auth_data **presult)
3072 struct cli_pipe_auth_data *result;
3074 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3075 if (result == NULL) {
3076 return NT_STATUS_NO_MEMORY;
3079 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3080 result->auth_level = auth_level;
3082 result->user_name = talloc_strdup(result, "");
3083 result->domain = talloc_strdup(result, domain);
3084 if ((result->user_name == NULL) || (result->domain == NULL)) {
3085 goto fail;
3088 result->a_u.schannel_auth = talloc(result,
3089 struct schannel_auth_struct);
3090 if (result->a_u.schannel_auth == NULL) {
3091 goto fail;
3094 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
3095 sizeof(result->a_u.schannel_auth->sess_key));
3096 result->a_u.schannel_auth->seq_num = 0;
3098 *presult = result;
3099 return NT_STATUS_OK;
3101 fail:
3102 TALLOC_FREE(result);
3103 return NT_STATUS_NO_MEMORY;
3106 #ifdef HAVE_KRB5
3107 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3109 data_blob_free(&auth->session_key);
3110 return 0;
3112 #endif
3114 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3115 enum pipe_auth_level auth_level,
3116 const char *service_princ,
3117 const char *username,
3118 const char *password,
3119 struct cli_pipe_auth_data **presult)
3121 #ifdef HAVE_KRB5
3122 struct cli_pipe_auth_data *result;
3124 if ((username != NULL) && (password != NULL)) {
3125 int ret = kerberos_kinit_password(username, password, 0, NULL);
3126 if (ret != 0) {
3127 return NT_STATUS_ACCESS_DENIED;
3131 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3132 if (result == NULL) {
3133 return NT_STATUS_NO_MEMORY;
3136 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3137 result->auth_level = auth_level;
3140 * Username / domain need fixing!
3142 result->user_name = talloc_strdup(result, "");
3143 result->domain = talloc_strdup(result, "");
3144 if ((result->user_name == NULL) || (result->domain == NULL)) {
3145 goto fail;
3148 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3149 result, struct kerberos_auth_struct);
3150 if (result->a_u.kerberos_auth == NULL) {
3151 goto fail;
3153 talloc_set_destructor(result->a_u.kerberos_auth,
3154 cli_auth_kerberos_data_destructor);
3156 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3157 result, service_princ);
3158 if (result->a_u.kerberos_auth->service_principal == NULL) {
3159 goto fail;
3162 *presult = result;
3163 return NT_STATUS_OK;
3165 fail:
3166 TALLOC_FREE(result);
3167 return NT_STATUS_NO_MEMORY;
3168 #else
3169 return NT_STATUS_NOT_SUPPORTED;
3170 #endif
3174 * Create an rpc pipe client struct, connecting to a tcp port.
3176 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3177 uint16_t port,
3178 const struct ndr_syntax_id *abstract_syntax,
3179 struct rpc_pipe_client **presult)
3181 struct rpc_pipe_client *result;
3182 struct sockaddr_storage addr;
3183 NTSTATUS status;
3184 int fd;
3186 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3187 if (result == NULL) {
3188 return NT_STATUS_NO_MEMORY;
3191 result->abstract_syntax = *abstract_syntax;
3192 result->transfer_syntax = ndr_transfer_syntax;
3193 result->dispatch = cli_do_rpc_ndr;
3195 result->desthost = talloc_strdup(result, host);
3196 result->srv_name_slash = talloc_asprintf_strupper_m(
3197 result, "\\\\%s", result->desthost);
3198 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3199 status = NT_STATUS_NO_MEMORY;
3200 goto fail;
3203 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3204 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3206 if (!resolve_name(host, &addr, 0)) {
3207 status = NT_STATUS_NOT_FOUND;
3208 goto fail;
3211 status = open_socket_out(&addr, port, 60, &fd);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 goto fail;
3215 set_socket_options(fd, lp_socket_options());
3217 status = rpc_transport_sock_init(result, fd, &result->transport);
3218 if (!NT_STATUS_IS_OK(status)) {
3219 close(fd);
3220 goto fail;
3223 *presult = result;
3224 return NT_STATUS_OK;
3226 fail:
3227 TALLOC_FREE(result);
3228 return status;
3232 * Determine the tcp port on which a dcerpc interface is listening
3233 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3234 * target host.
3236 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3237 const struct ndr_syntax_id *abstract_syntax,
3238 uint16_t *pport)
3240 NTSTATUS status;
3241 struct rpc_pipe_client *epm_pipe = NULL;
3242 struct cli_pipe_auth_data *auth = NULL;
3243 struct dcerpc_binding *map_binding = NULL;
3244 struct dcerpc_binding *res_binding = NULL;
3245 struct epm_twr_t *map_tower = NULL;
3246 struct epm_twr_t *res_towers = NULL;
3247 struct policy_handle *entry_handle = NULL;
3248 uint32_t num_towers = 0;
3249 uint32_t max_towers = 1;
3250 struct epm_twr_p_t towers;
3251 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3253 if (pport == NULL) {
3254 status = NT_STATUS_INVALID_PARAMETER;
3255 goto done;
3258 /* open the connection to the endpoint mapper */
3259 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3260 &ndr_table_epmapper.syntax_id,
3261 &epm_pipe);
3263 if (!NT_STATUS_IS_OK(status)) {
3264 goto done;
3267 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 goto done;
3272 status = rpc_pipe_bind(epm_pipe, auth);
3273 if (!NT_STATUS_IS_OK(status)) {
3274 goto done;
3277 /* create tower for asking the epmapper */
3279 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3280 if (map_binding == NULL) {
3281 status = NT_STATUS_NO_MEMORY;
3282 goto done;
3285 map_binding->transport = NCACN_IP_TCP;
3286 map_binding->object = *abstract_syntax;
3287 map_binding->host = host; /* needed? */
3288 map_binding->endpoint = "0"; /* correct? needed? */
3290 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3291 if (map_tower == NULL) {
3292 status = NT_STATUS_NO_MEMORY;
3293 goto done;
3296 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3297 &(map_tower->tower));
3298 if (!NT_STATUS_IS_OK(status)) {
3299 goto done;
3302 /* allocate further parameters for the epm_Map call */
3304 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3305 if (res_towers == NULL) {
3306 status = NT_STATUS_NO_MEMORY;
3307 goto done;
3309 towers.twr = res_towers;
3311 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3312 if (entry_handle == NULL) {
3313 status = NT_STATUS_NO_MEMORY;
3314 goto done;
3317 /* ask the endpoint mapper for the port */
3319 status = rpccli_epm_Map(epm_pipe,
3320 tmp_ctx,
3321 CONST_DISCARD(struct GUID *,
3322 &(abstract_syntax->uuid)),
3323 map_tower,
3324 entry_handle,
3325 max_towers,
3326 &num_towers,
3327 &towers);
3329 if (!NT_STATUS_IS_OK(status)) {
3330 goto done;
3333 if (num_towers != 1) {
3334 status = NT_STATUS_UNSUCCESSFUL;
3335 goto done;
3338 /* extract the port from the answer */
3340 status = dcerpc_binding_from_tower(tmp_ctx,
3341 &(towers.twr->tower),
3342 &res_binding);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 goto done;
3347 /* are further checks here necessary? */
3348 if (res_binding->transport != NCACN_IP_TCP) {
3349 status = NT_STATUS_UNSUCCESSFUL;
3350 goto done;
3353 *pport = (uint16_t)atoi(res_binding->endpoint);
3355 done:
3356 TALLOC_FREE(tmp_ctx);
3357 return status;
3361 * Create a rpc pipe client struct, connecting to a host via tcp.
3362 * The port is determined by asking the endpoint mapper on the given
3363 * host.
3365 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3366 const struct ndr_syntax_id *abstract_syntax,
3367 struct rpc_pipe_client **presult)
3369 NTSTATUS status;
3370 uint16_t port = 0;
3372 *presult = NULL;
3374 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3375 if (!NT_STATUS_IS_OK(status)) {
3376 goto done;
3379 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3380 abstract_syntax, presult);
3382 done:
3383 return status;
3386 /********************************************************************
3387 Create a rpc pipe client struct, connecting to a unix domain socket
3388 ********************************************************************/
3389 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3390 const struct ndr_syntax_id *abstract_syntax,
3391 struct rpc_pipe_client **presult)
3393 struct rpc_pipe_client *result;
3394 struct sockaddr_un addr;
3395 NTSTATUS status;
3396 int fd;
3398 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3399 if (result == NULL) {
3400 return NT_STATUS_NO_MEMORY;
3403 result->abstract_syntax = *abstract_syntax;
3404 result->transfer_syntax = ndr_transfer_syntax;
3405 result->dispatch = cli_do_rpc_ndr;
3407 result->desthost = get_myname(result);
3408 result->srv_name_slash = talloc_asprintf_strupper_m(
3409 result, "\\\\%s", result->desthost);
3410 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3411 status = NT_STATUS_NO_MEMORY;
3412 goto fail;
3415 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3416 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3418 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3419 if (fd == -1) {
3420 status = map_nt_error_from_unix(errno);
3421 goto fail;
3424 ZERO_STRUCT(addr);
3425 addr.sun_family = AF_UNIX;
3426 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3428 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3429 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3430 strerror(errno)));
3431 close(fd);
3432 return map_nt_error_from_unix(errno);
3435 status = rpc_transport_sock_init(result, fd, &result->transport);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 close(fd);
3438 goto fail;
3441 *presult = result;
3442 return NT_STATUS_OK;
3444 fail:
3445 TALLOC_FREE(result);
3446 return status;
3449 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3451 struct cli_state *cli;
3453 cli = rpc_pipe_np_smb_conn(p);
3454 if (cli != NULL) {
3455 DLIST_REMOVE(cli->pipe_list, p);
3457 return 0;
3460 /****************************************************************************
3461 Open a named pipe over SMB to a remote server.
3463 * CAVEAT CALLER OF THIS FUNCTION:
3464 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3465 * so be sure that this function is called AFTER any structure (vs pointer)
3466 * assignment of the cli. In particular, libsmbclient does structure
3467 * assignments of cli, which invalidates the data in the returned
3468 * rpc_pipe_client if this function is called before the structure assignment
3469 * of cli.
3471 ****************************************************************************/
3473 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3474 const struct ndr_syntax_id *abstract_syntax,
3475 struct rpc_pipe_client **presult)
3477 struct rpc_pipe_client *result;
3478 NTSTATUS status;
3480 /* sanity check to protect against crashes */
3482 if ( !cli ) {
3483 return NT_STATUS_INVALID_HANDLE;
3486 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3487 if (result == NULL) {
3488 return NT_STATUS_NO_MEMORY;
3491 result->abstract_syntax = *abstract_syntax;
3492 result->transfer_syntax = ndr_transfer_syntax;
3493 result->dispatch = cli_do_rpc_ndr;
3494 result->desthost = talloc_strdup(result, cli->desthost);
3495 result->srv_name_slash = talloc_asprintf_strupper_m(
3496 result, "\\\\%s", result->desthost);
3498 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3499 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3501 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3502 TALLOC_FREE(result);
3503 return NT_STATUS_NO_MEMORY;
3506 status = rpc_transport_np_init(result, cli, abstract_syntax,
3507 &result->transport);
3508 if (!NT_STATUS_IS_OK(status)) {
3509 TALLOC_FREE(result);
3510 return status;
3513 DLIST_ADD(cli->pipe_list, result);
3514 talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3516 *presult = result;
3517 return NT_STATUS_OK;
3520 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3521 struct rpc_cli_smbd_conn *conn,
3522 const struct ndr_syntax_id *syntax,
3523 struct rpc_pipe_client **presult)
3525 struct rpc_pipe_client *result;
3526 struct cli_pipe_auth_data *auth;
3527 NTSTATUS status;
3529 result = talloc(mem_ctx, struct rpc_pipe_client);
3530 if (result == NULL) {
3531 return NT_STATUS_NO_MEMORY;
3533 result->abstract_syntax = *syntax;
3534 result->transfer_syntax = ndr_transfer_syntax;
3535 result->dispatch = cli_do_rpc_ndr;
3536 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3537 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3539 result->desthost = talloc_strdup(result, global_myname());
3540 result->srv_name_slash = talloc_asprintf_strupper_m(
3541 result, "\\\\%s", global_myname());
3542 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3543 TALLOC_FREE(result);
3544 return NT_STATUS_NO_MEMORY;
3547 status = rpc_transport_smbd_init(result, conn, syntax,
3548 &result->transport);
3549 if (!NT_STATUS_IS_OK(status)) {
3550 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3551 nt_errstr(status)));
3552 TALLOC_FREE(result);
3553 return status;
3556 status = rpccli_anon_bind_data(result, &auth);
3557 if (!NT_STATUS_IS_OK(status)) {
3558 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3559 nt_errstr(status)));
3560 TALLOC_FREE(result);
3561 return status;
3564 status = rpc_pipe_bind(result, auth);
3565 if (!NT_STATUS_IS_OK(status)) {
3566 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3567 TALLOC_FREE(result);
3568 return status;
3571 *presult = result;
3572 return NT_STATUS_OK;
3575 /****************************************************************************
3576 Open a pipe to a remote server.
3577 ****************************************************************************/
3579 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3580 const struct ndr_syntax_id *interface,
3581 struct rpc_pipe_client **presult)
3583 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3585 * We should have a better way to figure out this drsuapi
3586 * speciality...
3588 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3589 presult);
3592 return rpc_pipe_open_np(cli, interface, presult);
3595 /****************************************************************************
3596 Open a named pipe to an SMB server and bind anonymously.
3597 ****************************************************************************/
3599 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3600 const struct ndr_syntax_id *interface,
3601 struct rpc_pipe_client **presult)
3603 struct rpc_pipe_client *result;
3604 struct cli_pipe_auth_data *auth;
3605 NTSTATUS status;
3607 status = cli_rpc_pipe_open(cli, interface, &result);
3608 if (!NT_STATUS_IS_OK(status)) {
3609 return status;
3612 status = rpccli_anon_bind_data(result, &auth);
3613 if (!NT_STATUS_IS_OK(status)) {
3614 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3615 nt_errstr(status)));
3616 TALLOC_FREE(result);
3617 return status;
3621 * This is a bit of an abstraction violation due to the fact that an
3622 * anonymous bind on an authenticated SMB inherits the user/domain
3623 * from the enclosing SMB creds
3626 TALLOC_FREE(auth->user_name);
3627 TALLOC_FREE(auth->domain);
3629 auth->user_name = talloc_strdup(auth, cli->user_name);
3630 auth->domain = talloc_strdup(auth, cli->domain);
3631 auth->user_session_key = data_blob_talloc(auth,
3632 cli->user_session_key.data,
3633 cli->user_session_key.length);
3635 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3636 TALLOC_FREE(result);
3637 return NT_STATUS_NO_MEMORY;
3640 status = rpc_pipe_bind(result, auth);
3641 if (!NT_STATUS_IS_OK(status)) {
3642 int lvl = 0;
3643 if (ndr_syntax_id_equal(interface,
3644 &ndr_table_dssetup.syntax_id)) {
3645 /* non AD domains just don't have this pipe, avoid
3646 * level 0 statement in that case - gd */
3647 lvl = 3;
3649 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3650 "%s failed with error %s\n",
3651 get_pipe_name_from_iface(interface),
3652 nt_errstr(status) ));
3653 TALLOC_FREE(result);
3654 return status;
3657 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3658 "%s and bound anonymously.\n",
3659 get_pipe_name_from_iface(interface), cli->desthost));
3661 *presult = result;
3662 return NT_STATUS_OK;
3665 /****************************************************************************
3666 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3667 ****************************************************************************/
3669 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3670 const struct ndr_syntax_id *interface,
3671 enum pipe_auth_type auth_type,
3672 enum pipe_auth_level auth_level,
3673 const char *domain,
3674 const char *username,
3675 const char *password,
3676 struct rpc_pipe_client **presult)
3678 struct rpc_pipe_client *result;
3679 struct cli_pipe_auth_data *auth;
3680 NTSTATUS status;
3682 status = cli_rpc_pipe_open(cli, interface, &result);
3683 if (!NT_STATUS_IS_OK(status)) {
3684 return status;
3687 status = rpccli_ntlmssp_bind_data(
3688 result, auth_type, auth_level, domain, username,
3689 password, &auth);
3690 if (!NT_STATUS_IS_OK(status)) {
3691 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3692 nt_errstr(status)));
3693 goto err;
3696 status = rpc_pipe_bind(result, auth);
3697 if (!NT_STATUS_IS_OK(status)) {
3698 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3699 nt_errstr(status) ));
3700 goto err;
3703 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3704 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3705 get_pipe_name_from_iface(interface), cli->desthost, domain,
3706 username ));
3708 *presult = result;
3709 return NT_STATUS_OK;
3711 err:
3713 TALLOC_FREE(result);
3714 return status;
3717 /****************************************************************************
3718 External interface.
3719 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3720 ****************************************************************************/
3722 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3723 const struct ndr_syntax_id *interface,
3724 enum pipe_auth_level auth_level,
3725 const char *domain,
3726 const char *username,
3727 const char *password,
3728 struct rpc_pipe_client **presult)
3730 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3731 interface,
3732 PIPE_AUTH_TYPE_NTLMSSP,
3733 auth_level,
3734 domain,
3735 username,
3736 password,
3737 presult);
3740 /****************************************************************************
3741 External interface.
3742 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3743 ****************************************************************************/
3745 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3746 const struct ndr_syntax_id *interface,
3747 enum pipe_auth_level auth_level,
3748 const char *domain,
3749 const char *username,
3750 const char *password,
3751 struct rpc_pipe_client **presult)
3753 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3754 interface,
3755 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3756 auth_level,
3757 domain,
3758 username,
3759 password,
3760 presult);
3763 /****************************************************************************
3764 Get a the schannel session key out of an already opened netlogon pipe.
3765 ****************************************************************************/
3766 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3767 struct cli_state *cli,
3768 const char *domain,
3769 uint32 *pneg_flags)
3771 uint32 sec_chan_type = 0;
3772 unsigned char machine_pwd[16];
3773 const char *machine_account;
3774 NTSTATUS status;
3776 /* Get the machine account credentials from secrets.tdb. */
3777 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3778 &sec_chan_type))
3780 DEBUG(0, ("get_schannel_session_key: could not fetch "
3781 "trust account password for domain '%s'\n",
3782 domain));
3783 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3786 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3787 cli->desthost, /* server name */
3788 domain, /* domain */
3789 global_myname(), /* client name */
3790 machine_account, /* machine account name */
3791 machine_pwd,
3792 sec_chan_type,
3793 pneg_flags);
3795 if (!NT_STATUS_IS_OK(status)) {
3796 DEBUG(3, ("get_schannel_session_key_common: "
3797 "rpccli_netlogon_setup_creds failed with result %s "
3798 "to server %s, domain %s, machine account %s.\n",
3799 nt_errstr(status), cli->desthost, domain,
3800 machine_account ));
3801 return status;
3804 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3805 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3806 cli->desthost));
3807 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3810 return NT_STATUS_OK;;
3813 /****************************************************************************
3814 Open a netlogon pipe and get the schannel session key.
3815 Now exposed to external callers.
3816 ****************************************************************************/
3819 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3820 const char *domain,
3821 uint32 *pneg_flags,
3822 struct rpc_pipe_client **presult)
3824 struct rpc_pipe_client *netlogon_pipe = NULL;
3825 NTSTATUS status;
3827 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3828 &netlogon_pipe);
3829 if (!NT_STATUS_IS_OK(status)) {
3830 return status;
3833 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3834 pneg_flags);
3835 if (!NT_STATUS_IS_OK(status)) {
3836 TALLOC_FREE(netlogon_pipe);
3837 return status;
3840 *presult = netlogon_pipe;
3841 return NT_STATUS_OK;
3844 /****************************************************************************
3845 External interface.
3846 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3847 using session_key. sign and seal.
3849 The *pdc will be stolen onto this new pipe
3850 ****************************************************************************/
3852 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3853 const struct ndr_syntax_id *interface,
3854 enum pipe_auth_level auth_level,
3855 const char *domain,
3856 struct netlogon_creds_CredentialState **pdc,
3857 struct rpc_pipe_client **presult)
3859 struct rpc_pipe_client *result;
3860 struct cli_pipe_auth_data *auth;
3861 NTSTATUS status;
3863 status = cli_rpc_pipe_open(cli, interface, &result);
3864 if (!NT_STATUS_IS_OK(status)) {
3865 return status;
3868 status = rpccli_schannel_bind_data(result, domain, auth_level,
3869 (*pdc)->session_key, &auth);
3870 if (!NT_STATUS_IS_OK(status)) {
3871 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3872 nt_errstr(status)));
3873 TALLOC_FREE(result);
3874 return status;
3877 status = rpc_pipe_bind(result, auth);
3878 if (!NT_STATUS_IS_OK(status)) {
3879 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3880 "cli_rpc_pipe_bind failed with error %s\n",
3881 nt_errstr(status) ));
3882 TALLOC_FREE(result);
3883 return status;
3887 * The credentials on a new netlogon pipe are the ones we are passed
3888 * in - reference them in
3890 result->dc = talloc_move(result, pdc);
3891 if (result->dc == NULL) {
3892 DEBUG(0, ("talloc reference failed\n"));
3893 TALLOC_FREE(result);
3894 return NT_STATUS_NO_MEMORY;
3897 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3898 "for domain %s and bound using schannel.\n",
3899 get_pipe_name_from_iface(interface),
3900 cli->desthost, domain ));
3902 *presult = result;
3903 return NT_STATUS_OK;
3906 /****************************************************************************
3907 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3908 Fetch the session key ourselves using a temporary netlogon pipe. This
3909 version uses an ntlmssp auth bound netlogon pipe to get the key.
3910 ****************************************************************************/
3912 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3913 const char *domain,
3914 const char *username,
3915 const char *password,
3916 uint32 *pneg_flags,
3917 struct rpc_pipe_client **presult)
3919 struct rpc_pipe_client *netlogon_pipe = NULL;
3920 NTSTATUS status;
3922 status = cli_rpc_pipe_open_spnego_ntlmssp(
3923 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3924 domain, username, password, &netlogon_pipe);
3925 if (!NT_STATUS_IS_OK(status)) {
3926 return status;
3929 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3930 pneg_flags);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 TALLOC_FREE(netlogon_pipe);
3933 return status;
3936 *presult = netlogon_pipe;
3937 return NT_STATUS_OK;
3940 /****************************************************************************
3941 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3942 Fetch the session key ourselves using a temporary netlogon pipe. This version
3943 uses an ntlmssp bind to get the session key.
3944 ****************************************************************************/
3946 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3947 const struct ndr_syntax_id *interface,
3948 enum pipe_auth_level auth_level,
3949 const char *domain,
3950 const char *username,
3951 const char *password,
3952 struct rpc_pipe_client **presult)
3954 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3955 struct rpc_pipe_client *netlogon_pipe = NULL;
3956 struct rpc_pipe_client *result = NULL;
3957 NTSTATUS status;
3959 status = get_schannel_session_key_auth_ntlmssp(
3960 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3963 "key from server %s for domain %s.\n",
3964 cli->desthost, domain ));
3965 return status;
3968 status = cli_rpc_pipe_open_schannel_with_key(
3969 cli, interface, auth_level, domain, &netlogon_pipe->dc,
3970 &result);
3972 /* Now we've bound using the session key we can close the netlog pipe. */
3973 TALLOC_FREE(netlogon_pipe);
3975 if (NT_STATUS_IS_OK(status)) {
3976 *presult = result;
3978 return status;
3981 /****************************************************************************
3982 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3983 Fetch the session key ourselves using a temporary netlogon pipe.
3984 ****************************************************************************/
3986 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3987 const struct ndr_syntax_id *interface,
3988 enum pipe_auth_level auth_level,
3989 const char *domain,
3990 struct rpc_pipe_client **presult)
3992 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3993 struct rpc_pipe_client *netlogon_pipe = NULL;
3994 struct rpc_pipe_client *result = NULL;
3995 NTSTATUS status;
3997 status = get_schannel_session_key(cli, domain, &neg_flags,
3998 &netlogon_pipe);
3999 if (!NT_STATUS_IS_OK(status)) {
4000 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4001 "key from server %s for domain %s.\n",
4002 cli->desthost, domain ));
4003 return status;
4006 status = cli_rpc_pipe_open_schannel_with_key(
4007 cli, interface, auth_level, domain, &netlogon_pipe->dc,
4008 &result);
4010 /* Now we've bound using the session key we can close the netlog pipe. */
4011 TALLOC_FREE(netlogon_pipe);
4013 if (NT_STATUS_IS_OK(status)) {
4014 *presult = result;
4017 return NT_STATUS_OK;
4020 /****************************************************************************
4021 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4022 The idea is this can be called with service_princ, username and password all
4023 NULL so long as the caller has a TGT.
4024 ****************************************************************************/
4026 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4027 const struct ndr_syntax_id *interface,
4028 enum pipe_auth_level auth_level,
4029 const char *service_princ,
4030 const char *username,
4031 const char *password,
4032 struct rpc_pipe_client **presult)
4034 #ifdef HAVE_KRB5
4035 struct rpc_pipe_client *result;
4036 struct cli_pipe_auth_data *auth;
4037 NTSTATUS status;
4039 status = cli_rpc_pipe_open(cli, interface, &result);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 return status;
4044 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4045 username, password, &auth);
4046 if (!NT_STATUS_IS_OK(status)) {
4047 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4048 nt_errstr(status)));
4049 TALLOC_FREE(result);
4050 return status;
4053 status = rpc_pipe_bind(result, auth);
4054 if (!NT_STATUS_IS_OK(status)) {
4055 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4056 "with error %s\n", nt_errstr(status)));
4057 TALLOC_FREE(result);
4058 return status;
4061 *presult = result;
4062 return NT_STATUS_OK;
4063 #else
4064 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4065 return NT_STATUS_NOT_IMPLEMENTED;
4066 #endif
4069 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4070 struct rpc_pipe_client *cli,
4071 DATA_BLOB *session_key)
4073 if (!session_key || !cli) {
4074 return NT_STATUS_INVALID_PARAMETER;
4077 if (!cli->auth) {
4078 return NT_STATUS_INVALID_PARAMETER;
4081 switch (cli->auth->auth_type) {
4082 case PIPE_AUTH_TYPE_SCHANNEL:
4083 *session_key = data_blob_talloc(mem_ctx,
4084 cli->auth->a_u.schannel_auth->sess_key, 16);
4085 break;
4086 case PIPE_AUTH_TYPE_NTLMSSP:
4087 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4088 *session_key = data_blob_talloc(mem_ctx,
4089 cli->auth->a_u.ntlmssp_state->session_key.data,
4090 cli->auth->a_u.ntlmssp_state->session_key.length);
4091 break;
4092 case PIPE_AUTH_TYPE_KRB5:
4093 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4094 *session_key = data_blob_talloc(mem_ctx,
4095 cli->auth->a_u.kerberos_auth->session_key.data,
4096 cli->auth->a_u.kerberos_auth->session_key.length);
4097 break;
4098 case PIPE_AUTH_TYPE_NONE:
4099 *session_key = data_blob_talloc(mem_ctx,
4100 cli->auth->user_session_key.data,
4101 cli->auth->user_session_key.length);
4102 break;
4103 default:
4104 return NT_STATUS_NO_USER_SESSION_KEY;
4107 return NT_STATUS_OK;