source: branches/samba-3.2.x/source/rpc_client/cli_pipe.c

Last change on this file was 228, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.6

File size: 84.7 KB
Line 
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.
10 *
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.
15 *
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/>.
18 */
19
20#include "includes.h"
21
22#undef DBGC_CLASS
23#define DBGC_CLASS DBGC_RPC_CLI
24
25extern struct pipe_id_info pipe_names[];
26
27/********************************************************************
28 Map internal value to wire value.
29 ********************************************************************/
30
31static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
32{
33 switch (auth_type) {
34
35 case PIPE_AUTH_TYPE_NONE:
36 return RPC_ANONYMOUS_AUTH_TYPE;
37
38 case PIPE_AUTH_TYPE_NTLMSSP:
39 return RPC_NTLMSSP_AUTH_TYPE;
40
41 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
42 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
43 return RPC_SPNEGO_AUTH_TYPE;
44
45 case PIPE_AUTH_TYPE_SCHANNEL:
46 return RPC_SCHANNEL_AUTH_TYPE;
47
48 case PIPE_AUTH_TYPE_KRB5:
49 return RPC_KRB5_AUTH_TYPE;
50
51 default:
52 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
53 "auth type %u\n",
54 (unsigned int)auth_type ));
55 break;
56 }
57 return -1;
58}
59
60/********************************************************************
61 Rpc pipe call id.
62 ********************************************************************/
63
64static uint32 get_rpc_call_id(void)
65{
66 static uint32 call_id = 0;
67 return ++call_id;
68}
69
70/*******************************************************************
71 Use SMBreadX to get rest of one fragment's worth of rpc data.
72 Will expand the current_pdu struct to the correct size.
73 ********************************************************************/
74
75static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
76 prs_struct *current_pdu,
77 uint32 data_to_read,
78 uint32 *current_pdu_offset)
79{
80 size_t size = (size_t)cli->max_recv_frag;
81 uint32 stream_offset = 0;
82 ssize_t num_read;
83 char *pdata;
84 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
85
86 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
87 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
88
89 /*
90 * Grow the buffer if needed to accommodate the data to be read.
91 */
92
93 if (extra_data_size > 0) {
94 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
95 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
96 return NT_STATUS_NO_MEMORY;
97 }
98 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
99 }
100
101 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
102
103 do {
104 /* read data using SMBreadX */
105 if (size > (size_t)data_to_read) {
106 size = (size_t)data_to_read;
107 }
108
109 num_read = cli_read(cli->cli, cli->fnum, pdata,
110 (off_t)stream_offset, size);
111
112 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
113 (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
114
115 /*
116 * A dos error of ERRDOS/ERRmoredata is not an error.
117 */
118 if (cli_is_dos_error(cli->cli)) {
119 uint32 ecode;
120 uint8 eclass;
121 cli_dos_error(cli->cli, &eclass, &ecode);
122 if (eclass != ERRDOS && ecode != ERRmoredata) {
123 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
124 eclass, (unsigned int)ecode,
125 cli_errstr(cli->cli),
126 cli->pipe_name ));
127 return dos_to_ntstatus(eclass, ecode);
128 }
129 }
130
131 /*
132 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
133 */
134 if (cli_is_nt_error(cli->cli)) {
135 if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
136 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
137 nt_errstr(cli_nt_error(cli->cli)),
138 cli->pipe_name ));
139 return cli_nt_error(cli->cli);
140 }
141 }
142
143 if (num_read == -1) {
144 DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
145 cli->pipe_name ));
146 return cli_get_nt_error(cli->cli);
147 }
148
149 data_to_read -= num_read;
150 stream_offset += num_read;
151 pdata += num_read;
152
153 } while (num_read > 0 && data_to_read > 0);
154 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
155
156 /*
157 * Update the current offset into current_pdu by the amount read.
158 */
159 *current_pdu_offset += stream_offset;
160 return NT_STATUS_OK;
161}
162
163/****************************************************************************
164 Try and get a PDU's worth of data from current_pdu. If not, then read more
165 from the wire.
166 ****************************************************************************/
167
168static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
169{
170 NTSTATUS ret = NT_STATUS_OK;
171 uint32 current_pdu_len = prs_data_size(current_pdu);
172
173 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
174 if (current_pdu_len < RPC_HEADER_LEN) {
175 /* rpc_read expands the current_pdu struct as neccessary. */
176 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
177 if (!NT_STATUS_IS_OK(ret)) {
178 return ret;
179 }
180 }
181
182 /* This next call sets the endian bit correctly in current_pdu. */
183 /* We will propagate this to rbuf later. */
184 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
185 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
186 return NT_STATUS_BUFFER_TOO_SMALL;
187 }
188
189 /* Ensure we have frag_len bytes of data. */
190 if (current_pdu_len < prhdr->frag_len) {
191 /* rpc_read expands the current_pdu struct as neccessary. */
192 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
193 if (!NT_STATUS_IS_OK(ret)) {
194 return ret;
195 }
196 }
197
198 if (current_pdu_len < prhdr->frag_len) {
199 return NT_STATUS_BUFFER_TOO_SMALL;
200 }
201
202 return NT_STATUS_OK;
203}
204
205/****************************************************************************
206 NTLMSSP specific sign/seal.
207 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
208 In fact I should probably abstract these into identical pieces of code... JRA.
209 ****************************************************************************/
210
211static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
212 prs_struct *current_pdu,
213 uint8 *p_ss_padding_len)
214{
215 RPC_HDR_AUTH auth_info;
216 uint32 save_offset = prs_offset(current_pdu);
217 uint32 auth_len = prhdr->auth_len;
218 NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
219 unsigned char *data = NULL;
220 size_t data_len;
221 unsigned char *full_packet_data = NULL;
222 size_t full_packet_data_len;
223 DATA_BLOB auth_blob;
224 NTSTATUS status;
225
226 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
227 return NT_STATUS_OK;
228 }
229
230 if (!ntlmssp_state) {
231 return NT_STATUS_INVALID_PARAMETER;
232 }
233
234 /* Ensure there's enough data for an authenticated response. */
235 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
236 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
237 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
238 (unsigned int)auth_len ));
239 return NT_STATUS_BUFFER_TOO_SMALL;
240 }
241
242 /*
243 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
244 * after the RPC header.
245 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
246 * functions as NTLMv2 checks the rpc headers also.
247 */
248
249 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
250 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
251
252 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
253 full_packet_data_len = prhdr->frag_len - auth_len;
254
255 /* Pull the auth header and the following data into a blob. */
256 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
257 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
258 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
259 return NT_STATUS_BUFFER_TOO_SMALL;
260 }
261
262 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
263 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
264 return NT_STATUS_BUFFER_TOO_SMALL;
265 }
266
267 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
268 auth_blob.length = auth_len;
269
270 switch (cli->auth.auth_level) {
271 case PIPE_AUTH_LEVEL_PRIVACY:
272 /* Data is encrypted. */
273 status = ntlmssp_unseal_packet(ntlmssp_state,
274 data, data_len,
275 full_packet_data,
276 full_packet_data_len,
277 &auth_blob);
278 if (!NT_STATUS_IS_OK(status)) {
279 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
280 "packet from remote machine %s on pipe %s "
281 "fnum 0x%x. Error was %s.\n",
282 cli->cli->desthost,
283 cli->pipe_name,
284 (unsigned int)cli->fnum,
285 nt_errstr(status) ));
286 return status;
287 }
288 break;
289 case PIPE_AUTH_LEVEL_INTEGRITY:
290 /* Data is signed. */
291 status = ntlmssp_check_packet(ntlmssp_state,
292 data, data_len,
293 full_packet_data,
294 full_packet_data_len,
295 &auth_blob);
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
298 "packet from remote machine %s on pipe %s "
299 "fnum 0x%x. Error was %s.\n",
300 cli->cli->desthost,
301 cli->pipe_name,
302 (unsigned int)cli->fnum,
303 nt_errstr(status) ));
304 return status;
305 }
306 break;
307 default:
308 DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
309 cli->auth.auth_level ));
310 return NT_STATUS_INVALID_INFO_CLASS;
311 }
312
313 /*
314 * Return the current pointer to the data offset.
315 */
316
317 if(!prs_set_offset(current_pdu, save_offset)) {
318 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
319 (unsigned int)save_offset ));
320 return NT_STATUS_BUFFER_TOO_SMALL;
321 }
322
323 /*
324 * Remember the padding length. We must remove it from the real data
325 * stream once the sign/seal is done.
326 */
327
328 *p_ss_padding_len = auth_info.auth_pad_len;
329
330 return NT_STATUS_OK;
331}
332
333/****************************************************************************
334 schannel specific sign/seal.
335 ****************************************************************************/
336
337static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
338 prs_struct *current_pdu,
339 uint8 *p_ss_padding_len)
340{
341 RPC_HDR_AUTH auth_info;
342 RPC_AUTH_SCHANNEL_CHK schannel_chk;
343 uint32 auth_len = prhdr->auth_len;
344 uint32 save_offset = prs_offset(current_pdu);
345 struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
346 uint32 data_len;
347
348 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
349 return NT_STATUS_OK;
350 }
351
352 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
353 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
354 return NT_STATUS_INVALID_PARAMETER;
355 }
356
357 if (!schannel_auth) {
358 return NT_STATUS_INVALID_PARAMETER;
359 }
360
361 /* Ensure there's enough data for an authenticated response. */
362 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
363 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
364 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
365 (unsigned int)auth_len ));
366 return NT_STATUS_INVALID_PARAMETER;
367 }
368
369 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
370
371 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
372 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
373 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
374 return NT_STATUS_BUFFER_TOO_SMALL;
375 }
376
377 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
378 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
379 return NT_STATUS_BUFFER_TOO_SMALL;
380 }
381
382 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
383 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
384 auth_info.auth_type));
385 return NT_STATUS_BUFFER_TOO_SMALL;
386 }
387
388 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
389 &schannel_chk, current_pdu, 0)) {
390 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
391 return NT_STATUS_BUFFER_TOO_SMALL;
392 }
393
394 if (!schannel_decode(schannel_auth,
395 cli->auth.auth_level,
396 SENDER_IS_ACCEPTOR,
397 &schannel_chk,
398 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
399 data_len)) {
400 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
401 "Connection to remote machine %s "
402 "pipe %s fnum 0x%x.\n",
403 cli->cli->desthost,
404 cli->pipe_name,
405 (unsigned int)cli->fnum ));
406 return NT_STATUS_INVALID_PARAMETER;
407 }
408
409 /* The sequence number gets incremented on both send and receive. */
410 schannel_auth->seq_num++;
411
412 /*
413 * Return the current pointer to the data offset.
414 */
415
416 if(!prs_set_offset(current_pdu, save_offset)) {
417 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
418 (unsigned int)save_offset ));
419 return NT_STATUS_BUFFER_TOO_SMALL;
420 }
421
422 /*
423 * Remember the padding length. We must remove it from the real data
424 * stream once the sign/seal is done.
425 */
426
427 *p_ss_padding_len = auth_info.auth_pad_len;
428
429 return NT_STATUS_OK;
430}
431
432/****************************************************************************
433 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
434 ****************************************************************************/
435
436static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
437 prs_struct *current_pdu,
438 uint8 *p_ss_padding_len)
439{
440 NTSTATUS ret = NT_STATUS_OK;
441
442 /* Paranioa checks for auth_len. */
443 if (prhdr->auth_len) {
444 if (prhdr->auth_len > prhdr->frag_len) {
445 return NT_STATUS_INVALID_PARAMETER;
446 }
447
448 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
449 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
450 /* Integer wrap attempt. */
451 return NT_STATUS_INVALID_PARAMETER;
452 }
453 }
454
455 /*
456 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
457 */
458
459 switch(cli->auth.auth_type) {
460 case PIPE_AUTH_TYPE_NONE:
461 if (prhdr->auth_len) {
462 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
463 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
464 cli->cli->desthost,
465 cli->pipe_name,
466 (unsigned int)cli->fnum,
467 (unsigned int)prhdr->auth_len ));
468 return NT_STATUS_INVALID_PARAMETER;
469 }
470 break;
471
472 case PIPE_AUTH_TYPE_NTLMSSP:
473 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
474 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
475 if (!NT_STATUS_IS_OK(ret)) {
476 return ret;
477 }
478 break;
479
480 case PIPE_AUTH_TYPE_SCHANNEL:
481 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
482 if (!NT_STATUS_IS_OK(ret)) {
483 return ret;
484 }
485 break;
486
487 case PIPE_AUTH_TYPE_KRB5:
488 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
489 default:
490 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
491 "pipe %s fnum %x - unknown internal auth type %u.\n",
492 cli->cli->desthost,
493 cli->pipe_name,
494 (unsigned int)cli->fnum,
495 cli->auth.auth_type ));
496 return NT_STATUS_INVALID_INFO_CLASS;
497 }
498
499 return NT_STATUS_OK;
500}
501
502/****************************************************************************
503 Do basic authentication checks on an incoming pdu.
504 ****************************************************************************/
505
506static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
507 prs_struct *current_pdu,
508 uint8 expected_pkt_type,
509 char **ppdata,
510 uint32 *pdata_len,
511 prs_struct *return_data)
512{
513
514 NTSTATUS ret = NT_STATUS_OK;
515 uint32 current_pdu_len = prs_data_size(current_pdu);
516
517 if (current_pdu_len != prhdr->frag_len) {
518 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
519 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
520 return NT_STATUS_INVALID_PARAMETER;
521 }
522
523 /*
524 * Point the return values at the real data including the RPC
525 * header. Just in case the caller wants it.
526 */
527 *ppdata = prs_data_p(current_pdu);
528 *pdata_len = current_pdu_len;
529
530 /* Ensure we have the correct type. */
531 switch (prhdr->pkt_type) {
532 case RPC_ALTCONTRESP:
533 case RPC_BINDACK:
534
535 /* Alter context and bind ack share the same packet definitions. */
536 break;
537
538
539 case RPC_RESPONSE:
540 {
541 RPC_HDR_RESP rhdr_resp;
542 uint8 ss_padding_len = 0;
543
544 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
545 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
546 return NT_STATUS_BUFFER_TOO_SMALL;
547 }
548
549 /* Here's where we deal with incoming sign/seal. */
550 ret = cli_pipe_validate_rpc_response(cli, prhdr,
551 current_pdu, &ss_padding_len);
552 if (!NT_STATUS_IS_OK(ret)) {
553 return ret;
554 }
555
556 /* Point the return values at the NDR data. Remember to remove any ss padding. */
557 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
558
559 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
560 return NT_STATUS_BUFFER_TOO_SMALL;
561 }
562
563 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
564
565 /* Remember to remove the auth footer. */
566 if (prhdr->auth_len) {
567 /* We've already done integer wrap tests on auth_len in
568 cli_pipe_validate_rpc_response(). */
569 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
570 return NT_STATUS_BUFFER_TOO_SMALL;
571 }
572 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
573 }
574
575 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
576 current_pdu_len, *pdata_len, ss_padding_len ));
577
578 /*
579 * If this is the first reply, and the allocation hint is reasonably, try and
580 * set up the return_data parse_struct to the correct size.
581 */
582
583 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
584 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
585 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
586 "too large to allocate\n",
587 (unsigned int)rhdr_resp.alloc_hint ));
588 return NT_STATUS_NO_MEMORY;
589 }
590 }
591
592 break;
593 }
594
595 case RPC_BINDNACK:
596 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
597 "pipe %s fnum 0x%x!\n",
598 cli->cli->desthost,
599 cli->pipe_name,
600 (unsigned int)cli->fnum));
601 /* Use this for now... */
602 return NT_STATUS_NETWORK_ACCESS_DENIED;
603
604 case RPC_FAULT:
605 {
606 RPC_HDR_RESP rhdr_resp;
607 RPC_HDR_FAULT fault_resp;
608
609 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
610 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
611 return NT_STATUS_BUFFER_TOO_SMALL;
612 }
613
614 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
615 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
616 return NT_STATUS_BUFFER_TOO_SMALL;
617 }
618
619 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
620 "pipe %s fnum 0x%x!\n",
621 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
622 cli->cli->desthost,
623 cli->pipe_name,
624 (unsigned int)cli->fnum));
625 if (NT_STATUS_IS_OK(fault_resp.status)) {
626 return NT_STATUS_UNSUCCESSFUL;
627 } else {
628 return fault_resp.status;
629 }
630
631 }
632
633 default:
634 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
635 "from remote machine %s pipe %s fnum 0x%x!\n",
636 (unsigned int)prhdr->pkt_type,
637 cli->cli->desthost,
638 cli->pipe_name,
639 (unsigned int)cli->fnum));
640 return NT_STATUS_INVALID_INFO_CLASS;
641 }
642
643 if (prhdr->pkt_type != expected_pkt_type) {
644 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
645 "pipe %s fnum %x got an unexpected RPC packet "
646 "type - %u, not %u\n",
647 cli->cli->desthost,
648 cli->pipe_name,
649 (unsigned int)cli->fnum,
650 prhdr->pkt_type,
651 expected_pkt_type));
652 return NT_STATUS_INVALID_INFO_CLASS;
653 }
654
655 /* Do this just before return - we don't want to modify any rpc header
656 data before now as we may have needed to do cryptographic actions on
657 it before. */
658
659 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
660 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
661 "setting fragment first/last ON.\n"));
662 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
663 }
664
665 return NT_STATUS_OK;
666}
667
668/****************************************************************************
669 Ensure we eat the just processed pdu from the current_pdu prs_struct.
670 Normally the frag_len and buffer size will match, but on the first trans
671 reply there is a theoretical chance that buffer size > frag_len, so we must
672 deal with that.
673 ****************************************************************************/
674
675static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
676{
677 uint32 current_pdu_len = prs_data_size(current_pdu);
678
679 if (current_pdu_len < prhdr->frag_len) {
680 return NT_STATUS_BUFFER_TOO_SMALL;
681 }
682
683 /* Common case. */
684 if (current_pdu_len == (uint32)prhdr->frag_len) {
685 prs_mem_free(current_pdu);
686 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
687 /* Make current_pdu dynamic with no memory. */
688 prs_give_memory(current_pdu, 0, 0, True);
689 return NT_STATUS_OK;
690 }
691
692 /*
693 * Oh no ! More data in buffer than we processed in current pdu.
694 * Cheat. Move the data down and shrink the buffer.
695 */
696
697 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
698 current_pdu_len - prhdr->frag_len);
699
700 /* Remember to set the read offset back to zero. */
701 prs_set_offset(current_pdu, 0);
702
703 /* Shrink the buffer. */
704 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
705 return NT_STATUS_BUFFER_TOO_SMALL;
706 }
707
708 return NT_STATUS_OK;
709}
710
711/****************************************************************************
712 Send data on an rpc pipe via trans. The prs_struct data must be the last
713 pdu fragment of an NDR data stream.
714
715 Receive response data from an rpc pipe, which may be large...
716
717 Read the first fragment: unfortunately have to use SMBtrans for the first
718 bit, then SMBreadX for subsequent bits.
719
720 If first fragment received also wasn't the last fragment, continue
721 getting fragments until we _do_ receive the last fragment.
722
723 Request/Response PDU's look like the following...
724
725 |<------------------PDU len----------------------------------------------->|
726 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
727
728 +------------+-----------------+-------------+---------------+-------------+
729 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
730 +------------+-----------------+-------------+---------------+-------------+
731
732 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
733 signing & sealing being negotiated.
734
735 ****************************************************************************/
736
737static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
738 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
739 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
740 uint8 expected_pkt_type)
741{
742 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
743 char *rparam = NULL;
744 uint32 rparam_len = 0;
745 uint16 setup[2];
746 char *pdata = prs_data_p(data);
747 uint32 data_len = prs_offset(data);
748 char *prdata = NULL;
749 uint32 rdata_len = 0;
750 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
751 uint32 current_rbuf_offset = 0;
752 prs_struct current_pdu;
753
754#ifdef DEVELOPER
755 /* Ensure we're not sending too much. */
756 SMB_ASSERT(data_len <= max_data);
757#endif
758
759 /* Set up the current pdu parse struct. */
760 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
761
762 /* Create setup parameters - must be in native byte order. */
763 setup[0] = TRANSACT_DCERPCCMD;
764 setup[1] = cli->fnum; /* Pipe file handle. */
765
766 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
767 cli->cli->desthost,
768 cli->pipe_name,
769 (unsigned int)cli->fnum ));
770
771 /*
772 * Send the last (or only) fragment of an RPC request. For small
773 * amounts of data (about 1024 bytes or so) the RPC request and response
774 * appears in a SMBtrans request and response.
775 */
776
777 if (!cli_api_pipe(cli->cli, "\\PIPE\\",
778 setup, 2, 0, /* Setup, length, max */
779 NULL, 0, 0, /* Params, length, max */
780 pdata, data_len, max_data, /* data, length, max */
781 &rparam, &rparam_len, /* return params, len */
782 &prdata, &rdata_len)) /* return data, len */
783 {
784 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
785 "returned critical error. Error was %s\n",
786 cli->cli->desthost,
787 cli->pipe_name,
788 (unsigned int)cli->fnum,
789 cli_errstr(cli->cli)));
790 ret = cli_get_nt_error(cli->cli);
791 SAFE_FREE(rparam);
792 SAFE_FREE(prdata);
793 goto err;
794 }
795
796 /* Throw away returned params - we know we won't use them. */
797
798 SAFE_FREE(rparam);
799
800 if (prdata == NULL) {
801 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
802 "fnum 0x%x failed to return data.\n",
803 cli->cli->desthost,
804 cli->pipe_name,
805 (unsigned int)cli->fnum));
806 /* Yes - some calls can truely return no data... */
807 prs_mem_free(&current_pdu);
808 return NT_STATUS_OK;
809 }
810
811 /*
812 * Give this memory as dynamic to the current pdu.
813 */
814
815 prs_give_memory(&current_pdu, prdata, rdata_len, True);
816
817 /* Ensure we can mess with the return prs_struct. */
818 SMB_ASSERT(UNMARSHALLING(rbuf));
819 SMB_ASSERT(prs_data_size(rbuf) == 0);
820
821 /* Make rbuf dynamic with no memory. */
822 prs_give_memory(rbuf, 0, 0, True);
823
824 while(1) {
825 RPC_HDR rhdr;
826 char *ret_data = NULL;
827 uint32 ret_data_len = 0;
828
829 /* Ensure we have enough data for a pdu. */
830 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
831 if (!NT_STATUS_IS_OK(ret)) {
832 goto err;
833 }
834
835 /* We pass in rbuf here so if the alloc hint is set correctly
836 we can set the output size and avoid reallocs. */
837
838 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
839 &ret_data, &ret_data_len, rbuf);
840
841 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
842 prs_data_size(&current_pdu), current_rbuf_offset ));
843
844 if (!NT_STATUS_IS_OK(ret)) {
845 goto err;
846 }
847
848 if ((rhdr.flags & RPC_FLG_FIRST)) {
849 if (rhdr.pack_type[0] == 0) {
850 /* Set the data type correctly for big-endian data on the first packet. */
851 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
852 "PDU data format is big-endian.\n",
853 cli->cli->desthost,
854 cli->pipe_name,
855 (unsigned int)cli->fnum));
856
857 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
858 } else {
859 /* Check endianness on subsequent packets. */
860 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
861 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
862 rbuf->bigendian_data ? "big" : "little",
863 current_pdu.bigendian_data ? "big" : "little" ));
864 ret = NT_STATUS_INVALID_PARAMETER;
865 goto err;
866 }
867 }
868 }
869
870 /* Now copy the data portion out of the pdu into rbuf. */
871 if (!prs_force_grow(rbuf, ret_data_len)) {
872 ret = NT_STATUS_NO_MEMORY;
873 goto err;
874 }
875 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
876 current_rbuf_offset += ret_data_len;
877
878 /* See if we've finished with all the data in current_pdu yet ? */
879 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
880 if (!NT_STATUS_IS_OK(ret)) {
881 goto err;
882 }
883
884 if (rhdr.flags & RPC_FLG_LAST) {
885 break; /* We're done. */
886 }
887 }
888
889 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
890 cli->cli->desthost,
891 cli->pipe_name,
892 (unsigned int)cli->fnum,
893 (unsigned int)prs_data_size(rbuf) ));
894
895 prs_mem_free(&current_pdu);
896 return NT_STATUS_OK;
897
898 err:
899
900 prs_mem_free(&current_pdu);
901 prs_mem_free(rbuf);
902 return ret;
903}
904
905/*******************************************************************
906 Creates krb5 auth bind.
907 ********************************************************************/
908
909static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
910 enum pipe_auth_level auth_level,
911 RPC_HDR_AUTH *pauth_out,
912 prs_struct *auth_data)
913{
914#ifdef HAVE_KRB5
915 int ret;
916 struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
917 DATA_BLOB tkt = data_blob_null;
918 DATA_BLOB tkt_wrapped = data_blob_null;
919
920 /* We may change the pad length before marshalling. */
921 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
922
923 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
924 a->service_principal ));
925
926 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
927
928 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
929 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
930
931 if (ret) {
932 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
933 "failed with %s\n",
934 a->service_principal,
935 error_message(ret) ));
936
937 data_blob_free(&tkt);
938 prs_mem_free(auth_data);
939 return NT_STATUS_INVALID_PARAMETER;
940 }
941
942 /* wrap that up in a nice GSS-API wrapping */
943 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
944
945 data_blob_free(&tkt);
946
947 /* Auth len in the rpc header doesn't include auth_header. */
948 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
949 data_blob_free(&tkt_wrapped);
950 prs_mem_free(auth_data);
951 return NT_STATUS_NO_MEMORY;
952 }
953
954 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
955 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
956
957 data_blob_free(&tkt_wrapped);
958 return NT_STATUS_OK;
959#else
960 return NT_STATUS_INVALID_PARAMETER;
961#endif
962}
963
964/*******************************************************************
965 Creates SPNEGO NTLMSSP auth bind.
966 ********************************************************************/
967
968static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
969 enum pipe_auth_level auth_level,
970 RPC_HDR_AUTH *pauth_out,
971 prs_struct *auth_data)
972{
973 NTSTATUS nt_status;
974 DATA_BLOB null_blob = data_blob_null;
975 DATA_BLOB request = data_blob_null;
976 DATA_BLOB spnego_msg = data_blob_null;
977
978 /* We may change the pad length before marshalling. */
979 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
980
981 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
982 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
983 null_blob,
984 &request);
985
986 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
987 data_blob_free(&request);
988 prs_mem_free(auth_data);
989 return nt_status;
990 }
991
992 /* Wrap this in SPNEGO. */
993 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
994
995 data_blob_free(&request);
996
997 /* Auth len in the rpc header doesn't include auth_header. */
998 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
999 data_blob_free(&spnego_msg);
1000 prs_mem_free(auth_data);
1001 return NT_STATUS_NO_MEMORY;
1002 }
1003
1004 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1005 dump_data(5, spnego_msg.data, spnego_msg.length);
1006
1007 data_blob_free(&spnego_msg);
1008 return NT_STATUS_OK;
1009}
1010
1011/*******************************************************************
1012 Creates NTLMSSP auth bind.
1013 ********************************************************************/
1014
1015static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1016 enum pipe_auth_level auth_level,
1017 RPC_HDR_AUTH *pauth_out,
1018 prs_struct *auth_data)
1019{
1020 NTSTATUS nt_status;
1021 DATA_BLOB null_blob = data_blob_null;
1022 DATA_BLOB request = data_blob_null;
1023
1024 /* We may change the pad length before marshalling. */
1025 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1026
1027 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1028 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1029 null_blob,
1030 &request);
1031
1032 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033 data_blob_free(&request);
1034 prs_mem_free(auth_data);
1035 return nt_status;
1036 }
1037
1038 /* Auth len in the rpc header doesn't include auth_header. */
1039 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1040 data_blob_free(&request);
1041 prs_mem_free(auth_data);
1042 return NT_STATUS_NO_MEMORY;
1043 }
1044
1045 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1046 dump_data(5, request.data, request.length);
1047
1048 data_blob_free(&request);
1049 return NT_STATUS_OK;
1050}
1051
1052/*******************************************************************
1053 Creates schannel auth bind.
1054 ********************************************************************/
1055
1056static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1057 enum pipe_auth_level auth_level,
1058 RPC_HDR_AUTH *pauth_out,
1059 prs_struct *auth_data)
1060{
1061 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1062
1063 /* We may change the pad length before marshalling. */
1064 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1065
1066 /* Use lp_workgroup() if domain not specified */
1067
1068 if (!cli->domain || !cli->domain[0]) {
1069 cli->domain = lp_workgroup();
1070 }
1071
1072 init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1073
1074 /*
1075 * Now marshall the data into the auth parse_struct.
1076 */
1077
1078 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1079 &schannel_neg, auth_data, 0)) {
1080 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1081 prs_mem_free(auth_data);
1082 return NT_STATUS_NO_MEMORY;
1083 }
1084
1085 return NT_STATUS_OK;
1086}
1087
1088/*******************************************************************
1089 Creates the internals of a DCE/RPC bind request or alter context PDU.
1090 ********************************************************************/
1091
1092static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1093 prs_struct *rpc_out,
1094 uint32 rpc_call_id,
1095 RPC_IFACE *abstract,
1096 RPC_IFACE *transfer,
1097 RPC_HDR_AUTH *phdr_auth,
1098 prs_struct *pauth_info)
1099{
1100 RPC_HDR hdr;
1101 RPC_HDR_RB hdr_rb;
1102 RPC_CONTEXT rpc_ctx;
1103 uint16 auth_len = prs_offset(pauth_info);
1104 uint8 ss_padding_len = 0;
1105 uint16 frag_len = 0;
1106
1107 /* create the RPC context. */
1108 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1109
1110 /* create the bind request RPC_HDR_RB */
1111 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1112
1113 /* Start building the frag length. */
1114 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1115
1116 /* Do we need to pad ? */
1117 if (auth_len) {
1118 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1119 if (data_len % 8) {
1120 ss_padding_len = 8 - (data_len % 8);
1121 phdr_auth->auth_pad_len = ss_padding_len;
1122 }
1123 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1124 }
1125
1126 /* Create the request RPC_HDR */
1127 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1128
1129 /* Marshall the RPC header */
1130 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1131 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1132 return NT_STATUS_NO_MEMORY;
1133 }
1134
1135 /* Marshall the bind request data */
1136 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1137 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1138 return NT_STATUS_NO_MEMORY;
1139 }
1140
1141 /*
1142 * Grow the outgoing buffer to store any auth info.
1143 */
1144
1145 if(auth_len != 0) {
1146 if (ss_padding_len) {
1147 char pad[8];
1148 memset(pad, '\0', 8);
1149 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1150 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1151 return NT_STATUS_NO_MEMORY;
1152 }
1153 }
1154
1155 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1156 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1157 return NT_STATUS_NO_MEMORY;
1158 }
1159
1160
1161 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1162 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1163 return NT_STATUS_NO_MEMORY;
1164 }
1165 }
1166
1167 return NT_STATUS_OK;
1168}
1169
1170/*******************************************************************
1171 Creates a DCE/RPC bind request.
1172 ********************************************************************/
1173
1174static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1175 prs_struct *rpc_out,
1176 uint32 rpc_call_id,
1177 RPC_IFACE *abstract, RPC_IFACE *transfer,
1178 enum pipe_auth_type auth_type,
1179 enum pipe_auth_level auth_level)
1180{
1181 RPC_HDR_AUTH hdr_auth;
1182 prs_struct auth_info;
1183 NTSTATUS ret = NT_STATUS_OK;
1184
1185 ZERO_STRUCT(hdr_auth);
1186 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1187 return NT_STATUS_NO_MEMORY;
1188
1189 switch (auth_type) {
1190 case PIPE_AUTH_TYPE_SCHANNEL:
1191 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1192 if (!NT_STATUS_IS_OK(ret)) {
1193 prs_mem_free(&auth_info);
1194 return ret;
1195 }
1196 break;
1197
1198 case PIPE_AUTH_TYPE_NTLMSSP:
1199 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1200 if (!NT_STATUS_IS_OK(ret)) {
1201 prs_mem_free(&auth_info);
1202 return ret;
1203 }
1204 break;
1205
1206 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1207 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1208 if (!NT_STATUS_IS_OK(ret)) {
1209 prs_mem_free(&auth_info);
1210 return ret;
1211 }
1212 break;
1213
1214 case PIPE_AUTH_TYPE_KRB5:
1215 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1216 if (!NT_STATUS_IS_OK(ret)) {
1217 prs_mem_free(&auth_info);
1218 return ret;
1219 }
1220 break;
1221
1222 case PIPE_AUTH_TYPE_NONE:
1223 break;
1224
1225 default:
1226 /* "Can't" happen. */
1227 return NT_STATUS_INVALID_INFO_CLASS;
1228 }
1229
1230 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1231 rpc_out,
1232 rpc_call_id,
1233 abstract,
1234 transfer,
1235 &hdr_auth,
1236 &auth_info);
1237
1238 prs_mem_free(&auth_info);
1239 return ret;
1240}
1241
1242/*******************************************************************
1243 Create and add the NTLMSSP sign/seal auth header and data.
1244 ********************************************************************/
1245
1246static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1247 RPC_HDR *phdr,
1248 uint32 ss_padding_len,
1249 prs_struct *outgoing_pdu)
1250{
1251 RPC_HDR_AUTH auth_info;
1252 NTSTATUS status;
1253 DATA_BLOB auth_blob = data_blob_null;
1254 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1255
1256 if (!cli->auth.a_u.ntlmssp_state) {
1257 return NT_STATUS_INVALID_PARAMETER;
1258 }
1259
1260 /* Init and marshall the auth header. */
1261 init_rpc_hdr_auth(&auth_info,
1262 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1263 cli->auth.auth_level,
1264 ss_padding_len,
1265 1 /* context id. */);
1266
1267 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1268 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1269 data_blob_free(&auth_blob);
1270 return NT_STATUS_NO_MEMORY;
1271 }
1272
1273 switch (cli->auth.auth_level) {
1274 case PIPE_AUTH_LEVEL_PRIVACY:
1275 /* Data portion is encrypted. */
1276 status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
1277 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1278 data_and_pad_len,
1279 (unsigned char *)prs_data_p(outgoing_pdu),
1280 (size_t)prs_offset(outgoing_pdu),
1281 &auth_blob);
1282 if (!NT_STATUS_IS_OK(status)) {
1283 data_blob_free(&auth_blob);
1284 return status;
1285 }
1286 break;
1287
1288 case PIPE_AUTH_LEVEL_INTEGRITY:
1289 /* Data is signed. */
1290 status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
1291 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1292 data_and_pad_len,
1293 (unsigned char *)prs_data_p(outgoing_pdu),
1294 (size_t)prs_offset(outgoing_pdu),
1295 &auth_blob);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 data_blob_free(&auth_blob);
1298 return status;
1299 }
1300 break;
1301
1302 default:
1303 /* Can't happen. */
1304 smb_panic("bad auth level");
1305 /* Notreached. */
1306 return NT_STATUS_INVALID_PARAMETER;
1307 }
1308
1309 /* Finally marshall the blob. */
1310
1311 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1312 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1313 (unsigned int)NTLMSSP_SIG_SIZE));
1314 data_blob_free(&auth_blob);
1315 return NT_STATUS_NO_MEMORY;
1316 }
1317
1318 data_blob_free(&auth_blob);
1319 return NT_STATUS_OK;
1320}
1321
1322/*******************************************************************
1323 Create and add the schannel sign/seal auth header and data.
1324 ********************************************************************/
1325
1326static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1327 RPC_HDR *phdr,
1328 uint32 ss_padding_len,
1329 prs_struct *outgoing_pdu)
1330{
1331 RPC_HDR_AUTH auth_info;
1332 RPC_AUTH_SCHANNEL_CHK verf;
1333 struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
1334 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1335 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1336
1337 if (!sas) {
1338 return NT_STATUS_INVALID_PARAMETER;
1339 }
1340
1341 /* Init and marshall the auth header. */
1342 init_rpc_hdr_auth(&auth_info,
1343 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1344 cli->auth.auth_level,
1345 ss_padding_len,
1346 1 /* context id. */);
1347
1348 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1349 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1350 return NT_STATUS_NO_MEMORY;
1351 }
1352
1353 switch (cli->auth.auth_level) {
1354 case PIPE_AUTH_LEVEL_PRIVACY:
1355 case PIPE_AUTH_LEVEL_INTEGRITY:
1356 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1357 sas->seq_num));
1358
1359 schannel_encode(sas,
1360 cli->auth.auth_level,
1361 SENDER_IS_INITIATOR,
1362 &verf,
1363 data_p,
1364 data_and_pad_len);
1365
1366 sas->seq_num++;
1367 break;
1368
1369 default:
1370 /* Can't happen. */
1371 smb_panic("bad auth level");
1372 /* Notreached. */
1373 return NT_STATUS_INVALID_PARAMETER;
1374 }
1375
1376 /* Finally marshall the blob. */
1377 smb_io_rpc_auth_schannel_chk("",
1378 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1379 &verf,
1380 outgoing_pdu,
1381 0);
1382
1383 return NT_STATUS_OK;
1384}
1385
1386/*******************************************************************
1387 Calculate how much data we're going to send in this packet, also
1388 work out any sign/seal padding length.
1389 ********************************************************************/
1390
1391static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1392 uint32 data_left,
1393 uint16 *p_frag_len,
1394 uint16 *p_auth_len,
1395 uint32 *p_ss_padding)
1396{
1397 uint32 data_space, data_len;
1398
1399 switch (cli->auth.auth_level) {
1400 case PIPE_AUTH_LEVEL_NONE:
1401 case PIPE_AUTH_LEVEL_CONNECT:
1402 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1403 data_len = MIN(data_space, data_left);
1404 *p_ss_padding = 0;
1405 *p_auth_len = 0;
1406 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1407 return data_len;
1408
1409 case PIPE_AUTH_LEVEL_INTEGRITY:
1410 case PIPE_AUTH_LEVEL_PRIVACY:
1411 /* Treat the same for all authenticated rpc requests. */
1412 switch(cli->auth.auth_type) {
1413 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1414 case PIPE_AUTH_TYPE_NTLMSSP:
1415 *p_auth_len = NTLMSSP_SIG_SIZE;
1416 break;
1417 case PIPE_AUTH_TYPE_SCHANNEL:
1418 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1419 break;
1420 default:
1421 smb_panic("bad auth type");
1422 break;
1423 }
1424
1425 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1426 RPC_HDR_AUTH_LEN - *p_auth_len;
1427
1428 data_len = MIN(data_space, data_left);
1429 if (data_len % 8) {
1430 *p_ss_padding = 8 - (data_len % 8);
1431 }
1432 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1433 data_len + *p_ss_padding + /* data plus padding. */
1434 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1435 return data_len;
1436
1437 default:
1438 smb_panic("bad auth level");
1439 /* Notreached. */
1440 return 0;
1441 }
1442}
1443
1444/*******************************************************************
1445 External interface.
1446 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1447 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1448 and deals with signing/sealing details.
1449 ********************************************************************/
1450
1451NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1452 uint8 op_num,
1453 prs_struct *in_data,
1454 prs_struct *out_data)
1455{
1456 NTSTATUS ret;
1457 uint32 data_left = prs_offset(in_data);
1458 uint32 alloc_hint = prs_offset(in_data);
1459 uint32 data_sent_thistime = 0;
1460 uint32 current_data_offset = 0;
1461 uint32 call_id = get_rpc_call_id();
1462 char pad[8];
1463 prs_struct outgoing_pdu;
1464
1465 memset(pad, '\0', 8);
1466
1467 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1468 /* Server is screwed up ! */
1469 return NT_STATUS_INVALID_PARAMETER;
1470 }
1471
1472 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1473 return NT_STATUS_NO_MEMORY;
1474
1475 while (1) {
1476 RPC_HDR hdr;
1477 RPC_HDR_REQ hdr_req;
1478 uint16 auth_len = 0;
1479 uint16 frag_len = 0;
1480 uint8 flags = 0;
1481 uint32 ss_padding = 0;
1482
1483 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1484 &frag_len, &auth_len, &ss_padding);
1485
1486 if (current_data_offset == 0) {
1487 flags = RPC_FLG_FIRST;
1488 }
1489
1490 if (data_sent_thistime == data_left) {
1491 flags |= RPC_FLG_LAST;
1492 }
1493
1494 /* Create and marshall the header and request header. */
1495 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1496
1497 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1498 prs_mem_free(&outgoing_pdu);
1499 return NT_STATUS_NO_MEMORY;
1500 }
1501
1502 /* Create the rpc request RPC_HDR_REQ */
1503 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1504
1505 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1506 prs_mem_free(&outgoing_pdu);
1507 return NT_STATUS_NO_MEMORY;
1508 }
1509
1510 /* Copy in the data, plus any ss padding. */
1511 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1512 prs_mem_free(&outgoing_pdu);
1513 return NT_STATUS_NO_MEMORY;
1514 }
1515
1516 /* Copy the sign/seal padding data. */
1517 if (ss_padding) {
1518 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1519 prs_mem_free(&outgoing_pdu);
1520 return NT_STATUS_NO_MEMORY;
1521 }
1522 }
1523
1524 /* Generate any auth sign/seal and add the auth footer. */
1525 if (auth_len) {
1526 switch (cli->auth.auth_type) {
1527 case PIPE_AUTH_TYPE_NONE:
1528 break;
1529 case PIPE_AUTH_TYPE_NTLMSSP:
1530 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1531 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1532 if (!NT_STATUS_IS_OK(ret)) {
1533 prs_mem_free(&outgoing_pdu);
1534 return ret;
1535 }
1536 break;
1537 case PIPE_AUTH_TYPE_SCHANNEL:
1538 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1539 if (!NT_STATUS_IS_OK(ret)) {
1540 prs_mem_free(&outgoing_pdu);
1541 return ret;
1542 }
1543 break;
1544 default:
1545 smb_panic("bad auth type");
1546 break; /* notreached */
1547 }
1548 }
1549
1550 /* Actually send the packet. */
1551 if (flags & RPC_FLG_LAST) {
1552 /* Last packet - send the data, get the reply and return. */
1553 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1554 prs_mem_free(&outgoing_pdu);
1555
1556 if (DEBUGLEVEL >= 50) {
1557 char *dump_name = NULL;
1558 /* Also capture received data */
1559 if (asprintf(&dump_name, "%s/reply_%s_%d",
1560 get_dyn_LOGFILEBASE(), cli->pipe_name,
1561 op_num) > 0) {
1562 prs_dump(dump_name, op_num, out_data);
1563 SAFE_FREE(dump_name);
1564 }
1565 }
1566
1567 return ret;
1568 } else {
1569 /* More packets to come - write and continue. */
1570 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1571 prs_data_p(&outgoing_pdu),
1572 (off_t)0,
1573 (size_t)hdr.frag_len);
1574
1575 if (num_written != hdr.frag_len) {
1576 prs_mem_free(&outgoing_pdu);
1577 return cli_get_nt_error(cli->cli);
1578 }
1579 }
1580
1581 current_data_offset += data_sent_thistime;
1582 data_left -= data_sent_thistime;
1583
1584 /* Reset the marshalling position back to zero. */
1585 if (!prs_set_offset(&outgoing_pdu, 0)) {
1586 prs_mem_free(&outgoing_pdu);
1587 return NT_STATUS_NO_MEMORY;
1588 }
1589 }
1590}
1591#if 0
1592/****************************************************************************
1593 Set the handle state.
1594****************************************************************************/
1595
1596static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1597 const char *pipe_name, uint16 device_state)
1598{
1599 bool state_set = False;
1600 char param[2];
1601 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1602 char *rparam = NULL;
1603 char *rdata = NULL;
1604 uint32 rparam_len, rdata_len;
1605
1606 if (pipe_name == NULL)
1607 return False;
1608
1609 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1610 cli->fnum, pipe_name, device_state));
1611
1612 /* create parameters: device state */
1613 SSVAL(param, 0, device_state);
1614
1615 /* create setup parameters. */
1616 setup[0] = 0x0001;
1617 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1618
1619 /* send the data on \PIPE\ */
1620 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1621 setup, 2, 0, /* setup, length, max */
1622 param, 2, 0, /* param, length, max */
1623 NULL, 0, 1024, /* data, length, max */
1624 &rparam, &rparam_len, /* return param, length */
1625 &rdata, &rdata_len)) /* return data, length */
1626 {
1627 DEBUG(5, ("Set Handle state: return OK\n"));
1628 state_set = True;
1629 }
1630
1631 SAFE_FREE(rparam);
1632 SAFE_FREE(rdata);
1633
1634 return state_set;
1635}
1636#endif
1637
1638/****************************************************************************
1639 Check the rpc bind acknowledge response.
1640****************************************************************************/
1641
1642static bool valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
1643{
1644 if ( pipe_idx >= PI_MAX_PIPES ) {
1645 DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n",
1646 pipe_idx));
1647 return False;
1648 }
1649
1650 DEBUG(5,("Bind Abstract Syntax: "));
1651 dump_data(5, (uint8 *)&pipe_names[pipe_idx].abstr_syntax,
1652 sizeof(pipe_names[pipe_idx].abstr_syntax));
1653 DEBUG(5,("Bind Transfer Syntax: "));
1654 dump_data(5, (uint8 *)&pipe_names[pipe_idx].trans_syntax,
1655 sizeof(pipe_names[pipe_idx].trans_syntax));
1656
1657 /* copy the required syntaxes out so we can do the right bind */
1658
1659 *transfer = pipe_names[pipe_idx].trans_syntax;
1660 *abstract = pipe_names[pipe_idx].abstr_syntax;
1661
1662 return True;
1663}
1664
1665/****************************************************************************
1666 Check the rpc bind acknowledge response.
1667****************************************************************************/
1668
1669static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
1670{
1671 if ( hdr_ba->addr.len == 0) {
1672 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1673 }
1674
1675# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
1676 if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
1677 !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
1678 {
1679 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
1680 pipe_names[i].server_pipe ,hdr_ba->addr.str));
1681 return False;
1682 }
1683
1684 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe ));
1685
1686 if (pipe_names[pipe_idx].server_pipe == NULL) {
1687 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
1688 return False;
1689 }
1690#endif /* JERRY */
1691
1692 /* check the transfer syntax */
1693 if ((hdr_ba->transfer.version != transfer->version) ||
1694 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1695 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1696 return False;
1697 }
1698
1699 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1700 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1701 hdr_ba->res.num_results, hdr_ba->res.reason));
1702 }
1703
1704 DEBUG(5,("check_bind_response: accepted!\n"));
1705 return True;
1706}
1707
1708/*******************************************************************
1709 Creates a DCE/RPC bind authentication response.
1710 This is the packet that is sent back to the server once we
1711 have received a BIND-ACK, to finish the third leg of
1712 the authentication handshake.
1713 ********************************************************************/
1714
1715static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1716 uint32 rpc_call_id,
1717 enum pipe_auth_type auth_type,
1718 enum pipe_auth_level auth_level,
1719 DATA_BLOB *pauth_blob,
1720 prs_struct *rpc_out)
1721{
1722 RPC_HDR hdr;
1723 RPC_HDR_AUTH hdr_auth;
1724 uint32 pad = 0;
1725
1726 /* Create the request RPC_HDR */
1727 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1728 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1729 pauth_blob->length );
1730
1731 /* Marshall it. */
1732 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1733 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1734 return NT_STATUS_NO_MEMORY;
1735 }
1736
1737 /*
1738 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1739 about padding - shouldn't this pad to length 8 ? JRA.
1740 */
1741
1742 /* 4 bytes padding. */
1743 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1744 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1745 return NT_STATUS_NO_MEMORY;
1746 }
1747
1748 /* Create the request RPC_HDR_AUTHA */
1749 init_rpc_hdr_auth(&hdr_auth,
1750 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1751 auth_level, 0, 1);
1752
1753 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1754 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1755 return NT_STATUS_NO_MEMORY;
1756 }
1757
1758 /*
1759 * Append the auth data to the outgoing buffer.
1760 */
1761
1762 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1763 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1764 return NT_STATUS_NO_MEMORY;
1765 }
1766
1767 return NT_STATUS_OK;
1768}
1769
1770/****************************************************************************
1771 Create and send the third packet in an RPC auth.
1772****************************************************************************/
1773
1774static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1775 RPC_HDR *phdr,
1776 prs_struct *rbuf,
1777 uint32 rpc_call_id,
1778 enum pipe_auth_type auth_type,
1779 enum pipe_auth_level auth_level)
1780{
1781 DATA_BLOB server_response = data_blob_null;
1782 DATA_BLOB client_reply = data_blob_null;
1783 RPC_HDR_AUTH hdr_auth;
1784 NTSTATUS nt_status;
1785 prs_struct rpc_out;
1786 ssize_t ret;
1787
1788 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1789 return NT_STATUS_INVALID_PARAMETER;
1790 }
1791
1792 /* Process the returned NTLMSSP blob first. */
1793 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1794 return NT_STATUS_INVALID_PARAMETER;
1795 }
1796
1797 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1798 return NT_STATUS_INVALID_PARAMETER;
1799 }
1800
1801 /* TODO - check auth_type/auth_level match. */
1802
1803 server_response = data_blob(NULL, phdr->auth_len);
1804 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1805
1806 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1807 server_response,
1808 &client_reply);
1809
1810 if (!NT_STATUS_IS_OK(nt_status)) {
1811 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1812 data_blob_free(&server_response);
1813 return nt_status;
1814 }
1815
1816 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1817
1818 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1819 auth_type, auth_level,
1820 &client_reply, &rpc_out);
1821
1822 if (!NT_STATUS_IS_OK(nt_status)) {
1823 prs_mem_free(&rpc_out);
1824 data_blob_free(&client_reply);
1825 data_blob_free(&server_response);
1826 return nt_status;
1827 }
1828
1829 /* 8 here is named pipe message mode. */
1830 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1831 (size_t)prs_offset(&rpc_out));
1832
1833 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1834 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1835 prs_mem_free(&rpc_out);
1836 data_blob_free(&client_reply);
1837 data_blob_free(&server_response);
1838 return cli_get_nt_error(cli->cli);
1839 }
1840
1841 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1842 "fnum 0x%x sent auth3 response ok.\n",
1843 cli->cli->desthost,
1844 cli->pipe_name,
1845 (unsigned int)cli->fnum));
1846
1847 prs_mem_free(&rpc_out);
1848 data_blob_free(&client_reply);
1849 data_blob_free(&server_response);
1850 return NT_STATUS_OK;
1851}
1852
1853/*******************************************************************
1854 Creates a DCE/RPC bind alter context authentication request which
1855 may contain a spnego auth blobl
1856 ********************************************************************/
1857
1858static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1859 RPC_IFACE *abstract,
1860 RPC_IFACE *transfer,
1861 enum pipe_auth_level auth_level,
1862 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1863 prs_struct *rpc_out)
1864{
1865 RPC_HDR_AUTH hdr_auth;
1866 prs_struct auth_info;
1867 NTSTATUS ret = NT_STATUS_OK;
1868
1869 ZERO_STRUCT(hdr_auth);
1870 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1871 return NT_STATUS_NO_MEMORY;
1872
1873 /* We may change the pad length before marshalling. */
1874 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1875
1876 if (pauth_blob->length) {
1877 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1878 prs_mem_free(&auth_info);
1879 return NT_STATUS_NO_MEMORY;
1880 }
1881 }
1882
1883 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1884 rpc_out,
1885 rpc_call_id,
1886 abstract,
1887 transfer,
1888 &hdr_auth,
1889 &auth_info);
1890 prs_mem_free(&auth_info);
1891 return ret;
1892}
1893
1894/*******************************************************************
1895 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1896 and gets a response.
1897 ********************************************************************/
1898
1899static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1900 RPC_HDR *phdr,
1901 prs_struct *rbuf,
1902 uint32 rpc_call_id,
1903 RPC_IFACE *abstract,
1904 RPC_IFACE *transfer,
1905 enum pipe_auth_type auth_type,
1906 enum pipe_auth_level auth_level)
1907{
1908 DATA_BLOB server_spnego_response = data_blob_null;
1909 DATA_BLOB server_ntlm_response = data_blob_null;
1910 DATA_BLOB client_reply = data_blob_null;
1911 DATA_BLOB tmp_blob = data_blob_null;
1912 RPC_HDR_AUTH hdr_auth;
1913 NTSTATUS nt_status;
1914 prs_struct rpc_out;
1915
1916 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1917 return NT_STATUS_INVALID_PARAMETER;
1918 }
1919
1920 /* Process the returned NTLMSSP blob first. */
1921 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1922 return NT_STATUS_INVALID_PARAMETER;
1923 }
1924
1925 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1926 return NT_STATUS_INVALID_PARAMETER;
1927 }
1928
1929 server_spnego_response = data_blob(NULL, phdr->auth_len);
1930 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1931
1932 /* The server might give us back two challenges - tmp_blob is for the second. */
1933 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1934 data_blob_free(&server_spnego_response);
1935 data_blob_free(&server_ntlm_response);
1936 data_blob_free(&tmp_blob);
1937 return NT_STATUS_INVALID_PARAMETER;
1938 }
1939
1940 /* We're finished with the server spnego response and the tmp_blob. */
1941 data_blob_free(&server_spnego_response);
1942 data_blob_free(&tmp_blob);
1943
1944 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1945 server_ntlm_response,
1946 &client_reply);
1947
1948 /* Finished with the server_ntlm response */
1949 data_blob_free(&server_ntlm_response);
1950
1951 if (!NT_STATUS_IS_OK(nt_status)) {
1952 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1953 data_blob_free(&client_reply);
1954 return nt_status;
1955 }
1956
1957 /* SPNEGO wrap the client reply. */
1958 tmp_blob = spnego_gen_auth(client_reply);
1959 data_blob_free(&client_reply);
1960 client_reply = tmp_blob;
1961 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1962
1963 /* Now prepare the alter context pdu. */
1964 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1965
1966 nt_status = create_rpc_alter_context(rpc_call_id,
1967 abstract,
1968 transfer,
1969 auth_level,
1970 &client_reply,
1971 &rpc_out);
1972
1973 data_blob_free(&client_reply);
1974
1975 if (!NT_STATUS_IS_OK(nt_status)) {
1976 prs_mem_free(&rpc_out);
1977 return nt_status;
1978 }
1979
1980 /* Initialize the returning data struct. */
1981 prs_mem_free(rbuf);
1982 prs_init_empty(rbuf, cli->mem_ctx, UNMARSHALL);
1983
1984 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1985 if (!NT_STATUS_IS_OK(nt_status)) {
1986 prs_mem_free(&rpc_out);
1987 return nt_status;
1988 }
1989
1990 prs_mem_free(&rpc_out);
1991
1992 /* Get the auth blob from the reply. */
1993 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
1994 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1995 return NT_STATUS_BUFFER_TOO_SMALL;
1996 }
1997
1998 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1999 return NT_STATUS_INVALID_PARAMETER;
2000 }
2001
2002 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2003 return NT_STATUS_INVALID_PARAMETER;
2004 }
2005
2006 server_spnego_response = data_blob(NULL, phdr->auth_len);
2007 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2008
2009 /* Check we got a valid auth response. */
2010 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2011 data_blob_free(&server_spnego_response);
2012 data_blob_free(&tmp_blob);
2013 return NT_STATUS_INVALID_PARAMETER;
2014 }
2015
2016 data_blob_free(&server_spnego_response);
2017 data_blob_free(&tmp_blob);
2018
2019 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2020 "remote machine %s pipe %s fnum 0x%x.\n",
2021 cli->cli->desthost,
2022 cli->pipe_name,
2023 (unsigned int)cli->fnum));
2024
2025 return NT_STATUS_OK;
2026}
2027
2028/****************************************************************************
2029 Do an rpc bind.
2030****************************************************************************/
2031
2032static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2033 enum pipe_auth_type auth_type,
2034 enum pipe_auth_level auth_level)
2035{
2036 RPC_HDR hdr;
2037 RPC_HDR_BA hdr_ba;
2038 RPC_IFACE abstract;
2039 RPC_IFACE transfer;
2040 prs_struct rpc_out;
2041 prs_struct rbuf;
2042 uint32 rpc_call_id;
2043 NTSTATUS status;
2044
2045 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2046 (unsigned int)cli->fnum,
2047 cli->pipe_name,
2048 (unsigned int)auth_type,
2049 (unsigned int)auth_level ));
2050
2051 if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
2052 return NT_STATUS_INVALID_PARAMETER;
2053 }
2054
2055 prs_init_empty(&rpc_out, cli->mem_ctx, MARSHALL);
2056
2057 rpc_call_id = get_rpc_call_id();
2058
2059 /* Marshall the outgoing data. */
2060 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2061 &abstract, &transfer,
2062 auth_type,
2063 auth_level);
2064
2065 if (!NT_STATUS_IS_OK(status)) {
2066 prs_mem_free(&rpc_out);
2067 return status;
2068 }
2069
2070 /* Initialize the incoming data struct. */
2071 prs_init_empty(&rbuf, cli->mem_ctx, UNMARSHALL);
2072
2073 /* send data on \PIPE\. receive a response */
2074 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2075 if (!NT_STATUS_IS_OK(status)) {
2076 prs_mem_free(&rpc_out);
2077 return status;
2078 }
2079
2080 prs_mem_free(&rpc_out);
2081
2082 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2083 "fnum 0x%x bind request returned ok.\n",
2084 cli->cli->desthost,
2085 cli->pipe_name,
2086 (unsigned int)cli->fnum));
2087
2088 /* Unmarshall the RPC header */
2089 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2090 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2091 prs_mem_free(&rbuf);
2092 return NT_STATUS_BUFFER_TOO_SMALL;
2093 }
2094
2095 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2096 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2097 prs_mem_free(&rbuf);
2098 return NT_STATUS_BUFFER_TOO_SMALL;
2099 }
2100
2101 if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
2102 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2103 prs_mem_free(&rbuf);
2104 return NT_STATUS_BUFFER_TOO_SMALL;
2105 }
2106
2107 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2108 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2109
2110 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2111 switch(auth_type) {
2112
2113 case PIPE_AUTH_TYPE_NONE:
2114 case PIPE_AUTH_TYPE_SCHANNEL:
2115 /* Bind complete. */
2116 break;
2117
2118 case PIPE_AUTH_TYPE_NTLMSSP:
2119 /* Need to send AUTH3 packet - no reply. */
2120 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2121 auth_type, auth_level);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 prs_mem_free(&rbuf);
2124 return status;
2125 }
2126 break;
2127
2128 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2129 /* Need to send alter context request and reply. */
2130 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2131 &abstract, &transfer,
2132 auth_type, auth_level);
2133 if (!NT_STATUS_IS_OK(status)) {
2134 prs_mem_free(&rbuf);
2135 return status;
2136 }
2137 break;
2138
2139 case PIPE_AUTH_TYPE_KRB5:
2140 /* */
2141
2142 default:
2143 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2144 (unsigned int)auth_type ));
2145 prs_mem_free(&rbuf);
2146 return NT_STATUS_INVALID_INFO_CLASS;
2147 }
2148
2149 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2150 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2151 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2152 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2153 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2154 prs_mem_free(&rbuf);
2155 return NT_STATUS_INVALID_PARAMETER;
2156 }
2157 }
2158 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2159 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2160 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2161 prs_mem_free(&rbuf);
2162 return NT_STATUS_INVALID_PARAMETER;
2163 }
2164 }
2165 }
2166
2167 /* Pipe is bound - set up auth_type and auth_level data. */
2168
2169 cli->auth.auth_type = auth_type;
2170 cli->auth.auth_level = auth_level;
2171
2172 prs_mem_free(&rbuf);
2173 return NT_STATUS_OK;
2174}
2175
2176/****************************************************************************
2177 Open a named pipe over SMB to a remote server.
2178 *
2179 * CAVEAT CALLER OF THIS FUNCTION:
2180 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2181 * so be sure that this function is called AFTER any structure (vs pointer)
2182 * assignment of the cli. In particular, libsmbclient does structure
2183 * assignments of cli, which invalidates the data in the returned
2184 * rpc_pipe_client if this function is called before the structure assignment
2185 * of cli.
2186 *
2187 ****************************************************************************/
2188
2189static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2190{
2191 TALLOC_CTX *mem_ctx;
2192 struct rpc_pipe_client *result;
2193 int fnum;
2194
2195 *perr = NT_STATUS_NO_MEMORY;
2196
2197 /* sanity check to protect against crashes */
2198
2199 if ( !cli ) {
2200 *perr = NT_STATUS_INVALID_HANDLE;
2201 return NULL;
2202 }
2203
2204 /* The pipe name index must fall within our array */
2205 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2206
2207 mem_ctx = talloc_init("struct rpc_pipe_client");
2208 if (mem_ctx == NULL) {
2209 return NULL;
2210 }
2211
2212 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2213 if (result == NULL) {
2214 return NULL;
2215 }
2216
2217 result->mem_ctx = mem_ctx;
2218
2219 result->pipe_name = cli_get_pipe_name(pipe_idx);
2220
2221 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2222
2223 if (fnum == -1) {
2224 DEBUG(3,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2225 "to machine %s. Error was %s\n",
2226 result->pipe_name, cli->desthost,
2227 cli_errstr(cli)));
2228 *perr = cli_get_nt_error(cli);
2229 talloc_destroy(result->mem_ctx);
2230 return NULL;
2231 }
2232
2233 result->fnum = fnum;
2234 result->cli = cli;
2235 result->pipe_idx = pipe_idx;
2236 result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2237 result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2238
2239 if (pipe_idx == PI_NETLOGON) {
2240 /* Set up a netlogon credential chain for a netlogon pipe. */
2241 result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
2242 if (result->dc == NULL) {
2243 talloc_destroy(result->mem_ctx);
2244 return NULL;
2245 }
2246 }
2247
2248 DLIST_ADD(cli->pipe_list, result);
2249 *perr = NT_STATUS_OK;
2250
2251 return result;
2252}
2253
2254/****************************************************************************
2255 Open a named pipe to an SMB server and bind anonymously.
2256 ****************************************************************************/
2257
2258struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2259{
2260 struct rpc_pipe_client *result;
2261
2262 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2263 if (result == NULL) {
2264 return NULL;
2265 }
2266
2267 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2268 if (!NT_STATUS_IS_OK(*perr)) {
2269 int lvl = 0;
2270 if (pipe_idx == PI_DSSETUP) {
2271 /* non AD domains just don't have this pipe, avoid
2272 * level 0 statement in that case - gd */
2273 lvl = 3;
2274 }
2275 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2276 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2277 cli_rpc_pipe_close(result);
2278 return NULL;
2279 }
2280
2281 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2282 result->pipe_name, cli->desthost ));
2283
2284 return result;
2285}
2286
2287/****************************************************************************
2288 Free function for NTLMSSP auth.
2289 ****************************************************************************/
2290
2291static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2292{
2293 if (auth->a_u.ntlmssp_state) {
2294 ntlmssp_end(&auth->a_u.ntlmssp_state);
2295 auth->a_u.ntlmssp_state = NULL;
2296 }
2297}
2298
2299/****************************************************************************
2300 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2301 ****************************************************************************/
2302
2303static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2304 int pipe_idx,
2305 enum pipe_auth_type auth_type,
2306 enum pipe_auth_level auth_level,
2307 const char *domain,
2308 const char *username,
2309 const char *password,
2310 NTSTATUS *perr)
2311{
2312 struct rpc_pipe_client *result;
2313 NTLMSSP_STATE *ntlmssp_state = NULL;
2314
2315 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2316 if (result == NULL) {
2317 return NULL;
2318 }
2319
2320 result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2321
2322 result->domain = domain;
2323 result->user_name = username;
2324 pwd_set_cleartext(&result->pwd, password);
2325
2326 *perr = ntlmssp_client_start(&ntlmssp_state);
2327 if (!NT_STATUS_IS_OK(*perr)) {
2328 goto err;
2329 }
2330
2331 result->auth.a_u.ntlmssp_state = ntlmssp_state;
2332
2333 *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
2334 if (!NT_STATUS_IS_OK(*perr)) {
2335 goto err;
2336 }
2337
2338 *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain);
2339 if (!NT_STATUS_IS_OK(*perr)) {
2340 goto err;
2341 }
2342
2343 if (cli->pwd.null_pwd) {
2344 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2345 if (!NT_STATUS_IS_OK(*perr)) {
2346 goto err;
2347 }
2348 } else {
2349 *perr = ntlmssp_set_password(ntlmssp_state, password);
2350 if (!NT_STATUS_IS_OK(*perr)) {
2351 goto err;
2352 }
2353 }
2354
2355 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2356 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2357
2358 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2359 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2360 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2361 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2362 }
2363
2364 *perr = rpc_pipe_bind(result, auth_type, auth_level);
2365 if (!NT_STATUS_IS_OK(*perr)) {
2366 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2367 nt_errstr(*perr) ));
2368 goto err;
2369 }
2370
2371 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2372 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2373 result->pipe_name, cli->desthost,
2374 domain, username ));
2375
2376 return result;
2377
2378 err:
2379
2380 cli_rpc_pipe_close(result);
2381 return NULL;
2382}
2383
2384/****************************************************************************
2385 External interface.
2386 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2387 ****************************************************************************/
2388
2389struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2390 int pipe_idx,
2391 enum pipe_auth_level auth_level,
2392 const char *domain,
2393 const char *username,
2394 const char *password,
2395 NTSTATUS *perr)
2396{
2397 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2398 pipe_idx,
2399 PIPE_AUTH_TYPE_NTLMSSP,
2400 auth_level,
2401 domain,
2402 username,
2403 password,
2404 perr);
2405}
2406
2407/****************************************************************************
2408 External interface.
2409 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2410 ****************************************************************************/
2411
2412struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2413 int pipe_idx,
2414 enum pipe_auth_level auth_level,
2415 const char *domain,
2416 const char *username,
2417 const char *password,
2418 NTSTATUS *perr)
2419{
2420 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2421 pipe_idx,
2422 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2423 auth_level,
2424 domain,
2425 username,
2426 password,
2427 perr);
2428}
2429
2430/****************************************************************************
2431 Get a the schannel session key out of an already opened netlogon pipe.
2432 ****************************************************************************/
2433static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2434 struct cli_state *cli,
2435 const char *domain,
2436 uint32 *pneg_flags,
2437 NTSTATUS *perr)
2438{
2439 uint32 sec_chan_type = 0;
2440 unsigned char machine_pwd[16];
2441 const char *machine_account;
2442
2443 /* Get the machine account credentials from secrets.tdb. */
2444 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2445 &sec_chan_type))
2446 {
2447 DEBUG(0, ("get_schannel_session_key: could not fetch "
2448 "trust account password for domain '%s'\n",
2449 domain));
2450 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2451 return false;
2452 }
2453
2454 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2455 cli->desthost, /* server name */
2456 domain, /* domain */
2457 global_myname(), /* client name */
2458 machine_account, /* machine account name */
2459 machine_pwd,
2460 sec_chan_type,
2461 pneg_flags);
2462
2463 if (!NT_STATUS_IS_OK(*perr)) {
2464 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2465 "failed with result %s to server %s, domain %s, machine account %s.\n",
2466 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2467 return false;
2468 }
2469
2470 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2471 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2472 cli->desthost));
2473 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2474 return false;
2475 }
2476
2477 return true;
2478}
2479
2480/****************************************************************************
2481 Open a netlogon pipe and get the schannel session key.
2482 Now exposed to external callers.
2483 ****************************************************************************/
2484
2485
2486struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2487 const char *domain,
2488 uint32 *pneg_flags,
2489 NTSTATUS *perr)
2490{
2491 struct rpc_pipe_client *netlogon_pipe = NULL;
2492
2493 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2494 if (!netlogon_pipe) {
2495 return NULL;
2496 }
2497
2498 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2499 pneg_flags, perr))
2500 {
2501 cli_rpc_pipe_close(netlogon_pipe);
2502 return NULL;
2503 }
2504
2505 return netlogon_pipe;
2506}
2507
2508/****************************************************************************
2509 External interface.
2510 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2511 using session_key. sign and seal.
2512 ****************************************************************************/
2513
2514struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2515 int pipe_idx,
2516 enum pipe_auth_level auth_level,
2517 const char *domain,
2518 const struct dcinfo *pdc,
2519 NTSTATUS *perr)
2520{
2521 struct rpc_pipe_client *result;
2522
2523 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2524 if (result == NULL) {
2525 return NULL;
2526 }
2527
2528 result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
2529 if (!result->auth.a_u.schannel_auth) {
2530 cli_rpc_pipe_close(result);
2531 *perr = NT_STATUS_NO_MEMORY;
2532 return NULL;
2533 }
2534
2535 result->domain = domain;
2536 memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2537
2538 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2539 if (!NT_STATUS_IS_OK(*perr)) {
2540 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2541 nt_errstr(*perr) ));
2542 cli_rpc_pipe_close(result);
2543 return NULL;
2544 }
2545
2546 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2547 if (result->dc) {
2548 *result->dc = *pdc;
2549 }
2550
2551 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2552 "for domain %s "
2553 "and bound using schannel.\n",
2554 result->pipe_name, cli->desthost, domain ));
2555
2556 return result;
2557}
2558
2559/****************************************************************************
2560 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2561 Fetch the session key ourselves using a temporary netlogon pipe. This
2562 version uses an ntlmssp auth bound netlogon pipe to get the key.
2563 ****************************************************************************/
2564
2565static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2566 const char *domain,
2567 const char *username,
2568 const char *password,
2569 uint32 *pneg_flags,
2570 NTSTATUS *perr)
2571{
2572 struct rpc_pipe_client *netlogon_pipe = NULL;
2573
2574 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2575 if (!netlogon_pipe) {
2576 return NULL;
2577 }
2578
2579 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2580 pneg_flags, perr))
2581 {
2582 cli_rpc_pipe_close(netlogon_pipe);
2583 return NULL;
2584 }
2585
2586 return netlogon_pipe;
2587}
2588
2589/****************************************************************************
2590 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2591 Fetch the session key ourselves using a temporary netlogon pipe. This version
2592 uses an ntlmssp bind to get the session key.
2593 ****************************************************************************/
2594
2595struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2596 int pipe_idx,
2597 enum pipe_auth_level auth_level,
2598 const char *domain,
2599 const char *username,
2600 const char *password,
2601 NTSTATUS *perr)
2602{
2603 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2604 struct rpc_pipe_client *netlogon_pipe = NULL;
2605 struct rpc_pipe_client *result = NULL;
2606
2607 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2608 password, &neg_flags, perr);
2609 if (!netlogon_pipe) {
2610 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2611 "key from server %s for domain %s.\n",
2612 cli->desthost, domain ));
2613 return NULL;
2614 }
2615
2616 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2617 auth_level,
2618 domain, netlogon_pipe->dc, perr);
2619
2620 /* Now we've bound using the session key we can close the netlog pipe. */
2621 cli_rpc_pipe_close(netlogon_pipe);
2622
2623 return result;
2624}
2625
2626/****************************************************************************
2627 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2628 Fetch the session key ourselves using a temporary netlogon pipe.
2629 ****************************************************************************/
2630
2631struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2632 int pipe_idx,
2633 enum pipe_auth_level auth_level,
2634 const char *domain,
2635 NTSTATUS *perr)
2636{
2637 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2638 struct rpc_pipe_client *netlogon_pipe = NULL;
2639 struct rpc_pipe_client *result = NULL;
2640
2641 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2642 if (!netlogon_pipe) {
2643 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2644 "key from server %s for domain %s.\n",
2645 cli->desthost, domain ));
2646 return NULL;
2647 }
2648
2649 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2650 auth_level,
2651 domain, netlogon_pipe->dc, perr);
2652
2653 /* Now we've bound using the session key we can close the netlog pipe. */
2654 cli_rpc_pipe_close(netlogon_pipe);
2655
2656 return result;
2657}
2658
2659#ifdef HAVE_KRB5
2660
2661/****************************************************************************
2662 Free function for the kerberos spcific data.
2663 ****************************************************************************/
2664
2665static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2666{
2667 data_blob_free(&a->a_u.kerberos_auth->session_key);
2668}
2669
2670#endif
2671
2672/****************************************************************************
2673 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2674 The idea is this can be called with service_princ, username and password all
2675 NULL so long as the caller has a TGT.
2676 ****************************************************************************/
2677
2678struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2679 int pipe_idx,
2680 enum pipe_auth_level auth_level,
2681 const char *service_princ,
2682 const char *username,
2683 const char *password,
2684 NTSTATUS *perr)
2685{
2686#ifdef HAVE_KRB5
2687 struct rpc_pipe_client *result;
2688
2689 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2690 if (result == NULL) {
2691 return NULL;
2692 }
2693
2694 /* Default service principal is "desthost$@realm" */
2695 if (!service_princ) {
2696 service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s",
2697 cli->desthost, lp_realm() );
2698 if (!service_princ) {
2699 cli_rpc_pipe_close(result);
2700 return NULL;
2701 }
2702 }
2703
2704 /* Only get a new TGT if username/password are given. */
2705 if (username && password) {
2706 int ret = kerberos_kinit_password(username, password, 0, NULL);
2707 if (ret) {
2708 cli_rpc_pipe_close(result);
2709 return NULL;
2710 }
2711 }
2712
2713 result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(result->mem_ctx, struct kerberos_auth_struct);
2714 if (!result->auth.a_u.kerberos_auth) {
2715 cli_rpc_pipe_close(result);
2716 *perr = NT_STATUS_NO_MEMORY;
2717 return NULL;
2718 }
2719
2720 result->auth.a_u.kerberos_auth->service_principal = service_princ;
2721 result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2722
2723 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2724 if (!NT_STATUS_IS_OK(*perr)) {
2725 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2726 nt_errstr(*perr) ));
2727 cli_rpc_pipe_close(result);
2728 return NULL;
2729 }
2730
2731 return result;
2732#else
2733 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2734 return NULL;
2735#endif
2736}
Note: See TracBrowser for help on using the repository browser.