From: Stefan Metzmacher Date: Thu, 5 Aug 2021 12:24:40 +0000 (+0200) Subject: CVE-2021-3738 s4:rpc_server/samr: make use of dcesrv_samdb_connect_as_*() helper X-Git-Tag: ldb-2.5.0~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3121be69cac7748d1cb01273c0d09fab2fe726a0;p=thirdparty%2Fsamba.git 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 Reviewed-by: Andrew Bartlett Autobuild-User(master): Jule Anger Autobuild-Date(master): Tue Nov 9 20:37:30 UTC 2021 on sn-devel-184 --- diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 29c509522be..10c53b19e0d 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -212,8 +212,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; @@ -225,18 +223,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); @@ -4809,8 +4801,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 }; @@ -4818,12 +4808,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 0f5a6d0f820..b490723c08b 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" @@ -156,12 +157,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; } @@ -262,12 +258,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; } @@ -340,8 +331,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; @@ -387,12 +376,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; } @@ -498,12 +482,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; }