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