1 /*
2 * Copyright (c) 2021-2024 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 "user/user_manager.h"
17 #include "bundle_mgr_client.h"
18
19 #ifdef USER_CRYPTO_MANAGER
20 #include "crypto/key_manager.h"
21 #endif
22 #include "ipc/istorage_daemon.h"
23 #include "storage_service_constant.h"
24 #include "storage_service_errno.h"
25 #include "storage_service_log.h"
26 #include "utils/storage_radar.h"
27 #include "utils/string_utils.h"
28
29 using namespace std;
30 using namespace OHOS::StorageService;
31 namespace OHOS {
32 namespace StorageDaemon {
33 static constexpr int MODE_0711 = 0711;
34 static constexpr int MODE_02771 = 02771;
35 std::shared_ptr<UserManager> UserManager::instance_ = nullptr;
UserManager()36 UserManager::UserManager()
37 : rootDirVec_{{"/data/app/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
38 {"/data/service/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
39 {"/data/chipset/%s/%d", MODE_0711, OID_ROOT, OID_ROOT}},
40 el3DirEl4DirEl5DirVec_{{"/data/app/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
41 {"/data/service/%s/%d", MODE_0711, OID_ROOT, OID_ROOT}},
42 subDirVec_{{"/data/app/%s/%d/base", MODE_0711, OID_ROOT, OID_ROOT},
43 {"/data/app/%s/%d/database", MODE_0711, OID_ROOT, OID_ROOT}},
44 el2DirVec_{{"/data/service/el2/%d/backup", MODE_02771, OID_BACKUP, OID_BACKUP},
45 {"/data/service/el2/%d/backup/backup_sa", MODE_0711, OID_BACKUP, OID_BACKUP},
46 {"/data/service/el2/%d/backup/bundles", MODE_0711, OID_BACKUP, OID_BACKUP},
47 {"/data/app/el2/%d/log", MODE_0711, OID_ROOT, OID_ROOT}},
48 el1DirVec_{{"/data/service/el1/%d/distributeddata", MODE_0711, OID_DDMS, OID_DDMS},
49 {"/data/service/el1/%d/backup", MODE_02771, OID_BACKUP, OID_BACKUP},
50 {"/data/service/el1/%d/backup/bundles", MODE_0711, OID_BACKUP, OID_BACKUP},
51 {"/data/service/el1/%d/utdtypes", MODE_0711, OID_FOUNDATION, OID_FOUNDATION},
52 {"/data/app/el1/%d/aot_compiler", MODE_0711, OID_ROOT, OID_ROOT},
53 {"/data/app/el1/%d/aot_compiler/ark_profile", MODE_0711, OID_ROOT, OID_ROOT}}
54 {
55 }
56
GetInstance()57 std::shared_ptr<UserManager> UserManager::GetInstance()
58 {
59 static std::once_flag onceFlag;
60 std::call_once(onceFlag, [&]() { instance_ = std::make_shared<UserManager>(); });
61
62 return instance_;
63 }
64
StartUser(int32_t userId)65 int32_t UserManager::StartUser(int32_t userId)
66 {
67 LOGI("start user %{public}d", userId);
68 std::lock_guard<std::mutex> lock(mutex_);
69 int32_t err = CheckUserIdRange(userId);
70 if (err != E_OK) {
71 LOGE("UserManager::StartUser userId %{public}d out of range", userId);
72 return err;
73 }
74 return MountManager::GetInstance()->MountByUser(userId);
75 }
76
StopUser(int32_t userId)77 int32_t UserManager::StopUser(int32_t userId)
78 {
79 LOGI("stop user %{public}d", userId);
80 std::lock_guard<std::mutex> lock(mutex_);
81 int32_t err = CheckUserIdRange(userId);
82 if (err != E_OK) {
83 LOGE("UserManager::StopUser userId %{public}d out of range", userId);
84 return err;
85 }
86 return MountManager::GetInstance()->UmountByUser(userId);
87 }
88
PrepareUserDirs(int32_t userId,uint32_t flags)89 int32_t UserManager::PrepareUserDirs(int32_t userId, uint32_t flags)
90 {
91 LOGI("prepare user dirs for %{public}d, flags %{public}u", userId, flags);
92 std::lock_guard<std::mutex> lock(mutex_);
93 int32_t err = CheckCrypto(userId, flags);
94 if (err != E_OK) {
95 return err;
96 }
97 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
98 err = MountManager::GetInstance()->PrepareHmdfsDirs(userId);
99 if (err != E_OK) {
100 LOGE("Prepare hmdfs dir error");
101 return err;
102 }
103 err = MountManager::GetInstance()->PrepareFileManagerDirs(userId);
104 if (err != E_OK) {
105 LOGE("Prepare fileManager dir error");
106 return err;
107 }
108 }
109
110 return E_OK;
111 }
112
DestroyUserDirs(int32_t userId,uint32_t flags)113 int32_t UserManager::DestroyUserDirs(int32_t userId, uint32_t flags)
114 {
115 LOGI("destroy user dirs for %{public}d, flags %{public}u", userId, flags);
116 std::lock_guard<std::mutex> lock(mutex_);
117 int32_t err = CheckUserIdRange(userId);
118 if (err != E_OK) {
119 LOGE("UserManager::DestroyUserDirs userId %{public}d out of range", userId);
120 return err;
121 }
122 int32_t ret = E_OK;
123 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
124 err = DestroyDirsFromIdAndLevel(userId, EL1);
125 ret = (err != E_OK) ? err : ret;
126
127 err = DestroyEl1BundleDir(userId);
128 ret = (err != E_OK) ? err : ret;
129 }
130 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
131 err = DestroyDirsFromIdAndLevel(userId, EL2);
132 ret = (err != E_OK) ? err : ret;
133
134 err = MountManager::GetInstance()->DestroyFileManagerDirs(userId);
135 ret = (err != E_OK) ? err : ret;
136
137 err = MountManager::GetInstance()->DestroyHmdfsDirs(userId);
138 ret = (err != E_OK) ? err : ret;
139
140 err = MountManager::GetInstance()->DestroySystemServiceDirs(userId);
141 ret = (err != E_OK) ? err : ret;
142
143 err = DestroyEl2BackupDir(userId);
144 ret = (err != E_OK) ? err : ret;
145
146 err = DestroyEl1Dir(userId);
147 ret = (err != E_OK) ? err : ret;
148 }
149 if (flags & IStorageDaemon::CRYPTO_FLAG_EL3) {
150 err = DestroyDirsFromIdAndLevel(userId, EL3);
151 ret = (err != E_OK) ? err : ret;
152 }
153 if (flags & IStorageDaemon::CRYPTO_FLAG_EL4) {
154 err = DestroyDirsFromIdAndLevel(userId, EL4);
155 ret = (err != E_OK) ? err : ret;
156 }
157 if (flags & IStorageDaemon::CRYPTO_FLAG_EL5) {
158 err = DestroyDirsFromIdAndLevel(userId, EL5);
159 ret = (err != E_OK) ? err : ret;
160 }
161
162 return ret;
163 }
164
PrepareDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)165 inline bool PrepareDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
166 {
167 for (const DirInfo &dir : vec) {
168 if (!PrepareDir(StringPrintf(dir.path.c_str(), level.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
169 return false;
170 }
171 }
172
173 return true;
174 }
175
DestroyDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)176 inline bool DestroyDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
177 {
178 bool err = true;
179
180 for (const DirInfo &dir : vec) {
181 if (IsEndWith(dir.path.c_str(), "%d")) {
182 err = RmDirRecurse(StringPrintf(dir.path.c_str(), level.c_str(), userId));
183 }
184 }
185
186 return err;
187 }
188
PrepareDirsFromIdAndLevel(int32_t userId,const std::string & level)189 int32_t UserManager::PrepareDirsFromIdAndLevel(int32_t userId, const std::string &level)
190 {
191 std::vector<FileList> list;
192 if (level != EL3 && level != EL4 && level != EL5) {
193 if (!PrepareDirsFromVec(userId, level, rootDirVec_)) {
194 LOGE("failed to prepare %{public}s root dirs for userid %{public}d", level.c_str(), userId);
195 if (level != EL1) {
196 return E_PREPARE_DIR;
197 }
198 }
199 // set policy here
200 for (auto item : rootDirVec_) {
201 FileList temp;
202 temp.userId = static_cast<uint32_t>(userId);
203 temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
204 list.push_back(temp);
205 }
206 } else {
207 if (!PrepareDirsFromVec(userId, level, el3DirEl4DirEl5DirVec_)) {
208 LOGE("failed to prepare %{public}s root dirs for userid %{public}d", level.c_str(), userId);
209 return E_PREPARE_DIR;
210 }
211 // set policy here
212 for (auto item : el3DirEl4DirEl5DirVec_) {
213 FileList temp;
214 temp.userId = static_cast<uint32_t>(userId);
215 temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
216 list.push_back(temp);
217 }
218 }
219 int ret = SetElDirFscryptPolicy(userId, level, list);
220 if (ret != E_OK) {
221 LOGE("Set el poilcy failed");
222 return ret;
223 }
224
225 if (!PrepareDirsFromVec(userId, level, subDirVec_)) {
226 LOGE("failed to prepare %{public}s sub dirs for userid %{public}d", level.c_str(), userId);
227 return E_PREPARE_DIR;
228 }
229
230 return E_OK;
231 }
232
DestroyDirsFromIdAndLevel(int32_t userId,const std::string & level)233 int32_t UserManager::DestroyDirsFromIdAndLevel(int32_t userId, const std::string &level)
234 {
235 if (level != EL3 && level != EL4 && level != EL5) {
236 if (!DestroyDirsFromVec(userId, level, rootDirVec_)) {
237 LOGE("failed to destroy %{public}s dirs for userid %{public}d", level.c_str(), userId);
238 return E_DESTROY_DIR;
239 }
240 } else {
241 if (!DestroyDirsFromVec(userId, level, el3DirEl4DirEl5DirVec_)) {
242 LOGE("failed to destroy %{public}s dirs for userid %{public}d", level.c_str(), userId);
243 return E_DESTROY_DIR;
244 }
245 }
246 return E_OK;
247 }
248
PrepareEl1BundleDir(int32_t userId)249 int32_t UserManager::PrepareEl1BundleDir(int32_t userId)
250 {
251 if (!PrepareDir(StringPrintf(bundle_.c_str(), userId), MODE_0711, OID_ROOT, OID_ROOT)) {
252 return E_PREPARE_DIR;
253 }
254
255 // set policy here
256 std::vector<FileList> list;
257 FileList temp;
258 temp.userId = static_cast<uint32_t>(userId);
259 temp.path = StringPrintf(bundle_.c_str(), userId);
260 list.push_back(temp);
261 int ret = SetElDirFscryptPolicy(userId, EL1, list);
262 if (ret != E_OK) {
263 LOGE("Set el1 poilcy failed");
264 return ret;
265 }
266
267 return E_OK;
268 }
269
DestroyEl1BundleDir(int32_t userId)270 int32_t UserManager::DestroyEl1BundleDir(int32_t userId)
271 {
272 if (!RmDirRecurse(StringPrintf(bundle_.c_str(), userId))) {
273 return E_DESTROY_DIR;
274 }
275
276 return E_OK;
277 }
278
SetElDirFscryptPolicy(int32_t userId,const std::string & level,const std::vector<FileList> & list)279 int32_t UserManager::SetElDirFscryptPolicy(int32_t userId, const std::string &level,
280 const std::vector<FileList> &list)
281 {
282 #ifdef USER_CRYPTO_MANAGER
283 if (EL_DIR_MAP.find(level) == EL_DIR_MAP.end()) {
284 LOGE("el type error");
285 return E_SET_POLICY;
286 }
287 if (KeyManager::GetInstance()->SetDirectoryElPolicy(userId, EL_DIR_MAP[level], list)) {
288 LOGE("Set user dir el1 policy error");
289 return E_SET_POLICY;
290 }
291 #endif
292
293 return E_OK;
294 }
295
PrepareEl2BackupDir(int32_t userId)296 int32_t UserManager::PrepareEl2BackupDir(int32_t userId)
297 {
298 for (const DirInfo &dir : el2DirVec_) {
299 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
300 return E_PREPARE_DIR;
301 }
302 }
303
304 return E_OK;
305 }
306
DestroyEl2BackupDir(int32_t userId)307 int32_t UserManager::DestroyEl2BackupDir(int32_t userId)
308 {
309 for (const DirInfo &dir : el2DirVec_) {
310 if (!RmDirRecurse(StringPrintf(dir.path.c_str(), userId))) {
311 return E_DESTROY_DIR;
312 }
313 }
314
315 return E_OK;
316 }
317
PrepareEl1Dir(int32_t userId)318 int32_t UserManager::PrepareEl1Dir(int32_t userId)
319 {
320 for (const DirInfo &dir : el1DirVec_) {
321 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
322 return E_PREPARE_DIR;
323 }
324 }
325
326 return E_OK;
327 }
328
DestroyEl1Dir(int32_t userId)329 int32_t UserManager::DestroyEl1Dir(int32_t userId)
330 {
331 for (const DirInfo &dir : el1DirVec_) {
332 if (!RmDirRecurse(StringPrintf(dir.path.c_str(), userId))) {
333 return E_DESTROY_DIR;
334 }
335 }
336
337 return E_OK;
338 }
339
CreateElxBundleDataDir(uint32_t userId,uint8_t elx)340 void UserManager::CreateElxBundleDataDir(uint32_t userId, uint8_t elx)
341 {
342 LOGI("CreateElxBundleDataDir start: userId %{public}u, elx is %{public}d", userId, elx);
343 if (elx == EL1_KEY) {
344 LOGW("CreateElxBundleDataDir pass: userId %{public}u, elx is %{public}d", userId, elx);
345 return;
346 }
347 OHOS::AppExecFwk::BundleMgrClient client;
348 auto ret = client.CreateBundleDataDirWithEl(userId, static_cast<OHOS::AppExecFwk::DataDirEl>(elx));
349 LOGI("CreateElxBundleDataDir end: userId %{public}u, elx is %{public}d, ret %{public}d", userId, elx, ret);
350 if (ret != E_OK) {
351 StorageRadar::ReportBundleMgrResult("CreateElxBundleDataDir", ret, userId, std::to_string(elx));
352 }
353 }
354
CheckUserIdRange(int32_t userId)355 int32_t UserManager::CheckUserIdRange(int32_t userId)
356 {
357 if ((userId < StorageService::START_USER_ID && userId != StorageService::ZERO_USER) ||
358 userId > StorageService::MAX_USER_ID) {
359 LOGE("UserManager: userId:%{public}d is out of range", userId);
360 return E_USERID_RANGE;
361 }
362 return E_OK;
363 }
364
CheckCrypto(int32_t userId,uint32_t flags)365 int32_t UserManager::CheckCrypto(int32_t userId, uint32_t flags)
366 {
367 int32_t err = CheckUserIdRange(userId);
368 if (err != E_OK) {
369 LOGE("UserManager::PrepareUserDirs userId %{public}d out of range", userId);
370 return err;
371 }
372 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
373 err = PrepareDirsFromIdAndLevel(userId, EL1);
374 if (err != E_OK) {
375 return err;
376 }
377 err = PrepareEl1BundleDir(userId);
378 if (err != E_OK) {
379 return err;
380 }
381 int32_t errorCode = PrepareEl1Dir(userId);
382 if (errorCode != E_OK) {
383 LOGW("Prepare el1 dir fail, %{public}d.", errorCode);
384 }
385 }
386 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
387 err = PrepareDirsFromIdAndLevel(userId, EL2);
388 if (err != E_OK) {
389 return err;
390 }
391 err = PrepareEl2BackupDir(userId);
392 if (err != E_OK) {
393 return err;
394 }
395 }
396 if (flags & IStorageDaemon::CRYPTO_FLAG_EL3) {
397 err = PrepareDirsFromIdAndLevel(userId, EL3);
398 if (err != E_OK) {
399 return err;
400 }
401 }
402 if (flags & IStorageDaemon::CRYPTO_FLAG_EL4) {
403 err = PrepareDirsFromIdAndLevel(userId, EL4);
404 if (err != E_OK) {
405 return err;
406 }
407 }
408 if (flags & IStorageDaemon::CRYPTO_FLAG_EL5) {
409 err = PrepareDirsFromIdAndLevel(userId, EL5);
410 if (err != E_OK) {
411 return err;
412 }
413 }
414 return E_OK;
415 }
416 } // namespace StorageDaemon
417 } // namespace OHOS
418