Merge "Allow device or profile owner app to modify user restrictions."

This commit is contained in:
Emily Bernier
2014-04-23 18:27:45 +00:00
committed by Android (Google) Code Review
2 changed files with 59 additions and 14 deletions

View File

@@ -300,7 +300,8 @@ public class UserManager {
/**
* Sets all the user-wide restrictions for this user.
* Requires the MANAGE_USERS permission.
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission or profile/device owner
* privileges.
* @param restrictions the Bundle containing all the restrictions.
*/
public void setUserRestrictions(Bundle restrictions) {
@@ -309,7 +310,8 @@ public class UserManager {
/**
* Sets all the user-wide restrictions for the specified user.
* Requires the MANAGE_USERS permission.
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission or profile/device owner
* privileges.
* @param restrictions the Bundle containing all the restrictions.
* @param userHandle the UserHandle of the user for whom to set the restrictions.
*/
@@ -323,7 +325,8 @@ public class UserManager {
/**
* Sets the value of a specific restriction.
* Requires the MANAGE_USERS permission.
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission or profile/device owner
* privileges.
* @param key the key of the restriction
* @param value the value for the restriction
*/
@@ -336,7 +339,8 @@ public class UserManager {
/**
* @hide
* Sets the value of a specific restriction on a specific user.
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission or profile/device owner
* privileges.
* @param key the key of the restriction
* @param value the value for the restriction
* @param userHandle the user whose restriction is to be changed.
@@ -548,7 +552,7 @@ public class UserManager {
/**
* Returns information for all users on this device. Requires
* {@link android.Manifest.permission#MANAGE_USERS} permission.
*
*
* @param excludeDying specify if the list should exclude users being
* removed.
* @return the list of users that were created.

View File

@@ -22,6 +22,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.admin.DevicePolicyManager;
import android.app.IStopUserCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -437,7 +438,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public void setUserRestrictions(Bundle restrictions, int userId) {
checkManageUsersPermission("setUserRestrictions");
checkProfileOwnerOrManageUsersPermission("setUserRestrictions");
if (restrictions == null) return;
synchronized (mPackagesLock) {
@@ -463,16 +464,53 @@ public class UserManagerService extends IUserManager.Stub {
* @param message used as message if SecurityException is thrown
* @throws SecurityException if the caller is not system or root
*/
private static final void checkManageUsersPermission(String message) {
private final void checkManageUsersPermission(String message) {
final int uid = Binder.getCallingUid();
if (uid != Process.SYSTEM_UID && uid != 0
&& ActivityManager.checkComponentPermission(
android.Manifest.permission.MANAGE_USERS,
uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
if (missingManageUsersPermission(uid)) {
throw new SecurityException("You need MANAGE_USERS permission to: " + message);
}
}
/**
* Enforces that only the system UID, root's UID, apps that have the
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
* permission, the profile owner, or the device owner can make certain calls to the
* UserManager.
*
* @param message used as message if SecurityException is thrown
* @throws SecurityException if the caller is not system, root, or device
* owner
*/
private final void checkProfileOwnerOrManageUsersPermission(String message) {
final int uid = Binder.getCallingUid();
boolean isProfileOwner = false;
if (mContext != null && mContext.getPackageManager() != null) {
String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid);
DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm != null) {
for (String pkg : pkgs) {
if (dpm.isDeviceOwnerApp(pkg) || dpm.isProfileOwnerApp(pkg)) {
isProfileOwner = true;
}
}
}
}
if (missingManageUsersPermission(uid) && !isProfileOwner) {
throw new SecurityException(
"You need MANAGE_USERS permission or device owner privileges to: " + message);
}
}
private boolean missingManageUsersPermission(int uid) {
return uid != Process.SYSTEM_UID && uid != 0
&& ActivityManager.checkComponentPermission(
android.Manifest.permission.MANAGE_USERS,
uid, -1, true) != PackageManager.PERMISSION_GRANTED;
}
private void writeBitmapLocked(UserInfo info, Bitmap bitmap) {
try {
File dir = new File(mUsersDir, Integer.toString(info.id));
@@ -1175,7 +1213,8 @@ public class UserManagerService extends IUserManager.Stub {
public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
checkManageUsersPermission("Only system can get restrictions for other users/apps");
checkProfileOwnerOrManageUsersPermission(
"Only system or device owner can get restrictions for other users/apps");
}
synchronized (mPackagesLock) {
// Read the restrictions from XML
@@ -1188,7 +1227,8 @@ public class UserManagerService extends IUserManager.Stub {
int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
checkManageUsersPermission("Only system can set restrictions for other users/apps");
checkProfileOwnerOrManageUsersPermission(
"Only system or device owner can set restrictions for other users/apps");
}
synchronized (mPackagesLock) {
// Write the restrictions to XML
@@ -1290,7 +1330,8 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public void removeRestrictions() {
checkManageUsersPermission("Only system can remove restrictions");
checkProfileOwnerOrManageUsersPermission(
"Only system or device owner can remove restrictions");
final int userHandle = UserHandle.getCallingUserId();
removeRestrictionsForUser(userHandle, true);
}