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