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