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