Loading core/java/android/app/admin/DeviceAdminInfo.java +15 −22 Original line number Diff line number Diff line Loading @@ -74,12 +74,10 @@ public final class DeviceAdminInfo implements Parcelable { * that the user can select, via {@link DevicePolicyManager#setPasswordQuality} * and {@link DevicePolicyManager#setPasswordMinimumLength}. * * <p>To control this policy, the device admin must have a "limit-password" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to enforce constraints on user * passwords. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "limit-password" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy only affects the primary user and its profiles, * but not any secondary users on the device. */ public static final int USES_POLICY_LIMIT_PASSWORD = 0; Loading Loading @@ -139,11 +137,10 @@ public final class DeviceAdminInfo implements Parcelable { * A type of policy that this device admin can use: force the user to * change their password after an administrator-defined time limit. * * <p>To control this policy, the device admin must have an "expire-password" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to enforce password expiry. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have an "expire-password" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy only affects the primary user and its profiles, * but not any secondary users on the device. */ public static final int USES_POLICY_EXPIRE_PASSWORD = 6; Loading @@ -158,23 +155,19 @@ public final class DeviceAdminInfo implements Parcelable { /** * A type of policy that this device admin can use: disables use of all device cameras. * * <p>To control this policy, the device admin must have a "disable-camera" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to disable use of the camera. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "disable-camera" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy affects all users on the device. */ public static final int USES_POLICY_DISABLE_CAMERA = 8; /** * A type of policy that this device admin can use: disables use of keyguard features. * * <p>To control this policy, the device admin must have a "disable-keyguard-features" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to disable use of keyguard * features. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "disable-keyguard-features" tag in the "uses-policies" section of its * meta-data. If used by a device owner, the policy only affects the primary user and * its profiles, but not any secondary users on the device. */ public static final int USES_POLICY_DISABLE_KEYGUARD_FEATURES = 9; Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +19 −1 Original line number Diff line number Diff line Loading @@ -377,6 +377,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private static final Set<String> GLOBAL_SETTINGS_WHITELIST; private static final Set<String> GLOBAL_SETTINGS_DEPRECATED; private static final Set<String> SYSTEM_SETTINGS_WHITELIST; private static final Set<Integer> DA_DISALLOWED_POLICIES; static { SECURE_SETTINGS_WHITELIST = new ArraySet<>(); SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD); Loading Loading @@ -408,6 +409,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_OFF_TIMEOUT); DA_DISALLOWED_POLICIES = new ArraySet<>(); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); } /** Loading Loading @@ -2607,6 +2614,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final int userId = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userId); ActiveAdmin admin = policy.mAdminMap.get(who); final boolean isDeviceOwner = isDeviceOwner(admin.info.getComponent(), userId); final boolean isProfileOwner = isProfileOwner(admin.info.getComponent(), userId); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the device"); Loading @@ -2615,6 +2625,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the profile"); } if (DA_DISALLOWED_POLICIES.contains(reqPolicy) && !isDeviceOwner && !isProfileOwner) { throw new SecurityException("Admin " + admin.info.getComponent() + " is not a device owner or profile owner, so may not use policy: " + admin.info.getTagForPolicy(reqPolicy)); } throw new SecurityException("Admin " + admin.info.getComponent() + " did not specify uses-policy for: " + admin.info.getTagForPolicy(reqPolicy)); Loading Loading @@ -2694,7 +2709,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // DO always has the PO power. return ownsDevice || ownsProfile; } else { return admin.info.usesPolicy(reqPolicy); boolean allowedToUsePolicy = ownsDevice || ownsProfile || !DA_DISALLOWED_POLICIES.contains(reqPolicy) || getTargetSdk(admin.info.getPackageName(), userId) < Build.VERSION_CODES.Q; return allowedToUsePolicy && admin.info.usesPolicy(reqPolicy); } } Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +26 −15 Original line number Diff line number Diff line Loading @@ -1713,24 +1713,35 @@ public class DevicePolicyManagerTest extends DpmTestBase { UserManager.DISALLOW_ADD_USER), eq(true), eq(CAMERA_DISABLED_GLOBALLY)); reset(getServices().userManagerInternal); } // Set up another DA and let it disable camera. Now DISALLOW_CAMERA will only be applied // locally. dpm.setCameraDisabled(admin1, false); reset(getServices().userManagerInternal); public void testDaDisallowedPolicies_SecurityException() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM); dpm.setCameraDisabled(admin2, true); setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, UserManager.DISALLOW_ADD_USER), eq(true), eq(CAMERA_DISABLED_LOCALLY)); reset(getServices().userManagerInternal); // TODO Make sure restrictions are written to the file. boolean originalCameraDisabled = dpm.getCameraDisabled(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setCameraDisabled(admin1, true)); assertEquals(originalCameraDisabled, dpm.getCameraDisabled(admin1)); int originalKeyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setKeyguardDisabledFeatures(admin1, DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)); assertEquals(originalKeyguardDisabledFeatures, dpm.getKeyguardDisabledFeatures(admin1)); long originalPasswordExpirationTimeout = dpm.getPasswordExpirationTimeout(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setPasswordExpirationTimeout(admin1, 1234)); assertEquals(originalPasswordExpirationTimeout, dpm.getPasswordExpirationTimeout(admin1)); int originalPasswordQuality = dpm.getPasswordQuality(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)); assertEquals(originalPasswordQuality, dpm.getPasswordQuality(admin1)); } public void testSetUserRestriction_asPo() { Loading Loading
core/java/android/app/admin/DeviceAdminInfo.java +15 −22 Original line number Diff line number Diff line Loading @@ -74,12 +74,10 @@ public final class DeviceAdminInfo implements Parcelable { * that the user can select, via {@link DevicePolicyManager#setPasswordQuality} * and {@link DevicePolicyManager#setPasswordMinimumLength}. * * <p>To control this policy, the device admin must have a "limit-password" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to enforce constraints on user * passwords. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "limit-password" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy only affects the primary user and its profiles, * but not any secondary users on the device. */ public static final int USES_POLICY_LIMIT_PASSWORD = 0; Loading Loading @@ -139,11 +137,10 @@ public final class DeviceAdminInfo implements Parcelable { * A type of policy that this device admin can use: force the user to * change their password after an administrator-defined time limit. * * <p>To control this policy, the device admin must have an "expire-password" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to enforce password expiry. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have an "expire-password" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy only affects the primary user and its profiles, * but not any secondary users on the device. */ public static final int USES_POLICY_EXPIRE_PASSWORD = 6; Loading @@ -158,23 +155,19 @@ public final class DeviceAdminInfo implements Parcelable { /** * A type of policy that this device admin can use: disables use of all device cameras. * * <p>To control this policy, the device admin must have a "disable-camera" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to disable use of the camera. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "disable-camera" tag in the "uses-policies" section of its meta-data. * If used by a device owner, the policy affects all users on the device. */ public static final int USES_POLICY_DISABLE_CAMERA = 8; /** * A type of policy that this device admin can use: disables use of keyguard features. * * <p>To control this policy, the device admin must have a "disable-keyguard-features" * tag in the "uses-policies" section of its meta-data. * * <p>This policy is deprecated for use by a device admin. In future releases, it will * only be possible for a device owner or profile owner to disable use of keyguard * features. * <p>To control this policy, the device admin must be a device owner or profile owner, * and must have a "disable-keyguard-features" tag in the "uses-policies" section of its * meta-data. If used by a device owner, the policy only affects the primary user and * its profiles, but not any secondary users on the device. */ public static final int USES_POLICY_DISABLE_KEYGUARD_FEATURES = 9; Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +19 −1 Original line number Diff line number Diff line Loading @@ -377,6 +377,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private static final Set<String> GLOBAL_SETTINGS_WHITELIST; private static final Set<String> GLOBAL_SETTINGS_DEPRECATED; private static final Set<String> SYSTEM_SETTINGS_WHITELIST; private static final Set<Integer> DA_DISALLOWED_POLICIES; static { SECURE_SETTINGS_WHITELIST = new ArraySet<>(); SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD); Loading Loading @@ -408,6 +409,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_OFF_TIMEOUT); DA_DISALLOWED_POLICIES = new ArraySet<>(); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); } /** Loading Loading @@ -2607,6 +2614,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final int userId = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userId); ActiveAdmin admin = policy.mAdminMap.get(who); final boolean isDeviceOwner = isDeviceOwner(admin.info.getComponent(), userId); final boolean isProfileOwner = isProfileOwner(admin.info.getComponent(), userId); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the device"); Loading @@ -2615,6 +2625,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the profile"); } if (DA_DISALLOWED_POLICIES.contains(reqPolicy) && !isDeviceOwner && !isProfileOwner) { throw new SecurityException("Admin " + admin.info.getComponent() + " is not a device owner or profile owner, so may not use policy: " + admin.info.getTagForPolicy(reqPolicy)); } throw new SecurityException("Admin " + admin.info.getComponent() + " did not specify uses-policy for: " + admin.info.getTagForPolicy(reqPolicy)); Loading Loading @@ -2694,7 +2709,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // DO always has the PO power. return ownsDevice || ownsProfile; } else { return admin.info.usesPolicy(reqPolicy); boolean allowedToUsePolicy = ownsDevice || ownsProfile || !DA_DISALLOWED_POLICIES.contains(reqPolicy) || getTargetSdk(admin.info.getPackageName(), userId) < Build.VERSION_CODES.Q; return allowedToUsePolicy && admin.info.usesPolicy(reqPolicy); } } Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +26 −15 Original line number Diff line number Diff line Loading @@ -1713,24 +1713,35 @@ public class DevicePolicyManagerTest extends DpmTestBase { UserManager.DISALLOW_ADD_USER), eq(true), eq(CAMERA_DISABLED_GLOBALLY)); reset(getServices().userManagerInternal); } // Set up another DA and let it disable camera. Now DISALLOW_CAMERA will only be applied // locally. dpm.setCameraDisabled(admin1, false); reset(getServices().userManagerInternal); public void testDaDisallowedPolicies_SecurityException() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM); dpm.setCameraDisabled(admin2, true); setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, UserManager.DISALLOW_ADD_USER), eq(true), eq(CAMERA_DISABLED_LOCALLY)); reset(getServices().userManagerInternal); // TODO Make sure restrictions are written to the file. boolean originalCameraDisabled = dpm.getCameraDisabled(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setCameraDisabled(admin1, true)); assertEquals(originalCameraDisabled, dpm.getCameraDisabled(admin1)); int originalKeyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setKeyguardDisabledFeatures(admin1, DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)); assertEquals(originalKeyguardDisabledFeatures, dpm.getKeyguardDisabledFeatures(admin1)); long originalPasswordExpirationTimeout = dpm.getPasswordExpirationTimeout(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setPasswordExpirationTimeout(admin1, 1234)); assertEquals(originalPasswordExpirationTimeout, dpm.getPasswordExpirationTimeout(admin1)); int originalPasswordQuality = dpm.getPasswordQuality(admin1); assertExpectException(SecurityException.class, /* messageRegex= */ null, () -> dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)); assertEquals(originalPasswordQuality, dpm.getPasswordQuality(admin1)); } public void testSetUserRestriction_asPo() { Loading