source: trunk/server/source3/rpc_server/srv_pipe.c

Last change on this file was 920, checked in by Silvan Scherrer, 9 years ago

Samba Server: apply latest security patches to trunk

File size: 62.3 KB
Line 
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_ntlmssp.h"
37#include "dcesrv_gssapi.h"
38#include "dcesrv_spnego.h"
39#include "rpc_server.h"
40#include "rpc_dce.h"
41#include "smbd/smbd.h"
42#include "auth.h"
43#include "ntdomain.h"
44#include "rpc_server/srv_pipe.h"
45#include "../librpc/gen_ndr/ndr_dcerpc.h"
46#include "../librpc/ndr/ndr_dcerpc.h"
47#include "../librpc/gen_ndr/ndr_samr.h"
48#include "../librpc/gen_ndr/ndr_lsa.h"
49#include "../librpc/gen_ndr/ndr_netlogon.h"
50#include "../librpc/gen_ndr/ndr_epmapper.h"
51#include "../librpc/gen_ndr/ndr_echo.h"
52
53#undef DBGC_CLASS
54#define DBGC_CLASS DBGC_RPC_SRV
55
56/**
57 * Dump everything from the start of the end up of the provided data
58 * into a file, but only at debug level >= 50
59 **/
60static void dump_pdu_region(const char *name, int v,
61 DATA_BLOB *data, size_t start, size_t end)
62{
63 int fd, i;
64 char *fname = NULL;
65 ssize_t sz;
66
67 if (DEBUGLEVEL < 50) return;
68
69 if (start > data->length || end > data->length || start > end) return;
70
71 for (i = 1; i < 100; i++) {
72 if (v != -1) {
73 fname = talloc_asprintf(talloc_tos(),
74 "/tmp/%s_%d.%d.prs",
75 name, v, i);
76 } else {
77 fname = talloc_asprintf(talloc_tos(),
78 "/tmp/%s_%d.prs",
79 name, i);
80 }
81 if (!fname) {
82 return;
83 }
84 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
85 if (fd != -1 || errno != EEXIST) break;
86 }
87 if (fd != -1) {
88 sz = write(fd, data->data + start, end - start);
89 i = close(fd);
90 if ((sz != end - start) || (i != 0) ) {
91 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
92 fname, (unsigned long)sz,
93 (unsigned long)end - start, i));
94 } else {
95 DEBUG(0,("created %s\n", fname));
96 }
97 }
98 TALLOC_FREE(fname);
99}
100
101static DATA_BLOB generic_session_key(void)
102{
103 return data_blob_const("SystemLibraryDTC", 16);
104}
105
106/*******************************************************************
107 Generate the next PDU to be returned from the data.
108********************************************************************/
109
110static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
111 struct pipe_auth_data *auth,
112 uint32_t call_id,
113 DATA_BLOB *rdata,
114 size_t data_sent_length,
115 DATA_BLOB *frag,
116 size_t *pdu_size)
117{
118 union dcerpc_payload u;
119 uint8_t pfc_flags;
120 size_t data_left;
121 size_t data_to_send;
122 size_t frag_len;
123 size_t pad_len = 0;
124 size_t auth_len = 0;
125 NTSTATUS status;
126
127 ZERO_STRUCT(u.response);
128
129 /* Set up rpc packet pfc flags. */
130 if (data_sent_length == 0) {
131 pfc_flags = DCERPC_PFC_FLAG_FIRST;
132 } else {
133 pfc_flags = 0;
134 }
135
136 /* Work out how much we can fit in a single PDU. */
137 data_left = rdata->length - data_sent_length;
138
139 /* Ensure there really is data left to send. */
140 if (!data_left) {
141 DEBUG(0, ("No data left to send !\n"));
142 return NT_STATUS_BUFFER_TOO_SMALL;
143 }
144
145 status = dcerpc_guess_sizes(auth,
146 DCERPC_RESPONSE_LENGTH,
147 data_left,
148 RPC_MAX_PDU_FRAG_LEN,
149 SERVER_NDR_PADDING_SIZE,
150 &data_to_send, &frag_len,
151 &auth_len, &pad_len);
152 if (!NT_STATUS_IS_OK(status)) {
153 return status;
154 }
155
156 /* Set up the alloc hint. This should be the data left to send. */
157 u.response.alloc_hint = data_left;
158
159 /* Work out if this PDU will be the last. */
160 if (data_sent_length + data_to_send >= rdata->length) {
161 pfc_flags |= DCERPC_PFC_FLAG_LAST;
162 }
163
164 /* Prepare data to be NDR encoded. */
165 u.response.stub_and_verifier =
166 data_blob_const(rdata->data + data_sent_length, data_to_send);
167
168 /* Store the packet in the data stream. */
169 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
170 pfc_flags, auth_len, call_id,
171 &u, frag);
172 if (!NT_STATUS_IS_OK(status)) {
173 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
174 return status;
175 }
176
177 if (auth_len) {
178 /* Set the proper length on the pdu, including padding.
179 * Only needed if an auth trailer will be appended. */
180 dcerpc_set_frag_length(frag, frag->length
181 + pad_len
182 + DCERPC_AUTH_TRAILER_LENGTH
183 + auth_len);
184 }
185
186 if (auth_len) {
187 status = dcerpc_add_auth_footer(auth, pad_len, frag);
188 if (!NT_STATUS_IS_OK(status)) {
189 data_blob_free(frag);
190 return status;
191 }
192 }
193
194 *pdu_size = data_to_send;
195 return NT_STATUS_OK;
196}
197
198/*******************************************************************
199 Generate the next PDU to be returned from the data in p->rdata.
200********************************************************************/
201
202bool create_next_pdu(struct pipes_struct *p)
203{
204 size_t pdu_size = 0;
205 NTSTATUS status;
206
207 /*
208 * If we're in the fault state, keep returning fault PDU's until
209 * the pipe gets closed. JRA.
210 */
211 if (p->fault_state) {
212 setup_fault_pdu(p, NT_STATUS(p->fault_state));
213 return true;
214 }
215
216 status = create_next_packet(p->mem_ctx, &p->auth,
217 p->call_id, &p->out_data.rdata,
218 p->out_data.data_sent_length,
219 &p->out_data.frag, &pdu_size);
220 if (!NT_STATUS_IS_OK(status)) {
221 DEBUG(0, ("Failed to create packet with error %s, "
222 "(auth level %u / type %u)\n",
223 nt_errstr(status),
224 (unsigned int)p->auth.auth_level,
225 (unsigned int)p->auth.auth_type));
226 return false;
227 }
228
229 /* Setup the counts for this PDU. */
230 p->out_data.data_sent_length += pdu_size;
231 p->out_data.current_pdu_sent = 0;
232 return true;
233}
234
235
236static bool pipe_init_outgoing_data(struct pipes_struct *p);
237
238/*******************************************************************
239 Marshall a bind_nak pdu.
240*******************************************************************/
241
242static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
243{
244 NTSTATUS status;
245 union dcerpc_payload u;
246
247 /* Free any memory in the current return data buffer. */
248 pipe_init_outgoing_data(p);
249
250 /*
251 * Initialize a bind_nak header.
252 */
253
254 ZERO_STRUCT(u);
255
256 u.bind_nak.reject_reason = 0;
257
258 /*
259 * Marshall directly into the outgoing PDU space. We
260 * must do this as we need to set to the bind response
261 * header and are never sending more than one PDU here.
262 */
263
264 status = dcerpc_push_ncacn_packet(p->mem_ctx,
265 DCERPC_PKT_BIND_NAK,
266 DCERPC_PFC_FLAG_FIRST |
267 DCERPC_PFC_FLAG_LAST,
268 0,
269 pkt->call_id,
270 &u,
271 &p->out_data.frag);
272 if (!NT_STATUS_IS_OK(status)) {
273 return False;
274 }
275
276 p->out_data.data_sent_length = 0;
277 p->out_data.current_pdu_sent = 0;
278
279 set_incoming_fault(p);
280 TALLOC_FREE(p->auth.auth_ctx);
281 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
282 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
283 p->pipe_bound = False;
284 p->allow_bind = false;
285 p->allow_alter = false;
286 p->allow_auth3 = false;
287
288 return True;
289}
290
291/*******************************************************************
292 Marshall a fault pdu.
293*******************************************************************/
294
295bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
296{
297 NTSTATUS status;
298 union dcerpc_payload u;
299
300 /* Free any memory in the current return data buffer. */
301 pipe_init_outgoing_data(p);
302
303 /*
304 * Initialize a fault header.
305 */
306
307 ZERO_STRUCT(u);
308
309 u.fault.status = NT_STATUS_V(fault_status);
310 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
311
312 /*
313 * Marshall directly into the outgoing PDU space. We
314 * must do this as we need to set to the bind response
315 * header and are never sending more than one PDU here.
316 */
317
318 status = dcerpc_push_ncacn_packet(p->mem_ctx,
319 DCERPC_PKT_FAULT,
320 DCERPC_PFC_FLAG_FIRST |
321 DCERPC_PFC_FLAG_LAST |
322 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
323 0,
324 p->call_id,
325 &u,
326 &p->out_data.frag);
327 if (!NT_STATUS_IS_OK(status)) {
328 return False;
329 }
330
331 p->out_data.data_sent_length = 0;
332 p->out_data.current_pdu_sent = 0;
333
334 return True;
335}
336
337/*******************************************************************
338 Ensure a bind request has the correct abstract & transfer interface.
339 Used to reject unknown binds from Win2k.
340*******************************************************************/
341
342static bool check_bind_req(struct pipes_struct *p,
343 struct ndr_syntax_id* abstract,
344 struct ndr_syntax_id* transfer,
345 uint32 context_id)
346{
347 struct pipe_rpc_fns *context_fns;
348 const char *interface_name = NULL;
349 bool ok;
350
351 DEBUG(3,("check_bind_req for %s\n",
352 get_pipe_name_from_syntax(talloc_tos(), abstract)));
353
354 ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax);
355 if (!ok) {
356 DEBUG(1,("check_bind_req unknown transfer syntax for "
357 "%s context_id=%u\n",
358 get_pipe_name_from_syntax(talloc_tos(), abstract),
359 (unsigned)context_id));
360 return false;
361 }
362
363 for (context_fns = p->contexts;
364 context_fns != NULL;
365 context_fns = context_fns->next)
366 {
367 if (context_fns->context_id != context_id) {
368 continue;
369 }
370
371 ok = ndr_syntax_id_equal(&context_fns->syntax,
372 abstract);
373 if (ok) {
374 return true;
375 }
376
377 DEBUG(1,("check_bind_req: changing abstract syntax for "
378 "%s context_id=%u into %s not supported\n",
379 get_pipe_name_from_syntax(talloc_tos(), &context_fns->syntax),
380 (unsigned)context_id,
381 get_pipe_name_from_syntax(talloc_tos(), abstract)));
382 return false;
383 }
384
385 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
386 if (!rpc_srv_pipe_exists_by_id(abstract)) {
387 return false;
388 }
389
390 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
391 rpc_srv_get_pipe_cli_name(abstract),
392 rpc_srv_get_pipe_srv_name(abstract)));
393
394 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
395 if (context_fns == NULL) {
396 DEBUG(0,("check_bind_req: malloc() failed!\n"));
397 return False;
398 }
399
400 interface_name = get_pipe_name_from_syntax(talloc_tos(),
401 abstract);
402
403 SMB_ASSERT(interface_name != NULL);
404
405 context_fns->next = context_fns->prev = NULL;
406 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
407 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
408 context_fns->context_id = context_id;
409 context_fns->syntax = *abstract;
410
411 context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
412 /*
413 * for the samr and the lsarpc interfaces we don't allow "connect"
414 * auth_level by default.
415 */
416 ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
417 if (ok) {
418 context_fns->allow_connect = false;
419 }
420 ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
421 if (ok) {
422 context_fns->allow_connect = false;
423 }
424 ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
425 if (ok) {
426 context_fns->allow_connect = false;
427 }
428 /*
429 * for the epmapper and echo interfaces we allow "connect"
430 * auth_level by default.
431 */
432 ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
433 if (ok) {
434 context_fns->allow_connect = true;
435 }
436 ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
437 if (ok) {
438 context_fns->allow_connect = true;
439 }
440 /*
441 * every interface can be modified to allow "connect" auth_level by
442 * using a parametric option like:
443 * allow dcerpc auth level connect:<interface>
444 * e.g.
445 * allow dcerpc auth level connect:samr = yes
446 */
447 context_fns->allow_connect = lp_parm_bool(-1,
448 "allow dcerpc auth level connect",
449 interface_name, context_fns->allow_connect);
450
451 /* add to the list of open contexts */
452
453 DLIST_ADD( p->contexts, context_fns );
454
455 return True;
456}
457
458/**
459 * Is a named pipe known?
460 * @param[in] cli_filename The pipe name requested by the client
461 * @result Do we want to serve this?
462 */
463bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
464{
465 const char *pipename = cli_filename;
466 NTSTATUS status;
467
468 if (strnequal(pipename, "\\PIPE\\", 6)) {
469 pipename += 5;
470 }
471
472 if (*pipename == '\\') {
473 pipename += 1;
474 }
475
476 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
477 DEBUG(10, ("refusing spoolss access\n"));
478 return false;
479 }
480
481 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
482 return true;
483 }
484
485 status = smb_probe_module("rpc", pipename);
486 if (!NT_STATUS_IS_OK(status)) {
487 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
488 return false;
489 }
490 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
491
492 /*
493 * Scan the list again for the interface id
494 */
495 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
496 return true;
497 }
498
499 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
500 pipename));
501
502 return false;
503}
504
505/*******************************************************************
506 Handle the first part of a SPNEGO bind auth.
507*******************************************************************/
508
509static bool pipe_spnego_auth_bind(struct pipes_struct *p,
510 TALLOC_CTX *mem_ctx,
511 struct dcerpc_auth *auth_info,
512 DATA_BLOB *response)
513{
514 struct spnego_context *spnego_ctx;
515 NTSTATUS status;
516
517 status = spnego_server_auth_start(p,
518 (auth_info->auth_level ==
519 DCERPC_AUTH_LEVEL_INTEGRITY),
520 (auth_info->auth_level ==
521 DCERPC_AUTH_LEVEL_PRIVACY),
522 true,
523 &auth_info->credentials,
524 response,
525 &spnego_ctx);
526 if (!NT_STATUS_IS_OK(status)) {
527 DEBUG(0, ("Failed SPNEGO negotiate (%s)\n",
528 nt_errstr(status)));
529 return false;
530 }
531
532 /* Make sure data is bound to the memctx, to be freed the caller */
533 talloc_steal(mem_ctx, response->data);
534
535 p->auth.auth_ctx = spnego_ctx;
536 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
537 p->auth.auth_context_id = auth_info->auth_context_id;
538
539 DEBUG(10, ("SPNEGO auth started\n"));
540
541 return true;
542}
543
544/*******************************************************************
545 Handle an schannel bind auth.
546*******************************************************************/
547
548static bool pipe_schannel_auth_bind(struct pipes_struct *p,
549 TALLOC_CTX *mem_ctx,
550 struct dcerpc_auth *auth_info,
551 DATA_BLOB *response)
552{
553 struct NL_AUTH_MESSAGE neg;
554 struct NL_AUTH_MESSAGE reply;
555 bool ret;
556 NTSTATUS status;
557 struct netlogon_creds_CredentialState *creds;
558 enum ndr_err_code ndr_err;
559 struct schannel_state *schannel_auth;
560
561 ndr_err = ndr_pull_struct_blob(
562 &auth_info->credentials, mem_ctx, &neg,
563 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
564 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
565 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
566 return false;
567 }
568
569 if (DEBUGLEVEL >= 10) {
570 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
571 }
572
573 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
574 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
575 return false;
576 }
577
578 /*
579 * The neg.oem_netbios_computer.a key here must match the remote computer name
580 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
581 * operations that use credentials.
582 */
583
584 become_root();
585 status = schannel_get_creds_state(p, lp_private_dir(),
586 neg.oem_netbios_computer.a, &creds);
587 unbecome_root();
588
589 if (!NT_STATUS_IS_OK(status)) {
590 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
591 return False;
592 }
593
594 schannel_auth = talloc(p, struct schannel_state);
595 if (!schannel_auth) {
596 TALLOC_FREE(creds);
597 return False;
598 }
599
600 schannel_auth->state = SCHANNEL_STATE_START;
601 schannel_auth->seq_num = 0;
602 schannel_auth->initiator = false;
603 schannel_auth->creds = creds;
604
605 /*
606 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
607 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
608 * struct of the person who opened the pipe. I need to test this further. JRA.
609 *
610 * VL. As we are mapping this to guest set the generic key
611 * "SystemLibraryDTC" key here. It's a bit difficult to test against
612 * W2k3, as it does not allow schannel binds against SAMR and LSA
613 * anymore.
614 */
615
616 ret = session_info_set_session_key(p->session_info, generic_session_key());
617
618 if (!ret) {
619 DEBUG(0, ("session_info_set_session_key failed\n"));
620 return false;
621 }
622
623 /*** SCHANNEL verifier ***/
624
625 reply.MessageType = NL_NEGOTIATE_RESPONSE;
626 reply.Flags = 0;
627 reply.Buffer.dummy = 5; /* ??? actually I don't think
628 * this has any meaning
629 * here - gd */
630
631 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
632 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
633 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
634 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
635 return false;
636 }
637
638 if (DEBUGLEVEL >= 10) {
639 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
640 }
641
642 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
643 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
644
645 /* We're finished with this bind - no more packets. */
646 p->auth.auth_ctx = schannel_auth;
647 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
648 p->auth.auth_context_id = auth_info->auth_context_id;
649
650 p->pipe_bound = True;
651
652 return True;
653}
654
655/*******************************************************************
656 Handle an NTLMSSP bind auth.
657*******************************************************************/
658
659static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
660 TALLOC_CTX *mem_ctx,
661 struct dcerpc_auth *auth_info,
662 DATA_BLOB *response)
663{
664 struct auth_ntlmssp_state *ntlmssp_state = NULL;
665 NTSTATUS status;
666
667 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
668 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
669 return false;
670 }
671
672 /* We have an NTLMSSP blob. */
673 status = ntlmssp_server_auth_start(p,
674 (auth_info->auth_level ==
675 DCERPC_AUTH_LEVEL_INTEGRITY),
676 (auth_info->auth_level ==
677 DCERPC_AUTH_LEVEL_PRIVACY),
678 true,
679 &auth_info->credentials,
680 response,
681 &ntlmssp_state);
682 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
683 DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
684 nt_errstr(status)));
685 return false;
686 }
687
688 /* Make sure data is bound to the memctx, to be freed the caller */
689 talloc_steal(mem_ctx, response->data);
690
691 p->auth.auth_ctx = ntlmssp_state;
692 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
693 p->auth.auth_context_id = auth_info->auth_context_id;
694
695 DEBUG(10, (__location__ ": NTLMSSP auth started\n"));
696
697 return true;
698}
699
700/*******************************************************************
701 Process an NTLMSSP authentication response.
702 If this function succeeds, the user has been authenticated
703 and their domain, name and calling workstation stored in
704 the pipe struct.
705*******************************************************************/
706
707static bool pipe_ntlmssp_verify_final(TALLOC_CTX *mem_ctx,
708 struct auth_ntlmssp_state *ntlmssp_ctx,
709 enum dcerpc_AuthLevel auth_level,
710 struct client_address *client_id,
711 struct ndr_syntax_id *syntax,
712 struct auth_serversupplied_info **session_info)
713{
714 NTSTATUS status;
715 bool ret;
716
717 DEBUG(5, (__location__ ": pipe %s checking user details\n",
718 get_pipe_name_from_syntax(talloc_tos(), syntax)));
719
720 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
721 ensure the underlying NTLMSSP flags are also set. If not we should
722 refuse the bind. */
723
724 status = ntlmssp_server_check_flags(ntlmssp_ctx,
725 (auth_level ==
726 DCERPC_AUTH_LEVEL_INTEGRITY),
727 (auth_level ==
728 DCERPC_AUTH_LEVEL_PRIVACY));
729 if (!NT_STATUS_IS_OK(status)) {
730 DEBUG(0, (__location__ ": Client failed to negotatie proper "
731 "security for pipe %s\n",
732 get_pipe_name_from_syntax(talloc_tos(), syntax)));
733 return false;
734 }
735
736 TALLOC_FREE(*session_info);
737
738 status = ntlmssp_server_get_user_info(ntlmssp_ctx,
739 mem_ctx, session_info);
740 if (!NT_STATUS_IS_OK(status)) {
741 DEBUG(0, (__location__ ": failed to obtain the server info "
742 "for authenticated user: %s\n", nt_errstr(status)));
743 return false;
744 }
745
746 if ((*session_info)->security_token == NULL) {
747 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
748 return false;
749 }
750
751 /*
752 * We're an authenticated bind over smb, so the session key needs to
753 * be set to "SystemLibraryDTC". Weird, but this is what Windows
754 * does. See the RPC-SAMBA3SESSIONKEY.
755 */
756
757 ret = session_info_set_session_key((*session_info), generic_session_key());
758 if (!ret) {
759 DEBUG(0, ("Failed to set session key!\n"));
760 return false;
761 }
762
763 return true;
764}
765
766/*******************************************************************
767 Handle a GSSAPI bind auth.
768*******************************************************************/
769
770static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
771 TALLOC_CTX *mem_ctx,
772 struct dcerpc_auth *auth_info,
773 DATA_BLOB *response)
774{
775 NTSTATUS status;
776 struct gse_context *gse_ctx = NULL;
777
778 status = gssapi_server_auth_start(p,
779 (auth_info->auth_level ==
780 DCERPC_AUTH_LEVEL_INTEGRITY),
781 (auth_info->auth_level ==
782 DCERPC_AUTH_LEVEL_PRIVACY),
783 true,
784 &auth_info->credentials,
785 response,
786 &gse_ctx);
787 if (!NT_STATUS_IS_OK(status)) {
788 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
789 nt_errstr(status)));
790 goto err;
791 }
792
793 /* Make sure data is bound to the memctx, to be freed the caller */
794 talloc_steal(mem_ctx, response->data);
795
796 p->auth.auth_ctx = gse_ctx;
797 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
798
799 DEBUG(10, ("KRB5 auth started\n"));
800
801 return true;
802
803err:
804 TALLOC_FREE(gse_ctx);
805 return false;
806}
807
808static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
809 struct gse_context *gse_ctx,
810 struct client_address *client_id,
811 struct auth_serversupplied_info **session_info)
812{
813 NTSTATUS status;
814 bool bret;
815
816 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
817 ensure the underlying flags are also set. If not we should
818 refuse the bind. */
819
820 status = gssapi_server_check_flags(gse_ctx);
821 if (!NT_STATUS_IS_OK(status)) {
822 DEBUG(0, ("Requested Security Layers not honored!\n"));
823 return status;
824 }
825
826 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
827 client_id, session_info);
828 if (!NT_STATUS_IS_OK(status)) {
829 DEBUG(0, (__location__ ": failed to obtain the server info "
830 "for authenticated user: %s\n", nt_errstr(status)));
831 return status;
832 }
833
834 if ((*session_info)->security_token == NULL) {
835 status = create_local_token(*session_info);
836 if (!NT_STATUS_IS_OK(status)) {
837 DEBUG(1, ("Failed to create local user token (%s)\n",
838 nt_errstr(status)));
839 status = NT_STATUS_ACCESS_DENIED;
840 return status;
841 }
842 }
843
844 /* TODO: this is what the ntlmssp code does with the session_key, check
845 * it is ok with gssapi too */
846 /*
847 * We're an authenticated bind over smb, so the session key needs to
848 * be set to "SystemLibraryDTC". Weird, but this is what Windows
849 * does. See the RPC-SAMBA3SESSIONKEY.
850 */
851
852 bret = session_info_set_session_key((*session_info), generic_session_key());
853 if (!bret) {
854 return NT_STATUS_ACCESS_DENIED;
855 }
856
857 return NT_STATUS_OK;
858}
859
860static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
861{
862 enum spnego_mech auth_type;
863 struct auth_ntlmssp_state *ntlmssp_ctx;
864 struct spnego_context *spnego_ctx;
865 struct gse_context *gse_ctx;
866 void *mech_ctx;
867 NTSTATUS status;
868
869 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
870 p->pipe_bound = true;
871 return NT_STATUS_OK;
872 }
873
874 switch (p->auth.auth_type) {
875 case DCERPC_AUTH_TYPE_NTLMSSP:
876 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
877 struct auth_ntlmssp_state);
878 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
879 p->auth.auth_level,
880 p->client_id, &p->syntax,
881 &p->session_info)) {
882 return NT_STATUS_ACCESS_DENIED;
883 }
884 break;
885 case DCERPC_AUTH_TYPE_KRB5:
886 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
887 struct gse_context);
888 status = pipe_gssapi_verify_final(p, gse_ctx,
889 p->client_id,
890 &p->session_info);
891 if (!NT_STATUS_IS_OK(status)) {
892 DEBUG(1, ("gssapi bind failed with: %s",
893 nt_errstr(status)));
894 return status;
895 }
896 break;
897 case DCERPC_AUTH_TYPE_SPNEGO:
898 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
899 struct spnego_context);
900 status = spnego_get_negotiated_mech(spnego_ctx,
901 &auth_type, &mech_ctx);
902 if (!NT_STATUS_IS_OK(status)) {
903 DEBUG(0, ("Bad SPNEGO state (%s)\n",
904 nt_errstr(status)));
905 return status;
906 }
907 switch(auth_type) {
908 case SPNEGO_KRB5:
909 gse_ctx = talloc_get_type_abort(mech_ctx,
910 struct gse_context);
911 status = pipe_gssapi_verify_final(p, gse_ctx,
912 p->client_id,
913 &p->session_info);
914 if (!NT_STATUS_IS_OK(status)) {
915 DEBUG(1, ("gssapi bind failed with: %s",
916 nt_errstr(status)));
917 return status;
918 }
919 break;
920 case SPNEGO_NTLMSSP:
921 ntlmssp_ctx = talloc_get_type_abort(mech_ctx,
922 struct auth_ntlmssp_state);
923 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
924 p->auth.auth_level,
925 p->client_id,
926 &p->syntax,
927 &p->session_info)) {
928 return NT_STATUS_ACCESS_DENIED;
929 }
930 break;
931 default:
932 DEBUG(0, (__location__ ": incorrect spnego type "
933 "(%d).\n", auth_type));
934 return NT_STATUS_ACCESS_DENIED;
935 }
936 break;
937 default:
938 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
939 (unsigned int)p->auth.auth_type));
940 return NT_STATUS_ACCESS_DENIED;
941 }
942
943 p->pipe_bound = true;
944
945 return NT_STATUS_OK;
946}
947
948/*******************************************************************
949 Respond to a pipe bind request.
950*******************************************************************/
951
952static bool api_pipe_bind_req(struct pipes_struct *p,
953 struct ncacn_packet *pkt)
954{
955 struct dcerpc_auth auth_info;
956 uint16 assoc_gid;
957 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
958 NTSTATUS status;
959 struct ndr_syntax_id id;
960 union dcerpc_payload u;
961 struct dcerpc_ack_ctx bind_ack_ctx;
962 DATA_BLOB auth_resp = data_blob_null;
963 DATA_BLOB auth_blob = data_blob_null;
964
965 if (!p->allow_bind) {
966 DEBUG(2,("Pipe not in allow bind state\n"));
967 return setup_bind_nak(p, pkt);
968 }
969 p->allow_bind = false;
970
971 status = dcerpc_verify_ncacn_packet_header(pkt,
972 DCERPC_PKT_BIND,
973 pkt->u.bind.auth_info.length,
974 0, /* required flags */
975 DCERPC_PFC_FLAG_FIRST |
976 DCERPC_PFC_FLAG_LAST |
977 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
978 0x08 | /* this is not defined, but should be ignored */
979 DCERPC_PFC_FLAG_CONC_MPX |
980 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
981 DCERPC_PFC_FLAG_MAYBE |
982 DCERPC_PFC_FLAG_OBJECT_UUID);
983 if (!NT_STATUS_IS_OK(status)) {
984 DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
985 nt_errstr(status)));
986 NDR_PRINT_DEBUG(ncacn_packet, pkt);
987 goto err_exit;
988 }
989
990 if (pkt->u.bind.num_contexts == 0) {
991 DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
992 goto err_exit;
993 }
994
995 if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) {
996 DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n"));
997 goto err_exit;
998 }
999
1000 /*
1001 * Try and find the correct pipe name to ensure
1002 * that this is a pipe name we support.
1003 */
1004 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1005 if (rpc_srv_pipe_exists_by_id(&id)) {
1006 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1007 rpc_srv_get_pipe_cli_name(&id),
1008 rpc_srv_get_pipe_srv_name(&id)));
1009 } else {
1010 status = smb_probe_module(
1011 "rpc", get_pipe_name_from_syntax(
1012 talloc_tos(),
1013 &pkt->u.bind.ctx_list[0].abstract_syntax));
1014
1015 if (NT_STATUS_IS_ERR(status)) {
1016 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1017 get_pipe_name_from_syntax(
1018 talloc_tos(),
1019 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1020
1021 return setup_bind_nak(p, pkt);
1022 }
1023
1024 if (rpc_srv_get_pipe_interface_by_cli_name(
1025 get_pipe_name_from_syntax(talloc_tos(),
1026 &p->syntax),
1027 &id)) {
1028 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1029 rpc_srv_get_pipe_cli_name(&id),
1030 rpc_srv_get_pipe_srv_name(&id)));
1031 } else {
1032 DEBUG(0, ("module %s doesn't provide functions for "
1033 "pipe %s!\n",
1034 get_pipe_name_from_syntax(talloc_tos(),
1035 &p->syntax),
1036 get_pipe_name_from_syntax(talloc_tos(),
1037 &p->syntax)));
1038 return setup_bind_nak(p, pkt);
1039 }
1040 }
1041
1042 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1043
1044 if (pkt->u.bind.assoc_group_id != 0) {
1045 assoc_gid = pkt->u.bind.assoc_group_id;
1046 } else {
1047 assoc_gid = 0x53f0;
1048 }
1049
1050 /*
1051 * Create the bind response struct.
1052 */
1053
1054 /* If the requested abstract synt uuid doesn't match our client pipe,
1055 reject the bind_ack & set the transfer interface synt to all 0's,
1056 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1057 unknown to NT4)
1058 Needed when adding entries to a DACL from NT5 - SK */
1059
1060 if (check_bind_req(p,
1061 &pkt->u.bind.ctx_list[0].abstract_syntax,
1062 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1063 pkt->u.bind.ctx_list[0].context_id)) {
1064
1065 bind_ack_ctx.result = 0;
1066 bind_ack_ctx.reason = 0;
1067 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1068 } else {
1069 p->pipe_bound = False;
1070 /* Rejection reason: abstract syntax not supported */
1071 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1072 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1073 bind_ack_ctx.syntax = null_ndr_syntax_id;
1074 }
1075
1076 /*
1077 * Check if this is an authenticated bind request.
1078 */
1079 if (pkt->auth_length) {
1080 /*
1081 * Decode the authentication verifier.
1082 */
1083 status = dcerpc_pull_auth_trailer(pkt, pkt,
1084 &pkt->u.bind.auth_info,
1085 &auth_info, NULL, true);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1088 goto err_exit;
1089 }
1090
1091 auth_type = auth_info.auth_type;
1092
1093 /* Work out if we have to sign or seal etc. */
1094 switch (auth_info.auth_level) {
1095 case DCERPC_AUTH_LEVEL_INTEGRITY:
1096 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1097 break;
1098 case DCERPC_AUTH_LEVEL_PRIVACY:
1099 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1100 break;
1101 case DCERPC_AUTH_LEVEL_CONNECT:
1102 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
1103 break;
1104 default:
1105 DEBUG(0, ("Unexpected auth level (%u).\n",
1106 (unsigned int)auth_info.auth_level ));
1107 goto err_exit;
1108 }
1109
1110 switch (auth_type) {
1111 case DCERPC_AUTH_TYPE_NTLMSSP:
1112 if (!pipe_ntlmssp_auth_bind(p, pkt,
1113 &auth_info, &auth_resp)) {
1114 goto err_exit;
1115 }
1116 assoc_gid = 0x7a77;
1117 break;
1118
1119 case DCERPC_AUTH_TYPE_SCHANNEL:
1120 if (!pipe_schannel_auth_bind(p, pkt,
1121 &auth_info, &auth_resp)) {
1122 goto err_exit;
1123 }
1124 break;
1125
1126 case DCERPC_AUTH_TYPE_SPNEGO:
1127 if (!pipe_spnego_auth_bind(p, pkt,
1128 &auth_info, &auth_resp)) {
1129 goto err_exit;
1130 }
1131 break;
1132
1133 case DCERPC_AUTH_TYPE_KRB5:
1134 if (!pipe_gssapi_auth_bind(p, pkt,
1135 &auth_info, &auth_resp)) {
1136 goto err_exit;
1137 }
1138 break;
1139
1140 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1141 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
1142 TALLOC_FREE(p->session_info);
1143
1144 status = make_session_info_system(p,
1145 &p->session_info);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 goto err_exit;
1148 }
1149
1150 auth_resp = data_blob_talloc(pkt,
1151 "NCALRPC_AUTH_OK",
1152 15);
1153
1154 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
1155 p->pipe_bound = true;
1156 } else {
1157 goto err_exit;
1158 }
1159 break;
1160
1161 case DCERPC_AUTH_TYPE_NONE:
1162 break;
1163
1164 default:
1165 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1166 goto err_exit;
1167 }
1168 }
1169
1170 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1171 /* Unauthenticated bind request. */
1172 /* We're finished - no more packets. */
1173 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1174 /* We must set the pipe auth_level here also. */
1175 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1176 p->pipe_bound = True;
1177 /* The session key was initialized from the SMB
1178 * session in make_internal_rpc_pipe_p */
1179 p->auth.auth_context_id = 0;
1180 }
1181
1182 ZERO_STRUCT(u.bind_ack);
1183 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1184 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1185 u.bind_ack.assoc_group_id = assoc_gid;
1186
1187 /* name has to be \PIPE\xxxxx */
1188 u.bind_ack.secondary_address =
1189 talloc_asprintf(pkt, "\\PIPE\\%s",
1190 rpc_srv_get_pipe_srv_name(&id));
1191 if (!u.bind_ack.secondary_address) {
1192 DEBUG(0, ("Out of memory!\n"));
1193 goto err_exit;
1194 }
1195 u.bind_ack.secondary_address_size =
1196 strlen(u.bind_ack.secondary_address) + 1;
1197
1198 u.bind_ack.num_results = 1;
1199 u.bind_ack.ctx_list = &bind_ack_ctx;
1200
1201 /* NOTE: We leave the auth_info empty so we can calculate the padding
1202 * later and then append the auth_info --simo */
1203
1204 /*
1205 * Marshall directly into the outgoing PDU space. We
1206 * must do this as we need to set to the bind response
1207 * header and are never sending more than one PDU here.
1208 */
1209
1210 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1211 DCERPC_PKT_BIND_ACK,
1212 DCERPC_PFC_FLAG_FIRST |
1213 DCERPC_PFC_FLAG_LAST,
1214 auth_resp.length,
1215 pkt->call_id,
1216 &u,
1217 &p->out_data.frag);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1220 nt_errstr(status)));
1221 goto err_exit;
1222 }
1223
1224 if (auth_resp.length) {
1225 status = dcerpc_push_dcerpc_auth(pkt,
1226 auth_type,
1227 auth_info.auth_level,
1228 0, /* pad_len */
1229 p->auth.auth_context_id,
1230 &auth_resp,
1231 &auth_blob);
1232 if (!NT_STATUS_IS_OK(status)) {
1233 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1234 goto err_exit;
1235 }
1236 }
1237
1238 /* Now that we have the auth len store it into the right place in
1239 * the dcerpc header */
1240 dcerpc_set_frag_length(&p->out_data.frag,
1241 p->out_data.frag.length + auth_blob.length);
1242
1243 if (auth_blob.length) {
1244
1245 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1246 auth_blob.data, auth_blob.length)) {
1247 DEBUG(0, ("Append of auth info failed.\n"));
1248 goto err_exit;
1249 }
1250 }
1251
1252 /*
1253 * Setup the lengths for the initial reply.
1254 */
1255
1256 p->out_data.data_sent_length = 0;
1257 p->out_data.current_pdu_sent = 0;
1258
1259 TALLOC_FREE(auth_blob.data);
1260
1261 if (bind_ack_ctx.result == 0) {
1262 p->allow_alter = true;
1263 p->allow_auth3 = true;
1264 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
1265 status = pipe_auth_verify_final(p);
1266 if (!NT_STATUS_IS_OK(status)) {
1267 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
1268 nt_errstr(status)));
1269 goto err_exit;
1270 }
1271 }
1272 } else {
1273 goto err_exit;
1274 }
1275
1276 return True;
1277
1278 err_exit:
1279
1280 data_blob_free(&p->out_data.frag);
1281 TALLOC_FREE(auth_blob.data);
1282 return setup_bind_nak(p, pkt);
1283}
1284
1285/*******************************************************************
1286 This is the "stage3" response after a bind request and reply.
1287*******************************************************************/
1288
1289bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1290{
1291 struct dcerpc_auth auth_info;
1292 DATA_BLOB response = data_blob_null;
1293 struct auth_ntlmssp_state *ntlmssp_ctx;
1294 struct spnego_context *spnego_ctx;
1295 struct gse_context *gse_ctx;
1296 NTSTATUS status;
1297
1298 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1299
1300 if (!p->allow_auth3) {
1301 DEBUG(1, ("Pipe not in allow auth3 state.\n"));
1302 goto err;
1303 }
1304
1305 status = dcerpc_verify_ncacn_packet_header(pkt,
1306 DCERPC_PKT_AUTH3,
1307 pkt->u.auth3.auth_info.length,
1308 0, /* required flags */
1309 DCERPC_PFC_FLAG_FIRST |
1310 DCERPC_PFC_FLAG_LAST |
1311 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1312 0x08 | /* this is not defined, but should be ignored */
1313 DCERPC_PFC_FLAG_CONC_MPX |
1314 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1315 DCERPC_PFC_FLAG_MAYBE |
1316 DCERPC_PFC_FLAG_OBJECT_UUID);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
1319 nt_errstr(status)));
1320 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1321 goto err;
1322 }
1323
1324 /* We can only finish if the pipe is unbound for now */
1325 if (p->pipe_bound) {
1326 DEBUG(0, (__location__ ": Pipe already bound, "
1327 "AUTH3 not supported!\n"));
1328 goto err;
1329 }
1330
1331 if (pkt->auth_length == 0) {
1332 DEBUG(1, ("No auth field sent for auth3 request!\n"));
1333 goto err;
1334 }
1335
1336 /*
1337 * Decode the authentication verifier response.
1338 */
1339
1340 status = dcerpc_pull_auth_trailer(pkt, pkt,
1341 &pkt->u.auth3.auth_info,
1342 &auth_info, NULL, true);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1345 goto err;
1346 }
1347
1348 /* We must NEVER look at auth_info->auth_pad_len here,
1349 * as old Samba client code gets it wrong and sends it
1350 * as zero. JRA.
1351 */
1352
1353 if (auth_info.auth_type != p->auth.auth_type) {
1354 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1355 "but auth was started as type %d!\n",
1356 auth_info.auth_type, p->auth.auth_type));
1357 goto err;
1358 }
1359
1360 if (auth_info.auth_level != p->auth.auth_level) {
1361 DEBUG(1, ("Auth level mismatch! Client sent %d, "
1362 "but auth was started as level %d!\n",
1363 auth_info.auth_level, p->auth.auth_level));
1364 goto err;
1365 }
1366
1367 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1368 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1369 "but auth was started as level %u!\n",
1370 (unsigned)auth_info.auth_context_id,
1371 (unsigned)p->auth.auth_context_id));
1372 goto err;
1373 }
1374
1375 switch (auth_info.auth_type) {
1376 case DCERPC_AUTH_TYPE_NTLMSSP:
1377 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1378 struct auth_ntlmssp_state);
1379 status = ntlmssp_server_step(ntlmssp_ctx,
1380 pkt, &auth_info.credentials,
1381 &response);
1382 break;
1383 case DCERPC_AUTH_TYPE_KRB5:
1384 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1385 struct gse_context);
1386 status = gssapi_server_step(gse_ctx,
1387 pkt, &auth_info.credentials,
1388 &response);
1389 break;
1390 case DCERPC_AUTH_TYPE_SPNEGO:
1391 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1392 struct spnego_context);
1393 status = spnego_server_step(spnego_ctx,
1394 pkt, &auth_info.credentials,
1395 &response);
1396 break;
1397 default:
1398 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1399 (unsigned int)auth_info.auth_type));
1400 return false;
1401 }
1402
1403 if (NT_STATUS_EQUAL(status,
1404 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1405 response.length) {
1406 DEBUG(0, (__location__ ": This was supposed to be the final "
1407 "leg, but crypto machinery claims a response is "
1408 "needed, aborting auth!\n"));
1409 data_blob_free(&response);
1410 goto err;
1411 }
1412 if (!NT_STATUS_IS_OK(status)) {
1413 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1414 goto err;
1415 }
1416
1417 /* Now verify auth was indeed successful and extract server info */
1418 status = pipe_auth_verify_final(p);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1421 goto err;
1422 }
1423
1424 return true;
1425
1426err:
1427 p->pipe_bound = false;
1428 p->allow_bind = false;
1429 p->allow_alter = false;
1430 p->allow_auth3 = false;
1431
1432 TALLOC_FREE(p->auth.auth_ctx);
1433 return false;
1434}
1435
1436/****************************************************************************
1437 Deal with an alter context call. Can be third part of 3 leg auth request for
1438 SPNEGO calls.
1439****************************************************************************/
1440
1441static bool api_pipe_alter_context(struct pipes_struct *p,
1442 struct ncacn_packet *pkt)
1443{
1444 struct dcerpc_auth auth_info;
1445 uint16 assoc_gid;
1446 NTSTATUS status;
1447 union dcerpc_payload u;
1448 struct dcerpc_ack_ctx alter_ack_ctx;
1449 DATA_BLOB auth_resp = data_blob_null;
1450 DATA_BLOB auth_blob = data_blob_null;
1451 int pad_len = 0;
1452 struct auth_ntlmssp_state *ntlmssp_ctx;
1453 struct spnego_context *spnego_ctx;
1454 struct gse_context *gse_ctx;
1455
1456 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1457
1458 if (!p->allow_alter) {
1459 DEBUG(1, ("Pipe not in allow alter state.\n"));
1460 goto err_exit;
1461 }
1462
1463 status = dcerpc_verify_ncacn_packet_header(pkt,
1464 DCERPC_PKT_ALTER,
1465 pkt->u.alter.auth_info.length,
1466 0, /* required flags */
1467 DCERPC_PFC_FLAG_FIRST |
1468 DCERPC_PFC_FLAG_LAST |
1469 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1470 0x08 | /* this is not defined, but should be ignored */
1471 DCERPC_PFC_FLAG_CONC_MPX |
1472 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1473 DCERPC_PFC_FLAG_MAYBE |
1474 DCERPC_PFC_FLAG_OBJECT_UUID);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
1477 nt_errstr(status)));
1478 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1479 goto err_exit;
1480 }
1481
1482 if (pkt->u.alter.num_contexts == 0) {
1483 DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
1484 goto err_exit;
1485 }
1486
1487 if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) {
1488 DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n"));
1489 goto err_exit;
1490 }
1491
1492 if (pkt->u.alter.assoc_group_id != 0) {
1493 assoc_gid = pkt->u.alter.assoc_group_id;
1494 } else {
1495 assoc_gid = 0x53f0;
1496 }
1497
1498 /*
1499 * Create the bind response struct.
1500 */
1501
1502 /* If the requested abstract synt uuid doesn't match our client pipe,
1503 reject the alter_ack & set the transfer interface synt to all 0's,
1504 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1505 unknown to NT4)
1506 Needed when adding entries to a DACL from NT5 - SK */
1507
1508 if (check_bind_req(p,
1509 &pkt->u.alter.ctx_list[0].abstract_syntax,
1510 &pkt->u.alter.ctx_list[0].transfer_syntaxes[0],
1511 pkt->u.alter.ctx_list[0].context_id)) {
1512
1513 alter_ack_ctx.result = 0;
1514 alter_ack_ctx.reason = 0;
1515 alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0];
1516 } else {
1517 /* Rejection reason: abstract syntax not supported */
1518 alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1519 alter_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1520 alter_ack_ctx.syntax = null_ndr_syntax_id;
1521 }
1522
1523 /*
1524 * Check if this is an authenticated alter context request.
1525 */
1526 if (pkt->auth_length) {
1527 /* We can only finish if the pipe is unbound for now */
1528 if (p->pipe_bound) {
1529 DEBUG(0, (__location__ ": Pipe already bound, "
1530 "Altering Context not yet supported!\n"));
1531 goto err_exit;
1532 }
1533
1534 status = dcerpc_pull_auth_trailer(pkt, pkt,
1535 &pkt->u.alter.auth_info,
1536 &auth_info, NULL, true);
1537 if (!NT_STATUS_IS_OK(status)) {
1538 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1539 goto err_exit;
1540 }
1541
1542 if (auth_info.auth_type != p->auth.auth_type) {
1543 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1544 "but auth was started as type %d!\n",
1545 auth_info.auth_type, p->auth.auth_type));
1546 goto err_exit;
1547 }
1548
1549 if (auth_info.auth_level != p->auth.auth_level) {
1550 DEBUG(0, ("Auth level mismatch! Client sent %d, "
1551 "but auth was started as level %d!\n",
1552 auth_info.auth_level, p->auth.auth_level));
1553 goto err_exit;
1554 }
1555
1556 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1557 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1558 "but auth was started as level %u!\n",
1559 (unsigned)auth_info.auth_context_id,
1560 (unsigned)p->auth.auth_context_id));
1561 goto err_exit;
1562 }
1563
1564 switch (auth_info.auth_type) {
1565 case DCERPC_AUTH_TYPE_SPNEGO:
1566 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1567 struct spnego_context);
1568 status = spnego_server_step(spnego_ctx,
1569 pkt,
1570 &auth_info.credentials,
1571 &auth_resp);
1572 break;
1573
1574 case DCERPC_AUTH_TYPE_KRB5:
1575 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1576 struct gse_context);
1577 status = gssapi_server_step(gse_ctx,
1578 pkt,
1579 &auth_info.credentials,
1580 &auth_resp);
1581 break;
1582 case DCERPC_AUTH_TYPE_NTLMSSP:
1583 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1584 struct auth_ntlmssp_state);
1585 status = ntlmssp_server_step(ntlmssp_ctx,
1586 pkt,
1587 &auth_info.credentials,
1588 &auth_resp);
1589 break;
1590
1591 default:
1592 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1593 "in alter-context call\n",
1594 auth_info.auth_type));
1595 goto err_exit;
1596 }
1597
1598 if (NT_STATUS_IS_OK(status)) {
1599 /* third leg of auth, verify auth info */
1600 status = pipe_auth_verify_final(p);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 DEBUG(0, ("Auth Verify failed (%s)\n",
1603 nt_errstr(status)));
1604 goto err_exit;
1605 }
1606 } else if (NT_STATUS_EQUAL(status,
1607 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1608 DEBUG(10, ("More auth legs required.\n"));
1609 } else {
1610 DEBUG(0, ("Auth step returned an error (%s)\n",
1611 nt_errstr(status)));
1612 goto err_exit;
1613 }
1614 }
1615
1616 ZERO_STRUCT(u.alter_resp);
1617 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1618 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1619 u.alter_resp.assoc_group_id = assoc_gid;
1620
1621 /* secondary address CAN be NULL
1622 * as the specs say it's ignored.
1623 * It MUST be NULL to have the spoolss working.
1624 */
1625 u.alter_resp.secondary_address = "";
1626 u.alter_resp.secondary_address_size = 1;
1627
1628 u.alter_resp.num_results = 1;
1629 u.alter_resp.ctx_list = &alter_ack_ctx;
1630
1631 /* NOTE: We leave the auth_info empty so we can calculate the padding
1632 * later and then append the auth_info --simo */
1633
1634 /*
1635 * Marshall directly into the outgoing PDU space. We
1636 * must do this as we need to set to the bind response
1637 * header and are never sending more than one PDU here.
1638 */
1639
1640 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1641 DCERPC_PKT_ALTER_RESP,
1642 DCERPC_PFC_FLAG_FIRST |
1643 DCERPC_PFC_FLAG_LAST,
1644 auth_resp.length,
1645 pkt->call_id,
1646 &u,
1647 &p->out_data.frag);
1648 if (!NT_STATUS_IS_OK(status)) {
1649 DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n",
1650 nt_errstr(status)));
1651 goto err_exit;
1652 }
1653
1654 if (auth_resp.length) {
1655
1656 /* Work out any padding needed before the auth footer. */
1657 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1658 if (pad_len) {
1659 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1660 DEBUG(10, ("auth pad_len = %u\n",
1661 (unsigned int)pad_len));
1662 }
1663
1664 status = dcerpc_push_dcerpc_auth(pkt,
1665 auth_info.auth_type,
1666 auth_info.auth_level,
1667 pad_len,
1668 p->auth.auth_context_id,
1669 &auth_resp,
1670 &auth_blob);
1671 if (!NT_STATUS_IS_OK(status)) {
1672 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1673 goto err_exit;
1674 }
1675 }
1676
1677 /* Now that we have the auth len store it into the right place in
1678 * the dcerpc header */
1679 dcerpc_set_frag_length(&p->out_data.frag,
1680 p->out_data.frag.length +
1681 pad_len + auth_blob.length);
1682
1683 if (auth_resp.length) {
1684 if (pad_len) {
1685 char pad[SERVER_NDR_PADDING_SIZE];
1686 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1687 if (!data_blob_append(p->mem_ctx,
1688 &p->out_data.frag,
1689 pad, pad_len)) {
1690 DEBUG(0, ("api_pipe_bind_req: failed to add "
1691 "%u bytes of pad data.\n",
1692 (unsigned int)pad_len));
1693 goto err_exit;
1694 }
1695 }
1696
1697 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1698 auth_blob.data, auth_blob.length)) {
1699 DEBUG(0, ("Append of auth info failed.\n"));
1700 goto err_exit;
1701 }
1702 }
1703
1704 /*
1705 * Setup the lengths for the initial reply.
1706 */
1707
1708 p->out_data.data_sent_length = 0;
1709 p->out_data.current_pdu_sent = 0;
1710
1711 TALLOC_FREE(auth_blob.data);
1712 return True;
1713
1714 err_exit:
1715
1716 data_blob_free(&p->out_data.frag);
1717 TALLOC_FREE(auth_blob.data);
1718 return setup_bind_nak(p, pkt);
1719}
1720
1721/****************************************************************************
1722 Find the set of RPC functions associated with this context_id
1723****************************************************************************/
1724
1725static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1726{
1727 PIPE_RPC_FNS *fns = NULL;
1728
1729 if ( !list ) {
1730 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1731 return NULL;
1732 }
1733
1734 for (fns=list; fns; fns=fns->next ) {
1735 if ( fns->context_id == context_id )
1736 return fns;
1737 }
1738 return NULL;
1739}
1740
1741static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1742 const struct api_struct *api_rpc_cmds, int n_cmds,
1743 const struct ndr_syntax_id *syntax);
1744
1745static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1746 struct ncacn_packet *pkt,
1747 struct pipe_rpc_fns *pipe_fns)
1748{
1749 TALLOC_CTX *frame = talloc_stackframe();
1750 struct dcerpc_sec_verification_trailer *vt = NULL;
1751 const uint32_t bitmask1 = 0;
1752 const struct dcerpc_sec_vt_pcontext pcontext = {
1753 .abstract_syntax = pipe_fns->syntax,
1754 .transfer_syntax = ndr_transfer_syntax,
1755 };
1756 const struct dcerpc_sec_vt_header2 header2 =
1757 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1758 struct ndr_pull *ndr;
1759 enum ndr_err_code ndr_err;
1760 bool ret = false;
1761
1762 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1763 if (ndr == NULL) {
1764 goto done;
1765 }
1766
1767 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1768 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1769 goto done;
1770 }
1771
1772 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1773 &pcontext, &header2);
1774done:
1775 TALLOC_FREE(frame);
1776 return ret;
1777}
1778
1779/****************************************************************************
1780 Find the correct RPC function to call for this request.
1781 If the pipe is authenticated then become the correct UNIX user
1782 before doing the call.
1783****************************************************************************/
1784
1785static bool api_pipe_request(struct pipes_struct *p,
1786 struct ncacn_packet *pkt)
1787{
1788 TALLOC_CTX *frame = talloc_stackframe();
1789 bool ret = False;
1790 PIPE_RPC_FNS *pipe_fns;
1791 const char *interface_name = NULL;
1792
1793 if (!p->pipe_bound) {
1794 DEBUG(1, ("Pipe not bound!\n"));
1795 data_blob_free(&p->out_data.rdata);
1796 TALLOC_FREE(frame);
1797 return false;
1798 }
1799
1800 /* get the set of RPC functions for this context */
1801
1802 pipe_fns = find_pipe_fns_by_context(p->contexts,
1803 pkt->u.request.context_id);
1804 if (pipe_fns == NULL) {
1805 DEBUG(0, ("No rpc function table associated with context "
1806 "[%d]\n",
1807 pkt->u.request.context_id));
1808 data_blob_free(&p->out_data.rdata);
1809 TALLOC_FREE(frame);
1810 return false;
1811 }
1812
1813 interface_name = get_pipe_name_from_syntax(talloc_tos(),
1814 &pipe_fns->syntax);
1815
1816 SMB_ASSERT(interface_name != NULL);
1817
1818 DEBUG(5, ("Requested \\PIPE\\%s\n",
1819 interface_name));
1820
1821 switch (p->auth.auth_level) {
1822 case DCERPC_AUTH_LEVEL_NONE:
1823 case DCERPC_AUTH_LEVEL_INTEGRITY:
1824 case DCERPC_AUTH_LEVEL_PRIVACY:
1825 break;
1826 default:
1827 if (!pipe_fns->allow_connect) {
1828 DEBUG(1, ("%s: restrict auth_level_connect access "
1829 "to [%s] with auth[type=0x%x,level=0x%x] "
1830 "on [%s] from [%s]\n",
1831 __func__, interface_name,
1832 p->auth.auth_type,
1833 p->auth.auth_level,
1834 derpc_transport_string_by_transport(p->transport),
1835 p->client_id->name));
1836
1837 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1838 TALLOC_FREE(frame);
1839 return true;
1840 }
1841 break;
1842 }
1843
1844 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1845 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1846 set_incoming_fault(p);
1847 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1848 data_blob_free(&p->out_data.rdata);
1849 TALLOC_FREE(frame);
1850 return true;
1851 }
1852
1853 if (!become_authenticated_pipe_user(p->session_info)) {
1854 DEBUG(1, ("Failed to become pipe user!\n"));
1855 data_blob_free(&p->out_data.rdata);
1856 TALLOC_FREE(frame);
1857 return false;
1858 }
1859
1860 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1861 &pipe_fns->syntax);
1862 unbecome_authenticated_pipe_user();
1863
1864 TALLOC_FREE(frame);
1865 return ret;
1866}
1867
1868/*******************************************************************
1869 Calls the underlying RPC function for a named pipe.
1870 ********************************************************************/
1871
1872static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1873 const struct api_struct *api_rpc_cmds, int n_cmds,
1874 const struct ndr_syntax_id *syntax)
1875{
1876 int fn_num;
1877 uint32_t offset1;
1878
1879 /* interpret the command */
1880 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1881 get_pipe_name_from_syntax(talloc_tos(), syntax),
1882 pkt->u.request.opnum));
1883
1884 if (DEBUGLEVEL >= 50) {
1885 fstring name;
1886 slprintf(name, sizeof(name)-1, "in_%s",
1887 get_pipe_name_from_syntax(talloc_tos(), syntax));
1888 dump_pdu_region(name, pkt->u.request.opnum,
1889 &p->in_data.data, 0,
1890 p->in_data.data.length);
1891 }
1892
1893 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1894 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1895 api_rpc_cmds[fn_num].fn != NULL) {
1896 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1897 api_rpc_cmds[fn_num].name));
1898 break;
1899 }
1900 }
1901
1902 if (fn_num == n_cmds) {
1903 /*
1904 * For an unknown RPC just return a fault PDU but
1905 * return True to allow RPC's on the pipe to continue
1906 * and not put the pipe into fault state. JRA.
1907 */
1908 DEBUG(4, ("unknown\n"));
1909 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1910 return True;
1911 }
1912
1913 offset1 = p->out_data.rdata.length;
1914
1915 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1916 fn_num, api_rpc_cmds[fn_num].fn));
1917 /* do the actual command */
1918 if(!api_rpc_cmds[fn_num].fn(p)) {
1919 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1920 get_pipe_name_from_syntax(talloc_tos(), syntax),
1921 api_rpc_cmds[fn_num].name));
1922 data_blob_free(&p->out_data.rdata);
1923 return False;
1924 }
1925
1926 if (p->fault_state) {
1927 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1928 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1929 p->fault_state = 0;
1930 return true;
1931 }
1932
1933 if (DEBUGLEVEL >= 50) {
1934 fstring name;
1935 slprintf(name, sizeof(name)-1, "out_%s",
1936 get_pipe_name_from_syntax(talloc_tos(), syntax));
1937 dump_pdu_region(name, pkt->u.request.opnum,
1938 &p->out_data.rdata, offset1,
1939 p->out_data.rdata.length);
1940 }
1941
1942 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1943 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1944
1945 /* Check for buffer underflow in rpc parsing */
1946 if ((DEBUGLEVEL >= 10) &&
1947 (pkt->frag_length < p->in_data.data.length)) {
1948 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1949 dump_data(10, p->in_data.data.data + pkt->frag_length,
1950 p->in_data.data.length - pkt->frag_length);
1951 }
1952
1953 return True;
1954}
1955
1956/****************************************************************************
1957 Initialise an outgoing packet.
1958****************************************************************************/
1959
1960static bool pipe_init_outgoing_data(struct pipes_struct *p)
1961{
1962 output_data *o_data = &p->out_data;
1963
1964 /* Reset the offset counters. */
1965 o_data->data_sent_length = 0;
1966 o_data->current_pdu_sent = 0;
1967
1968 data_blob_free(&o_data->frag);
1969
1970 /* Free any memory in the current return data buffer. */
1971 data_blob_free(&o_data->rdata);
1972
1973 return True;
1974}
1975
1976/****************************************************************************
1977 Sets the fault state on incoming packets.
1978****************************************************************************/
1979
1980void set_incoming_fault(struct pipes_struct *p)
1981{
1982 data_blob_free(&p->in_data.data);
1983 p->in_data.pdu_needed_len = 0;
1984 p->in_data.pdu.length = 0;
1985 p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
1986
1987 p->allow_alter = false;
1988 p->allow_auth3 = false;
1989 p->pipe_bound = false;
1990
1991 DEBUG(10, ("Setting fault state\n"));
1992}
1993
1994static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1995 struct ncacn_packet *pkt,
1996 DATA_BLOB *raw_pkt)
1997{
1998 NTSTATUS status;
1999 size_t hdr_size = DCERPC_REQUEST_LENGTH;
2000
2001 DEBUG(10, ("Checking request auth.\n"));
2002
2003 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2004 hdr_size += 16;
2005 }
2006
2007 /* in case of sealing this function will unseal the data in place */
2008 status = dcerpc_check_auth(auth, pkt,
2009 &pkt->u.request.stub_and_verifier,
2010 hdr_size, raw_pkt);
2011 if (!NT_STATUS_IS_OK(status)) {
2012 return status;
2013 }
2014
2015 return NT_STATUS_OK;
2016}
2017
2018/****************************************************************************
2019 Processes a request pdu. This will do auth processing if needed, and
2020 appends the data into the complete stream if the LAST flag is not set.
2021****************************************************************************/
2022
2023static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
2024{
2025 NTSTATUS status;
2026 DATA_BLOB data;
2027
2028 if (!p->pipe_bound) {
2029 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
2030 set_incoming_fault(p);
2031 return False;
2032 }
2033
2034 /*
2035 * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
2036 * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
2037 */
2038 status = dcerpc_verify_ncacn_packet_header(pkt,
2039 DCERPC_PKT_REQUEST,
2040 pkt->u.request.stub_and_verifier.length,
2041 0, /* required_flags */
2042 DCERPC_PFC_FLAG_FIRST |
2043 DCERPC_PFC_FLAG_LAST |
2044 0x08 | /* this is not defined, but should be ignored */
2045 DCERPC_PFC_FLAG_CONC_MPX |
2046 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2047 DCERPC_PFC_FLAG_MAYBE |
2048 DCERPC_PFC_FLAG_OBJECT_UUID);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
2051 nt_errstr(status)));
2052 NDR_PRINT_DEBUG(ncacn_packet, pkt);
2053 set_incoming_fault(p);
2054 return false;
2055 }
2056
2057 /* Store the opnum */
2058 p->opnum = pkt->u.request.opnum;
2059
2060 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
2061 if (!NT_STATUS_IS_OK(status)) {
2062 DEBUG(0, ("Failed to check packet auth. (%s)\n",
2063 nt_errstr(status)));
2064 set_incoming_fault(p);
2065 return false;
2066 }
2067
2068 data = pkt->u.request.stub_and_verifier;
2069
2070 /*
2071 * Check the data length doesn't go over the 15Mb limit.
2072 * increased after observing a bug in the Windows NT 4.0 SP6a
2073 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
2074 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
2075 */
2076
2077 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
2078 DEBUG(0, ("process_request_pdu: "
2079 "rpc data buffer too large (%u) + (%u)\n",
2080 (unsigned int)p->in_data.data.length,
2081 (unsigned int)data.length));
2082 set_incoming_fault(p);
2083 return False;
2084 }
2085
2086 /*
2087 * Append the data portion into the buffer and return.
2088 */
2089
2090 if (data.length) {
2091 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
2092 data.data, data.length)) {
2093 DEBUG(0, ("Unable to append data size %u "
2094 "to parse buffer of size %u.\n",
2095 (unsigned int)data.length,
2096 (unsigned int)p->in_data.data.length));
2097 set_incoming_fault(p);
2098 return False;
2099 }
2100 }
2101
2102 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
2103 bool ret = False;
2104 /*
2105 * Ok - we finally have a complete RPC stream.
2106 * Call the rpc command to process it.
2107 */
2108
2109 /*
2110 * Process the complete data stream here.
2111 */
2112 if (pipe_init_outgoing_data(p)) {
2113 ret = api_pipe_request(p, pkt);
2114 }
2115
2116 return ret;
2117 }
2118
2119 return True;
2120}
2121
2122/****************************************************************************
2123 Processes a finished PDU stored in p->in_data.pdu.
2124****************************************************************************/
2125
2126void process_complete_pdu(struct pipes_struct *p)
2127{
2128 struct ncacn_packet *pkt = NULL;
2129 NTSTATUS status;
2130 bool reply = False;
2131
2132 if(p->fault_state) {
2133 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
2134 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
2135 goto done;
2136 }
2137
2138 pkt = talloc(p->mem_ctx, struct ncacn_packet);
2139 if (!pkt) {
2140 DEBUG(0, ("Out of memory!\n"));
2141 goto done;
2142 }
2143
2144 /*
2145 * Ensure we're using the corrent endianness for both the
2146 * RPC header flags and the raw data we will be reading from.
2147 */
2148 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
2149 p->endian = RPC_LITTLE_ENDIAN;
2150 } else {
2151 p->endian = RPC_BIG_ENDIAN;
2152 }
2153 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
2154
2155 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
2156 pkt, p->endian);
2157 if (!NT_STATUS_IS_OK(status)) {
2158 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
2159 nt_errstr(status)));
2160 goto done;
2161 }
2162
2163 /* Store the call_id */
2164 p->call_id = pkt->call_id;
2165
2166 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
2167
2168 switch (pkt->ptype) {
2169 case DCERPC_PKT_REQUEST:
2170 reply = process_request_pdu(p, pkt);
2171 break;
2172
2173 case DCERPC_PKT_PING: /* CL request - ignore... */
2174 DEBUG(0, ("process_complete_pdu: Error. "
2175 "Connectionless packet type %d received on "
2176 "pipe %s.\n", (int)pkt->ptype,
2177 get_pipe_name_from_syntax(talloc_tos(),
2178 &p->syntax)));
2179 break;
2180
2181 case DCERPC_PKT_RESPONSE: /* No responses here. */
2182 DEBUG(0, ("process_complete_pdu: Error. "
2183 "DCERPC_PKT_RESPONSE received from client "
2184 "on pipe %s.\n",
2185 get_pipe_name_from_syntax(talloc_tos(),
2186 &p->syntax)));
2187 break;
2188
2189 case DCERPC_PKT_FAULT:
2190 case DCERPC_PKT_WORKING:
2191 /* CL request - reply to a ping when a call in process. */
2192 case DCERPC_PKT_NOCALL:
2193 /* CL - server reply to a ping call. */
2194 case DCERPC_PKT_REJECT:
2195 case DCERPC_PKT_ACK:
2196 case DCERPC_PKT_CL_CANCEL:
2197 case DCERPC_PKT_FACK:
2198 case DCERPC_PKT_CANCEL_ACK:
2199 DEBUG(0, ("process_complete_pdu: Error. "
2200 "Connectionless packet type %u received on "
2201 "pipe %s.\n", (unsigned int)pkt->ptype,
2202 get_pipe_name_from_syntax(talloc_tos(),
2203 &p->syntax)));
2204 break;
2205
2206 case DCERPC_PKT_BIND:
2207 /*
2208 * We assume that a pipe bind is only in one pdu.
2209 */
2210 if (pipe_init_outgoing_data(p)) {
2211 reply = api_pipe_bind_req(p, pkt);
2212 }
2213 break;
2214
2215 case DCERPC_PKT_BIND_ACK:
2216 case DCERPC_PKT_BIND_NAK:
2217 DEBUG(0, ("process_complete_pdu: Error. "
2218 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
2219 "packet type %u received on pipe %s.\n",
2220 (unsigned int)pkt->ptype,
2221 get_pipe_name_from_syntax(talloc_tos(),
2222 &p->syntax)));
2223 break;
2224
2225
2226 case DCERPC_PKT_ALTER:
2227 /*
2228 * We assume that a pipe bind is only in one pdu.
2229 */
2230 if (pipe_init_outgoing_data(p)) {
2231 reply = api_pipe_alter_context(p, pkt);
2232 }
2233 break;
2234
2235 case DCERPC_PKT_ALTER_RESP:
2236 DEBUG(0, ("process_complete_pdu: Error. "
2237 "DCERPC_PKT_ALTER_RESP on pipe %s: "
2238 "Should only be server -> client.\n",
2239 get_pipe_name_from_syntax(talloc_tos(),
2240 &p->syntax)));
2241 break;
2242
2243 case DCERPC_PKT_AUTH3:
2244 /*
2245 * The third packet in an auth exchange.
2246 */
2247 if (pipe_init_outgoing_data(p)) {
2248 reply = api_pipe_bind_auth3(p, pkt);
2249 }
2250 break;
2251
2252 case DCERPC_PKT_SHUTDOWN:
2253 DEBUG(0, ("process_complete_pdu: Error. "
2254 "DCERPC_PKT_SHUTDOWN on pipe %s: "
2255 "Should only be server -> client.\n",
2256 get_pipe_name_from_syntax(talloc_tos(),
2257 &p->syntax)));
2258 break;
2259
2260 case DCERPC_PKT_CO_CANCEL:
2261 /* For now just free all client data and continue
2262 * processing. */
2263 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
2264 " Abandoning rpc call.\n"));
2265 /* As we never do asynchronous RPC serving, we can
2266 * never cancel a call (as far as I know).
2267 * If we ever did we'd have to send a cancel_ack reply.
2268 * For now, just free all client data and continue
2269 * processing. */
2270 reply = True;
2271 break;
2272
2273#if 0
2274 /* Enable this if we're doing async rpc. */
2275 /* We must check the outstanding callid matches. */
2276 if (pipe_init_outgoing_data(p)) {
2277 /* Send a cancel_ack PDU reply. */
2278 /* We should probably check the auth-verifier here. */
2279 reply = setup_cancel_ack_reply(p, pkt);
2280 }
2281 break;
2282#endif
2283
2284 case DCERPC_PKT_ORPHANED:
2285 /* We should probably check the auth-verifier here.
2286 * For now just free all client data and continue
2287 * processing. */
2288 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2289 " Abandoning rpc call.\n"));
2290 reply = True;
2291 break;
2292
2293 default:
2294 DEBUG(0, ("process_complete_pdu: "
2295 "Unknown rpc type = %u received.\n",
2296 (unsigned int)pkt->ptype));
2297 break;
2298 }
2299
2300done:
2301 if (!reply) {
2302 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2303 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2304 &p->syntax)));
2305 set_incoming_fault(p);
2306 setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR));
2307 TALLOC_FREE(pkt);
2308 } else {
2309 /*
2310 * Reset the lengths. We're ready for a new pdu.
2311 */
2312 TALLOC_FREE(p->in_data.pdu.data);
2313 p->in_data.pdu_needed_len = 0;
2314 p->in_data.pdu.length = 0;
2315 }
2316
2317 TALLOC_FREE(pkt);
2318}
2319
Note: See TracBrowser for help on using the repository browser.