summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Johnston <acjohnston@google.com> 2020-08-17 10:35:18 +0100
committer Alex Johnston <acjohnston@google.com> 2020-08-19 12:57:50 +0100
commit65eacc95e387cb8d3fd3620aa69ffb07f93c0047 (patch)
tree84410fae90296e9d4ed8ed596c006b537ef5b59d
parent509f1c79df9186f9757fbffafa891585575c9304 (diff)
Replace enforce permission checks in DPMS
Replaced * enforceFullCrossUsersPermission -> hasFullCrossUsersPermission * enforceCrossUsersPermission -> hasCrossUsersPermission Removed * enforceSystemUserOrPermissionIfCrossUser * enforceSystemUserOrPermission * enforceAcrossUsersPermissions * hasMarkProfileOwnerOnOrganizationOwnedDevicePermission Updated methods * getCurrentFailedPasswordAttempts * getAllCrossProfilePackages * setActiveAdmin * isAdminActive * isRemovingAdmin * hasGrantedPolicy * getActiveAdmins * packageHasActiveAdmins * removeActiveAdmin * getPasswordQuality * getPasswordExpirationTimeout * getPasswordExpiration * getStrictestPasswordRequirement * getPasswordMinimumMetrics * isActivePasswordSufficient * isProfileActivePasswordSufficientForParent * isPasswordSufficientAfterProfileUnification * getCurrentFailedPasswordAttempts * getMaximumFailedPasswordsForWipe * getProfileWithMinimumFailedPasswordsForWipe * getMaximumTimeToLock * getRequiredStrongAuthTimeout * wipeDataWithReason * getRemoveWarning * reportFailedPasswordAttempt * reportSuccessfulPasswordAttempt * reportFailedBiometricAttempt * reportSuccessfulBiometricAttempt * reportKeyguardDismissed * reportKeyguardSecured * getGlobalProxyAdmin * getStorageEncryption * getStorageEncryptionStatus * getKeyguardDisabledFeatures * getTrustAgentConfiguration * getAccountTypesWithManagementDisabledAsUser * setOrganizationColorForUser * getOrganizationColorForUser * getOrganizationNameForUser * getProfileOwnerAsUser * getCrossProfileCallerIdDisabledForUser * getCrossProfileContactsSearchDisabledForUser * isPackageAllowedToAccessCalendarForUser * getCrossProfileCalendarPackagesForUser * getActiveAdminOrCheckPermissionForCallerLocked * resetPassword * lockNow * enforceNetworkStackOrProfileOrDeviceOwner * getFactoryResetProtectionPolicy Bug: 165302873 Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest atest com.google.android.cts.deviceowner.DeviceOwnerTest atest com.android.cts.devicepolicy.MixedDeviceOwnerTest atest com.android.cts.devicepolicy.MixedProfileOwnerTest atest com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest Change-Id: Ic3fea2f0483c02623a21bc3a67ff6bd29fbcc792
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java401
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java36
3 files changed, 295 insertions, 144 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6154bef2bda3..f4e8d05e8da6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1566,7 +1566,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
/**
* Creates a new {@link CallerIdentity} object to represent the caller's identity.
*/
- private CallerIdentity getCallerIdentity(String callerPackage) {
+ private CallerIdentity getCallerIdentity() {
+ final int callerUid = mInjector.binderGetCallingUid();
+ return new CallerIdentity(callerUid, null, null);
+ }
+
+ /**
+ * Creates a new {@link CallerIdentity} object to represent the caller's identity.
+ */
+ private CallerIdentity getCallerIdentity(@NonNull String callerPackage) {
final int callerUid = mInjector.binderGetCallingUid();
if (!isCallingFromPackage(callerPackage, callerUid)) {
@@ -2145,9 +2153,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid);
if (result != null) {
return result;
- } else if (permission != null
- && (mContext.checkCallingPermission(permission)
- == PackageManager.PERMISSION_GRANTED)) {
+ } else if (permission != null && hasCallingPermission(permission)) {
return null;
}
@@ -2844,9 +2850,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle,
Bundle onEnableData) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(
+ hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS));
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
DevicePolicyData policy = getUserData(userHandle);
DeviceAdminInfo info = findAdmin(adminReceiver, userHandle,
@@ -2986,7 +2995,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return false;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
}
@@ -2997,7 +3010,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return false;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
DevicePolicyData policyData = getUserData(userHandle);
return policyData.mRemovingAdmins.contains(adminReceiver);
@@ -3009,7 +3026,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return false;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity(adminReceiver);
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (administrator == null) {
@@ -3025,8 +3046,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return Collections.EMPTY_LIST;
}
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
- enforceFullCrossUsersPermission(userHandle);
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(userHandle);
final int N = policy.mAdminList.size();
@@ -3046,7 +3070,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return false;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(userHandle);
final int N = policy.mAdminList.size();
@@ -3156,8 +3184,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
enforceUserUnlocked(userHandle);
+
synchronized (getLockObject()) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (admin == null) {
@@ -3309,7 +3341,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return PASSWORD_QUALITY_UNSPECIFIED;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
int mode = PASSWORD_QUALITY_UNSPECIFIED;
@@ -3521,7 +3557,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return 0L;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
long timeout = 0L;
@@ -3656,7 +3696,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return 0L;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
return getPasswordExpirationLocked(who, userHandle, parent);
}
@@ -3862,7 +3906,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return 0;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
if (who != null) {
final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
@@ -3902,7 +3950,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
new PasswordMetrics(CREDENTIAL_TYPE_NONE);
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>();
synchronized (getLockObject()) {
List<ActiveAdmin> admins =
@@ -3919,7 +3971,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return true;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
enforceUserUnlocked(userHandle, parent);
synchronized (getLockObject()) {
@@ -3951,7 +4006,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return true;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
enforceManagedProfile(userHandle, "call APIs refering to the parent profile");
synchronized (getLockObject()) {
@@ -3970,7 +4028,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return true;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
enforceNotManagedProfile(userHandle, "check password sufficiency");
enforceUserUnlocked(userHandle);
@@ -4058,12 +4119,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mLockPatternUtils.hasSecureLockScreen()) {
return 0;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
- if (!isCallerWithSystemUid()) {
+ if (!isSystemUid(identity)) {
// This API can be called by an active device admin or by keyguard code.
- if (mContext.checkCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
+ if (!hasCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)) {
getActiveAdminForCallerLocked(
null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
}
@@ -4106,7 +4170,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return 0;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
ActiveAdmin admin = (who != null)
? getActiveAdminUncheckedLocked(who, userHandle, parent)
@@ -4120,7 +4188,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return UserHandle.USER_NULL;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(
userHandle, parent);
@@ -4191,8 +4263,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// As of R, only privlleged caller holding RESET_PASSWORD can call resetPassword() to
// set password to an unsecured user.
- if (mContext.checkCallingPermission(permission.RESET_PASSWORD)
- == PackageManager.PERMISSION_GRANTED) {
+ if (hasCallingPermission(permission.RESET_PASSWORD)) {
return setPasswordPrivileged(password, flags, callingUid);
}
@@ -4392,7 +4463,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return 0;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
if (who != null) {
final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
@@ -4465,12 +4540,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
}
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId));
+
if (!mLockPatternUtils.hasSecureLockScreen()) {
// No strong auth timeout on devices not supporting the
// {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature
return 0;
}
- enforceFullCrossUsersPermission(userId);
synchronized (getLockObject()) {
if (who != null) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent);
@@ -4504,8 +4583,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void lockNow(int flags, boolean parent) {
- if (!mHasFeature && mContext.checkCallingPermission(android.Manifest.permission.LOCK_DEVICE)
- != PackageManager.PERMISSION_GRANTED) {
+ if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) {
return;
}
@@ -4597,8 +4675,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) {
- if (mContext.checkCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
- == PackageManager.PERMISSION_GRANTED) {
+ if (hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)) {
return;
}
enforceProfileOrDeviceOwner(who);
@@ -5677,8 +5754,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return;
}
-
- enforceFullCrossUsersPermission(mInjector.userHandleGetCallingUserId());
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(isSystemUid(identity) || isRootUid(identity)
+ || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS_FULL));
final ActiveAdmin admin;
synchronized (getLockObject()) {
@@ -5854,8 +5932,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
synchronized (getLockObject()) {
if (who == null) {
if ((frpManagementAgentUid != mInjector.binderGetCallingUid())
- && (mContext.checkCallingPermission(permission.MASTER_CLEAR)
- != PackageManager.PERMISSION_GRANTED)) {
+ && !hasCallingPermission(permission.MASTER_CLEAR)) {
throw new SecurityException(
"Must be called by the FRP management agent on device");
}
@@ -5893,9 +5970,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return;
}
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = comp != null
+ ? getCallerIdentity(comp)
+ : getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
synchronized (getLockObject()) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle);
@@ -5972,13 +6053,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportFailedPasswordAttempt(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
if (!isSeparateProfileChallengeEnabled(userHandle)) {
enforceNotManagedProfile(userHandle,
"report failed password attempt if separate profile challenge is not in place");
}
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
boolean wipeData = false;
ActiveAdmin strictestAdmin = null;
@@ -6051,9 +6134,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportSuccessfulPasswordAttempt(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(userHandle);
@@ -6079,9 +6164,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportFailedBiometricAttempt(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
+
if (mInjector.securityLogIsLoggingEnabled()) {
SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 0,
/*method strength*/ 0);
@@ -6090,9 +6178,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportSuccessfulBiometricAttempt(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
+
if (mInjector.securityLogIsLoggingEnabled()) {
SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 1,
/*method strength*/ 0);
@@ -6101,9 +6192,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportKeyguardDismissed(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
if (mInjector.securityLogIsLoggingEnabled()) {
SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISSED);
@@ -6112,9 +6205,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void reportKeyguardSecured(int userHandle) {
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN));
if (mInjector.securityLogIsLoggingEnabled()) {
SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_SECURED);
@@ -6176,7 +6271,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return null;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
// Scan through active admins and find if anyone has already
@@ -6310,7 +6409,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return false;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = who != null
+ ? getCallerIdentity(who)
+ : getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
// Check for permissions if a particular caller is specified
if (who != null) {
@@ -6340,7 +6445,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
// Ok to return current status.
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = callerPackage != null
+ ? getCallerIdentity(callerPackage)
+ : getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
// It's not critical here, but let's make sure the package name is correct, in case
// we start using it for different purposes.
@@ -7033,7 +7143,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return 0;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
final long ident = mInjector.binderClearCallingIdentity();
try {
synchronized (getLockObject()) {
@@ -7783,7 +7897,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public ComponentName getProfileOwnerAsUser(int userHandle) {
- enforceCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle));
return getProfileOwner(userHandle);
}
@@ -8140,56 +8257,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- private void enforceAcrossUsersPermissions() {
- final int callingUid = mInjector.binderGetCallingUid();
- final int callingPid = mInjector.binderGetCallingPid();
- final String packageName = mContext.getPackageName();
-
- if (isCallerWithSystemUid() || callingUid == Process.ROOT_UID) {
- return;
- }
- if (PermissionChecker.checkPermissionForPreflight(
- mContext, permission.INTERACT_ACROSS_PROFILES, callingPid, callingUid,
- packageName) == PermissionChecker.PERMISSION_GRANTED) {
- return;
- }
- if (mContext.checkCallingPermission(permission.INTERACT_ACROSS_USERS)
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
- if (mContext.checkCallingPermission(permission.INTERACT_ACROSS_USERS_FULL)
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
- throw new SecurityException("Calling user does not have INTERACT_ACROSS_PROFILES or"
- + "INTERACT_ACROSS_USERS or INTERACT_ACROSS_USERS_FULL permissions");
+ private boolean hasCallingPermission(String permission) {
+ return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
- private void enforceFullCrossUsersPermission(int userHandle) {
- enforceSystemUserOrPermissionIfCrossUser(userHandle,
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ private boolean hasCallingOrSelfPermission(String permission) {
+ return mContext.checkCallingOrSelfPermission(permission)
+ == PackageManager.PERMISSION_GRANTED;
}
- private void enforceCrossUsersPermission(int userHandle) {
- enforceSystemUserOrPermissionIfCrossUser(userHandle,
- android.Manifest.permission.INTERACT_ACROSS_USERS);
+ private boolean hasPermissionForPreflight(CallerIdentity identity, String permission) {
+ final int callingPid = mInjector.binderGetCallingPid();
+ final String packageName = mContext.getPackageName();
+
+ return PermissionChecker.checkPermissionForPreflight(mContext, permission, callingPid,
+ identity.getUid(), packageName) == PermissionChecker.PERMISSION_GRANTED;
}
- private void enforceSystemUserOrPermission(String permission) {
- if (!(isCallerWithSystemUid() || mInjector.binderGetCallingUid() == Process.ROOT_UID)) {
- mContext.enforceCallingOrSelfPermission(permission,
- "Must be system or have " + permission + " permission");
- }
+ private boolean hasFullCrossUsersPermission(CallerIdentity identity, int userHandle) {
+ return (userHandle == identity.getUserId()) || isSystemUid(identity) || isRootUid(identity)
+ || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS_FULL);
}
- private void enforceSystemUserOrPermissionIfCrossUser(int userHandle, String permission) {
- if (userHandle < 0) {
- throw new IllegalArgumentException("Invalid userId " + userHandle);
- }
- if (userHandle == mInjector.userHandleGetCallingUserId()) {
- return;
- }
- enforceSystemUserOrPermission(permission);
+ private boolean hasCrossUsersPermission(CallerIdentity identity, int userHandle) {
+ return (userHandle == identity.getUserId()) || isSystemUid(identity) || isRootUid(identity)
+ || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS);
}
private void enforceManagedProfile(int userId, String message) {
@@ -8249,19 +8341,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
throw new SecurityException("No active admin found");
}
- private void enforceProfileOwnerOrFullCrossUsersPermission(int userId) {
- if (userId == mInjector.userHandleGetCallingUserId()) {
+ private void enforceProfileOwnerOrFullCrossUsersPermission(CallerIdentity identity,
+ int userId) {
+ if (userId == identity.getUserId()) {
synchronized (getLockObject()) {
if (getActiveAdminWithPolicyForUidLocked(null,
- DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid())
- != null) {
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, identity.getUid()) != null) {
// Device Owner/Profile Owner may access the user it runs on.
return;
}
}
}
- // Otherwise, INTERACT_ACROSS_USERS_FULL permission, system UID or root UID is required.
- enforceSystemUserOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId));
}
private boolean canUserUseLockTaskLocked(int userId) {
@@ -8315,6 +8406,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID);
}
+ private boolean isSystemUid(CallerIdentity identity) {
+ return UserHandle.isSameApp(identity.getUid(), Process.SYSTEM_UID);
+ }
+
+ private boolean isRootUid(CallerIdentity identity) {
+ return UserHandle.isSameApp(identity.getUid(), Process.ROOT_UID);
+ }
+
+ private boolean isShellUid(CallerIdentity identity) {
+ return UserHandle.isSameApp(identity.getUid(), Process.SHELL_UID);
+ }
+
protected int getProfileParentId(int userHandle) {
return mInjector.binderWithCleanCallingIdentity(() -> {
UserInfo parentUser = mUserManager.getProfileParent(userHandle);
@@ -8569,7 +8672,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return null;
}
Objects.requireNonNull(agent, "agent null");
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = admin != null
+ ? getCallerIdentity(admin)
+ : getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
synchronized (getLockObject()) {
final String componentName = agent.flattenToString();
@@ -9922,10 +10030,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public String[] getAccountTypesWithManagementDisabledAsUser(int userId, boolean parent) {
- enforceFullCrossUsersPermission(userId);
if (!mHasFeature) {
return null;
}
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId));
+
synchronized (getLockObject()) {
final ArraySet<String> resultSet = new ArraySet<>();
@@ -10045,7 +10157,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public boolean getCrossProfileCallerIdDisabledForUser(int userId) {
- enforceCrossUsersPermission(userId);
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userId));
+
synchronized (getLockObject()) {
ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
return (admin != null) ? admin.disableCallerId : false;
@@ -10088,7 +10204,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public boolean getCrossProfileContactsSearchDisabledForUser(int userId) {
- enforceCrossUsersPermission(userId);
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userId));
+
synchronized (getLockObject()) {
ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
return (admin != null) ? admin.disableContactsSearch : false;
@@ -12157,7 +12277,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return;
}
- enforceFullCrossUsersPermission(userId);
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId));
+
enforceManageUsers();
enforceManagedProfile(userId, "set organization color");
synchronized (getLockObject()) {
@@ -12186,7 +12310,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return ActiveAdmin.DEF_ORGANIZATION_COLOR;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
enforceManagedProfile(userHandle, "get organization color");
synchronized (getLockObject()) {
ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle);
@@ -12246,7 +12374,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return null;
}
- enforceFullCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle));
+
enforceManagedProfile(userHandle, "get organization name");
synchronized (getLockObject()) {
ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle);
@@ -12337,12 +12469,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return false;
}
- private boolean hasMarkProfileOwnerOnOrganizationOwnedDevicePermission() {
- return mContext.checkCallingPermission(
- permission.MARK_DEVICE_ORGANIZATION_OWNED)
- == PackageManager.PERMISSION_GRANTED;
- }
-
@Override
public void markProfileOwnerOnOrganizationOwnedDevice(ComponentName who, int userId) {
// As the caller is the system, it must specify the component name of the profile owner
@@ -12355,7 +12481,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// Only adb or system apps with the right permission can mark a profile owner on
// organization-owned device.
- if (!(isAdb() || hasMarkProfileOwnerOnOrganizationOwnedDevicePermission())) {
+ if (!(isAdb() || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED))) {
throw new SecurityException(
"Only the system can mark a profile owner of organization-owned device.");
}
@@ -13483,7 +13609,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) {
final int userId = user.getIdentifier();
- enforceProfileOwnerOrFullCrossUsersPermission(userId);
+ final CallerIdentity identity = getCallerIdentity();
+ enforceProfileOwnerOrFullCrossUsersPermission(identity, userId);
synchronized (getLockObject()) {
return new StringParceledListSlice(
new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts));
@@ -14136,8 +14263,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return false;
}
Preconditions.checkStringNotEmpty(packageName, "Package name is null or empty");
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle));
- enforceCrossUsersPermission(userHandle);
synchronized (getLockObject()) {
if (mInjector.settingsSecureGetIntForUser(
Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 0, userHandle) == 0) {
@@ -14159,7 +14289,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return Collections.emptyList();
}
- enforceCrossUsersPermission(userHandle);
+ Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle));
+
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
if (admin != null) {
@@ -14221,7 +14355,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!mHasFeature) {
return Collections.emptyList();
}
- enforceAcrossUsersPermissions();
+ final CallerIdentity identity = getCallerIdentity();
+ Preconditions.checkCallAuthorization(
+ isSystemUid(identity) || isRootUid(identity) || hasCallingPermission(
+ permission.INTERACT_ACROSS_USERS) || hasCallingPermission(
+ permission.INTERACT_ACROSS_USERS_FULL) || hasPermissionForPreflight(
+ identity, permission.INTERACT_ACROSS_PROFILES));
synchronized (getLockObject()) {
final List<ActiveAdmin> admins = getProfileOwnerAdminsForCurrentProfileGroup();
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 32afe8244eb6..e6fc792c6a9d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4465,6 +4465,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
+ mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL);
// Even if the caller is the managed profile, the current user is the user 0
when(getServices().iactivityManager.getCurrentUser())
@@ -5694,6 +5695,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
final long ident = mServiceContext.binder.clearCallingIdentity();
configureContextForAccess(mServiceContext, true);
+ mServiceContext.permissions.add(permission.MARK_DEVICE_ORGANIZATION_OWNED);
mServiceContext.binder.callingUid =
UserHandle.getUid(CALLER_USER_HANDLE,
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index ce7ac9e796d2..09b6d7b0cd7e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -259,18 +259,7 @@ public class DpmMockContext extends MockContext {
@Override
public int checkPermission(String permission, int pid, int uid) {
- if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
- return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions.
- }
- List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
- if (permissions == null) {
- permissions = callerPermissions;
- }
- if (permissions.contains(permission)) {
- return PackageManager.PERMISSION_GRANTED;
- } else {
- return PackageManager.PERMISSION_DENIED;
- }
+ return checkPermission(permission);
}
@Override
@@ -480,11 +469,32 @@ public class DpmMockContext extends MockContext {
@Override
public int checkCallingPermission(String permission) {
- return spiedContext.checkCallingPermission(permission);
+ return checkPermission(permission);
+ }
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ return checkPermission(permission);
}
@Override
public void startActivityAsUser(Intent intent, UserHandle userHandle) {
spiedContext.startActivityAsUser(intent, userHandle);
}
+
+ private int checkPermission(String permission) {
+ if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
+ return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions.
+ }
+ List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
+ if (permissions == null) {
+ permissions = callerPermissions;
+ }
+ if (permissions.contains(permission)) {
+ return PackageManager.PERMISSION_GRANTED;
+ } else {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ }
+
}