summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Cabrero <scabrero@suse.de>2022-12-22 16:30:26 +0100
committerJule Anger <janger@samba.org>2023-01-23 09:06:16 +0000
commit4975adda2c9e44ee5dc7043e64949d93cfd18f84 (patch)
tree975688f3f302bc76b97db3ad009306af7764217c
parent9d7732e8225d42974445c044a69b4615bfd7b301 (diff)
downloadsamba-4975adda2c9e44ee5dc7043e64949d93cfd18f84.tar.gz
CVE-2022-38023 s3:rpc_server/netlogon: Use dcesrv_netr_creds_server_step_check()
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)
-rw-r--r--librpc/rpc/server/netlogon/schannel_util.c6
-rwxr-xr-xselftest/target/Samba3.pm14
-rw-r--r--source3/rpc_server/netlogon/srv_netlog_nt.c200
-rw-r--r--source3/rpc_server/wscript_build2
4 files changed, 58 insertions, 164 deletions
diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c
index 9b2a88a2628..b14497b13ce 100644
--- a/librpc/rpc/server/netlogon/schannel_util.c
+++ b/librpc/rpc/server/netlogon/schannel_util.c
@@ -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,
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 9dd9e23a555..96029d44525 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -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
";
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index cf40825179c..cc67958244b 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -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;
@@ -1032,128 +1033,6 @@ NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
/*************************************************************************
*************************************************************************/
-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;
-}
-
-
-/*************************************************************************
- *************************************************************************/
-
static NTSTATUS samr_open_machine_account(
struct dcerpc_binding_handle *b,
const struct dom_sid *machine_sid,
@@ -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;
diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build
index 482e582bd8b..649b86abc89 100644
--- a/source3/rpc_server/wscript_build
+++ b/source3/rpc_server/wscript_build
@@ -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''',