diff options
author | Nicolas Prevot <nprevot@google.com> | 2015-04-24 15:08:01 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-04-24 15:08:02 +0000 |
commit | 7defaef1bfc05757652d3a5d00d35090397e7f3e (patch) | |
tree | 50cfedf437340a751bf4d70407a3f3347fbdb2d3 /services | |
parent | f74a212ffbdfdf39de128682ec174a9ee1403a9e (diff) | |
parent | 2806374f9531490296547d4e884ce9163f4ac867 (diff) | |
download | frameworks_base-7defaef1bfc05757652d3a5d00d35090397e7f3e.zip frameworks_base-7defaef1bfc05757652d3a5d00d35090397e7f3e.tar.gz frameworks_base-7defaef1bfc05757652d3a5d00d35090397e7f3e.tar.bz2 |
Merge "Restrict setting the profile/device owner with a signature-level permission."
Diffstat (limited to 'services')
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 117 |
1 files changed, 74 insertions, 43 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index eb9234a..6fc3103 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3983,15 +3983,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + " for device owner"); } synchronized (this) { - if (!allowedToSetDeviceOwnerOnDevice()) { - throw new IllegalStateException( - "Trying to set device owner but device is already provisioned."); - } - - if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()) { - throw new IllegalStateException( - "Trying to set device owner but device owner is already set."); - } + enforceCanSetDeviceOwner(); // Shutting down backup manager service permanently. long ident = Binder.clearCallingIdentity(); @@ -4009,7 +4001,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Device owner is not set and does not exist, set it. mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName); } else { - // Device owner is not set but a profile owner exists, update Device owner state. + // Device owner state already exists, update it. mDeviceOwner.setDeviceOwner(packageName, ownerName); } mDeviceOwner.writeOwnerFile(); @@ -4225,43 +4217,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); - - UserInfo info = mUserManager.getUserInfo(userHandle); - if (info == null) { - // User doesn't exist. - throw new IllegalArgumentException( - "Attempted to set profile owner for invalid userId: " + userHandle); - } - if (info.isGuest()) { - throw new IllegalStateException("Cannot set a profile owner on a guest"); - } - if (who == null || !DeviceOwner.isInstalledForUser(who.getPackageName(), userHandle)) { throw new IllegalArgumentException("Component " + who + " not installed for userId:" + userHandle); } synchronized (this) { - // Only SYSTEM_UID can override the userSetupComplete - if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID - && hasUserSetupCompleted(userHandle)) { - throw new IllegalStateException( - "Trying to set profile owner but user is already set-up."); - } - + enforceCanSetProfileOwner(userHandle); if (mDeviceOwner == null) { // Device owner state does not exist, create it. mDeviceOwner = DeviceOwner.createWithProfileOwner(who, ownerName, userHandle); - mDeviceOwner.writeOwnerFile(); - return true; } else { - // Device owner already exists, update it. + // Device owner state already exists, update it. mDeviceOwner.setProfileOwner(who, ownerName, userHandle); - mDeviceOwner.writeOwnerFile(); - return true; } + mDeviceOwner.writeOwnerFile(); + return true; } } @@ -4451,18 +4423,77 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** - * Device owner can only be set on an unprovisioned device. However, if initiated via "adb", - * we also allow it if no accounts or additional users are present on the device. + * The profile owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS + * permission. + * The profile owner can only be set before the user setup phase has completed, + * except for: + * - SYSTEM_UID + * - adb if there are not accounts. */ - private boolean allowedToSetDeviceOwnerOnDevice() { - if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) { - return true; + private void enforceCanSetProfileOwner(int userHandle) { + UserInfo info = mUserManager.getUserInfo(userHandle); + if (info == null) { + // User doesn't exist. + throw new IllegalArgumentException( + "Attempted to set profile owner for invalid userId: " + userHandle); + } + if (info.isGuest()) { + throw new IllegalStateException("Cannot set a profile owner on a guest"); + } + if (getProfileOwner(userHandle) != null) { + throw new IllegalStateException("Trying to set the profile owner, but profile owner " + + "is already set."); + } + int callingUid = Binder.getCallingUid(); + if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { + if (hasUserSetupCompleted(userHandle) && + AccountManager.get(mContext).getAccountsAsUser(userHandle).length > 0) { + throw new IllegalStateException("Not allowed to set the profile owner because " + + "there are already some accounts on the profile"); + } + return; + } + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); + if (hasUserSetupCompleted(userHandle) + && UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { + throw new IllegalStateException("Cannot set the profile owner on a user which is " + + "already set-up"); } + } - int callingId = Binder.getCallingUid(); - return (callingId == Process.SHELL_UID || callingId == Process.ROOT_UID) - && mUserManager.getUserCount() == 1 - && AccountManager.get(mContext).getAccounts().length == 0; + /** + * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS + * permission. + * The device owner can only be set before the setup phase of the primary user has completed, + * except for adb if no accounts or additional users are present on the device. + */ + private void enforceCanSetDeviceOwner() { + if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()) { + throw new IllegalStateException("Trying to set the device owner, but device owner " + + "is already set."); + } + int callingUid = Binder.getCallingUid(); + if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { + if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) { + return; + } + if (mUserManager.getUserCount() > 1) { + throw new IllegalStateException("Not allowed to set the device owner because there " + + "are already several users on the device"); + } + if (AccountManager.get(mContext).getAccounts().length > 0) { + throw new IllegalStateException("Not allowed to set the device owner because there " + + "are already some accounts on the device"); + } + return; + } + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); + if (hasUserSetupCompleted(UserHandle.USER_OWNER)) { + throw new IllegalStateException("Cannot set the device owner if the device is " + + "already set-up"); + } } private void enforceCrossUserPermission(int userHandle) { |