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