1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "permission_helpers.h" 18 19 #include <base/logging.h> 20 #include <base/strings/stringprintf.h> 21 #include <binder/IPCThreadState.h> 22 #include <binder/IServiceManager.h> 23 #include <pwd.h> 24 #include <sys/types.h> 25 #include "IUserManager.h" 26 27 using ::android::binder::Status; 28 29 namespace android { 30 namespace bluetooth { 31 32 uid_t foregroundUserId; 33 uid_t systemUiUid; 34 static uid_t SYSTEM_UID = 1000; 35 constexpr int PER_USER_RANGE = 100000; 36 37 Status checkPermission(const char* permission) { 38 int32_t pid; 39 int32_t uid; 40 41 if (android::checkCallingPermission(String16(permission), &pid, &uid)) { 42 return Status::ok(); 43 } 44 45 auto err = ::base::StringPrintf("UID %d / PID %d lacks permission %s", uid, 46 pid, permission); 47 return Status::fromExceptionCode(Status::EX_SECURITY, String8(err.c_str())); 48 } 49 50 bool isCallerActiveUser() { 51 IPCThreadState* ipcState = IPCThreadState::selfOrNull(); 52 if (!ipcState) return true; // It's a local call 53 54 uid_t callingUid = ipcState->getCallingUid(); 55 uid_t callingUser = callingUid / PER_USER_RANGE; 56 if (callingUid == getuid()) return true; // It's a local call 57 58 return (foregroundUserId == callingUser) || (systemUiUid == callingUid) || 59 (SYSTEM_UID == callingUid); 60 } 61 62 bool isCallerActiveUserOrManagedProfile() { 63 IPCThreadState* ipcState = IPCThreadState::selfOrNull(); 64 if (!ipcState) return true; // It's a local call 65 66 uid_t callingUid = ipcState->getCallingUid(); 67 uid_t callingUser = callingUid / PER_USER_RANGE; 68 if (callingUid == getuid()) return true; // It's a local call 69 70 if ((foregroundUserId == callingUser) || (systemUiUid == callingUid) || 71 (SYSTEM_UID == callingUid)) 72 return true; 73 74 uid_t parentUser = callingUser; 75 76 sp<IServiceManager> sm = defaultServiceManager(); 77 sp<IBinder> binder = sm->getService(String16("user")); 78 sp<IUserManager> um = interface_cast<IUserManager>(binder); 79 if (um != NULL) { 80 // Must use Bluetooth process identity when making call to get parent user 81 int64_t ident = ipcState->clearCallingIdentity(); 82 parentUser = um->getProfileParentId(callingUser); 83 ipcState->restoreCallingIdentity(ident); 84 } 85 86 return foregroundUserId == parentUser; 87 } 88 89 } // namespace bluetooth 90 } // namespace android 91