source: branches/samba-3.0/source/rpc_client/cli_pipe.c

Last change on this file was 140, checked in by Paul Smedley, 17 years ago

Update branch to 3.0.31 release

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