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