]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2021-20251 s4-rpc_server: Use authsam_search_account() to find the user
authorAndrew Bartlett <abartlet@samba.org>
Mon, 29 Mar 2021 21:51:26 +0000 (10:51 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 12 Sep 2022 23:07:37 +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: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/rpc_server/samr/samr_password.c

index da22ab7484b2750f96ef88d178c0ae8e910de61c..09d7501d47465c2e008c05e46f04ec75ba102538 100644 (file)
@@ -312,13 +312,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
        struct ldb_context *sam_ctx = NULL;
        struct ldb_dn *user_dn = NULL;
        int ret;
-       struct ldb_result *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 samr_Password *nt_pwd;
        struct samr_DomInfo1 *dominfo = NULL;
        struct userPwdChangeFailureInformation *reject = NULL;
@@ -356,26 +350,26 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
-       /* 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 */
-       ret = dsdb_search(sam_ctx, mem_ctx, &res,
-                         ldb_get_default_basedn(sam_ctx),
-                         LDB_SCOPE_SUBTREE, attrs,
-                         DSDB_SEARCH_SHOW_EXTENDED_DN,
-                         "(&(sAMAccountName=%s)(objectclass=user))",
-                         ldb_binary_encode_string(mem_ctx, r->in.account->string));
-       if (ret != LDB_SUCCESS || res->count != 1) {
-               status = NT_STATUS_NO_SUCH_USER; /* Converted to WRONG_PASSWORD below */
+       /*
+        * 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.
+        */
+       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)) {
                goto failed;
        }
 
-       user_dn = res->msgs[0]->dn;
-       user_samAccountName = ldb_msg_find_attr_as_string(res->msgs[0], "samAccountName", NULL);
-       user_objectSid = samdb_result_dom_sid(res, res->msgs[0], "objectSid");
+       user_dn = msg->dn;
+       user_samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
+       user_objectSid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
 
        status = samdb_result_passwords(mem_ctx, lp_ctx,
-                                       res->msgs[0], &nt_pwd);
+                                       msg, &nt_pwd);
        if (!NT_STATUS_IS_OK(status) ) {
                goto failed;
        }
@@ -491,7 +485,7 @@ failed:
 
        /* 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, res->msgs[0], ldb_get_default_basedn(sam_ctx));
+               authsam_update_bad_pwd_count(sam_ctx, msg, ldb_get_default_basedn(sam_ctx));
        } else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
                /* Don't give the game away:  (don't allow anonymous users to prove the existence of usernames) */
                status = NT_STATUS_WRONG_PASSWORD;