diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index a672d8097d3b8..63afdd86bd938 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2191,7 +2191,8 @@ public class DevicePolicyManager { * Note: This API has been limited as of {@link android.os.Build.VERSION_CODES#N} for * device admins that are not device owner and not profile owner. * The password can now only be changed if there is currently no password set. Device owner - * and profile owner can still do this. + * and profile owner can still do this when user is unlocked and does not have a managed + * profile. *
* The given password must be sufficient for the current password quality and length constraints * as returned by {@link #getPasswordQuality(ComponentName)} and @@ -2217,6 +2218,7 @@ public class DevicePolicyManager { * current constraints or if the user has not been decrypted yet. * @throws SecurityException if the calling application does not own an active administrator * that uses {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} + * @throws IllegalStateException if the calling user is locked or has a managed profile. */ public boolean resetPassword(String password, int flags) { throwIfParentInstance("resetPassword"); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c1913decde16b..1af9ccbbcfd7b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3810,14 +3810,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // If caller has PO (or DO) it can change the password, so see if that's the case first. ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked( null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, callingUid); + final boolean preN = getTargetSdk(admin.info.getPackageName(), + userHandle) <= android.os.Build.VERSION_CODES.M; if (admin == null) { // Otherwise, make sure the caller has any active admin with the right policy. admin = getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); - final boolean preN = getTargetSdk(admin.info.getPackageName(), userHandle) - <= android.os.Build.VERSION_CODES.M; - // As of N, password resetting to empty/null is not allowed anymore. // TODO Should we allow DO/PO to set an empty password? if (TextUtils.isEmpty(password)) { @@ -3838,6 +3837,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + // Do not allow to reset password when current user has a managed profile + if (!isManagedProfile(userHandle)) { + for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { + if (userInfo.isManagedProfile()) { + if (!preN) { + throw new IllegalStateException( + "Cannot reset password on user has managed profile"); + } else { + Slog.e(LOG_TAG, "Cannot reset password on user has managed profile"); + return false; + } + } + } + } + // Do not allow to reset password when user is locked + if (!mUserManager.isUserUnlocked(userHandle)) { + if (!preN) { + throw new IllegalStateException("Cannot reset password when user is locked"); + } else { + Slog.e(LOG_TAG, "Cannot reset password when user is locked"); + return false; + } + } + quality = getPasswordQuality(null, userHandle, /* parent */ false); if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) { quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;