summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEsteban Talavera <etalavera@google.com>2014-08-06 16:20:56 +0100
committerEsteban Talavera <etalavera@google.com>2014-08-06 18:10:16 +0100
commitfe0f24cc92b04e03cac3f807859721f1ce7ef54a (patch)
tree1ef3bbf51014c4775a686bb2808978d60549ba0e
parent3f1ddf83a4faba3dec71ed7eebe1835f4685cf60 (diff)
downloadframeworks_base-fe0f24cc92b04e03cac3f807859721f1ce7ef54a.zip
frameworks_base-fe0f24cc92b04e03cac3f807859721f1ce7ef54a.tar.gz
frameworks_base-fe0f24cc92b04e03cac3f807859721f1ce7ef54a.tar.bz2
Wipe only managed profile when max number of incorrect passwords exceeded
When the maximum number of retries that has been exceeded is not for the primary profile of the user, wipe only the profile that set that policy (e.g. the managed profile) rather than the entire user. At the moment the whole device is wiped if the max number of incorrect passwords for a managed profile is reached, as the password is shared with the USER_OWNER. Bug: 14453697 Change-Id: I5746de104133c0ea0a51d75b9c92e1516d365d8c
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java13
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java60
2 files changed, 46 insertions, 27 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 7727e4a..724b560 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -57,7 +57,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
public KeyguardSecurityContainer(Context context) {
- this(null, null, 0);
+ this(context, null, 0);
}
public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
@@ -240,10 +240,13 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
boolean showTimeout = false;
if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
- // If we reach this code, it means the user has installed a DevicePolicyManager
- // that requests device wipe after N attempts. Once we get below the grace
- // period, we'll post this dialog every time as a clear warning until the
- // bombshell hits and the device is wiped.
+ // The user has installed a DevicePolicyManager that requests a user/profile to be wiped
+ // N attempts. Once we get below the grace period, we post this dialog every time as a
+ // clear warning until the deletion fires.
+ //
+ // TODO: Show a different dialog depending on whether the device will be completely
+ // wiped (i.e. policy is set for the primary profile of the USER_OWNER) or a single
+ // secondary user or managed profile will be removed.
if (remainingBeforeWipe > 0) {
showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
} else {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c6730bf..7f2018e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2229,30 +2229,39 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
enforceCrossUserPermission(userHandle);
synchronized (this) {
- int count = 0;
+ ActiveAdmin admin = (who != null) ? getActiveAdminUncheckedLocked(who, userHandle)
+ : getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+ return admin != null ? admin.maximumFailedPasswordsForWipe : 0;
+ }
+ }
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.maximumFailedPasswordsForWipe : count;
- }
+ /**
+ * Returns the admin with the strictest policy on maximum failed passwords for this user and all
+ * profiles that are visible from this user. If the policy for the primary and any other profile
+ * are equal, it returns the admin for the primary profile.
+ * Returns {@code null} if none of them have that policy set.
+ */
+ private ActiveAdmin getAdminWithMinimumFailedPasswordsForWipeLocked(int userHandle) {
+ int count = 0;
+ ActiveAdmin strictestAdmin = null;
+ for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+ DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ for (ActiveAdmin admin : policy.mAdminList) {
+ if (admin.maximumFailedPasswordsForWipe ==
+ ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
+ continue; // No max number of failed passwords policy set for this profile.
+ }
- // Return strictest policy for this user and profiles that are visible from this user.
- List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
- for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (count == 0) {
- count = admin.maximumFailedPasswordsForWipe;
- } else if (admin.maximumFailedPasswordsForWipe != 0
- && count > admin.maximumFailedPasswordsForWipe) {
- count = admin.maximumFailedPasswordsForWipe;
- }
+ // We always favor the primary profile if several profiles have the same value set.
+ if (count == 0 ||
+ count > admin.maximumFailedPasswordsForWipe ||
+ (userInfo.isPrimary() && count >= admin.maximumFailedPasswordsForWipe)) {
+ count = admin.maximumFailedPasswordsForWipe;
+ strictestAdmin = admin;
}
}
- return count;
}
+ return strictestAdmin;
}
public boolean resetPassword(String password, int flags, int userHandle) {
@@ -2627,7 +2636,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public void run() {
try {
ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
- mUserManager.removeUser(userHandle);
+ if (!mUserManager.removeUser(userHandle)) {
+ Slog.w(LOG_TAG, "Couldn't remove user " + userHandle);
+ }
} catch (RemoteException re) {
// Shouldn't happen
}
@@ -2751,9 +2762,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy.mFailedPasswordAttempts++;
saveSettingsLocked(userHandle);
if (mHasFeature) {
- int max = getMaximumFailedPasswordsForWipe(null, userHandle);
+ ActiveAdmin strictestAdmin =
+ getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+ int max = strictestAdmin.maximumFailedPasswordsForWipe;
if (max > 0 && policy.mFailedPasswordAttempts >= max) {
- wipeDeviceOrUserLocked(0, userHandle);
+ // Wipe the user/profile associated with the policy that was violated. This
+ // is not necessarily calling user: if the policy that fired was from a
+ // managed profile rather than the main user profile, we wipe former only.
+ wipeDeviceOrUserLocked(0, strictestAdmin.getUserHandle().getIdentifier());
}
sendAdminCommandToSelfAndProfilesLocked(
DeviceAdminReceiver.ACTION_PASSWORD_FAILED,