diff options
3 files changed, 100 insertions, 66 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index f111a9541303..6cb577eafc2f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -699,7 +699,7 @@ final class DevicePolicyEngine { if (policyDefinition.isGlobalOnlyPolicy()) { throw new IllegalArgumentException(policyDefinition.getPolicyKey() + " is a global only" - + "policy."); + + " policy."); } if (!mLocalPolicies.contains(userId)) { @@ -724,7 +724,7 @@ final class DevicePolicyEngine { private <V> PolicyState<V> getGlobalPolicyStateLocked(PolicyDefinition<V> policyDefinition) { if (policyDefinition.isLocalOnlyPolicy()) { throw new IllegalArgumentException(policyDefinition.getPolicyKey() + " is a local only" - + "policy."); + + " policy."); } if (!mGlobalPolicies.containsKey(policyDefinition.getPolicyKey())) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 94e6e732dd76..b8d9e0e870f9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -441,7 +441,6 @@ import android.util.AtomicFile; import android.util.DebugUtils; import android.util.IndentingPrintWriter; import android.util.IntArray; -import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; @@ -13131,19 +13130,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int userId = caller.getUserId(); - if (!UserRestrictionsUtils.isValidRestriction(key)) { - return; - } checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION); if (isPolicyEngineForFinanceFlagEnabled()) { - int affectedUserId = parent ? getProfileParentId(userId) : userId; - EnforcingAdmin admin = enforcePermissionForUserRestriction( - who, - key, - caller.getPackageName(), - affectedUserId); - if (mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, callerPackage, userId)) { + if (!isDeviceOwner(caller) && !isProfileOwner(caller)) { + if (!mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, callerPackage, userId)) { + throw new IllegalStateException("Calling package is not targeting Android U."); + } + if (!UserRestrictionsUtils.isValidRestriction(key)) { + throw new IllegalArgumentException("Invalid restriction key: " + key); + } + int affectedUserId = parent ? getProfileParentId(userId) : userId; + EnforcingAdmin admin = enforcePermissionForUserRestriction( + who, + key, + caller.getPackageName(), + affectedUserId); PolicyDefinition<Boolean> policyDefinition = PolicyDefinition.getPolicyDefinitionForUserRestriction(key); if (enabledFromThisOwner) { @@ -13155,7 +13157,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setGlobalUserRestrictionInternal(admin, key, /* enabled= */ false); } if (!policyDefinition.isGlobalOnlyPolicy()) { - setLocalUserRestrictionInternal(admin, key, /* enabled= */ false, userId); + setLocalUserRestrictionInternal(admin, key, /* enabled= */ false, + userId); int parentUserId = getProfileParentId(userId); if (parentUserId != userId) { @@ -13165,49 +13168,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } else { + if (!UserRestrictionsUtils.isValidRestriction(key)) { + return; + } + Objects.requireNonNull(who, "ComponentName is null"); + EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage); + checkAdminCanSetRestriction(caller, parent, key); setBackwardCompatibleUserRestriction( caller, admin, key, enabledFromThisOwner, parent); } } else { - Objects.requireNonNull(who, "ComponentName is null"); - if (parent) { - Preconditions.checkCallAuthorization( - isProfileOwnerOfOrganizationOwnedDevice(caller)); - } else { - Preconditions.checkCallAuthorization( - isDeviceOwner(caller) || isProfileOwner(caller)); - } - synchronized (getLockObject()) { - if (isDefaultDeviceOwner(caller)) { - if (!UserRestrictionsUtils.canDeviceOwnerChange(key)) { - throw new SecurityException("Device owner cannot set user restriction " - + key); - } - Preconditions.checkArgument(!parent, - "Cannot use the parent instance in Device Owner mode"); - } else if (isFinancedDeviceOwner(caller)) { - if (!UserRestrictionsUtils.canFinancedDeviceOwnerChange(key)) { - throw new SecurityException("Cannot set user restriction " + key - + " when managing a financed device"); - } - Preconditions.checkArgument(!parent, - "Cannot use the parent instance in Financed Device Owner" - + " mode"); - } else { - boolean profileOwnerCanChangeOnItself = !parent - && UserRestrictionsUtils.canProfileOwnerChange( - key, userId == getMainUserId()); - boolean orgOwnedProfileOwnerCanChangeGlobally = parent - && isProfileOwnerOfOrganizationOwnedDevice(caller) - && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange( - key); - - if (!profileOwnerCanChangeOnItself && !orgOwnedProfileOwnerCanChangeGlobally) { - throw new SecurityException("Profile owner cannot set user restriction " - + key); - } - } + if (!UserRestrictionsUtils.isValidRestriction(key)) { + return; } + Objects.requireNonNull(who, "ComponentName is null"); + checkAdminCanSetRestriction(caller, parent, key); synchronized (getLockObject()) { final ActiveAdmin activeAdmin = getParentOfAdminIfRequired( getProfileOwnerOrDeviceOwnerLocked(userId), parent); @@ -13224,6 +13199,46 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { logUserRestrictionCall(key, enabledFromThisOwner, parent, caller); } + private void checkAdminCanSetRestriction(CallerIdentity caller, boolean parent, String key) { + if (parent) { + Preconditions.checkCallAuthorization( + isProfileOwnerOfOrganizationOwnedDevice(caller)); + } else { + Preconditions.checkCallAuthorization( + isDeviceOwner(caller) || isProfileOwner(caller)); + } + synchronized (getLockObject()) { + if (isDefaultDeviceOwner(caller)) { + if (!UserRestrictionsUtils.canDeviceOwnerChange(key)) { + throw new SecurityException("Device owner cannot set user restriction " + + key); + } + Preconditions.checkArgument(!parent, + "Cannot use the parent instance in Device Owner mode"); + } else if (isFinancedDeviceOwner(caller)) { + if (!UserRestrictionsUtils.canFinancedDeviceOwnerChange(key)) { + throw new SecurityException("Cannot set user restriction " + key + + " when managing a financed device"); + } + Preconditions.checkArgument(!parent, + "Cannot use the parent instance in Financed Device Owner" + + " mode"); + } else { + boolean profileOwnerCanChangeOnItself = !parent + && UserRestrictionsUtils.canProfileOwnerChange( + key, caller.getUserId() == getMainUserId()); + boolean orgOwnedProfileOwnerCanChangeGlobally = parent + && isProfileOwnerOfOrganizationOwnedDevice(caller) + && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange( + key); + + if (!profileOwnerCanChangeOnItself && !orgOwnedProfileOwnerCanChangeGlobally) { + throw new SecurityException("Profile owner cannot set user restriction " + + key); + } + } + } + } private void setBackwardCompatibleUserRestriction( CallerIdentity caller, EnforcingAdmin admin, String key, boolean enabled, boolean parent) { @@ -13252,20 +13267,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setUserRestrictionGlobally(String callerPackage, String key) { final CallerIdentity caller = getCallerIdentity(callerPackage); - if (!UserRestrictionsUtils.isValidRestriction(key)) { - return; - } checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION); if (!isPolicyEngineForFinanceFlagEnabled()) { throw new IllegalStateException("Feature flag is not enabled."); } - + if (isDeviceOwner(caller) || isProfileOwner(caller)) { + throw new IllegalStateException("Admins are not allowed to call this API."); + } if (!mInjector.isChangeEnabled( ENABLE_COEXISTENCE_CHANGE, callerPackage, caller.getUserId())) { throw new IllegalStateException("Calling package is not targeting Android U."); } + if (!UserRestrictionsUtils.isValidRestriction(key)) { + throw new IllegalArgumentException("Invalid restriction key: " + key); + } EnforcingAdmin admin = enforcePermissionForUserRestriction( /* who= */ null, @@ -13416,14 +13433,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int targetUserId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId(); EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage); - Bundle restrictions = getUserRestrictionsFromPolicyEngine(admin, targetUserId); - // Add global restrictions set by the admin as well if admin is not targeting Android U. - if (!mInjector.isChangeEnabled( - ENABLE_COEXISTENCE_CHANGE, callerPackage, caller.getUserId())) { + if (isDeviceOwner(caller) || isProfileOwner(caller)) { + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) + || isFinancedDeviceOwner(caller) + || isProfileOwner(caller) + || (parent && isProfileOwnerOfOrganizationOwnedDevice(caller))); + + Bundle restrictions = getUserRestrictionsFromPolicyEngine(admin, targetUserId); + // Add global restrictions set by the admin as well. restrictions.putAll( getUserRestrictionsFromPolicyEngine(admin, UserHandle.USER_ALL)); + return restrictions; + } else { + if (!mInjector.isChangeEnabled( + ENABLE_COEXISTENCE_CHANGE, callerPackage, caller.getUserId())) { + throw new IllegalStateException("Calling package is not targeting Android U."); + } + return getUserRestrictionsFromPolicyEngine(admin, targetUserId); } - return restrictions; } else { Objects.requireNonNull(who, "ComponentName is null"); Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index 509a66b4f8f7..8c2468af1146 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -284,6 +284,7 @@ final class PolicyDefinition<V> { private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>(); private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>(); + // TODO(b/277218360): Revisit policies that should be marked as global-only. static { POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMISSION_GRANT_POLICY, @@ -312,8 +313,9 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put( UserManager.DISALLOW_WIFI_TETHERING, POLICY_FLAG_GLOBAL_ONLY_POLICY); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_GRANT_ADMIN, /* flags= */ 0); + // TODO: set as global only once we get rid of the mapping USER_RESTRICTION_FLAGS.put( - UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, POLICY_FLAG_GLOBAL_ONLY_POLICY); + UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, /* flags= */ 0); USER_RESTRICTION_FLAGS.put( UserManager.DISALLOW_WIFI_DIRECT, POLICY_FLAG_GLOBAL_ONLY_POLICY); USER_RESTRICTION_FLAGS.put( @@ -333,8 +335,10 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_BLUETOOTH, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_BLUETOOTH, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_BLUETOOTH_SHARING, /* flags= */ 0); + // This effectively always applies globally, but it can be set on the profile + // parent, check the javadocs on the restriction for more info. USER_RESTRICTION_FLAGS.put( - UserManager.DISALLOW_USB_FILE_TRANSFER, POLICY_FLAG_GLOBAL_ONLY_POLICY); + UserManager.DISALLOW_USB_FILE_TRANSFER, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_CREDENTIALS, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_REMOVE_USER, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, /* flags= */ 0); @@ -344,8 +348,10 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_DATE_TIME, /* flags= */ 0); USER_RESTRICTION_FLAGS.put( UserManager.DISALLOW_CONFIG_TETHERING, /* flags= */ 0); + // This effectively always applies globally, but it can be set on the profile + // parent, check the javadocs on the restriction for more info. USER_RESTRICTION_FLAGS.put( - UserManager.DISALLOW_NETWORK_RESET, POLICY_FLAG_GLOBAL_ONLY_POLICY); + UserManager.DISALLOW_NETWORK_RESET, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_FACTORY_RESET, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_USER, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_MANAGED_PROFILE, /* flags= */ 0); @@ -376,8 +382,7 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_UNMUTE_DEVICE, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_DATA_ROAMING, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_SET_USER_ICON, /* flags= */ 0); - // TODO: double check flags - USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_OEM_UNLOCK, POLICY_FLAG_GLOBAL_ONLY_POLICY); + USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_OEM_UNLOCK, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_UNIFIED_PASSWORD, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_AUTOFILL, /* flags= */ 0); @@ -390,6 +395,7 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put( UserManager.DISALLOW_CONFIG_PRIVATE_DNS, POLICY_FLAG_GLOBAL_ONLY_POLICY); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MICROPHONE_TOGGLE, /* flags= */ 0); + // TODO: According the UserRestrictionsUtils, this is global only, need to confirm. USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CAMERA_TOGGLE, /* flags= */ 0); // TODO: check if its global only USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_BIOMETRIC, /* flags= */ 0); |