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