Make rpc_read async
[Samba.git] / source3 / rpc_client / cli_pipe.c
blob1f7e33261227b7a9120633e29a8643e914a76fe3
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
59 } pipe_names [] =
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &syntax_spoolss },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
77 { NULL, NULL }
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
85 struct cli_state *cli,
86 const struct ndr_syntax_id *interface)
88 int i;
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
91 interface)) {
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
101 return NULL;
104 /********************************************************************
105 Map internal value to wire value.
106 ********************************************************************/
108 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
110 switch (auth_type) {
112 case PIPE_AUTH_TYPE_NONE:
113 return RPC_ANONYMOUS_AUTH_TYPE;
115 case PIPE_AUTH_TYPE_NTLMSSP:
116 return RPC_NTLMSSP_AUTH_TYPE;
118 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
119 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
120 return RPC_SPNEGO_AUTH_TYPE;
122 case PIPE_AUTH_TYPE_SCHANNEL:
123 return RPC_SCHANNEL_AUTH_TYPE;
125 case PIPE_AUTH_TYPE_KRB5:
126 return RPC_KRB5_AUTH_TYPE;
128 default:
129 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
130 "auth type %u\n",
131 (unsigned int)auth_type ));
132 break;
134 return -1;
137 /********************************************************************
138 Pipe description for a DEBUG
139 ********************************************************************/
140 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
142 char *result;
144 switch (cli->transport_type) {
145 case NCACN_NP:
146 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
147 "fnum 0x%x",
148 cli->desthost,
149 cli->trans.np.pipe_name,
150 (unsigned int)(cli->trans.np.fnum));
151 break;
152 case NCACN_IP_TCP:
153 case NCACN_UNIX_STREAM:
154 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
155 cli->desthost, cli->trans.sock.fd);
156 break;
157 default:
158 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
159 break;
161 SMB_ASSERT(result != NULL);
162 return result;
165 /********************************************************************
166 Rpc pipe call id.
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
172 return ++call_id;
176 * Realloc pdu to have a least "size" bytes
179 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
181 size_t extra_size;
183 if (prs_data_size(pdu) >= size) {
184 return true;
187 extra_size = size - prs_data_size(pdu);
189 if (!prs_force_grow(pdu, extra_size)) {
190 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
191 "%d bytes.\n", (int)extra_size));
192 return false;
195 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
196 (int)extra_size, prs_data_size(pdu)));
197 return true;
201 /*******************************************************************
202 Use SMBreadX to get rest of one fragment's worth of rpc data.
203 Reads the whole size or give an error message
204 ********************************************************************/
206 struct rpc_read_state {
207 struct event_context *ev;
208 struct rpc_pipe_client *cli;
209 char *data;
210 size_t size;
211 size_t num_read;
214 static void rpc_read_np_done(struct async_req *subreq);
215 static void rpc_read_sock_done(struct async_req *subreq);
217 static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx,
218 struct event_context *ev,
219 struct rpc_pipe_client *cli,
220 char *data, size_t size)
222 struct async_req *result, *subreq;
223 struct rpc_read_state *state;
225 result = async_req_new(mem_ctx);
226 if (result == NULL) {
227 return NULL;
229 state = talloc(result, struct rpc_read_state);
230 if (state == NULL) {
231 goto fail;
233 result->private_data = state;
235 state->ev = ev;
236 state->cli = cli;
237 state->data = data;
238 state->size = size;
239 state->num_read = 0;
241 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
243 if (cli->transport_type == NCACN_NP) {
244 subreq = cli_read_andx_send(
245 state, ev, cli->trans.np.cli,
246 cli->trans.np.fnum, 0, size);
247 if (subreq == NULL) {
248 DEBUG(10, ("cli_read_andx_send failed\n"));
249 goto fail;
251 subreq->async.fn = rpc_read_np_done;
252 subreq->async.priv = result;
253 return result;
256 if ((cli->transport_type == NCACN_IP_TCP)
257 || (cli->transport_type == NCACN_UNIX_STREAM)) {
258 subreq = recvall_send(state, ev, cli->trans.sock.fd,
259 data, size, 0);
260 if (subreq == NULL) {
261 DEBUG(10, ("recvall_send failed\n"));
262 goto fail;
264 subreq->async.fn = rpc_read_sock_done;
265 subreq->async.priv = result;
266 return result;
269 if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) {
270 return result;
272 fail:
273 TALLOC_FREE(result);
274 return NULL;
277 static void rpc_read_np_done(struct async_req *subreq)
279 struct async_req *req = talloc_get_type_abort(
280 subreq->async.priv, struct async_req);
281 struct rpc_read_state *state = talloc_get_type_abort(
282 req->private_data, struct rpc_read_state);
283 NTSTATUS status;
284 ssize_t received;
285 uint8_t *rcvbuf;
287 status = cli_read_andx_recv(subreq, &received, &rcvbuf);
289 * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
290 * child of that.
292 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
293 status = NT_STATUS_OK;
295 if (!NT_STATUS_IS_OK(status)) {
296 TALLOC_FREE(subreq);
297 async_req_error(req, status);
298 return;
301 memcpy(state->data + state->num_read, rcvbuf, received);
302 TALLOC_FREE(subreq);
304 state->num_read += received;
306 if (state->num_read == state->size) {
307 async_req_done(req);
308 return;
311 subreq = cli_read_andx_send(
312 state, state->ev, state->cli->trans.np.cli,
313 state->cli->trans.np.fnum, 0,
314 state->size - state->num_read);
316 if (async_req_nomem(subreq, req)) {
317 return;
320 subreq->async.fn = rpc_read_np_done;
321 subreq->async.priv = req;
324 static void rpc_read_sock_done(struct async_req *subreq)
326 struct async_req *req = talloc_get_type_abort(
327 subreq->async.priv, struct async_req);
328 NTSTATUS status;
330 status = recvall_recv(subreq);
331 TALLOC_FREE(subreq);
332 if (!NT_STATUS_IS_OK(status)) {
333 async_req_error(req, status);
334 return;
337 async_req_done(req);
340 static NTSTATUS rpc_read_recv(struct async_req *req)
342 return async_req_simple_recv(req);
345 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
346 char *pdata, size_t size)
348 TALLOC_CTX *frame = talloc_stackframe();
349 struct event_context *ev;
350 struct async_req *req;
351 NTSTATUS status = NT_STATUS_NO_MEMORY;
353 ev = event_context_init(frame);
354 if (ev == NULL) {
355 goto fail;
358 req = rpc_read_send(frame, ev, cli, pdata, size);
359 if (req == NULL) {
360 goto fail;
363 while (req->state < ASYNC_REQ_DONE) {
364 event_loop_once(ev);
367 status = rpc_read_recv(req);
368 fail:
369 TALLOC_FREE(frame);
370 return status;
373 /****************************************************************************
374 Try and get a PDU's worth of data from current_pdu. If not, then read more
375 from the wire.
376 ****************************************************************************/
378 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
380 NTSTATUS ret = NT_STATUS_OK;
381 uint32 current_pdu_len = prs_data_size(current_pdu);
383 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
384 if (current_pdu_len < RPC_HEADER_LEN) {
385 if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) {
386 return NT_STATUS_NO_MEMORY;
388 ret = rpc_read(cli,
389 prs_data_p(current_pdu) + current_pdu_len,
390 RPC_HEADER_LEN - current_pdu_len);
391 if (!NT_STATUS_IS_OK(ret)) {
392 return ret;
394 current_pdu_len = RPC_HEADER_LEN;
397 /* This next call sets the endian bit correctly in current_pdu. */
398 /* We will propagate this to rbuf later. */
399 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
400 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
401 return NT_STATUS_BUFFER_TOO_SMALL;
404 if (prhdr->frag_len > cli->max_recv_frag) {
405 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
406 " we only allow %d\n", (int)prhdr->frag_len,
407 (int)cli->max_recv_frag));
408 return NT_STATUS_BUFFER_TOO_SMALL;
411 /* Ensure we have frag_len bytes of data. */
412 if (current_pdu_len < prhdr->frag_len) {
413 if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) {
414 return NT_STATUS_NO_MEMORY;
416 ret = rpc_read(cli,
417 prs_data_p(current_pdu) + current_pdu_len,
418 prhdr->frag_len - current_pdu_len);
419 if (!NT_STATUS_IS_OK(ret)) {
420 return ret;
424 return NT_STATUS_OK;
427 /****************************************************************************
428 NTLMSSP specific sign/seal.
429 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
430 In fact I should probably abstract these into identical pieces of code... JRA.
431 ****************************************************************************/
433 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
434 prs_struct *current_pdu,
435 uint8 *p_ss_padding_len)
437 RPC_HDR_AUTH auth_info;
438 uint32 save_offset = prs_offset(current_pdu);
439 uint32 auth_len = prhdr->auth_len;
440 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
441 unsigned char *data = NULL;
442 size_t data_len;
443 unsigned char *full_packet_data = NULL;
444 size_t full_packet_data_len;
445 DATA_BLOB auth_blob;
446 NTSTATUS status;
448 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
449 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
450 return NT_STATUS_OK;
453 if (!ntlmssp_state) {
454 return NT_STATUS_INVALID_PARAMETER;
457 /* Ensure there's enough data for an authenticated response. */
458 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
459 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
460 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
461 (unsigned int)auth_len ));
462 return NT_STATUS_BUFFER_TOO_SMALL;
466 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
467 * after the RPC header.
468 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
469 * functions as NTLMv2 checks the rpc headers also.
472 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
473 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
475 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
476 full_packet_data_len = prhdr->frag_len - auth_len;
478 /* Pull the auth header and the following data into a blob. */
479 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
480 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
481 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
482 return NT_STATUS_BUFFER_TOO_SMALL;
485 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
486 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
487 return NT_STATUS_BUFFER_TOO_SMALL;
490 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
491 auth_blob.length = auth_len;
493 switch (cli->auth->auth_level) {
494 case PIPE_AUTH_LEVEL_PRIVACY:
495 /* Data is encrypted. */
496 status = ntlmssp_unseal_packet(ntlmssp_state,
497 data, data_len,
498 full_packet_data,
499 full_packet_data_len,
500 &auth_blob);
501 if (!NT_STATUS_IS_OK(status)) {
502 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
503 "packet from %s. Error was %s.\n",
504 rpccli_pipe_txt(debug_ctx(), cli),
505 nt_errstr(status) ));
506 return status;
508 break;
509 case PIPE_AUTH_LEVEL_INTEGRITY:
510 /* Data is signed. */
511 status = ntlmssp_check_packet(ntlmssp_state,
512 data, data_len,
513 full_packet_data,
514 full_packet_data_len,
515 &auth_blob);
516 if (!NT_STATUS_IS_OK(status)) {
517 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
518 "packet from %s. Error was %s.\n",
519 rpccli_pipe_txt(debug_ctx(), cli),
520 nt_errstr(status) ));
521 return status;
523 break;
524 default:
525 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
526 "auth level %d\n", cli->auth->auth_level));
527 return NT_STATUS_INVALID_INFO_CLASS;
531 * Return the current pointer to the data offset.
534 if(!prs_set_offset(current_pdu, save_offset)) {
535 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
536 (unsigned int)save_offset ));
537 return NT_STATUS_BUFFER_TOO_SMALL;
541 * Remember the padding length. We must remove it from the real data
542 * stream once the sign/seal is done.
545 *p_ss_padding_len = auth_info.auth_pad_len;
547 return NT_STATUS_OK;
550 /****************************************************************************
551 schannel specific sign/seal.
552 ****************************************************************************/
554 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
555 prs_struct *current_pdu,
556 uint8 *p_ss_padding_len)
558 RPC_HDR_AUTH auth_info;
559 RPC_AUTH_SCHANNEL_CHK schannel_chk;
560 uint32 auth_len = prhdr->auth_len;
561 uint32 save_offset = prs_offset(current_pdu);
562 struct schannel_auth_struct *schannel_auth =
563 cli->auth->a_u.schannel_auth;
564 uint32 data_len;
566 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
567 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
568 return NT_STATUS_OK;
571 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
572 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
573 return NT_STATUS_INVALID_PARAMETER;
576 if (!schannel_auth) {
577 return NT_STATUS_INVALID_PARAMETER;
580 /* Ensure there's enough data for an authenticated response. */
581 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
582 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
583 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
584 (unsigned int)auth_len ));
585 return NT_STATUS_INVALID_PARAMETER;
588 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
590 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
591 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
592 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
593 return NT_STATUS_BUFFER_TOO_SMALL;
596 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
597 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
598 return NT_STATUS_BUFFER_TOO_SMALL;
601 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
602 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
603 auth_info.auth_type));
604 return NT_STATUS_BUFFER_TOO_SMALL;
607 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
608 &schannel_chk, current_pdu, 0)) {
609 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
610 return NT_STATUS_BUFFER_TOO_SMALL;
613 if (!schannel_decode(schannel_auth,
614 cli->auth->auth_level,
615 SENDER_IS_ACCEPTOR,
616 &schannel_chk,
617 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
618 data_len)) {
619 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
620 "Connection to %s.\n",
621 rpccli_pipe_txt(debug_ctx(), cli)));
622 return NT_STATUS_INVALID_PARAMETER;
625 /* The sequence number gets incremented on both send and receive. */
626 schannel_auth->seq_num++;
629 * Return the current pointer to the data offset.
632 if(!prs_set_offset(current_pdu, save_offset)) {
633 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
634 (unsigned int)save_offset ));
635 return NT_STATUS_BUFFER_TOO_SMALL;
639 * Remember the padding length. We must remove it from the real data
640 * stream once the sign/seal is done.
643 *p_ss_padding_len = auth_info.auth_pad_len;
645 return NT_STATUS_OK;
648 /****************************************************************************
649 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
650 ****************************************************************************/
652 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
653 prs_struct *current_pdu,
654 uint8 *p_ss_padding_len)
656 NTSTATUS ret = NT_STATUS_OK;
658 /* Paranioa checks for auth_len. */
659 if (prhdr->auth_len) {
660 if (prhdr->auth_len > prhdr->frag_len) {
661 return NT_STATUS_INVALID_PARAMETER;
664 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
665 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
666 /* Integer wrap attempt. */
667 return NT_STATUS_INVALID_PARAMETER;
672 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
675 switch(cli->auth->auth_type) {
676 case PIPE_AUTH_TYPE_NONE:
677 if (prhdr->auth_len) {
678 DEBUG(3, ("cli_pipe_validate_rpc_response: "
679 "Connection to %s - got non-zero "
680 "auth len %u.\n",
681 rpccli_pipe_txt(debug_ctx(), cli),
682 (unsigned int)prhdr->auth_len ));
683 return NT_STATUS_INVALID_PARAMETER;
685 break;
687 case PIPE_AUTH_TYPE_NTLMSSP:
688 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
689 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
690 if (!NT_STATUS_IS_OK(ret)) {
691 return ret;
693 break;
695 case PIPE_AUTH_TYPE_SCHANNEL:
696 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
697 if (!NT_STATUS_IS_OK(ret)) {
698 return ret;
700 break;
702 case PIPE_AUTH_TYPE_KRB5:
703 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
704 default:
705 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
706 "to %s - unknown internal auth type %u.\n",
707 rpccli_pipe_txt(debug_ctx(), cli),
708 cli->auth->auth_type ));
709 return NT_STATUS_INVALID_INFO_CLASS;
712 return NT_STATUS_OK;
715 /****************************************************************************
716 Do basic authentication checks on an incoming pdu.
717 ****************************************************************************/
719 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
720 prs_struct *current_pdu,
721 uint8 expected_pkt_type,
722 char **ppdata,
723 uint32 *pdata_len,
724 prs_struct *return_data)
727 NTSTATUS ret = NT_STATUS_OK;
728 uint32 current_pdu_len = prs_data_size(current_pdu);
730 if (current_pdu_len != prhdr->frag_len) {
731 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
732 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
733 return NT_STATUS_INVALID_PARAMETER;
737 * Point the return values at the real data including the RPC
738 * header. Just in case the caller wants it.
740 *ppdata = prs_data_p(current_pdu);
741 *pdata_len = current_pdu_len;
743 /* Ensure we have the correct type. */
744 switch (prhdr->pkt_type) {
745 case RPC_ALTCONTRESP:
746 case RPC_BINDACK:
748 /* Alter context and bind ack share the same packet definitions. */
749 break;
752 case RPC_RESPONSE:
754 RPC_HDR_RESP rhdr_resp;
755 uint8 ss_padding_len = 0;
757 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
758 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
759 return NT_STATUS_BUFFER_TOO_SMALL;
762 /* Here's where we deal with incoming sign/seal. */
763 ret = cli_pipe_validate_rpc_response(cli, prhdr,
764 current_pdu, &ss_padding_len);
765 if (!NT_STATUS_IS_OK(ret)) {
766 return ret;
769 /* Point the return values at the NDR data. Remember to remove any ss padding. */
770 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
772 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
773 return NT_STATUS_BUFFER_TOO_SMALL;
776 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
778 /* Remember to remove the auth footer. */
779 if (prhdr->auth_len) {
780 /* We've already done integer wrap tests on auth_len in
781 cli_pipe_validate_rpc_response(). */
782 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
783 return NT_STATUS_BUFFER_TOO_SMALL;
785 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
788 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
789 current_pdu_len, *pdata_len, ss_padding_len ));
792 * If this is the first reply, and the allocation hint is reasonably, try and
793 * set up the return_data parse_struct to the correct size.
796 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
797 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
798 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
799 "too large to allocate\n",
800 (unsigned int)rhdr_resp.alloc_hint ));
801 return NT_STATUS_NO_MEMORY;
805 break;
808 case RPC_BINDNACK:
809 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
810 "received from %s!\n",
811 rpccli_pipe_txt(debug_ctx(), cli)));
812 /* Use this for now... */
813 return NT_STATUS_NETWORK_ACCESS_DENIED;
815 case RPC_FAULT:
817 RPC_HDR_RESP rhdr_resp;
818 RPC_HDR_FAULT fault_resp;
820 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
821 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
822 return NT_STATUS_BUFFER_TOO_SMALL;
825 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
826 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
827 return NT_STATUS_BUFFER_TOO_SMALL;
830 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
831 "code %s received from %s!\n",
832 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
833 rpccli_pipe_txt(debug_ctx(), cli)));
834 if (NT_STATUS_IS_OK(fault_resp.status)) {
835 return NT_STATUS_UNSUCCESSFUL;
836 } else {
837 return fault_resp.status;
841 default:
842 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
843 "from %s!\n",
844 (unsigned int)prhdr->pkt_type,
845 rpccli_pipe_txt(debug_ctx(), cli)));
846 return NT_STATUS_INVALID_INFO_CLASS;
849 if (prhdr->pkt_type != expected_pkt_type) {
850 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
851 "got an unexpected RPC packet type - %u, not %u\n",
852 rpccli_pipe_txt(debug_ctx(), cli),
853 prhdr->pkt_type,
854 expected_pkt_type));
855 return NT_STATUS_INVALID_INFO_CLASS;
858 /* Do this just before return - we don't want to modify any rpc header
859 data before now as we may have needed to do cryptographic actions on
860 it before. */
862 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
863 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
864 "setting fragment first/last ON.\n"));
865 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
868 return NT_STATUS_OK;
871 /****************************************************************************
872 Ensure we eat the just processed pdu from the current_pdu prs_struct.
873 Normally the frag_len and buffer size will match, but on the first trans
874 reply there is a theoretical chance that buffer size > frag_len, so we must
875 deal with that.
876 ****************************************************************************/
878 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
880 uint32 current_pdu_len = prs_data_size(current_pdu);
882 if (current_pdu_len < prhdr->frag_len) {
883 return NT_STATUS_BUFFER_TOO_SMALL;
886 /* Common case. */
887 if (current_pdu_len == (uint32)prhdr->frag_len) {
888 prs_mem_free(current_pdu);
889 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
890 /* Make current_pdu dynamic with no memory. */
891 prs_give_memory(current_pdu, 0, 0, True);
892 return NT_STATUS_OK;
896 * Oh no ! More data in buffer than we processed in current pdu.
897 * Cheat. Move the data down and shrink the buffer.
900 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
901 current_pdu_len - prhdr->frag_len);
903 /* Remember to set the read offset back to zero. */
904 prs_set_offset(current_pdu, 0);
906 /* Shrink the buffer. */
907 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
908 return NT_STATUS_BUFFER_TOO_SMALL;
911 return NT_STATUS_OK;
914 /****************************************************************************
915 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
916 ****************************************************************************/
918 static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
919 uint16 *setup, uint32 setup_count,
920 uint32 max_setup_count,
921 char *params, uint32 param_count,
922 uint32 max_param_count,
923 char *data, uint32 data_count,
924 uint32 max_data_count,
925 char **rparam, uint32 *rparam_count,
926 char **rdata, uint32 *rdata_count)
928 cli_send_trans(cli, SMBtrans,
929 pipe_name,
930 0,0, /* fid, flags */
931 setup, setup_count, max_setup_count,
932 params, param_count, max_param_count,
933 data, data_count, max_data_count);
935 return (cli_receive_trans(cli, SMBtrans,
936 rparam, (unsigned int *)rparam_count,
937 rdata, (unsigned int *)rdata_count));
940 /****************************************************************************
941 Send data on an rpc pipe via trans. The prs_struct data must be the last
942 pdu fragment of an NDR data stream.
944 Receive response data from an rpc pipe, which may be large...
946 Read the first fragment: unfortunately have to use SMBtrans for the first
947 bit, then SMBreadX for subsequent bits.
949 If first fragment received also wasn't the last fragment, continue
950 getting fragments until we _do_ receive the last fragment.
952 Request/Response PDU's look like the following...
954 |<------------------PDU len----------------------------------------------->|
955 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
957 +------------+-----------------+-------------+---------------+-------------+
958 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
959 +------------+-----------------+-------------+---------------+-------------+
961 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
962 signing & sealing being negotiated.
964 ****************************************************************************/
966 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
967 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
968 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
969 uint8 expected_pkt_type)
971 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
972 char *rparam = NULL;
973 uint32 rparam_len = 0;
974 char *pdata = prs_data_p(data);
975 uint32 data_len = prs_offset(data);
976 char *prdata = NULL;
977 uint32 rdata_len = 0;
978 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
979 uint32 current_rbuf_offset = 0;
980 prs_struct current_pdu;
982 #ifdef DEVELOPER
983 /* Ensure we're not sending too much. */
984 SMB_ASSERT(data_len <= max_data);
985 #endif
987 /* Set up the current pdu parse struct. */
988 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
990 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
992 switch (cli->transport_type) {
993 case NCACN_NP: {
994 uint16 setup[2];
995 /* Create setup parameters - must be in native byte order. */
996 setup[0] = TRANSACT_DCERPCCMD;
997 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
1000 * Send the last (or only) fragment of an RPC request. For
1001 * small amounts of data (about 1024 bytes or so) the RPC
1002 * request and response appears in a SMBtrans request and
1003 * response.
1006 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
1007 setup, 2, 0, /* Setup, length, max */
1008 NULL, 0, 0, /* Params, length, max */
1009 pdata, data_len, max_data, /* data, length,
1010 * max */
1011 &rparam, &rparam_len, /* return params,
1012 * len */
1013 &prdata, &rdata_len)) /* return data, len */
1015 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
1016 "Error was %s\n",
1017 rpccli_pipe_txt(debug_ctx(), cli),
1018 cli_errstr(cli->trans.np.cli)));
1019 ret = cli_get_nt_error(cli->trans.np.cli);
1020 SAFE_FREE(rparam);
1021 SAFE_FREE(prdata);
1022 goto err;
1024 break;
1026 case NCACN_IP_TCP:
1027 case NCACN_UNIX_STREAM:
1029 ssize_t nwritten, nread;
1030 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
1031 if (nwritten == -1) {
1032 ret = map_nt_error_from_unix(errno);
1033 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
1034 strerror(errno)));
1035 goto err;
1037 rparam = NULL;
1038 prdata = SMB_MALLOC_ARRAY(char, 1);
1039 if (prdata == NULL) {
1040 return NT_STATUS_NO_MEMORY;
1042 nread = sys_read(cli->trans.sock.fd, prdata, 1);
1043 if (nread == 0) {
1044 SAFE_FREE(prdata);
1046 if (nread == -1) {
1047 ret = NT_STATUS_END_OF_FILE;
1048 goto err;
1050 rdata_len = nread;
1051 break;
1053 default:
1054 DEBUG(0, ("unknown transport type %d\n",
1055 cli->transport_type));
1056 return NT_STATUS_INTERNAL_ERROR;
1059 /* Throw away returned params - we know we won't use them. */
1061 SAFE_FREE(rparam);
1063 if (prdata == NULL) {
1064 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1065 rpccli_pipe_txt(debug_ctx(), cli)));
1066 /* Yes - some calls can truely return no data... */
1067 prs_mem_free(&current_pdu);
1068 return NT_STATUS_OK;
1072 * Give this memory as dynamic to the current pdu.
1075 prs_give_memory(&current_pdu, prdata, rdata_len, True);
1077 /* Ensure we can mess with the return prs_struct. */
1078 SMB_ASSERT(UNMARSHALLING(rbuf));
1079 SMB_ASSERT(prs_data_size(rbuf) == 0);
1081 /* Make rbuf dynamic with no memory. */
1082 prs_give_memory(rbuf, 0, 0, True);
1084 while(1) {
1085 RPC_HDR rhdr;
1086 char *ret_data = NULL;
1087 uint32 ret_data_len = 0;
1089 /* Ensure we have enough data for a pdu. */
1090 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
1091 if (!NT_STATUS_IS_OK(ret)) {
1092 goto err;
1095 /* We pass in rbuf here so if the alloc hint is set correctly
1096 we can set the output size and avoid reallocs. */
1098 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
1099 &ret_data, &ret_data_len, rbuf);
1101 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1102 prs_data_size(&current_pdu), current_rbuf_offset ));
1104 if (!NT_STATUS_IS_OK(ret)) {
1105 goto err;
1108 if ((rhdr.flags & RPC_FLG_FIRST)) {
1109 if (rhdr.pack_type[0] == 0) {
1110 /* Set the data type correctly for big-endian data on the first packet. */
1111 DEBUG(10,("rpc_api_pipe: On %s "
1112 "PDU data format is big-endian.\n",
1113 rpccli_pipe_txt(debug_ctx(), cli)));
1115 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1116 } else {
1117 /* Check endianness on subsequent packets. */
1118 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1119 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1120 rbuf->bigendian_data ? "big" : "little",
1121 current_pdu.bigendian_data ? "big" : "little" ));
1122 ret = NT_STATUS_INVALID_PARAMETER;
1123 goto err;
1128 /* Now copy the data portion out of the pdu into rbuf. */
1129 if (!prs_force_grow(rbuf, ret_data_len)) {
1130 ret = NT_STATUS_NO_MEMORY;
1131 goto err;
1133 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1134 current_rbuf_offset += ret_data_len;
1136 /* See if we've finished with all the data in current_pdu yet ? */
1137 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
1138 if (!NT_STATUS_IS_OK(ret)) {
1139 goto err;
1142 if (rhdr.flags & RPC_FLG_LAST) {
1143 break; /* We're done. */
1147 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1148 rpccli_pipe_txt(debug_ctx(), cli),
1149 (unsigned int)prs_data_size(rbuf) ));
1151 prs_mem_free(&current_pdu);
1152 return NT_STATUS_OK;
1154 err:
1156 prs_mem_free(&current_pdu);
1157 prs_mem_free(rbuf);
1158 return ret;
1161 /*******************************************************************
1162 Creates krb5 auth bind.
1163 ********************************************************************/
1165 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1166 enum pipe_auth_level auth_level,
1167 RPC_HDR_AUTH *pauth_out,
1168 prs_struct *auth_data)
1170 #ifdef HAVE_KRB5
1171 int ret;
1172 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1173 DATA_BLOB tkt = data_blob_null;
1174 DATA_BLOB tkt_wrapped = data_blob_null;
1176 /* We may change the pad length before marshalling. */
1177 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1179 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1180 a->service_principal ));
1182 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1184 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1185 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1187 if (ret) {
1188 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1189 "failed with %s\n",
1190 a->service_principal,
1191 error_message(ret) ));
1193 data_blob_free(&tkt);
1194 prs_mem_free(auth_data);
1195 return NT_STATUS_INVALID_PARAMETER;
1198 /* wrap that up in a nice GSS-API wrapping */
1199 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1201 data_blob_free(&tkt);
1203 /* Auth len in the rpc header doesn't include auth_header. */
1204 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1205 data_blob_free(&tkt_wrapped);
1206 prs_mem_free(auth_data);
1207 return NT_STATUS_NO_MEMORY;
1210 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1211 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1213 data_blob_free(&tkt_wrapped);
1214 return NT_STATUS_OK;
1215 #else
1216 return NT_STATUS_INVALID_PARAMETER;
1217 #endif
1220 /*******************************************************************
1221 Creates SPNEGO NTLMSSP auth bind.
1222 ********************************************************************/
1224 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1225 enum pipe_auth_level auth_level,
1226 RPC_HDR_AUTH *pauth_out,
1227 prs_struct *auth_data)
1229 NTSTATUS nt_status;
1230 DATA_BLOB null_blob = data_blob_null;
1231 DATA_BLOB request = data_blob_null;
1232 DATA_BLOB spnego_msg = data_blob_null;
1234 /* We may change the pad length before marshalling. */
1235 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1237 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1238 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1239 null_blob,
1240 &request);
1242 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1243 data_blob_free(&request);
1244 prs_mem_free(auth_data);
1245 return nt_status;
1248 /* Wrap this in SPNEGO. */
1249 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1251 data_blob_free(&request);
1253 /* Auth len in the rpc header doesn't include auth_header. */
1254 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1255 data_blob_free(&spnego_msg);
1256 prs_mem_free(auth_data);
1257 return NT_STATUS_NO_MEMORY;
1260 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1261 dump_data(5, spnego_msg.data, spnego_msg.length);
1263 data_blob_free(&spnego_msg);
1264 return NT_STATUS_OK;
1267 /*******************************************************************
1268 Creates NTLMSSP auth bind.
1269 ********************************************************************/
1271 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1272 enum pipe_auth_level auth_level,
1273 RPC_HDR_AUTH *pauth_out,
1274 prs_struct *auth_data)
1276 NTSTATUS nt_status;
1277 DATA_BLOB null_blob = data_blob_null;
1278 DATA_BLOB request = data_blob_null;
1280 /* We may change the pad length before marshalling. */
1281 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1283 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1284 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1285 null_blob,
1286 &request);
1288 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1289 data_blob_free(&request);
1290 prs_mem_free(auth_data);
1291 return nt_status;
1294 /* Auth len in the rpc header doesn't include auth_header. */
1295 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1296 data_blob_free(&request);
1297 prs_mem_free(auth_data);
1298 return NT_STATUS_NO_MEMORY;
1301 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1302 dump_data(5, request.data, request.length);
1304 data_blob_free(&request);
1305 return NT_STATUS_OK;
1308 /*******************************************************************
1309 Creates schannel auth bind.
1310 ********************************************************************/
1312 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1313 enum pipe_auth_level auth_level,
1314 RPC_HDR_AUTH *pauth_out,
1315 prs_struct *auth_data)
1317 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1319 /* We may change the pad length before marshalling. */
1320 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1322 /* Use lp_workgroup() if domain not specified */
1324 if (!cli->auth->domain || !cli->auth->domain[0]) {
1325 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1326 if (cli->auth->domain == NULL) {
1327 return NT_STATUS_NO_MEMORY;
1331 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1332 global_myname());
1335 * Now marshall the data into the auth parse_struct.
1338 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1339 &schannel_neg, auth_data, 0)) {
1340 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1341 prs_mem_free(auth_data);
1342 return NT_STATUS_NO_MEMORY;
1345 return NT_STATUS_OK;
1348 /*******************************************************************
1349 Creates the internals of a DCE/RPC bind request or alter context PDU.
1350 ********************************************************************/
1352 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1353 prs_struct *rpc_out,
1354 uint32 rpc_call_id,
1355 const RPC_IFACE *abstract,
1356 const RPC_IFACE *transfer,
1357 RPC_HDR_AUTH *phdr_auth,
1358 prs_struct *pauth_info)
1360 RPC_HDR hdr;
1361 RPC_HDR_RB hdr_rb;
1362 RPC_CONTEXT rpc_ctx;
1363 uint16 auth_len = prs_offset(pauth_info);
1364 uint8 ss_padding_len = 0;
1365 uint16 frag_len = 0;
1367 /* create the RPC context. */
1368 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1370 /* create the bind request RPC_HDR_RB */
1371 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1373 /* Start building the frag length. */
1374 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1376 /* Do we need to pad ? */
1377 if (auth_len) {
1378 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1379 if (data_len % 8) {
1380 ss_padding_len = 8 - (data_len % 8);
1381 phdr_auth->auth_pad_len = ss_padding_len;
1383 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1386 /* Create the request RPC_HDR */
1387 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1389 /* Marshall the RPC header */
1390 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1391 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1392 return NT_STATUS_NO_MEMORY;
1395 /* Marshall the bind request data */
1396 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1397 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1398 return NT_STATUS_NO_MEMORY;
1402 * Grow the outgoing buffer to store any auth info.
1405 if(auth_len != 0) {
1406 if (ss_padding_len) {
1407 char pad[8];
1408 memset(pad, '\0', 8);
1409 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1410 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1411 return NT_STATUS_NO_MEMORY;
1415 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1416 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1417 return NT_STATUS_NO_MEMORY;
1421 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1422 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1423 return NT_STATUS_NO_MEMORY;
1427 return NT_STATUS_OK;
1430 /*******************************************************************
1431 Creates a DCE/RPC bind request.
1432 ********************************************************************/
1434 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1435 prs_struct *rpc_out,
1436 uint32 rpc_call_id,
1437 const RPC_IFACE *abstract,
1438 const RPC_IFACE *transfer,
1439 enum pipe_auth_type auth_type,
1440 enum pipe_auth_level auth_level)
1442 RPC_HDR_AUTH hdr_auth;
1443 prs_struct auth_info;
1444 NTSTATUS ret = NT_STATUS_OK;
1446 ZERO_STRUCT(hdr_auth);
1447 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1448 return NT_STATUS_NO_MEMORY;
1450 switch (auth_type) {
1451 case PIPE_AUTH_TYPE_SCHANNEL:
1452 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1453 if (!NT_STATUS_IS_OK(ret)) {
1454 prs_mem_free(&auth_info);
1455 return ret;
1457 break;
1459 case PIPE_AUTH_TYPE_NTLMSSP:
1460 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1461 if (!NT_STATUS_IS_OK(ret)) {
1462 prs_mem_free(&auth_info);
1463 return ret;
1465 break;
1467 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1468 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1469 if (!NT_STATUS_IS_OK(ret)) {
1470 prs_mem_free(&auth_info);
1471 return ret;
1473 break;
1475 case PIPE_AUTH_TYPE_KRB5:
1476 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1477 if (!NT_STATUS_IS_OK(ret)) {
1478 prs_mem_free(&auth_info);
1479 return ret;
1481 break;
1483 case PIPE_AUTH_TYPE_NONE:
1484 break;
1486 default:
1487 /* "Can't" happen. */
1488 return NT_STATUS_INVALID_INFO_CLASS;
1491 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1492 rpc_out,
1493 rpc_call_id,
1494 abstract,
1495 transfer,
1496 &hdr_auth,
1497 &auth_info);
1499 prs_mem_free(&auth_info);
1500 return ret;
1503 /*******************************************************************
1504 Create and add the NTLMSSP sign/seal auth header and data.
1505 ********************************************************************/
1507 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1508 RPC_HDR *phdr,
1509 uint32 ss_padding_len,
1510 prs_struct *outgoing_pdu)
1512 RPC_HDR_AUTH auth_info;
1513 NTSTATUS status;
1514 DATA_BLOB auth_blob = data_blob_null;
1515 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1517 if (!cli->auth->a_u.ntlmssp_state) {
1518 return NT_STATUS_INVALID_PARAMETER;
1521 /* Init and marshall the auth header. */
1522 init_rpc_hdr_auth(&auth_info,
1523 map_pipe_auth_type_to_rpc_auth_type(
1524 cli->auth->auth_type),
1525 cli->auth->auth_level,
1526 ss_padding_len,
1527 1 /* context id. */);
1529 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1530 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1531 data_blob_free(&auth_blob);
1532 return NT_STATUS_NO_MEMORY;
1535 switch (cli->auth->auth_level) {
1536 case PIPE_AUTH_LEVEL_PRIVACY:
1537 /* Data portion is encrypted. */
1538 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1539 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1540 data_and_pad_len,
1541 (unsigned char *)prs_data_p(outgoing_pdu),
1542 (size_t)prs_offset(outgoing_pdu),
1543 &auth_blob);
1544 if (!NT_STATUS_IS_OK(status)) {
1545 data_blob_free(&auth_blob);
1546 return status;
1548 break;
1550 case PIPE_AUTH_LEVEL_INTEGRITY:
1551 /* Data is signed. */
1552 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1553 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1554 data_and_pad_len,
1555 (unsigned char *)prs_data_p(outgoing_pdu),
1556 (size_t)prs_offset(outgoing_pdu),
1557 &auth_blob);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 data_blob_free(&auth_blob);
1560 return status;
1562 break;
1564 default:
1565 /* Can't happen. */
1566 smb_panic("bad auth level");
1567 /* Notreached. */
1568 return NT_STATUS_INVALID_PARAMETER;
1571 /* Finally marshall the blob. */
1573 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1574 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1575 (unsigned int)NTLMSSP_SIG_SIZE));
1576 data_blob_free(&auth_blob);
1577 return NT_STATUS_NO_MEMORY;
1580 data_blob_free(&auth_blob);
1581 return NT_STATUS_OK;
1584 /*******************************************************************
1585 Create and add the schannel sign/seal auth header and data.
1586 ********************************************************************/
1588 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1589 RPC_HDR *phdr,
1590 uint32 ss_padding_len,
1591 prs_struct *outgoing_pdu)
1593 RPC_HDR_AUTH auth_info;
1594 RPC_AUTH_SCHANNEL_CHK verf;
1595 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1596 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1597 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1599 if (!sas) {
1600 return NT_STATUS_INVALID_PARAMETER;
1603 /* Init and marshall the auth header. */
1604 init_rpc_hdr_auth(&auth_info,
1605 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1606 cli->auth->auth_level,
1607 ss_padding_len,
1608 1 /* context id. */);
1610 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1611 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1612 return NT_STATUS_NO_MEMORY;
1615 switch (cli->auth->auth_level) {
1616 case PIPE_AUTH_LEVEL_PRIVACY:
1617 case PIPE_AUTH_LEVEL_INTEGRITY:
1618 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1619 sas->seq_num));
1621 schannel_encode(sas,
1622 cli->auth->auth_level,
1623 SENDER_IS_INITIATOR,
1624 &verf,
1625 data_p,
1626 data_and_pad_len);
1628 sas->seq_num++;
1629 break;
1631 default:
1632 /* Can't happen. */
1633 smb_panic("bad auth level");
1634 /* Notreached. */
1635 return NT_STATUS_INVALID_PARAMETER;
1638 /* Finally marshall the blob. */
1639 smb_io_rpc_auth_schannel_chk("",
1640 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1641 &verf,
1642 outgoing_pdu,
1645 return NT_STATUS_OK;
1648 /*******************************************************************
1649 Calculate how much data we're going to send in this packet, also
1650 work out any sign/seal padding length.
1651 ********************************************************************/
1653 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1654 uint32 data_left,
1655 uint16 *p_frag_len,
1656 uint16 *p_auth_len,
1657 uint32 *p_ss_padding)
1659 uint32 data_space, data_len;
1661 switch (cli->auth->auth_level) {
1662 case PIPE_AUTH_LEVEL_NONE:
1663 case PIPE_AUTH_LEVEL_CONNECT:
1664 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1665 data_len = MIN(data_space, data_left);
1666 *p_ss_padding = 0;
1667 *p_auth_len = 0;
1668 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1669 return data_len;
1671 case PIPE_AUTH_LEVEL_INTEGRITY:
1672 case PIPE_AUTH_LEVEL_PRIVACY:
1673 /* Treat the same for all authenticated rpc requests. */
1674 switch(cli->auth->auth_type) {
1675 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1676 case PIPE_AUTH_TYPE_NTLMSSP:
1677 *p_auth_len = NTLMSSP_SIG_SIZE;
1678 break;
1679 case PIPE_AUTH_TYPE_SCHANNEL:
1680 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1681 break;
1682 default:
1683 smb_panic("bad auth type");
1684 break;
1687 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1688 RPC_HDR_AUTH_LEN - *p_auth_len;
1690 data_len = MIN(data_space, data_left);
1691 if (data_len % 8) {
1692 *p_ss_padding = 8 - (data_len % 8);
1694 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1695 data_len + *p_ss_padding + /* data plus padding. */
1696 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1697 return data_len;
1699 default:
1700 smb_panic("bad auth level");
1701 /* Notreached. */
1702 return 0;
1706 /*******************************************************************
1707 External interface.
1708 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1709 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1710 and deals with signing/sealing details.
1711 ********************************************************************/
1713 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1714 uint8 op_num,
1715 prs_struct *in_data,
1716 prs_struct *out_data)
1718 NTSTATUS ret;
1719 uint32 data_left = prs_offset(in_data);
1720 uint32 alloc_hint = prs_offset(in_data);
1721 uint32 data_sent_thistime = 0;
1722 uint32 current_data_offset = 0;
1723 uint32 call_id = get_rpc_call_id();
1724 char pad[8];
1725 prs_struct outgoing_pdu;
1727 memset(pad, '\0', 8);
1729 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1730 /* Server is screwed up ! */
1731 return NT_STATUS_INVALID_PARAMETER;
1734 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1735 return NT_STATUS_NO_MEMORY;
1737 while (1) {
1738 RPC_HDR hdr;
1739 RPC_HDR_REQ hdr_req;
1740 uint16 auth_len = 0;
1741 uint16 frag_len = 0;
1742 uint8 flags = 0;
1743 uint32 ss_padding = 0;
1744 ssize_t num_written;
1746 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1747 &frag_len, &auth_len, &ss_padding);
1749 if (current_data_offset == 0) {
1750 flags = RPC_FLG_FIRST;
1753 if (data_sent_thistime == data_left) {
1754 flags |= RPC_FLG_LAST;
1757 /* Create and marshall the header and request header. */
1758 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1760 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1761 prs_mem_free(&outgoing_pdu);
1762 return NT_STATUS_NO_MEMORY;
1765 /* Create the rpc request RPC_HDR_REQ */
1766 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1768 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1769 prs_mem_free(&outgoing_pdu);
1770 return NT_STATUS_NO_MEMORY;
1773 /* Copy in the data, plus any ss padding. */
1774 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1775 prs_mem_free(&outgoing_pdu);
1776 return NT_STATUS_NO_MEMORY;
1779 /* Copy the sign/seal padding data. */
1780 if (ss_padding) {
1781 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1782 prs_mem_free(&outgoing_pdu);
1783 return NT_STATUS_NO_MEMORY;
1787 /* Generate any auth sign/seal and add the auth footer. */
1788 if (auth_len) {
1789 switch (cli->auth->auth_type) {
1790 case PIPE_AUTH_TYPE_NONE:
1791 break;
1792 case PIPE_AUTH_TYPE_NTLMSSP:
1793 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1794 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1795 if (!NT_STATUS_IS_OK(ret)) {
1796 prs_mem_free(&outgoing_pdu);
1797 return ret;
1799 break;
1800 case PIPE_AUTH_TYPE_SCHANNEL:
1801 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1802 if (!NT_STATUS_IS_OK(ret)) {
1803 prs_mem_free(&outgoing_pdu);
1804 return ret;
1806 break;
1807 default:
1808 smb_panic("bad auth type");
1809 break; /* notreached */
1813 /* Actually send the packet. */
1814 if (flags & RPC_FLG_LAST) {
1815 /* Last packet - send the data, get the reply and return. */
1816 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1817 prs_mem_free(&outgoing_pdu);
1819 if ((DEBUGLEVEL >= 50)
1820 && (cli->transport_type == NCACN_NP)) {
1821 char *dump_name = NULL;
1822 /* Also capture received data */
1823 if (asprintf(&dump_name, "%s/reply_%s_%d",
1824 get_dyn_LOGFILEBASE(),
1825 cli->trans.np.pipe_name, op_num) > 0) {
1826 prs_dump(dump_name, op_num, out_data);
1827 SAFE_FREE(dump_name);
1831 return ret;
1834 switch (cli->transport_type) {
1835 case NCACN_NP:
1836 num_written = cli_write(cli->trans.np.cli,
1837 cli->trans.np.fnum,
1838 8, /* 8 means message mode. */
1839 prs_data_p(&outgoing_pdu),
1840 (off_t)0,
1841 (size_t)hdr.frag_len);
1843 if (num_written != hdr.frag_len) {
1844 prs_mem_free(&outgoing_pdu);
1845 return cli_get_nt_error(cli->trans.np.cli);
1847 break;
1848 case NCACN_IP_TCP:
1849 case NCACN_UNIX_STREAM:
1850 num_written = write_data(
1851 cli->trans.sock.fd,
1852 prs_data_p(&outgoing_pdu),
1853 (size_t)hdr.frag_len);
1854 if (num_written != hdr.frag_len) {
1855 NTSTATUS status;
1856 status = map_nt_error_from_unix(errno);
1857 prs_mem_free(&outgoing_pdu);
1858 return status;
1860 break;
1861 default:
1862 DEBUG(0, ("unknown transport type %d\n",
1863 cli->transport_type));
1864 return NT_STATUS_INTERNAL_ERROR;
1867 current_data_offset += data_sent_thistime;
1868 data_left -= data_sent_thistime;
1870 /* Reset the marshalling position back to zero. */
1871 if (!prs_set_offset(&outgoing_pdu, 0)) {
1872 prs_mem_free(&outgoing_pdu);
1873 return NT_STATUS_NO_MEMORY;
1877 #if 0
1878 /****************************************************************************
1879 Set the handle state.
1880 ****************************************************************************/
1882 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1883 const char *pipe_name, uint16 device_state)
1885 bool state_set = False;
1886 char param[2];
1887 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1888 char *rparam = NULL;
1889 char *rdata = NULL;
1890 uint32 rparam_len, rdata_len;
1892 if (pipe_name == NULL)
1893 return False;
1895 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1896 cli->fnum, pipe_name, device_state));
1898 /* create parameters: device state */
1899 SSVAL(param, 0, device_state);
1901 /* create setup parameters. */
1902 setup[0] = 0x0001;
1903 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1905 /* send the data on \PIPE\ */
1906 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1907 setup, 2, 0, /* setup, length, max */
1908 param, 2, 0, /* param, length, max */
1909 NULL, 0, 1024, /* data, length, max */
1910 &rparam, &rparam_len, /* return param, length */
1911 &rdata, &rdata_len)) /* return data, length */
1913 DEBUG(5, ("Set Handle state: return OK\n"));
1914 state_set = True;
1917 SAFE_FREE(rparam);
1918 SAFE_FREE(rdata);
1920 return state_set;
1922 #endif
1924 /****************************************************************************
1925 Check the rpc bind acknowledge response.
1926 ****************************************************************************/
1928 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1930 if ( hdr_ba->addr.len == 0) {
1931 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1934 /* check the transfer syntax */
1935 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1936 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1937 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1938 return False;
1941 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1942 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1943 hdr_ba->res.num_results, hdr_ba->res.reason));
1946 DEBUG(5,("check_bind_response: accepted!\n"));
1947 return True;
1950 /*******************************************************************
1951 Creates a DCE/RPC bind authentication response.
1952 This is the packet that is sent back to the server once we
1953 have received a BIND-ACK, to finish the third leg of
1954 the authentication handshake.
1955 ********************************************************************/
1957 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1958 uint32 rpc_call_id,
1959 enum pipe_auth_type auth_type,
1960 enum pipe_auth_level auth_level,
1961 DATA_BLOB *pauth_blob,
1962 prs_struct *rpc_out)
1964 RPC_HDR hdr;
1965 RPC_HDR_AUTH hdr_auth;
1966 uint32 pad = 0;
1968 /* Create the request RPC_HDR */
1969 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1970 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1971 pauth_blob->length );
1973 /* Marshall it. */
1974 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1975 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1976 return NT_STATUS_NO_MEMORY;
1980 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1981 about padding - shouldn't this pad to length 8 ? JRA.
1984 /* 4 bytes padding. */
1985 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1986 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1987 return NT_STATUS_NO_MEMORY;
1990 /* Create the request RPC_HDR_AUTHA */
1991 init_rpc_hdr_auth(&hdr_auth,
1992 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1993 auth_level, 0, 1);
1995 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1996 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1997 return NT_STATUS_NO_MEMORY;
2001 * Append the auth data to the outgoing buffer.
2004 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2005 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2006 return NT_STATUS_NO_MEMORY;
2009 return NT_STATUS_OK;
2012 /****************************************************************************
2013 Create and send the third packet in an RPC auth.
2014 ****************************************************************************/
2016 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
2017 RPC_HDR *phdr,
2018 prs_struct *rbuf,
2019 uint32 rpc_call_id,
2020 enum pipe_auth_type auth_type,
2021 enum pipe_auth_level auth_level)
2023 DATA_BLOB server_response = data_blob_null;
2024 DATA_BLOB client_reply = data_blob_null;
2025 RPC_HDR_AUTH hdr_auth;
2026 NTSTATUS nt_status;
2027 prs_struct rpc_out;
2028 ssize_t ret;
2030 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2031 return NT_STATUS_INVALID_PARAMETER;
2034 /* Process the returned NTLMSSP blob first. */
2035 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2036 return NT_STATUS_INVALID_PARAMETER;
2039 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2040 return NT_STATUS_INVALID_PARAMETER;
2043 /* TODO - check auth_type/auth_level match. */
2045 server_response = data_blob(NULL, phdr->auth_len);
2046 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
2048 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2049 server_response,
2050 &client_reply);
2052 if (!NT_STATUS_IS_OK(nt_status)) {
2053 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
2054 data_blob_free(&server_response);
2055 return nt_status;
2058 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2060 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
2061 auth_type, auth_level,
2062 &client_reply, &rpc_out);
2064 if (!NT_STATUS_IS_OK(nt_status)) {
2065 prs_mem_free(&rpc_out);
2066 data_blob_free(&client_reply);
2067 data_blob_free(&server_response);
2068 return nt_status;
2071 switch (cli->transport_type) {
2072 case NCACN_NP:
2073 /* 8 here is named pipe message mode. */
2074 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
2075 0x8, prs_data_p(&rpc_out), 0,
2076 (size_t)prs_offset(&rpc_out));
2077 break;
2079 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2080 nt_status = cli_get_nt_error(cli->trans.np.cli);
2082 case NCACN_IP_TCP:
2083 case NCACN_UNIX_STREAM:
2084 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2085 (size_t)prs_offset(&rpc_out));
2086 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2087 nt_status = map_nt_error_from_unix(errno);
2089 break;
2090 default:
2091 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2092 return NT_STATUS_INTERNAL_ERROR;
2095 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2096 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2097 nt_errstr(nt_status)));
2098 prs_mem_free(&rpc_out);
2099 data_blob_free(&client_reply);
2100 data_blob_free(&server_response);
2101 return nt_status;
2104 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2105 rpccli_pipe_txt(debug_ctx(), cli)));
2107 prs_mem_free(&rpc_out);
2108 data_blob_free(&client_reply);
2109 data_blob_free(&server_response);
2110 return NT_STATUS_OK;
2113 /*******************************************************************
2114 Creates a DCE/RPC bind alter context authentication request which
2115 may contain a spnego auth blobl
2116 ********************************************************************/
2118 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2119 const RPC_IFACE *abstract,
2120 const RPC_IFACE *transfer,
2121 enum pipe_auth_level auth_level,
2122 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2123 prs_struct *rpc_out)
2125 RPC_HDR_AUTH hdr_auth;
2126 prs_struct auth_info;
2127 NTSTATUS ret = NT_STATUS_OK;
2129 ZERO_STRUCT(hdr_auth);
2130 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2131 return NT_STATUS_NO_MEMORY;
2133 /* We may change the pad length before marshalling. */
2134 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2136 if (pauth_blob->length) {
2137 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2138 prs_mem_free(&auth_info);
2139 return NT_STATUS_NO_MEMORY;
2143 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2144 rpc_out,
2145 rpc_call_id,
2146 abstract,
2147 transfer,
2148 &hdr_auth,
2149 &auth_info);
2150 prs_mem_free(&auth_info);
2151 return ret;
2154 /*******************************************************************
2155 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2156 and gets a response.
2157 ********************************************************************/
2159 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2160 RPC_HDR *phdr,
2161 prs_struct *rbuf,
2162 uint32 rpc_call_id,
2163 const RPC_IFACE *abstract,
2164 const RPC_IFACE *transfer,
2165 enum pipe_auth_type auth_type,
2166 enum pipe_auth_level auth_level)
2168 DATA_BLOB server_spnego_response = data_blob_null;
2169 DATA_BLOB server_ntlm_response = data_blob_null;
2170 DATA_BLOB client_reply = data_blob_null;
2171 DATA_BLOB tmp_blob = data_blob_null;
2172 RPC_HDR_AUTH hdr_auth;
2173 NTSTATUS nt_status;
2174 prs_struct rpc_out;
2176 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2177 return NT_STATUS_INVALID_PARAMETER;
2180 /* Process the returned NTLMSSP blob first. */
2181 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2182 return NT_STATUS_INVALID_PARAMETER;
2185 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2186 return NT_STATUS_INVALID_PARAMETER;
2189 server_spnego_response = data_blob(NULL, phdr->auth_len);
2190 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2192 /* The server might give us back two challenges - tmp_blob is for the second. */
2193 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2194 data_blob_free(&server_spnego_response);
2195 data_blob_free(&server_ntlm_response);
2196 data_blob_free(&tmp_blob);
2197 return NT_STATUS_INVALID_PARAMETER;
2200 /* We're finished with the server spnego response and the tmp_blob. */
2201 data_blob_free(&server_spnego_response);
2202 data_blob_free(&tmp_blob);
2204 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2205 server_ntlm_response,
2206 &client_reply);
2208 /* Finished with the server_ntlm response */
2209 data_blob_free(&server_ntlm_response);
2211 if (!NT_STATUS_IS_OK(nt_status)) {
2212 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2213 data_blob_free(&client_reply);
2214 return nt_status;
2217 /* SPNEGO wrap the client reply. */
2218 tmp_blob = spnego_gen_auth(client_reply);
2219 data_blob_free(&client_reply);
2220 client_reply = tmp_blob;
2221 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2223 /* Now prepare the alter context pdu. */
2224 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2226 nt_status = create_rpc_alter_context(rpc_call_id,
2227 abstract,
2228 transfer,
2229 auth_level,
2230 &client_reply,
2231 &rpc_out);
2233 data_blob_free(&client_reply);
2235 if (!NT_STATUS_IS_OK(nt_status)) {
2236 prs_mem_free(&rpc_out);
2237 return nt_status;
2240 /* Initialize the returning data struct. */
2241 prs_mem_free(rbuf);
2242 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2244 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2245 prs_mem_free(&rpc_out);
2246 if (!NT_STATUS_IS_OK(nt_status)) {
2247 return nt_status;
2250 /* Get the auth blob from the reply. */
2251 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2252 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2253 return NT_STATUS_BUFFER_TOO_SMALL;
2256 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2257 return NT_STATUS_INVALID_PARAMETER;
2260 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2261 return NT_STATUS_INVALID_PARAMETER;
2264 server_spnego_response = data_blob(NULL, phdr->auth_len);
2265 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2267 /* Check we got a valid auth response. */
2268 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2269 data_blob_free(&server_spnego_response);
2270 data_blob_free(&tmp_blob);
2271 return NT_STATUS_INVALID_PARAMETER;
2274 data_blob_free(&server_spnego_response);
2275 data_blob_free(&tmp_blob);
2277 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2278 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2280 return NT_STATUS_OK;
2283 /****************************************************************************
2284 Do an rpc bind.
2285 ****************************************************************************/
2287 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2288 struct cli_pipe_auth_data *auth)
2290 RPC_HDR hdr;
2291 RPC_HDR_BA hdr_ba;
2292 prs_struct rpc_out;
2293 prs_struct rbuf;
2294 uint32 rpc_call_id;
2295 NTSTATUS status;
2297 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2298 rpccli_pipe_txt(debug_ctx(), cli),
2299 (unsigned int)auth->auth_type,
2300 (unsigned int)auth->auth_level ));
2302 cli->auth = talloc_move(cli, &auth);
2304 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2306 rpc_call_id = get_rpc_call_id();
2308 /* Marshall the outgoing data. */
2309 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2310 &cli->abstract_syntax,
2311 &cli->transfer_syntax,
2312 cli->auth->auth_type,
2313 cli->auth->auth_level);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 prs_mem_free(&rpc_out);
2317 return status;
2320 /* Initialize the incoming data struct. */
2321 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2323 /* send data on \PIPE\. receive a response */
2324 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2325 prs_mem_free(&rpc_out);
2326 if (!NT_STATUS_IS_OK(status)) {
2327 return status;
2330 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2331 rpccli_pipe_txt(debug_ctx(), cli)));
2333 /* Unmarshall the RPC header */
2334 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2335 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2336 prs_mem_free(&rbuf);
2337 return NT_STATUS_BUFFER_TOO_SMALL;
2340 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2341 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2342 prs_mem_free(&rbuf);
2343 return NT_STATUS_BUFFER_TOO_SMALL;
2346 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2347 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2348 prs_mem_free(&rbuf);
2349 return NT_STATUS_BUFFER_TOO_SMALL;
2352 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2353 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2355 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2356 switch(cli->auth->auth_type) {
2358 case PIPE_AUTH_TYPE_NONE:
2359 case PIPE_AUTH_TYPE_SCHANNEL:
2360 /* Bind complete. */
2361 break;
2363 case PIPE_AUTH_TYPE_NTLMSSP:
2364 /* Need to send AUTH3 packet - no reply. */
2365 status = rpc_finish_auth3_bind(
2366 cli, &hdr, &rbuf, rpc_call_id,
2367 cli->auth->auth_type,
2368 cli->auth->auth_level);
2369 if (!NT_STATUS_IS_OK(status)) {
2370 prs_mem_free(&rbuf);
2371 return status;
2373 break;
2375 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2376 /* Need to send alter context request and reply. */
2377 status = rpc_finish_spnego_ntlmssp_bind(
2378 cli, &hdr, &rbuf, rpc_call_id,
2379 &cli->abstract_syntax, &cli->transfer_syntax,
2380 cli->auth->auth_type, cli->auth->auth_level);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 prs_mem_free(&rbuf);
2383 return status;
2385 break;
2387 case PIPE_AUTH_TYPE_KRB5:
2388 /* */
2390 default:
2391 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2392 "%u\n", (unsigned int)cli->auth->auth_type));
2393 prs_mem_free(&rbuf);
2394 return NT_STATUS_INVALID_INFO_CLASS;
2397 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2398 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2399 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2400 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2401 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2402 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2403 prs_mem_free(&rbuf);
2404 return NT_STATUS_INVALID_PARAMETER;
2407 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2408 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2409 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2410 prs_mem_free(&rbuf);
2411 return NT_STATUS_INVALID_PARAMETER;
2416 prs_mem_free(&rbuf);
2417 return NT_STATUS_OK;
2420 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2421 unsigned int timeout)
2423 return cli_set_timeout(cli->trans.np.cli, timeout);
2426 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2428 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2429 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2430 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2431 return true;
2434 if (cli->transport_type == NCACN_NP) {
2435 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2436 return true;
2439 return false;
2442 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2444 if (p->transport_type == NCACN_NP) {
2445 return p->trans.np.cli;
2447 return NULL;
2450 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2452 if (p->transport_type == NCACN_NP) {
2453 bool ret;
2454 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2455 if (!ret) {
2456 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2457 "pipe %s. Error was %s\n",
2458 rpccli_pipe_txt(debug_ctx(), p),
2459 cli_errstr(p->trans.np.cli)));
2462 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2463 rpccli_pipe_txt(debug_ctx(), p)));
2465 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2466 return ret ? -1 : 0;
2469 return -1;
2472 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2473 struct cli_pipe_auth_data **presult)
2475 struct cli_pipe_auth_data *result;
2477 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2478 if (result == NULL) {
2479 return NT_STATUS_NO_MEMORY;
2482 result->auth_type = PIPE_AUTH_TYPE_NONE;
2483 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2485 result->user_name = talloc_strdup(result, "");
2486 result->domain = talloc_strdup(result, "");
2487 if ((result->user_name == NULL) || (result->domain == NULL)) {
2488 TALLOC_FREE(result);
2489 return NT_STATUS_NO_MEMORY;
2492 *presult = result;
2493 return NT_STATUS_OK;
2496 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2498 ntlmssp_end(&auth->a_u.ntlmssp_state);
2499 return 0;
2502 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2503 enum pipe_auth_type auth_type,
2504 enum pipe_auth_level auth_level,
2505 const char *domain,
2506 const char *username,
2507 const char *password,
2508 struct cli_pipe_auth_data **presult)
2510 struct cli_pipe_auth_data *result;
2511 NTSTATUS status;
2513 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2514 if (result == NULL) {
2515 return NT_STATUS_NO_MEMORY;
2518 result->auth_type = auth_type;
2519 result->auth_level = auth_level;
2521 result->user_name = talloc_strdup(result, username);
2522 result->domain = talloc_strdup(result, domain);
2523 if ((result->user_name == NULL) || (result->domain == NULL)) {
2524 status = NT_STATUS_NO_MEMORY;
2525 goto fail;
2528 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2529 if (!NT_STATUS_IS_OK(status)) {
2530 goto fail;
2533 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2535 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2536 if (!NT_STATUS_IS_OK(status)) {
2537 goto fail;
2540 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2541 if (!NT_STATUS_IS_OK(status)) {
2542 goto fail;
2545 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 goto fail;
2551 * Turn off sign+seal to allow selected auth level to turn it back on.
2553 result->a_u.ntlmssp_state->neg_flags &=
2554 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2556 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2557 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2558 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2559 result->a_u.ntlmssp_state->neg_flags
2560 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2563 *presult = result;
2564 return NT_STATUS_OK;
2566 fail:
2567 TALLOC_FREE(result);
2568 return status;
2571 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2572 enum pipe_auth_level auth_level,
2573 const uint8_t sess_key[16],
2574 struct cli_pipe_auth_data **presult)
2576 struct cli_pipe_auth_data *result;
2578 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2579 if (result == NULL) {
2580 return NT_STATUS_NO_MEMORY;
2583 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2584 result->auth_level = auth_level;
2586 result->user_name = talloc_strdup(result, "");
2587 result->domain = talloc_strdup(result, domain);
2588 if ((result->user_name == NULL) || (result->domain == NULL)) {
2589 goto fail;
2592 result->a_u.schannel_auth = talloc(result,
2593 struct schannel_auth_struct);
2594 if (result->a_u.schannel_auth == NULL) {
2595 goto fail;
2598 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2599 sizeof(result->a_u.schannel_auth->sess_key));
2600 result->a_u.schannel_auth->seq_num = 0;
2602 *presult = result;
2603 return NT_STATUS_OK;
2605 fail:
2606 TALLOC_FREE(result);
2607 return NT_STATUS_NO_MEMORY;
2610 #ifdef HAVE_KRB5
2611 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2613 data_blob_free(&auth->session_key);
2614 return 0;
2616 #endif
2618 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2619 enum pipe_auth_level auth_level,
2620 const char *service_princ,
2621 const char *username,
2622 const char *password,
2623 struct cli_pipe_auth_data **presult)
2625 #ifdef HAVE_KRB5
2626 struct cli_pipe_auth_data *result;
2628 if ((username != NULL) && (password != NULL)) {
2629 int ret = kerberos_kinit_password(username, password, 0, NULL);
2630 if (ret != 0) {
2631 return NT_STATUS_ACCESS_DENIED;
2635 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2636 if (result == NULL) {
2637 return NT_STATUS_NO_MEMORY;
2640 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2641 result->auth_level = auth_level;
2644 * Username / domain need fixing!
2646 result->user_name = talloc_strdup(result, "");
2647 result->domain = talloc_strdup(result, "");
2648 if ((result->user_name == NULL) || (result->domain == NULL)) {
2649 goto fail;
2652 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2653 result, struct kerberos_auth_struct);
2654 if (result->a_u.kerberos_auth == NULL) {
2655 goto fail;
2657 talloc_set_destructor(result->a_u.kerberos_auth,
2658 cli_auth_kerberos_data_destructor);
2660 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2661 result, service_princ);
2662 if (result->a_u.kerberos_auth->service_principal == NULL) {
2663 goto fail;
2666 *presult = result;
2667 return NT_STATUS_OK;
2669 fail:
2670 TALLOC_FREE(result);
2671 return NT_STATUS_NO_MEMORY;
2672 #else
2673 return NT_STATUS_NOT_SUPPORTED;
2674 #endif
2677 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2679 close(p->trans.sock.fd);
2680 return 0;
2684 * Create an rpc pipe client struct, connecting to a tcp port.
2686 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2687 uint16_t port,
2688 const struct ndr_syntax_id *abstract_syntax,
2689 struct rpc_pipe_client **presult)
2691 struct rpc_pipe_client *result;
2692 struct sockaddr_storage addr;
2693 NTSTATUS status;
2695 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2696 if (result == NULL) {
2697 return NT_STATUS_NO_MEMORY;
2700 result->transport_type = NCACN_IP_TCP;
2702 result->abstract_syntax = *abstract_syntax;
2703 result->transfer_syntax = ndr_transfer_syntax;
2705 result->desthost = talloc_strdup(result, host);
2706 result->srv_name_slash = talloc_asprintf_strupper_m(
2707 result, "\\\\%s", result->desthost);
2708 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2709 status = NT_STATUS_NO_MEMORY;
2710 goto fail;
2713 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2714 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2716 if (!resolve_name(host, &addr, 0)) {
2717 status = NT_STATUS_NOT_FOUND;
2718 goto fail;
2721 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2722 if (!NT_STATUS_IS_OK(status)) {
2723 goto fail;
2726 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2728 *presult = result;
2729 return NT_STATUS_OK;
2731 fail:
2732 TALLOC_FREE(result);
2733 return status;
2737 * Determine the tcp port on which a dcerpc interface is listening
2738 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2739 * target host.
2741 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2742 const struct ndr_syntax_id *abstract_syntax,
2743 uint16_t *pport)
2745 NTSTATUS status;
2746 struct rpc_pipe_client *epm_pipe = NULL;
2747 struct cli_pipe_auth_data *auth = NULL;
2748 struct dcerpc_binding *map_binding = NULL;
2749 struct dcerpc_binding *res_binding = NULL;
2750 struct epm_twr_t *map_tower = NULL;
2751 struct epm_twr_t *res_towers = NULL;
2752 struct policy_handle *entry_handle = NULL;
2753 uint32_t num_towers = 0;
2754 uint32_t max_towers = 1;
2755 struct epm_twr_p_t towers;
2756 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2758 if (pport == NULL) {
2759 status = NT_STATUS_INVALID_PARAMETER;
2760 goto done;
2763 /* open the connection to the endpoint mapper */
2764 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2765 &ndr_table_epmapper.syntax_id,
2766 &epm_pipe);
2768 if (!NT_STATUS_IS_OK(status)) {
2769 goto done;
2772 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2773 if (!NT_STATUS_IS_OK(status)) {
2774 goto done;
2777 status = rpc_pipe_bind(epm_pipe, auth);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 goto done;
2782 /* create tower for asking the epmapper */
2784 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2785 if (map_binding == NULL) {
2786 status = NT_STATUS_NO_MEMORY;
2787 goto done;
2790 map_binding->transport = NCACN_IP_TCP;
2791 map_binding->object = *abstract_syntax;
2792 map_binding->host = host; /* needed? */
2793 map_binding->endpoint = "0"; /* correct? needed? */
2795 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2796 if (map_tower == NULL) {
2797 status = NT_STATUS_NO_MEMORY;
2798 goto done;
2801 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2802 &(map_tower->tower));
2803 if (!NT_STATUS_IS_OK(status)) {
2804 goto done;
2807 /* allocate further parameters for the epm_Map call */
2809 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2810 if (res_towers == NULL) {
2811 status = NT_STATUS_NO_MEMORY;
2812 goto done;
2814 towers.twr = res_towers;
2816 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2817 if (entry_handle == NULL) {
2818 status = NT_STATUS_NO_MEMORY;
2819 goto done;
2822 /* ask the endpoint mapper for the port */
2824 status = rpccli_epm_Map(epm_pipe,
2825 tmp_ctx,
2826 CONST_DISCARD(struct GUID *,
2827 &(abstract_syntax->uuid)),
2828 map_tower,
2829 entry_handle,
2830 max_towers,
2831 &num_towers,
2832 &towers);
2834 if (!NT_STATUS_IS_OK(status)) {
2835 goto done;
2838 if (num_towers != 1) {
2839 status = NT_STATUS_UNSUCCESSFUL;
2840 goto done;
2843 /* extract the port from the answer */
2845 status = dcerpc_binding_from_tower(tmp_ctx,
2846 &(towers.twr->tower),
2847 &res_binding);
2848 if (!NT_STATUS_IS_OK(status)) {
2849 goto done;
2852 /* are further checks here necessary? */
2853 if (res_binding->transport != NCACN_IP_TCP) {
2854 status = NT_STATUS_UNSUCCESSFUL;
2855 goto done;
2858 *pport = (uint16_t)atoi(res_binding->endpoint);
2860 done:
2861 TALLOC_FREE(tmp_ctx);
2862 return status;
2866 * Create a rpc pipe client struct, connecting to a host via tcp.
2867 * The port is determined by asking the endpoint mapper on the given
2868 * host.
2870 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2871 const struct ndr_syntax_id *abstract_syntax,
2872 struct rpc_pipe_client **presult)
2874 NTSTATUS status;
2875 uint16_t port = 0;
2877 *presult = NULL;
2879 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2880 if (!NT_STATUS_IS_OK(status)) {
2881 goto done;
2884 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2885 abstract_syntax, presult);
2887 done:
2888 return status;
2891 /********************************************************************
2892 Create a rpc pipe client struct, connecting to a unix domain socket
2893 ********************************************************************/
2894 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2895 const struct ndr_syntax_id *abstract_syntax,
2896 struct rpc_pipe_client **presult)
2898 struct rpc_pipe_client *result;
2899 struct sockaddr_un addr;
2900 NTSTATUS status;
2902 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2903 if (result == NULL) {
2904 return NT_STATUS_NO_MEMORY;
2907 result->transport_type = NCACN_UNIX_STREAM;
2909 result->abstract_syntax = *abstract_syntax;
2910 result->transfer_syntax = ndr_transfer_syntax;
2912 result->desthost = talloc_get_myname(result);
2913 result->srv_name_slash = talloc_asprintf_strupper_m(
2914 result, "\\\\%s", result->desthost);
2915 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2916 status = NT_STATUS_NO_MEMORY;
2917 goto fail;
2920 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2921 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2923 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2924 if (result->trans.sock.fd == -1) {
2925 status = map_nt_error_from_unix(errno);
2926 goto fail;
2929 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2931 ZERO_STRUCT(addr);
2932 addr.sun_family = AF_UNIX;
2933 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2935 if (sys_connect(result->trans.sock.fd,
2936 (struct sockaddr *)&addr) == -1) {
2937 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2938 strerror(errno)));
2939 close(result->trans.sock.fd);
2940 return map_nt_error_from_unix(errno);
2943 *presult = result;
2944 return NT_STATUS_OK;
2946 fail:
2947 TALLOC_FREE(result);
2948 return status;
2952 /****************************************************************************
2953 Open a named pipe over SMB to a remote server.
2955 * CAVEAT CALLER OF THIS FUNCTION:
2956 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2957 * so be sure that this function is called AFTER any structure (vs pointer)
2958 * assignment of the cli. In particular, libsmbclient does structure
2959 * assignments of cli, which invalidates the data in the returned
2960 * rpc_pipe_client if this function is called before the structure assignment
2961 * of cli.
2963 ****************************************************************************/
2965 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2966 const struct ndr_syntax_id *abstract_syntax,
2967 struct rpc_pipe_client **presult)
2969 struct rpc_pipe_client *result;
2970 int fnum;
2972 /* sanity check to protect against crashes */
2974 if ( !cli ) {
2975 return NT_STATUS_INVALID_HANDLE;
2978 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2979 if (result == NULL) {
2980 return NT_STATUS_NO_MEMORY;
2983 result->transport_type = NCACN_NP;
2985 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2986 result, cli, abstract_syntax);
2987 if (result->trans.np.pipe_name == NULL) {
2988 DEBUG(1, ("Could not find pipe for interface\n"));
2989 TALLOC_FREE(result);
2990 return NT_STATUS_INVALID_PARAMETER;
2993 result->trans.np.cli = cli;
2994 result->abstract_syntax = *abstract_syntax;
2995 result->transfer_syntax = ndr_transfer_syntax;
2996 result->desthost = talloc_strdup(result, cli->desthost);
2997 result->srv_name_slash = talloc_asprintf_strupper_m(
2998 result, "\\\\%s", result->desthost);
3000 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3001 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3003 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3004 TALLOC_FREE(result);
3005 return NT_STATUS_NO_MEMORY;
3008 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
3009 DESIRED_ACCESS_PIPE);
3010 if (fnum == -1) {
3011 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
3012 "to machine %s. Error was %s\n",
3013 result->trans.np.pipe_name, cli->desthost,
3014 cli_errstr(cli)));
3015 TALLOC_FREE(result);
3016 return cli_get_nt_error(cli);
3019 result->trans.np.fnum = fnum;
3021 DLIST_ADD(cli->pipe_list, result);
3022 talloc_set_destructor(result, rpc_pipe_destructor);
3024 *presult = result;
3025 return NT_STATUS_OK;
3028 /****************************************************************************
3029 Open a pipe to a remote server.
3030 ****************************************************************************/
3032 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3033 const struct ndr_syntax_id *interface,
3034 struct rpc_pipe_client **presult)
3036 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3038 * We should have a better way to figure out this drsuapi
3039 * speciality...
3041 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3042 presult);
3045 return rpc_pipe_open_np(cli, interface, presult);
3048 /****************************************************************************
3049 Open a named pipe to an SMB server and bind anonymously.
3050 ****************************************************************************/
3052 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3053 const struct ndr_syntax_id *interface,
3054 struct rpc_pipe_client **presult)
3056 struct rpc_pipe_client *result;
3057 struct cli_pipe_auth_data *auth;
3058 NTSTATUS status;
3060 status = cli_rpc_pipe_open(cli, interface, &result);
3061 if (!NT_STATUS_IS_OK(status)) {
3062 return status;
3065 status = rpccli_anon_bind_data(result, &auth);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3068 nt_errstr(status)));
3069 TALLOC_FREE(result);
3070 return status;
3074 * This is a bit of an abstraction violation due to the fact that an
3075 * anonymous bind on an authenticated SMB inherits the user/domain
3076 * from the enclosing SMB creds
3079 TALLOC_FREE(auth->user_name);
3080 TALLOC_FREE(auth->domain);
3082 auth->user_name = talloc_strdup(auth, cli->user_name);
3083 auth->domain = talloc_strdup(auth, cli->domain);
3084 auth->user_session_key = data_blob_talloc(auth,
3085 cli->user_session_key.data,
3086 cli->user_session_key.length);
3088 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3089 TALLOC_FREE(result);
3090 return NT_STATUS_NO_MEMORY;
3093 status = rpc_pipe_bind(result, auth);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 int lvl = 0;
3096 if (ndr_syntax_id_equal(interface,
3097 &ndr_table_dssetup.syntax_id)) {
3098 /* non AD domains just don't have this pipe, avoid
3099 * level 0 statement in that case - gd */
3100 lvl = 3;
3102 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3103 "%s failed with error %s\n",
3104 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3105 interface),
3106 nt_errstr(status) ));
3107 TALLOC_FREE(result);
3108 return status;
3111 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3112 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3113 cli->desthost ));
3115 *presult = result;
3116 return NT_STATUS_OK;
3119 /****************************************************************************
3120 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3121 ****************************************************************************/
3123 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3124 const struct ndr_syntax_id *interface,
3125 enum pipe_auth_type auth_type,
3126 enum pipe_auth_level auth_level,
3127 const char *domain,
3128 const char *username,
3129 const char *password,
3130 struct rpc_pipe_client **presult)
3132 struct rpc_pipe_client *result;
3133 struct cli_pipe_auth_data *auth;
3134 NTSTATUS status;
3136 status = cli_rpc_pipe_open(cli, interface, &result);
3137 if (!NT_STATUS_IS_OK(status)) {
3138 return status;
3141 status = rpccli_ntlmssp_bind_data(
3142 result, auth_type, auth_level, domain, username,
3143 cli->pwd.null_pwd ? NULL : password, &auth);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3146 nt_errstr(status)));
3147 goto err;
3150 status = rpc_pipe_bind(result, auth);
3151 if (!NT_STATUS_IS_OK(status)) {
3152 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3153 nt_errstr(status) ));
3154 goto err;
3157 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3158 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3159 result->trans.np.pipe_name, cli->desthost,
3160 domain, username ));
3162 *presult = result;
3163 return NT_STATUS_OK;
3165 err:
3167 TALLOC_FREE(result);
3168 return status;
3171 /****************************************************************************
3172 External interface.
3173 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3174 ****************************************************************************/
3176 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3177 const struct ndr_syntax_id *interface,
3178 enum pipe_auth_level auth_level,
3179 const char *domain,
3180 const char *username,
3181 const char *password,
3182 struct rpc_pipe_client **presult)
3184 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3185 interface,
3186 PIPE_AUTH_TYPE_NTLMSSP,
3187 auth_level,
3188 domain,
3189 username,
3190 password,
3191 presult);
3194 /****************************************************************************
3195 External interface.
3196 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3197 ****************************************************************************/
3199 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3200 const struct ndr_syntax_id *interface,
3201 enum pipe_auth_level auth_level,
3202 const char *domain,
3203 const char *username,
3204 const char *password,
3205 struct rpc_pipe_client **presult)
3207 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3208 interface,
3209 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3210 auth_level,
3211 domain,
3212 username,
3213 password,
3214 presult);
3217 /****************************************************************************
3218 Get a the schannel session key out of an already opened netlogon pipe.
3219 ****************************************************************************/
3220 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3221 struct cli_state *cli,
3222 const char *domain,
3223 uint32 *pneg_flags)
3225 uint32 sec_chan_type = 0;
3226 unsigned char machine_pwd[16];
3227 const char *machine_account;
3228 NTSTATUS status;
3230 /* Get the machine account credentials from secrets.tdb. */
3231 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3232 &sec_chan_type))
3234 DEBUG(0, ("get_schannel_session_key: could not fetch "
3235 "trust account password for domain '%s'\n",
3236 domain));
3237 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3240 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3241 cli->desthost, /* server name */
3242 domain, /* domain */
3243 global_myname(), /* client name */
3244 machine_account, /* machine account name */
3245 machine_pwd,
3246 sec_chan_type,
3247 pneg_flags);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 DEBUG(3, ("get_schannel_session_key_common: "
3251 "rpccli_netlogon_setup_creds failed with result %s "
3252 "to server %s, domain %s, machine account %s.\n",
3253 nt_errstr(status), cli->desthost, domain,
3254 machine_account ));
3255 return status;
3258 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3259 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3260 cli->desthost));
3261 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3264 return NT_STATUS_OK;;
3267 /****************************************************************************
3268 Open a netlogon pipe and get the schannel session key.
3269 Now exposed to external callers.
3270 ****************************************************************************/
3273 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3274 const char *domain,
3275 uint32 *pneg_flags,
3276 struct rpc_pipe_client **presult)
3278 struct rpc_pipe_client *netlogon_pipe = NULL;
3279 NTSTATUS status;
3281 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3282 &netlogon_pipe);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 return status;
3287 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3288 pneg_flags);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 TALLOC_FREE(netlogon_pipe);
3291 return status;
3294 *presult = netlogon_pipe;
3295 return NT_STATUS_OK;
3298 /****************************************************************************
3299 External interface.
3300 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3301 using session_key. sign and seal.
3302 ****************************************************************************/
3304 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3305 const struct ndr_syntax_id *interface,
3306 enum pipe_auth_level auth_level,
3307 const char *domain,
3308 const struct dcinfo *pdc,
3309 struct rpc_pipe_client **presult)
3311 struct rpc_pipe_client *result;
3312 struct cli_pipe_auth_data *auth;
3313 NTSTATUS status;
3315 status = cli_rpc_pipe_open(cli, interface, &result);
3316 if (!NT_STATUS_IS_OK(status)) {
3317 return status;
3320 status = rpccli_schannel_bind_data(result, domain, auth_level,
3321 pdc->sess_key, &auth);
3322 if (!NT_STATUS_IS_OK(status)) {
3323 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3324 nt_errstr(status)));
3325 TALLOC_FREE(result);
3326 return status;
3329 status = rpc_pipe_bind(result, auth);
3330 if (!NT_STATUS_IS_OK(status)) {
3331 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3332 "cli_rpc_pipe_bind failed with error %s\n",
3333 nt_errstr(status) ));
3334 TALLOC_FREE(result);
3335 return status;
3339 * The credentials on a new netlogon pipe are the ones we are passed
3340 * in - copy them over.
3342 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3343 if (result->dc == NULL) {
3344 DEBUG(0, ("talloc failed\n"));
3345 TALLOC_FREE(result);
3346 return NT_STATUS_NO_MEMORY;
3349 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3350 "for domain %s "
3351 "and bound using schannel.\n",
3352 result->trans.np.pipe_name, cli->desthost, domain ));
3354 *presult = result;
3355 return NT_STATUS_OK;
3358 /****************************************************************************
3359 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3360 Fetch the session key ourselves using a temporary netlogon pipe. This
3361 version uses an ntlmssp auth bound netlogon pipe to get the key.
3362 ****************************************************************************/
3364 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3365 const char *domain,
3366 const char *username,
3367 const char *password,
3368 uint32 *pneg_flags,
3369 struct rpc_pipe_client **presult)
3371 struct rpc_pipe_client *netlogon_pipe = NULL;
3372 NTSTATUS status;
3374 status = cli_rpc_pipe_open_spnego_ntlmssp(
3375 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3376 domain, username, password, &netlogon_pipe);
3377 if (!NT_STATUS_IS_OK(status)) {
3378 return status;
3381 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3382 pneg_flags);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 TALLOC_FREE(netlogon_pipe);
3385 return status;
3388 *presult = netlogon_pipe;
3389 return NT_STATUS_OK;
3392 /****************************************************************************
3393 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3394 Fetch the session key ourselves using a temporary netlogon pipe. This version
3395 uses an ntlmssp bind to get the session key.
3396 ****************************************************************************/
3398 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3399 const struct ndr_syntax_id *interface,
3400 enum pipe_auth_level auth_level,
3401 const char *domain,
3402 const char *username,
3403 const char *password,
3404 struct rpc_pipe_client **presult)
3406 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3407 struct rpc_pipe_client *netlogon_pipe = NULL;
3408 struct rpc_pipe_client *result = NULL;
3409 NTSTATUS status;
3411 status = get_schannel_session_key_auth_ntlmssp(
3412 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3413 if (!NT_STATUS_IS_OK(status)) {
3414 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3415 "key from server %s for domain %s.\n",
3416 cli->desthost, domain ));
3417 return status;
3420 status = cli_rpc_pipe_open_schannel_with_key(
3421 cli, interface, auth_level, domain, netlogon_pipe->dc,
3422 &result);
3424 /* Now we've bound using the session key we can close the netlog pipe. */
3425 TALLOC_FREE(netlogon_pipe);
3427 if (NT_STATUS_IS_OK(status)) {
3428 *presult = result;
3430 return status;
3433 /****************************************************************************
3434 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3435 Fetch the session key ourselves using a temporary netlogon pipe.
3436 ****************************************************************************/
3438 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3439 const struct ndr_syntax_id *interface,
3440 enum pipe_auth_level auth_level,
3441 const char *domain,
3442 struct rpc_pipe_client **presult)
3444 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3445 struct rpc_pipe_client *netlogon_pipe = NULL;
3446 struct rpc_pipe_client *result = NULL;
3447 NTSTATUS status;
3449 status = get_schannel_session_key(cli, domain, &neg_flags,
3450 &netlogon_pipe);
3451 if (!NT_STATUS_IS_OK(status)) {
3452 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3453 "key from server %s for domain %s.\n",
3454 cli->desthost, domain ));
3455 return status;
3458 status = cli_rpc_pipe_open_schannel_with_key(
3459 cli, interface, auth_level, domain, netlogon_pipe->dc,
3460 &result);
3462 /* Now we've bound using the session key we can close the netlog pipe. */
3463 TALLOC_FREE(netlogon_pipe);
3465 if (NT_STATUS_IS_OK(status)) {
3466 *presult = result;
3469 return NT_STATUS_OK;
3472 /****************************************************************************
3473 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3474 The idea is this can be called with service_princ, username and password all
3475 NULL so long as the caller has a TGT.
3476 ****************************************************************************/
3478 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3479 const struct ndr_syntax_id *interface,
3480 enum pipe_auth_level auth_level,
3481 const char *service_princ,
3482 const char *username,
3483 const char *password,
3484 struct rpc_pipe_client **presult)
3486 #ifdef HAVE_KRB5
3487 struct rpc_pipe_client *result;
3488 struct cli_pipe_auth_data *auth;
3489 NTSTATUS status;
3491 status = cli_rpc_pipe_open(cli, interface, &result);
3492 if (!NT_STATUS_IS_OK(status)) {
3493 return status;
3496 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3497 username, password, &auth);
3498 if (!NT_STATUS_IS_OK(status)) {
3499 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3500 nt_errstr(status)));
3501 TALLOC_FREE(result);
3502 return status;
3505 status = rpc_pipe_bind(result, auth);
3506 if (!NT_STATUS_IS_OK(status)) {
3507 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3508 "with error %s\n", nt_errstr(status)));
3509 TALLOC_FREE(result);
3510 return status;
3513 *presult = result;
3514 return NT_STATUS_OK;
3515 #else
3516 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3517 return NT_STATUS_NOT_IMPLEMENTED;
3518 #endif
3521 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3522 struct rpc_pipe_client *cli,
3523 DATA_BLOB *session_key)
3525 if (!session_key || !cli) {
3526 return NT_STATUS_INVALID_PARAMETER;
3529 if (!cli->auth) {
3530 return NT_STATUS_INVALID_PARAMETER;
3533 switch (cli->auth->auth_type) {
3534 case PIPE_AUTH_TYPE_SCHANNEL:
3535 *session_key = data_blob_talloc(mem_ctx,
3536 cli->auth->a_u.schannel_auth->sess_key, 16);
3537 break;
3538 case PIPE_AUTH_TYPE_NTLMSSP:
3539 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3540 *session_key = data_blob_talloc(mem_ctx,
3541 cli->auth->a_u.ntlmssp_state->session_key.data,
3542 cli->auth->a_u.ntlmssp_state->session_key.length);
3543 break;
3544 case PIPE_AUTH_TYPE_KRB5:
3545 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3546 *session_key = data_blob_talloc(mem_ctx,
3547 cli->auth->a_u.kerberos_auth->session_key.data,
3548 cli->auth->a_u.kerberos_auth->session_key.length);
3549 break;
3550 case PIPE_AUTH_TYPE_NONE:
3551 *session_key = data_blob_talloc(mem_ctx,
3552 cli->auth->user_session_key.data,
3553 cli->auth->user_session_key.length);
3554 break;
3555 default:
3556 return NT_STATUS_NO_USER_SESSION_KEY;
3559 return NT_STATUS_OK;