s3-rpc: use ndr_interface_name() instead of get_pipe_name_from_syntax() in DEBUG.
[samba.git] / source3 / rpc_server / srv_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
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 /*  this module apparently provides an implementation of DCE/RPC over a
21  *  named pipe (IPC$ connection using SMBtrans).  details of DCE/RPC
22  *  documentation are available (in on-line form) from the X-Open group.
23  *
24  *  this module should provide a level of abstraction between SMB
25  *  and DCE/RPC, while minimising the amount of mallocs, unnecessary
26  *  data copies, and network traffic.
27  *
28  */
29
30 #include "includes.h"
31 #include "system/filesys.h"
32 #include "srv_pipe_internal.h"
33 #include "../librpc/gen_ndr/dcerpc.h"
34 #include "../librpc/rpc/rpc_common.h"
35 #include "dcesrv_auth_generic.h"
36 #include "rpc_server.h"
37 #include "rpc_dce.h"
38 #include "smbd/smbd.h"
39 #include "auth.h"
40 #include "ntdomain.h"
41 #include "rpc_server/srv_pipe.h"
42 #include "rpc_server/rpc_contexts.h"
43 #include "lib/param/param.h"
44 #include "librpc/ndr/ndr_table.h"
45
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_RPC_SRV
48
49 /**
50  * Dump everything from the start of the end up of the provided data
51  * into a file, but only at debug level >= 50
52  **/
53 static void dump_pdu_region(const char *name, int v,
54                             DATA_BLOB *data, size_t start, size_t end)
55 {
56         int fd, i;
57         char *fname = NULL;
58         ssize_t sz;
59
60         if (DEBUGLEVEL < 50) return;
61
62         if (start > data->length || end > data->length || start > end) return;
63
64         for (i = 1; i < 100; i++) {
65                 if (v != -1) {
66                         fname = talloc_asprintf(talloc_tos(),
67                                                 "/tmp/%s_%d.%d.prs",
68                                                 name, v, i);
69                 } else {
70                         fname = talloc_asprintf(talloc_tos(),
71                                                 "/tmp/%s_%d.prs",
72                                                 name, i);
73                 }
74                 if (!fname) {
75                         return;
76                 }
77                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
78                 if (fd != -1 || errno != EEXIST) break;
79         }
80         if (fd != -1) {
81                 sz = write(fd, data->data + start, end - start);
82                 i = close(fd);
83                 if ((sz != end - start) || (i != 0) ) {
84                         DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
85                                   fname, (unsigned long)sz,
86                                   (unsigned long)end - start, i));
87                 } else {
88                         DEBUG(0,("created %s\n", fname));
89                 }
90         }
91         TALLOC_FREE(fname);
92 }
93
94 static DATA_BLOB generic_session_key(void)
95 {
96         return data_blob_const("SystemLibraryDTC", 16);
97 }
98
99 /*******************************************************************
100  Generate the next PDU to be returned from the data.
101 ********************************************************************/
102
103 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
104                                    struct pipe_auth_data *auth,
105                                    uint32_t call_id,
106                                    DATA_BLOB *rdata,
107                                    size_t data_sent_length,
108                                    DATA_BLOB *frag,
109                                    size_t *pdu_size)
110 {
111         union dcerpc_payload u;
112         uint8_t pfc_flags;
113         size_t data_left;
114         size_t data_to_send;
115         size_t frag_len;
116         size_t pad_len = 0;
117         size_t auth_len = 0;
118         NTSTATUS status;
119
120         ZERO_STRUCT(u.response);
121
122         /* Set up rpc packet pfc flags. */
123         if (data_sent_length == 0) {
124                 pfc_flags = DCERPC_PFC_FLAG_FIRST;
125         } else {
126                 pfc_flags = 0;
127         }
128
129         /* Work out how much we can fit in a single PDU. */
130         data_left = rdata->length - data_sent_length;
131
132         /* Ensure there really is data left to send. */
133         if (!data_left) {
134                 DEBUG(0, ("No data left to send !\n"));
135                 return NT_STATUS_BUFFER_TOO_SMALL;
136         }
137
138         status = dcerpc_guess_sizes(auth,
139                                     DCERPC_RESPONSE_LENGTH,
140                                     data_left,
141                                     RPC_MAX_PDU_FRAG_LEN,
142                                     SERVER_NDR_PADDING_SIZE,
143                                     &data_to_send, &frag_len,
144                                     &auth_len, &pad_len);
145         if (!NT_STATUS_IS_OK(status)) {
146                 return status;
147         }
148
149         /* Set up the alloc hint. This should be the data left to send. */
150         u.response.alloc_hint = data_left;
151
152         /* Work out if this PDU will be the last. */
153         if (data_sent_length + data_to_send >= rdata->length) {
154                 pfc_flags |= DCERPC_PFC_FLAG_LAST;
155         }
156
157         /* Prepare data to be NDR encoded. */
158         u.response.stub_and_verifier =
159                 data_blob_const(rdata->data + data_sent_length, data_to_send);
160
161         /* Store the packet in the data stream. */
162         status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
163                                           pfc_flags, auth_len, call_id,
164                                           &u, frag);
165         if (!NT_STATUS_IS_OK(status)) {
166                 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
167                 return status;
168         }
169
170         if (auth_len) {
171                 /* Set the proper length on the pdu, including padding.
172                  * Only needed if an auth trailer will be appended. */
173                 dcerpc_set_frag_length(frag, frag->length
174                                                 + pad_len
175                                                 + DCERPC_AUTH_TRAILER_LENGTH
176                                                 + auth_len);
177         }
178
179         if (auth_len) {
180                 status = dcerpc_add_auth_footer(auth, pad_len, frag);
181                 if (!NT_STATUS_IS_OK(status)) {
182                         data_blob_free(frag);
183                         return status;
184                 }
185         }
186
187         *pdu_size = data_to_send;
188         return NT_STATUS_OK;
189 }
190
191 /*******************************************************************
192  Generate the next PDU to be returned from the data in p->rdata. 
193 ********************************************************************/
194
195 bool create_next_pdu(struct pipes_struct *p)
196 {
197         size_t pdu_size = 0;
198         NTSTATUS status;
199
200         /*
201          * If we're in the fault state, keep returning fault PDU's until
202          * the pipe gets closed. JRA.
203          */
204         if (p->fault_state) {
205                 setup_fault_pdu(p, NT_STATUS(p->fault_state));
206                 return true;
207         }
208
209         status = create_next_packet(p->mem_ctx, &p->auth,
210                                     p->call_id, &p->out_data.rdata,
211                                     p->out_data.data_sent_length,
212                                     &p->out_data.frag, &pdu_size);
213         if (!NT_STATUS_IS_OK(status)) {
214                 DEBUG(0, ("Failed to create packet with error %s, "
215                           "(auth level %u / type %u)\n",
216                           nt_errstr(status),
217                           (unsigned int)p->auth.auth_level,
218                           (unsigned int)p->auth.auth_type));
219                 return false;
220         }
221
222         /* Setup the counts for this PDU. */
223         p->out_data.data_sent_length += pdu_size;
224         p->out_data.current_pdu_sent = 0;
225         return true;
226 }
227
228
229 static bool pipe_init_outgoing_data(struct pipes_struct *p);
230
231 /*******************************************************************
232  Marshall a bind_nak pdu.
233 *******************************************************************/
234
235 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
236 {
237         NTSTATUS status;
238         union dcerpc_payload u;
239
240         /* Free any memory in the current return data buffer. */
241         pipe_init_outgoing_data(p);
242
243         /*
244          * Initialize a bind_nak header.
245          */
246
247         ZERO_STRUCT(u);
248
249         u.bind_nak.reject_reason  = 0;
250
251         /*
252          * Marshall directly into the outgoing PDU space. We
253          * must do this as we need to set to the bind response
254          * header and are never sending more than one PDU here.
255          */
256
257         status = dcerpc_push_ncacn_packet(p->mem_ctx,
258                                           DCERPC_PKT_BIND_NAK,
259                                           DCERPC_PFC_FLAG_FIRST |
260                                                 DCERPC_PFC_FLAG_LAST,
261                                           0,
262                                           pkt->call_id,
263                                           &u,
264                                           &p->out_data.frag);
265         if (!NT_STATUS_IS_OK(status)) {
266                 return False;
267         }
268
269         p->out_data.data_sent_length = 0;
270         p->out_data.current_pdu_sent = 0;
271
272         TALLOC_FREE(p->auth.auth_ctx);
273         p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
274         p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
275         p->pipe_bound = False;
276
277         return True;
278 }
279
280 /*******************************************************************
281  Marshall a fault pdu.
282 *******************************************************************/
283
284 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
285 {
286         NTSTATUS status;
287         union dcerpc_payload u;
288
289         /* Free any memory in the current return data buffer. */
290         pipe_init_outgoing_data(p);
291
292         /*
293          * Initialize a fault header.
294          */
295
296         ZERO_STRUCT(u);
297
298         u.fault.status          = NT_STATUS_V(fault_status);
299         u.fault._pad            = data_blob_talloc_zero(p->mem_ctx, 4);
300
301         /*
302          * Marshall directly into the outgoing PDU space. We
303          * must do this as we need to set to the bind response
304          * header and are never sending more than one PDU here.
305          */
306
307         status = dcerpc_push_ncacn_packet(p->mem_ctx,
308                                           DCERPC_PKT_FAULT,
309                                           DCERPC_PFC_FLAG_FIRST |
310                                            DCERPC_PFC_FLAG_LAST |
311                                            DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
312                                           0,
313                                           p->call_id,
314                                           &u,
315                                           &p->out_data.frag);
316         if (!NT_STATUS_IS_OK(status)) {
317                 return False;
318         }
319
320         p->out_data.data_sent_length = 0;
321         p->out_data.current_pdu_sent = 0;
322
323         return True;
324 }
325
326 /*******************************************************************
327  Ensure a bind request has the correct abstract & transfer interface.
328  Used to reject unknown binds from Win2k.
329 *******************************************************************/
330
331 static bool check_bind_req(struct pipes_struct *p,
332                            struct ndr_syntax_id* abstract,
333                            struct ndr_syntax_id* transfer,
334                            uint32_t context_id)
335 {
336         struct pipe_rpc_fns *context_fns;
337         bool ok;
338
339         DEBUG(3,("check_bind_req for %s\n",
340                  ndr_interface_name(&abstract->uuid,
341                                     abstract->if_version)));
342
343         /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
344         if (rpc_srv_pipe_exists_by_id(abstract) &&
345            ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
346                 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
347                           rpc_srv_get_pipe_cli_name(abstract),
348                           rpc_srv_get_pipe_srv_name(abstract)));
349         } else {
350                 return false;
351         }
352
353         ok = init_pipe_handles(p, abstract);
354         if (!ok) {
355                 DEBUG(1, ("Failed to init pipe handles!\n"));
356                 return false;
357         }
358
359         context_fns = talloc(p, struct pipe_rpc_fns);
360         if (context_fns == NULL) {
361                 DEBUG(0,("check_bind_req: talloc() failed!\n"));
362                 return false;
363         }
364
365         context_fns->next = context_fns->prev = NULL;
366         context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
367         context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
368         context_fns->context_id = context_id;
369         context_fns->syntax = *abstract;
370
371         /* add to the list of open contexts */
372
373         DLIST_ADD( p->contexts, context_fns );
374
375         return True;
376 }
377
378 /**
379  * Is a named pipe known?
380  * @param[in] pipename          Just the filename
381  * @result                      Do we want to serve this?
382  */
383 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
384 {
385         NTSTATUS status;
386
387         if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
388                 DEBUG(10, ("refusing spoolss access\n"));
389                 return false;
390         }
391
392         if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
393                 return true;
394         }
395
396         status = smb_probe_module("rpc", pipename);
397         if (!NT_STATUS_IS_OK(status)) {
398                 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
399                 return false;
400         }
401         DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
402
403         /*
404          * Scan the list again for the interface id
405          */
406         if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
407                 return true;
408         }
409
410         DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
411                    pipename));
412
413         return false;
414 }
415
416 /*******************************************************************
417  Handle an NTLMSSP bind auth.
418 *******************************************************************/
419
420 static bool pipe_auth_generic_bind(struct pipes_struct *p,
421                                    TALLOC_CTX *mem_ctx,
422                                    struct dcerpc_auth *auth_info,
423                                    DATA_BLOB *response)
424 {
425         struct gensec_security *gensec_security = NULL;
426         NTSTATUS status;
427
428         status = auth_generic_server_authtype_start(p,
429                                                     auth_info->auth_type,
430                                                     auth_info->auth_level,
431                                                     &auth_info->credentials,
432                                                     response,
433                                                     p->remote_address,
434                                                     &gensec_security);
435         if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
436                 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
437                           nt_errstr(status)));
438                 return false;
439         }
440
441         /* Make sure data is bound to the memctx, to be freed the caller */
442         talloc_steal(mem_ctx, response->data);
443
444         p->auth.auth_ctx = gensec_security;
445         p->auth.auth_type = auth_info->auth_type;
446
447         return true;
448 }
449
450 /*******************************************************************
451  Process an NTLMSSP authentication response.
452  If this function succeeds, the user has been authenticated
453  and their domain, name and calling workstation stored in
454  the pipe struct.
455 *******************************************************************/
456
457 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
458                                 struct gensec_security *gensec_security,
459                                 enum dcerpc_AuthLevel auth_level,
460                                 struct auth_session_info **session_info)
461 {
462         NTSTATUS status;
463         bool ret;
464
465         DEBUG(5, (__location__ ": checking user details\n"));
466
467         /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
468            ensure the underlying NTLMSSP flags are also set. If not we should
469            refuse the bind. */
470
471         status = auth_generic_server_check_flags(gensec_security,
472                                             (auth_level ==
473                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
474                                             (auth_level ==
475                                                 DCERPC_AUTH_LEVEL_PRIVACY));
476         if (!NT_STATUS_IS_OK(status)) {
477                 DEBUG(0, (__location__ ": Client failed to negotatie proper "
478                           "security for rpc connection\n"));
479                 return false;
480         }
481
482         TALLOC_FREE(*session_info);
483
484         status = auth_generic_server_get_user_info(gensec_security,
485                                                 mem_ctx, session_info);
486         if (!NT_STATUS_IS_OK(status)) {
487                 DEBUG(0, (__location__ ": failed to obtain the server info "
488                           "for authenticated user: %s\n", nt_errstr(status)));
489                 return false;
490         }
491
492         if ((*session_info)->security_token == NULL) {
493                 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
494                 return false;
495         }
496
497         /*
498          * We're an authenticated bind over smb, so the session key needs to
499          * be set to "SystemLibraryDTC". Weird, but this is what Windows
500          * does. See the RPC-SAMBA3SESSIONKEY.
501          */
502
503         ret = session_info_set_session_key((*session_info), generic_session_key());
504         if (!ret) {
505                 DEBUG(0, ("Failed to set session key!\n"));
506                 return false;
507         }
508
509         return true;
510 }
511
512 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
513 {
514         struct gensec_security *gensec_security;
515
516         switch (p->auth.auth_type) {
517         case DCERPC_AUTH_TYPE_NTLMSSP:
518         case DCERPC_AUTH_TYPE_KRB5:
519         case DCERPC_AUTH_TYPE_SPNEGO:
520                 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
521                                                         struct gensec_security);
522                 if (!pipe_auth_generic_verify_final(p, gensec_security,
523                                                 p->auth.auth_level,
524                                                 &p->session_info)) {
525                         return NT_STATUS_ACCESS_DENIED;
526                 }
527                 break;
528         default:
529                 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
530                           (unsigned int)p->auth.auth_type));
531                 return NT_STATUS_ACCESS_DENIED;
532         }
533
534         p->pipe_bound = true;
535
536         return NT_STATUS_OK;
537 }
538
539 /*******************************************************************
540  Respond to a pipe bind request.
541 *******************************************************************/
542
543 static bool api_pipe_bind_req(struct pipes_struct *p,
544                                 struct ncacn_packet *pkt)
545 {
546         struct dcerpc_auth auth_info;
547         uint16 assoc_gid;
548         unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
549         NTSTATUS status;
550         struct ndr_syntax_id id;
551         union dcerpc_payload u;
552         struct dcerpc_ack_ctx bind_ack_ctx;
553         DATA_BLOB auth_resp = data_blob_null;
554         DATA_BLOB auth_blob = data_blob_null;
555
556         /* No rebinds on a bound pipe - use alter context. */
557         if (p->pipe_bound) {
558                 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
559                 return setup_bind_nak(p, pkt);
560         }
561
562         if (pkt->u.bind.num_contexts == 0) {
563                 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
564                 goto err_exit;
565         }
566
567         /*
568          * Try and find the correct pipe name to ensure
569          * that this is a pipe name we support.
570          */
571         id = pkt->u.bind.ctx_list[0].abstract_syntax;
572         if (rpc_srv_pipe_exists_by_id(&id)) {
573                 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
574                           rpc_srv_get_pipe_cli_name(&id),
575                           rpc_srv_get_pipe_srv_name(&id)));
576         } else {
577                 status = smb_probe_module(
578                         "rpc", get_pipe_name_from_syntax(
579                                 talloc_tos(),
580                                 &id));
581
582                 if (NT_STATUS_IS_ERR(status)) {
583                         DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
584                                  "%s in bind request.\n",
585                                  ndr_interface_name(&id.uuid,
586                                                     id.if_version)));
587
588                         return setup_bind_nak(p, pkt);
589                 }
590
591                 if (rpc_srv_get_pipe_interface_by_cli_name(
592                                 get_pipe_name_from_syntax(talloc_tos(),
593                                                           &id),
594                                 &id)) {
595                         DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
596                                   rpc_srv_get_pipe_cli_name(&id),
597                                   rpc_srv_get_pipe_srv_name(&id)));
598                 } else {
599                         DEBUG(0, ("module %s doesn't provide functions for "
600                                   "pipe %s!\n",
601                                   ndr_interface_name(&id.uuid,
602                                                      id.if_version),
603                                   ndr_interface_name(&id.uuid,
604                                                      id.if_version)));
605                         return setup_bind_nak(p, pkt);
606                 }
607         }
608
609         DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
610
611         if (pkt->u.bind.assoc_group_id != 0) {
612                 assoc_gid = pkt->u.bind.assoc_group_id;
613         } else {
614                 assoc_gid = 0x53f0;
615         }
616
617         /*
618          * Create the bind response struct.
619          */
620
621         /* If the requested abstract synt uuid doesn't match our client pipe,
622                 reject the bind_ack & set the transfer interface synt to all 0's,
623                 ver 0 (observed when NT5 attempts to bind to abstract interfaces
624                 unknown to NT4)
625                 Needed when adding entries to a DACL from NT5 - SK */
626
627         if (check_bind_req(p,
628                         &pkt->u.bind.ctx_list[0].abstract_syntax,
629                         &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
630                         pkt->u.bind.ctx_list[0].context_id)) {
631
632                 bind_ack_ctx.result = 0;
633                 bind_ack_ctx.reason = 0;
634                 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
635         } else {
636                 p->pipe_bound = False;
637                 /* Rejection reason: abstract syntax not supported */
638                 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
639                 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
640                 bind_ack_ctx.syntax = ndr_syntax_id_null;
641         }
642
643         /*
644          * Check if this is an authenticated bind request.
645          */
646         if (pkt->auth_length) {
647                 /* Quick length check. Won't catch a bad auth footer,
648                  * prevents overrun. */
649
650                 if (pkt->frag_length < RPC_HEADER_LEN +
651                                         DCERPC_AUTH_TRAILER_LENGTH +
652                                         pkt->auth_length) {
653                         DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
654                                 "too long for fragment %u.\n",
655                                 (unsigned int)pkt->auth_length,
656                                 (unsigned int)pkt->frag_length));
657                         goto err_exit;
658                 }
659
660                 /*
661                  * Decode the authentication verifier.
662                  */
663                 status = dcerpc_pull_dcerpc_auth(pkt,
664                                                  &pkt->u.bind.auth_info,
665                                                  &auth_info, p->endian);
666                 if (!NT_STATUS_IS_OK(status)) {
667                         DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
668                         goto err_exit;
669                 }
670
671                 auth_type = auth_info.auth_type;
672
673                 /* Work out if we have to sign or seal etc. */
674                 switch (auth_info.auth_level) {
675                 case DCERPC_AUTH_LEVEL_INTEGRITY:
676                         p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
677                         break;
678                 case DCERPC_AUTH_LEVEL_PRIVACY:
679                         p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
680                         break;
681                 case DCERPC_AUTH_LEVEL_CONNECT:
682                         p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
683                         break;
684                 default:
685                         DEBUG(0, ("Unexpected auth level (%u).\n",
686                                 (unsigned int)auth_info.auth_level ));
687                         goto err_exit;
688                 }
689
690                 switch (auth_type) {
691                 case DCERPC_AUTH_TYPE_NTLMSSP:
692                         if (!pipe_auth_generic_bind(p, pkt,
693                                                     &auth_info, &auth_resp)) {
694                                 goto err_exit;
695                         }
696                         assoc_gid = 0x7a77;
697                         break;
698
699                 case DCERPC_AUTH_TYPE_SCHANNEL:
700                         if (!pipe_auth_generic_bind(p, pkt,
701                                                     &auth_info, &auth_resp)) {
702                                 goto err_exit;
703                         }
704                         if (!session_info_set_session_key(p->session_info, generic_session_key())) {
705                                 DEBUG(0, ("session_info_set_session_key failed\n"));
706                                 goto err_exit;
707                         }
708                         p->pipe_bound = true;
709                         break;
710
711                 case DCERPC_AUTH_TYPE_SPNEGO:
712                 case DCERPC_AUTH_TYPE_KRB5:
713                         if (!pipe_auth_generic_bind(p, pkt,
714                                                     &auth_info, &auth_resp)) {
715                                 goto err_exit;
716                         }
717                         break;
718
719                 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
720                         if (p->transport == NCALRPC && p->ncalrpc_as_system) {
721                                 TALLOC_FREE(p->session_info);
722
723                                 status = make_session_info_system(p,
724                                                                   &p->session_info);
725                                 if (!NT_STATUS_IS_OK(status)) {
726                                         goto err_exit;
727                                 }
728
729                                 auth_resp = data_blob_talloc(pkt,
730                                                              "NCALRPC_AUTH_OK",
731                                                              15);
732
733                                 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
734                                 p->pipe_bound = true;
735                         } else {
736                                 goto err_exit;
737                         }
738                         break;
739
740                 case DCERPC_AUTH_TYPE_NONE:
741                         break;
742
743                 default:
744                         DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
745                         goto err_exit;
746                 }
747         }
748
749         if (auth_type == DCERPC_AUTH_TYPE_NONE) {
750                 /* Unauthenticated bind request. */
751                 /* We're finished - no more packets. */
752                 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
753                 /* We must set the pipe auth_level here also. */
754                 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
755                 p->pipe_bound = True;
756                 /* The session key was initialized from the SMB
757                  * session in make_internal_rpc_pipe_p */
758         }
759
760         ZERO_STRUCT(u.bind_ack);
761         u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
762         u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
763         u.bind_ack.assoc_group_id = assoc_gid;
764
765         /* name has to be \PIPE\xxxxx */
766         u.bind_ack.secondary_address =
767                         talloc_asprintf(pkt, "\\PIPE\\%s",
768                                         rpc_srv_get_pipe_srv_name(&id));
769         if (!u.bind_ack.secondary_address) {
770                 DEBUG(0, ("Out of memory!\n"));
771                 goto err_exit;
772         }
773         u.bind_ack.secondary_address_size =
774                                 strlen(u.bind_ack.secondary_address) + 1;
775
776         u.bind_ack.num_results = 1;
777         u.bind_ack.ctx_list = &bind_ack_ctx;
778
779         /* NOTE: We leave the auth_info empty so we can calculate the padding
780          * later and then append the auth_info --simo */
781
782         /*
783          * Marshall directly into the outgoing PDU space. We
784          * must do this as we need to set to the bind response
785          * header and are never sending more than one PDU here.
786          */
787
788         status = dcerpc_push_ncacn_packet(p->mem_ctx,
789                                           DCERPC_PKT_BIND_ACK,
790                                           DCERPC_PFC_FLAG_FIRST |
791                                                 DCERPC_PFC_FLAG_LAST,
792                                           auth_resp.length,
793                                           pkt->call_id,
794                                           &u,
795                                           &p->out_data.frag);
796         if (!NT_STATUS_IS_OK(status)) {
797                 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
798                           nt_errstr(status)));
799         }
800
801         if (auth_resp.length) {
802
803                 status = dcerpc_push_dcerpc_auth(pkt,
804                                                  auth_type,
805                                                  auth_info.auth_level,
806                                                  0,
807                                                  1, /* auth_context_id */
808                                                  &auth_resp,
809                                                  &auth_blob);
810                 if (!NT_STATUS_IS_OK(status)) {
811                         DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
812                         goto err_exit;
813                 }
814         }
815
816         /* Now that we have the auth len store it into the right place in
817          * the dcerpc header */
818         dcerpc_set_frag_length(&p->out_data.frag,
819                                 p->out_data.frag.length + auth_blob.length);
820
821         if (auth_blob.length) {
822
823                 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
824                                         auth_blob.data, auth_blob.length)) {
825                         DEBUG(0, ("Append of auth info failed.\n"));
826                         goto err_exit;
827                 }
828         }
829
830         /*
831          * Setup the lengths for the initial reply.
832          */
833
834         p->out_data.data_sent_length = 0;
835         p->out_data.current_pdu_sent = 0;
836
837         TALLOC_FREE(auth_blob.data);
838         return True;
839
840   err_exit:
841
842         data_blob_free(&p->out_data.frag);
843         TALLOC_FREE(auth_blob.data);
844         return setup_bind_nak(p, pkt);
845 }
846
847 /*******************************************************************
848  This is the "stage3" response after a bind request and reply.
849 *******************************************************************/
850
851 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
852 {
853         struct dcerpc_auth auth_info;
854         DATA_BLOB response = data_blob_null;
855         struct gensec_security *gensec_security;
856         NTSTATUS status;
857
858         DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
859
860         if (pkt->auth_length == 0) {
861                 DEBUG(1, ("No auth field sent for bind request!\n"));
862                 goto err;
863         }
864
865         /* Ensure there's enough data for an authenticated request. */
866         if (pkt->frag_length < RPC_HEADER_LEN
867                                 + DCERPC_AUTH_TRAILER_LENGTH
868                                 + pkt->auth_length) {
869                         DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
870                                 "%u is too large.\n",
871                         (unsigned int)pkt->auth_length));
872                 goto err;
873         }
874
875         /*
876          * Decode the authentication verifier response.
877          */
878
879         status = dcerpc_pull_dcerpc_auth(pkt,
880                                          &pkt->u.auth3.auth_info,
881                                          &auth_info, p->endian);
882         if (!NT_STATUS_IS_OK(status)) {
883                 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
884                 goto err;
885         }
886
887         /* We must NEVER look at auth_info->auth_pad_len here,
888          * as old Samba client code gets it wrong and sends it
889          * as zero. JRA.
890          */
891
892         if (auth_info.auth_type != p->auth.auth_type) {
893                 DEBUG(1, ("Auth type mismatch! Client sent %d, "
894                           "but auth was started as type %d!\n",
895                           auth_info.auth_type, p->auth.auth_type));
896                 goto err;
897         }
898
899         switch (auth_info.auth_type) {
900         case DCERPC_AUTH_TYPE_NTLMSSP:
901         case DCERPC_AUTH_TYPE_KRB5:
902         case DCERPC_AUTH_TYPE_SPNEGO:
903                 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
904                                                     struct gensec_security);
905                 status = auth_generic_server_step(gensec_security,
906                                              pkt, &auth_info.credentials,
907                                              &response);
908                 break;
909         default:
910                 DEBUG(1, (__location__ ": incorrect auth type (%u).\n",
911                           (unsigned int)auth_info.auth_type));
912                 return false;
913         }
914
915         if (NT_STATUS_EQUAL(status,
916                             NT_STATUS_MORE_PROCESSING_REQUIRED) ||
917             response.length) {
918                 DEBUG(1, (__location__ ": This was supposed to be the final "
919                           "leg, but crypto machinery claims a response is "
920                           "needed, aborting auth!\n"));
921                 data_blob_free(&response);
922                 goto err;
923         }
924         if (!NT_STATUS_IS_OK(status)) {
925                 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
926                 goto err;
927         }
928
929         /* Now verify auth was indeed successful and extract server info */
930         status = pipe_auth_verify_final(p);
931         if (!NT_STATUS_IS_OK(status)) {
932                 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
933                 goto err;
934         }
935
936         return true;
937
938 err:
939
940         TALLOC_FREE(p->auth.auth_ctx);
941         return false;
942 }
943
944 /****************************************************************************
945  Deal with an alter context call. Can be third part of 3 leg auth request for
946  SPNEGO calls.
947 ****************************************************************************/
948
949 static bool api_pipe_alter_context(struct pipes_struct *p,
950                                         struct ncacn_packet *pkt)
951 {
952         struct dcerpc_auth auth_info;
953         uint16 assoc_gid;
954         NTSTATUS status;
955         union dcerpc_payload u;
956         struct dcerpc_ack_ctx bind_ack_ctx;
957         DATA_BLOB auth_resp = data_blob_null;
958         DATA_BLOB auth_blob = data_blob_null;
959         int pad_len = 0;
960         struct gensec_security *gensec_security;
961
962         DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
963
964         if (pkt->u.bind.assoc_group_id != 0) {
965                 assoc_gid = pkt->u.bind.assoc_group_id;
966         } else {
967                 assoc_gid = 0x53f0;
968         }
969
970         /*
971          * Create the bind response struct.
972          */
973
974         /* If the requested abstract synt uuid doesn't match our client pipe,
975                 reject the bind_ack & set the transfer interface synt to all 0's,
976                 ver 0 (observed when NT5 attempts to bind to abstract interfaces
977                 unknown to NT4)
978                 Needed when adding entries to a DACL from NT5 - SK */
979
980         if (check_bind_req(p,
981                         &pkt->u.bind.ctx_list[0].abstract_syntax,
982                         &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
983                         pkt->u.bind.ctx_list[0].context_id)) {
984
985                 bind_ack_ctx.result = 0;
986                 bind_ack_ctx.reason = 0;
987                 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
988         } else {
989                 p->pipe_bound = False;
990                 /* Rejection reason: abstract syntax not supported */
991                 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
992                 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
993                 bind_ack_ctx.syntax = ndr_syntax_id_null;
994         }
995
996         /*
997          * Check if this is an authenticated alter context request.
998          */
999         if (pkt->auth_length) {
1000                 /* Quick length check. Won't catch a bad auth footer,
1001                  * prevents overrun. */
1002
1003                 if (pkt->frag_length < RPC_HEADER_LEN +
1004                                         DCERPC_AUTH_TRAILER_LENGTH +
1005                                         pkt->auth_length) {
1006                         DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1007                                 "too long for fragment %u.\n",
1008                                 (unsigned int)pkt->auth_length,
1009                                 (unsigned int)pkt->frag_length ));
1010                         goto err_exit;
1011                 }
1012
1013                 status = dcerpc_pull_dcerpc_auth(pkt,
1014                                                  &pkt->u.bind.auth_info,
1015                                                  &auth_info, p->endian);
1016                 if (!NT_STATUS_IS_OK(status)) {
1017                         DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1018                         goto err_exit;
1019                 }
1020
1021                 /* We can only finish if the pipe is unbound for now */
1022                 if (p->pipe_bound) {
1023                         DEBUG(0, (__location__ ": Pipe already bound, "
1024                                   "Altering Context not yet supported!\n"));
1025                         goto err_exit;
1026                 }
1027
1028                 if (auth_info.auth_type != p->auth.auth_type) {
1029                         DEBUG(0, ("Auth type mismatch! Client sent %d, "
1030                                   "but auth was started as type %d!\n",
1031                                   auth_info.auth_type, p->auth.auth_type));
1032                         goto err_exit;
1033                 }
1034
1035
1036                 switch (auth_info.auth_type) {
1037                 case DCERPC_AUTH_TYPE_SPNEGO:
1038                 case DCERPC_AUTH_TYPE_KRB5:
1039                 case DCERPC_AUTH_TYPE_NTLMSSP:
1040                         gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1041                                                     struct gensec_security);
1042                         status = auth_generic_server_step(gensec_security,
1043                                                      pkt,
1044                                                      &auth_info.credentials,
1045                                                      &auth_resp);
1046                         break;
1047
1048                 default:
1049                         DEBUG(3, (__location__ ": Usupported auth type (%d) "
1050                                   "in alter-context call\n",
1051                                   auth_info.auth_type));
1052                         goto err_exit;
1053                 }
1054
1055                 if (NT_STATUS_IS_OK(status)) {
1056                         /* third leg of auth, verify auth info */
1057                         status = pipe_auth_verify_final(p);
1058                         if (!NT_STATUS_IS_OK(status)) {
1059                                 DEBUG(0, ("Auth Verify failed (%s)\n",
1060                                           nt_errstr(status)));
1061                                 goto err_exit;
1062                         }
1063                 } else if (NT_STATUS_EQUAL(status,
1064                                         NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1065                         DEBUG(10, ("More auth legs required.\n"));
1066                 } else {
1067                         DEBUG(0, ("Auth step returned an error (%s)\n",
1068                                   nt_errstr(status)));
1069                         goto err_exit;
1070                 }
1071         }
1072
1073         ZERO_STRUCT(u.alter_resp);
1074         u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1075         u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1076         u.alter_resp.assoc_group_id = assoc_gid;
1077
1078         /* secondary address CAN be NULL
1079          * as the specs say it's ignored.
1080          * It MUST be NULL to have the spoolss working.
1081          */
1082         u.alter_resp.secondary_address = "";
1083         u.alter_resp.secondary_address_size = 1;
1084
1085         u.alter_resp.num_results = 1;
1086         u.alter_resp.ctx_list = &bind_ack_ctx;
1087
1088         /* NOTE: We leave the auth_info empty so we can calculate the padding
1089          * later and then append the auth_info --simo */
1090
1091         /*
1092          * Marshall directly into the outgoing PDU space. We
1093          * must do this as we need to set to the bind response
1094          * header and are never sending more than one PDU here.
1095          */
1096
1097         status = dcerpc_push_ncacn_packet(p->mem_ctx,
1098                                           DCERPC_PKT_ALTER_RESP,
1099                                           DCERPC_PFC_FLAG_FIRST |
1100                                                 DCERPC_PFC_FLAG_LAST,
1101                                           auth_resp.length,
1102                                           pkt->call_id,
1103                                           &u,
1104                                           &p->out_data.frag);
1105         if (!NT_STATUS_IS_OK(status)) {
1106                 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1107                           nt_errstr(status)));
1108         }
1109
1110         if (auth_resp.length) {
1111
1112                 /* Work out any padding needed before the auth footer. */
1113                 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1114                 if (pad_len) {
1115                         pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1116                         DEBUG(10, ("auth pad_len = %u\n",
1117                                    (unsigned int)pad_len));
1118                 }
1119
1120                 status = dcerpc_push_dcerpc_auth(pkt,
1121                                                  auth_info.auth_type,
1122                                                  auth_info.auth_level,
1123                                                  pad_len,
1124                                                  1, /* auth_context_id */
1125                                                  &auth_resp,
1126                                                  &auth_blob);
1127                 if (!NT_STATUS_IS_OK(status)) {
1128                         DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1129                         goto err_exit;
1130                 }
1131         }
1132
1133         /* Now that we have the auth len store it into the right place in
1134          * the dcerpc header */
1135         dcerpc_set_frag_length(&p->out_data.frag,
1136                                 p->out_data.frag.length +
1137                                         pad_len + auth_blob.length);
1138
1139         if (auth_resp.length) {
1140                 if (pad_len) {
1141                         char pad[SERVER_NDR_PADDING_SIZE];
1142                         memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1143                         if (!data_blob_append(p->mem_ctx,
1144                                                 &p->out_data.frag,
1145                                                 pad, pad_len)) {
1146                                 DEBUG(0, ("api_pipe_bind_req: failed to add "
1147                                           "%u bytes of pad data.\n",
1148                                           (unsigned int)pad_len));
1149                                 goto err_exit;
1150                         }
1151                 }
1152
1153                 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1154                                         auth_blob.data, auth_blob.length)) {
1155                         DEBUG(0, ("Append of auth info failed.\n"));
1156                         goto err_exit;
1157                 }
1158         }
1159
1160         /*
1161          * Setup the lengths for the initial reply.
1162          */
1163
1164         p->out_data.data_sent_length = 0;
1165         p->out_data.current_pdu_sent = 0;
1166
1167         TALLOC_FREE(auth_blob.data);
1168         return True;
1169
1170   err_exit:
1171
1172         data_blob_free(&p->out_data.frag);
1173         TALLOC_FREE(auth_blob.data);
1174         return setup_bind_nak(p, pkt);
1175 }
1176
1177 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1178                        const struct api_struct *api_rpc_cmds, int n_cmds,
1179                        const struct ndr_syntax_id *syntax);
1180
1181 /****************************************************************************
1182  Find the correct RPC function to call for this request.
1183  If the pipe is authenticated then become the correct UNIX user
1184  before doing the call.
1185 ****************************************************************************/
1186
1187 static bool api_pipe_request(struct pipes_struct *p,
1188                                 struct ncacn_packet *pkt)
1189 {
1190         bool ret = False;
1191         struct pipe_rpc_fns *pipe_fns;
1192
1193         if (!p->pipe_bound) {
1194                 DEBUG(1, ("Pipe not bound!\n"));
1195                 data_blob_free(&p->out_data.rdata);
1196                 return false;
1197         }
1198
1199         if (!become_authenticated_pipe_user(p->session_info)) {
1200                 DEBUG(1, ("Failed to become pipe user!\n"));
1201                 data_blob_free(&p->out_data.rdata);
1202                 return false;
1203         }
1204
1205         /* get the set of RPC functions for this context */
1206
1207         pipe_fns = find_pipe_fns_by_context(p->contexts,
1208                                             pkt->u.request.context_id);
1209
1210         if ( pipe_fns ) {
1211                 TALLOC_CTX *frame = talloc_stackframe();
1212
1213                 DEBUG(5, ("Requested %s rpc service\n",
1214                           ndr_interface_name(&pipe_fns->syntax.uuid,
1215                                              pipe_fns->syntax.if_version)));
1216
1217                 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1218                                  &pipe_fns->syntax);
1219
1220                 TALLOC_FREE(frame);
1221         }
1222         else {
1223                 DEBUG(0, ("No rpc function table associated with context "
1224                           "[%d]\n",
1225                           pkt->u.request.context_id));
1226         }
1227
1228         unbecome_authenticated_pipe_user();
1229
1230         return ret;
1231 }
1232
1233 /*******************************************************************
1234  Calls the underlying RPC function for a named pipe.
1235  ********************************************************************/
1236
1237 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1238                        const struct api_struct *api_rpc_cmds, int n_cmds,
1239                        const struct ndr_syntax_id *syntax)
1240 {
1241         int fn_num;
1242         uint32_t offset1;
1243
1244         /* interpret the command */
1245         DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1246                  ndr_interface_name(&syntax->uuid, syntax->if_version),
1247                  pkt->u.request.opnum));
1248
1249         if (DEBUGLEVEL >= 50) {
1250                 fstring name;
1251                 slprintf(name, sizeof(name)-1, "in_%s",
1252                          get_pipe_name_from_syntax(talloc_tos(), syntax));
1253                 dump_pdu_region(name, pkt->u.request.opnum,
1254                                 &p->in_data.data, 0,
1255                                 p->in_data.data.length);
1256         }
1257
1258         for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1259                 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1260                     api_rpc_cmds[fn_num].fn != NULL) {
1261                         DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1262                                   api_rpc_cmds[fn_num].name));
1263                         break;
1264                 }
1265         }
1266
1267         if (fn_num == n_cmds) {
1268                 /*
1269                  * For an unknown RPC just return a fault PDU but
1270                  * return True to allow RPC's on the pipe to continue
1271                  * and not put the pipe into fault state. JRA.
1272                  */
1273                 DEBUG(4, ("unknown\n"));
1274                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1275                 return True;
1276         }
1277
1278         offset1 = p->out_data.rdata.length;
1279
1280         DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n", 
1281                 fn_num, api_rpc_cmds[fn_num].fn));
1282         /* do the actual command */
1283         if(!api_rpc_cmds[fn_num].fn(p)) {
1284                 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1285                          ndr_interface_name(&syntax->uuid, syntax->if_version),
1286                          api_rpc_cmds[fn_num].name));
1287                 data_blob_free(&p->out_data.rdata);
1288                 return False;
1289         }
1290
1291         if (p->fault_state) {
1292                 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1293                 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1294                 p->fault_state = 0;
1295                 return true;
1296         }
1297
1298         if (DEBUGLEVEL >= 50) {
1299                 fstring name;
1300                 slprintf(name, sizeof(name)-1, "out_%s",
1301                          get_pipe_name_from_syntax(talloc_tos(), syntax));
1302                 dump_pdu_region(name, pkt->u.request.opnum,
1303                                 &p->out_data.rdata, offset1,
1304                                 p->out_data.rdata.length);
1305         }
1306
1307         DEBUG(5,("api_rpcTNP: called %s successfully\n",
1308                  ndr_interface_name(&syntax->uuid, syntax->if_version)));
1309
1310         /* Check for buffer underflow in rpc parsing */
1311         if ((DEBUGLEVEL >= 10) &&
1312             (pkt->frag_length < p->in_data.data.length)) {
1313                 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1314                 dump_data(10, p->in_data.data.data + pkt->frag_length,
1315                               p->in_data.data.length - pkt->frag_length);
1316         }
1317
1318         return True;
1319 }
1320
1321 /****************************************************************************
1322  Initialise an outgoing packet.
1323 ****************************************************************************/
1324
1325 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1326 {
1327         output_data *o_data = &p->out_data;
1328
1329         /* Reset the offset counters. */
1330         o_data->data_sent_length = 0;
1331         o_data->current_pdu_sent = 0;
1332
1333         data_blob_free(&o_data->frag);
1334
1335         /* Free any memory in the current return data buffer. */
1336         data_blob_free(&o_data->rdata);
1337
1338         return True;
1339 }
1340
1341 /****************************************************************************
1342  Sets the fault state on incoming packets.
1343 ****************************************************************************/
1344
1345 void set_incoming_fault(struct pipes_struct *p)
1346 {
1347         data_blob_free(&p->in_data.data);
1348         p->in_data.pdu_needed_len = 0;
1349         p->in_data.pdu.length = 0;
1350         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1351
1352         DEBUG(10, ("Setting fault state\n"));
1353 }
1354
1355 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1356                                     struct ncacn_packet *pkt,
1357                                     DATA_BLOB *raw_pkt)
1358 {
1359         NTSTATUS status;
1360         size_t hdr_size = DCERPC_REQUEST_LENGTH;
1361         size_t pad_len;
1362
1363         DEBUG(10, ("Checking request auth.\n"));
1364
1365         if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1366                 hdr_size += 16;
1367         }
1368
1369         /* in case of sealing this function will unseal the data in place */
1370         status = dcerpc_check_auth(auth, pkt,
1371                                    &pkt->u.request.stub_and_verifier,
1372                                    hdr_size, raw_pkt,
1373                                    &pad_len);
1374         if (!NT_STATUS_IS_OK(status)) {
1375                 return status;
1376         }
1377
1378
1379         /* remove padding and auth trailer,
1380          * this way the caller will get just the data */
1381         if (pkt->auth_length) {
1382                 size_t trail_len = pad_len
1383                                         + DCERPC_AUTH_TRAILER_LENGTH
1384                                         + pkt->auth_length;
1385                 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1386                         return NT_STATUS_INFO_LENGTH_MISMATCH;
1387                 }
1388                 pkt->u.request.stub_and_verifier.length -= trail_len;
1389         }
1390
1391         return NT_STATUS_OK;
1392 }
1393
1394 /****************************************************************************
1395  Processes a request pdu. This will do auth processing if needed, and
1396  appends the data into the complete stream if the LAST flag is not set.
1397 ****************************************************************************/
1398
1399 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1400 {
1401         NTSTATUS status;
1402         DATA_BLOB data;
1403
1404         if (!p->pipe_bound) {
1405                 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1406                 set_incoming_fault(p);
1407                 return False;
1408         }
1409
1410         /* Store the opnum */
1411         p->opnum = pkt->u.request.opnum;
1412
1413         status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1414         if (!NT_STATUS_IS_OK(status)) {
1415                 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1416                           nt_errstr(status)));
1417                 set_incoming_fault(p);
1418                 return false;
1419         }
1420
1421         data = pkt->u.request.stub_and_verifier;
1422
1423         /*
1424          * Check the data length doesn't go over the 15Mb limit.
1425          * increased after observing a bug in the Windows NT 4.0 SP6a
1426          * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1427          * will not fit in the initial buffer of size 0x1068   --jerry 22/01/2002
1428          */
1429
1430         if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1431                 DEBUG(0, ("process_request_pdu: "
1432                           "rpc data buffer too large (%u) + (%u)\n",
1433                           (unsigned int)p->in_data.data.length,
1434                           (unsigned int)data.length));
1435                 set_incoming_fault(p);
1436                 return False;
1437         }
1438
1439         /*
1440          * Append the data portion into the buffer and return.
1441          */
1442
1443         if (data.length) {
1444                 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1445                                           data.data, data.length)) {
1446                         DEBUG(0, ("Unable to append data size %u "
1447                                   "to parse buffer of size %u.\n",
1448                                   (unsigned int)data.length,
1449                                   (unsigned int)p->in_data.data.length));
1450                         set_incoming_fault(p);
1451                         return False;
1452                 }
1453         }
1454
1455         if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1456                 bool ret = False;
1457                 /*
1458                  * Ok - we finally have a complete RPC stream.
1459                  * Call the rpc command to process it.
1460                  */
1461
1462                 /*
1463                  * Process the complete data stream here.
1464                  */
1465                 if (pipe_init_outgoing_data(p)) {
1466                         ret = api_pipe_request(p, pkt);
1467                 }
1468
1469                 return ret;
1470         }
1471
1472         return True;
1473 }
1474
1475 /****************************************************************************
1476  Processes a finished PDU stored in p->in_data.pdu.
1477 ****************************************************************************/
1478
1479 void process_complete_pdu(struct pipes_struct *p)
1480 {
1481         struct ncacn_packet *pkt = NULL;
1482         NTSTATUS status;
1483         bool reply = False;
1484
1485         if(p->fault_state) {
1486                 DEBUG(10,("RPC connection in fault state.\n"));
1487                 goto done;
1488         }
1489
1490         pkt = talloc(p->mem_ctx, struct ncacn_packet);
1491         if (!pkt) {
1492                 DEBUG(0, ("Out of memory!\n"));
1493                 goto done;
1494         }
1495
1496         /*
1497          * Ensure we're using the corrent endianness for both the
1498          * RPC header flags and the raw data we will be reading from.
1499          */
1500         if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1501                 p->endian = RPC_LITTLE_ENDIAN;
1502         } else {
1503                 p->endian = RPC_BIG_ENDIAN;
1504         }
1505         DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1506
1507         status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1508                                           pkt, p->endian);
1509         if (!NT_STATUS_IS_OK(status)) {
1510                 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1511                           nt_errstr(status)));
1512                 goto done;
1513         }
1514
1515         /* Store the call_id */
1516         p->call_id = pkt->call_id;
1517
1518         DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1519
1520         switch (pkt->ptype) {
1521         case DCERPC_PKT_REQUEST:
1522                 reply = process_request_pdu(p, pkt);
1523                 break;
1524
1525         case DCERPC_PKT_PING: /* CL request - ignore... */
1526                 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1527                           (unsigned int)pkt->ptype));
1528                 break;
1529
1530         case DCERPC_PKT_RESPONSE: /* No responses here. */
1531                 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1532                 break;
1533
1534         case DCERPC_PKT_FAULT:
1535         case DCERPC_PKT_WORKING:
1536                 /* CL request - reply to a ping when a call in process. */
1537         case DCERPC_PKT_NOCALL:
1538                 /* CL - server reply to a ping call. */
1539         case DCERPC_PKT_REJECT:
1540         case DCERPC_PKT_ACK:
1541         case DCERPC_PKT_CL_CANCEL:
1542         case DCERPC_PKT_FACK:
1543         case DCERPC_PKT_CANCEL_ACK:
1544                 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1545                           (unsigned int)pkt->ptype));
1546                 break;
1547
1548         case DCERPC_PKT_BIND:
1549                 /*
1550                  * We assume that a pipe bind is only in one pdu.
1551                  */
1552                 if (pipe_init_outgoing_data(p)) {
1553                         reply = api_pipe_bind_req(p, pkt);
1554                 }
1555                 break;
1556
1557         case DCERPC_PKT_BIND_ACK:
1558         case DCERPC_PKT_BIND_NAK:
1559                 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1560                           "packet type %u received.\n",
1561                           (unsigned int)pkt->ptype));
1562                 break;
1563
1564
1565         case DCERPC_PKT_ALTER:
1566                 /*
1567                  * We assume that a pipe bind is only in one pdu.
1568                  */
1569                 if (pipe_init_outgoing_data(p)) {
1570                         reply = api_pipe_alter_context(p, pkt);
1571                 }
1572                 break;
1573
1574         case DCERPC_PKT_ALTER_RESP:
1575                 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1576                           "Should only be server -> client.\n"));
1577                 break;
1578
1579         case DCERPC_PKT_AUTH3:
1580                 /*
1581                  * The third packet in an auth exchange.
1582                  */
1583                 if (pipe_init_outgoing_data(p)) {
1584                         reply = api_pipe_bind_auth3(p, pkt);
1585                 }
1586                 break;
1587
1588         case DCERPC_PKT_SHUTDOWN:
1589                 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1590                           "Should only be server -> client.\n"));
1591                 break;
1592
1593         case DCERPC_PKT_CO_CANCEL:
1594                 /* For now just free all client data and continue
1595                  * processing. */
1596                 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1597                          " Abandoning rpc call.\n"));
1598                 /* As we never do asynchronous RPC serving, we can
1599                  * never cancel a call (as far as I know).
1600                  * If we ever did we'd have to send a cancel_ack reply.
1601                  * For now, just free all client data and continue
1602                  * processing. */
1603                 reply = True;
1604                 break;
1605
1606 #if 0
1607                 /* Enable this if we're doing async rpc. */
1608                 /* We must check the outstanding callid matches. */
1609                 if (pipe_init_outgoing_data(p)) {
1610                         /* Send a cancel_ack PDU reply. */
1611                         /* We should probably check the auth-verifier here. */
1612                         reply = setup_cancel_ack_reply(p, pkt);
1613                 }
1614                 break;
1615 #endif
1616
1617         case DCERPC_PKT_ORPHANED:
1618                 /* We should probably check the auth-verifier here.
1619                  * For now just free all client data and continue
1620                  * processing. */
1621                 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1622                           " Abandoning rpc call.\n"));
1623                 reply = True;
1624                 break;
1625
1626         default:
1627                 DEBUG(0, ("process_complete_pdu: "
1628                           "Unknown rpc type = %u received.\n",
1629                           (unsigned int)pkt->ptype));
1630                 break;
1631         }
1632
1633 done:
1634         if (!reply) {
1635                 DEBUG(3,("DCE/RPC fault sent!"));
1636                 set_incoming_fault(p);
1637                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1638                 TALLOC_FREE(pkt);
1639         } else {
1640                 /*
1641                  * Reset the lengths. We're ready for a new pdu.
1642                  */
1643                 TALLOC_FREE(p->in_data.pdu.data);
1644                 p->in_data.pdu_needed_len = 0;
1645                 p->in_data.pdu.length = 0;
1646         }
1647
1648         TALLOC_FREE(pkt);
1649 }
1650