mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
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 25300d354c
)
This commit is contained in:
parent
0d27e4b459
commit
080ff2cd28
@ -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,
|
||||
|
@ -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
|
||||
";
|
||||
|
@ -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;
|
||||
|
||||
@ -1061,129 +1062,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)
|
||||
{
|
||||
struct dcesrv_call_state *dce_call = p->dce_call;
|
||||
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 = dce_call->pkt.u.request.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;
|
||||
}
|
||||
|
||||
dcesrv_call_auth_info(dce_call, &auth_type, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*************************************************************************/
|
||||
|
||||
@ -1429,7 +1307,8 @@ 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,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
@ -1493,7 +1372,8 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
|
||||
bool ok;
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
@ -1644,7 +1524,8 @@ NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
@ -2061,7 +1942,8 @@ NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
|
||||
}
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
&return_authenticator,
|
||||
@ -2411,7 +2293,8 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
|
||||
NTSTATUS status;
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
@ -2775,7 +2658,8 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
|
||||
/* TODO: check server name */
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
@ -2878,7 +2762,8 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
|
||||
/* TODO: check server name */
|
||||
|
||||
become_root();
|
||||
status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
p->mem_ctx,
|
||||
r->in.computer_name,
|
||||
r->in.credential,
|
||||
r->out.return_authenticator,
|
||||
|
@ -174,7 +174,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''',
|
||||
|
Loading…
Reference in New Issue
Block a user