CVE-2021-3738 s4:rpc_server/samr: make use of dcesrv_samdb_connect_as_*() helper
authorStefan Metzmacher <metze@samba.org>
Thu, 5 Aug 2021 12:24:40 +0000 (14:24 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:13 +0000 (10:52 +0100)
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
source4/rpc_server/samr/samr_password.c

index 7345cac6bd679fbe1abab1747cf84657bdf03c90..c810aac7c8a0701af084e6b1c2fd5f114f80264f 100644 (file)
@@ -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;
        }
index 52a644176e26f79b53a2cadd7af04bef9704c5d6..9144c23155b1ac79bc991f68a5c98a1ccf85fa58 100644 (file)
@@ -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;
        }