CVE-2022-38023 s3:rpc_server/netlogon: Use dcesrv_netr_creds_server_step_check()
authorSamuel Cabrero <scabrero@suse.de>
Thu, 22 Dec 2022 15:30:26 +0000 (16:30 +0100)
committerJule Anger <janger@samba.org>
Mon, 23 Jan 2023 09:06:16 +0000 (09:06 +0000)
After s3 and s4 rpc servers merge we can avoid duplicated code.

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

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 25300d354c80995997d552581cd91dddaf4bbf48)

librpc/rpc/server/netlogon/schannel_util.c
selftest/target/Samba3.pm
source3/rpc_server/netlogon/srv_netlog_nt.c
source3/rpc_server/wscript_build

index 9b2a88a26288db77101596c489ccaac0a5fb9282..b14497b13ce3e0ba773998fe223b4c87bce9f5e5 100644 (file)
@@ -529,12 +529,6 @@ NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
        return NT_STATUS_OK;
 }
 
-/*
- * NOTE: The following functions are nearly identical to the ones available in
- * source3/rpc_server/srv_nelog_nt.c
- * The reason we keep 2 copies is that they use different structures to
- * represent the auth_info and the decrpc pipes.
- */
 NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
                                                    TALLOC_CTX *mem_ctx,
                                                    const char *computer_name,
index 9dd9e23a5554461a17e2078899159918cf617cb1..96029d44525d6de718a2303e088567aae732b1d0 100755 (executable)
@@ -288,6 +288,20 @@ sub setup_nt4_dc
        server require schannel:schannel11\$ = no
        server require schannel:torturetest\$ = no
 
+       server schannel require seal:schannel0\$ = no
+       server schannel require seal:schannel1\$ = no
+       server schannel require seal:schannel2\$ = no
+       server schannel require seal:schannel3\$ = no
+       server schannel require seal:schannel4\$ = no
+       server schannel require seal:schannel5\$ = no
+       server schannel require seal:schannel6\$ = no
+       server schannel require seal:schannel7\$ = no
+       server schannel require seal:schannel8\$ = no
+       server schannel require seal:schannel9\$ = no
+       server schannel require seal:schannel10\$ = no
+       server schannel require seal:schannel11\$ = no
+       server schannel require seal:torturetest\$ = no
+
        fss: sequence timeout = 1
        check parent directory delete on close = yes
 ";
index cf40825179c8760285d0fb4bc76c9481b83ec038..cc67958244bac871434e1acb7432646e5dba2245 100644 (file)
@@ -51,6 +51,7 @@
 #include "libsmb/dsgetdcname.h"
 #include "lib/util/util_str_escape.h"
 #include "source3/lib/substitute.h"
+#include "librpc/rpc/server/netlogon/schannel_util.h"
 
 extern userdom_struct current_user_info;
 
@@ -1029,128 +1030,6 @@ NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
        return _netr_ServerAuthenticate3(p, &a);
 }
 
-/*************************************************************************
- *************************************************************************/
-
-static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
-                                            TALLOC_CTX *mem_ctx,
-                                            const char *computer_name,
-                                            struct netr_Authenticator *received_authenticator,
-                                            struct netr_Authenticator *return_authenticator,
-                                            struct netlogon_creds_CredentialState **creds_out)
-{
-       NTSTATUS status;
-       bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
-       bool schannel_required = schannel_global_required;
-       const char *explicit_opt = NULL;
-       struct loadparm_context *lp_ctx;
-       struct netlogon_creds_CredentialState *creds = NULL;
-       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
-       uint16_t opnum = p->opnum;
-       const char *opname = "<unknown>";
-
-       if (creds_out != NULL) {
-               *creds_out = NULL;
-       }
-
-       if (opnum < ndr_table_netlogon.num_calls) {
-               opname = ndr_table_netlogon.calls[opnum].name;
-       }
-
-       auth_type = p->auth.auth_type;
-
-       lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
-       if (lp_ctx == NULL) {
-               DEBUG(0, ("loadparm_init_s3 failed\n"));
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       status = schannel_check_creds_state(mem_ctx, lp_ctx,
-                                           computer_name, received_authenticator,
-                                           return_authenticator, &creds);
-       talloc_unlink(mem_ctx, lp_ctx);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               ZERO_STRUCTP(return_authenticator);
-               return status;
-       }
-
-       /*
-        * We don't use lp_parm_bool(), as we
-        * need the explicit_opt pointer in order to
-        * adjust the debug messages.
-        */
-
-       explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
-                                           "server require schannel",
-                                           creds->account_name,
-                                           NULL);
-       if (explicit_opt != NULL) {
-               schannel_required = lp_bool(explicit_opt);
-       }
-
-       if (schannel_required) {
-               if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-                       *creds_out = creds;
-                       return NT_STATUS_OK;
-               }
-
-               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(mem_ctx, creds->account_name),
-                       log_escape(mem_ctx, creds->computer_name));
-               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-                       "'server require schannel:%s = no' is needed! \n",
-                       log_escape(mem_ctx, creds->account_name));
-               TALLOC_FREE(creds);
-               ZERO_STRUCTP(return_authenticator);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-               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(mem_ctx, creds->account_name),
-                       log_escape(mem_ctx, creds->computer_name));
-               DBG_ERR("CVE-2020-1472(ZeroLogon): "
-                       "Option 'server require schannel:%s = no' not needed!?\n",
-                       log_escape(mem_ctx, creds->account_name));
-
-               *creds_out = creds;
-               return 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(mem_ctx, creds->account_name),
-                        log_escape(mem_ctx, creds->computer_name));
-               DBG_INFO("CVE-2020-1472(ZeroLogon): "
-                        "Option 'server require schannel:%s = no' still needed!\n",
-                        log_escape(mem_ctx, creds->account_name));
-       } 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(mem_ctx, creds->account_name),
-                       log_escape(mem_ctx, creds->computer_name));
-               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-                       "'server require schannel:%s = no' might be needed!\n",
-                       log_escape(mem_ctx, creds->account_name));
-       }
-
-       *creds_out = creds;
-       return NT_STATUS_OK;
-}
-
-
 /*************************************************************************
  *************************************************************************/
 
@@ -1397,11 +1276,12 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
        DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1458,11 +1338,12 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
        bool ok;
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1613,11 +1494,12 @@ NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
        struct netlogon_creds_CredentialState *creds;
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
 
        return status;
@@ -2019,11 +1901,12 @@ NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
        }
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             &return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               &return_authenticator,
+                                               &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -2364,11 +2247,12 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
        NTSTATUS status;
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -2725,11 +2609,12 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
        /* TODO: check server name */
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -2828,11 +2713,12 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
        /* TODO: check server name */
 
        become_root();
-       status = netr_creds_server_step_check(p, p->mem_ctx,
-                                             r->in.computer_name,
-                                             r->in.credential,
-                                             r->out.return_authenticator,
-                                             &creds);
+       status = dcesrv_netr_creds_server_step_check(p->dce_call,
+                                               p->mem_ctx,
+                                               r->in.computer_name,
+                                               r->in.credential,
+                                               r->out.return_authenticator,
+                                               &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
index 482e582bd8b18fc0711eaec53288893af9862907..649b86abc89ea74186009cd92d6fb8e766d2f309 100644 (file)
@@ -71,7 +71,7 @@ bld.SAMBA3_SUBSYSTEM('RPC_NETDFS',
 
 bld.SAMBA3_SUBSYSTEM('RPC_NETLOGON',
                      source='''netlogon/srv_netlog_nt.c''',
-                    deps='LIBCLI_AUTH')
+                    deps='LIBCLI_AUTH DCERPC_SERVER_NETLOGON')
 
 bld.SAMBA3_SUBSYSTEM('RPC_NTSVCS',
                     source='''ntsvcs/srv_ntsvcs_nt.c''',