• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "admin_manager.h"
17 #include <algorithm>
18 #include <ctime>
19 #include <fstream>
20 #include <iostream>
21 #include "edm_log.h"
22 #include "permission_manager.h"
23 #include "super_admin.h"
24 
25 namespace OHOS {
26 namespace EDM {
27 const std::string EDM_ADMIN_JSON_FILE = "/data/system/admin_policies.json";
28 std::shared_ptr<AdminManager> AdminManager::instance_;
29 std::mutex AdminManager::mutexLock_;
30 
GetInstance()31 std::shared_ptr<AdminManager> AdminManager::GetInstance()
32 {
33     if (instance_ == nullptr) {
34         std::lock_guard<std::mutex> autoLock(mutexLock_);
35         if (instance_ == nullptr) {
36             instance_.reset(new AdminManager());
37         }
38     }
39     return instance_;
40 }
41 
AdminManager()42 AdminManager::AdminManager()
43 {
44     EDMLOGI("AdminManager::AdminManager");
45 }
46 
~AdminManager()47 AdminManager::~AdminManager()
48 {
49     EDMLOGI("AdminManager::~AdminManager");
50     admins_.clear();
51 }
52 
GetReqPermission(const std::vector<std::string> & permissions,std::vector<EdmPermission> & reqPermissions)53 ErrCode AdminManager::GetReqPermission(const std::vector<std::string> &permissions,
54     std::vector<EdmPermission> &reqPermissions)
55 {
56     EDMLOGD("AdminManager::GetReqPermission");
57     PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermissions);
58     return reqPermissions.empty() ? ERR_EDM_EMPTY_PERMISSIONS : ERR_OK;
59 }
60 
SetAdminValue(AppExecFwk::AbilityInfo & abilityInfo,EntInfo & entInfo,AdminType role,std::vector<std::string> & permissions)61 ErrCode AdminManager::SetAdminValue(AppExecFwk::AbilityInfo &abilityInfo, EntInfo &entInfo, AdminType role,
62     std::vector<std::string> &permissions)
63 {
64     std::vector<AdminPermission> reqPermission;
65     std::vector<std::string> permissionNames;
66     PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission);
67     if (reqPermission.empty()) {
68         EDMLOGW("SetAdminValue::the application is requesting useless permissions");
69     }
70     for (const auto &it : reqPermission) {
71         if (role == AdminType::NORMAL && it.adminType == AdminType::ENT) {
72             return ERR_EDM_DENY_PERMISSION;
73         }
74         permissionNames.push_back(it.permissionName);
75     }
76 
77     std::shared_ptr<Admin> adminItem = GetAdminByPkgName(abilityInfo.bundleName);
78     if (adminItem == nullptr) {
79         if (role == NORMAL) {
80             admins_.emplace_back(std::make_shared<Admin>());
81         } else {
82             admins_.emplace_back(std::make_shared<SuperAdmin>());
83         }
84         adminItem = admins_.back();
85     }
86     adminItem->adminInfo_.adminType_ = role;
87     adminItem->adminInfo_.entInfo_ = entInfo;
88     adminItem->adminInfo_.permission_ = permissionNames;
89     adminItem->adminInfo_.packageName_ = abilityInfo.bundleName;
90     adminItem->adminInfo_.className_ = abilityInfo.name;
91     SaveAdmin();
92     return ERR_OK;
93 }
94 
GetAllAdmin(std::vector<std::shared_ptr<Admin>> & allAdmin)95 void AdminManager::GetAllAdmin(std::vector<std::shared_ptr<Admin>> &allAdmin)
96 {
97     allAdmin = admins_;
98 }
99 
GetAdminByPkgName(const std::string & packageName)100 std::shared_ptr<Admin> AdminManager::GetAdminByPkgName(const std::string &packageName)
101 {
102     for (auto &item : admins_) {
103         if (item->adminInfo_.packageName_ == packageName) {
104             return item;
105         }
106     }
107     EDMLOGD("GetAdminByPkgName:get admin failed. admin size= %{public}u, packageName= %{public}s",
108         (uint32_t)admins_.size(), packageName.c_str());
109     return nullptr;
110 }
111 
DeleteAdmin(const std::string & packageName)112 ErrCode AdminManager::DeleteAdmin(const std::string &packageName)
113 {
114     ErrCode retCode;
115     auto iter = admins_.begin();
116     while (iter != admins_.end()) {
117         if ((*iter)->adminInfo_.packageName_ == packageName) {
118             iter = admins_.erase(iter);
119             retCode = ERR_OK;
120         } else {
121             iter++;
122         }
123     }
124     if (SUCCEEDED(retCode)) {
125         EDMLOGD("SaveAdmin %{public}s", packageName.c_str());
126         SaveAdmin();
127         return retCode;
128     }
129 
130     EDMLOGW("delete admin (%{public}s) failed!", packageName.c_str());
131     return ERR_EDM_UNKNOWN_ADMIN;
132 }
133 
GetGrantedPermission(AppExecFwk::AbilityInfo & abilityInfo,std::vector<std::string> & permissions,AdminType type)134 ErrCode AdminManager::GetGrantedPermission(AppExecFwk::AbilityInfo &abilityInfo, std::vector<std::string> &permissions,
135     AdminType type)
136 {
137     if (permissions.empty()) {
138         EDMLOGW("GetGrantedPermission: permissions is empty");
139         return ERR_OK;
140     }
141     // filtering out non-edm permissions
142     std::vector<AdminPermission> reqPermission;
143     PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission);
144     if (reqPermission.empty()) {
145         EDMLOGW("GetGrantedPermission: edm permission is empty");
146         return ERR_OK;
147     }
148 
149     // filter out super permissions if admin is NORMAL
150     std::vector<std::string> permissionNameList;
151     for (const auto &it : reqPermission) {
152         if ((type == AdminType::NORMAL) && (it.adminType == AdminType::ENT)) {
153             continue;
154         }
155         permissionNameList.push_back(it.permissionName);
156     }
157     permissions.assign(permissionNameList.begin(), permissionNameList.end());
158     return ERR_OK;
159 }
160 
UpdateAdmin(AppExecFwk::AbilityInfo & abilityInfo,const std::vector<std::string> & permissions)161 ErrCode AdminManager::UpdateAdmin(AppExecFwk::AbilityInfo &abilityInfo, const std::vector<std::string> &permissions)
162 {
163     auto adminItem = GetAdminByPkgName(abilityInfo.bundleName);
164     if (adminItem == nullptr) {
165         EDMLOGW("UpdateAdmin: get null admin, never get here");
166         return ERR_EDM_UNKNOWN_ADMIN;
167     }
168 
169     std::vector<std::string> combinePermission = permissions;
170     ErrCode ret = GetGrantedPermission(abilityInfo, combinePermission, adminItem->adminInfo_.adminType_);
171     if (ret != ERR_OK) {
172         EDMLOGW("UpdateAdmin: GetGrantedPermission failed");
173         return ret;
174     }
175 
176     adminItem->adminInfo_.permission_ = combinePermission;
177     adminItem->adminInfo_.packageName_ = abilityInfo.bundleName;
178     adminItem->adminInfo_.className_ = abilityInfo.className;
179     SaveAdmin();
180     return ERR_OK;
181 }
182 
183 // success is returned as long as there is a super administrator
IsSuperAdminExist()184 bool AdminManager::IsSuperAdminExist()
185 {
186     return std::any_of(admins_.begin(), admins_.end(),
187         [](const std::shared_ptr<Admin> &admin) { return admin->adminInfo_.adminType_ == AdminType::ENT; });
188 }
189 
190 /*
191  * There are different administrator types according to the input parameters.
192  * Returns a list of package names
193  */
GetActiveAdmin(AdminType role,std::vector<std::string> & packageNameList)194 void AdminManager::GetActiveAdmin(AdminType role, std::vector<std::string> &packageNameList)
195 {
196     EDMLOGD("AdminManager:GetActiveAdmin adminType: %{public}d , admin size: %{public}zu", role, admins_.size());
197     packageNameList.clear();
198     if (role >= AdminType::UNKNOWN || role < AdminType::NORMAL) {
199         EDMLOGD("there is no admin(%{public}u) device manager package name list!", role);
200         return;
201     }
202 
203     for (auto &item : admins_) {
204         if (item->adminInfo_.adminType_ == role) {
205             std::string adminName = item->adminInfo_.packageName_ + "/" + item->adminInfo_.className_;
206             packageNameList.push_back(adminName);
207         }
208     }
209 }
210 
GetEntInfo(const std::string & packageName,EntInfo & entInfo)211 ErrCode AdminManager::GetEntInfo(const std::string &packageName, EntInfo &entInfo)
212 {
213     for (auto &item : admins_) {
214         if (item->adminInfo_.packageName_ == packageName) {
215             entInfo = item->adminInfo_.entInfo_;
216             return ERR_OK;
217         }
218     }
219     return ERR_EDM_UNKNOWN_ADMIN;
220 }
221 
SetEntInfo(const std::string & packageName,EntInfo & entInfo)222 ErrCode AdminManager::SetEntInfo(const std::string &packageName, EntInfo &entInfo)
223 {
224     for (auto &item : admins_) {
225         if (item->adminInfo_.packageName_ == packageName) {
226             item->adminInfo_.entInfo_ = entInfo;
227             SaveAdmin();
228             return ERR_OK;
229         }
230     }
231     return ERR_EDM_UNKNOWN_ADMIN;
232 }
233 
234 // init
Init()235 void AdminManager::Init()
236 {
237     RestoreAdminFromFile();
238 }
239 
FindPackageAndClass(const std::string & name,std::string & packageName,std::string & className)240 void FindPackageAndClass(const std::string &name, std::string &packageName, std::string &className)
241 {
242     std::size_t initPos = name.find('/', 0);
243     std::size_t len = name.size();
244     packageName = name.substr(0, initPos);
245     className = name.substr(initPos + 1, len - (initPos + 1));
246 }
247 
ReadJsonAdminType(Json::Value & admin)248 void AdminManager::ReadJsonAdminType(Json::Value &admin)
249 {
250     std::shared_ptr<Admin> activeAdmin;
251     if (admin["adminType"].asUInt() == AdminType::NORMAL) {
252         activeAdmin = std::make_shared<Admin>();
253     } else if (admin["adminType"].asUInt() == AdminType::ENT) {
254         activeAdmin = std::make_shared<SuperAdmin>();
255     } else {
256         EDMLOGD("admin type is error!");
257         return;
258     }
259 
260     FindPackageAndClass(admin["name"].asString(), activeAdmin->adminInfo_.packageName_,
261         activeAdmin->adminInfo_.className_);
262     activeAdmin->adminInfo_.adminType_ = static_cast<AdminType>(admin["adminType"].asUInt());
263     activeAdmin->adminInfo_.entInfo_.enterpriseName = admin["enterpriseInfo"]["enterpriseName"].asString(); // object
264     activeAdmin->adminInfo_.entInfo_.description = admin["enterpriseInfo"]["declaration"].asString();
265     unsigned int adminSize = admin["permission"].size();
266     for (unsigned int i = 0; i < adminSize; i++) {
267         activeAdmin->adminInfo_.permission_.push_back(admin["permission"][i].asString()); // array
268     }
269 
270     // read admin and store it in vector container
271     admins_.push_back(activeAdmin);
272 }
273 
ReadJsonAdmin(const std::string & filePath)274 void AdminManager::ReadJsonAdmin(const std::string &filePath)
275 {
276     std::ifstream is(filePath);
277     JSONCPP_STRING errs;
278     Json::Value root, lang;
279     Json::CharReaderBuilder readerBuilder;
280 
281     if (!is.is_open()) {
282         EDMLOGE("ReadJsonAdmin open admin policies file failed!");
283         return;
284     }
285     bool res = parseFromStream(readerBuilder, is, &root, &errs);
286     if (!res || !errs.empty()) {
287         // no data, return
288         EDMLOGW("AdminManager:read admin policies file is :%{public}d , is not empty: %{public}d", res, errs.empty());
289         is.close();
290         return;
291     }
292     is.close();
293 
294     lang = root["admin"];
295     EDMLOGD("AdminManager: size of %{public}u", lang.size());
296 
297     for (auto temp : lang) {
298         ReadJsonAdminType(temp);
299     }
300 }
301 
302 // read admin from file
RestoreAdminFromFile()303 void AdminManager::RestoreAdminFromFile()
304 {
305     // admin information storage location
306     ReadJsonAdmin(EDM_ADMIN_JSON_FILE);
307 }
308 
WriteJsonAdminType(std::shared_ptr<Admin> & activeAdmin,Json::Value & tree)309 void AdminManager::WriteJsonAdminType(std::shared_ptr<Admin> &activeAdmin, Json::Value &tree)
310 {
311     Json::Value entTree;
312     Json::Value permissionTree;
313 
314     tree["name"] = activeAdmin->adminInfo_.packageName_ + "/" + activeAdmin->adminInfo_.className_;
315     tree["adminType"] = activeAdmin->adminInfo_.adminType_;
316 
317     entTree["enterpriseName"] = activeAdmin->adminInfo_.entInfo_.enterpriseName;
318     entTree["declaration"] = activeAdmin->adminInfo_.entInfo_.description;
319     tree["enterpriseInfo"] = entTree;
320 
321     for (auto &it : activeAdmin->adminInfo_.permission_) {
322         permissionTree.append(it);
323     }
324     tree["permission"] = permissionTree;
325 }
326 
WriteJsonAdmin(const std::string & filePath)327 void AdminManager::WriteJsonAdmin(const std::string &filePath)
328 {
329     Json::Value root, tree, temp;
330 
331     EDMLOGD("WriteJsonAdmin start!  size = %{public}u  empty = %{public}d", (uint32_t)admins_.size(), admins_.empty());
332     // structure of each admin
333     for (std::uint32_t i = 0; i < admins_.size(); i++) {
334         WriteJsonAdminType(admins_.at(i), temp);
335         tree.append(temp);
336     }
337     // root
338     root["admin"] = tree;
339 
340     double time1 = clock();
341     // write to file
342     std::ofstream ofs(filePath);
343     if (!ofs.is_open()) {
344         EDMLOGE("WriteJsonAdmin open admin policies file failed!");
345         return;
346     }
347 
348     Json::StreamWriterBuilder builder;
349     builder["indentation"] = "    ";
350     const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
351     writer->write(root, &ofs);
352     ofs.flush();
353     ofs.close();
354     double time2 = clock();
355     if (time1 != 0 && time2 != 0) {
356         EDMLOGD("WriteJsonAdmin spend time %{public}f", (time2 - time1) / CLOCKS_PER_SEC);
357     }
358 }
359 
360 // write admin to file
SaveAdmin()361 void AdminManager::SaveAdmin()
362 {
363     WriteJsonAdmin(EDM_ADMIN_JSON_FILE);
364 }
365 } // namespace EDM
366 } // namespace OHOS
367