diff options
author | Amith Yamasani <yamasani@google.com> | 2013-03-30 19:20:18 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2013-03-30 19:26:37 -0700 |
commit | bb49e8573e22cb6325dc31bf007a500fb7c136eb (patch) | |
tree | bf527e3d95965d80cfd20962bff1c60128355064 /services/java/com/android/server/accounts/AccountManagerService.java | |
parent | 7c480f25b89d298af8278c578762dbfe03ae65c8 (diff) | |
parent | 15935aad3d37a16153bfc4396540f91a7a1bce47 (diff) |
resolved conflicts for merge of 15935aad to master
Change-Id: I9664186a62cf7b11844c6a14967f5b8c2b67c289
Diffstat (limited to 'services/java/com/android/server/accounts/AccountManagerService.java')
-rw-r--r-- | services/java/com/android/server/accounts/AccountManagerService.java | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java index 0ebaecdd9288..8c7eb075060d 100644 --- a/services/java/com/android/server/accounts/AccountManagerService.java +++ b/services/java/com/android/server/accounts/AccountManagerService.java @@ -58,6 +58,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -270,7 +271,7 @@ public class AccountManagerService private UserManager getUserManager() { if (mUserManager == null) { - mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + mUserManager = UserManager.get(mContext); } return mUserManager; } @@ -542,9 +543,9 @@ public class AccountManagerService } @Override - public boolean addAccount(Account account, String password, Bundle extras) { + public boolean addAccountExplicitly(Account account, String password, Bundle extras) { if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "addAccount: " + account + Log.v(TAG, "addAccountExplicitly: " + account + ", caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } @@ -1167,7 +1168,7 @@ public class AccountManagerService final int callingUid = getCallingUid(); clearCallingIdentity(); - if (callingUid != android.os.Process.SYSTEM_UID) { + if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("can only call from system"); } UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); @@ -1395,7 +1396,7 @@ public class AccountManagerService return id; } - public void addAcount(final IAccountManagerResponse response, final String accountType, + public void addAccount(final IAccountManagerResponse response, final String accountType, final String authTokenType, final String[] requiredFeatures, final boolean expectActivityLaunch, final Bundle optionsIn) { if (Log.isLoggable(TAG, Log.VERBOSE)) { @@ -1412,7 +1413,7 @@ public class AccountManagerService checkManageAccountsPermission(); // Is user disallowed from modifying accounts? - if (getUserManager().hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { + if (!canUserModifyAccounts(Binder.getCallingUid())) { try { response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, "User is not allowed to add an account!"); @@ -1457,7 +1458,7 @@ public class AccountManagerService int userId) { // Only allow the system process to read accounts of other users if (userId != UserHandle.getCallingUserId() - && Binder.getCallingUid() != android.os.Process.myUid() + && Binder.getCallingUid() != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { @@ -1576,7 +1577,8 @@ public class AccountManagerService public void run() throws RemoteException { synchronized (mAccounts.cacheLock) { - mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid); + mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid, + null); } // check whether each account matches the requested features mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); @@ -1665,7 +1667,7 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { synchronized (accounts.cacheLock) { - return getAccountsFromCacheLocked(accounts, null, callingUid); + return getAccountsFromCacheLocked(accounts, null, callingUid, null); } } finally { restoreCallingIdentity(identityToken); @@ -1706,7 +1708,7 @@ public class AccountManagerService if (userAccounts == null) continue; synchronized (userAccounts.cacheLock) { Account[] accounts = getAccountsFromCacheLocked(userAccounts, null, - Binder.getCallingUid()); + Binder.getCallingUid(), null); for (int a = 0; a < accounts.length; a++) { runningAccounts.add(new AccountAndUser(accounts[a], userId)); } @@ -1720,10 +1722,15 @@ public class AccountManagerService @Override public Account[] getAccountsAsUser(String type, int userId) { - final int callingUid = Binder.getCallingUid(); + return getAccountsAsUser(type, userId, null, -1); + } + + private Account[] getAccountsAsUser(String type, int userId, String callingPackage, + int packageUid) { + int callingUid = Binder.getCallingUid(); // Only allow the system process to read accounts of other users if (userId != UserHandle.getCallingUserId() - && callingUid != android.os.Process.myUid() + && callingUid != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { @@ -1736,12 +1743,17 @@ public class AccountManagerService + ", caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } + // If the original calling app was using the framework account chooser activity, we'll + // be passed in the original caller's uid here, which is what should be used for filtering. + if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) { + callingUid = packageUid; + } checkReadAccountsPermission(); UserAccounts accounts = getUserAccounts(userId); long identityToken = clearCallingIdentity(); try { synchronized (accounts.cacheLock) { - return getAccountsFromCacheLocked(accounts, type, callingUid); + return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage); } } finally { restoreCallingIdentity(identityToken); @@ -1812,6 +1824,16 @@ public class AccountManagerService return getAccountsAsUser(type, UserHandle.getCallingUserId()); } + @Override + public Account[] getAccountsForPackage(String packageName, int uid) { + int callingUid = Binder.getCallingUid(); + if (!UserHandle.isSameApp(callingUid, Process.myUid())) { + throw new SecurityException("getAccountsForPackage() called from unauthorized uid " + + callingUid + " with uid=" + uid); + } + return getAccountsAsUser(null, UserHandle.getCallingUserId(), packageName, uid); + } + public void getAccountsByFeatures(IAccountManagerResponse response, String type, String[] features) { if (Log.isLoggable(TAG, Log.VERBOSE)) { @@ -1831,7 +1853,7 @@ public class AccountManagerService if (features == null || features.length == 0) { Account[] accounts; synchronized (userAccounts.cacheLock) { - accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid); + accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid, null); } Bundle result = new Bundle(); result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); @@ -2354,7 +2376,7 @@ public class AccountManagerService } } else { Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, - android.os.Process.myUid()); + Process.myUid(), null); fout.println("Accounts: " + accounts.length); for (Account account : accounts) { fout.println(" " + account); @@ -2507,7 +2529,7 @@ public class AccountManagerService private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, int callerUid) { - if (callerUid == android.os.Process.SYSTEM_UID) { + if (callerUid == Process.SYSTEM_UID) { return true; } UserAccounts accounts = getUserAccountsForCaller(); @@ -2560,8 +2582,10 @@ public class AccountManagerService } private boolean canUserModifyAccounts(int callingUid) { - if (callingUid != android.os.Process.myUid()) { - if (getUserManager().hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { + if (callingUid != Process.myUid()) { + if (getUserManager().getUserRestrictions( + new UserHandle(UserHandle.getUserId(callingUid))) + .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { return false; } } @@ -2572,7 +2596,7 @@ public class AccountManagerService throws RemoteException { final int callingUid = getCallingUid(); - if (callingUid != android.os.Process.SYSTEM_UID) { + if (callingUid != Process.SYSTEM_UID) { throw new SecurityException(); } @@ -2692,9 +2716,9 @@ public class AccountManagerService } private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered, - int callingUid) { + int callingUid, String callingPackage) { if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0 - || callingUid == android.os.Process.myUid()) { + || callingUid == Process.myUid()) { return unfiltered; } if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) { @@ -2718,6 +2742,10 @@ public class AccountManagerService PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0); if (pi != null && pi.restrictedAccountType != null) { requiredAccountType = pi.restrictedAccountType; + // If it matches the package name of the original caller, use this choice. + if (callingPackage != null && packageName.equals(callingPackage)) { + break; + } } } } catch (NameNotFoundException nnfe) { @@ -2746,15 +2774,19 @@ public class AccountManagerService } } + /* + * packageName can be null. If not null, it should be used to filter out restricted accounts + * that the package is not allowed to access. + */ protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, - int callingUid) { + int callingUid, String callingPackage) { if (accountType != null) { final Account[] accounts = userAccounts.accountCache.get(accountType); if (accounts == null) { return EMPTY_ACCOUNT_ARRAY; } else { return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length), - callingUid); + callingUid, callingPackage); } } else { int totalLength = 0; @@ -2771,7 +2803,7 @@ public class AccountManagerService accountsOfType.length); totalLength += accountsOfType.length; } - return filterSharedAccounts(userAccounts, accounts, callingUid); + return filterSharedAccounts(userAccounts, accounts, callingUid, callingPackage); } } |