Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : server side dcerpc authentication code
5 :
6 : Copyright (C) Andrew Tridgell 2003
7 : Copyright (C) Stefan (metze) Metzmacher 2004
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "librpc/rpc/dcesrv_core.h"
25 : #include "librpc/rpc/dcesrv_core_proto.h"
26 : #include "librpc/rpc/dcerpc_util.h"
27 : #include "librpc/rpc/dcerpc_pkt_auth.h"
28 : #include "librpc/gen_ndr/ndr_dcerpc.h"
29 : #include "auth/credentials/credentials.h"
30 : #include "auth/gensec/gensec.h"
31 : #include "auth/auth.h"
32 : #include "param/param.h"
33 :
34 32235 : static NTSTATUS dcesrv_auth_negotiate_hdr_signing(struct dcesrv_call_state *call,
35 : struct ncacn_packet *pkt)
36 : {
37 32235 : struct dcesrv_connection *dce_conn = call->conn;
38 32235 : struct dcesrv_auth *a = NULL;
39 :
40 32235 : if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) {
41 24999 : return NT_STATUS_OK;
42 : }
43 :
44 7236 : if (dce_conn->client_hdr_signing) {
45 0 : if (dce_conn->negotiated_hdr_signing && pkt != NULL) {
46 0 : pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
47 : }
48 0 : return NT_STATUS_OK;
49 : }
50 :
51 7236 : dce_conn->client_hdr_signing = true;
52 7236 : dce_conn->negotiated_hdr_signing = dce_conn->support_hdr_signing;
53 :
54 7236 : if (!dce_conn->negotiated_hdr_signing) {
55 506 : return NT_STATUS_OK;
56 : }
57 :
58 6730 : if (pkt != NULL) {
59 6730 : pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
60 : }
61 :
62 6730 : a = call->conn->default_auth_state;
63 6730 : if (a->gensec_security != NULL) {
64 0 : gensec_want_feature(a->gensec_security,
65 : GENSEC_FEATURE_SIGN_PKT_HEADER);
66 : }
67 :
68 13458 : for (a = call->conn->auth_states; a != NULL; a = a->next) {
69 6728 : if (a->gensec_security == NULL) {
70 0 : continue;
71 : }
72 :
73 6728 : gensec_want_feature(a->gensec_security,
74 : GENSEC_FEATURE_SIGN_PKT_HEADER);
75 : }
76 :
77 6730 : return NT_STATUS_OK;
78 : }
79 :
80 7790 : static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call)
81 : {
82 7790 : struct dcesrv_connection *dce_conn = call->conn;
83 7790 : struct dcesrv_auth *auth = call->auth_state;
84 7790 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
85 : NTSTATUS status;
86 :
87 7790 : if (auth->auth_started) {
88 0 : return false;
89 : }
90 :
91 7790 : auth->auth_started = true;
92 :
93 7790 : if (auth->auth_invalid) {
94 0 : return false;
95 : }
96 :
97 7790 : if (auth->auth_finished) {
98 0 : return false;
99 : }
100 :
101 7790 : if (auth->gensec_security != NULL) {
102 0 : return false;
103 : }
104 :
105 7790 : switch (call->in_auth_info.auth_level) {
106 7358 : case DCERPC_AUTH_LEVEL_CONNECT:
107 : case DCERPC_AUTH_LEVEL_CALL:
108 : case DCERPC_AUTH_LEVEL_PACKET:
109 : case DCERPC_AUTH_LEVEL_INTEGRITY:
110 : case DCERPC_AUTH_LEVEL_PRIVACY:
111 : /*
112 : * We evaluate auth_type only if auth_level was valid
113 : */
114 7358 : break;
115 8 : default:
116 : /*
117 : * Setting DCERPC_AUTH_LEVEL_NONE,
118 : * gives the caller the reject_reason
119 : * as auth_context_id.
120 : *
121 : * Note: DCERPC_AUTH_LEVEL_NONE == 1
122 : */
123 8 : auth->auth_type = DCERPC_AUTH_TYPE_NONE;
124 8 : auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
125 8 : auth->auth_context_id = DCERPC_BIND_NAK_REASON_NOT_SPECIFIED;
126 8 : return false;
127 : }
128 :
129 7782 : auth->auth_type = call->in_auth_info.auth_type;
130 7782 : auth->auth_level = call->in_auth_info.auth_level;
131 7782 : auth->auth_context_id = call->in_auth_info.auth_context_id;
132 :
133 7782 : status = cb->auth.gensec_prepare(
134 : auth,
135 : call,
136 : &auth->gensec_security,
137 : cb->auth.private_data);
138 7782 : if (!NT_STATUS_IS_OK(status)) {
139 0 : DEBUG(1, ("Failed to call samba_server_gensec_start %s\n",
140 : nt_errstr(status)));
141 0 : return false;
142 : }
143 :
144 : /*
145 : * We have to call this because we set the target_service for
146 : * Kerberos to NULL above, and in any case we wish to log a
147 : * more specific service target.
148 : *
149 : */
150 7782 : status = gensec_set_target_service_description(auth->gensec_security,
151 : "DCE/RPC");
152 7782 : if (!NT_STATUS_IS_OK(status)) {
153 0 : DEBUG(1, ("Failed to call gensec_set_target_service_description %s\n",
154 : nt_errstr(status)));
155 0 : return false;
156 : }
157 :
158 7782 : if (call->conn->remote_address != NULL) {
159 7782 : status = gensec_set_remote_address(auth->gensec_security,
160 7358 : call->conn->remote_address);
161 7782 : if (!NT_STATUS_IS_OK(status)) {
162 0 : DEBUG(1, ("Failed to call gensec_set_remote_address() %s\n",
163 : nt_errstr(status)));
164 0 : return false;
165 : }
166 : }
167 :
168 7782 : if (call->conn->local_address != NULL) {
169 7782 : status = gensec_set_local_address(auth->gensec_security,
170 7358 : call->conn->local_address);
171 7782 : if (!NT_STATUS_IS_OK(status)) {
172 0 : DEBUG(1, ("Failed to call gensec_set_local_address() %s\n",
173 : nt_errstr(status)));
174 0 : return false;
175 : }
176 : }
177 :
178 7782 : status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_type,
179 7782 : auth->auth_level);
180 7782 : if (!NT_STATUS_IS_OK(status)) {
181 7 : const char *backend_name =
182 7 : gensec_get_name_by_authtype(auth->gensec_security,
183 7 : auth->auth_type);
184 :
185 7 : DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: "
186 : "auth_type=%d (%s), auth_level=%d: %s\n",
187 : (int)auth->auth_type, backend_name,
188 : (int)auth->auth_level,
189 : nt_errstr(status)));
190 :
191 : /*
192 : * Setting DCERPC_AUTH_LEVEL_NONE,
193 : * gives the caller the reject_reason
194 : * as auth_context_id.
195 : *
196 : * Note: DCERPC_AUTH_LEVEL_NONE == 1
197 : */
198 7 : auth->auth_type = DCERPC_AUTH_TYPE_NONE;
199 7 : auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
200 7 : if (backend_name != NULL) {
201 1 : auth->auth_context_id =
202 : DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM;
203 : } else {
204 6 : auth->auth_context_id =
205 : DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE;
206 : }
207 7 : return false;
208 : }
209 :
210 7775 : if (dce_conn->negotiated_hdr_signing) {
211 0 : gensec_want_feature(auth->gensec_security,
212 : GENSEC_FEATURE_SIGN_PKT_HEADER);
213 : }
214 :
215 7351 : return true;
216 : }
217 :
218 27121 : static void dcesrv_default_auth_state_finish_bind(struct dcesrv_call_state *call)
219 : {
220 27121 : SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_BIND);
221 :
222 27121 : if (call->auth_state == call->conn->default_auth_state) {
223 19516 : return;
224 : }
225 :
226 7173 : if (call->conn->default_auth_state->auth_started) {
227 0 : return;
228 : }
229 :
230 7173 : if (call->conn->default_auth_state->auth_invalid) {
231 0 : return;
232 : }
233 :
234 7173 : call->conn->default_auth_state->auth_type = DCERPC_AUTH_TYPE_NONE;
235 7173 : call->conn->default_auth_state->auth_level = DCERPC_AUTH_LEVEL_NONE;
236 7173 : call->conn->default_auth_state->auth_context_id = 0;
237 7173 : call->conn->default_auth_state->auth_started = true;
238 7173 : call->conn->default_auth_state->auth_finished = true;
239 :
240 : /*
241 : *
242 : * We defer log_successful_dcesrv_authz_event()
243 : * to dcesrv_default_auth_state_prepare_request()
244 : *
245 : * As we don't want to trigger authz_events
246 : * just for alter_context requests without authentication
247 : */
248 : }
249 :
250 380964 : void dcesrv_default_auth_state_prepare_request(struct dcesrv_call_state *call)
251 : {
252 380964 : struct dcesrv_connection *dce_conn = call->conn;
253 380964 : struct dcesrv_auth *auth = call->auth_state;
254 380964 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
255 :
256 380964 : if (auth->auth_audited) {
257 289188 : return;
258 : }
259 :
260 88342 : if (call->pkt.ptype != DCERPC_PKT_REQUEST) {
261 0 : return;
262 : }
263 :
264 88342 : if (auth != dce_conn->default_auth_state) {
265 84617 : return;
266 : }
267 :
268 572 : if (auth->auth_invalid) {
269 0 : return;
270 : }
271 :
272 572 : if (!auth->auth_finished) {
273 0 : return;
274 : }
275 :
276 572 : if (cb->log.successful_authz == NULL) {
277 0 : return;
278 : }
279 :
280 572 : cb->log.successful_authz(call, cb->log.private_data);
281 : }
282 :
283 : /*
284 : parse any auth information from a dcerpc bind request
285 : return false if we can't handle the auth request for some
286 : reason (in which case we send a bind_nak)
287 : */
288 27136 : bool dcesrv_auth_bind(struct dcesrv_call_state *call)
289 : {
290 27136 : struct ncacn_packet *pkt = &call->pkt;
291 27136 : struct dcesrv_auth *auth = call->auth_state;
292 27136 : struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
293 : NTSTATUS status;
294 :
295 27136 : if (pkt->auth_length == 0) {
296 19380 : auth->auth_type = DCERPC_AUTH_TYPE_NONE;
297 19380 : auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
298 19380 : auth->auth_context_id = 0;
299 19380 : auth->auth_started = true;
300 :
301 19380 : if (cb->log.successful_authz != NULL) {
302 19380 : cb->log.successful_authz(call, cb->log.private_data);
303 : }
304 :
305 18948 : return true;
306 : }
307 :
308 7756 : status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info,
309 : &call->in_auth_info,
310 : NULL, true);
311 7756 : if (!NT_STATUS_IS_OK(status)) {
312 : /*
313 : * Setting DCERPC_AUTH_LEVEL_NONE,
314 : * gives the caller the reject_reason
315 : * as auth_context_id.
316 : *
317 : * Note: DCERPC_AUTH_LEVEL_NONE == 1
318 : */
319 1 : auth->auth_type = DCERPC_AUTH_TYPE_NONE;
320 1 : auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
321 1 : auth->auth_context_id =
322 : DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED;
323 1 : return false;
324 : }
325 :
326 7755 : return dcesrv_auth_prepare_gensec(call);
327 : }
328 :
329 12883 : NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status)
330 : {
331 12883 : struct dcesrv_auth *auth = call->auth_state;
332 12883 : const char *pdu = "<unknown>";
333 :
334 12883 : switch (call->pkt.ptype) {
335 7317 : case DCERPC_PKT_BIND:
336 7317 : pdu = "BIND";
337 7317 : break;
338 4987 : case DCERPC_PKT_ALTER:
339 4987 : pdu = "ALTER";
340 4987 : break;
341 155 : case DCERPC_PKT_AUTH3:
342 155 : pdu = "AUTH3";
343 155 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
344 0 : DEBUG(4, ("GENSEC not finished at at %s\n", pdu));
345 0 : return NT_STATUS_RPC_SEC_PKG_ERROR;
346 : }
347 155 : break;
348 0 : default:
349 0 : return NT_STATUS_INTERNAL_ERROR;
350 : }
351 :
352 12883 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
353 5117 : return NT_STATUS_OK;
354 : }
355 :
356 7766 : if (!NT_STATUS_IS_OK(status)) {
357 15 : DEBUG(4, ("GENSEC mech rejected the incoming authentication "
358 : "at %s: %s\n", pdu, nt_errstr(status)));
359 15 : return status;
360 : }
361 :
362 7751 : status = gensec_session_info(auth->gensec_security,
363 : auth,
364 : &auth->session_info);
365 7751 : if (!NT_STATUS_IS_OK(status)) {
366 0 : DEBUG(1, ("Failed to establish session_info: %s\n",
367 : nt_errstr(status)));
368 0 : return status;
369 : }
370 7751 : auth->auth_finished = true;
371 :
372 8054 : if (auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT &&
373 501 : !call->conn->got_explicit_auth_level_connect)
374 : {
375 495 : call->conn->default_auth_level_connect = auth;
376 : }
377 :
378 7751 : if (call->pkt.ptype != DCERPC_PKT_AUTH3) {
379 7596 : return NT_STATUS_OK;
380 : }
381 :
382 155 : if (call->out_auth_info->credentials.length != 0) {
383 1 : DEBUG(4, ("GENSEC produced output token (len=%zu) at %s\n",
384 : call->out_auth_info->credentials.length, pdu));
385 1 : return NT_STATUS_RPC_SEC_PKG_ERROR;
386 : }
387 :
388 154 : return NT_STATUS_OK;
389 : }
390 :
391 : /*
392 : add any auth information needed in a bind ack, and process the authentication
393 : information found in the bind.
394 : */
395 27121 : NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
396 : {
397 27121 : struct dcesrv_connection *dce_conn = call->conn;
398 27121 : struct dcesrv_auth *auth = call->auth_state;
399 : NTSTATUS status;
400 :
401 27121 : status = dcesrv_auth_negotiate_hdr_signing(call, pkt);
402 27121 : if (!NT_STATUS_IS_OK(status)) {
403 0 : return status;
404 : }
405 :
406 27121 : dce_conn->allow_alter = true;
407 27121 : dcesrv_default_auth_state_finish_bind(call);
408 :
409 27121 : if (call->pkt.auth_length == 0) {
410 19380 : auth->auth_finished = true;
411 19380 : return NT_STATUS_OK;
412 : }
413 :
414 : /* We can't work without an existing gensec state */
415 7741 : if (auth->gensec_security == NULL) {
416 0 : return NT_STATUS_INTERNAL_ERROR;
417 : }
418 :
419 7741 : call->_out_auth_info = (struct dcerpc_auth) {
420 7741 : .auth_type = auth->auth_type,
421 7741 : .auth_level = auth->auth_level,
422 7741 : .auth_context_id = auth->auth_context_id,
423 : };
424 7741 : call->out_auth_info = &call->_out_auth_info;
425 :
426 7741 : return NT_STATUS_OK;
427 : }
428 :
429 : /*
430 : process the final stage of a auth request
431 : */
432 156 : bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
433 : {
434 156 : struct ncacn_packet *pkt = &call->pkt;
435 156 : struct dcesrv_auth *auth = call->auth_state;
436 : NTSTATUS status;
437 :
438 156 : if (pkt->auth_length == 0) {
439 0 : return false;
440 : }
441 :
442 156 : if (auth->auth_finished) {
443 0 : return false;
444 : }
445 :
446 : /* We can't work without an existing gensec state */
447 156 : if (auth->gensec_security == NULL) {
448 0 : return false;
449 : }
450 :
451 156 : status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info,
452 : &call->in_auth_info, NULL, true);
453 156 : if (!NT_STATUS_IS_OK(status)) {
454 : /*
455 : * Windows returns DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY
456 : * instead of DCERPC_NCA_S_PROTO_ERROR.
457 : */
458 1 : call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
459 1 : return false;
460 : }
461 :
462 155 : if (call->in_auth_info.auth_type != auth->auth_type) {
463 0 : return false;
464 : }
465 :
466 155 : if (call->in_auth_info.auth_level != auth->auth_level) {
467 0 : return false;
468 : }
469 :
470 155 : if (call->in_auth_info.auth_context_id != auth->auth_context_id) {
471 0 : return false;
472 : }
473 :
474 155 : call->_out_auth_info = (struct dcerpc_auth) {
475 155 : .auth_type = auth->auth_type,
476 155 : .auth_level = auth->auth_level,
477 155 : .auth_context_id = auth->auth_context_id,
478 : };
479 155 : call->out_auth_info = &call->_out_auth_info;
480 :
481 155 : return true;
482 : }
483 :
484 : /*
485 : parse any auth information from a dcerpc alter request
486 : return false if we can't handle the auth request for some
487 : reason (in which case we send a bind_nak (is this true for here?))
488 : */
489 5137 : bool dcesrv_auth_alter(struct dcesrv_call_state *call)
490 : {
491 5137 : struct ncacn_packet *pkt = &call->pkt;
492 5137 : struct dcesrv_auth *auth = call->auth_state;
493 : NTSTATUS status;
494 :
495 : /* on a pure interface change there is no auth blob */
496 5137 : if (pkt->auth_length == 0) {
497 144 : if (!auth->auth_finished) {
498 0 : return false;
499 : }
500 144 : return true;
501 : }
502 :
503 4993 : if (auth->auth_finished) {
504 1 : call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
505 1 : return false;
506 : }
507 :
508 4992 : status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info,
509 : &call->in_auth_info, NULL, true);
510 4992 : if (!NT_STATUS_IS_OK(status)) {
511 1 : call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
512 1 : return false;
513 : }
514 :
515 4991 : if (!auth->auth_started) {
516 : bool ok;
517 :
518 35 : ok = dcesrv_auth_prepare_gensec(call);
519 35 : if (!ok) {
520 1 : call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
521 1 : return false;
522 : }
523 :
524 34 : return true;
525 : }
526 :
527 4956 : if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) {
528 0 : call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
529 0 : return false;
530 : }
531 :
532 4956 : if (call->in_auth_info.auth_type != auth->auth_type) {
533 0 : return false;
534 : }
535 :
536 4956 : if (call->in_auth_info.auth_level != auth->auth_level) {
537 3 : return false;
538 : }
539 :
540 4953 : if (call->in_auth_info.auth_context_id != auth->auth_context_id) {
541 0 : return false;
542 : }
543 :
544 4953 : return true;
545 : }
546 :
547 : /*
548 : add any auth information needed in a alter ack, and process the authentication
549 : information found in the alter.
550 : */
551 5114 : NTSTATUS dcesrv_auth_prepare_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
552 : {
553 5114 : struct dcesrv_auth *auth = call->auth_state;
554 : NTSTATUS status;
555 :
556 5114 : status = dcesrv_auth_negotiate_hdr_signing(call, pkt);
557 5114 : if (!NT_STATUS_IS_OK(status)) {
558 0 : return status;
559 : }
560 :
561 : /* on a pure interface change there is no auth_info structure
562 : setup */
563 5114 : if (call->pkt.auth_length == 0) {
564 127 : return NT_STATUS_OK;
565 : }
566 :
567 4987 : if (auth->gensec_security == NULL) {
568 0 : return NT_STATUS_INTERNAL_ERROR;
569 : }
570 :
571 4987 : call->_out_auth_info = (struct dcerpc_auth) {
572 4987 : .auth_type = auth->auth_type,
573 4987 : .auth_level = auth->auth_level,
574 4987 : .auth_context_id = auth->auth_context_id,
575 : };
576 4987 : call->out_auth_info = &call->_out_auth_info;
577 :
578 4987 : return NT_STATUS_OK;
579 : }
580 :
581 : /*
582 : check credentials on a packet
583 : */
584 380940 : bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call,
585 : DATA_BLOB *full_packet,
586 : uint8_t required_flags,
587 : uint8_t optional_flags,
588 : uint8_t payload_offset,
589 : DATA_BLOB *payload_and_verifier)
590 : {
591 380940 : struct ncacn_packet *pkt = &call->pkt;
592 380940 : struct dcesrv_auth *auth = call->auth_state;
593 1324497 : const struct dcerpc_auth tmp_auth = {
594 380940 : .auth_type = auth->auth_type,
595 380940 : .auth_level = auth->auth_level,
596 380940 : .auth_context_id = auth->auth_context_id,
597 : };
598 : NTSTATUS status;
599 :
600 380940 : if (!auth->auth_started) {
601 8 : return false;
602 : }
603 :
604 380932 : if (!auth->auth_finished) {
605 0 : call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
606 0 : return false;
607 : }
608 :
609 380932 : if (auth->auth_invalid) {
610 13 : return false;
611 : }
612 :
613 380916 : status = dcerpc_ncacn_pull_pkt_auth(&tmp_auth,
614 : auth->gensec_security,
615 : call,
616 : pkt->ptype,
617 : required_flags,
618 : optional_flags,
619 : payload_offset,
620 : payload_and_verifier,
621 : full_packet,
622 : pkt);
623 380916 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
624 0 : call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
625 0 : return false;
626 : }
627 380916 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL)) {
628 0 : call->fault_code = DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL;
629 0 : return false;
630 : }
631 380916 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
632 6 : call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
633 6 : return false;
634 : }
635 380910 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
636 0 : call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
637 0 : return false;
638 : }
639 380910 : if (!NT_STATUS_IS_OK(status)) {
640 0 : return false;
641 : }
642 :
643 380910 : return true;
644 : }
645 :
646 : /*
647 : push a signed or sealed dcerpc request packet into a blob
648 : */
649 572498 : bool dcesrv_auth_pkt_push(struct dcesrv_call_state *call,
650 : DATA_BLOB *blob, size_t sig_size,
651 : uint8_t payload_offset,
652 : const DATA_BLOB *payload,
653 : const struct ncacn_packet *pkt)
654 : {
655 572498 : struct dcesrv_auth *auth = call->auth_state;
656 2064749 : const struct dcerpc_auth tmp_auth = {
657 572498 : .auth_type = auth->auth_type,
658 572498 : .auth_level = auth->auth_level,
659 572498 : .auth_context_id = auth->auth_context_id,
660 : };
661 : NTSTATUS status;
662 :
663 572498 : status = dcerpc_ncacn_push_pkt_auth(&tmp_auth,
664 : auth->gensec_security,
665 : call, blob, sig_size,
666 : payload_offset,
667 : payload,
668 : pkt);
669 572498 : return NT_STATUS_IS_OK(status);
670 : }
|