CVE-2022-38023 s4:rpc_server/netlogon: improve CVE-2020-1472(ZeroLogon) debug messages
authorStefan Metzmacher <metze@samba.org>
Wed, 30 Nov 2022 11:37:03 +0000 (12:37 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 13 Dec 2022 20:37:58 +0000 (21:37 +0100)
In order to avoid generating useless debug messages during make test,
we will use 'CVE_2020_1472:warn_about_unused_debug_level = 3'
and 'CVE_2020_1472:error_debug_level = 2' in order to avoid schannel warnings.

Review with: git show -w

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 16ee03efc194d9c1c2c746f63236b977a419918d)

source4/rpc_server/netlogon/dcerpc_netlogon.c

index 637be93dacc986b07bf2af4c09922e821ed1114f..d4bbb1261c3a3a879cd6a2a02c93a4cc0f63ee34 100644 (file)
@@ -641,15 +641,34 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
        bool schannel_required = schannel_global_required;
        const char *explicit_opt = NULL;
        struct netlogon_creds_CredentialState *creds = NULL;
+       int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
+       int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
+       unsigned int dbg_lvl = DBGLVL_DEBUG;
        enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+       enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
        uint16_t opnum = dce_call->pkt.u.request.opnum;
        const char *opname = "<unknown>";
+       const char *reason = "<unknown>";
 
        if (opnum < ndr_table_netlogon.num_calls) {
                opname = ndr_table_netlogon.calls[opnum].name;
        }
 
-       dcesrv_call_auth_info(dce_call, &auth_type, NULL);
+       dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+
+       if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+               if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+                       reason = "WITH SEALED";
+               } else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+                       reason = "WITH SIGNED";
+               } else {
+                       smb_panic("Schannel without SIGN/SEAL");
+               }
+       } else {
+               reason = "WITHOUT";
+       }
 
        nt_status = schannel_check_creds_state(mem_ctx,
                                               lp_ctx,
@@ -676,62 +695,108 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
        }
 
        if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-               if (!schannel_required) {
-                       DBG_ERR("CVE-2020-1472(ZeroLogon): "
-                               "%s request (opnum[%u]) WITH schannel from "
-                               "client_account[%s] client_computer_name[%s]\n",
-                               opname, opnum,
-                               log_escape(frame, creds->account_name),
-                               log_escape(frame, creds->computer_name));
+               nt_status = NT_STATUS_OK;
+
+               if (explicit_opt != NULL && !schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
+               } else if (!schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
                }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon): "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(nt_status)));
+
                if (explicit_opt != NULL && !schannel_required) {
-                       DBG_ERR("CVE-2020-1472(ZeroLogon): "
-                               "Option 'server require schannel:%s = no' not needed!?\n",
-                               log_escape(frame, creds->account_name));
+                       DEBUG(CVE_2020_1472_warn_level, (
+                             "CVE-2020-1472(ZeroLogon): "
+                             "Option 'server require schannel:%s = no' not needed for '%s'!\n",
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name)));
                }
 
                *creds_out = creds;
                TALLOC_FREE(frame);
-               return NT_STATUS_OK;
+               return nt_status;
        }
 
        if (schannel_required) {
-               DBG_ERR("CVE-2020-1472(ZeroLogon): "
-                       "%s request (opnum[%u]) without schannel from "
-                       "client_account[%s] client_computer_name[%s]\n",
-                       opname, opnum,
-                       log_escape(frame, creds->account_name),
-                       log_escape(frame, creds->computer_name));
-               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-                       "'server require schannel:%s = no' "
-                       "might be needed for a legacy client.\n",
-                       log_escape(frame, creds->account_name));
+               nt_status = NT_STATUS_ACCESS_DENIED;
+
+               if (explicit_opt != NULL) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+               } else {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(nt_status)));
+               if (explicit_opt != NULL) {
+                       D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
+                               "'server require schannel:%s = yes' "
+                               "rejects access for client.\n",
+                               log_escape(frame, creds->account_name));
+               } else {
+                       DEBUG(CVE_2020_1472_error_level, (
+                             "CVE-2020-1472(ZeroLogon): Check if option "
+                             "'server require schannel:%s = no' "
+                             "might be needed for a legacy client.\n",
+                             log_escape(frame, creds->account_name)));
+               }
                TALLOC_FREE(creds);
                ZERO_STRUCTP(return_authenticator);
                TALLOC_FREE(frame);
-               return NT_STATUS_ACCESS_DENIED;
+               return nt_status;
        }
 
+       nt_status = NT_STATUS_OK;
+
        if (explicit_opt != NULL) {
-               DBG_INFO("CVE-2020-1472(ZeroLogon): "
-                        "%s request (opnum[%u]) without schannel from "
-                        "client_account[%s] client_computer_name[%s]\n",
-                        opname, opnum,
-                        log_escape(frame, creds->account_name),
-                        log_escape(frame, creds->computer_name));
-               DBG_INFO("CVE-2020-1472(ZeroLogon): "
-                        "Option 'server require schannel:%s = no' still needed!\n",
-                        log_escape(frame, creds->account_name));
+               dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
        } else {
-               DBG_ERR("CVE-2020-1472(ZeroLogon): "
-                       "%s request (opnum[%u]) without schannel from "
-                       "client_account[%s] client_computer_name[%s]\n",
-                       opname, opnum,
-                       log_escape(frame, creds->account_name),
-                       log_escape(frame, creds->computer_name));
-               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-                       "'server require schannel:%s = no' might be needed!\n",
-                       log_escape(frame, creds->account_name));
+               dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+       }
+
+       DEBUG(dbg_lvl, (
+             "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+             "%s request (opnum[%u]) %s schannel from "
+             "client_account[%s] client_computer_name[%s] %s\n",
+             opname, opnum, reason,
+             log_escape(frame, creds->account_name),
+             log_escape(frame, creds->computer_name),
+             nt_errstr(nt_status)));
+
+       if (explicit_opt != NULL) {
+               D_INFO("CVE-2020-1472(ZeroLogon): Option "
+                      "'server require schannel:%s = no' "
+                      "still needed for '%s'!\n",
+                      log_escape(frame, creds->account_name),
+                      log_escape(frame, creds->computer_name));
+       } else {
+               /*
+                * admins should set
+                * server require schannel:COMPUTER$ = no
+                * in order to avoid the level 0 messages.
+                * Over time they can switch the global value
+                * to be strict.
+                */
+               DEBUG(CVE_2020_1472_error_level, (
+                     "CVE-2020-1472(ZeroLogon): "
+                     "Please use 'server require schannel:%s = no' "
+                     "for '%s' to avoid this warning!\n",
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name)));
        }
 
        *creds_out = creds;