• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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