summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2021-08-05 14:24:40 +0200
committerJule Anger <janger@samba.org>2021-11-08 10:52:13 +0100
commit0203330e2fa23482d99809e777ccb8a93a728aa3 (patch)
treee13dc7f176f3b0de762b37a360a52ab4d9ad6e36
parent08b6c8fda591c129adecd0779bf4a62386b8c740 (diff)
downloadsamba-0203330e2fa23482d99809e777ccb8a93a728aa3.tar.gz
CVE-2021-3738 s4:rpc_server/samr: make use of 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.]
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c19
-rw-r--r--source4/rpc_server/samr/samr_password.c33
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/md4.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);
struct imessaging_context *imsg_ctx =
dcesrv_imessaging_context(dce_call->conn);
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
@@ -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);
struct imessaging_context *imsg_ctx =
dcesrv_imessaging_context(dce_call->conn);
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
@@ -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;
}