diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f8d457e877fa6..183a1495b075d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2081,9 +2081,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle, boolean parent) { ensureLocked(); if (parent) { - Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( - "You can not call APIs on the parent profile outside a managed profile, " - + "userId = %d", userHandle)); + enforceManagedProfile(userHandle, "call APIs on the parent profile"); } ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin != null && parent) { @@ -2259,7 +2257,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Nullable String permission) throws SecurityException { ensureLocked(); if (parent) { - Preconditions.checkCallingUser(isManagedProfile(getCallerIdentity(who).getUserId())); + enforceManagedProfile(mInjector.userHandleGetCallingUserId(), + "call APIs on the parent profile"); } ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked( who, reqPolicy, permission); @@ -2853,7 +2852,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + enforceManageUsers(); synchronized (getLockObject()) { final DevicePolicyData policy = getUserData(userHandle.getIdentifier()); @@ -4043,13 +4042,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return true; } - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); - - return !isSeparateProfileChallengeEnabled(caller.getUserId()); + final int userId = mInjector.userHandleGetCallingUserId(); + enforceProfileOrDeviceOwner(admin); + enforceManagedProfile(userId, "query unified challenge status"); + return !isSeparateProfileChallengeEnabled(userId); } @Override @@ -4061,9 +4057,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( - "can not call APIs refering to the parent profile outside a managed profile, " - + "userId = %d", userHandle)); + enforceManagedProfile(userHandle, "call APIs refering to the parent profile"); synchronized (getLockObject()) { final int targetUser = getProfileParentId(userHandle); @@ -4085,9 +4079,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - Preconditions.checkCallAuthorization(!isManagedProfile(userHandle), String.format( - "You can not check password sufficiency for a managed profile, userId = %d", - userHandle)); + enforceNotManagedProfile(userHandle, "check password sufficiency"); enforceUserUnlocked(userHandle); synchronized (getLockObject()) { @@ -4643,9 +4635,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) { return; } - final CallerIdentity caller = getCallerIdentity(); - final int callingUserId = caller.getUserId(); + final int callingUserId = mInjector.userHandleGetCallingUserId(); ComponentName adminComponent = null; synchronized (getLockObject()) { // Make sure the caller has any active admin with the right policy or @@ -4662,13 +4653,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // For Profile Owners only, callers with only permission not allowed. if ((flags & DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY) != 0) { // Evict key - Preconditions.checkCallingUser(isManagedProfile(callingUserId)); - Preconditions.checkArgument(!parent, - "Cannot set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY for the parent"); + enforceManagedProfile( + callingUserId, "set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY"); if (!isProfileOwner(adminComponent, callingUserId)) { throw new SecurityException("Only profile owner admins can set " + "FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY"); } + if (parent) { + throw new IllegalArgumentException( + "Cannot set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY for the parent"); + } if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) { throw new UnsupportedOperationException( "FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY only applies to FBE devices"); @@ -4713,19 +4707,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void enforceCanManageCaCerts(ComponentName who, String callerPackage) { - final CallerIdentity caller = getCallerIdentity(who, callerPackage); - Preconditions.checkCallAuthorization(canManageCaCerts(caller)); + if (who == null) { + if (!isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(), + DELEGATION_CERT_INSTALL)) { + mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null); + } + } else { + enforceProfileOrDeviceOwner(who); + } } - private boolean canManageCaCerts(CallerIdentity caller) { - return isDeviceOwner(caller) || isProfileOwner(caller) || isCallerDelegate(caller, - DELEGATION_CERT_INSTALL) || hasCallingOrSelfPermission(MANAGE_CA_CERTIFICATES); + private void enforceProfileOrDeviceOwner(ComponentName who) { + synchronized (getLockObject()) { + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + } + } + + private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) { + if (hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)) { + return; + } + enforceProfileOrDeviceOwner(who); } @Override public boolean approveCaCert(String alias, int userId, boolean approval) { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { Set certs = getUserData(userId).mAcceptedCaCertificates; boolean changed = (approval ? certs.add(alias) : certs.remove(alias)); @@ -4740,8 +4747,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isCaCertApproved(String alias, int userId) { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { return getUserData(userId).mAcceptedCaCertificates.contains(alias); } @@ -4766,20 +4772,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public boolean installCaCert(ComponentName admin, String callerPackage, byte[] certBuffer) { + public boolean installCaCert(ComponentName admin, String callerPackage, byte[] certBuffer) + throws RemoteException { if (!mHasFeature) { return false; } - final CallerIdentity caller = getCallerIdentity(admin, callerPackage); - Preconditions.checkCallAuthorization(canManageCaCerts(caller)); + enforceCanManageCaCerts(admin, callerPackage); + final UserHandle userHandle = mInjector.binderGetCallingUserHandle(); final String alias = mInjector.binderWithCleanCallingIdentity(() -> { - String installedAlias = mCertificateMonitor.installCaCert( - caller.getUserHandle(), certBuffer); + String installedAlias = mCertificateMonitor.installCaCert(userHandle, certBuffer); + final boolean isDelegate = (admin == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.INSTALL_CA_CERT) - .setAdmin(caller.getPackageName()) - .setBoolean(/* isDelegate */ admin == null) + .setAdmin(callerPackage) + .setBoolean(isDelegate) .write(); return installedAlias; }); @@ -4790,8 +4797,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } synchronized (getLockObject()) { - getUserData(caller.getUserId()).mOwnerInstalledCaCerts.add(alias); - saveSettingsLocked(caller.getUserId()); + getUserData(userHandle.getIdentifier()).mOwnerInstalledCaCerts.add(alias); + saveSettingsLocked(userHandle.getIdentifier()); } return true; } @@ -4801,22 +4808,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - final CallerIdentity caller = getCallerIdentity(admin, callerPackage); - Preconditions.checkCallAuthorization(canManageCaCerts(caller)); + enforceCanManageCaCerts(admin, callerPackage); + final int userId = mInjector.userHandleGetCallingUserId(); mInjector.binderWithCleanCallingIdentity(() -> { - mCertificateMonitor.uninstallCaCerts(caller.getUserHandle(), aliases); + mCertificateMonitor.uninstallCaCerts(UserHandle.of(userId), aliases); + final boolean isDelegate = (admin == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.UNINSTALL_CA_CERTS) - .setAdmin(caller.getPackageName()) - .setBoolean(/* isDelegate */ admin == null) + .setAdmin(callerPackage) + .setBoolean(isDelegate) .write(); }); synchronized (getLockObject()) { - if (getUserData(caller.getUserId()).mOwnerInstalledCaCerts.removeAll( - Arrays.asList(aliases))) { - saveSettingsLocked(caller.getUserId()); + if (getUserData(userId).mOwnerInstalledCaCerts.removeAll(Arrays.asList(aliases))) { + saveSettingsLocked(userId); } } } @@ -5606,10 +5613,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public boolean setAlwaysOnVpnPackage(ComponentName who, String vpnPackage, boolean lockdown, List lockdownWhitelist) throws SecurityException { - Objects.requireNonNull(who, "ComponentName is null"); - + enforceProfileOrDeviceOwner(who); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); final int userId = caller.getUserId(); mInjector.binderWithCleanCallingIdentity(() -> { @@ -5635,7 +5640,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_ALWAYS_ON_VPN_PACKAGE) - .setAdmin(caller.getComponentName()) + .setAdmin(who) .setStrings(vpnPackage) .setBoolean(lockdown) .setInt(lockdownWhitelist != null ? lockdownWhitelist.size() : 0) @@ -5655,14 +5660,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public String getAlwaysOnVpnPackage(ComponentName admin) throws SecurityException { - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); + final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser( - caller.getUserId())); + () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser(userId)); } @Override @@ -5676,14 +5678,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isAlwaysOnVpnLockdownEnabled(ComponentName admin) throws SecurityException { - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller) - || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)); + enforceNetworkStackOrProfileOrDeviceOwner(admin); + final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(caller.getUserId())); + () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(userId)); } @Override @@ -5698,14 +5697,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List getAlwaysOnVpnLockdownWhitelist(ComponentName admin) throws SecurityException { - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); + final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist( - caller.getUserId())); + () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist(userId)); } private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) { @@ -5994,13 +5990,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return; } + enforceSystemCaller("report password change"); - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(isSystemUid(caller)); // Managed Profile password can only be changed when it has a separate challenge. if (!isSeparateProfileChallengeEnabled(userId)) { - Preconditions.checkCallAuthorization(!isManagedProfile(userId), String.format("You can " - + "not set the active password for a managed profile, userId = %d", userId)); + enforceNotManagedProfile(userId, "set the active password"); } DevicePolicyData policy = getUserData(userId); @@ -6053,9 +6047,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); if (!isSeparateProfileChallengeEnabled(userHandle)) { - Preconditions.checkCallAuthorization(!isManagedProfile(userHandle), String.format( - "You can not report failed password attempt if separate profile challenge is " - + "not in place for a managed profile, userId = %d", userHandle)); + enforceNotManagedProfile(userHandle, + "report failed password attempt if separate profile challenge is not in place"); } boolean wipeData = false; @@ -7284,7 +7277,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } if (!callingUserOnly) { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + enforceManageUsers(); } synchronized (getLockObject()) { if (!mOwners.hasDeviceOwner()) { @@ -7303,8 +7296,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return UserHandle.USER_NULL; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { return mOwners.hasDeviceOwner() ? mOwners.getDeviceOwnerUserId() : UserHandle.USER_NULL; } @@ -7319,8 +7311,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { if (!mOwners.hasDeviceOwner()) { return null; @@ -7545,10 +7536,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallingUser(!isManagedProfile(caller.getUserId())); - - final int userId = caller.getUserId(); + final int userId = mInjector.userHandleGetCallingUserId(); + enforceNotManagedProfile(userId, "clear profile owner"); enforceUserUnlocked(userId); synchronized (getLockObject()) { // Check if this is the profile owner who is calling @@ -7665,10 +7654,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return DevicePolicyManager.STATE_USER_UNMANAGED; } - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(canManageUsers(caller)); - - return getUserProvisioningState(caller.getUserId()); + enforceManageUsers(); + int userHandle = mInjector.userHandleGetCallingUserId(); + return getUserProvisioningState(userHandle); } private int getUserProvisioningState(int userHandle) { @@ -7706,8 +7694,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } transitionCheckNeeded = false; } else { - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + // For all other cases, caller must have MANAGE_PROFILE_AND_DEVICE_OWNERS. + enforceCanManageProfileAndDeviceOwners(); } final DevicePolicyData policyData = getUserData(userHandle); @@ -7762,13 +7750,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isProfileOwner(caller)); - Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); - synchronized (getLockObject()) { - final int userId = caller.getUserId(); + // Check if this is the profile owner who is calling + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + final int userId = UserHandle.getCallingUserId(); + enforceManagedProfile(userId, "enable the profile"); // Check if the profile is already enabled. UserInfo managedProfile = getUserInfo(userId); if (managedProfile.isEnabled()) { @@ -7794,15 +7780,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setProfileName(ComponentName who, String profileName) { Objects.requireNonNull(who, "ComponentName is null"); + enforceProfileOrDeviceOwner(who); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - + final int userId = UserHandle.getCallingUserId(); mInjector.binderWithCleanCallingIdentity(() -> { - mUserManager.setUserName(caller.getUserId(), profileName); + mUserManager.setUserName(userId, profileName); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PROFILE_NAME) - .setAdmin(caller.getComponentName()) + .setAdmin(who) .write(); }); } @@ -7911,8 +7896,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); ComponentName profileOwner = getProfileOwner(userHandle); if (profileOwner == null) { return null; @@ -8084,8 +8068,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } return; } - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + enforceCanManageProfileAndDeviceOwners(); if ((mIsWatch || hasUserSetupCompleted(userHandle))) { if (!isCallerWithSystemUid()) { @@ -8121,8 +8104,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @UserIdInt int userId, boolean hasIncompatibleAccountsOrNonAdb) { if (!isAdb()) { - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + enforceCanManageProfileAndDeviceOwners(); } final int code = checkDeviceOwnerProvisioningPreConditionLocked( @@ -8176,9 +8158,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private boolean canManageUsers(CallerIdentity caller) { - return isSystemUid(caller) || isRootUid(caller) - || hasCallingOrSelfPermission(permission.MANAGE_USERS); + private void enforceManageUsers() { + final int callingUid = mInjector.binderGetCallingUid(); + if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); + } } private boolean hasCallingPermission(String permission) { @@ -8208,6 +8192,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS); } + private void enforceManagedProfile(int userId, String message) { + if (!isManagedProfile(userId)) { + throw new SecurityException(String.format( + "You can not %s outside a managed profile, userId = %d", message, userId)); + } + } + + private void enforceNotManagedProfile(int userId, String message) { + if (isManagedProfile(userId)) { + throw new SecurityException(String.format( + "You can not %s for a managed profile, userId = %d", message, userId)); + } + } + private void enforceDeviceOwnerOrManageUsers() { synchronized (getLockObject()) { if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, @@ -8215,7 +8213,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + enforceManageUsers(); } private void enforceProfileOwnerOrSystemUser() { @@ -8816,7 +8814,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -8831,8 +8828,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { List result = null; // If we have multiple profiles we return the intersection of the @@ -8917,7 +8913,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -8959,7 +8954,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -8971,13 +8965,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List getPermittedInputMethodsForCurrentUser() { - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(canManageUsers(caller)); + enforceManageUsers(); + final int callingUserId = mInjector.userHandleGetCallingUserId(); synchronized (getLockObject()) { List result = null; // Only device or profile owners can have permitted lists set. - DevicePolicyData policy = getUserDataUnchecked(caller.getUserId()); + DevicePolicyData policy = getUserDataUnchecked(callingUserId); for (int i = 0; i < policy.mAdminList.size(); i++) { ActiveAdmin admin = policy.mAdminList.get(i); List fromAdmin = admin.permittedInputMethods; @@ -8992,8 +8986,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // If we have a permitted list add all system input methods. if (result != null) { - List imes = InputMethodManagerInternal - .get().getInputMethodListAsUser(caller.getUserId()); + List imes = + InputMethodManagerInternal.get().getInputMethodListAsUser(callingUserId); if (imes != null) { for (InputMethodInfo ime : imes) { ServiceInfo serviceInfo = ime.getServiceInfo(); @@ -9437,12 +9431,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isEphemeralUser(ComponentName who) { Objects.requireNonNull(who, "ComponentName is null"); + enforceProfileOrDeviceOwner(who); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - + final int callingUserId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getUserManager().isUserEphemeral(caller.getUserId())); + () -> mInjector.getUserManager().isUserEphemeral(callingUserId)); } @Override @@ -10170,7 +10163,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -10194,7 +10186,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -10217,23 +10208,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setSecondaryLockscreenEnabled(ComponentName who, boolean enabled) { - Objects.requireNonNull(who, "ComponentName is null"); - - // Check can set secondary lockscreen enabled - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - Preconditions.checkCallAuthorization(!isManagedProfile(caller.getUserId()), - String.format("User %d is not allowed to call setSecondaryLockscreenEnabled", - caller.getUserId())); - // Allow testOnly admins to bypass supervision config requirement. - Preconditions.checkCallAuthorization(isAdminTestOnlyLocked(who, caller.getUserId()) - || isDefaultSupervisor(caller), String.format("Admin %s is not the " - + "default supervision component", caller.getComponentName())); - + enforceCanSetSecondaryLockscreenEnabled(who); synchronized (getLockObject()) { - DevicePolicyData policy = getUserData(caller.getUserId()); + final int userId = mInjector.userHandleGetCallingUserId(); + DevicePolicyData policy = getUserData(userId); policy.mSecondaryLockscreenEnabled = enabled; - saveSettingsLocked(caller.getUserId()); + saveSettingsLocked(userId); } } @@ -10244,14 +10224,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private boolean isDefaultSupervisor(CallerIdentity caller) { + private void enforceCanSetSecondaryLockscreenEnabled(ComponentName who) { + enforceProfileOrDeviceOwner(who); + final int userId = mInjector.userHandleGetCallingUserId(); + if (isManagedProfile(userId)) { + throw new SecurityException( + "User " + userId + " is not allowed to call setSecondaryLockscreenEnabled"); + } + synchronized (getLockObject()) { + if (isAdminTestOnlyLocked(who, userId)) { + // Allow testOnly admins to bypass supervision config requirement. + return; + } + } + // Only the default supervision app can use this API. final String supervisor = mContext.getResources().getString( com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent); if (supervisor == null) { - return false; + throw new SecurityException("Unable to set secondary lockscreen setting, no " + + "default supervision component defined"); } final ComponentName supervisorComponent = ComponentName.unflattenFromString(supervisor); - return caller.getComponentName().equals(supervisorComponent); + if (!who.equals(supervisorComponent)) { + throw new SecurityException( + "Admin " + who + " is not the default supervision component"); + } } @Override @@ -11591,9 +11588,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public SystemUpdateInfo getPendingSystemUpdate(ComponentName admin) { Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); return mOwners.getSystemUpdateInfo(); } @@ -11784,11 +11779,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public int checkProvisioningPreCondition(String action, String packageName) { - Objects.requireNonNull(packageName, "packageName is null"); - - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); - + Objects.requireNonNull(packageName); + enforceCanManageProfileAndDeviceOwners(); return checkProvisioningPreConditionSkipPermission(action, packageName); } @@ -12049,12 +12041,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isManagedProfile(ComponentName admin) { - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - - return isManagedProfile(caller.getUserId()); + enforceProfileOrDeviceOwner(admin); + return isManagedProfile(mInjector.userHandleGetCallingUserId()); } @Override @@ -12180,10 +12168,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); - + enforceManagedProfile(caller.getUserId(), "set organization color"); synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); admin.organizationColor = color; @@ -12191,7 +12177,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_ORGANIZATION_COLOR) - .setAdmin(caller.getComponentName()) + .setAdmin(who) .write(); } @@ -12204,10 +12190,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId)); - Preconditions.checkCallAuthorization(canManageUsers(caller)); - Preconditions.checkCallAuthorization(isManagedProfile(userId), String.format("You can not " - + "set organization color outside a managed profile, userId = %d", userId)); + enforceManageUsers(); + enforceManagedProfile(userId, "set organization color"); synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerAdminLocked(userId); admin.organizationColor = color; @@ -12221,10 +12206,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return ActiveAdmin.DEF_ORGANIZATION_COLOR; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); - + enforceManagedProfile(caller.getUserId(), "get organization color"); synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); return admin.organizationColor; @@ -12240,9 +12223,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format("You can " - + "not get organization color outside a managed profile, userId = %d", userHandle)); + enforceManagedProfile(userHandle, "get organization color"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); return (profileOwner != null) @@ -12275,10 +12257,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(who, "ComponentName is null"); - final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); - + enforceManagedProfile(caller.getUserId(), "get organization name"); synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); return admin.organizationName; @@ -12306,10 +12286,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( - "You can not get organization name outside a managed profile, userId = %d", - userHandle)); + enforceManagedProfile(userHandle, "get organization name"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); return (profileOwner != null) @@ -12744,6 +12722,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mSecurityLogMonitor.forceLogs(); } + private void enforceCanManageDeviceAdmin() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS, + null); + } + + private void enforceCanManageProfileAndDeviceOwners() { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); + } + private void enforceCallerSystemUserHandle() { final int callingUid = mInjector.binderGetCallingUid(); final int userId = UserHandle.getUserId(callingUid); @@ -12754,11 +12742,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isUninstallInQueue(final String packageName) { - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); - - Pair packageUserPair = new Pair<>(packageName, caller.getUserId()); + enforceCanManageDeviceAdmin(); + final int userId = mInjector.userHandleGetCallingUserId(); + Pair packageUserPair = new Pair<>(packageName, userId); synchronized (getLockObject()) { return mPackagesToRemove.contains(packageUserPair); } @@ -12766,13 +12752,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void uninstallPackageWithActiveAdmins(final String packageName) { + enforceCanManageDeviceAdmin(); Preconditions.checkArgument(!TextUtils.isEmpty(packageName)); - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); + final int userId = mInjector.userHandleGetCallingUserId(); - final int userId = caller.getUserId(); enforceUserUnlocked(userId); final ComponentName profileOwner = getProfileOwner(userId); @@ -12821,9 +12805,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isDeviceProvisioned() { - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(canManageUsers(caller)); - + enforceManageUsers(); synchronized (getLockObject()) { return getUserDataUnchecked(UserHandle.USER_SYSTEM).mUserSetupComplete; } @@ -12907,8 +12889,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setDeviceProvisioningConfigApplied() { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); policy.mDeviceProvisioningConfigApplied = true; @@ -12918,8 +12899,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isDeviceProvisioningConfigApplied() { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); synchronized (getLockObject()) { final DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); return policy.mDeviceProvisioningConfigApplied; @@ -12935,10 +12915,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ @Override public void forceUpdateUserSetupComplete() { - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + enforceCanManageProfileAndDeviceOwners(); enforceCallerSystemUserHandle(); - // no effect if it's called from user build if (!mInjector.isBuildDebuggable()) { return; @@ -12959,28 +12937,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - - toggleBackupServiceActive(caller.getUserId(), enabled); + Objects.requireNonNull(admin); + enforceProfileOrDeviceOwner(admin); + int userId = mInjector.userHandleGetCallingUserId(); + toggleBackupServiceActive(userId, enabled); } @Override public boolean isBackupServiceEnabled(ComponentName admin) { + Objects.requireNonNull(admin); if (!mHasFeature) { return true; } - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); synchronized (getLockObject()) { try { IBackupManager ibm = mInjector.getIBackupManager(); - return ibm != null && ibm.isBackupServiceActive(caller.getUserId()); + return ibm != null && ibm.isBackupServiceActive( + mInjector.userHandleGetCallingUserId()); } catch (RemoteException e) { throw new IllegalStateException("Failed requesting backup service state.", e); } @@ -13292,9 +13267,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } final CallerIdentity caller = getCallerIdentity(admin, packageName); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) - || isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING) - || hasCallingOrSelfPermission(permission.MANAGE_USERS)); + Preconditions.checkCallAuthorization( + isDeviceOwner(caller) || isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING) + || hasCallingOrSelfPermission(permission.MANAGE_USERS)); synchronized (getLockObject()) { return isNetworkLoggingEnabledInternalLocked(); @@ -13562,14 +13537,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(admin, "ComponentName is null"); Objects.requireNonNull(packageName, "packageName is null"); Objects.requireNonNull(callback, "callback is null"); - - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); + final int userId = UserHandle.getCallingUserId(); long ident = mInjector.binderClearCallingIdentity(); try { ActivityManager.getService().clearApplicationUserData(packageName, false, callback, - caller.getUserId()); + userId); } catch(RemoteException re) { // Same process, should not happen. } catch (SecurityException se) { @@ -13622,9 +13596,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List getDisallowedSystemApps(ComponentName admin, int userId, String provisioningAction) throws RemoteException { - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); - + enforceCanManageProfileAndDeviceOwners(); return new ArrayList<>( mOverlayPackagesProvider.getNonRequiredApps(admin, userId, provisioningAction)); } @@ -13635,23 +13607,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - Objects.requireNonNull(admin, "ComponentName is null"); + + Objects.requireNonNull(admin, "Admin cannot be null."); Objects.requireNonNull(target, "Target cannot be null."); - Preconditions.checkArgument(!admin.equals(target), - "Provided administrator and target are the same object."); - Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()), - "Provided administrator and target have the same package name."); - final CallerIdentity caller = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + enforceProfileOrDeviceOwner(admin); - final int callingUserId = caller.getUserId(); + if (admin.equals(target)) { + throw new IllegalArgumentException("Provided administrator and target are " + + "the same object."); + } + + if (admin.getPackageName().equals(target.getPackageName())) { + throw new IllegalArgumentException("Provided administrator and target have " + + "the same package name."); + } + + final int callingUserId = mInjector.userHandleGetCallingUserId(); final DevicePolicyData policy = getUserData(callingUserId); final DeviceAdminInfo incomingDeviceInfo = findAdmin(target, callingUserId, /* throwForMissingPermission= */ true); checkActiveAdminPrecondition(target, incomingDeviceInfo, policy); - Preconditions.checkArgument(incomingDeviceInfo.supportsTransferOwnership(), - "Provided target does not support ownership transfer."); + if (!incomingDeviceInfo.supportsTransferOwnership()) { + throw new IllegalArgumentException("Provided target does not support " + + "ownership transfer."); + } final long id = mInjector.binderClearCallingIdentity(); String ownerType = null; @@ -13674,7 +13654,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (bundle == null) { bundle = new PersistableBundle(); } - if (isProfileOwner(caller)) { + if (isProfileOwner(admin, callingUserId)) { ownerType = ADMIN_TYPE_PROFILE_OWNER; prepareTransfer(admin, target, bundle, callingUserId, ADMIN_TYPE_PROFILE_OWNER); @@ -13685,7 +13665,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (isUserAffiliatedWithDeviceLocked(callingUserId)) { notifyAffiliatedProfileTransferOwnershipComplete(callingUserId); } - } else if (isDeviceOwner(caller)) { + } else if (isDeviceOwner(admin, callingUserId)) { ownerType = ADMIN_TYPE_DEVICE_OWNER; prepareTransfer(admin, target, bundle, callingUserId, ADMIN_TYPE_DEVICE_OWNER); @@ -14355,8 +14335,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); long id = mInjector.binderClearCallingIdentity(); try { return isManagedKioskInternal(); @@ -14381,8 +14360,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); - + enforceManageUsers(); return mInjector.binderWithCleanCallingIdentity(() -> isUnattendedManagedKioskUnchecked()); } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index cbfe636445fdd..3a8d9c3e9ff5f 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -4407,7 +4407,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Caller is Profile Owner, but no supervision app is configured. setAsProfileOwner(admin1); - assertExpectException(SecurityException.class, "is not the default supervision component", + assertExpectException(SecurityException.class, "no default supervision component defined", () -> dpm.setSecondaryLockscreenEnabled(admin1, true)); assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));