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