• 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 #include "os_account_interface.h"
16 
17 #include <cerrno>
18 #include <condition_variable>
19 #include <thread>
20 
21 #include "ability_manager_adapter.h"
22 #include "account_constants.h"
23 #include "account_log_wrapper.h"
24 #include "bundle_manager_adapter.h"
25 #ifdef HAS_CES_PART
26 #include "common_event_manager.h"
27 #include "common_event_support.h"
28 #endif // HAS_CES_PART
29 #include "datetime_ex.h"
30 #include "account_hisysevent_adapter.h"
31 #include "hitrace_adapter.h"
32 #include "if_system_ability_manager.h"
33 #include "iservice_registry.h"
34 #ifdef HAS_STORAGE_PART
35 #include "istorage_manager.h"
36 #endif
37 #include "os_account_constants.h"
38 #include "os_account_delete_user_idm_callback.h"
39 #include "os_account_user_callback.h"
40 #include "os_account_subscribe_manager.h"
41 #ifdef HAS_STORAGE_PART
42 #include "storage_manager_proxy.h"
43 #include "storage_service_errno.h"
44 #endif
45 #include "iinner_os_account_manager.h"
46 #include "system_ability_definition.h"
47 #ifdef HAS_USER_IDM_PART
48 #include "account_iam_callback.h"
49 #include "user_idm_client.h"
50 #endif // HAS_USER_IDM_PART
51 #ifdef HAS_CES_PART
52 #include "want.h"
53 #endif // HAS_CES_PART
54 
55 
56 namespace OHOS {
57 namespace AccountSA {
58 namespace {
59 const char OPERATION_START[] = "start";
60 
61 #ifdef HAS_STORAGE_PART
62 constexpr uint32_t CRYPTO_FLAG_EL1 = 1;
63 constexpr uint32_t CRYPTO_FLAG_EL2 = 2;
64 #endif
65 
66 constexpr int32_t DELAY_FOR_EXCEPTION = 100;
67 constexpr int32_t MAX_RETRY_TIMES = 10;
68 constexpr int32_t MAX_GETBUNDLE_WAIT_TIMES = 10 * 1000 * 1000;
69 constexpr int32_t GET_MSG_FREQ = 100 * 1000;
70 constexpr int32_t DEAL_TIMES = MAX_GETBUNDLE_WAIT_TIMES / GET_MSG_FREQ;
71 }
72 
InnerSendToAMSAccountStart(int32_t localId,sptr<OsAccountUserCallback> callback,bool isAppRecovery)73 ErrCode InnerSendToAMSAccountStart(int32_t localId, sptr<OsAccountUserCallback> callback, bool isAppRecovery)
74 {
75     ErrCode code = ERR_OK;
76     int32_t retryTimes = 0;
77     while (retryTimes < MAX_RETRY_TIMES) {
78         code = AbilityManagerAdapter::GetInstance()->StartUser(localId, callback, isAppRecovery);
79         if (code == ERR_OK || (code != Constants::E_IPC_ERROR && code != Constants::E_IPC_SA_DIED)) {
80             break;
81         }
82         ACCOUNT_LOGE("AbilityManagerAdapter StartUser failed! errcode is %{public}d, retry %{public}d",
83             code, retryTimes + 1);
84         retryTimes++;
85         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
86     }
87     return code;
88 }
89 
SendToAMSAccountStart(OsAccountInfo & osAccountInfo,const OsAccountStartCallbackFunc & callbackFunc,bool isAppRecovery)90 ErrCode OsAccountInterface::SendToAMSAccountStart(OsAccountInfo &osAccountInfo,
91     const OsAccountStartCallbackFunc &callbackFunc, bool isAppRecovery)
92 {
93     int32_t localId = osAccountInfo.GetLocalId();
94     ACCOUNT_LOGI("Start OS account %{public}d", localId);
95     sptr<OsAccountUserCallback> osAccountStartUserCallback = new (std::nothrow) OsAccountUserCallback(callbackFunc);
96     if (osAccountStartUserCallback == nullptr) {
97         ACCOUNT_LOGE("Alloc memory for start user callback failed!");
98         ReportOsAccountOperationFail(localId, OPERATION_START,
99             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
100         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
101     }
102     StartTraceAdapter("AbilityManagerAdapter StartUser");
103 
104     ErrCode code = InnerSendToAMSAccountStart(localId, osAccountStartUserCallback, isAppRecovery);
105     if (code != ERR_OK) {
106         ACCOUNT_LOGE("AbilityManagerAdapter StartUser failed after retries! errcode is %{public}d", code);
107         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE, code,
108             "AbilityManager failed to start user");
109         FinishTraceAdapter();
110         return code;
111     }
112     std::unique_lock<std::mutex> lock(osAccountStartUserCallback->mutex_);
113     osAccountStartUserCallback->onStartCondition_.wait(
114         lock, [osAccountStartUserCallback] { return osAccountStartUserCallback->isCalled_; });
115     FinishTraceAdapter();
116     if (osAccountStartUserCallback->resultCode_ != ERR_OK) {
117         ACCOUNT_LOGE("Failed to AbilityManagerService in call back");
118         ReportOsAccountOperationFail(localId, OPERATION_START, osAccountStartUserCallback->resultCode_,
119                                      "AbilityManager failed to start user in callback");
120         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
121     }
122     ACCOUNT_LOGI("End, succeed %{public}d", localId);
123     return code;
124 }
125 
InnerSendToAMSAccountStop(int32_t localId,sptr<OsAccountUserCallback> callback)126 ErrCode InnerSendToAMSAccountStop(int32_t localId, sptr<OsAccountUserCallback> callback)
127 {
128     ErrCode code = ERR_OK;
129     int32_t retryTimes = 0;
130     while (retryTimes < MAX_RETRY_TIMES) {
131         code = AbilityManagerAdapter::GetInstance()->StopUser(localId, callback);
132         if (code == ERR_OK || (code != Constants::E_IPC_ERROR && code != Constants::E_IPC_SA_DIED)) {
133             break;
134         }
135         ACCOUNT_LOGE("AbilityManagerAdapter StopUser failed! errcode is %{public}d, retry %{public}d",
136             code, retryTimes + 1);
137         retryTimes++;
138         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
139     }
140     return code;
141 }
142 
SendToAMSAccountStop(OsAccountInfo & osAccountInfo)143 ErrCode OsAccountInterface::SendToAMSAccountStop(OsAccountInfo &osAccountInfo)
144 {
145     int32_t localId = osAccountInfo.GetLocalId();
146     ACCOUNT_LOGI("Stop OS account %{public}d", localId);
147     sptr<OsAccountUserCallback> osAccountStopUserCallback = new (std::nothrow) OsAccountUserCallback();
148     if (osAccountStopUserCallback == nullptr) {
149         ACCOUNT_LOGE("Alloc memory for stop user callback failed!");
150         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
151             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
152         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
153     }
154     StartTraceAdapter("AbilityManagerAdapter StopUser");
155 
156     ErrCode code = InnerSendToAMSAccountStop(localId, osAccountStopUserCallback);
157     if (code != ERR_OK) {
158         ACCOUNT_LOGE("Failed to AbilityManagerAdapter stop after retries! errcode is %{public}d", code);
159         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP, code,
160             "AbilityManager failed to stop user");
161         FinishTraceAdapter();
162         return code;
163     }
164     std::unique_lock<std::mutex> lock(osAccountStopUserCallback->mutex_);
165     osAccountStopUserCallback->onStopCondition_.wait(lock, [osAccountStopUserCallback] {
166         return osAccountStopUserCallback->isCalled_;
167     });
168     FinishTraceAdapter();
169     if (osAccountStopUserCallback->resultCode_ != ERR_OK) {
170         ACCOUNT_LOGE("Failed to AbilityManagerService in call back");
171         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
172             osAccountStopUserCallback->resultCode_, "AbilityManager failed to stop user in callback");
173         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
174     }
175     ACCOUNT_LOGI("End, succeed %{public}d", localId);
176     return code;
177 }
178 
InnerSendToAMSAccountDeactivate(int32_t localId,sptr<OsAccountUserCallback> callback)179 ErrCode InnerSendToAMSAccountDeactivate(int32_t localId, sptr<OsAccountUserCallback> callback)
180 {
181     ErrCode code = ERR_OK;
182     int32_t retryTimes = 0;
183     while (retryTimes < MAX_RETRY_TIMES) {
184         code = AbilityManagerAdapter::GetInstance()->LogoutUser(localId, callback);
185         if (code == ERR_OK || (code != Constants::E_IPC_ERROR && code != Constants::E_IPC_SA_DIED)) {
186             break;
187         }
188         ACCOUNT_LOGE("AbilityManagerAdapter LogoutUser failed! errcode is %{public}d, retry %{public}d",
189             code, retryTimes + 1);
190         retryTimes++;
191         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
192     }
193     return code;
194 }
195 
SendToAMSAccountDeactivate(OsAccountInfo & osAccountInfo)196 ErrCode OsAccountInterface::SendToAMSAccountDeactivate(OsAccountInfo &osAccountInfo)
197 {
198     int32_t localId = osAccountInfo.GetLocalId();
199     ACCOUNT_LOGI("Deactivate OS account %{public}d", localId);
200     sptr<OsAccountUserCallback> deactivateUserCallback = new (std::nothrow) OsAccountUserCallback();
201     if (deactivateUserCallback == nullptr) {
202         ACCOUNT_LOGE("Alloc memory for deactivate user callback failed!");
203         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
204             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
205         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
206     }
207 
208     StartTraceAdapter("AbilityManagerAdapter LogoutUser");
209     ErrCode code = InnerSendToAMSAccountDeactivate(localId, deactivateUserCallback);
210     if (code != ERR_OK) {
211         ACCOUNT_LOGE("Failed to AbilityManagerAdapter logout after retries! errcode is %{public}d", code);
212         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP, code,
213             "AbilityManager failed to logout user");
214         FinishTraceAdapter();
215         return code;
216     }
217     std::unique_lock<std::mutex> lock(deactivateUserCallback->mutex_);
218     deactivateUserCallback->onLogoutCondition_.wait(lock, [deactivateUserCallback] {
219         return deactivateUserCallback->isCalled_;
220     });
221     FinishTraceAdapter();
222     if (deactivateUserCallback->resultCode_ != ERR_OK) {
223         ACCOUNT_LOGE("Failed to logout user in call back");
224         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
225             deactivateUserCallback->resultCode_, "AbilityManager failed to logout user in callback");
226         return deactivateUserCallback->resultCode_;
227     }
228     ACCOUNT_LOGI("Deactivate End, succeed %{public}d", localId);
229     return code;
230 }
231 
SendToBMSAccountCreate(OsAccountInfo & osAccountInfo,const std::vector<std::string> & disallowedHapList,const std::optional<std::vector<std::string>> & allowedHapList)232 ErrCode OsAccountInterface::SendToBMSAccountCreate(
233     OsAccountInfo &osAccountInfo, const std::vector<std::string> &disallowedHapList,
234     const std::optional<std::vector<std::string>> &allowedHapList)
235 {
236     ErrCode errCode = ERR_OK;
237     int32_t retryTimes = 0;
238     while (retryTimes < MAX_RETRY_TIMES) {
239         errCode = BundleManagerAdapter::GetInstance()->CreateNewUser(osAccountInfo.GetLocalId(),
240             disallowedHapList, allowedHapList);
241         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
242             break;
243         }
244         ACCOUNT_LOGE("Fail to SendToBMSAccountCreate, errCode %{public}d.", errCode);
245         retryTimes++;
246         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
247     }
248     return errCode;
249 }
250 
SendToBMSAccountDelete(OsAccountInfo & osAccountInfo)251 ErrCode OsAccountInterface::SendToBMSAccountDelete(OsAccountInfo &osAccountInfo)
252 {
253     return BundleManagerAdapter::GetInstance()->RemoveUser(osAccountInfo.GetLocalId());
254 }
255 
256 #ifdef HAS_USER_IDM_PART
SendToIDMAccountDelete(OsAccountInfo & osAccountInfo)257 ErrCode OsAccountInterface::SendToIDMAccountDelete(OsAccountInfo &osAccountInfo)
258 {
259     std::shared_ptr<OsAccountDeleteUserIdmCallback> callback = std::make_shared<OsAccountDeleteUserIdmCallback>();
260     if (callback == nullptr) {
261         ACCOUNT_LOGE("Get idm callback ptr failed! insufficient memory!");
262         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
263             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR,
264             "Failed to malloc for OsAccountDeleteUserIdmCallback");
265         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
266     }
267     StartTraceAdapter("UserIDMClient EnforceDelUser");
268     int32_t ret = UserIam::UserAuth::UserIdmClient::GetInstance().EraseUser(osAccountInfo.GetLocalId(), callback);
269     if ((ret != UserIam::UserAuth::ResultCode::SUCCESS) &&
270         (ret != UserIam::UserAuth::ResultCode::NOT_ENROLLED)) {
271         ACCOUNT_LOGE("Idm enforce delete user failed! error %{public}d", ret);
272         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, ret,
273             "Failed to call EraseUser");
274         FinishTraceAdapter();
275         return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
276     }
277 
278     // wait callback
279     {
280         std::unique_lock<std::mutex> lck(callback->mutex_);
281         if (!callback->isCalled_) {
282             callback->onResultCondition_.wait_for(lck, std::chrono::seconds(Constants::TIME_WAIT_TIME_OUT));
283         }
284         if (!callback->isCalled_) {
285             ACCOUNT_LOGE("Idm did not call back! timeout!");
286             ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, -1,
287                 "UserIDM erase user timeout");
288             FinishTraceAdapter();
289             return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
290         }
291         if ((callback->resultCode_ != UserIam::UserAuth::ResultCode::SUCCESS) &&
292             (callback->resultCode_ != UserIam::UserAuth::ResultCode::NOT_ENROLLED)) {
293             ACCOUNT_LOGE("Idm enforce delete user failed! Callback error %{public}d", callback->resultCode_);
294             ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
295                 callback->resultCode_, "Failed to erase user credential");
296             FinishTraceAdapter();
297             return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
298         }
299     }
300 
301     ACCOUNT_LOGI("Send to idm account delete and get callback succeed!");
302     FinishTraceAdapter();
303     return ERR_OK;
304 }
305 #endif // HAS_USER_IDM_PART
306 
SendToCESAccountCreate(OsAccountInfo & osAccountInfo)307 void OsAccountInterface::SendToCESAccountCreate(OsAccountInfo &osAccountInfo)
308 {
309     int osAccountID = osAccountInfo.GetLocalId();
310 #ifdef HAS_CES_PART
311     StartTraceAdapter("PublishCommonEvent account create");
312     OHOS::AAFwk::Want want;
313     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
314     OHOS::EventFwk::CommonEventData data;
315     data.SetCode(osAccountID);
316     data.SetWant(want);
317     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
318         ACCOUNT_LOGE("PublishCommonEvent for create account %{public}d failed!", osAccountID);
319         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_CREATE, -1, "PublishCommonEvent failed!");
320     } else {
321         ACCOUNT_LOGI("PublishCommonEvent for create account %{public}d succeed!", osAccountID);
322     }
323     FinishTraceAdapter();
324 #else // HAS_CES_PART
325     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d create!", osAccountID);
326 #endif // HAS_CES_PART
327 }
328 
SendToCESAccountDelete(OsAccountInfo & osAccountInfo)329 void OsAccountInterface::SendToCESAccountDelete(OsAccountInfo &osAccountInfo)
330 {
331     int osAccountID = osAccountInfo.GetLocalId();
332 #ifdef HAS_CES_PART
333     StartTraceAdapter("PublishCommonEvent account delete");
334     OHOS::AAFwk::Want want;
335     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
336     OHOS::EventFwk::CommonEventData data;
337     data.SetCode(osAccountID);
338     data.SetWant(want);
339     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
340         ACCOUNT_LOGE("PublishCommonEvent for delete account %{public}d failed!", osAccountID);
341         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_REMOVE, -1, "Failed to publish common event");
342     } else {
343         ACCOUNT_LOGI("PublishCommonEvent for delete account %{public}d succeed!", osAccountID);
344     }
345     FinishTraceAdapter();
346 #else // HAS_CES_PART
347     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d delete!", osAccountID);
348 #endif // HAS_CES_PART
349 }
350 
PublishCommonEvent(const OsAccountInfo & osAccountInfo,const std::string & commonEvent,const std::string & operation)351 void OsAccountInterface::PublishCommonEvent(
352     const OsAccountInfo &osAccountInfo, const std::string &commonEvent, const std::string &operation)
353 {
354     int osAccountID = osAccountInfo.GetLocalId();
355 #ifdef HAS_CES_PART
356     StartTraceAdapter("PublishCommonEvent account");
357     OHOS::AAFwk::Want want;
358     want.SetAction(commonEvent);
359     OHOS::EventFwk::CommonEventData data;
360     data.SetCode(osAccountID);
361     data.SetWant(want);
362     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
363         ACCOUNT_LOGE("PublishCommonEvent %{public}d failed!", osAccountID);
364         ReportOsAccountOperationFail(osAccountID, operation, -1, "PublishCommonEvent failed!");
365     } else {
366         ACCOUNT_LOGI("PublishCommonEvent %{public}d succeed!", osAccountID);
367     }
368     FinishTraceAdapter();
369 #else  // HAS_CES_PART
370     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d!", osAccountID);
371 #endif // HAS_CES_PART
372 }
373 
SendToCESAccountSwitched(int newId,int oldId)374 void OsAccountInterface::SendToCESAccountSwitched(int newId, int oldId)
375 {
376 #ifdef HAS_CES_PART
377     StartTraceAdapter("PublishCommonEvent account switched");
378     OHOS::AAFwk::Want want;
379     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
380     want.SetParam("oldId", std::to_string(oldId));
381     OHOS::EventFwk::CommonEventData data;
382     data.SetCode(newId);
383     data.SetWant(want);
384     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
385         ACCOUNT_LOGE("PublishCommonEvent failed, account switched:%{public}d->%{public}d", oldId, newId);
386         ReportOsAccountOperationFail(newId, Constants::OPERATION_SWITCH, -1, "PublishCommonEvent switched failed!");
387     } else {
388         ACCOUNT_LOGI("PublishCommonEvent successful, account switched:%{public}d->%{public}d", oldId, newId);
389     }
390     FinishTraceAdapter();
391 #else // HAS_CES_PART
392     ACCOUNT_LOGI("No common event part, do not publish for account switched:%{public}d->%{public}d", oldId, newId);
393 #endif // HAS_CES_PART
394 }
395 
SendToStorageAccountCreate(OsAccountInfo & osAccountInfo)396 ErrCode OsAccountInterface::SendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
397 {
398     ErrCode errCode = ERR_OK;
399     int32_t retryTimes = 0;
400     while (retryTimes < MAX_RETRY_TIMES) {
401         errCode = InnerSendToStorageAccountCreate(osAccountInfo);
402         if (errCode != Constants::E_IPC_ERROR && errCode != Constants::E_IPC_SA_DIED) {
403             break;
404         }
405         ACCOUNT_LOGE("Fail to SendToStorageAccountCreate,id=%{public}d, errCode %{public}d.",
406             osAccountInfo.GetLocalId(), errCode);
407         retryTimes++;
408         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
409     }
410     return errCode;
411 }
412 
413 #ifdef HAS_STORAGE_PART
PrepareAddUser(const sptr<StorageManager::IStorageManager> & proxy,int32_t userId)414 static ErrCode PrepareAddUser(const sptr<StorageManager::IStorageManager> &proxy, int32_t userId)
415 {
416     ErrCode err = proxy->PrepareAddUser(userId, CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
417     if (err == 0) {
418         return ERR_OK;
419     }
420     ReportOsAccountOperationFail(userId, Constants::OPERATION_CREATE, err, "StorageManager failed to add user");
421     if (err == -EEXIST) {
422         return ERR_OK;
423     }
424     return err;
425 }
426 #endif
427 
InnerSendToStorageAccountCreate(OsAccountInfo & osAccountInfo)428 ErrCode OsAccountInterface::InnerSendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
429 {
430 #ifdef HAS_STORAGE_PART
431     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
432     int32_t localId = osAccountInfo.GetLocalId();
433     if (!systemAbilityManager) {
434         ACCOUNT_LOGE("Failed to get system ability mgr.");
435         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
436             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
437             "GetSystemAbilityManager for storage failed!");
438         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
439     }
440     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
441     if (!remote) {
442         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
443         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
444             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
445             "CheckSystemAbility for storage failed!");
446         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
447     }
448     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
449     if (!proxy) {
450         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
451         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
452     }
453     StartTraceAdapter("StorageManager PrepareAddUser");
454 
455     ErrCode err = PrepareAddUser(proxy, localId);
456     if (err == ERR_OK) {
457         FinishTraceAdapter();
458         return ERR_OK;
459     }
460 
461     ACCOUNT_LOGI("PrepareAddUser Failed, start check and clean accounts.");
462     auto &osAccountManager = IInnerOsAccountManager::GetInstance();
463     if (osAccountManager.CleanGarbageOsAccounts(localId) <= 0) {
464         FinishTraceAdapter();
465         return err;
466     }
467     ACCOUNT_LOGI("Clean garbage account data, Retry Storage PrepareAddUser.");
468     err = PrepareAddUser(proxy, localId);
469     FinishTraceAdapter();
470     return err;
471 #else
472     return ERR_OK;
473 #endif
474 }
475 
SendToStorageAccountRemove(OsAccountInfo & osAccountInfo)476 ErrCode OsAccountInterface::SendToStorageAccountRemove(OsAccountInfo &osAccountInfo)
477 {
478     ACCOUNT_LOGI("Start");
479 #ifdef HAS_STORAGE_PART
480     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
481     if (!systemAbilityManager) {
482         ACCOUNT_LOGE("Failed to get system ability mgr.");
483         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
484             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
485             "Failed to get SystemAbilityManager");
486         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
487     }
488     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
489     if (!remote) {
490         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
491         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
492             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
493             "Failed to get StorageManager service");
494         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
495     }
496     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
497     if (!proxy) {
498         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
499         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
500     }
501 
502     StartTraceAdapter("StorageManager RemoveUser");
503     int err = proxy->RemoveUser(osAccountInfo.GetLocalId(),
504         CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
505     if (err != 0) {
506         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
507             err, "StorageManager failed to remove user");
508         ACCOUNT_LOGE("Storage RemoveUser failed, ret %{public}d", err);
509         FinishTraceAdapter();
510         return err;
511     }
512 
513     ACCOUNT_LOGI("End, Storage RemoveUser ret %{public}d.", err);
514     FinishTraceAdapter();
515 #endif
516     return ERR_OK;
517 }
518 
519 #ifdef HAS_STORAGE_PART
GetStorageProxy(sptr<StorageManager::IStorageManager> & proxy)520 static ErrCode GetStorageProxy(sptr<StorageManager::IStorageManager> &proxy)
521 {
522     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
523     if (!systemAbilityManager) {
524         ACCOUNT_LOGE("Failed to get system ability mgr.");
525         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
526     }
527     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
528     if (!remote) {
529         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
530         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
531     }
532     proxy = iface_cast<StorageManager::IStorageManager>(remote);
533     return ERR_OK;
534 }
535 
536 #ifdef HAS_USER_IDM_PART
ReportDecryptionFaultAsync(const int localId)537 void ReportDecryptionFaultAsync(const int localId)
538 {
539     std::thread([localId]() {
540         std::vector<UserIam::UserAuth::CredentialInfo> credentialInfoList;
541         int32_t ret = UserIam::UserAuth::UserIdmClient::GetInstance().GetCredentialInfoSync(
542             localId, UserIam::UserAuth::AuthType::PIN, credentialInfoList);
543         if (ret != ERR_OK) {
544             ACCOUNT_LOGE("Get credential info sync failed, ret=%{public}d, localId=%{public}d", ret, localId);
545             ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
546                 ret, "Get credential info sync failed");
547             return;
548         }
549         if (credentialInfoList.empty()) {
550             ACCOUNT_LOGE("EL2 decryption failed and no credential, localId=%{public}d", localId);
551             ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
552                 ErrNo::E_ACTIVE_EL2_FAILED, "EL2 decryption failed and no credential");
553         }
554     }).detach();
555 }
556 #endif
557 
558 #ifdef HAS_USER_IDM_PART
GetPINCredentialInfo(int32_t userId,bool & isPINExist)559 static ErrCode GetPINCredentialInfo(int32_t userId, bool &isPINExist)
560 {
561     int32_t retryTimes = 0;
562     while (retryTimes < MAX_RETRY_TIMES) {
563         auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
564         if ((systemAbilityManager == nullptr) ||
565             (systemAbilityManager->GetSystemAbility(SUBSYS_USERIAM_SYS_ABILITY_USERIDM) == nullptr)) {
566             ACCOUNT_LOGE("Failed to get iam service, id:%{public}d, retry!", userId);
567             retryTimes++;
568             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
569         } else {
570             break;
571         }
572     }
573     auto callback = std::make_shared<GetCredentialInfoSyncCallback>(userId);
574     ACCOUNT_LOGI("Start get credential info, userId:%{public}d", userId);
575     int32_t ret = UserIam::UserAuth::UserIdmClient::GetInstance().GetCredentialInfo(
576         userId, UserIam::UserAuth::AuthType::PIN, callback);
577     if (ret != ERR_OK) {
578         ACCOUNT_LOGE("GetCredentialInfo failed, ret:%{public}d", ret);
579         return ret;
580     }
581     std::unique_lock<std::mutex> lck(callback->secureMtx_);
582     auto status = callback->secureCv_.wait_for(lck, std::chrono::seconds(Constants::TIME_WAIT_TIME_OUT), [callback] {
583         return callback->isCalled_;
584     });
585     if (!status) {
586         ACCOUNT_LOGE("Get credential info timed out");
587         isPINExist = false; // Timeout defaults to false
588         ReportOsAccountOperationFail(userId, "checkIAMFault", ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT,
589             "Get credential info timed out in the secret exception flag check process");
590         return ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT;
591     }
592     if ((callback->result_ == ERR_OK) || (callback->result_ == ERR_IAM_NOT_ENROLLED)) {
593         isPINExist = callback->hasPIN_;
594     }
595     return callback->result_;
596 }
597 
IsSecretFlagExist(int32_t userId)598 static bool IsSecretFlagExist(int32_t userId)
599 {
600     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(userId) +
601         Constants::PATH_SEPARATOR + Constants::USER_SECRET_FLAG_FILE_NAME;
602     auto accountFileOperator = std::make_shared<AccountFileOperator>();
603     bool isExist = accountFileOperator->IsExistFile(path);
604     ACCOUNT_LOGI("The iam_fault file existence status:%{public}d, userId:%{public}d", isExist, userId);
605     return isExist;
606 }
607 
DeleteSecretFlag(int32_t userId)608 static void DeleteSecretFlag(int32_t userId)
609 {
610     auto accountFileOperator = std::make_shared<AccountFileOperator>();
611     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(userId) +
612         Constants::PATH_SEPARATOR + Constants::USER_SECRET_FLAG_FILE_NAME;
613     ErrCode code = accountFileOperator->DeleteDirOrFile(path);
614     if (code != ERR_OK) {
615         ReportOsAccountOperationFail(userId, "startUser", code,
616             "Failed to delete iam_fault file when PIN is not exist");
617     }
618 }
619 
IsExistPIN(int32_t userId)620 bool IsExistPIN(int32_t userId)
621 {
622     bool isExistPIN = false;
623     ErrCode ret = GetPINCredentialInfo(userId, isExistPIN);
624     if (ret == ERR_IAM_NOT_ENROLLED) {
625         DeleteSecretFlag(userId);
626         return false;
627     }
628     if (ret == ERR_OK) {
629         if (isExistPIN) {
630             return true;
631         } else {
632             DeleteSecretFlag(userId);
633             return false;
634         }
635     }
636     return false;
637 }
638 
NeedSkipActiveUserKey(const int localId,bool & isNeedSkip)639 int32_t NeedSkipActiveUserKey(const int localId, bool &isNeedSkip)
640 {
641     isNeedSkip = false;
642     if (!IsSecretFlagExist(localId)) {
643         return ERR_OK;
644     }
645     // Check if the storage is already unlocked
646     sptr<StorageManager::IStorageManager> proxy = nullptr;
647     if (GetStorageProxy(proxy) != ERR_OK) {
648         ACCOUNT_LOGE("Failed to get storage manager proxy!");
649         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
650     }
651     bool isFileEncrypt = true;
652     ErrCode errCode = proxy->GetFileEncryptStatus(localId, isFileEncrypt, true);
653     ACCOUNT_LOGI("Get file encrypt ret = %{public}d, status = %{public}d, id = %{public}d",
654         errCode, isFileEncrypt, localId);
655     if (errCode != 0) {
656         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
657             errCode, "StorageManager failed to get file encrypt status.");
658         return errCode;
659     }
660     if (!isFileEncrypt) {
661         ACCOUNT_LOGW("The storage has been decrypted and does not need to be processed again.");
662         isNeedSkip = true;
663         return ERR_OK; // return ok to send unlock events
664     }
665     // Check if the IAM has PIN credential
666     if (IsExistPIN(localId)) {
667         ACCOUNT_LOGW("Secret operation flag and PIN exists, skip empty secret 'ActiveUserKey'!");
668         isNeedSkip = true;
669         return ERR_ACCOUNT_COMMON_SECRET_CHECK; // return err to not send unlock events
670     }
671     return ERR_OK;
672 }
673 #endif // HAS_USER_IDM_PART
674 
UnlockUser(const int localId)675 int32_t OsAccountInterface::UnlockUser(const int localId)
676 {
677     int32_t retryTimes = 0;
678     int32_t errCode = 0;
679     while (retryTimes < MAX_RETRY_TIMES) {
680         sptr<StorageManager::IStorageManager> proxy = nullptr;
681         if (GetStorageProxy(proxy) != ERR_OK) {
682             ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy, retry!");
683             errCode = ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
684             retryTimes++;
685             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
686             continue;
687         }
688 #ifdef HAS_USER_IDM_PART
689         bool isNeedSkip = false;
690         errCode = NeedSkipActiveUserKey(localId, isNeedSkip);
691         if (isNeedSkip) {
692             return errCode;
693         }
694 #endif // HAS_USER_IDM_PART
695         std::vector<uint8_t> emptyData;
696         errCode = proxy->ActiveUserKey(localId, emptyData, emptyData);
697         ACCOUNT_LOGI("ActiveUserKey end, ret %{public}d.", errCode);
698         if (errCode != ErrNo::E_ACTIVE_EL2_FAILED) {
699             errCode = proxy->PrepareStartUser(localId);
700             ACCOUNT_LOGI("PrepareStartUser end, errCode %{public}d.", errCode);
701             if (errCode != 0) {
702                 ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
703                     errCode, "StorageManager failed to start user");
704             }
705 #ifdef HAS_USER_IDM_PART
706         } else {
707             ReportDecryptionFaultAsync(localId);
708 #endif
709         }
710         if ((errCode == Constants::E_IPC_ERROR) || (errCode == Constants::E_IPC_SA_DIED)) {
711             ACCOUNT_LOGE("Failed to PrepareStartUser, id:%{public}d, errCode:%{public}d, retry!", localId, errCode);
712             retryTimes++;
713             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
714             continue;
715         } else {
716             break;
717         }
718     }
719     return errCode;
720 }
721 #endif
722 
SendToStorageAccountStart(OsAccountInfo & osAccountInfo)723 ErrCode OsAccountInterface::SendToStorageAccountStart(OsAccountInfo &osAccountInfo)
724 {
725     ACCOUNT_LOGI("Start");
726     bool isUserUnlocked = false;
727 #ifdef HAS_STORAGE_PART
728     int localId = osAccountInfo.GetLocalId();
729     StartTraceAdapter("StorageManager PrepareStartUser");
730     int32_t err = UnlockUser(localId);
731     if (err == ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER) {
732         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
733             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER, "Failed to get StorageManager service");
734         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
735         return err;
736     }
737     if (err == ERR_OK) {
738         isUserUnlocked = true;
739     }
740     ACCOUNT_LOGI("End, Storage PrepareStartUser ret %{public}d.", err);
741     FinishTraceAdapter();
742 #else
743     isUserUnlocked = true;
744 #endif
745     if (!osAccountInfo.GetIsVerified() && isUserUnlocked) {
746         ACCOUNT_LOGI("OS account:%{public}d is unlocked.", osAccountInfo.GetLocalId());
747         osAccountInfo.SetIsVerified(true);
748         bool hasCredential = osAccountInfo.GetCredentialId() > 0;
749         if (!hasCredential) {
750             ACCOUNT_LOGI("OS account:%{public}d is loggen in.", osAccountInfo.GetLocalId());
751             osAccountInfo.SetIsLoggedIn(true);
752             osAccountInfo.SetLastLoginTime(std::chrono::duration_cast<std::chrono::seconds>(
753                 std::chrono::system_clock::now().time_since_epoch()).count());
754         }
755     }
756     ACCOUNT_LOGI("End, succeed!");
757     return ERR_OK;
758 }
759 
SendToStorageAccountStop(OsAccountInfo & osAccountInfo)760 ErrCode OsAccountInterface::SendToStorageAccountStop(OsAccountInfo &osAccountInfo)
761 {
762     ACCOUNT_LOGI("Stop storage, account id = %{public}d", osAccountInfo.GetLocalId());
763 #ifdef HAS_STORAGE_PART
764     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
765     if (!systemAbilityManager) {
766         ACCOUNT_LOGE("Failed to get system ability mgr.");
767         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
768             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
769             "GetSystemAbilityManager for storage failed!");
770         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
771     }
772     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
773     if (!remote) {
774         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
775         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
776             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
777             "GetSystemAbility for storage failed!");
778         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
779     }
780     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
781     if (!proxy) {
782         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
783         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
784     }
785     osAccountInfo.SetIsVerified(false);
786     StartTraceAdapter("StorageManager StopUser");
787     int localId = osAccountInfo.GetLocalId();
788     int err = proxy->StopUser(localId);
789     if (err != 0) {
790         ACCOUNT_LOGE("StorageManager failed to stop user, err: %{public}d", err);
791         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
792             err, "StorageManager failed to stop user");
793         FinishTraceAdapter();
794         return ERR_OSACCOUNT_SERVICE_STORAGE_STOP_USER_FAILED;
795     }
796     err = proxy->InactiveUserKey(localId);
797     if (err != 0) {
798         ACCOUNT_LOGE("StorageManager failed to inactivate user key, err: %{public}d", err);
799         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
800             err, "StorageManager failed to inactivate user key");
801         FinishTraceAdapter();
802         return ERR_OSACCOUNT_SERVICE_STORAGE_STOP_USER_FAILED;
803     }
804     FinishTraceAdapter();
805 #else
806     osAccountInfo.SetIsVerified(false);
807 #endif
808     return ERR_OK;
809 }
810 
SendToStorageAccountCreateComplete(int32_t localId)811 ErrCode OsAccountInterface::SendToStorageAccountCreateComplete(int32_t localId)
812 {
813     ErrCode errCode = ERR_OK;
814     int32_t retryTimes = 0;
815     while (retryTimes < MAX_RETRY_TIMES) {
816         errCode = InnerSendToStorageAccountCreateComplete(localId);
817         if (errCode == ERR_OK) {
818             break;
819         }
820         ACCOUNT_LOGE("Fail to complete account, localId=%{public}d, errCode=%{public}d.", localId, errCode);
821         retryTimes++;
822         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
823     }
824     return errCode;
825 }
826 
InnerSendToStorageAccountCreateComplete(int32_t localId)827 ErrCode OsAccountInterface::InnerSendToStorageAccountCreateComplete(int32_t localId)
828 {
829 #ifdef HAS_STORAGE_PART
830     sptr<StorageManager::IStorageManager> proxy = nullptr;
831     if (GetStorageProxy(proxy) != ERR_OK) {
832         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
833         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
834     }
835     StartTraceAdapter("StorageManager CompleteAddUser");
836     int errCode = proxy->CompleteAddUser(localId);
837     if (errCode != 0) {
838         ACCOUNT_LOGE("Failed to CompleteAddUser, localId=%{public}d, errCode=%{public}d", localId, errCode);
839         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE, errCode,
840             "StorageManager failed to complete add user");
841         return errCode;
842     }
843     FinishTraceAdapter();
844 #endif
845     return ERR_OK;
846 }
847 
CheckAllAppDied(int32_t accountId)848 ErrCode OsAccountInterface::CheckAllAppDied(int32_t accountId)
849 {
850     int32_t dealTimes = DEAL_TIMES;
851     while (dealTimes > 0) {
852         bool isAllDied = AbilityManagerAdapter::GetInstance()->IsAllAppDied(accountId);
853         if (isAllDied) {
854             return ERR_OK;
855         }
856         ACCOUNT_LOGE("IsAllAppDied check failed");
857         usleep(GET_MSG_FREQ);
858         dealTimes--;
859     }
860     return ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT;
861 }
862 }  // namespace AccountSA
863 }  // namespace OHOS
864