]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2021-20251 s4-rpc_server: Use authsam_search_account() to find the user
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Tue, 2 Aug 2022 02:37:52 +0000 (14:37 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 12 Sep 2022 23:07:38 +0000 (23:07 +0000)
This helps the bad password and audit log handling code as it
allows assumptions to be made about the attributes found in
the variable "msg", such as that DSDB_SEARCH_SHOW_EXTENDED_DN
was used.

This ensures we can re-search on the DN via the embedded GUID,
which in in turn rename-proof.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/rpc_server/samr/samr_password.c

index e55d5c28b5c3d41d59a7338b17e12d870ec51b51..904e5fba6c54669b945fd3aa6b07fa80c4493b48 100644 (file)
@@ -119,16 +119,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser4(struct dcesrv_call_state *dce_call,
 {
 #ifdef HAVE_GNUTLS_PBKDF2
        struct ldb_context *sam_ctx = NULL;
-       struct ldb_message **ldb_res = NULL;
-       const char *const attrs[] = {"unicodePwd",
-                                    "dBCSPwd",
-                                    "userAccountControl",
-                                    "msDS-ResultantPSO",
-                                    "msDS-User-Account-Control-Computed",
-                                    "badPwdCount",
-                                    "badPasswordTime",
-                                    "objectSid",
-                                    NULL};
+       struct ldb_message *msg = NULL;
        struct ldb_dn *dn = NULL;
        const char *samAccountName = NULL;
        struct dom_sid *objectSid = NULL;
@@ -178,35 +169,27 @@ NTSTATUS dcesrv_samr_ChangePasswordUser4(struct dcesrv_call_state *dce_call,
        }
 
        /*
-        * We need the users dn and the domain dn (derived from the user SID).
-        * We also need the current lm and nt password hashes in order to
-        * decrypt the incoming passwords.
+        * We use authsam_search_account() to be consistent with the
+        * other callers in the bad password and audit log handling
+        * systems.  It ensures we get DSDB_SEARCH_SHOW_EXTENDED_DN.
         */
-       rc = gendb_search(
-               sam_ctx,
-               mem_ctx,
-               NULL,
-               &ldb_res,
-               attrs,
-               "(&(sAMAccountName=%s)(objectclass=user))",
-               ldb_binary_encode_string(mem_ctx, r->in.account->string));
-       if (rc != 1) {
-               /* Will be converted to WRONG_PASSWORD below */
+       status = authsam_search_account(mem_ctx,
+                                       sam_ctx,
+                                       r->in.account->string,
+                                       ldb_get_default_basedn(sam_ctx),
+                                       &msg);
+       if (!NT_STATUS_IS_OK(status)) {
                ldb_transaction_cancel(sam_ctx);
-               DBG_WARNING("Unable to find account: %s",
-                           r->in.account->string);
-               status = NT_STATUS_NO_SUCH_USER;
                goto done;
        }
 
-       dn = ldb_res[0]->dn;
-       samAccountName =
-               ldb_msg_find_attr_as_string(ldb_res[0], "samAccountName", NULL);
-       objectSid = samdb_result_dom_sid(ldb_res, ldb_res[0], "objectSid");
+       dn = msg->dn;
+       samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
+       objectSid = samdb_result_dom_sid(msg, msg, "objectSid");
 
        status = samdb_result_passwords(mem_ctx,
                                        dce_call->conn->dce_ctx->lp_ctx,
-                                       ldb_res[0],
+                                       msg,
                                        &nt_pwd);
        if (!NT_STATUS_IS_OK(status)) {
                ldb_transaction_cancel(sam_ctx);
@@ -282,7 +265,7 @@ done:
        /* Only update the badPwdCount if we found the user */
        if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
                authsam_update_bad_pwd_count(sam_ctx,
-                                            ldb_res[0],
+                                            msg,
                                             ldb_get_default_basedn(sam_ctx));
        } else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
                /*