1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "permission_checker.h"
17
18 #include "access_token.h"
19 #include "admin_manager.h"
20 #include "edm_constants.h"
21 #include "edm_ipc_interface_code.h"
22 #include "edm_log.h"
23 #include "func_code_utils.h"
24 #include "ipc_skeleton.h"
25 #include "permission_manager.h"
26
27 namespace OHOS {
28 namespace EDM {
29
30 std::shared_ptr<PermissionChecker> PermissionChecker::instance_;
31 std::once_flag PermissionChecker::flag_;
32
33 std::vector<uint32_t> PermissionChecker::supportAdminNullPolicyCode_ = {
34 EdmInterfaceCode::DISALLOW_ADD_OS_ACCOUNT_BY_USER,
35 EdmInterfaceCode::DISALLOW_ADD_LOCAL_ACCOUNT,
36 EdmInterfaceCode::DISABLE_BLUETOOTH,
37 EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES,
38 EdmInterfaceCode::SET_BROWSER_POLICIES,
39 EdmInterfaceCode::MANAGED_BROWSER_POLICY,
40 EdmInterfaceCode::DISALLOW_MODIFY_DATETIME,
41 EdmInterfaceCode::LOCATION_POLICY,
42 EdmInterfaceCode::FINGERPRINT_AUTH,
43 EdmInterfaceCode::DISABLE_MICROPHONE,
44 EdmInterfaceCode::DISABLED_PRINTER,
45 EdmInterfaceCode::DISABLED_HDC,
46 EdmInterfaceCode::DISABLE_USB,
47 EdmInterfaceCode::DISALLOWED_USB_DEVICES,
48 EdmInterfaceCode::USB_READ_ONLY,
49 EdmInterfaceCode::ALLOWED_USB_DEVICES,
50 EdmInterfaceCode::DISABLE_WIFI,
51 EdmInterfaceCode::DISABLE_MTP_CLIENT,
52 EdmInterfaceCode::DISABLE_MTP_SERVER,
53 EdmInterfaceCode::DISALLOWED_TETHERING,
54 EdmInterfaceCode::INACTIVE_USER_FREEZE,
55 EdmInterfaceCode::DISABLE_CAMERA,
56 EdmInterfaceCode::PASSWORD_POLICY,
57 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_SCREEN_SHOT,
58 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_SCREEN_RECORD,
59 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_DISK_RECOVERY_KEY,
60 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_NEAR_LINK,
61 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_DEVELOPER_MODE,
62 EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_RESET_FACTORY
63 };
64
GetInstance()65 std::shared_ptr<PermissionChecker> PermissionChecker::GetInstance()
66 {
67 std::call_once(flag_, []() {
68 if (instance_ == nullptr) {
69 instance_.reset(new (std::nothrow) PermissionChecker());
70 }
71 });
72 return instance_;
73 }
74
GetExternalManagerFactory()75 std::shared_ptr<IExternalManagerFactory> PermissionChecker::GetExternalManagerFactory()
76 {
77 return externalManagerFactory_;
78 }
79
CheckCallerPermission(std::shared_ptr<Admin> admin,const std::string & permission,bool isNeedSuperAdmin)80 ErrCode PermissionChecker::CheckCallerPermission(std::shared_ptr<Admin> admin, const std::string &permission,
81 bool isNeedSuperAdmin)
82 {
83 if (admin == nullptr) {
84 return EdmReturnErrCode::ADMIN_INACTIVE;
85 }
86 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
87 if (!GetExternalManagerFactory()->CreateAccessTokenManager()->VerifyCallingPermission(tokenId, permission)) {
88 EDMLOGE("CheckCallerPermission verify calling permission failed.");
89 return EdmReturnErrCode::PERMISSION_DENIED;
90 }
91 if (FAILED(CheckCallingUid(admin->adminInfo_.packageName_))) {
92 EDMLOGE("CheckCallerPermission check calling uid failed.");
93 return EdmReturnErrCode::PERMISSION_DENIED;
94 }
95 if (isNeedSuperAdmin && admin->GetAdminType() != AdminType::ENT) {
96 EDMLOGE("CheckCallerPermission caller not a super admin.");
97 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
98 }
99 if (!isNeedSuperAdmin && admin->GetAdminType() == AdminType::VIRTUAL_ADMIN) {
100 EDMLOGE("CheckCallerPermission delegated admin does not have permission to handle.");
101 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
102 }
103 if (!isNeedSuperAdmin && admin->GetAdminType() == AdminType::BYOD) {
104 EDMLOGE("CheckCallerPermission byod admin does not have permission to handle.");
105 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
106 }
107 return ERR_OK;
108 }
109
CheckCallingUid(const std::string & bundleName)110 ErrCode PermissionChecker::CheckCallingUid(const std::string &bundleName)
111 {
112 // super admin can be removed by itself
113 int uid = IPCSkeleton::GetCallingUid();
114 std::string callingBundleName;
115 if (GetExternalManagerFactory()->CreateBundleManager()->GetNameForUid(uid, callingBundleName) != ERR_OK) {
116 EDMLOGW("CheckCallingUid failed: get bundleName for uid %{public}d fail.", uid);
117 return ERR_EDM_PERMISSION_ERROR;
118 }
119 if (bundleName == callingBundleName) {
120 return ERR_OK;
121 }
122 EDMLOGW("CheckCallingUid failed: only the app %{public}s can remove itself.", callingBundleName.c_str());
123 return ERR_EDM_PERMISSION_ERROR;
124 }
125
CheckSystemCalling(IPlugin::ApiType apiType,const std::string & permissionTag)126 ErrCode PermissionChecker::CheckSystemCalling(IPlugin::ApiType apiType, const std::string &permissionTag)
127 {
128 bool isCheckSystem = (apiType == IPlugin::ApiType::SYSTEM)
129 || (permissionTag == EdmConstants::PERMISSION_TAG_SYSTEM_API);
130 if (isCheckSystem && !CheckIsSystemAppOrNative()) {
131 EDMLOGE("CheckSystemCalling: not system app or native process");
132 return EdmReturnErrCode::SYSTEM_API_DENIED;
133 }
134 return ERR_OK;
135 }
136
GetAllPermissionsByAdmin(const std::string & bundleInfoName,AdminType adminType,int32_t userId,std::vector<std::string> & permissionList)137 ErrCode PermissionChecker::GetAllPermissionsByAdmin(const std::string &bundleInfoName, AdminType adminType,
138 int32_t userId, std::vector<std::string> &permissionList)
139 {
140 permissionList.clear();
141 AppExecFwk::BundleInfo bundleInfo;
142 EDMLOGD("GetAllPermissionsByAdmin GetBundleInfo: bundleInfoName %{public}s userid %{public}d",
143 bundleInfoName.c_str(), userId);
144 bool ret = GetExternalManagerFactory()->CreateBundleManager()->GetBundleInfo(bundleInfoName,
145 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION, bundleInfo, userId);
146 if (!ret) {
147 EDMLOGW("GetAllPermissionsByAdmin: GetBundleInfo failed %{public}d", ret);
148 return ERR_EDM_PARAM_ERROR;
149 }
150 PermissionManager::GetInstance()->GetAdminGrantedPermission(bundleInfo.reqPermissions, adminType, permissionList);
151 return ERR_OK;
152 }
153
CheckHandlePolicyPermission(FuncOperateType operateType,const std::string & bundleName,const std::string & policyName,const std::string & permissionName,int32_t userId)154 ErrCode PermissionChecker::CheckHandlePolicyPermission(FuncOperateType operateType,
155 const std::string &bundleName, const std::string &policyName, const std::string &permissionName, int32_t userId)
156 {
157 if (operateType == FuncOperateType::SET && permissionName.empty()) {
158 EDMLOGE("CheckHandlePolicyPermission failed, set policy need permission.");
159 return EdmReturnErrCode::PERMISSION_DENIED;
160 }
161 if (permissionName == NONE_PERMISSION_MATCH) {
162 EDMLOGE("CheckHandlePolicyPermission: GetPermission failed!");
163 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
164 }
165 std::shared_ptr<Admin> deviceAdmin = AdminManager::GetInstance()->GetAdminByPkgName(bundleName, GetCurrentUserId());
166 if (deviceAdmin == nullptr) {
167 EDMLOGE("CheckHandlePolicyPermission: get admin failed");
168 return EdmReturnErrCode::ADMIN_INACTIVE;
169 }
170 if (FAILED(CheckCallingUid(deviceAdmin->adminInfo_.packageName_))) {
171 EDMLOGE("CheckHandlePolicyPermission: CheckCallingUid failed.");
172 return EdmReturnErrCode::PERMISSION_DENIED;
173 }
174 if (operateType == FuncOperateType::SET && deviceAdmin->GetAdminType() == AdminType::NORMAL &&
175 userId != GetCurrentUserId()) {
176 EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle policy of other account.");
177 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
178 }
179 if (!permissionName.empty()) {
180 EDMLOGI("CheckHandlePolicyPermission: permissionName:%{public}s", permissionName.c_str());
181 auto ret = CheckAndUpdatePermission(deviceAdmin, IPCSkeleton::GetCallingTokenID(), permissionName, userId);
182 if (FAILED(ret)) {
183 return ret;
184 }
185 }
186 if (permissionName.empty() && deviceAdmin->GetAdminType() == AdminType::BYOD) {
187 return EdmReturnErrCode::PERMISSION_DENIED;
188 }
189 if (!AdminManager::GetInstance()->HasPermissionToHandlePolicy(deviceAdmin, policyName)) {
190 EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle the policy.");
191 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
192 }
193 return ERR_OK;
194 }
195
CheckAndUpdatePermission(std::shared_ptr<Admin> admin,Security::AccessToken::AccessTokenID tokenId,const std::string & permission,int32_t userId)196 ErrCode PermissionChecker::CheckAndUpdatePermission(std::shared_ptr<Admin> admin,
197 Security::AccessToken::AccessTokenID tokenId, const std::string &permission, int32_t userId)
198 {
199 if (admin == nullptr) {
200 EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle the policy.");
201 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
202 }
203 bool callingPermission = VerifyCallingPermission(tokenId, permission);
204 bool adminPermission = admin->CheckPermission(permission);
205 EDMLOGI("CheckAndUpdatePermission::callingPermission: %{public}d.adminPermission:%{public}d", callingPermission,
206 adminPermission);
207 if (callingPermission != adminPermission) {
208 std::vector<std::string> permissionList;
209 if (FAILED(GetAllPermissionsByAdmin(admin->adminInfo_.packageName_,
210 admin->GetAdminType(), userId, permissionList))) {
211 EDMLOGE("CheckAndUpdatePermission get all permission that admin request failed.");
212 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
213 }
214 auto hasPermission = std::find(permissionList.begin(), permissionList.end(), permission);
215 if (!callingPermission && hasPermission != permissionList.end()) {
216 EDMLOGE("CheckAndUpdatePermission access token check abnormally.");
217 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
218 }
219 if (!adminPermission && hasPermission == permissionList.end()) {
220 EDMLOGE("CheckAndUpdatePermission this admin does not have the permission.");
221 return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
222 }
223 Admin updateAdmin(admin->adminInfo_.packageName_, admin->GetAdminType(), permissionList);
224 updateAdmin.SetAccessiblePolicies(admin->adminInfo_.accessiblePolicies_);
225 if (FAILED(AdminManager::GetInstance()->UpdateAdmin(admin, userId, updateAdmin))) {
226 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
227 }
228 }
229 if (!callingPermission) {
230 return EdmReturnErrCode::PERMISSION_DENIED;
231 }
232 return ERR_OK;
233 }
234
GetCurrentUserId()235 int32_t PermissionChecker::GetCurrentUserId()
236 {
237 std::vector<int32_t> ids;
238 auto fac = GetExternalManagerFactory();
239 ErrCode ret = fac->CreateOsAccountManager()->QueryActiveOsAccountIds(ids);
240 if (FAILED(ret) || ids.empty()) {
241 EDMLOGE("PermissionChecker GetCurrentUserId failed");
242 return -1;
243 }
244 EDMLOGD("PermissionChecker GetCurrentUserId user id = %{public}d", ids.at(0));
245 return (ids.at(0));
246 }
247
AdminTypeToPermissionType(AdminType adminType)248 IPlugin::PermissionType PermissionChecker::AdminTypeToPermissionType(AdminType adminType)
249 {
250 if (adminType == AdminType::BYOD) {
251 return IPlugin::PermissionType::BYOD_DEVICE_ADMIN;
252 }
253 return IPlugin::PermissionType::SUPER_DEVICE_ADMIN;
254 }
255
CheckElementNullPermission(uint32_t funcCode,const std::string & permissionName)256 bool PermissionChecker::CheckElementNullPermission(uint32_t funcCode, const std::string &permissionName)
257 {
258 std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode);
259 auto item = std::find(supportAdminNullPolicyCode_.begin(), supportAdminNullPolicyCode_.end(), code);
260 if (item == supportAdminNullPolicyCode_.end()) {
261 EDMLOGE("PermissionChecker not support element null query code is %{public}d", code);
262 return false;
263 }
264 if (permissionName.empty()) {
265 return true;
266 }
267 if (CheckSpecialPolicyCallQuery(code)) {
268 return true;
269 }
270 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
271 if (!VerifyCallingPermission(tokenId, permissionName)) {
272 EDMLOGE("PermissionChecker element null query no permission code is %{public}d", code);
273 return false;
274 }
275 return true;
276 }
277
CheckSpecialPolicyCallQuery(uint32_t code)278 bool PermissionChecker::CheckSpecialPolicyCallQuery(uint32_t code)
279 {
280 bool isSystemAppCall = GetExternalManagerFactory()->CreateAccessTokenManager()->IsSystemAppCall();
281 if (isSystemAppCall) {
282 return true;
283 }
284 bool isNativeCall = GetExternalManagerFactory()->CreateAccessTokenManager()->IsNativeCall();
285 if (isNativeCall) {
286 int uid = IPCSkeleton::GetCallingUid();
287 if (code == EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES) {
288 return uid == EdmConstants::BLUETOOTH_SERVICE_UID;
289 } else if (code == EdmInterfaceCode::PASSWORD_POLICY) {
290 return uid == EdmConstants::USERIAM_SERVICE_UID;
291 }
292 }
293 return false;
294 }
295
CheckIsDebug()296 bool PermissionChecker::CheckIsDebug()
297 {
298 return GetExternalManagerFactory()->CreateAccessTokenManager()->IsDebug();
299 }
300
CheckIsSystemAppOrNative()301 bool PermissionChecker::CheckIsSystemAppOrNative()
302 {
303 return GetExternalManagerFactory()->CreateAccessTokenManager()->IsSystemAppOrNative();
304 }
305
VerifyCallingPermission(Security::AccessToken::AccessTokenID tokenId,const std::string & permissionName)306 bool PermissionChecker::VerifyCallingPermission(Security::AccessToken::AccessTokenID tokenId,
307 const std::string &permissionName)
308 {
309 return GetExternalManagerFactory()->CreateAccessTokenManager()->VerifyCallingPermission(tokenId, permissionName);
310 }
311 } // namespace EDM
312 } // namespace OHOS
313