UserManager.getUserName w/ GET_ACCOUNTS_PRIVILEGED

Previously, UserManager.getUserName() and getUserIcon()
required the MANAGE_USERS permission; this has been relaxed
so that the GET_ACCOUNTS_PRIVILEGED permission is also sufficient.

Test: atest UserManagerServiceUserInfoTest
Fixes: 127826840

Change-Id: If90b82313ecf23ea56dca3d24f23a4ca9caa939a
This commit is contained in:
Bookatz
2019-03-08 14:30:00 -08:00
parent f3d0737778
commit cde3d92f9d
4 changed files with 42 additions and 11 deletions

View File

@@ -5615,7 +5615,7 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon();
method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
method public boolean hasRestrictedProfiles();

View File

@@ -100,6 +100,7 @@ interface IUserManager {
boolean isUserNameSet(int userHandle);
boolean hasRestrictedProfiles();
boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userHandle, in IntentSender target);
String getUserName();
long getUserStartRealtime();
long getUserUnlockRealtime();
}

View File

@@ -1256,12 +1256,16 @@ public class UserManager {
/**
* Returns the user name of the user making this call. This call is only
* available to applications on the system image; it requires the
* MANAGE_USERS permission.
* {@code android.permission.MANAGE_USERS} or {@code android.permission.GET_ACCOUNTS_PRIVILEGED}
* permissions.
* @return the user name
*/
public String getUserName() {
UserInfo user = getUserInfo(getUserHandle());
return user == null ? "" : user.name;
try {
return mService.getUserName();
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
@@ -2764,14 +2768,16 @@ public class UserManager {
/**
* Returns a Bitmap for the calling user's photo.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
* Requires {@link android.Manifest.permission#MANAGE_USERS}
* or {@link android.Manifest.permission#GET_ACCOUNTS_PRIVILEGED} permissions.
*
* @return a {@link Bitmap} of the user's photo, or null if there's no photo.
* @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
@RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED})
public @Nullable Bitmap getUserIcon() {
return getUserIcon(getUserHandle());
}

View File

@@ -1143,6 +1143,19 @@ public class UserManagerService extends IUserManager.Stub {
return mLocalService.isUserRunning(userId);
}
@Override
public String getUserName() {
if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
+ "permissions to: get user name");
}
final int userId = UserHandle.getUserId(Binder.getCallingUid());
synchronized (mUsersLock) {
UserInfo userInfo = userWithName(getUserInfoLU(userId));
return userInfo == null ? "" : userInfo.name;
}
}
@Override
public long getUserStartRealtime() {
final int userId = UserHandle.getUserId(Binder.getCallingUid());
@@ -1324,7 +1337,10 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public ParcelFileDescriptor getUserIcon(int targetUserId) {
checkManageUsersPermission("get user icon");
if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
+ "permissions to: get user icon");
}
String iconPath;
synchronized (mPackagesLock) {
UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId);
@@ -1941,15 +1957,23 @@ public class UserManagerService extends IUserManager.Stub {
/**
* @return whether the calling UID is system UID or root's UID or the calling app has the
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
* {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or the provided permission.
*/
private static final boolean hasManageOrCreateUsersPermission() {
private static final boolean hasManageUsersOrPermission(String alternativePermission) {
final int callingUid = Binder.getCallingUid();
return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
|| callingUid == Process.ROOT_UID
|| hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid)
|| hasPermissionGranted(android.Manifest.permission.CREATE_USERS, callingUid);
|| hasPermissionGranted(alternativePermission, callingUid);
}
/**
* @return whether the calling UID is system UID or root's UID or the calling app has the
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
* {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
*/
private static final boolean hasManageOrCreateUsersPermission() {
return hasManageUsersOrPermission(android.Manifest.permission.CREATE_USERS);
}
/**