Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a521deb9 authored by Eric Sandness's avatar Eric Sandness Committed by Android (Google) Code Review
Browse files

Merge "Block Policies From Device Admin Targetting Q"

parents 6a43904b ca5969d6
Loading
Loading
Loading
Loading
+15 −22
Original line number Diff line number Diff line
@@ -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;

@@ -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;

@@ -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;

+19 −1
Original line number Diff line number Diff line
@@ -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);
@@ -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);
    }
    /**
@@ -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");
@@ -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));
@@ -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);
        }
    }
+26 −15
Original line number Diff line number Diff line
@@ -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() {