samba/backport-0006-CVE-2021-3738-s4-rpc_server-samr-make-use-of-dcesrv_.patch
haochenstar 8378df4821 fix CVE-2020-25717,CVE-2020-25718,CVE-2020-25719,CVE-2020-25721,CVE-2020-25722,CVE-2016-2124,CVE-2021-3738
(cherry picked from commit aee849c6c0708056f62f6445e3b5274d1cec6408)
2022-01-19 11:41:35 +08:00

177 lines
6.3 KiB
Diff

From 0203330e2fa23482d99809e777ccb8a93a728aa3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 5 Aug 2021 14:24:40 +0200
Subject: [PATCH 266/266] CVE-2021-3738 s4:rpc_server/samr: make use of
Conflict: NA
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=0203330e2fa23482d99809e777ccb8a93a728aa3
dcesrv_samdb_connect_as_*() helper
This avoids a crash that's triggered by windows clients using
handles from samr_Connect*() on across multiple connections within
an association group.
In other cases is not strictly required, but it makes it easier to audit that
source4/rpc_server no longer calls samdb_connect() directly and also
improves the auditing for the dcesrv_samdb_connect_as_system() case.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
[abartlet@samba.org Backported from master as Samba 4.13 does not
call dcerpc_is_transport_encrypted() and so session_info becomes
unused.]
---
source4/rpc_server/samr/dcesrv_samr.c | 19 ++------------
source4/rpc_server/samr/samr_password.c | 33 ++++---------------------
2 files changed, 7 insertions(+), 45 deletions(-)
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 7345cac6bd6..c810aac7c8a 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -210,8 +210,6 @@ exit:
static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_Connect *r)
{
- struct auth_session_info *session_info =
- dcesrv_call_session_info(dce_call);
struct samr_connect_state *c_state;
struct dcesrv_handle *handle;
@@ -223,18 +221,12 @@ static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_C
}
/* make sure the sam database is accessible */
- c_state->sam_ctx = samdb_connect(c_state,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- session_info,
- dce_call->conn->remote_address,
- 0);
+ c_state->sam_ctx = dcesrv_samdb_connect_as_user(c_state, dce_call);
if (c_state->sam_ctx == NULL) {
talloc_free(c_state);
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
-
handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_CONNECT);
if (!handle) {
talloc_free(c_state);
@@ -4807,8 +4799,6 @@ static NTSTATUS dcesrv_samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_st
static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_GetDomPwInfo *r)
{
- struct auth_session_info *session_info =
- dcesrv_call_session_info(dce_call);
struct ldb_message **msgs;
int ret;
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
@@ -4816,12 +4806,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
ZERO_STRUCTP(r->out.info);
- sam_ctx = samdb_connect(mem_ctx,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- session_info,
- dce_call->conn->remote_address,
- 0);
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 52a644176e2..9144c23155b 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "rpc_server/dcerpc_server.h"
+#include "rpc_server/common/common.h"
#include "rpc_server/samr/dcesrv_samr.h"
#include "system/time.h"
#include "../lib/crypto/crypto.h"
@@ -101,8 +102,6 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct samr_OemChangePasswordUser2 *r)
{
- struct auth_session_info *session_info =
- dcesrv_call_session_info(dce_call);
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
DATA_BLOB new_password, new_unicode_password;
char *new_pass;
@@ -146,12 +145,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
/* Connect to a SAMDB with system privileges for fetching the old pw
* hashes. */
- sam_ctx = samdb_connect(mem_ctx,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- system_session(dce_call->conn->dce_ctx->lp_ctx),
- dce_call->conn->remote_address,
- 0);
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
@@ -249,12 +243,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
}
/* Connect to a SAMDB with user privileges for the password change */
- sam_ctx = samdb_connect(mem_ctx,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- session_info,
- dce_call->conn->remote_address,
- 0);
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
@@ -327,8 +316,6 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct samr_ChangePasswordUser3 *r)
{
- struct auth_session_info *session_info =
- dcesrv_call_session_info(dce_call);
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
DATA_BLOB new_password;
struct ldb_context *sam_ctx = NULL;
@@ -374,12 +361,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
/* Connect to a SAMDB with system privileges for fetching the old pw
* hashes. */
- sam_ctx = samdb_connect(mem_ctx,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- system_session(dce_call->conn->dce_ctx->lp_ctx),
- dce_call->conn->remote_address,
- 0);
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
@@ -485,12 +467,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
}
/* Connect to a SAMDB with user privileges for the password change */
- sam_ctx = samdb_connect(mem_ctx,
- dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- session_info,
- dce_call->conn->remote_address,
- 0);
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
--
2.23.0