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