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