Merge "Restrict setting the profile/device owner with a signature-level permission."
This commit is contained in:
committed by
Android (Google) Code Review
commit
7defaef1bf
@@ -2651,14 +2651,12 @@ public class DevicePolicyManager {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Sets the given package as the device owner. The package must already be installed and there
|
||||
* shouldn't be an existing device owner registered, for this call to succeed. Also, this
|
||||
* method must be called before the device is provisioned.
|
||||
* Sets the given package as the device owner.
|
||||
* Same as {@link #setDeviceOwner(String, String)} but without setting a device owner name.
|
||||
* @param packageName the package name of the application to be registered as the device owner.
|
||||
* @return whether the package was successfully registered as the device owner.
|
||||
* @throws IllegalArgumentException if the package name is null or invalid
|
||||
* @throws IllegalStateException if a device owner is already registered or the device has
|
||||
* already been provisioned.
|
||||
* @throws IllegalStateException If the preconditions mentioned are not met.
|
||||
*/
|
||||
public boolean setDeviceOwner(String packageName) throws IllegalArgumentException,
|
||||
IllegalStateException {
|
||||
@@ -2667,15 +2665,17 @@ public class DevicePolicyManager {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Sets the given package as the device owner. The package must already be installed and there
|
||||
* shouldn't be an existing device owner registered, for this call to succeed. Also, this
|
||||
* method must be called before the device is provisioned.
|
||||
* Sets the given package as the device owner. The package must already be installed. There
|
||||
* must not already be a device owner.
|
||||
* Only apps with the MANAGE_PROFILE_AND_DEVICE_OWNERS permission and the shell uid can call
|
||||
* this method.
|
||||
* Calling this after the setup phase of the primary user has completed is allowed only if
|
||||
* the caller is the shell uid, and there are no additional users and no accounts.
|
||||
* @param packageName the package name of the application to be registered as the device owner.
|
||||
* @param ownerName the human readable name of the institution that owns this device.
|
||||
* @return whether the package was successfully registered as the device owner.
|
||||
* @throws IllegalArgumentException if the package name is null or invalid
|
||||
* @throws IllegalStateException if a device owner is already registered or the device has
|
||||
* already been provisioned.
|
||||
* @throws IllegalStateException If the preconditions mentioned are not met.
|
||||
*/
|
||||
public boolean setDeviceOwner(String packageName, String ownerName)
|
||||
throws IllegalArgumentException, IllegalStateException {
|
||||
@@ -2961,14 +2961,18 @@ public class DevicePolicyManager {
|
||||
/**
|
||||
* @hide
|
||||
* Sets the given component as the profile owner of the given user profile. The package must
|
||||
* already be installed and there shouldn't be an existing profile owner registered for this
|
||||
* user. Only the system can call this API if the user has already completed setup.
|
||||
* already be installed. There must not already be a profile owner for this user.
|
||||
* Only apps with the MANAGE_PROFILE_AND_DEVICE_OWNERS permission and the shell uid can call
|
||||
* this method.
|
||||
* Calling this after the setup phase of the specified user has completed is allowed only if:
|
||||
* - the caller is SYSTEM_UID.
|
||||
* - or the caller is the shell uid, and there are no accounts on the specified user.
|
||||
* @param admin the component name to be registered as profile owner.
|
||||
* @param ownerName the human readable name of the organisation associated with this DPM.
|
||||
* @param userHandle the userId to set the profile owner for.
|
||||
* @return whether the component was successfully registered as the profile owner.
|
||||
* @throws IllegalArgumentException if admin is null, the package isn't installed, or
|
||||
* the user has already been set up.
|
||||
* @throws IllegalArgumentException if admin is null, the package isn't installed, or the
|
||||
* preconditions mentioned are not met.
|
||||
*/
|
||||
public boolean setProfileOwner(ComponentName admin, String ownerName, int userHandle)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
@@ -1309,6 +1309,14 @@
|
||||
<permission android:name="android.permission.MANAGE_USERS"
|
||||
android:protectionLevel="signature|system" />
|
||||
|
||||
<!-- @hide Allows an application to set the profile owners and the device owner.
|
||||
This permission is not available to third party applications.-->
|
||||
<permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
|
||||
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
|
||||
android:protectionLevel="signature"
|
||||
android:label="@string/permlab_manageProfileAndDeviceOwners"
|
||||
android:description="@string/permdesc_manageProfileAndDeviceOwners" />
|
||||
|
||||
<!-- Allows an application to get full detailed information about
|
||||
recently running tasks, with full fidelity to the real state.
|
||||
@hide -->
|
||||
|
||||
@@ -698,6 +698,12 @@
|
||||
about currently and recently running tasks. This may allow the app to
|
||||
discover information about which applications are used on the device.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_manageProfileAndDeviceOwners">Manage profile and device owners</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to set the profile/device owners.
|
||||
[CHAR LIMIT=NONE] -->
|
||||
<string name="permdesc_manageProfileAndDeviceOwners">Allows apps to set the profile owners and the device owner.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_reorderTasks">reorder running apps</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user