Redfish: Repair the wrong change made by non-admin

In Redfish spec, the Operator and Readonly group should only change
their own passwd using patch in ManagerAccount.
(because of their ConfigureSelf privilege)

But now they can even modify their RoleId in the code.

https://www.dmtf.org/sites/default/files/standards/documents/DSP2046_2021.2.pdf

Test:
the 'xiao' is a Operator
~ curl -k -H "X-Auth-Token: $token" -X PATCH -d '{"RoleId":"ReadOnly"}'
https://${bmc}/redfish/v1/AccountService/Accounts/xiao
{
  "error": {
    "@Message.ExtendedInfo": [
      {
        "@odata.type": "#Message.v1_1_1.Message",
        "Message": "There are insufficient privileges for the account
or credentials associated with the current session to perform the
requested operation.",
        "MessageArgs": [],
        "MessageId": "Base.1.8.1.InsufficientPrivilege",
        "MessageSeverity": "Critical",
        "Resolution": "Either abandon the operation or change the
associated access rights and resubmit the request if the operation
failed."
      }
    ],
    "code": "Base.1.8.1.InsufficientPrivilege",
    "message": "There are insufficient privileges for the account or
credentials associated with the current session to perform the
requested operation."
  }
}%

Signed-off-by: Xiaochao Ma <maxiaochao@inspur.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I9befcd94ee3a0b55f1ae7af38eb40e5f92fc3264
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 8e27930..2ab0a1e 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1846,34 +1846,37 @@
                 std::optional<bool> enabled;
                 std::optional<std::string> roleId;
                 std::optional<bool> locked;
-                if (!json_util::readJson(req, asyncResp->res, "UserName",
-                                         newUserName, "Password", password,
-                                         "RoleId", roleId, "Enabled", enabled,
-                                         "Locked", locked))
+
+                Privileges effectiveUserPrivileges =
+                    redfish::getUserPrivileges(req.userRole);
+                Privileges configureUsers = {"ConfigureUsers"};
+                bool userHasConfigureUsers =
+                    effectiveUserPrivileges.isSupersetOf(configureUsers);
+                if (userHasConfigureUsers)
                 {
-                    return;
+                    // Users with ConfigureUsers can modify for all users
+                    if (!json_util::readJson(req, asyncResp->res, "UserName",
+                                             newUserName, "Password", password,
+                                             "RoleId", roleId, "Enabled",
+                                             enabled, "Locked", locked))
+                    {
+                        return;
+                    }
                 }
-
-                // Perform a proper ConfigureSelf authority check.  If the
-                // session is being used to PATCH a property other than
-                // Password, then the ConfigureSelf privilege does not apply.
-                // If the user is operating on an account not their own, then
-                // their ConfigureSelf privilege does not apply.  In either
-                // case, perform the authority check again without the user's
-                // ConfigureSelf privilege.
-                if ((username != req.session->username))
+                else
                 {
-                    Privileges requiredPermissionsToChangeNonSelf = {
-                        "ConfigureUsers"};
-                    Privileges effectiveUserPrivileges =
-                        redfish::getUserPrivileges(req.userRole);
-
-                    if (!effectiveUserPrivileges.isSupersetOf(
-                            requiredPermissionsToChangeNonSelf))
+                    // ConfigureSelf accounts can only modify their own account
+                    if (username != req.session->username)
                     {
                         messages::insufficientPrivilege(asyncResp->res);
                         return;
                     }
+                    // ConfigureSelf accounts can only modify their password
+                    if (!json_util::readJson(req, asyncResp->res, "Password",
+                                             password))
+                    {
+                        return;
+                    }
                 }
 
                 // if user name is not provided in the patch method or if it