LCOV - code coverage report
Current view: top level - librpc/rpc/server/netlogon - schannel_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 136 208 65.4 %
Date: 2024-04-21 15:09:00 Functions: 4 4 100.0 %

          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             : }

Generated by: LCOV version 1.14