Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : netlogon schannel utility functions
5 :
6 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7 : Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
8 : Copyright (C) Matthias Dieter Wallnöfer 2009-2010
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "schannel_util.h"
26 : #include "param/param.h"
27 : #include "libcli/security/dom_sid.h"
28 : #include "libcli/auth/schannel.h"
29 : #include "librpc/rpc/dcesrv_core.h"
30 : #include "librpc/gen_ndr/ndr_netlogon.h"
31 : #include "lib/util/util_str_escape.h"
32 :
33 : struct dcesrv_netr_check_schannel_state {
34 : struct dom_sid account_sid;
35 : enum dcerpc_AuthType auth_type;
36 : enum dcerpc_AuthLevel auth_level;
37 :
38 : bool schannel_global_required;
39 : bool schannel_required;
40 : bool schannel_explicitly_set;
41 :
42 : bool seal_global_required;
43 : bool seal_required;
44 : bool seal_explicitly_set;
45 :
46 : NTSTATUS result;
47 : };
48 :
49 17950 : static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *dce_call,
50 : const struct netlogon_creds_CredentialState *creds,
51 : enum dcerpc_AuthType auth_type,
52 : enum dcerpc_AuthLevel auth_level,
53 : struct dcesrv_netr_check_schannel_state **_s)
54 : {
55 17950 : struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
56 17950 : int schannel = lpcfg_server_schannel(lp_ctx);
57 17950 : bool schannel_global_required = (schannel == true);
58 17950 : bool schannel_required = schannel_global_required;
59 17950 : const char *explicit_opt = NULL;
60 17950 : bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
61 17950 : bool require_seal = global_require_seal;
62 17950 : const char *explicit_seal_opt = NULL;
63 : #define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
64 17950 : struct dcesrv_netr_check_schannel_state *s = NULL;
65 1453 : NTSTATUS status;
66 :
67 17950 : *_s = NULL;
68 :
69 17950 : s = dcesrv_iface_state_find_conn(dce_call,
70 : DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
71 : struct dcesrv_netr_check_schannel_state);
72 17950 : if (s != NULL) {
73 16188 : if (!dom_sid_equal(&s->account_sid, creds->sid)) {
74 0 : goto new_state;
75 : }
76 16188 : if (s->auth_type != auth_type) {
77 0 : goto new_state;
78 : }
79 16188 : if (s->auth_level != auth_level) {
80 0 : goto new_state;
81 : }
82 :
83 16188 : *_s = s;
84 16188 : return NT_STATUS_OK;
85 : }
86 :
87 1762 : new_state:
88 1762 : TALLOC_FREE(s);
89 1762 : s = talloc_zero(dce_call,
90 : struct dcesrv_netr_check_schannel_state);
91 1762 : if (s == NULL) {
92 0 : return NT_STATUS_NO_MEMORY;
93 : }
94 :
95 1762 : s->account_sid = *creds->sid;
96 1762 : s->auth_type = auth_type;
97 1762 : s->auth_level = auth_level;
98 1762 : s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
99 :
100 : /*
101 : * We don't use lpcfg_parm_bool(), as we
102 : * need the explicit_opt pointer in order to
103 : * adjust the debug messages.
104 : */
105 1941 : explicit_seal_opt = lpcfg_get_parametric(lp_ctx,
106 : NULL,
107 : "server schannel require seal",
108 1762 : creds->account_name);
109 1762 : if (explicit_seal_opt != NULL) {
110 1097 : require_seal = lp_bool(explicit_seal_opt);
111 : }
112 :
113 : /*
114 : * We don't use lpcfg_parm_bool(), as we
115 : * need the explicit_opt pointer in order to
116 : * adjust the debug messages.
117 : */
118 1941 : explicit_opt = lpcfg_get_parametric(lp_ctx,
119 : NULL,
120 : "server require schannel",
121 1762 : creds->account_name);
122 1762 : if (explicit_opt != NULL) {
123 1097 : schannel_required = lp_bool(explicit_opt);
124 : }
125 :
126 1762 : s->schannel_global_required = schannel_global_required;
127 1762 : s->schannel_required = schannel_required;
128 1762 : s->schannel_explicitly_set = explicit_opt != NULL;
129 :
130 1762 : s->seal_global_required = global_require_seal;
131 1762 : s->seal_required = require_seal;
132 1762 : s->seal_explicitly_set = explicit_seal_opt != NULL;
133 :
134 1762 : status = dcesrv_iface_state_store_conn(dce_call,
135 : DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
136 : s);
137 1762 : if (!NT_STATUS_IS_OK(status)) {
138 0 : return status;
139 : }
140 :
141 1762 : *_s = s;
142 1762 : return NT_STATUS_OK;
143 : }
144 :
145 17950 : static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_call,
146 : struct dcesrv_netr_check_schannel_state *s,
147 : const struct netlogon_creds_CredentialState *creds,
148 : uint16_t opnum)
149 : {
150 17950 : struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
151 17950 : int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
152 : "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
153 17950 : int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
154 : "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
155 17950 : int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
156 : "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
157 17950 : int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
158 : "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
159 17950 : TALLOC_CTX *frame = talloc_stackframe();
160 17950 : unsigned int dbg_lvl = DBGLVL_DEBUG;
161 17950 : const char *opname = "<unknown>";
162 17950 : const char *reason = "<unknown>";
163 :
164 17950 : if (opnum < ndr_table_netlogon.num_calls) {
165 17950 : opname = ndr_table_netlogon.calls[opnum].name;
166 : }
167 :
168 17950 : if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
169 16072 : if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
170 12464 : reason = "WITH SEALED";
171 2990 : } else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
172 2470 : reason = "WITH SIGNED";
173 : } else {
174 0 : reason = "WITH INVALID";
175 0 : dbg_lvl = DBGLVL_ERR;
176 0 : s->result = NT_STATUS_INTERNAL_ERROR;
177 : }
178 : } else {
179 1563 : reason = "WITHOUT";
180 : }
181 :
182 17950 : if (!NT_STATUS_EQUAL(s->result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
183 16188 : if (!NT_STATUS_IS_OK(s->result)) {
184 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
185 : }
186 :
187 16188 : DEBUG(dbg_lvl, (
188 : "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
189 : "%s request (opnum[%u]) %s schannel from "
190 : "client_account[%s] client_computer_name[%s] %s\n",
191 : opname, opnum, reason,
192 : log_escape(frame, creds->account_name),
193 : log_escape(frame, creds->computer_name),
194 : nt_errstr(s->result)));
195 16188 : TALLOC_FREE(frame);
196 16188 : return s->result;
197 : }
198 :
199 1762 : if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
200 1447 : s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
201 : {
202 1125 : s->result = NT_STATUS_OK;
203 :
204 1125 : if (s->schannel_explicitly_set && !s->schannel_required) {
205 460 : dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
206 665 : } else if (!s->schannel_required) {
207 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
208 : }
209 1125 : if (s->seal_explicitly_set && !s->seal_required) {
210 460 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
211 665 : } else if (!s->seal_required) {
212 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
213 : }
214 :
215 1125 : DEBUG(dbg_lvl, (
216 : "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
217 : "%s request (opnum[%u]) %s schannel from "
218 : "client_account[%s] client_computer_name[%s] %s\n",
219 : opname, opnum, reason,
220 : log_escape(frame, creds->account_name),
221 : log_escape(frame, creds->computer_name),
222 : nt_errstr(s->result)));
223 :
224 1125 : if (s->schannel_explicitly_set && !s->schannel_required) {
225 460 : DEBUG(CVE_2020_1472_warn_level, (
226 : "CVE-2020-1472(ZeroLogon): "
227 : "Option 'server require schannel:%s = no' not needed for '%s'!\n",
228 : log_escape(frame, creds->account_name),
229 : log_escape(frame, creds->computer_name)));
230 : }
231 :
232 1125 : if (s->seal_explicitly_set && !s->seal_required) {
233 460 : DEBUG(CVE_2022_38023_warn_level, (
234 : "CVE-2022-38023: "
235 : "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
236 : log_escape(frame, creds->account_name),
237 : log_escape(frame, creds->computer_name)));
238 : }
239 :
240 1125 : TALLOC_FREE(frame);
241 1125 : return s->result;
242 : }
243 :
244 637 : if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
245 322 : if (s->seal_required) {
246 0 : s->result = NT_STATUS_ACCESS_DENIED;
247 :
248 0 : if (s->seal_explicitly_set) {
249 0 : dbg_lvl = DBGLVL_NOTICE;
250 : } else {
251 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
252 : }
253 0 : if (s->schannel_explicitly_set && !s->schannel_required) {
254 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
255 : }
256 :
257 0 : DEBUG(dbg_lvl, (
258 : "CVE-2022-38023: "
259 : "%s request (opnum[%u]) %s schannel from "
260 : "from client_account[%s] client_computer_name[%s] %s\n",
261 : opname, opnum, reason,
262 : log_escape(frame, creds->account_name),
263 : log_escape(frame, creds->computer_name),
264 : nt_errstr(s->result)));
265 0 : if (s->seal_explicitly_set) {
266 0 : D_NOTICE("CVE-2022-38023: Option "
267 : "'server schannel require seal:%s = yes' "
268 : "rejects access for client.\n",
269 : log_escape(frame, creds->account_name));
270 : } else {
271 0 : DEBUG(CVE_2020_1472_error_level, (
272 : "CVE-2022-38023: Check if option "
273 : "'server schannel require seal:%s = no' "
274 : "might be needed for a legacy client.\n",
275 : log_escape(frame, creds->account_name)));
276 : }
277 0 : if (s->schannel_explicitly_set && !s->schannel_required) {
278 0 : DEBUG(CVE_2020_1472_warn_level, (
279 : "CVE-2020-1472(ZeroLogon): Option "
280 : "'server require schannel:%s = no' "
281 : "not needed for '%s'!\n",
282 : log_escape(frame, creds->account_name),
283 : log_escape(frame, creds->computer_name)));
284 : }
285 0 : TALLOC_FREE(frame);
286 0 : return s->result;
287 : }
288 :
289 322 : s->result = NT_STATUS_OK;
290 :
291 322 : if (s->schannel_explicitly_set && !s->schannel_required) {
292 322 : dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
293 0 : } else if (!s->schannel_required) {
294 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
295 : }
296 322 : if (s->seal_explicitly_set && !s->seal_required) {
297 322 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
298 0 : } else if (!s->seal_required) {
299 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
300 : }
301 :
302 322 : DEBUG(dbg_lvl, (
303 : "CVE-2020-1472(ZeroLogon): "
304 : "%s request (opnum[%u]) %s schannel from "
305 : "client_account[%s] client_computer_name[%s] %s\n",
306 : opname, opnum, reason,
307 : log_escape(frame, creds->account_name),
308 : log_escape(frame, creds->computer_name),
309 : nt_errstr(s->result)));
310 322 : if (s->schannel_explicitly_set && !s->schannel_required) {
311 322 : DEBUG(CVE_2020_1472_warn_level, (
312 : "CVE-2020-1472(ZeroLogon): "
313 : "Option 'server require schannel:%s = no' not needed for '%s'!\n",
314 : log_escape(frame, creds->account_name),
315 : log_escape(frame, creds->computer_name)));
316 : }
317 322 : if (s->seal_explicitly_set && !s->seal_required) {
318 322 : D_INFO("CVE-2022-38023: "
319 : "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
320 : log_escape(frame, creds->account_name),
321 : log_escape(frame, creds->computer_name));
322 0 : } else if (!s->seal_required) {
323 : /*
324 : * admins should set
325 : * server schannel require seal:COMPUTER$ = no
326 : * in order to avoid the level 0 messages.
327 : * Over time they can switch the global value
328 : * to be strict.
329 : */
330 0 : DEBUG(CVE_2022_38023_error_level, (
331 : "CVE-2022-38023: "
332 : "Please use 'server schannel require seal:%s = no' "
333 : "for '%s' to avoid this warning!\n",
334 : log_escape(frame, creds->account_name),
335 : log_escape(frame, creds->computer_name)));
336 : }
337 :
338 322 : TALLOC_FREE(frame);
339 322 : return s->result;
340 : }
341 :
342 315 : if (s->seal_required) {
343 0 : s->result = NT_STATUS_ACCESS_DENIED;
344 :
345 0 : if (s->seal_explicitly_set) {
346 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
347 : } else {
348 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
349 : }
350 0 : if (!s->schannel_explicitly_set) {
351 0 : dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
352 0 : } else if (s->schannel_required) {
353 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
354 : }
355 :
356 0 : DEBUG(dbg_lvl, (
357 : "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
358 : "%s request (opnum[%u]) %s schannel from "
359 : "from client_account[%s] client_computer_name[%s] %s\n",
360 : opname, opnum, reason,
361 : log_escape(frame, creds->account_name),
362 : log_escape(frame, creds->computer_name),
363 : nt_errstr(s->result)));
364 0 : if (s->seal_explicitly_set) {
365 0 : D_NOTICE("CVE-2022-38023: Option "
366 : "'server schannel require seal:%s = yes' "
367 : "rejects access for client.\n",
368 : log_escape(frame, creds->account_name));
369 : } else {
370 0 : DEBUG(CVE_2022_38023_error_level, (
371 : "CVE-2022-38023: Check if option "
372 : "'server schannel require seal:%s = no' "
373 : "might be needed for a legacy client.\n",
374 : log_escape(frame, creds->account_name)));
375 : }
376 0 : if (!s->schannel_explicitly_set) {
377 0 : DEBUG(CVE_2020_1472_error_level, (
378 : "CVE-2020-1472(ZeroLogon): Check if option "
379 : "'server require schannel:%s = no' "
380 : "might be needed for a legacy client.\n",
381 : log_escape(frame, creds->account_name)));
382 0 : } else if (s->schannel_required) {
383 0 : D_NOTICE("CVE-2022-38023: Option "
384 : "'server require schannel:%s = yes' "
385 : "also rejects access for client.\n",
386 : log_escape(frame, creds->account_name));
387 : }
388 0 : TALLOC_FREE(frame);
389 0 : return s->result;
390 : }
391 :
392 315 : if (s->schannel_required) {
393 0 : s->result = NT_STATUS_ACCESS_DENIED;
394 :
395 0 : if (s->schannel_explicitly_set) {
396 0 : dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
397 : } else {
398 0 : dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
399 : }
400 0 : if (!s->seal_explicitly_set) {
401 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
402 : }
403 :
404 0 : DEBUG(dbg_lvl, (
405 : "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
406 : "%s request (opnum[%u]) %s schannel from "
407 : "client_account[%s] client_computer_name[%s] %s\n",
408 : opname, opnum, reason,
409 : log_escape(frame, creds->account_name),
410 : log_escape(frame, creds->computer_name),
411 : nt_errstr(s->result)));
412 0 : if (s->schannel_explicitly_set) {
413 0 : D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
414 : "'server require schannel:%s = yes' "
415 : "rejects access for client.\n",
416 : log_escape(frame, creds->account_name));
417 : } else {
418 0 : DEBUG(CVE_2020_1472_error_level, (
419 : "CVE-2020-1472(ZeroLogon): Check if option "
420 : "'server require schannel:%s = no' "
421 : "might be needed for a legacy client.\n",
422 : log_escape(frame, creds->account_name)));
423 : }
424 0 : if (!s->seal_explicitly_set) {
425 0 : DEBUG(CVE_2022_38023_error_level, (
426 : "CVE-2022-38023: Check if option "
427 : "'server schannel require seal:%s = no' "
428 : "might be needed for a legacy client.\n",
429 : log_escape(frame, creds->account_name)));
430 : }
431 0 : TALLOC_FREE(frame);
432 0 : return s->result;
433 : }
434 :
435 315 : s->result = NT_STATUS_OK;
436 :
437 315 : if (s->seal_explicitly_set) {
438 315 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
439 : } else {
440 0 : dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
441 : }
442 :
443 315 : if (s->schannel_explicitly_set) {
444 315 : dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
445 : } else {
446 0 : dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
447 : }
448 :
449 315 : DEBUG(dbg_lvl, (
450 : "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
451 : "%s request (opnum[%u]) %s schannel from "
452 : "client_account[%s] client_computer_name[%s] %s\n",
453 : opname, opnum, reason,
454 : log_escape(frame, creds->account_name),
455 : log_escape(frame, creds->computer_name),
456 : nt_errstr(s->result)));
457 :
458 315 : if (s->seal_explicitly_set) {
459 315 : D_INFO("CVE-2022-38023: Option "
460 : "'server schannel require seal:%s = no' "
461 : "still needed for '%s'!\n",
462 : log_escape(frame, creds->account_name),
463 : log_escape(frame, creds->computer_name));
464 : } else {
465 : /*
466 : * admins should set
467 : * server schannel require seal:COMPUTER$ = no
468 : * in order to avoid the level 0 messages.
469 : * Over time they can switch the global value
470 : * to be strict.
471 : */
472 0 : DEBUG(CVE_2022_38023_error_level, (
473 : "CVE-2022-38023: Please use "
474 : "'server schannel require seal:%s = no' "
475 : "for '%s' to avoid this warning!\n",
476 : log_escape(frame, creds->account_name),
477 : log_escape(frame, creds->computer_name)));
478 : }
479 :
480 315 : if (s->schannel_explicitly_set) {
481 315 : D_INFO("CVE-2020-1472(ZeroLogon): Option "
482 : "'server require schannel:%s = no' "
483 : "still needed for '%s'!\n",
484 : log_escape(frame, creds->account_name),
485 : log_escape(frame, creds->computer_name));
486 : } else {
487 : /*
488 : * admins should set
489 : * server require schannel:COMPUTER$ = no
490 : * in order to avoid the level 0 messages.
491 : * Over time they can switch the global value
492 : * to be strict.
493 : */
494 0 : DEBUG(CVE_2020_1472_error_level, (
495 : "CVE-2020-1472(ZeroLogon): "
496 : "Please use 'server require schannel:%s = no' "
497 : "for '%s' to avoid this warning!\n",
498 : log_escape(frame, creds->account_name),
499 : log_escape(frame, creds->computer_name)));
500 : }
501 :
502 315 : TALLOC_FREE(frame);
503 315 : return s->result;
504 : }
505 :
506 17950 : NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
507 : const struct netlogon_creds_CredentialState *creds,
508 : enum dcerpc_AuthType auth_type,
509 : enum dcerpc_AuthLevel auth_level,
510 : uint16_t opnum)
511 : {
512 17950 : struct dcesrv_netr_check_schannel_state *s = NULL;
513 1453 : NTSTATUS status;
514 :
515 17950 : status = dcesrv_netr_check_schannel_get_state(dce_call,
516 : creds,
517 : auth_type,
518 : auth_level,
519 : &s);
520 17950 : if (!NT_STATUS_IS_OK(status)) {
521 0 : return status;
522 : }
523 :
524 17950 : status = dcesrv_netr_check_schannel_once(dce_call, s, creds, opnum);
525 17950 : if (!NT_STATUS_IS_OK(status)) {
526 0 : return status;
527 : }
528 :
529 17950 : return NT_STATUS_OK;
530 : }
531 :
532 11344 : NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
533 : TALLOC_CTX *mem_ctx,
534 : const char *computer_name,
535 : struct netr_Authenticator *received_authenticator,
536 : struct netr_Authenticator *return_authenticator,
537 : struct netlogon_creds_CredentialState **creds_out)
538 : {
539 1063 : NTSTATUS nt_status;
540 11344 : struct netlogon_creds_CredentialState *creds = NULL;
541 11344 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
542 11344 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
543 :
544 11344 : dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
545 :
546 12407 : nt_status = schannel_check_creds_state(mem_ctx,
547 11344 : dce_call->conn->dce_ctx->lp_ctx,
548 : computer_name,
549 : received_authenticator,
550 : return_authenticator,
551 : &creds);
552 11344 : if (!NT_STATUS_IS_OK(nt_status)) {
553 20 : ZERO_STRUCTP(return_authenticator);
554 20 : return nt_status;
555 : }
556 :
557 12385 : nt_status = dcesrv_netr_check_schannel(dce_call,
558 : creds,
559 : auth_type,
560 : auth_level,
561 11324 : dce_call->pkt.u.request.opnum);
562 11324 : if (!NT_STATUS_IS_OK(nt_status)) {
563 0 : TALLOC_FREE(creds);
564 0 : ZERO_STRUCTP(return_authenticator);
565 0 : return nt_status;
566 : }
567 :
568 11324 : *creds_out = creds;
569 11324 : return NT_STATUS_OK;
570 : }
|