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