diff options
author | Samuel Cabrero <scabrero@suse.de> | 2022-12-22 16:30:26 +0100 |
---|---|---|
committer | Jule Anger <janger@samba.org> | 2023-01-23 09:06:16 +0000 |
commit | 4975adda2c9e44ee5dc7043e64949d93cfd18f84 (patch) | |
tree | 975688f3f302bc76b97db3ad009306af7764217c | |
parent | 9d7732e8225d42974445c044a69b4615bfd7b301 (diff) | |
download | samba-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.c | 6 | ||||
-rwxr-xr-x | selftest/target/Samba3.pm | 14 | ||||
-rw-r--r-- | source3/rpc_server/netlogon/srv_netlog_nt.c | 200 | ||||
-rw-r--r-- | source3/rpc_server/wscript_build | 2 |
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''', |