diff options
| -rw-r--r-- | core/java/android/app/admin/DevicePolicyManagerInternal.java | 9 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 107 |
2 files changed, 74 insertions, 42 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java index a1f1d920ba7c..0a0d77d2a465 100644 --- a/core/java/android/app/admin/DevicePolicyManagerInternal.java +++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java @@ -60,4 +60,13 @@ public abstract class DevicePolicyManagerInternal { */ public abstract void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener); + + /** + * Checks if an app with given uid is an active device admin of its user and has the policy + * specified. + * @param uid App uid. + * @param reqPolicy Required policy, for policies see {@link DevicePolicyManager}. + * @return true if the uid is an active admin with the given policy. + */ + public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index d07cd984392d..d02b2d659df2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1140,70 +1140,85 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) throws SecurityException { final int callingUid = Binder.getCallingUid(); - final int userHandle = UserHandle.getUserId(callingUid); - final DevicePolicyData policy = getUserData(userHandle); - List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>(); + ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid); + if (result != null) { + return result; + } + + if (who != null) { + final int userId = UserHandle.getUserId(callingUid); + final DevicePolicyData policy = getUserData(userId); + ActiveAdmin admin = policy.mAdminMap.get(who); + if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { + throw new SecurityException("Admin " + admin.info.getComponent() + + " does not own the device"); + } + if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { + throw new SecurityException("Admin " + admin.info.getComponent() + + " does not own the profile"); + } + throw new SecurityException("Admin " + admin.info.getComponent() + + " did not specify uses-policy for: " + + admin.info.getTagForPolicy(reqPolicy)); + } else { + throw new SecurityException("No active admin owned by uid " + + Binder.getCallingUid() + " for policy #" + reqPolicy); + } + } - // Build a list of admins for this uid matching the given ComponentName + private ActiveAdmin getActiveAdminWithPolicyForUidLocked(ComponentName who, int reqPolicy, + int uid) { + // Try to find an admin which can use reqPolicy + final int userId = UserHandle.getUserId(uid); + final DevicePolicyData policy = getUserData(userId); if (who != null) { ActiveAdmin admin = policy.mAdminMap.get(who); if (admin == null) { throw new SecurityException("No active admin " + who); } - if (admin.getUid() != callingUid) { + if (admin.getUid() != uid) { throw new SecurityException("Admin " + who + " is not owned by uid " + Binder.getCallingUid()); } - candidates.add(admin); + if (isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) { + return admin; + } } else { for (ActiveAdmin admin : policy.mAdminList) { - if (admin.getUid() == callingUid) { - candidates.add(admin); + if (admin.getUid() == uid && isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, + userId)) { + return admin; } } } - // Try to find an admin which can use reqPolicy - for (ActiveAdmin admin : candidates) { - boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); - boolean ownsProfile = (getProfileOwner(userHandle) != null - && getProfileOwner(userHandle).getPackageName() - .equals(admin.info.getPackageName())); - boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName()) - && !hasUserSetupCompleted(userHandle); + return null; + } - if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { - if (ownsDevice || (userHandle == UserHandle.USER_OWNER && ownsInitialization)) { - return admin; - } - } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { - if (ownsDevice || ownsProfile || ownsInitialization) { - return admin; - } - } else { - if (admin.info.usesPolicy(reqPolicy)) { - return admin; - } - } - } + private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, + int userId) { + boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); + boolean ownsProfile = (getProfileOwner(userId) != null + && getProfileOwner(userId).getPackageName() + .equals(admin.info.getPackageName())); + boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName()) + && !hasUserSetupCompleted(userId); - if (who != null) { - if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { - throw new SecurityException("Admin " + candidates.get(0).info.getComponent() - + " does not own the device"); + if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { + if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) { + return true; } - if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { - throw new SecurityException("Admin " + candidates.get(0).info.getComponent() - + " does not own the profile"); + } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { + if (ownsDevice || ownsProfile || ownsInitialization) { + return true; } - throw new SecurityException("Admin " + candidates.get(0).info.getComponent() - + " did not specify uses-policy for: " - + candidates.get(0).info.getTagForPolicy(reqPolicy)); } else { - throw new SecurityException("No active admin owned by uid " - + Binder.getCallingUid() + " for policy #" + reqPolicy); + if (admin.info.usesPolicy(reqPolicy)) { + return true; + } } + return false; } void sendAdminCommandLocked(ActiveAdmin admin, String action) { @@ -5702,6 +5717,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + @Override + public boolean isActiveAdminWithPolicy(int uid, int reqPolicy) { + final int userId = UserHandle.getUserId(uid); + synchronized(DevicePolicyManagerService.this) { + return getActiveAdminWithPolicyForUidLocked(null, reqPolicy, uid) != null; + } + } + private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) { final List<OnCrossProfileWidgetProvidersChangeListener> listeners; synchronized (DevicePolicyManagerService.this) { |