dc4dfbd3b27cefc40b29f418e5d4ab8057424fb1
[ira/wip.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
26 #include "../libcli/auth/spnego.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_CLI
30
31 /*******************************************************************
32 interface/version dce/rpc pipe identification
33 ********************************************************************/
34
35 #define PIPE_SRVSVC   "\\PIPE\\srvsvc"
36 #define PIPE_SAMR     "\\PIPE\\samr"
37 #define PIPE_WINREG   "\\PIPE\\winreg"
38 #define PIPE_WKSSVC   "\\PIPE\\wkssvc"
39 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
40 #define PIPE_NTLSA    "\\PIPE\\ntlsa"
41 #define PIPE_NTSVCS   "\\PIPE\\ntsvcs"
42 #define PIPE_LSASS    "\\PIPE\\lsass"
43 #define PIPE_LSARPC   "\\PIPE\\lsarpc"
44 #define PIPE_SPOOLSS  "\\PIPE\\spoolss"
45 #define PIPE_NETDFS   "\\PIPE\\netdfs"
46 #define PIPE_ECHO     "\\PIPE\\rpcecho"
47 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
48 #define PIPE_EPM      "\\PIPE\\epmapper"
49 #define PIPE_SVCCTL   "\\PIPE\\svcctl"
50 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
51 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
52 #define PIPE_DRSUAPI  "\\PIPE\\drsuapi"
53
54 /*
55  * IMPORTANT!!  If you update this structure, make sure to
56  * update the index #defines in smb.h.
57  */
58
59 static const struct pipe_id_info {
60         /* the names appear not to matter: the syntaxes _do_ matter */
61
62         const char *client_pipe;
63         const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
64 } pipe_names [] =
65 {
66         { PIPE_LSARPC,          &ndr_table_lsarpc.syntax_id },
67         { PIPE_LSARPC,          &ndr_table_dssetup.syntax_id },
68         { PIPE_SAMR,            &ndr_table_samr.syntax_id },
69         { PIPE_NETLOGON,        &ndr_table_netlogon.syntax_id },
70         { PIPE_SRVSVC,          &ndr_table_srvsvc.syntax_id },
71         { PIPE_WKSSVC,          &ndr_table_wkssvc.syntax_id },
72         { PIPE_WINREG,          &ndr_table_winreg.syntax_id },
73         { PIPE_SPOOLSS,         &ndr_table_spoolss.syntax_id },
74         { PIPE_NETDFS,          &ndr_table_netdfs.syntax_id },
75         { PIPE_ECHO,            &ndr_table_rpcecho.syntax_id },
76         { PIPE_SHUTDOWN,        &ndr_table_initshutdown.syntax_id },
77         { PIPE_SVCCTL,          &ndr_table_svcctl.syntax_id },
78         { PIPE_EVENTLOG,        &ndr_table_eventlog.syntax_id },
79         { PIPE_NTSVCS,          &ndr_table_ntsvcs.syntax_id },
80         { PIPE_EPMAPPER,        &ndr_table_epmapper.syntax_id },
81         { PIPE_DRSUAPI,         &ndr_table_drsuapi.syntax_id },
82         { NULL, NULL }
83 };
84
85 /****************************************************************************
86  Return the pipe name from the interface.
87  ****************************************************************************/
88
89 const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
90 {
91         char *guid_str;
92         const char *result;
93         int i;
94         for (i = 0; pipe_names[i].client_pipe; i++) {
95                 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
96                                         interface)) {
97                         return &pipe_names[i].client_pipe[5];
98                 }
99         }
100
101         /*
102          * Here we should ask \\epmapper, but for now our code is only
103          * interested in the known pipes mentioned in pipe_names[]
104          */
105
106         guid_str = GUID_string(talloc_tos(), &interface->uuid);
107         if (guid_str == NULL) {
108                 return NULL;
109         }
110         result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
111                                  (int)interface->if_version);
112         TALLOC_FREE(guid_str);
113
114         if (result == NULL) {
115                 return "PIPE";
116         }
117         return result;
118 }
119
120 /********************************************************************
121  Map internal value to wire value.
122  ********************************************************************/
123
124 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
125 {
126         switch (auth_type) {
127
128         case PIPE_AUTH_TYPE_NONE:
129                 return DCERPC_AUTH_TYPE_NONE;
130
131         case PIPE_AUTH_TYPE_NTLMSSP:
132                 return DCERPC_AUTH_TYPE_NTLMSSP;
133
134         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
135         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
136                 return DCERPC_AUTH_TYPE_SPNEGO;
137
138         case PIPE_AUTH_TYPE_SCHANNEL:
139                 return DCERPC_AUTH_TYPE_SCHANNEL;
140
141         case PIPE_AUTH_TYPE_KRB5:
142                 return DCERPC_AUTH_TYPE_KRB5;
143
144         default:
145                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
146                         "auth type %u\n",
147                         (unsigned int)auth_type ));
148                 break;
149         }
150         return -1;
151 }
152
153 /********************************************************************
154  Pipe description for a DEBUG
155  ********************************************************************/
156 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
157                                    struct rpc_pipe_client *cli)
158 {
159         char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
160         if (result == NULL) {
161                 return "pipe";
162         }
163         return result;
164 }
165
166 /********************************************************************
167  Rpc pipe call id.
168  ********************************************************************/
169
170 static uint32 get_rpc_call_id(void)
171 {
172         static uint32 call_id = 0;
173         return ++call_id;
174 }
175
176 /*
177  * Realloc pdu to have a least "size" bytes
178  */
179
180 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
181 {
182         size_t extra_size;
183
184         if (prs_data_size(pdu) >= size) {
185                 return true;
186         }
187
188         extra_size = size - prs_data_size(pdu);
189
190         if (!prs_force_grow(pdu, extra_size)) {
191                 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
192                           "%d bytes.\n", (int)extra_size));
193                 return false;
194         }
195
196         DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
197                   (int)extra_size, prs_data_size(pdu)));
198         return true;
199 }
200
201
202 /*******************************************************************
203  Use SMBreadX to get rest of one fragment's worth of rpc data.
204  Reads the whole size or give an error message
205  ********************************************************************/
206
207 struct rpc_read_state {
208         struct event_context *ev;
209         struct rpc_cli_transport *transport;
210         uint8_t *data;
211         size_t size;
212         size_t num_read;
213 };
214
215 static void rpc_read_done(struct tevent_req *subreq);
216
217 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
218                                         struct event_context *ev,
219                                         struct rpc_cli_transport *transport,
220                                         uint8_t *data, size_t size)
221 {
222         struct tevent_req *req, *subreq;
223         struct rpc_read_state *state;
224
225         req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
226         if (req == NULL) {
227                 return NULL;
228         }
229         state->ev = ev;
230         state->transport = transport;
231         state->data = data;
232         state->size = size;
233         state->num_read = 0;
234
235         DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
236
237         subreq = transport->read_send(state, ev, (uint8_t *)data, size,
238                                       transport->priv);
239         if (subreq == NULL) {
240                 goto fail;
241         }
242         tevent_req_set_callback(subreq, rpc_read_done, req);
243         return req;
244
245  fail:
246         TALLOC_FREE(req);
247         return NULL;
248 }
249
250 static void rpc_read_done(struct tevent_req *subreq)
251 {
252         struct tevent_req *req = tevent_req_callback_data(
253                 subreq, struct tevent_req);
254         struct rpc_read_state *state = tevent_req_data(
255                 req, struct rpc_read_state);
256         NTSTATUS status;
257         ssize_t received;
258
259         status = state->transport->read_recv(subreq, &received);
260         TALLOC_FREE(subreq);
261         if (!NT_STATUS_IS_OK(status)) {
262                 tevent_req_nterror(req, status);
263                 return;
264         }
265
266         state->num_read += received;
267         if (state->num_read == state->size) {
268                 tevent_req_done(req);
269                 return;
270         }
271
272         subreq = state->transport->read_send(state, state->ev,
273                                              state->data + state->num_read,
274                                              state->size - state->num_read,
275                                              state->transport->priv);
276         if (tevent_req_nomem(subreq, req)) {
277                 return;
278         }
279         tevent_req_set_callback(subreq, rpc_read_done, req);
280 }
281
282 static NTSTATUS rpc_read_recv(struct tevent_req *req)
283 {
284         return tevent_req_simple_recv_ntstatus(req);
285 }
286
287 struct rpc_write_state {
288         struct event_context *ev;
289         struct rpc_cli_transport *transport;
290         const uint8_t *data;
291         size_t size;
292         size_t num_written;
293 };
294
295 static void rpc_write_done(struct tevent_req *subreq);
296
297 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
298                                          struct event_context *ev,
299                                          struct rpc_cli_transport *transport,
300                                          const uint8_t *data, size_t size)
301 {
302         struct tevent_req *req, *subreq;
303         struct rpc_write_state *state;
304
305         req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
306         if (req == NULL) {
307                 return NULL;
308         }
309         state->ev = ev;
310         state->transport = transport;
311         state->data = data;
312         state->size = size;
313         state->num_written = 0;
314
315         DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
316
317         subreq = transport->write_send(state, ev, data, size, transport->priv);
318         if (subreq == NULL) {
319                 goto fail;
320         }
321         tevent_req_set_callback(subreq, rpc_write_done, req);
322         return req;
323  fail:
324         TALLOC_FREE(req);
325         return NULL;
326 }
327
328 static void rpc_write_done(struct tevent_req *subreq)
329 {
330         struct tevent_req *req = tevent_req_callback_data(
331                 subreq, struct tevent_req);
332         struct rpc_write_state *state = tevent_req_data(
333                 req, struct rpc_write_state);
334         NTSTATUS status;
335         ssize_t written;
336
337         status = state->transport->write_recv(subreq, &written);
338         TALLOC_FREE(subreq);
339         if (!NT_STATUS_IS_OK(status)) {
340                 tevent_req_nterror(req, status);
341                 return;
342         }
343
344         state->num_written += written;
345
346         if (state->num_written == state->size) {
347                 tevent_req_done(req);
348                 return;
349         }
350
351         subreq = state->transport->write_send(state, state->ev,
352                                               state->data + state->num_written,
353                                               state->size - state->num_written,
354                                               state->transport->priv);
355         if (tevent_req_nomem(subreq, req)) {
356                 return;
357         }
358         tevent_req_set_callback(subreq, rpc_write_done, req);
359 }
360
361 static NTSTATUS rpc_write_recv(struct tevent_req *req)
362 {
363         return tevent_req_simple_recv_ntstatus(req);
364 }
365
366
367 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
368                                  struct rpc_hdr_info *prhdr,
369                                  prs_struct *pdu)
370 {
371         /*
372          * This next call sets the endian bit correctly in current_pdu. We
373          * will propagate this to rbuf later.
374          */
375
376         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, pdu, 0)) {
377                 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
378                 return NT_STATUS_BUFFER_TOO_SMALL;
379         }
380
381         if (prhdr->frag_len > cli->max_recv_frag) {
382                 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
383                           " we only allow %d\n", (int)prhdr->frag_len,
384                           (int)cli->max_recv_frag));
385                 return NT_STATUS_BUFFER_TOO_SMALL;
386         }
387
388         return NT_STATUS_OK;
389 }
390
391 /****************************************************************************
392  Try and get a PDU's worth of data from current_pdu. If not, then read more
393  from the wire.
394  ****************************************************************************/
395
396 struct get_complete_frag_state {
397         struct event_context *ev;
398         struct rpc_pipe_client *cli;
399         struct rpc_hdr_info *prhdr;
400         prs_struct *pdu;
401 };
402
403 static void get_complete_frag_got_header(struct tevent_req *subreq);
404 static void get_complete_frag_got_rest(struct tevent_req *subreq);
405
406 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
407                                                  struct event_context *ev,
408                                                  struct rpc_pipe_client *cli,
409                                                  struct rpc_hdr_info *prhdr,
410                                                  prs_struct *pdu)
411 {
412         struct tevent_req *req, *subreq;
413         struct get_complete_frag_state *state;
414         uint32_t pdu_len;
415         NTSTATUS status;
416
417         req = tevent_req_create(mem_ctx, &state,
418                                 struct get_complete_frag_state);
419         if (req == NULL) {
420                 return NULL;
421         }
422         state->ev = ev;
423         state->cli = cli;
424         state->prhdr = prhdr;
425         state->pdu = pdu;
426
427         pdu_len = prs_data_size(pdu);
428         if (pdu_len < RPC_HEADER_LEN) {
429                 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
430                         status = NT_STATUS_NO_MEMORY;
431                         goto post_status;
432                 }
433                 subreq = rpc_read_send(
434                         state, state->ev,
435                         state->cli->transport,
436                         (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
437                         RPC_HEADER_LEN - pdu_len);
438                 if (subreq == NULL) {
439                         status = NT_STATUS_NO_MEMORY;
440                         goto post_status;
441                 }
442                 tevent_req_set_callback(subreq, get_complete_frag_got_header,
443                                         req);
444                 return req;
445         }
446
447         status = parse_rpc_header(cli, prhdr, pdu);
448         if (!NT_STATUS_IS_OK(status)) {
449                 goto post_status;
450         }
451
452         /*
453          * Ensure we have frag_len bytes of data.
454          */
455         if (pdu_len < prhdr->frag_len) {
456                 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
457                         status = NT_STATUS_NO_MEMORY;
458                         goto post_status;
459                 }
460                 subreq = rpc_read_send(state, state->ev,
461                                        state->cli->transport,
462                                        (uint8_t *)(prs_data_p(pdu) + pdu_len),
463                                        prhdr->frag_len - pdu_len);
464                 if (subreq == NULL) {
465                         status = NT_STATUS_NO_MEMORY;
466                         goto post_status;
467                 }
468                 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
469                                         req);
470                 return req;
471         }
472
473         status = NT_STATUS_OK;
474  post_status:
475         if (NT_STATUS_IS_OK(status)) {
476                 tevent_req_done(req);
477         } else {
478                 tevent_req_nterror(req, status);
479         }
480         return tevent_req_post(req, ev);
481 }
482
483 static void get_complete_frag_got_header(struct tevent_req *subreq)
484 {
485         struct tevent_req *req = tevent_req_callback_data(
486                 subreq, struct tevent_req);
487         struct get_complete_frag_state *state = tevent_req_data(
488                 req, struct get_complete_frag_state);
489         NTSTATUS status;
490
491         status = rpc_read_recv(subreq);
492         TALLOC_FREE(subreq);
493         if (!NT_STATUS_IS_OK(status)) {
494                 tevent_req_nterror(req, status);
495                 return;
496         }
497
498         status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
499         if (!NT_STATUS_IS_OK(status)) {
500                 tevent_req_nterror(req, status);
501                 return;
502         }
503
504         if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
505                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
506                 return;
507         }
508
509         /*
510          * We're here in this piece of code because we've read exactly
511          * RPC_HEADER_LEN bytes into state->pdu.
512          */
513
514         subreq = rpc_read_send(
515                 state, state->ev, state->cli->transport,
516                 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
517                 state->prhdr->frag_len - RPC_HEADER_LEN);
518         if (tevent_req_nomem(subreq, req)) {
519                 return;
520         }
521         tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
522 }
523
524 static void get_complete_frag_got_rest(struct tevent_req *subreq)
525 {
526         struct tevent_req *req = tevent_req_callback_data(
527                 subreq, struct tevent_req);
528         NTSTATUS status;
529
530         status = rpc_read_recv(subreq);
531         TALLOC_FREE(subreq);
532         if (!NT_STATUS_IS_OK(status)) {
533                 tevent_req_nterror(req, status);
534                 return;
535         }
536         tevent_req_done(req);
537 }
538
539 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
540 {
541         return tevent_req_simple_recv_ntstatus(req);
542 }
543
544 /****************************************************************************
545  NTLMSSP specific sign/seal.
546  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
547  In fact I should probably abstract these into identical pieces of code... JRA.
548  ****************************************************************************/
549
550 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
551                                 prs_struct *current_pdu,
552                                 uint8 *p_ss_padding_len)
553 {
554         RPC_HDR_AUTH auth_info;
555         uint32 save_offset = prs_offset(current_pdu);
556         uint32 auth_len = prhdr->auth_len;
557         NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
558         unsigned char *data = NULL;
559         size_t data_len;
560         unsigned char *full_packet_data = NULL;
561         size_t full_packet_data_len;
562         DATA_BLOB auth_blob;
563         NTSTATUS status;
564
565         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
566             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
567                 return NT_STATUS_OK;
568         }
569
570         if (!ntlmssp_state) {
571                 return NT_STATUS_INVALID_PARAMETER;
572         }
573
574         /* Ensure there's enough data for an authenticated response. */
575         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
576                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
577                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
578                         (unsigned int)auth_len ));
579                 return NT_STATUS_BUFFER_TOO_SMALL;
580         }
581
582         /*
583          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
584          * after the RPC header.
585          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
586          * functions as NTLMv2 checks the rpc headers also.
587          */
588
589         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
590         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
591
592         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
593         full_packet_data_len = prhdr->frag_len - auth_len;
594
595         /* Pull the auth header and the following data into a blob. */
596         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
597                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
598                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
599                 return NT_STATUS_BUFFER_TOO_SMALL;
600         }
601
602         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
603                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
604                 return NT_STATUS_BUFFER_TOO_SMALL;
605         }
606
607         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
608         auth_blob.length = auth_len;
609
610         switch (cli->auth->auth_level) {
611                 case DCERPC_AUTH_LEVEL_PRIVACY:
612                         /* Data is encrypted. */
613                         status = ntlmssp_unseal_packet(ntlmssp_state,
614                                                         data, data_len,
615                                                         full_packet_data,
616                                                         full_packet_data_len,
617                                                         &auth_blob);
618                         if (!NT_STATUS_IS_OK(status)) {
619                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
620                                         "packet from %s. Error was %s.\n",
621                                         rpccli_pipe_txt(debug_ctx(), cli),
622                                         nt_errstr(status) ));
623                                 return status;
624                         }
625                         break;
626                 case DCERPC_AUTH_LEVEL_INTEGRITY:
627                         /* Data is signed. */
628                         status = ntlmssp_check_packet(ntlmssp_state,
629                                                         data, data_len,
630                                                         full_packet_data,
631                                                         full_packet_data_len,
632                                                         &auth_blob);
633                         if (!NT_STATUS_IS_OK(status)) {
634                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
635                                         "packet from %s. Error was %s.\n",
636                                         rpccli_pipe_txt(debug_ctx(), cli),
637                                         nt_errstr(status) ));
638                                 return status;
639                         }
640                         break;
641                 default:
642                         DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
643                                   "auth level %d\n", cli->auth->auth_level));
644                         return NT_STATUS_INVALID_INFO_CLASS;
645         }
646
647         /*
648          * Return the current pointer to the data offset.
649          */
650
651         if(!prs_set_offset(current_pdu, save_offset)) {
652                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
653                         (unsigned int)save_offset ));
654                 return NT_STATUS_BUFFER_TOO_SMALL;
655         }
656
657         /*
658          * Remember the padding length. We must remove it from the real data
659          * stream once the sign/seal is done.
660          */
661
662         *p_ss_padding_len = auth_info.auth_pad_len;
663
664         return NT_STATUS_OK;
665 }
666
667 /****************************************************************************
668  schannel specific sign/seal.
669  ****************************************************************************/
670
671 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
672                                 prs_struct *current_pdu,
673                                 uint8 *p_ss_padding_len)
674 {
675         RPC_HDR_AUTH auth_info;
676         uint32 auth_len = prhdr->auth_len;
677         uint32 save_offset = prs_offset(current_pdu);
678         struct schannel_state *schannel_auth =
679                 cli->auth->a_u.schannel_auth;
680         uint8_t *data;
681         uint32 data_len;
682         DATA_BLOB blob;
683         NTSTATUS status;
684
685         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
686             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
687                 return NT_STATUS_OK;
688         }
689
690         if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
691                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
692                 return NT_STATUS_INVALID_PARAMETER;
693         }
694
695         if (!schannel_auth) {
696                 return NT_STATUS_INVALID_PARAMETER;
697         }
698
699         /* Ensure there's enough data for an authenticated response. */
700         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
701                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
702                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
703                         (unsigned int)auth_len ));
704                 return NT_STATUS_INVALID_PARAMETER;
705         }
706
707         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
708
709         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
710                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
711                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
712                 return NT_STATUS_BUFFER_TOO_SMALL;
713         }
714
715         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
716                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
717                 return NT_STATUS_BUFFER_TOO_SMALL;
718         }
719
720         if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
721                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
722                         auth_info.auth_type));
723                 return NT_STATUS_BUFFER_TOO_SMALL;
724         }
725
726         blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
727
728         if (DEBUGLEVEL >= 10) {
729                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
730         }
731
732         data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
733
734         switch (cli->auth->auth_level) {
735         case DCERPC_AUTH_LEVEL_PRIVACY:
736                 status = netsec_incoming_packet(schannel_auth,
737                                                 talloc_tos(),
738                                                 true,
739                                                 data,
740                                                 data_len,
741                                                 &blob);
742                 break;
743         case DCERPC_AUTH_LEVEL_INTEGRITY:
744                 status = netsec_incoming_packet(schannel_auth,
745                                                 talloc_tos(),
746                                                 false,
747                                                 data,
748                                                 data_len,
749                                                 &blob);
750                 break;
751         default:
752                 status = NT_STATUS_INTERNAL_ERROR;
753                 break;
754         }
755
756         if (!NT_STATUS_IS_OK(status)) {
757                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
758                                 "Connection to %s (%s).\n",
759                                 rpccli_pipe_txt(debug_ctx(), cli),
760                                 nt_errstr(status)));
761                 return NT_STATUS_INVALID_PARAMETER;
762         }
763
764         /*
765          * Return the current pointer to the data offset.
766          */
767
768         if(!prs_set_offset(current_pdu, save_offset)) {
769                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
770                         (unsigned int)save_offset ));
771                 return NT_STATUS_BUFFER_TOO_SMALL;
772         }
773
774         /*
775          * Remember the padding length. We must remove it from the real data
776          * stream once the sign/seal is done.
777          */
778
779         *p_ss_padding_len = auth_info.auth_pad_len;
780
781         return NT_STATUS_OK;
782 }
783
784 /****************************************************************************
785  Do the authentication checks on an incoming pdu. Check sign and unseal etc.
786  ****************************************************************************/
787
788 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
789                                 prs_struct *current_pdu,
790                                 uint8 *p_ss_padding_len)
791 {
792         NTSTATUS ret = NT_STATUS_OK;
793
794         /* Paranioa checks for auth_len. */
795         if (prhdr->auth_len) {
796                 if (prhdr->auth_len > prhdr->frag_len) {
797                         return NT_STATUS_INVALID_PARAMETER;
798                 }
799
800                 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
801                                 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
802                         /* Integer wrap attempt. */
803                         return NT_STATUS_INVALID_PARAMETER;
804                 }
805         }
806
807         /*
808          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
809          */
810
811         switch(cli->auth->auth_type) {
812                 case PIPE_AUTH_TYPE_NONE:
813                         if (prhdr->auth_len) {
814                                 DEBUG(3, ("cli_pipe_validate_rpc_response: "
815                                           "Connection to %s - got non-zero "
816                                           "auth len %u.\n",
817                                         rpccli_pipe_txt(debug_ctx(), cli),
818                                         (unsigned int)prhdr->auth_len ));
819                                 return NT_STATUS_INVALID_PARAMETER;
820                         }
821                         break;
822
823                 case PIPE_AUTH_TYPE_NTLMSSP:
824                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
825                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
826                         if (!NT_STATUS_IS_OK(ret)) {
827                                 return ret;
828                         }
829                         break;
830
831                 case PIPE_AUTH_TYPE_SCHANNEL:
832                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
833                         if (!NT_STATUS_IS_OK(ret)) {
834                                 return ret;
835                         }
836                         break;
837
838                 case PIPE_AUTH_TYPE_KRB5:
839                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
840                 default:
841                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
842                                   "to %s - unknown internal auth type %u.\n",
843                                   rpccli_pipe_txt(debug_ctx(), cli),
844                                   cli->auth->auth_type ));
845                         return NT_STATUS_INVALID_INFO_CLASS;
846         }
847
848         return NT_STATUS_OK;
849 }
850
851 /****************************************************************************
852  Do basic authentication checks on an incoming pdu.
853  ****************************************************************************/
854
855 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
856                         prs_struct *current_pdu,
857                         uint8 expected_pkt_type,
858                         char **ppdata,
859                         uint32 *pdata_len,
860                         prs_struct *return_data)
861 {
862
863         NTSTATUS ret = NT_STATUS_OK;
864         uint32 current_pdu_len = prs_data_size(current_pdu);
865
866         if (current_pdu_len != prhdr->frag_len) {
867                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
868                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
869                 return NT_STATUS_INVALID_PARAMETER;
870         }
871
872         /*
873          * Point the return values at the real data including the RPC
874          * header. Just in case the caller wants it.
875          */
876         *ppdata = prs_data_p(current_pdu);
877         *pdata_len = current_pdu_len;
878
879         /* Ensure we have the correct type. */
880         switch (prhdr->pkt_type) {
881                 case DCERPC_PKT_ALTER_RESP:
882                 case DCERPC_PKT_BIND_ACK:
883
884                         /* Alter context and bind ack share the same packet definitions. */
885                         break;
886
887
888                 case DCERPC_PKT_RESPONSE:
889                 {
890                         RPC_HDR_RESP rhdr_resp;
891                         uint8 ss_padding_len = 0;
892
893                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
894                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
895                                 return NT_STATUS_BUFFER_TOO_SMALL;
896                         }
897
898                         /* Here's where we deal with incoming sign/seal. */
899                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
900                                         current_pdu, &ss_padding_len);
901                         if (!NT_STATUS_IS_OK(ret)) {
902                                 return ret;
903                         }
904
905                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
906                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
907
908                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
909                                 return NT_STATUS_BUFFER_TOO_SMALL;
910                         }
911
912                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
913
914                         /* Remember to remove the auth footer. */
915                         if (prhdr->auth_len) {
916                                 /* We've already done integer wrap tests on auth_len in
917                                         cli_pipe_validate_rpc_response(). */
918                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
919                                         return NT_STATUS_BUFFER_TOO_SMALL;
920                                 }
921                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
922                         }
923
924                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
925                                 current_pdu_len, *pdata_len, ss_padding_len ));
926
927                         /*
928                          * If this is the first reply, and the allocation hint is reasonably, try and
929                          * set up the return_data parse_struct to the correct size.
930                          */
931
932                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
933                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
934                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
935                                                 "too large to allocate\n",
936                                                 (unsigned int)rhdr_resp.alloc_hint ));
937                                         return NT_STATUS_NO_MEMORY;
938                                 }
939                         }
940
941                         break;
942                 }
943
944                 case DCERPC_PKT_BIND_NAK:
945                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
946                                   "received from %s!\n",
947                                   rpccli_pipe_txt(debug_ctx(), cli)));
948                         /* Use this for now... */
949                         return NT_STATUS_NETWORK_ACCESS_DENIED;
950
951                 case DCERPC_PKT_FAULT:
952                 {
953                         RPC_HDR_RESP rhdr_resp;
954                         RPC_HDR_FAULT fault_resp;
955
956                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
957                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
958                                 return NT_STATUS_BUFFER_TOO_SMALL;
959                         }
960
961                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
962                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
963                                 return NT_STATUS_BUFFER_TOO_SMALL;
964                         }
965
966                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
967                                   "code %s received from %s!\n",
968                                 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
969                                 rpccli_pipe_txt(debug_ctx(), cli)));
970                         if (NT_STATUS_IS_OK(fault_resp.status)) {
971                                 return NT_STATUS_UNSUCCESSFUL;
972                         } else {
973                                 return fault_resp.status;
974                         }
975                 }
976
977                 default:
978                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
979                                 "from %s!\n",
980                                 (unsigned int)prhdr->pkt_type,
981                                 rpccli_pipe_txt(debug_ctx(), cli)));
982                         return NT_STATUS_INVALID_INFO_CLASS;
983         }
984
985         if (prhdr->pkt_type != expected_pkt_type) {
986                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
987                           "got an unexpected RPC packet type - %u, not %u\n",
988                         rpccli_pipe_txt(debug_ctx(), cli),
989                         prhdr->pkt_type,
990                         expected_pkt_type));
991                 return NT_STATUS_INVALID_INFO_CLASS;
992         }
993
994         /* Do this just before return - we don't want to modify any rpc header
995            data before now as we may have needed to do cryptographic actions on
996            it before. */
997
998         if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
999                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1000                         "setting fragment first/last ON.\n"));
1001                 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1002         }
1003
1004         return NT_STATUS_OK;
1005 }
1006
1007 /****************************************************************************
1008  Ensure we eat the just processed pdu from the current_pdu prs_struct.
1009  Normally the frag_len and buffer size will match, but on the first trans
1010  reply there is a theoretical chance that buffer size > frag_len, so we must
1011  deal with that.
1012  ****************************************************************************/
1013
1014 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1015 {
1016         uint32 current_pdu_len = prs_data_size(current_pdu);
1017
1018         if (current_pdu_len < prhdr->frag_len) {
1019                 return NT_STATUS_BUFFER_TOO_SMALL;
1020         }
1021
1022         /* Common case. */
1023         if (current_pdu_len == (uint32)prhdr->frag_len) {
1024                 prs_mem_free(current_pdu);
1025                 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1026                 /* Make current_pdu dynamic with no memory. */
1027                 prs_give_memory(current_pdu, 0, 0, True);
1028                 return NT_STATUS_OK;
1029         }
1030
1031         /*
1032          * Oh no ! More data in buffer than we processed in current pdu.
1033          * Cheat. Move the data down and shrink the buffer.
1034          */
1035
1036         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1037                         current_pdu_len - prhdr->frag_len);
1038
1039         /* Remember to set the read offset back to zero. */
1040         prs_set_offset(current_pdu, 0);
1041
1042         /* Shrink the buffer. */
1043         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1044                 return NT_STATUS_BUFFER_TOO_SMALL;
1045         }
1046
1047         return NT_STATUS_OK;
1048 }
1049
1050 /****************************************************************************
1051  Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
1052 ****************************************************************************/
1053
1054 struct cli_api_pipe_state {
1055         struct event_context *ev;
1056         struct rpc_cli_transport *transport;
1057         uint8_t *rdata;
1058         uint32_t rdata_len;
1059 };
1060
1061 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1062 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1063 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1064
1065 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1066                                             struct event_context *ev,
1067                                             struct rpc_cli_transport *transport,
1068                                             uint8_t *data, size_t data_len,
1069                                             uint32_t max_rdata_len)
1070 {
1071         struct tevent_req *req, *subreq;
1072         struct cli_api_pipe_state *state;
1073         NTSTATUS status;
1074
1075         req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1076         if (req == NULL) {
1077                 return NULL;
1078         }
1079         state->ev = ev;
1080         state->transport = transport;
1081
1082         if (max_rdata_len < RPC_HEADER_LEN) {
1083                 /*
1084                  * For a RPC reply we always need at least RPC_HEADER_LEN
1085                  * bytes. We check this here because we will receive
1086                  * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1087                  */
1088                 status = NT_STATUS_INVALID_PARAMETER;
1089                 goto post_status;
1090         }
1091
1092         if (transport->trans_send != NULL) {
1093                 subreq = transport->trans_send(state, ev, data, data_len,
1094                                                max_rdata_len, transport->priv);
1095                 if (subreq == NULL) {
1096                         goto fail;
1097                 }
1098                 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1099                 return req;
1100         }
1101
1102         /*
1103          * If the transport does not provide a "trans" routine, i.e. for
1104          * example the ncacn_ip_tcp transport, do the write/read step here.
1105          */
1106
1107         subreq = rpc_write_send(state, ev, transport, data, data_len);
1108         if (subreq == NULL) {
1109                 goto fail;
1110         }
1111         tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1112         return req;
1113
1114         status = NT_STATUS_INVALID_PARAMETER;
1115
1116  post_status:
1117         tevent_req_nterror(req, status);
1118         return tevent_req_post(req, ev);
1119  fail:
1120         TALLOC_FREE(req);
1121         return NULL;
1122 }
1123
1124 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1125 {
1126         struct tevent_req *req = tevent_req_callback_data(
1127                 subreq, struct tevent_req);
1128         struct cli_api_pipe_state *state = tevent_req_data(
1129                 req, struct cli_api_pipe_state);
1130         NTSTATUS status;
1131
1132         status = state->transport->trans_recv(subreq, state, &state->rdata,
1133                                               &state->rdata_len);
1134         TALLOC_FREE(subreq);
1135         if (!NT_STATUS_IS_OK(status)) {
1136                 tevent_req_nterror(req, status);
1137                 return;
1138         }
1139         tevent_req_done(req);
1140 }
1141
1142 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1143 {
1144         struct tevent_req *req = tevent_req_callback_data(
1145                 subreq, struct tevent_req);
1146         struct cli_api_pipe_state *state = tevent_req_data(
1147                 req, struct cli_api_pipe_state);
1148         NTSTATUS status;
1149
1150         status = rpc_write_recv(subreq);
1151         TALLOC_FREE(subreq);
1152         if (!NT_STATUS_IS_OK(status)) {
1153                 tevent_req_nterror(req, status);
1154                 return;
1155         }
1156
1157         state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1158         if (tevent_req_nomem(state->rdata, req)) {
1159                 return;
1160         }
1161
1162         /*
1163          * We don't need to use rpc_read_send here, the upper layer will cope
1164          * with a short read, transport->trans_send could also return less
1165          * than state->max_rdata_len.
1166          */
1167         subreq = state->transport->read_send(state, state->ev, state->rdata,
1168                                              RPC_HEADER_LEN,
1169                                              state->transport->priv);
1170         if (tevent_req_nomem(subreq, req)) {
1171                 return;
1172         }
1173         tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1174 }
1175
1176 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1177 {
1178         struct tevent_req *req = tevent_req_callback_data(
1179                 subreq, struct tevent_req);
1180         struct cli_api_pipe_state *state = tevent_req_data(
1181                 req, struct cli_api_pipe_state);
1182         NTSTATUS status;
1183         ssize_t received;
1184
1185         status = state->transport->read_recv(subreq, &received);
1186         TALLOC_FREE(subreq);
1187         if (!NT_STATUS_IS_OK(status)) {
1188                 tevent_req_nterror(req, status);
1189                 return;
1190         }
1191         state->rdata_len = received;
1192         tevent_req_done(req);
1193 }
1194
1195 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1196                                   uint8_t **prdata, uint32_t *prdata_len)
1197 {
1198         struct cli_api_pipe_state *state = tevent_req_data(
1199                 req, struct cli_api_pipe_state);
1200         NTSTATUS status;
1201
1202         if (tevent_req_is_nterror(req, &status)) {
1203                 return status;
1204         }
1205
1206         *prdata = talloc_move(mem_ctx, &state->rdata);
1207         *prdata_len = state->rdata_len;
1208         return NT_STATUS_OK;
1209 }
1210
1211 /****************************************************************************
1212  Send data on an rpc pipe via trans. The prs_struct data must be the last
1213  pdu fragment of an NDR data stream.
1214
1215  Receive response data from an rpc pipe, which may be large...
1216
1217  Read the first fragment: unfortunately have to use SMBtrans for the first
1218  bit, then SMBreadX for subsequent bits.
1219
1220  If first fragment received also wasn't the last fragment, continue
1221  getting fragments until we _do_ receive the last fragment.
1222
1223  Request/Response PDU's look like the following...
1224
1225  |<------------------PDU len----------------------------------------------->|
1226  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1227
1228  +------------+-----------------+-------------+---------------+-------------+
1229  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
1230  +------------+-----------------+-------------+---------------+-------------+
1231
1232  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1233  signing & sealing being negotiated.
1234
1235  ****************************************************************************/
1236
1237 struct rpc_api_pipe_state {
1238         struct event_context *ev;
1239         struct rpc_pipe_client *cli;
1240         uint8_t expected_pkt_type;
1241
1242         prs_struct incoming_frag;
1243         struct rpc_hdr_info rhdr;
1244
1245         prs_struct incoming_pdu;        /* Incoming reply */
1246         uint32_t incoming_pdu_offset;
1247 };
1248
1249 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1250 {
1251         prs_mem_free(&state->incoming_frag);
1252         prs_mem_free(&state->incoming_pdu);
1253         return 0;
1254 }
1255
1256 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1257 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1258
1259 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1260                                             struct event_context *ev,
1261                                             struct rpc_pipe_client *cli,
1262                                             prs_struct *data, /* Outgoing PDU */
1263                                             uint8_t expected_pkt_type)
1264 {
1265         struct tevent_req *req, *subreq;
1266         struct rpc_api_pipe_state *state;
1267         uint16_t max_recv_frag;
1268         NTSTATUS status;
1269
1270         req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1271         if (req == NULL) {
1272                 return NULL;
1273         }
1274         state->ev = ev;
1275         state->cli = cli;
1276         state->expected_pkt_type = expected_pkt_type;
1277         state->incoming_pdu_offset = 0;
1278
1279         prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1280
1281         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1282         /* Make incoming_pdu dynamic with no memory. */
1283         prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1284
1285         talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1286
1287         /*
1288          * Ensure we're not sending too much.
1289          */
1290         if (prs_offset(data) > cli->max_xmit_frag) {
1291                 status = NT_STATUS_INVALID_PARAMETER;
1292                 goto post_status;
1293         }
1294
1295         DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
1296
1297         max_recv_frag = cli->max_recv_frag;
1298
1299 #if 0
1300         max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1301 #endif
1302
1303         subreq = cli_api_pipe_send(state, ev, cli->transport,
1304                                    (uint8_t *)prs_data_p(data),
1305                                    prs_offset(data), max_recv_frag);
1306         if (subreq == NULL) {
1307                 goto fail;
1308         }
1309         tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1310         return req;
1311
1312  post_status:
1313         tevent_req_nterror(req, status);
1314         return tevent_req_post(req, ev);
1315  fail:
1316         TALLOC_FREE(req);
1317         return NULL;
1318 }
1319
1320 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1321 {
1322         struct tevent_req *req = tevent_req_callback_data(
1323                 subreq, struct tevent_req);
1324         struct rpc_api_pipe_state *state = tevent_req_data(
1325                 req, struct rpc_api_pipe_state);
1326         NTSTATUS status;
1327         uint8_t *rdata = NULL;
1328         uint32_t rdata_len = 0;
1329         char *rdata_copy;
1330
1331         status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1332         TALLOC_FREE(subreq);
1333         if (!NT_STATUS_IS_OK(status)) {
1334                 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1335                 tevent_req_nterror(req, status);
1336                 return;
1337         }
1338
1339         if (rdata == NULL) {
1340                 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1341                          rpccli_pipe_txt(debug_ctx(), state->cli)));
1342                 tevent_req_done(req);
1343                 return;
1344         }
1345
1346         /*
1347          * Give the memory received from cli_trans as dynamic to the current
1348          * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1349          * :-(
1350          */
1351         rdata_copy = (char *)memdup(rdata, rdata_len);
1352         TALLOC_FREE(rdata);
1353         if (tevent_req_nomem(rdata_copy, req)) {
1354                 return;
1355         }
1356         prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1357
1358         /* Ensure we have enough data for a pdu. */
1359         subreq = get_complete_frag_send(state, state->ev, state->cli,
1360                                         &state->rhdr, &state->incoming_frag);
1361         if (tevent_req_nomem(subreq, req)) {
1362                 return;
1363         }
1364         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1365 }
1366
1367 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1368 {
1369         struct tevent_req *req = tevent_req_callback_data(
1370                 subreq, struct tevent_req);
1371         struct rpc_api_pipe_state *state = tevent_req_data(
1372                 req, struct rpc_api_pipe_state);
1373         NTSTATUS status;
1374         char *rdata = NULL;
1375         uint32_t rdata_len = 0;
1376
1377         status = get_complete_frag_recv(subreq);
1378         TALLOC_FREE(subreq);
1379         if (!NT_STATUS_IS_OK(status)) {
1380                 DEBUG(5, ("get_complete_frag failed: %s\n",
1381                           nt_errstr(status)));
1382                 tevent_req_nterror(req, status);
1383                 return;
1384         }
1385
1386         status = cli_pipe_validate_current_pdu(
1387                 state->cli, &state->rhdr, &state->incoming_frag,
1388                 state->expected_pkt_type, &rdata, &rdata_len,
1389                 &state->incoming_pdu);
1390
1391         DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1392                   (unsigned)prs_data_size(&state->incoming_frag),
1393                   (unsigned)state->incoming_pdu_offset,
1394                   nt_errstr(status)));
1395
1396         if (!NT_STATUS_IS_OK(status)) {
1397                 tevent_req_nterror(req, status);
1398                 return;
1399         }
1400
1401         if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1402             && (state->rhdr.pack_type[0] == 0)) {
1403                 /*
1404                  * Set the data type correctly for big-endian data on the
1405                  * first packet.
1406                  */
1407                 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1408                           "big-endian.\n",
1409                           rpccli_pipe_txt(debug_ctx(), state->cli)));
1410                 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1411         }
1412         /*
1413          * Check endianness on subsequent packets.
1414          */
1415         if (state->incoming_frag.bigendian_data
1416             != state->incoming_pdu.bigendian_data) {
1417                 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1418                          "%s\n",
1419                          state->incoming_pdu.bigendian_data?"big":"little",
1420                          state->incoming_frag.bigendian_data?"big":"little"));
1421                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1422                 return;
1423         }
1424
1425         /* Now copy the data portion out of the pdu into rbuf. */
1426         if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1427                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1428                 return;
1429         }
1430
1431         memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1432                rdata, (size_t)rdata_len);
1433         state->incoming_pdu_offset += rdata_len;
1434
1435         status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1436                                             &state->incoming_frag);
1437         if (!NT_STATUS_IS_OK(status)) {
1438                 tevent_req_nterror(req, status);
1439                 return;
1440         }
1441
1442         if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1443                 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1444                           rpccli_pipe_txt(debug_ctx(), state->cli),
1445                           (unsigned)prs_data_size(&state->incoming_pdu)));
1446                 tevent_req_done(req);
1447                 return;
1448         }
1449
1450         subreq = get_complete_frag_send(state, state->ev, state->cli,
1451                                         &state->rhdr, &state->incoming_frag);
1452         if (tevent_req_nomem(subreq, req)) {
1453                 return;
1454         }
1455         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1456 }
1457
1458 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1459                                   prs_struct *reply_pdu)
1460 {
1461         struct rpc_api_pipe_state *state = tevent_req_data(
1462                 req, struct rpc_api_pipe_state);
1463         NTSTATUS status;
1464
1465         if (tevent_req_is_nterror(req, &status)) {
1466                 return status;
1467         }
1468
1469         *reply_pdu = state->incoming_pdu;
1470         reply_pdu->mem_ctx = mem_ctx;
1471
1472         /*
1473          * Prevent state->incoming_pdu from being freed in
1474          * rpc_api_pipe_state_destructor()
1475          */
1476         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1477
1478         return NT_STATUS_OK;
1479 }
1480
1481 /*******************************************************************
1482  Creates krb5 auth bind.
1483  ********************************************************************/
1484
1485 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1486                                                 enum dcerpc_AuthLevel auth_level,
1487                                                 RPC_HDR_AUTH *pauth_out,
1488                                                 prs_struct *auth_data)
1489 {
1490 #ifdef HAVE_KRB5
1491         int ret;
1492         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1493         DATA_BLOB tkt = data_blob_null;
1494         DATA_BLOB tkt_wrapped = data_blob_null;
1495
1496         /* We may change the pad length before marshalling. */
1497         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1498
1499         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1500                 a->service_principal ));
1501
1502         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1503
1504         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1505                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1506
1507         if (ret) {
1508                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1509                         "failed with %s\n",
1510                         a->service_principal,
1511                         error_message(ret) ));
1512
1513                 data_blob_free(&tkt);
1514                 prs_mem_free(auth_data);
1515                 return NT_STATUS_INVALID_PARAMETER;
1516         }
1517
1518         /* wrap that up in a nice GSS-API wrapping */
1519         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1520
1521         data_blob_free(&tkt);
1522
1523         /* Auth len in the rpc header doesn't include auth_header. */
1524         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1525                 data_blob_free(&tkt_wrapped);
1526                 prs_mem_free(auth_data);
1527                 return NT_STATUS_NO_MEMORY;
1528         }
1529
1530         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1531         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1532
1533         data_blob_free(&tkt_wrapped);
1534         return NT_STATUS_OK;
1535 #else
1536         return NT_STATUS_INVALID_PARAMETER;
1537 #endif
1538 }
1539
1540 /*******************************************************************
1541  Creates SPNEGO NTLMSSP auth bind.
1542  ********************************************************************/
1543
1544 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1545                                                 enum dcerpc_AuthLevel auth_level,
1546                                                 RPC_HDR_AUTH *pauth_out,
1547                                                 prs_struct *auth_data)
1548 {
1549         NTSTATUS nt_status;
1550         DATA_BLOB null_blob = data_blob_null;
1551         DATA_BLOB request = data_blob_null;
1552         DATA_BLOB spnego_msg = data_blob_null;
1553
1554         /* We may change the pad length before marshalling. */
1555         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1556
1557         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1558         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1559                                         null_blob,
1560                                         &request);
1561
1562         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1563                 data_blob_free(&request);
1564                 prs_mem_free(auth_data);
1565                 return nt_status;
1566         }
1567
1568         /* Wrap this in SPNEGO. */
1569         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1570
1571         data_blob_free(&request);
1572
1573         /* Auth len in the rpc header doesn't include auth_header. */
1574         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1575                 data_blob_free(&spnego_msg);
1576                 prs_mem_free(auth_data);
1577                 return NT_STATUS_NO_MEMORY;
1578         }
1579
1580         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1581         dump_data(5, spnego_msg.data, spnego_msg.length);
1582
1583         data_blob_free(&spnego_msg);
1584         return NT_STATUS_OK;
1585 }
1586
1587 /*******************************************************************
1588  Creates NTLMSSP auth bind.
1589  ********************************************************************/
1590
1591 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1592                                                 enum dcerpc_AuthLevel auth_level,
1593                                                 RPC_HDR_AUTH *pauth_out,
1594                                                 prs_struct *auth_data)
1595 {
1596         NTSTATUS nt_status;
1597         DATA_BLOB null_blob = data_blob_null;
1598         DATA_BLOB request = data_blob_null;
1599
1600         /* We may change the pad length before marshalling. */
1601         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1602
1603         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1604         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1605                                         null_blob,
1606                                         &request);
1607
1608         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1609                 data_blob_free(&request);
1610                 prs_mem_free(auth_data);
1611                 return nt_status;
1612         }
1613
1614         /* Auth len in the rpc header doesn't include auth_header. */
1615         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1616                 data_blob_free(&request);
1617                 prs_mem_free(auth_data);
1618                 return NT_STATUS_NO_MEMORY;
1619         }
1620
1621         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1622         dump_data(5, request.data, request.length);
1623
1624         data_blob_free(&request);
1625         return NT_STATUS_OK;
1626 }
1627
1628 /*******************************************************************
1629  Creates schannel auth bind.
1630  ********************************************************************/
1631
1632 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1633                                                 enum dcerpc_AuthLevel auth_level,
1634                                                 RPC_HDR_AUTH *pauth_out,
1635                                                 prs_struct *auth_data)
1636 {
1637         struct NL_AUTH_MESSAGE r;
1638         enum ndr_err_code ndr_err;
1639         DATA_BLOB blob;
1640
1641         /* We may change the pad length before marshalling. */
1642         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1643
1644         /* Use lp_workgroup() if domain not specified */
1645
1646         if (!cli->auth->domain || !cli->auth->domain[0]) {
1647                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1648                 if (cli->auth->domain == NULL) {
1649                         return NT_STATUS_NO_MEMORY;
1650                 }
1651         }
1652
1653         /*
1654          * Now marshall the data into the auth parse_struct.
1655          */
1656
1657         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1658         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1659                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1660         r.oem_netbios_domain.a          = cli->auth->domain;
1661         r.oem_netbios_computer.a        = global_myname();
1662
1663         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1664                        (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1665         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1666                 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1667                 prs_mem_free(auth_data);
1668                 return ndr_map_error2ntstatus(ndr_err);
1669         }
1670
1671         if (DEBUGLEVEL >= 10) {
1672                 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1673         }
1674
1675         if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1676         {
1677                 prs_mem_free(auth_data);
1678                 return NT_STATUS_NO_MEMORY;
1679         }
1680
1681         return NT_STATUS_OK;
1682 }
1683
1684 /*******************************************************************
1685  Creates the internals of a DCE/RPC bind request or alter context PDU.
1686  ********************************************************************/
1687
1688 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1689                                                 prs_struct *rpc_out, 
1690                                                 uint32 rpc_call_id,
1691                                                 const struct ndr_syntax_id *abstract,
1692                                                 const struct ndr_syntax_id *transfer,
1693                                                 RPC_HDR_AUTH *phdr_auth,
1694                                                 prs_struct *pauth_info)
1695 {
1696         RPC_HDR hdr;
1697         RPC_HDR_RB hdr_rb;
1698         RPC_CONTEXT rpc_ctx;
1699         uint16 auth_len = prs_offset(pauth_info);
1700         uint8 ss_padding_len = 0;
1701         uint16 frag_len = 0;
1702
1703         /* create the RPC context. */
1704         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1705
1706         /* create the bind request RPC_HDR_RB */
1707         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1708
1709         /* Start building the frag length. */
1710         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1711
1712         /* Do we need to pad ? */
1713         if (auth_len) {
1714                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1715                 if (data_len % 8) {
1716                         ss_padding_len = 8 - (data_len % 8);
1717                         phdr_auth->auth_pad_len = ss_padding_len;
1718                 }
1719                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1720         }
1721
1722         /* Create the request RPC_HDR */
1723         init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1724
1725         /* Marshall the RPC header */
1726         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1727                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1728                 return NT_STATUS_NO_MEMORY;
1729         }
1730
1731         /* Marshall the bind request data */
1732         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1733                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1734                 return NT_STATUS_NO_MEMORY;
1735         }
1736
1737         /*
1738          * Grow the outgoing buffer to store any auth info.
1739          */
1740
1741         if(auth_len != 0) {
1742                 if (ss_padding_len) {
1743                         char pad[8];
1744                         memset(pad, '\0', 8);
1745                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1746                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1747                                 return NT_STATUS_NO_MEMORY;
1748                         }
1749                 }
1750
1751                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1752                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1753                         return NT_STATUS_NO_MEMORY;
1754                 }
1755
1756
1757                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1758                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1759                         return NT_STATUS_NO_MEMORY;
1760                 }
1761         }
1762
1763         return NT_STATUS_OK;
1764 }
1765
1766 /*******************************************************************
1767  Creates a DCE/RPC bind request.
1768  ********************************************************************/
1769
1770 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1771                                 prs_struct *rpc_out, 
1772                                 uint32 rpc_call_id,
1773                                 const struct ndr_syntax_id *abstract,
1774                                 const struct ndr_syntax_id *transfer,
1775                                 enum pipe_auth_type auth_type,
1776                                 enum dcerpc_AuthLevel auth_level)
1777 {
1778         RPC_HDR_AUTH hdr_auth;
1779         prs_struct auth_info;
1780         NTSTATUS ret = NT_STATUS_OK;
1781
1782         ZERO_STRUCT(hdr_auth);
1783         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1784                 return NT_STATUS_NO_MEMORY;
1785
1786         switch (auth_type) {
1787                 case PIPE_AUTH_TYPE_SCHANNEL:
1788                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1789                         if (!NT_STATUS_IS_OK(ret)) {
1790                                 prs_mem_free(&auth_info);
1791                                 return ret;
1792                         }
1793                         break;
1794
1795                 case PIPE_AUTH_TYPE_NTLMSSP:
1796                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1797                         if (!NT_STATUS_IS_OK(ret)) {
1798                                 prs_mem_free(&auth_info);
1799                                 return ret;
1800                         }
1801                         break;
1802
1803                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1804                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1805                         if (!NT_STATUS_IS_OK(ret)) {
1806                                 prs_mem_free(&auth_info);
1807                                 return ret;
1808                         }
1809                         break;
1810
1811                 case PIPE_AUTH_TYPE_KRB5:
1812                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1813                         if (!NT_STATUS_IS_OK(ret)) {
1814                                 prs_mem_free(&auth_info);
1815                                 return ret;
1816                         }
1817                         break;
1818
1819                 case PIPE_AUTH_TYPE_NONE:
1820                         break;
1821
1822                 default:
1823                         /* "Can't" happen. */
1824                         return NT_STATUS_INVALID_INFO_CLASS;
1825         }
1826
1827         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1828                                                 rpc_out, 
1829                                                 rpc_call_id,
1830                                                 abstract,
1831                                                 transfer,
1832                                                 &hdr_auth,
1833                                                 &auth_info);
1834
1835         prs_mem_free(&auth_info);
1836         return ret;
1837 }
1838
1839 /*******************************************************************
1840  Create and add the NTLMSSP sign/seal auth header and data.
1841  ********************************************************************/
1842
1843 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1844                                         RPC_HDR *phdr,
1845                                         uint32 ss_padding_len,
1846                                         prs_struct *outgoing_pdu)
1847 {
1848         RPC_HDR_AUTH auth_info;
1849         NTSTATUS status;
1850         DATA_BLOB auth_blob = data_blob_null;
1851         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1852
1853         if (!cli->auth->a_u.ntlmssp_state) {
1854                 return NT_STATUS_INVALID_PARAMETER;
1855         }
1856
1857         /* Init and marshall the auth header. */
1858         init_rpc_hdr_auth(&auth_info,
1859                         map_pipe_auth_type_to_rpc_auth_type(
1860                                 cli->auth->auth_type),
1861                         cli->auth->auth_level,
1862                         ss_padding_len,
1863                         1 /* context id. */);
1864
1865         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1866                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1867                 data_blob_free(&auth_blob);
1868                 return NT_STATUS_NO_MEMORY;
1869         }
1870
1871         switch (cli->auth->auth_level) {
1872                 case DCERPC_AUTH_LEVEL_PRIVACY:
1873                         /* Data portion is encrypted. */
1874                         status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1875                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1876                                         data_and_pad_len,
1877                                         (unsigned char *)prs_data_p(outgoing_pdu),
1878                                         (size_t)prs_offset(outgoing_pdu),
1879                                         &auth_blob);
1880                         if (!NT_STATUS_IS_OK(status)) {
1881                                 data_blob_free(&auth_blob);
1882                                 return status;
1883                         }
1884                         break;
1885
1886                 case DCERPC_AUTH_LEVEL_INTEGRITY:
1887                         /* Data is signed. */
1888                         status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1889                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1890                                         data_and_pad_len,
1891                                         (unsigned char *)prs_data_p(outgoing_pdu),
1892                                         (size_t)prs_offset(outgoing_pdu),
1893                                         &auth_blob);
1894                         if (!NT_STATUS_IS_OK(status)) {
1895                                 data_blob_free(&auth_blob);
1896                                 return status;
1897                         }
1898                         break;
1899
1900                 default:
1901                         /* Can't happen. */
1902                         smb_panic("bad auth level");
1903                         /* Notreached. */
1904                         return NT_STATUS_INVALID_PARAMETER;
1905         }
1906
1907         /* Finally marshall the blob. */
1908
1909         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1910                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1911                         (unsigned int)NTLMSSP_SIG_SIZE));
1912                 data_blob_free(&auth_blob);
1913                 return NT_STATUS_NO_MEMORY;
1914         }
1915
1916         data_blob_free(&auth_blob);
1917         return NT_STATUS_OK;
1918 }
1919
1920 /*******************************************************************
1921  Create and add the schannel sign/seal auth header and data.
1922  ********************************************************************/
1923
1924 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1925                                         RPC_HDR *phdr,
1926                                         uint32 ss_padding_len,
1927                                         prs_struct *outgoing_pdu)
1928 {
1929         RPC_HDR_AUTH auth_info;
1930         struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1931         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1932         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1933         DATA_BLOB blob;
1934         NTSTATUS status;
1935
1936         if (!sas) {
1937                 return NT_STATUS_INVALID_PARAMETER;
1938         }
1939
1940         /* Init and marshall the auth header. */
1941         init_rpc_hdr_auth(&auth_info,
1942                         map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1943                         cli->auth->auth_level,
1944                         ss_padding_len,
1945                         1 /* context id. */);
1946
1947         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1948                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1949                 return NT_STATUS_NO_MEMORY;
1950         }
1951
1952         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1953                         sas->seq_num));
1954
1955         switch (cli->auth->auth_level) {
1956         case DCERPC_AUTH_LEVEL_PRIVACY:
1957                 status = netsec_outgoing_packet(sas,
1958                                                 talloc_tos(),
1959                                                 true,
1960                                                 (uint8_t *)data_p,
1961                                                 data_and_pad_len,
1962                                                 &blob);
1963                 break;
1964         case DCERPC_AUTH_LEVEL_INTEGRITY:
1965                 status = netsec_outgoing_packet(sas,
1966                                                 talloc_tos(),
1967                                                 false,
1968                                                 (uint8_t *)data_p,
1969                                                 data_and_pad_len,
1970                                                 &blob);
1971                 break;
1972         default:
1973                 status = NT_STATUS_INTERNAL_ERROR;
1974                 break;
1975         }
1976
1977         if (!NT_STATUS_IS_OK(status)) {
1978                 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1979                         nt_errstr(status)));
1980                 return status;
1981         }
1982
1983         if (DEBUGLEVEL >= 10) {
1984                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1985         }
1986
1987         /* Finally marshall the blob. */
1988         if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
1989                 return NT_STATUS_NO_MEMORY;
1990         }
1991
1992         return NT_STATUS_OK;
1993 }
1994
1995 /*******************************************************************
1996  Calculate how much data we're going to send in this packet, also
1997  work out any sign/seal padding length.
1998  ********************************************************************/
1999
2000 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2001                                         uint32 data_left,
2002                                         uint16 *p_frag_len,
2003                                         uint16 *p_auth_len,
2004                                         uint32 *p_ss_padding)
2005 {
2006         uint32 data_space, data_len;
2007
2008 #if 0
2009         if ((data_left > 0) && (sys_random() % 2)) {
2010                 data_left = MAX(data_left/2, 1);
2011         }
2012 #endif
2013
2014         switch (cli->auth->auth_level) {
2015                 case DCERPC_AUTH_LEVEL_NONE:
2016                 case DCERPC_AUTH_LEVEL_CONNECT:
2017                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2018                         data_len = MIN(data_space, data_left);
2019                         *p_ss_padding = 0;
2020                         *p_auth_len = 0;
2021                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2022                         return data_len;
2023
2024                 case DCERPC_AUTH_LEVEL_INTEGRITY:
2025                 case DCERPC_AUTH_LEVEL_PRIVACY:
2026                         /* Treat the same for all authenticated rpc requests. */
2027                         switch(cli->auth->auth_type) {
2028                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2029                                 case PIPE_AUTH_TYPE_NTLMSSP:
2030                                         *p_auth_len = NTLMSSP_SIG_SIZE;
2031                                         break;
2032                                 case PIPE_AUTH_TYPE_SCHANNEL:
2033                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2034                                         break;
2035                                 default:
2036                                         smb_panic("bad auth type");
2037                                         break;
2038                         }
2039
2040                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2041                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
2042
2043                         data_len = MIN(data_space, data_left);
2044                         *p_ss_padding = 0;
2045                         if (data_len % 8) {
2046                                 *p_ss_padding = 8 - (data_len % 8);
2047                         }
2048                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
2049                                         data_len + *p_ss_padding +              /* data plus padding. */
2050                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
2051                         return data_len;
2052
2053                 default:
2054                         smb_panic("bad auth level");
2055                         /* Notreached. */
2056                         return 0;
2057         }
2058 }
2059
2060 /*******************************************************************
2061  External interface.
2062  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2063  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2064  and deals with signing/sealing details.
2065  ********************************************************************/
2066
2067 struct rpc_api_pipe_req_state {
2068         struct event_context *ev;
2069         struct rpc_pipe_client *cli;
2070         uint8_t op_num;
2071         uint32_t call_id;
2072         prs_struct *req_data;
2073         uint32_t req_data_sent;
2074         prs_struct outgoing_frag;
2075         prs_struct reply_pdu;
2076 };
2077
2078 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2079 {
2080         prs_mem_free(&s->outgoing_frag);
2081         prs_mem_free(&s->reply_pdu);
2082         return 0;
2083 }
2084
2085 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2086 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2087 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2088                                   bool *is_last_frag);
2089
2090 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2091                                          struct event_context *ev,
2092                                          struct rpc_pipe_client *cli,
2093                                          uint8_t op_num,
2094                                          prs_struct *req_data)
2095 {
2096         struct tevent_req *req, *subreq;
2097         struct rpc_api_pipe_req_state *state;
2098         NTSTATUS status;
2099         bool is_last_frag;
2100
2101         req = tevent_req_create(mem_ctx, &state,
2102                                 struct rpc_api_pipe_req_state);
2103         if (req == NULL) {
2104                 return NULL;
2105         }
2106         state->ev = ev;
2107         state->cli = cli;
2108         state->op_num = op_num;
2109         state->req_data = req_data;
2110         state->req_data_sent = 0;
2111         state->call_id = get_rpc_call_id();
2112
2113         if (cli->max_xmit_frag
2114             < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2115                 /* Server is screwed up ! */
2116                 status = NT_STATUS_INVALID_PARAMETER;
2117                 goto post_status;
2118         }
2119
2120         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2121
2122         if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2123                       state, MARSHALL)) {
2124                 goto fail;
2125         }
2126
2127         talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2128
2129         status = prepare_next_frag(state, &is_last_frag);
2130         if (!NT_STATUS_IS_OK(status)) {
2131                 goto post_status;
2132         }
2133
2134         if (is_last_frag) {
2135                 subreq = rpc_api_pipe_send(state, ev, state->cli,
2136                                            &state->outgoing_frag,
2137                                            DCERPC_PKT_RESPONSE);
2138                 if (subreq == NULL) {
2139                         goto fail;
2140                 }
2141                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2142         } else {
2143                 subreq = rpc_write_send(
2144                         state, ev, cli->transport,
2145                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2146                         prs_offset(&state->outgoing_frag));
2147                 if (subreq == NULL) {
2148                         goto fail;
2149                 }
2150                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2151                                         req);
2152         }
2153         return req;
2154
2155  post_status:
2156         tevent_req_nterror(req, status);
2157         return tevent_req_post(req, ev);
2158  fail:
2159         TALLOC_FREE(req);
2160         return NULL;
2161 }
2162
2163 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2164                                   bool *is_last_frag)
2165 {
2166         RPC_HDR hdr;
2167         RPC_HDR_REQ hdr_req;
2168         uint32_t data_sent_thistime;
2169         uint16_t auth_len;
2170         uint16_t frag_len;
2171         uint8_t flags = 0;
2172         uint32_t ss_padding;
2173         uint32_t data_left;
2174         char pad[8] = { 0, };
2175         NTSTATUS status;
2176
2177         data_left = prs_offset(state->req_data) - state->req_data_sent;
2178
2179         data_sent_thistime = calculate_data_len_tosend(
2180                 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2181
2182         if (state->req_data_sent == 0) {
2183                 flags = DCERPC_PFC_FLAG_FIRST;
2184         }
2185
2186         if (data_sent_thistime == data_left) {
2187                 flags |= DCERPC_PFC_FLAG_LAST;
2188         }
2189
2190         if (!prs_set_offset(&state->outgoing_frag, 0)) {
2191                 return NT_STATUS_NO_MEMORY;
2192         }
2193
2194         /* Create and marshall the header and request header. */
2195         init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2196                      auth_len);
2197
2198         if (!smb_io_rpc_hdr("hdr    ", &hdr, &state->outgoing_frag, 0)) {
2199                 return NT_STATUS_NO_MEMORY;
2200         }
2201
2202         /* Create the rpc request RPC_HDR_REQ */
2203         init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2204                          state->op_num);
2205
2206         if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2207                                 &state->outgoing_frag, 0)) {
2208                 return NT_STATUS_NO_MEMORY;
2209         }
2210
2211         /* Copy in the data, plus any ss padding. */
2212         if (!prs_append_some_prs_data(&state->outgoing_frag,
2213                                       state->req_data, state->req_data_sent,
2214                                       data_sent_thistime)) {
2215                 return NT_STATUS_NO_MEMORY;
2216         }
2217
2218         /* Copy the sign/seal padding data. */
2219         if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2220                 return NT_STATUS_NO_MEMORY;
2221         }
2222
2223         /* Generate any auth sign/seal and add the auth footer. */
2224         switch (state->cli->auth->auth_type) {
2225         case PIPE_AUTH_TYPE_NONE:
2226                 status = NT_STATUS_OK;
2227                 break;
2228         case PIPE_AUTH_TYPE_NTLMSSP:
2229         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2230                 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2231                                                  &state->outgoing_frag);
2232                 break;
2233         case PIPE_AUTH_TYPE_SCHANNEL:
2234                 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2235                                                   &state->outgoing_frag);
2236                 break;
2237         default:
2238                 status = NT_STATUS_INVALID_PARAMETER;
2239                 break;
2240         }
2241
2242         state->req_data_sent += data_sent_thistime;
2243         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2244
2245         return status;
2246 }
2247
2248 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2249 {
2250         struct tevent_req *req = tevent_req_callback_data(
2251                 subreq, struct tevent_req);
2252         struct rpc_api_pipe_req_state *state = tevent_req_data(
2253                 req, struct rpc_api_pipe_req_state);
2254         NTSTATUS status;
2255         bool is_last_frag;
2256
2257         status = rpc_write_recv(subreq);
2258         TALLOC_FREE(subreq);
2259         if (!NT_STATUS_IS_OK(status)) {
2260                 tevent_req_nterror(req, status);
2261                 return;
2262         }
2263
2264         status = prepare_next_frag(state, &is_last_frag);
2265         if (!NT_STATUS_IS_OK(status)) {
2266                 tevent_req_nterror(req, status);
2267                 return;
2268         }
2269
2270         if (is_last_frag) {
2271                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2272                                            &state->outgoing_frag,
2273                                            DCERPC_PKT_RESPONSE);
2274                 if (tevent_req_nomem(subreq, req)) {
2275                         return;
2276                 }
2277                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2278         } else {
2279                 subreq = rpc_write_send(
2280                         state, state->ev,
2281                         state->cli->transport,
2282                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2283                         prs_offset(&state->outgoing_frag));
2284                 if (tevent_req_nomem(subreq, req)) {
2285                         return;
2286                 }
2287                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2288                                         req);
2289         }
2290 }
2291
2292 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2293 {
2294         struct tevent_req *req = tevent_req_callback_data(
2295                 subreq, struct tevent_req);
2296         struct rpc_api_pipe_req_state *state = tevent_req_data(
2297                 req, struct rpc_api_pipe_req_state);
2298         NTSTATUS status;
2299
2300         status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2301         TALLOC_FREE(subreq);
2302         if (!NT_STATUS_IS_OK(status)) {
2303                 tevent_req_nterror(req, status);
2304                 return;
2305         }
2306         tevent_req_done(req);
2307 }
2308
2309 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2310                                prs_struct *reply_pdu)
2311 {
2312         struct rpc_api_pipe_req_state *state = tevent_req_data(
2313                 req, struct rpc_api_pipe_req_state);
2314         NTSTATUS status;
2315
2316         if (tevent_req_is_nterror(req, &status)) {
2317                 /*
2318                  * We always have to initialize to reply pdu, even if there is
2319                  * none. The rpccli_* caller routines expect this.
2320                  */
2321                 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2322                 return status;
2323         }
2324
2325         *reply_pdu = state->reply_pdu;
2326         reply_pdu->mem_ctx = mem_ctx;
2327
2328         /*
2329          * Prevent state->req_pdu from being freed in
2330          * rpc_api_pipe_req_state_destructor()
2331          */
2332         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2333
2334         return NT_STATUS_OK;
2335 }
2336
2337 #if 0
2338 /****************************************************************************
2339  Set the handle state.
2340 ****************************************************************************/
2341
2342 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2343                                    const char *pipe_name, uint16 device_state)
2344 {
2345         bool state_set = False;
2346         char param[2];
2347         uint16 setup[2]; /* only need 2 uint16 setup parameters */
2348         char *rparam = NULL;
2349         char *rdata = NULL;
2350         uint32 rparam_len, rdata_len;
2351
2352         if (pipe_name == NULL)
2353                 return False;
2354
2355         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2356                  cli->fnum, pipe_name, device_state));
2357
2358         /* create parameters: device state */
2359         SSVAL(param, 0, device_state);
2360
2361         /* create setup parameters. */
2362         setup[0] = 0x0001; 
2363         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
2364
2365         /* send the data on \PIPE\ */
2366         if (cli_api_pipe(cli->cli, "\\PIPE\\",
2367                     setup, 2, 0,                /* setup, length, max */
2368                     param, 2, 0,                /* param, length, max */
2369                     NULL, 0, 1024,              /* data, length, max */
2370                     &rparam, &rparam_len,        /* return param, length */
2371                     &rdata, &rdata_len))         /* return data, length */
2372         {
2373                 DEBUG(5, ("Set Handle state: return OK\n"));
2374                 state_set = True;
2375         }
2376
2377         SAFE_FREE(rparam);
2378         SAFE_FREE(rdata);
2379
2380         return state_set;
2381 }
2382 #endif
2383
2384 /****************************************************************************
2385  Check the rpc bind acknowledge response.
2386 ****************************************************************************/
2387
2388 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2389                                 const struct ndr_syntax_id *transfer)
2390 {
2391         if ( hdr_ba->addr.len == 0) {
2392                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2393         }
2394
2395         /* check the transfer syntax */
2396         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2397              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2398                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2399                 return False;
2400         }
2401
2402         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2403                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2404                           hdr_ba->res.num_results, hdr_ba->res.reason));
2405         }
2406
2407         DEBUG(5,("check_bind_response: accepted!\n"));
2408         return True;
2409 }
2410
2411 /*******************************************************************
2412  Creates a DCE/RPC bind authentication response.
2413  This is the packet that is sent back to the server once we
2414  have received a BIND-ACK, to finish the third leg of
2415  the authentication handshake.
2416  ********************************************************************/
2417
2418 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2419                                 uint32 rpc_call_id,
2420                                 enum pipe_auth_type auth_type,
2421                                 enum dcerpc_AuthLevel auth_level,
2422                                 DATA_BLOB *pauth_blob,
2423                                 prs_struct *rpc_out)
2424 {
2425         RPC_HDR hdr;
2426         RPC_HDR_AUTH hdr_auth;
2427         uint32 pad = 0;
2428
2429         /* Create the request RPC_HDR */
2430         init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2431                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2432                      pauth_blob->length );
2433
2434         /* Marshall it. */
2435         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2436                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2437                 return NT_STATUS_NO_MEMORY;
2438         }
2439
2440         /*
2441                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2442                 about padding - shouldn't this pad to length 8 ? JRA.
2443         */
2444
2445         /* 4 bytes padding. */
2446         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2447                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2448                 return NT_STATUS_NO_MEMORY;
2449         }
2450
2451         /* Create the request RPC_HDR_AUTHA */
2452         init_rpc_hdr_auth(&hdr_auth,
2453                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
2454                         auth_level, 0, 1);
2455
2456         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2457                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2458                 return NT_STATUS_NO_MEMORY;
2459         }
2460
2461         /*
2462          * Append the auth data to the outgoing buffer.
2463          */
2464
2465         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2466                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2467                 return NT_STATUS_NO_MEMORY;
2468         }
2469
2470         return NT_STATUS_OK;
2471 }
2472
2473 /*******************************************************************
2474  Creates a DCE/RPC bind alter context authentication request which
2475  may contain a spnego auth blobl
2476  ********************************************************************/
2477
2478 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2479                                         const struct ndr_syntax_id *abstract,
2480                                         const struct ndr_syntax_id *transfer,
2481                                         enum dcerpc_AuthLevel auth_level,
2482                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2483                                         prs_struct *rpc_out)
2484 {
2485         RPC_HDR_AUTH hdr_auth;
2486         prs_struct auth_info;
2487         NTSTATUS ret = NT_STATUS_OK;
2488
2489         ZERO_STRUCT(hdr_auth);
2490         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2491                 return NT_STATUS_NO_MEMORY;
2492
2493         /* We may change the pad length before marshalling. */
2494         init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2495
2496         if (pauth_blob->length) {
2497                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2498                         prs_mem_free(&auth_info);
2499                         return NT_STATUS_NO_MEMORY;
2500                 }
2501         }
2502
2503         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2504                                                 rpc_out, 
2505                                                 rpc_call_id,
2506                                                 abstract,
2507                                                 transfer,
2508                                                 &hdr_auth,
2509                                                 &auth_info);
2510         prs_mem_free(&auth_info);
2511         return ret;
2512 }
2513
2514 /****************************************************************************
2515  Do an rpc bind.
2516 ****************************************************************************/
2517
2518 struct rpc_pipe_bind_state {
2519         struct event_context *ev;
2520         struct rpc_pipe_client *cli;
2521         prs_struct rpc_out;
2522         uint32_t rpc_call_id;
2523 };
2524
2525 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2526 {
2527         prs_mem_free(&state->rpc_out);
2528         return 0;
2529 }
2530
2531 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2532 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2533                                            struct rpc_pipe_bind_state *state,
2534                                            struct rpc_hdr_info *phdr,
2535                                            prs_struct *reply_pdu);
2536 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2537 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2538                                                     struct rpc_pipe_bind_state *state,
2539                                                     struct rpc_hdr_info *phdr,
2540                                                     prs_struct *reply_pdu);
2541 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2542
2543 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2544                                       struct event_context *ev,
2545                                       struct rpc_pipe_client *cli,
2546                                       struct cli_pipe_auth_data *auth)
2547 {
2548         struct tevent_req *req, *subreq;
2549         struct rpc_pipe_bind_state *state;
2550         NTSTATUS status;
2551
2552         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2553         if (req == NULL) {
2554                 return NULL;
2555         }
2556
2557         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2558                 rpccli_pipe_txt(debug_ctx(), cli),
2559                 (unsigned int)auth->auth_type,
2560                 (unsigned int)auth->auth_level ));
2561
2562         state->ev = ev;
2563         state->cli = cli;
2564         state->rpc_call_id = get_rpc_call_id();
2565
2566         prs_init_empty(&state->rpc_out, state, MARSHALL);
2567         talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2568
2569         cli->auth = talloc_move(cli, &auth);
2570
2571         /* Marshall the outgoing data. */
2572         status = create_rpc_bind_req(cli, &state->rpc_out,
2573                                      state->rpc_call_id,
2574                                      &cli->abstract_syntax,
2575                                      &cli->transfer_syntax,
2576                                      cli->auth->auth_type,
2577                                      cli->auth->auth_level);
2578
2579         if (!NT_STATUS_IS_OK(status)) {
2580                 goto post_status;
2581         }
2582
2583         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2584                                    DCERPC_PKT_BIND_ACK);
2585         if (subreq == NULL) {
2586                 goto fail;
2587         }
2588         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2589         return req;
2590
2591  post_status:
2592         tevent_req_nterror(req, status);
2593         return tevent_req_post(req, ev);
2594  fail:
2595         TALLOC_FREE(req);
2596         return NULL;
2597 }
2598
2599 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2600 {
2601         struct tevent_req *req = tevent_req_callback_data(
2602                 subreq, struct tevent_req);
2603         struct rpc_pipe_bind_state *state = tevent_req_data(
2604                 req, struct rpc_pipe_bind_state);
2605         prs_struct reply_pdu;
2606         struct rpc_hdr_info hdr;
2607         struct rpc_hdr_ba_info hdr_ba;
2608         NTSTATUS status;
2609
2610         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2611         TALLOC_FREE(subreq);
2612         if (!NT_STATUS_IS_OK(status)) {
2613                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2614                           rpccli_pipe_txt(debug_ctx(), state->cli),
2615                           nt_errstr(status)));
2616                 tevent_req_nterror(req, status);
2617                 return;
2618         }
2619
2620         /* Unmarshall the RPC header */
2621         if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2622                 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2623                 prs_mem_free(&reply_pdu);
2624                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2625                 return;
2626         }
2627
2628         if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2629                 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2630                           "RPC_HDR_BA.\n"));
2631                 prs_mem_free(&reply_pdu);
2632                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2633                 return;
2634         }
2635
2636         if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2637                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2638                 prs_mem_free(&reply_pdu);
2639                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2640                 return;
2641         }
2642
2643         state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2644         state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2645
2646         /*
2647          * For authenticated binds we may need to do 3 or 4 leg binds.
2648          */
2649
2650         switch(state->cli->auth->auth_type) {
2651
2652         case PIPE_AUTH_TYPE_NONE:
2653         case PIPE_AUTH_TYPE_SCHANNEL:
2654                 /* Bind complete. */
2655                 prs_mem_free(&reply_pdu);
2656                 tevent_req_done(req);
2657                 break;
2658
2659         case PIPE_AUTH_TYPE_NTLMSSP:
2660                 /* Need to send AUTH3 packet - no reply. */
2661                 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2662                                                     &reply_pdu);
2663                 prs_mem_free(&reply_pdu);
2664                 if (!NT_STATUS_IS_OK(status)) {
2665                         tevent_req_nterror(req, status);
2666                 }
2667                 break;
2668
2669         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2670                 /* Need to send alter context request and reply. */
2671                 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2672                                                              &reply_pdu);
2673                 prs_mem_free(&reply_pdu);
2674                 if (!NT_STATUS_IS_OK(status)) {
2675                         tevent_req_nterror(req, status);
2676                 }
2677                 break;
2678
2679         case PIPE_AUTH_TYPE_KRB5:
2680                 /* */
2681
2682         default:
2683                 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2684                          (unsigned int)state->cli->auth->auth_type));
2685                 prs_mem_free(&reply_pdu);
2686                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2687         }
2688 }
2689
2690 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2691                                            struct rpc_pipe_bind_state *state,
2692                                            struct rpc_hdr_info *phdr,
2693                                            prs_struct *reply_pdu)
2694 {
2695         DATA_BLOB server_response = data_blob_null;
2696         DATA_BLOB client_reply = data_blob_null;
2697         struct rpc_hdr_auth_info hdr_auth;
2698         struct tevent_req *subreq;
2699         NTSTATUS status;
2700
2701         if ((phdr->auth_len == 0)
2702             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2703                 return NT_STATUS_INVALID_PARAMETER;
2704         }
2705
2706         if (!prs_set_offset(
2707                     reply_pdu,
2708                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2709                 return NT_STATUS_INVALID_PARAMETER;
2710         }
2711
2712         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2713                 return NT_STATUS_INVALID_PARAMETER;
2714         }
2715
2716         /* TODO - check auth_type/auth_level match. */
2717
2718         server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2719         prs_copy_data_out((char *)server_response.data, reply_pdu,
2720                           phdr->auth_len);
2721
2722         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2723                                 server_response, &client_reply);
2724
2725         if (!NT_STATUS_IS_OK(status)) {
2726                 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2727                           "blob failed: %s.\n", nt_errstr(status)));
2728                 return status;
2729         }
2730
2731         prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2732
2733         status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2734                                        state->cli->auth->auth_type,
2735                                        state->cli->auth->auth_level,
2736                                        &client_reply, &state->rpc_out);
2737         data_blob_free(&client_reply);
2738
2739         if (!NT_STATUS_IS_OK(status)) {
2740                 return status;
2741         }
2742
2743         subreq = rpc_write_send(state, state->ev, state->cli->transport,
2744                                 (uint8_t *)prs_data_p(&state->rpc_out),
2745                                 prs_offset(&state->rpc_out));
2746         if (subreq == NULL) {
2747                 return NT_STATUS_NO_MEMORY;
2748         }
2749         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2750         return NT_STATUS_OK;
2751 }
2752
2753 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2754 {
2755         struct tevent_req *req = tevent_req_callback_data(
2756                 subreq, struct tevent_req);
2757         NTSTATUS status;
2758
2759         status = rpc_write_recv(subreq);
2760         TALLOC_FREE(subreq);
2761         if (!NT_STATUS_IS_OK(status)) {
2762                 tevent_req_nterror(req, status);
2763                 return;
2764         }
2765         tevent_req_done(req);
2766 }
2767
2768 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2769                                                     struct rpc_pipe_bind_state *state,
2770                                                     struct rpc_hdr_info *phdr,
2771                                                     prs_struct *reply_pdu)
2772 {
2773         DATA_BLOB server_spnego_response = data_blob_null;
2774         DATA_BLOB server_ntlm_response = data_blob_null;
2775         DATA_BLOB client_reply = data_blob_null;
2776         DATA_BLOB tmp_blob = data_blob_null;
2777         RPC_HDR_AUTH hdr_auth;
2778         struct tevent_req *subreq;
2779         NTSTATUS status;
2780
2781         if ((phdr->auth_len == 0)
2782             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2783                 return NT_STATUS_INVALID_PARAMETER;
2784         }
2785
2786         /* Process the returned NTLMSSP blob first. */
2787         if (!prs_set_offset(
2788                     reply_pdu,
2789                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2790                 return NT_STATUS_INVALID_PARAMETER;
2791         }
2792
2793         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2794                 return NT_STATUS_INVALID_PARAMETER;
2795         }
2796
2797         server_spnego_response = data_blob(NULL, phdr->auth_len);
2798         prs_copy_data_out((char *)server_spnego_response.data,
2799                           reply_pdu, phdr->auth_len);
2800
2801         /*
2802          * The server might give us back two challenges - tmp_blob is for the
2803          * second.
2804          */
2805         if (!spnego_parse_challenge(server_spnego_response,
2806                                     &server_ntlm_response, &tmp_blob)) {
2807                 data_blob_free(&server_spnego_response);
2808                 data_blob_free(&server_ntlm_response);
2809                 data_blob_free(&tmp_blob);
2810                 return NT_STATUS_INVALID_PARAMETER;
2811         }
2812
2813         /* We're finished with the server spnego response and the tmp_blob. */
2814         data_blob_free(&server_spnego_response);
2815         data_blob_free(&tmp_blob);
2816
2817         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2818                                 server_ntlm_response, &client_reply);
2819
2820         /* Finished with the server_ntlm response */
2821         data_blob_free(&server_ntlm_response);
2822
2823         if (!NT_STATUS_IS_OK(status)) {
2824                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2825                           "using server blob failed.\n"));
2826                 data_blob_free(&client_reply);
2827                 return status;
2828         }
2829
2830         /* SPNEGO wrap the client reply. */
2831         tmp_blob = spnego_gen_auth(client_reply);
2832         data_blob_free(&client_reply);
2833         client_reply = tmp_blob;
2834         tmp_blob = data_blob_null;
2835
2836         /* Now prepare the alter context pdu. */
2837         prs_init_empty(&state->rpc_out, state, MARSHALL);
2838
2839         status = create_rpc_alter_context(state->rpc_call_id,
2840                                           &state->cli->abstract_syntax,
2841                                           &state->cli->transfer_syntax,
2842                                           state->cli->auth->auth_level,
2843                                           &client_reply,
2844                                           &state->rpc_out);
2845         data_blob_free(&client_reply);
2846
2847         if (!NT_STATUS_IS_OK(status)) {
2848                 return status;
2849         }
2850
2851         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2852                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2853         if (subreq == NULL) {
2854                 return NT_STATUS_NO_MEMORY;
2855         }
2856         tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2857         return NT_STATUS_OK;
2858 }
2859
2860 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2861 {
2862         struct tevent_req *req = tevent_req_callback_data(
2863                 subreq, struct tevent_req);
2864         struct rpc_pipe_bind_state *state = tevent_req_data(
2865                 req, struct rpc_pipe_bind_state);
2866         DATA_BLOB server_spnego_response = data_blob_null;
2867         DATA_BLOB tmp_blob = data_blob_null;
2868         prs_struct reply_pdu;
2869         struct rpc_hdr_info hdr;
2870         struct rpc_hdr_auth_info hdr_auth;
2871         NTSTATUS status;
2872
2873         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2874         TALLOC_FREE(subreq);
2875         if (!NT_STATUS_IS_OK(status)) {
2876                 tevent_req_nterror(req, status);
2877                 return;
2878         }
2879
2880         /* Get the auth blob from the reply. */
2881         if (!smb_io_rpc_hdr("rpc_hdr   ", &hdr, &reply_pdu, 0)) {
2882                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2883                           "unmarshall RPC_HDR.\n"));
2884                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2885                 return;
2886         }
2887
2888         if (!prs_set_offset(
2889                     &reply_pdu,
2890                     hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2891                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2892                 return;
2893         }
2894
2895         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2896                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2897                 return;
2898         }
2899
2900         server_spnego_response = data_blob(NULL, hdr.auth_len);
2901         prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2902                           hdr.auth_len);
2903
2904         /* Check we got a valid auth response. */
2905         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2906                                         OID_NTLMSSP, &tmp_blob)) {
2907                 data_blob_free(&server_spnego_response);
2908                 data_blob_free(&tmp_blob);
2909                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2910                 return;
2911         }
2912
2913         data_blob_free(&server_spnego_response);
2914         data_blob_free(&tmp_blob);
2915
2916         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2917                  "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
2918         tevent_req_done(req);
2919 }
2920
2921 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2922 {
2923         return tevent_req_simple_recv_ntstatus(req);
2924 }
2925
2926 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2927                        struct cli_pipe_auth_data *auth)
2928 {
2929         TALLOC_CTX *frame = talloc_stackframe();
2930         struct event_context *ev;
2931         struct tevent_req *req;
2932         NTSTATUS status = NT_STATUS_OK;
2933
2934         ev = event_context_init(frame);
2935         if (ev == NULL) {
2936                 status = NT_STATUS_NO_MEMORY;
2937                 goto fail;
2938         }
2939
2940         req = rpc_pipe_bind_send(frame, ev, cli, auth);
2941         if (req == NULL) {
2942                 status = NT_STATUS_NO_MEMORY;
2943                 goto fail;
2944         }
2945
2946         if (!tevent_req_poll(req, ev)) {
2947                 status = map_nt_error_from_unix(errno);
2948                 goto fail;
2949         }
2950
2951         status = rpc_pipe_bind_recv(req);
2952  fail:
2953         TALLOC_FREE(frame);
2954         return status;
2955 }
2956
2957 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2958                                 unsigned int timeout)
2959 {
2960         struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
2961
2962         if (cli == NULL) {
2963                 return 0;
2964         }
2965         return cli_set_timeout(cli, timeout);
2966 }
2967
2968 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2969 {
2970         struct cli_state *cli;
2971
2972         if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2973             || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2974                 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2975                 return true;
2976         }
2977
2978         cli = rpc_pipe_np_smb_conn(rpc_cli);
2979         if (cli == NULL) {
2980                 return false;
2981         }
2982         E_md4hash(cli->password ? cli->password : "", nt_hash);
2983         return true;
2984 }
2985
2986 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2987                                struct cli_pipe_auth_data **presult)
2988 {
2989         struct cli_pipe_auth_data *result;
2990
2991         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2992         if (result == NULL) {
2993                 return NT_STATUS_NO_MEMORY;
2994         }
2995
2996         result->auth_type = PIPE_AUTH_TYPE_NONE;
2997         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2998
2999         result->user_name = talloc_strdup(result, "");
3000         result->domain = talloc_strdup(result, "");
3001         if ((result->user_name == NULL) || (result->domain == NULL)) {
3002                 TALLOC_FREE(result);
3003                 return NT_STATUS_NO_MEMORY;
3004         }
3005
3006         *presult = result;
3007         return NT_STATUS_OK;
3008 }
3009
3010 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3011 {
3012         ntlmssp_end(&auth->a_u.ntlmssp_state);
3013         return 0;
3014 }
3015
3016 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3017                                   enum pipe_auth_type auth_type,
3018                                   enum dcerpc_AuthLevel auth_level,
3019                                   const char *domain,
3020                                   const char *username,
3021                                   const char *password,
3022                                   struct cli_pipe_auth_data **presult)
3023 {
3024         struct cli_pipe_auth_data *result;
3025         NTSTATUS status;
3026
3027         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3028         if (result == NULL) {
3029                 return NT_STATUS_NO_MEMORY;
3030         }
3031
3032         result->auth_type = auth_type;
3033         result->auth_level = auth_level;
3034
3035         result->user_name = talloc_strdup(result, username);
3036         result->domain = talloc_strdup(result, domain);
3037         if ((result->user_name == NULL) || (result->domain == NULL)) {
3038                 status = NT_STATUS_NO_MEMORY;
3039                 goto fail;
3040         }
3041
3042         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3043         if (!NT_STATUS_IS_OK(status)) {
3044                 goto fail;
3045         }
3046
3047         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3048
3049         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3050         if (!NT_STATUS_IS_OK(status)) {
3051                 goto fail;
3052         }
3053
3054         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3055         if (!NT_STATUS_IS_OK(status)) {
3056                 goto fail;
3057         }
3058
3059         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3060         if (!NT_STATUS_IS_OK(status)) {
3061                 goto fail;
3062         }
3063
3064         /*
3065          * Turn off sign+seal to allow selected auth level to turn it back on.
3066          */
3067         result->a_u.ntlmssp_state->neg_flags &=
3068                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3069
3070         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3071                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3072         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3073                 result->a_u.ntlmssp_state->neg_flags
3074                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3075         }
3076
3077         *presult = result;
3078         return NT_STATUS_OK;
3079
3080  fail:
3081         TALLOC_FREE(result);
3082         return status;
3083 }
3084
3085 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3086                                    enum dcerpc_AuthLevel auth_level,
3087                                    struct netlogon_creds_CredentialState *creds,
3088                                    struct cli_pipe_auth_data **presult)
3089 {
3090         struct cli_pipe_auth_data *result;
3091
3092         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3093         if (result == NULL) {
3094                 return NT_STATUS_NO_MEMORY;
3095         }
3096
3097         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3098         result->auth_level = auth_level;
3099
3100         result->user_name = talloc_strdup(result, "");
3101         result->domain = talloc_strdup(result, domain);
3102         if ((result->user_name == NULL) || (result->domain == NULL)) {
3103                 goto fail;
3104         }
3105
3106         result->a_u.schannel_auth = talloc(result, struct schannel_state);
3107         if (result->a_u.schannel_auth == NULL) {
3108                 goto fail;
3109         }
3110
3111         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3112         result->a_u.schannel_auth->seq_num = 0;
3113         result->a_u.schannel_auth->initiator = true;
3114         result->a_u.schannel_auth->creds = creds;
3115
3116         *presult = result;
3117         return NT_STATUS_OK;
3118
3119  fail:
3120         TALLOC_FREE(result);
3121         return NT_STATUS_NO_MEMORY;
3122 }
3123
3124 #ifdef HAVE_KRB5
3125 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3126 {
3127         data_blob_free(&auth->session_key);
3128         return 0;
3129 }
3130 #endif
3131
3132 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3133                                    enum dcerpc_AuthLevel auth_level,
3134                                    const char *service_princ,
3135                                    const char *username,
3136                                    const char *password,
3137                                    struct cli_pipe_auth_data **presult)
3138 {
3139 #ifdef HAVE_KRB5
3140         struct cli_pipe_auth_data *result;
3141
3142         if ((username != NULL) && (password != NULL)) {
3143                 int ret = kerberos_kinit_password(username, password, 0, NULL);
3144                 if (ret != 0) {
3145                         return NT_STATUS_ACCESS_DENIED;
3146                 }
3147         }
3148
3149         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3150         if (result == NULL) {
3151                 return NT_STATUS_NO_MEMORY;
3152         }
3153
3154         result->auth_type = PIPE_AUTH_TYPE_KRB5;
3155         result->auth_level = auth_level;
3156
3157         /*
3158          * Username / domain need fixing!
3159          */
3160         result->user_name = talloc_strdup(result, "");
3161         result->domain = talloc_strdup(result, "");
3162         if ((result->user_name == NULL) || (result->domain == NULL)) {
3163                 goto fail;
3164         }
3165
3166         result->a_u.kerberos_auth = TALLOC_ZERO_P(
3167                 result, struct kerberos_auth_struct);
3168         if (result->a_u.kerberos_auth == NULL) {
3169                 goto fail;
3170         }
3171         talloc_set_destructor(result->a_u.kerberos_auth,
3172                               cli_auth_kerberos_data_destructor);
3173
3174         result->a_u.kerberos_auth->service_principal = talloc_strdup(
3175                 result, service_princ);
3176         if (result->a_u.kerberos_auth->service_principal == NULL) {
3177                 goto fail;
3178         }
3179
3180         *presult = result;
3181         return NT_STATUS_OK;
3182
3183  fail:
3184         TALLOC_FREE(result);
3185         return NT_STATUS_NO_MEMORY;
3186 #else
3187         return NT_STATUS_NOT_SUPPORTED;
3188 #endif
3189 }
3190
3191 /**
3192  * Create an rpc pipe client struct, connecting to a tcp port.
3193  */
3194 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3195                                        uint16_t port,
3196                                        const struct ndr_syntax_id *abstract_syntax,
3197                                        struct rpc_pipe_client **presult)
3198 {
3199         struct rpc_pipe_client *result;
3200         struct sockaddr_storage addr;
3201         NTSTATUS status;
3202         int fd;
3203
3204         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3205         if (result == NULL) {
3206                 return NT_STATUS_NO_MEMORY;
3207         }
3208
3209         result->abstract_syntax = *abstract_syntax;
3210         result->transfer_syntax = ndr_transfer_syntax;
3211         result->dispatch = cli_do_rpc_ndr;
3212         result->dispatch_send = cli_do_rpc_ndr_send;
3213         result->dispatch_recv = cli_do_rpc_ndr_recv;
3214
3215         result->desthost = talloc_strdup(result, host);
3216         result->srv_name_slash = talloc_asprintf_strupper_m(
3217                 result, "\\\\%s", result->desthost);
3218         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3219                 status = NT_STATUS_NO_MEMORY;
3220                 goto fail;
3221         }
3222
3223         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3224         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3225
3226         if (!resolve_name(host, &addr, 0, false)) {
3227                 status = NT_STATUS_NOT_FOUND;
3228                 goto fail;
3229         }
3230
3231         status = open_socket_out(&addr, port, 60, &fd);
3232         if (!NT_STATUS_IS_OK(status)) {
3233                 goto fail;
3234         }
3235         set_socket_options(fd, lp_socket_options());
3236
3237         status = rpc_transport_sock_init(result, fd, &result->transport);
3238         if (!NT_STATUS_IS_OK(status)) {
3239                 close(fd);
3240                 goto fail;
3241         }
3242
3243         result->transport->transport = NCACN_IP_TCP;
3244
3245         *presult = result;
3246         return NT_STATUS_OK;
3247
3248  fail:
3249         TALLOC_FREE(result);
3250         return status;
3251 }
3252
3253 /**
3254  * Determine the tcp port on which a dcerpc interface is listening
3255  * for the ncacn_ip_tcp transport via the endpoint mapper of the
3256  * target host.
3257  */
3258 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3259                                       const struct ndr_syntax_id *abstract_syntax,
3260                                       uint16_t *pport)
3261 {
3262         NTSTATUS status;
3263         struct rpc_pipe_client *epm_pipe = NULL;
3264         struct cli_pipe_auth_data *auth = NULL;
3265         struct dcerpc_binding *map_binding = NULL;
3266         struct dcerpc_binding *res_binding = NULL;
3267         struct epm_twr_t *map_tower = NULL;
3268         struct epm_twr_t *res_towers = NULL;
3269         struct policy_handle *entry_handle = NULL;
3270         uint32_t num_towers = 0;
3271         uint32_t max_towers = 1;
3272         struct epm_twr_p_t towers;
3273         TALLOC_CTX *tmp_ctx = talloc_stackframe();
3274
3275         if (pport == NULL) {
3276                 status = NT_STATUS_INVALID_PARAMETER;
3277                 goto done;
3278         }
3279
3280         /* open the connection to the endpoint mapper */
3281         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3282                                         &ndr_table_epmapper.syntax_id,
3283                                         &epm_pipe);
3284
3285         if (!NT_STATUS_IS_OK(status)) {
3286                 goto done;
3287         }
3288
3289         status = rpccli_anon_bind_data(tmp_ctx, &auth);
3290         if (!NT_STATUS_IS_OK(status)) {
3291                 goto done;
3292         }
3293
3294         status = rpc_pipe_bind(epm_pipe, auth);
3295         if (!NT_STATUS_IS_OK(status)) {
3296                 goto done;
3297         }
3298
3299         /* create tower for asking the epmapper */
3300
3301         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3302         if (map_binding == NULL) {
3303                 status = NT_STATUS_NO_MEMORY;
3304                 goto done;
3305         }
3306
3307         map_binding->transport = NCACN_IP_TCP;
3308         map_binding->object = *abstract_syntax;
3309         map_binding->host = host; /* needed? */
3310         map_binding->endpoint = "0"; /* correct? needed? */
3311
3312         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3313         if (map_tower == NULL) {
3314                 status = NT_STATUS_NO_MEMORY;
3315                 goto done;
3316         }
3317
3318         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3319                                             &(map_tower->tower));
3320         if (!NT_STATUS_IS_OK(status)) {
3321                 goto done;
3322         }
3323
3324         /* allocate further parameters for the epm_Map call */
3325
3326         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3327         if (res_towers == NULL) {
3328                 status = NT_STATUS_NO_MEMORY;
3329                 goto done;
3330         }
3331         towers.twr = res_towers;
3332
3333         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3334         if (entry_handle == NULL) {
3335                 status = NT_STATUS_NO_MEMORY;
3336                 goto done;
3337         }
3338
3339         /* ask the endpoint mapper for the port */
3340
3341         status = rpccli_epm_Map(epm_pipe,
3342                                 tmp_ctx,
3343                                 CONST_DISCARD(struct GUID *,
3344                                               &(abstract_syntax->uuid)),
3345                                 map_tower,
3346                                 entry_handle,
3347                                 max_towers,
3348                                 &num_towers,
3349                                 &towers);
3350
3351         if (!NT_STATUS_IS_OK(status)) {
3352                 goto done;
3353         }
3354
3355         if (num_towers != 1) {
3356                 status = NT_STATUS_UNSUCCESSFUL;
3357                 goto done;
3358         }
3359
3360         /* extract the port from the answer */
3361
3362         status = dcerpc_binding_from_tower(tmp_ctx,
3363                                            &(towers.twr->tower),
3364                                            &res_binding);
3365         if (!NT_STATUS_IS_OK(status)) {
3366                 goto done;
3367         }
3368
3369         /* are further checks here necessary? */
3370         if (res_binding->transport != NCACN_IP_TCP) {
3371                 status = NT_STATUS_UNSUCCESSFUL;
3372                 goto done;
3373         }
3374
3375         *pport = (uint16_t)atoi(res_binding->endpoint);
3376
3377 done:
3378         TALLOC_FREE(tmp_ctx);
3379         return status;
3380 }
3381
3382 /**
3383  * Create a rpc pipe client struct, connecting to a host via tcp.
3384  * The port is determined by asking the endpoint mapper on the given
3385  * host.
3386  */
3387 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3388                            const struct ndr_syntax_id *abstract_syntax,
3389                            struct rpc_pipe_client **presult)
3390 {
3391         NTSTATUS status;
3392         uint16_t port = 0;
3393
3394         *presult = NULL;
3395
3396         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3397         if (!NT_STATUS_IS_OK(status)) {
3398                 goto done;
3399         }
3400
3401         status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3402                                         abstract_syntax, presult);
3403
3404 done:
3405         return status;
3406 }
3407
3408 /********************************************************************
3409  Create a rpc pipe client struct, connecting to a unix domain socket
3410  ********************************************************************/
3411 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3412                                const struct ndr_syntax_id *abstract_syntax,
3413                                struct rpc_pipe_client **presult)
3414 {
3415         struct rpc_pipe_client *result;
3416         struct sockaddr_un addr;
3417         NTSTATUS status;
3418         int fd;
3419
3420         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3421         if (result == NULL) {
3422                 return NT_STATUS_NO_MEMORY;
3423         }
3424
3425         result->abstract_syntax = *abstract_syntax;
3426         result->transfer_syntax = ndr_transfer_syntax;
3427         result->dispatch = cli_do_rpc_ndr;
3428         result->dispatch_send = cli_do_rpc_ndr_send;
3429         result->dispatch_recv = cli_do_rpc_ndr_recv;
3430
3431         result->desthost = get_myname(result);
3432         result->srv_name_slash = talloc_asprintf_strupper_m(
3433                 result, "\\\\%s", result->desthost);
3434         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3435                 status = NT_STATUS_NO_MEMORY;
3436                 goto fail;
3437         }
3438
3439         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3440         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3441
3442         fd = socket(AF_UNIX, SOCK_STREAM, 0);
3443         if (fd == -1) {
3444                 status = map_nt_error_from_unix(errno);
3445                 goto fail;
3446         }
3447
3448         ZERO_STRUCT(addr);
3449         addr.sun_family = AF_UNIX;
3450         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3451
3452         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3453                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3454                           strerror(errno)));
3455                 close(fd);
3456                 return map_nt_error_from_unix(errno);
3457         }
3458
3459         status = rpc_transport_sock_init(result, fd, &result->transport);
3460         if (!NT_STATUS_IS_OK(status)) {
3461                 close(fd);
3462                 goto fail;
3463         }
3464
3465         result->transport->transport = NCALRPC;
3466
3467         *presult = result;
3468         return NT_STATUS_OK;
3469
3470  fail:
3471         TALLOC_FREE(result);
3472         return status;
3473 }
3474
3475 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3476 {
3477         struct cli_state *cli;
3478
3479         cli = rpc_pipe_np_smb_conn(p);
3480         if (cli != NULL) {
3481                 DLIST_REMOVE(cli->pipe_list, p);
3482         }
3483         return 0;
3484 }
3485
3486 /****************************************************************************
3487  Open a named pipe over SMB to a remote server.
3488  *
3489  * CAVEAT CALLER OF THIS FUNCTION:
3490  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3491  *    so be sure that this function is called AFTER any structure (vs pointer)
3492  *    assignment of the cli.  In particular, libsmbclient does structure
3493  *    assignments of cli, which invalidates the data in the returned
3494  *    rpc_pipe_client if this function is called before the structure assignment
3495  *    of cli.
3496  * 
3497  ****************************************************************************/
3498
3499 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3500                                  const struct ndr_syntax_id *abstract_syntax,
3501                                  struct rpc_pipe_client **presult)
3502 {
3503         struct rpc_pipe_client *result;
3504         NTSTATUS status;
3505
3506         /* sanity check to protect against crashes */
3507
3508         if ( !cli ) {
3509                 return NT_STATUS_INVALID_HANDLE;
3510         }
3511
3512         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3513         if (result == NULL) {
3514                 return NT_STATUS_NO_MEMORY;
3515         }
3516
3517         result->abstract_syntax = *abstract_syntax;
3518         result->transfer_syntax = ndr_transfer_syntax;
3519         result->dispatch = cli_do_rpc_ndr;
3520         result->dispatch_send = cli_do_rpc_ndr_send;
3521         result->dispatch_recv = cli_do_rpc_ndr_recv;
3522         result->desthost = talloc_strdup(result, cli->desthost);
3523         result->srv_name_slash = talloc_asprintf_strupper_m(
3524                 result, "\\\\%s", result->desthost);
3525
3526         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3527         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3528
3529         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3530                 TALLOC_FREE(result);
3531                 return NT_STATUS_NO_MEMORY;
3532         }
3533
3534         status = rpc_transport_np_init(result, cli, abstract_syntax,
3535                                        &result->transport);
3536         if (!NT_STATUS_IS_OK(status)) {
3537                 TALLOC_FREE(result);
3538                 return status;
3539         }
3540
3541         result->transport->transport = NCACN_NP;
3542
3543         DLIST_ADD(cli->pipe_list, result);
3544         talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3545
3546         *presult = result;
3547         return NT_STATUS_OK;
3548 }
3549
3550 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3551                              struct rpc_cli_smbd_conn *conn,
3552                              const struct ndr_syntax_id *syntax,
3553                              struct rpc_pipe_client **presult)
3554 {
3555         struct rpc_pipe_client *result;
3556         struct cli_pipe_auth_data *auth;
3557         NTSTATUS status;
3558
3559         result = talloc(mem_ctx, struct rpc_pipe_client);
3560         if (result == NULL) {
3561                 return NT_STATUS_NO_MEMORY;
3562         }
3563         result->abstract_syntax = *syntax;
3564         result->transfer_syntax = ndr_transfer_syntax;
3565         result->dispatch = cli_do_rpc_ndr;
3566         result->dispatch_send = cli_do_rpc_ndr_send;
3567         result->dispatch_recv = cli_do_rpc_ndr_recv;
3568         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3569         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3570
3571         result->desthost = talloc_strdup(result, global_myname());
3572         result->srv_name_slash = talloc_asprintf_strupper_m(
3573                 result, "\\\\%s", global_myname());
3574         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3575                 TALLOC_FREE(result);
3576                 return NT_STATUS_NO_MEMORY;
3577         }
3578
3579         status = rpc_transport_smbd_init(result, conn, syntax,
3580                                          &result->transport);
3581         if (!NT_STATUS_IS_OK(status)) {
3582                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3583                           nt_errstr(status)));
3584                 TALLOC_FREE(result);
3585                 return status;
3586         }
3587
3588         status = rpccli_anon_bind_data(result, &auth);
3589         if (!NT_STATUS_IS_OK(status)) {
3590                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3591                           nt_errstr(status)));
3592                 TALLOC_FREE(result);
3593                 return status;
3594         }
3595
3596         status = rpc_pipe_bind(result, auth);
3597         if (!NT_STATUS_IS_OK(status)) {
3598                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3599                 TALLOC_FREE(result);
3600                 return status;
3601         }
3602
3603         result->transport->transport = NCACN_INTERNAL;
3604
3605         *presult = result;
3606         return NT_STATUS_OK;
3607 }
3608
3609 /****************************************************************************
3610  Open a pipe to a remote server.
3611  ****************************************************************************/
3612
3613 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3614                                   enum dcerpc_transport_t transport,
3615                                   const struct ndr_syntax_id *interface,
3616                                   struct rpc_pipe_client **presult)
3617 {
3618         switch (transport) {
3619         case NCACN_IP_TCP:
3620                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3621                                          presult);
3622         case NCACN_NP:
3623                 return rpc_pipe_open_np(cli, interface, presult);
3624         default:
3625                 return NT_STATUS_NOT_IMPLEMENTED;
3626         }
3627 }
3628
3629 /****************************************************************************
3630  Open a named pipe to an SMB server and bind anonymously.
3631  ****************************************************************************/
3632
3633 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3634                                             enum dcerpc_transport_t transport,
3635                                             const struct ndr_syntax_id *interface,
3636                                             struct rpc_pipe_client **presult)
3637 {
3638         struct rpc_pipe_client *result;
3639         struct cli_pipe_auth_data *auth;
3640         NTSTATUS status;
3641
3642         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3643         if (!NT_STATUS_IS_OK(status)) {
3644                 return status;
3645         }
3646
3647         status = rpccli_anon_bind_data(result, &auth);
3648         if (!NT_STATUS_IS_OK(status)) {
3649                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3650                           nt_errstr(status)));
3651                 TALLOC_FREE(result);
3652                 return status;
3653         }
3654
3655         /*
3656          * This is a bit of an abstraction violation due to the fact that an
3657          * anonymous bind on an authenticated SMB inherits the user/domain
3658          * from the enclosing SMB creds
3659          */
3660
3661         TALLOC_FREE(auth->user_name);
3662         TALLOC_FREE(auth->domain);
3663
3664         auth->user_name = talloc_strdup(auth, cli->user_name);
3665         auth->domain = talloc_strdup(auth, cli->domain);
3666         auth->user_session_key = data_blob_talloc(auth,
3667                 cli->user_session_key.data,
3668                 cli->user_session_key.length);
3669
3670         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3671                 TALLOC_FREE(result);
3672                 return NT_STATUS_NO_MEMORY;
3673         }
3674
3675         status = rpc_pipe_bind(result, auth);
3676         if (!NT_STATUS_IS_OK(status)) {
3677                 int lvl = 0;
3678                 if (ndr_syntax_id_equal(interface,
3679                                         &ndr_table_dssetup.syntax_id)) {
3680                         /* non AD domains just don't have this pipe, avoid
3681                          * level 0 statement in that case - gd */
3682                         lvl = 3;
3683                 }
3684                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3685                             "%s failed with error %s\n",
3686                             get_pipe_name_from_iface(interface),
3687                             nt_errstr(status) ));
3688                 TALLOC_FREE(result);
3689                 return status;
3690         }
3691
3692         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3693                   "%s and bound anonymously.\n",
3694                   get_pipe_name_from_iface(interface), cli->desthost));
3695
3696         *presult = result;
3697         return NT_STATUS_OK;
3698 }
3699
3700 /****************************************************************************
3701  ****************************************************************************/
3702
3703 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3704                                   const struct ndr_syntax_id *interface,
3705                                   struct rpc_pipe_client **presult)
3706 {
3707         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3708                                                   interface, presult);
3709 }
3710
3711 /****************************************************************************
3712  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3713  ****************************************************************************/
3714
3715 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3716                                                    const struct ndr_syntax_id *interface,
3717                                                    enum dcerpc_transport_t transport,
3718                                                    enum pipe_auth_type auth_type,
3719                                                    enum dcerpc_AuthLevel auth_level,
3720                                                    const char *domain,
3721                                                    const char *username,
3722                                                    const char *password,
3723                                                    struct rpc_pipe_client **presult)
3724 {
3725         struct rpc_pipe_client *result;
3726         struct cli_pipe_auth_data *auth;
3727         NTSTATUS status;
3728
3729         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3730         if (!NT_STATUS_IS_OK(status)) {
3731                 return status;
3732         }
3733
3734         status = rpccli_ntlmssp_bind_data(
3735                 result, auth_type, auth_level, domain, username,
3736                 password, &auth);
3737         if (!NT_STATUS_IS_OK(status)) {
3738                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3739                           nt_errstr(status)));
3740                 goto err;
3741         }
3742
3743         status = rpc_pipe_bind(result, auth);
3744         if (!NT_STATUS_IS_OK(status)) {
3745                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3746                         nt_errstr(status) ));
3747                 goto err;
3748         }
3749
3750         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3751                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3752                   get_pipe_name_from_iface(interface), cli->desthost, domain,
3753                   username ));
3754
3755         *presult = result;
3756         return NT_STATUS_OK;
3757
3758   err:
3759
3760         TALLOC_FREE(result);
3761         return status;
3762 }
3763
3764 /****************************************************************************
3765  External interface.
3766  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3767  ****************************************************************************/
3768
3769 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3770                                    const struct ndr_syntax_id *interface,
3771                                    enum dcerpc_transport_t transport,
3772                                    enum dcerpc_AuthLevel auth_level,
3773                                    const char *domain,
3774                                    const char *username,
3775                                    const char *password,
3776                                    struct rpc_pipe_client **presult)
3777 {
3778         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3779                                                 interface,
3780                                                 transport,
3781                                                 PIPE_AUTH_TYPE_NTLMSSP,
3782                                                 auth_level,
3783                                                 domain,
3784                                                 username,
3785                                                 password,
3786                                                 presult);
3787 }
3788
3789 /****************************************************************************
3790  External interface.
3791  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3792  ****************************************************************************/
3793
3794 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3795                                           const struct ndr_syntax_id *interface,
3796                                           enum dcerpc_transport_t transport,
3797                                           enum dcerpc_AuthLevel auth_level,
3798                                           const char *domain,
3799                                           const char *username,
3800                                           const char *password,
3801                                           struct rpc_pipe_client **presult)
3802 {
3803         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3804                                                 interface,
3805                                                 transport,
3806                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3807                                                 auth_level,
3808                                                 domain,
3809                                                 username,
3810                                                 password,
3811                                                 presult);
3812 }
3813
3814 /****************************************************************************
3815   Get a the schannel session key out of an already opened netlogon pipe.
3816  ****************************************************************************/
3817 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3818                                                 struct cli_state *cli,
3819                                                 const char *domain,
3820                                                 uint32 *pneg_flags)
3821 {
3822         uint32 sec_chan_type = 0;
3823         unsigned char machine_pwd[16];
3824         const char *machine_account;
3825         NTSTATUS status;
3826
3827         /* Get the machine account credentials from secrets.tdb. */
3828         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3829                                &sec_chan_type))
3830         {
3831                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3832                         "trust account password for domain '%s'\n",
3833                         domain));
3834                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3835         }
3836
3837         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3838                                         cli->desthost, /* server name */
3839                                         domain,        /* domain */
3840                                         global_myname(), /* client name */
3841                                         machine_account, /* machine account name */
3842                                         machine_pwd,
3843                                         sec_chan_type,
3844                                         pneg_flags);
3845
3846         if (!NT_STATUS_IS_OK(status)) {
3847                 DEBUG(3, ("get_schannel_session_key_common: "
3848                           "rpccli_netlogon_setup_creds failed with result %s "
3849                           "to server %s, domain %s, machine account %s.\n",
3850                           nt_errstr(status), cli->desthost, domain,
3851                           machine_account ));
3852                 return status;
3853         }
3854
3855         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3856                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3857                         cli->desthost));
3858                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3859         }
3860
3861         return NT_STATUS_OK;;
3862 }
3863
3864 /****************************************************************************
3865  Open a netlogon pipe and get the schannel session key.
3866  Now exposed to external callers.
3867  ****************************************************************************/
3868
3869
3870 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3871                                   const char *domain,
3872                                   uint32 *pneg_flags,
3873                                   struct rpc_pipe_client **presult)
3874 {
3875         struct rpc_pipe_client *netlogon_pipe = NULL;
3876         NTSTATUS status;
3877
3878         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3879                                           &netlogon_pipe);
3880         if (!NT_STATUS_IS_OK(status)) {
3881                 return status;
3882         }
3883
3884         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3885                                                  pneg_flags);
3886         if (!NT_STATUS_IS_OK(status)) {
3887                 TALLOC_FREE(netlogon_pipe);
3888                 return status;
3889         }
3890
3891         *presult = netlogon_pipe;
3892         return NT_STATUS_OK;
3893 }
3894
3895 /****************************************************************************
3896  External interface.
3897  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3898  using session_key. sign and seal.
3899
3900  The *pdc will be stolen onto this new pipe
3901  ****************************************************************************/
3902
3903 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3904                                              const struct ndr_syntax_id *interface,
3905                                              enum dcerpc_transport_t transport,
3906                                              enum dcerpc_AuthLevel auth_level,
3907                                              const char *domain,
3908                                              struct netlogon_creds_CredentialState **pdc,
3909                                              struct rpc_pipe_client **presult)
3910 {
3911         struct rpc_pipe_client *result;
3912         struct cli_pipe_auth_data *auth;
3913         NTSTATUS status;
3914
3915         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3916         if (!NT_STATUS_IS_OK(status)) {
3917                 return status;
3918         }
3919
3920         status = rpccli_schannel_bind_data(result, domain, auth_level,
3921                                            *pdc, &auth);
3922         if (!NT_STATUS_IS_OK(status)) {
3923                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3924                           nt_errstr(status)));
3925                 TALLOC_FREE(result);
3926                 return status;
3927         }
3928
3929         status = rpc_pipe_bind(result, auth);
3930         if (!NT_STATUS_IS_OK(status)) {
3931                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3932                           "cli_rpc_pipe_bind failed with error %s\n",
3933                           nt_errstr(status) ));
3934                 TALLOC_FREE(result);
3935                 return status;
3936         }
3937
3938         /*
3939          * The credentials on a new netlogon pipe are the ones we are passed
3940          * in - reference them in
3941          */
3942         result->dc = talloc_move(result, pdc);
3943
3944         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3945                   "for domain %s and bound using schannel.\n",
3946                   get_pipe_name_from_iface(interface),
3947                   cli->desthost, domain ));
3948
3949         *presult = result;
3950         return NT_STATUS_OK;
3951 }
3952
3953 /****************************************************************************
3954  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3955  Fetch the session key ourselves using a temporary netlogon pipe. This
3956  version uses an ntlmssp auth bound netlogon pipe to get the key.
3957  ****************************************************************************/
3958
3959 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3960                                                       const char *domain,
3961                                                       const char *username,
3962                                                       const char *password,
3963                                                       uint32 *pneg_flags,
3964                                                       struct rpc_pipe_client **presult)
3965 {
3966         struct rpc_pipe_client *netlogon_pipe = NULL;
3967         NTSTATUS status;
3968
3969         status = cli_rpc_pipe_open_spnego_ntlmssp(
3970                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3971                 DCERPC_AUTH_LEVEL_PRIVACY,
3972                 domain, username, password, &netlogon_pipe);
3973         if (!NT_STATUS_IS_OK(status)) {
3974                 return status;
3975         }
3976
3977         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3978                                                  pneg_flags);
3979         if (!NT_STATUS_IS_OK(status)) {
3980                 TALLOC_FREE(netlogon_pipe);
3981                 return status;
3982         }
3983
3984         *presult = netlogon_pipe;
3985         return NT_STATUS_OK;
3986 }
3987
3988 /****************************************************************************
3989  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3990  Fetch the session key ourselves using a temporary netlogon pipe. This version
3991  uses an ntlmssp bind to get the session key.
3992  ****************************************************************************/
3993
3994 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3995                                                  const struct ndr_syntax_id *interface,
3996                                                  enum dcerpc_transport_t transport,
3997                                                  enum dcerpc_AuthLevel auth_level,
3998                                                  const char *domain,
3999                                                  const char *username,
4000                                                  const char *password,
4001                                                  struct rpc_pipe_client **presult)
4002 {
4003         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4004         struct rpc_pipe_client *netlogon_pipe = NULL;
4005         struct rpc_pipe_client *result = NULL;
4006         NTSTATUS status;
4007
4008         status = get_schannel_session_key_auth_ntlmssp(
4009                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4010         if (!NT_STATUS_IS_OK(status)) {
4011                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4012                         "key from server %s for domain %s.\n",
4013                         cli->desthost, domain ));
4014                 return status;
4015         }
4016
4017         status = cli_rpc_pipe_open_schannel_with_key(
4018                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4019                 &result);
4020
4021         /* Now we've bound using the session key we can close the netlog pipe. */
4022         TALLOC_FREE(netlogon_pipe);
4023
4024         if (NT_STATUS_IS_OK(status)) {
4025                 *presult = result;
4026         }
4027         return status;
4028 }
4029
4030 /****************************************************************************
4031  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4032  Fetch the session key ourselves using a temporary netlogon pipe.
4033  ****************************************************************************/
4034
4035 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4036                                     const struct ndr_syntax_id *interface,
4037                                     enum dcerpc_transport_t transport,
4038                                     enum dcerpc_AuthLevel auth_level,
4039                                     const char *domain,
4040                                     struct rpc_pipe_client **presult)
4041 {
4042         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4043         struct rpc_pipe_client *netlogon_pipe = NULL;
4044         struct rpc_pipe_client *result = NULL;
4045         NTSTATUS status;
4046
4047         status = get_schannel_session_key(cli, domain, &neg_flags,
4048                                           &netlogon_pipe);
4049         if (!NT_STATUS_IS_OK(status)) {
4050                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4051                         "key from server %s for domain %s.\n",
4052                         cli->desthost, domain ));
4053                 return status;
4054         }
4055
4056         status = cli_rpc_pipe_open_schannel_with_key(
4057                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4058                 &result);
4059
4060         /* Now we've bound using the session key we can close the netlog pipe. */
4061         TALLOC_FREE(netlogon_pipe);
4062
4063         if (NT_STATUS_IS_OK(status)) {
4064                 *presult = result;
4065         }
4066
4067         return NT_STATUS_OK;
4068 }
4069
4070 /****************************************************************************
4071  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4072  The idea is this can be called with service_princ, username and password all
4073  NULL so long as the caller has a TGT.
4074  ****************************************************************************/
4075
4076 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4077                                 const struct ndr_syntax_id *interface,
4078                                 enum dcerpc_AuthLevel auth_level,
4079                                 const char *service_princ,
4080                                 const char *username,
4081                                 const char *password,
4082                                 struct rpc_pipe_client **presult)
4083 {
4084 #ifdef HAVE_KRB5
4085         struct rpc_pipe_client *result;
4086         struct cli_pipe_auth_data *auth;
4087         NTSTATUS status;
4088
4089         status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4090         if (!NT_STATUS_IS_OK(status)) {
4091                 return status;
4092         }
4093
4094         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4095                                            username, password, &auth);
4096         if (!NT_STATUS_IS_OK(status)) {
4097                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4098                           nt_errstr(status)));
4099                 TALLOC_FREE(result);
4100                 return status;
4101         }
4102
4103         status = rpc_pipe_bind(result, auth);
4104         if (!NT_STATUS_IS_OK(status)) {
4105                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4106                           "with error %s\n", nt_errstr(status)));
4107                 TALLOC_FREE(result);
4108                 return status;
4109         }
4110
4111         *presult = result;
4112         return NT_STATUS_OK;
4113 #else
4114         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4115         return NT_STATUS_NOT_IMPLEMENTED;
4116 #endif
4117 }
4118
4119 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4120                              struct rpc_pipe_client *cli,
4121                              DATA_BLOB *session_key)
4122 {
4123         if (!session_key || !cli) {
4124                 return NT_STATUS_INVALID_PARAMETER;
4125         }
4126
4127         if (!cli->auth) {
4128                 return NT_STATUS_INVALID_PARAMETER;
4129         }
4130
4131         switch (cli->auth->auth_type) {
4132                 case PIPE_AUTH_TYPE_SCHANNEL:
4133                         *session_key = data_blob_talloc(mem_ctx,
4134                                 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4135                         break;
4136                 case PIPE_AUTH_TYPE_NTLMSSP:
4137                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4138                         *session_key = data_blob_talloc(mem_ctx,
4139                                 cli->auth->a_u.ntlmssp_state->session_key.data,
4140                                 cli->auth->a_u.ntlmssp_state->session_key.length);
4141                         break;
4142                 case PIPE_AUTH_TYPE_KRB5:
4143                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4144                         *session_key = data_blob_talloc(mem_ctx,
4145                                 cli->auth->a_u.kerberos_auth->session_key.data,
4146                                 cli->auth->a_u.kerberos_auth->session_key.length);
4147                         break;
4148                 case PIPE_AUTH_TYPE_NONE:
4149                         *session_key = data_blob_talloc(mem_ctx,
4150                                 cli->auth->user_session_key.data,
4151                                 cli->auth->user_session_key.length);
4152                         break;
4153                 default:
4154                         return NT_STATUS_NO_USER_SESSION_KEY;
4155         }
4156
4157         return NT_STATUS_OK;
4158 }