• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "ohos_account_manager.h"
17 #include <cerrno>
18 #include <dirent.h>
19 #include <iomanip>
20 #include <sstream>
21 #include <sys/types.h>
22 #include "account_event_provider.h"
23 #include "account_helper_data.h"
24 #include "account_info.h"
25 #include "account_log_wrapper.h"
26 #include "account_mgr_service.h"
27 #include "common_event_support.h"
28 #include "hisysevent.h"
29 #include "ipc_skeleton.h"
30 #include "mbedtls/sha256.h"
31 #include "system_ability_definition.h"
32 
33 using namespace OHOS::EventFwk;
34 
35 namespace OHOS {
36 namespace AccountSA {
37 namespace {
38 constexpr std::int32_t MAX_RETRY_TIMES = 2; // give another chance when json file corrupted
39 constexpr std::uint32_t MAX_NAME_LENGTH = 256;
40 constexpr std::uint32_t MAX_UID_LENGTH = 512;
41 constexpr std::uint32_t HASH_LENGTH = 32;
42 constexpr std::uint32_t OHOS_ACCOUNT_UDID_LENGTH = HASH_LENGTH * 2;
43 constexpr std::uint32_t WIDTH_FOR_HEX = 2;
44 const std::string KEY_ACCOUNT_EVENT_LOGIN = "LOGIN";
45 const std::string KEY_ACCOUNT_EVENT_LOGOUT = "LOGOUT";
46 const std::string KEY_ACCOUNT_EVENT_TOKEN_INVALID = "TOKEN_INVALID";
47 const std::string KEY_ACCOUNT_EVENT_LOGOFF = "LOGOFF";
48 
GetAccountEventStr(const std::map<std::string,std::string> & accountEventMap,const std::string & eventKey,const std::string & defaultValue)49 std::string GetAccountEventStr(const std::map<std::string, std::string> &accountEventMap,
50     const std::string &eventKey, const std::string &defaultValue)
51 {
52     const auto &it = accountEventMap.find(eventKey);
53     if (it != accountEventMap.end()) {
54         return it->second;
55     }
56     return defaultValue;
57 }
58 
GenerateOhosUdidWithSha256(const std::string & name,const std::string & uid)59 std::string GenerateOhosUdidWithSha256(const std::string &name, const std::string &uid)
60 {
61     if (name.empty() || name.length() > MAX_NAME_LENGTH) {
62         ACCOUNT_LOGE("input name empty or too long, length %{public}zu", name.length());
63         return std::string("");
64     }
65 
66     if (uid.empty() || uid.length() > MAX_UID_LENGTH) {
67         ACCOUNT_LOGE("input uid empty or too long, length %{public}zu", uid.length());
68         return std::string("");
69     }
70 
71     unsigned char hash[HASH_LENGTH] = { 0 };
72     mbedtls_sha256_context context;
73     mbedtls_sha256_init(&context);
74     mbedtls_sha256_starts_ret(&context, 0);
75 
76     std::string plainStr = name + uid;
77     mbedtls_sha256_update_ret(&context, (const unsigned char*)plainStr.c_str(), plainStr.length());
78     mbedtls_sha256_finish_ret(&context, hash);
79     mbedtls_sha256_free(&context);
80 
81     std::stringstream ss;
82     for (std::uint32_t i = 0; i < HASH_LENGTH; ++i) {
83         ss << std::hex << std::uppercase << std::setw(WIDTH_FOR_HEX)
84             << std::setfill('0') << std::uint16_t(hash[i]);
85     }
86 
87     std::string ohosUidStr;
88     ss >> ohosUidStr;
89     return ohosUidStr;
90 }
91 
GetCallingUserID()92 std::int32_t GetCallingUserID()
93 {
94     std::int32_t callingUId = IPCSkeleton::GetCallingUid();
95     return (callingUId / UID_TRANSFORM_DIVISOR);
96 }
97 }
98 
99 /**
100  * Ohos account state change.
101  *
102  * @param name ohos account name
103  * @param uid ohos account uid
104  * @param eventStr ohos account state change event
105  * @return true if the processing was completed, otherwise false
106  */
OhosAccountStateChange(const std::string & name,const std::string & uid,const std::string & eventStr)107 bool OhosAccountManager::OhosAccountStateChange(const std::string &name, const std::string &uid,
108     const std::string &eventStr)
109 {
110     auto itFunc = eventFuncMap_.find(eventStr);
111     if (itFunc == eventFuncMap_.end()) {
112         ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
113         return false;
114     }
115     return (this->*(itFunc->second))(name, uid, eventStr);
116 }
117 
118 /**
119  * Clear current account information
120  */
ClearOhosAccount(AccountInfo & curOhosAccountInfo,std::int32_t clrStatus) const121 bool OhosAccountManager::ClearOhosAccount(AccountInfo &curOhosAccountInfo, std::int32_t clrStatus) const
122 {
123     curOhosAccountInfo.clear(clrStatus);
124     ErrCode errCode = dataDealer_->AccountInfoToJson(curOhosAccountInfo);
125     if (errCode != ERR_OK) {
126         ACCOUNT_LOGE("AccountInfoToJson error");
127         return false;
128     }
129     return true;
130 }
131 
132 /**
133  * Config current account config.
134  *
135  * @param account account information.
136  * @return true if success.
137  */
SaveOhosAccountInfo(AccountInfo & ohosAccountInfo) const138 bool OhosAccountManager::SaveOhosAccountInfo(AccountInfo &ohosAccountInfo) const
139 {
140     ErrCode errCode = dataDealer_->AccountInfoToJson(ohosAccountInfo);
141     if (errCode != ERR_OK) {
142         ACCOUNT_LOGE("AccountInfoToJson error.");
143         return false;
144     }
145     return true;
146 }
147 
148 /**
149  * Get current account information.
150  *
151  * @return current account information.
152  */
GetCurrentOhosAccountInfo()153 AccountInfo OhosAccountManager::GetCurrentOhosAccountInfo()
154 {
155     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
156 
157     AccountInfo currOhosAccountInfo;
158     std::int32_t callingUserId = GetCallingUserID();
159     if (dataDealer_->AccountInfoFromJson(currOhosAccountInfo, callingUserId) != ERR_OK) {
160         ACCOUNT_LOGE("get current ohos account info failed, callingUserId %{public}d.", callingUserId);
161         currOhosAccountInfo.clear();
162     }
163     return currOhosAccountInfo;
164 }
165 
166 /**
167  * Get current account state.
168  *
169  * @return current account state id.
170  */
GetCurrentOhosAccountState()171 std::int32_t OhosAccountManager::GetCurrentOhosAccountState()
172 {
173     AccountInfo currOhosAccountInfo = GetCurrentOhosAccountInfo();
174     return currOhosAccountInfo.ohosAccountStatus_;
175 }
176 
177 /**
178  * Process an account event.
179  * @param curOhosAccount current ohos account info
180  * @param eventStr ohos account state change event
181  * @return true if the processing was completed, otherwise false
182  */
HandleEvent(AccountInfo & curOhosAccount,const std::string & eventStr)183 bool OhosAccountManager::HandleEvent(AccountInfo &curOhosAccount, const std::string &eventStr)
184 {
185     auto iter = eventMap_.find(eventStr);
186     if (iter == eventMap_.end()) {
187         ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
188         return false;
189     }
190 
191     int event = iter->second;
192     accountState_->SetAccountState(curOhosAccount.ohosAccountStatus_);
193     bool ret = accountState_->StateChangeProcess(event);
194     if (!ret) {
195         ACCOUNT_LOGE("Handle event %{public}d failed", event);
196         return false;
197     }
198     std::int32_t newState = accountState_->GetAccountState();
199     if (newState != curOhosAccount.ohosAccountStatus_) {
200         HiviewDFX::HiSysEvent::Write("OS_ACCOUNT", "OHOS_ACCOUNT_STATE_MACHINE_EVENT",
201             HiviewDFX::HiSysEvent::EventType::FAULT, "USER_ID", curOhosAccount.userId_,
202             "OPERATION_TYPE", event, "OLD_STATE", curOhosAccount.ohosAccountStatus_, "NEW_STATE", newState);
203         curOhosAccount.ohosAccountStatus_ = newState;
204     }
205     return true;
206 }
207 
208 /**
209  * login ohos (for distributed network) account.
210  *
211  * @param name ohos account name
212  * @param uid ohos account uid
213  * @param eventStr ohos account state change event
214  * @return true if the processing was completed, otherwise false
215  */
LoginOhosAccount(const std::string & name,const std::string & uid,const std::string & eventStr)216 bool OhosAccountManager::LoginOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr)
217 {
218     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
219 
220     std::int32_t callingUserId = GetCallingUserID();
221     AccountInfo currOhosAccountInfo;
222     if (dataDealer_->AccountInfoFromJson(currOhosAccountInfo, callingUserId) != ERR_OK) {
223         ACCOUNT_LOGE("get current ohos account info failed, callingUserId %{public}d.", callingUserId);
224         return false;
225     }
226 
227     // current local user cannot be bound again when it has already been bound to an ohos account
228     if (currOhosAccountInfo.ohosAccountStatus_ == ACCOUNT_STATE_LOGIN) {
229         ACCOUNT_LOGE("current account has already been bounded. callingUserId %{public}d.", callingUserId);
230         return false;
231     }
232 
233     // traversal check
234     std::string ohosAccountUid = GenerateOhosUdidWithSha256(name, uid);
235     bool ret = CheckOhosAccountCanBind(ohosAccountUid);
236     if (!ret) {
237         ACCOUNT_LOGE("check can be bound failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
238             callingUserId, ohosAccountUid.c_str());
239         return false;
240     }
241 
242     std::int32_t oldStatus = currOhosAccountInfo.ohosAccountStatus_;
243     ret = HandleEvent(currOhosAccountInfo, eventStr); // update account status
244     if (!ret) {
245         ACCOUNT_LOGE("HandleEvent %{public}s failed! callingUserId %{public}d, ohosAccountUid %{public}s.",
246             eventStr.c_str(), callingUserId, ohosAccountUid.c_str());
247         return false;
248     }
249 
250     // update account info
251     currOhosAccountInfo.ohosAccountName_ = name;
252     currOhosAccountInfo.ohosAccountUid_ = ohosAccountUid;
253     currOhosAccountInfo.bindTime_ = std::time(nullptr);
254     currOhosAccountInfo.userId_ = callingUserId;
255     ret = SaveOhosAccountInfo(currOhosAccountInfo);
256     if (!ret) {
257         ACCOUNT_LOGE("SaveOhosAccountInfo failed! callingUserId %{public}d, ohosAccountUid %{public}s.",
258             callingUserId, ohosAccountUid.c_str());
259         return false;
260     }
261 
262     // publish event
263     bool errCode = AccountEventProvider::EventPublish(EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGIN);
264     if (!errCode) {
265         ACCOUNT_LOGE("publish ohos account login event failed! callingUserId %{public}d, ohosAccountUid %{public}s.",
266             callingUserId, ohosAccountUid.c_str());
267         ReportPublishFailureEvent(errCode, oldStatus, currOhosAccountInfo);
268         return false;
269     }
270     ACCOUNT_LOGI("LoginOhosAccount success! callingUserId %{public}d, ohosAccountUid %{public}s.",
271         callingUserId, ohosAccountUid.c_str());
272     return true;
273 }
274 
275 /**
276  * logout ohos (for distributed network) account.
277  *
278  * @param name ohos account name
279  * @param uid ohos account uid
280  * @param eventStr ohos account state change event
281  * @return true if the processing was completed, otherwise false
282  */
LogoutOhosAccount(const std::string & name,const std::string & uid,const std::string & eventStr)283 bool OhosAccountManager::LogoutOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr)
284 {
285     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
286 
287     std::int32_t callingUserId = GetCallingUserID();
288     AccountInfo currentAccount;
289     if (!GetCurOhosAccountAndCheckMatch(currentAccount, name, uid, callingUserId)) {
290         ACCOUNT_LOGE("check match failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
291             callingUserId, uid.c_str());
292         return false;
293     }
294 
295     std::int32_t oldStatus = currentAccount.ohosAccountStatus_;
296     bool ret = HandleEvent(currentAccount, eventStr); // update account status
297     if (!ret) {
298         ACCOUNT_LOGE("HandleEvent %{public}s failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
299             eventStr.c_str(), callingUserId, uid.c_str());
300         return false;
301     }
302 
303     ret = ClearOhosAccount(currentAccount); // clear account info with ACCOUNT_STATE_UNBOUND
304     if (!ret) {
305         ACCOUNT_LOGE("ClearOhosAccount failed! callingUserId %{public}d, ohosAccountUid %{public}s.",
306             callingUserId, uid.c_str());
307         return false;
308     }
309 
310     ret = AccountEventProvider::EventPublish(EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOUT);
311     if (!ret) {
312         ACCOUNT_LOGE("publish account logout event failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
313             callingUserId, uid.c_str());
314         ReportPublishFailureEvent(ret, oldStatus, currentAccount);
315         return false;
316     }
317     ACCOUNT_LOGI("LogoutOhosAccount success, callingUserId %{public}d, ohosAccountUid %{public}s.",
318         callingUserId, uid.c_str());
319     return true;
320 }
321 
322 /**
323  * logoff ohos (for distributed network) account.
324  *
325  * @param name ohos account name
326  * @param uid ohos account uid
327  * @param eventStr ohos account state change event
328  * @return true if the processing was completed, otherwise false
329  */
LogoffOhosAccount(const std::string & name,const std::string & uid,const std::string & eventStr)330 bool OhosAccountManager::LogoffOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr)
331 {
332     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
333 
334     std::int32_t callingUserId = GetCallingUserID();
335     AccountInfo currentAccount;
336     if (!GetCurOhosAccountAndCheckMatch(currentAccount, name, uid, callingUserId)) {
337         ACCOUNT_LOGE("check match failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
338             callingUserId, uid.c_str());
339         return false;
340     }
341 
342     std::int32_t oldStatus = currentAccount.ohosAccountStatus_;
343     bool ret = HandleEvent(currentAccount, eventStr); // update account status
344     if (!ret) {
345         ACCOUNT_LOGE("HandleEvent %{public}s failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
346             eventStr.c_str(), callingUserId, uid.c_str());
347         return false;
348     }
349 
350     ret = ClearOhosAccount(currentAccount, ACCOUNT_STATE_LOGOFF); // clear account info with ACCOUNT_STATE_LOGOFF
351     if (!ret) {
352         ACCOUNT_LOGE("ClearOhosAccount failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
353             callingUserId, uid.c_str());
354         return false;
355     }
356     bool errCode = AccountEventProvider::EventPublish(EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOFF);
357     if (errCode != true) {
358         ACCOUNT_LOGE("publish account logoff event failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
359             callingUserId, uid.c_str());
360         ReportPublishFailureEvent(errCode, oldStatus, currentAccount);
361         return false;
362     }
363     ACCOUNT_LOGI("LogoffOhosAccount success, callingUserId %{public}d, ohosAccountUid %{public}s.",
364         callingUserId, uid.c_str());
365     return true;
366 }
367 
368 /**
369  * Handle token_invalid event.
370  *
371  * @param name ohos account name
372  * @param uid ohos account uid
373  * @param eventStr ohos account state change event
374  * @return true if the processing was completed, otherwise false
375  */
HandleOhosAccountTokenInvalidEvent(const std::string & name,const std::string & uid,const std::string & eventStr)376 bool OhosAccountManager::HandleOhosAccountTokenInvalidEvent(const std::string &name,
377     const std::string &uid, const std::string &eventStr)
378 {
379     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
380 
381     std::int32_t callingUserId = GetCallingUserID();
382     AccountInfo currentOhosAccount;
383     if (!GetCurOhosAccountAndCheckMatch(currentOhosAccount, name, uid, callingUserId)) {
384         ACCOUNT_LOGE("check match failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
385             callingUserId, uid.c_str());
386         return false;
387     }
388 
389     std::int32_t oldStatus = currentOhosAccount.ohosAccountStatus_;
390     bool ret = HandleEvent(currentOhosAccount, eventStr); // update account status
391     if (!ret) {
392         ACCOUNT_LOGE("HandleEvent %{public}s failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
393             eventStr.c_str(), callingUserId, uid.c_str());
394         return false;
395     }
396 
397     ret = SaveOhosAccountInfo(currentOhosAccount);
398     if (!ret) {
399         // moving on even if failed to update account info
400         ACCOUNT_LOGW("SaveOhosAccountInfo failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
401             callingUserId, uid.c_str());
402     }
403     bool errCode = AccountEventProvider::EventPublish(EventFwk::CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID);
404     if (errCode != true) {
405         ACCOUNT_LOGE("publish token invalid event failed, callingUserId %{public}d, ohosAccountUid %{public}s.",
406             callingUserId, uid.c_str());
407         ReportPublishFailureEvent(errCode, oldStatus, currentOhosAccount);
408         return false;
409     }
410     ACCOUNT_LOGI("success, callingUserId %{public}d, ohosAccountUid %{public}s.", callingUserId, uid.c_str());
411     return true;
412 }
413 
414 /**
415  * Init event mapper.
416  */
BuildEventsMapper()417 void OhosAccountManager::BuildEventsMapper()
418 {
419     const std::map<std::string, std::string> accountEventMap = AccountHelperData::GetAccountEventMap();
420     std::string eventLogin = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGIN, OHOS_ACCOUNT_EVENT_LOGIN);
421     std::string eventLogout = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGOUT, OHOS_ACCOUNT_EVENT_LOGOUT);
422     std::string eventTokenInvalid = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_TOKEN_INVALID,
423         OHOS_ACCOUNT_EVENT_TOKEN_INVALID);
424     std::string eventLogoff = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGOFF, OHOS_ACCOUNT_EVENT_LOGOFF);
425 
426     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogin, ACCOUNT_BIND_SUCCESS_EVT));
427     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogout, ACCOUNT_MANUAL_UNBOUND_EVT));
428     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventTokenInvalid, ACCOUNT_TOKEN_EXPIRED_EVT));
429     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogoff, ACCOUNT_MANUAL_LOGOFF_EVT));
430 
431     eventFuncMap_.insert(std::make_pair(eventLogin, &OhosAccountManager::LoginOhosAccount));
432     eventFuncMap_.insert(std::make_pair(eventLogout, &OhosAccountManager::LogoutOhosAccount));
433     eventFuncMap_.insert(std::make_pair(eventLogoff, &OhosAccountManager::LogoffOhosAccount));
434     eventFuncMap_.insert(std::make_pair(eventTokenInvalid, &OhosAccountManager::HandleOhosAccountTokenInvalidEvent));
435 }
436 
437 /**
438  * Init ohos account manager.
439  *
440  */
OnInitialize()441 bool OhosAccountManager::OnInitialize()
442 {
443     accountState_ = std::make_unique<AccountStateMachine>();
444     BuildEventsMapper();
445 
446     dataDealer_ = std::make_unique<OhosAccountDataDeal>(ACCOUNT_CFG_DIR_ROOT_PATH);
447 
448     std::int32_t tryTimes = 0;
449     while (tryTimes < MAX_RETRY_TIMES) {
450         tryTimes++;
451         ErrCode errCode = dataDealer_->Init(DEVICE_ACCOUNT_OWNER);
452         if (errCode == ERR_OK) {
453             break;
454         }
455 
456         // when json file corrupted, have it another try
457         if ((tryTimes == MAX_RETRY_TIMES) || (errCode != ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION)) {
458             ACCOUNT_LOGE("parse json file failed: %{public}d, tryTime: %{public}d", errCode, tryTimes);
459             eventMap_.clear();
460             eventFuncMap_.clear();
461             return false;
462         }
463     }
464     return true;
465 }
466 
467 /**
468  * Handle device account switch event.
469  *
470  * @param None
471  * @return None
472  */
HandleDevAccountSwitchEvent()473 void OhosAccountManager::HandleDevAccountSwitchEvent()
474 {
475     std::lock_guard<std::mutex> mutexLock(mgrMutex_);
476     eventMap_.clear();
477     eventFuncMap_.clear();
478 
479     // Re-Init
480     if (!OnInitialize()) {
481         ACCOUNT_LOGE("Handle dev Account SwitchEvent failed");
482     }
483 }
484 
ReportPublishFailureEvent(std::int32_t errCode,std::int32_t oldStatus,const AccountInfo & account)485 void OhosAccountManager::ReportPublishFailureEvent(std::int32_t errCode,
486                                                    std::int32_t oldStatus,
487                                                    const AccountInfo &account)
488 {
489     HiviewDFX::HiSysEvent::Write("OS_ACCOUNT", "PUBLISH_COMMON_EVENT_FAILED",
490         HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", errCode, "OLD_STATE", oldStatus,
491         "NEW_STATE", account.ohosAccountStatus_, "USER_ID", account.userId_);
492 }
493 
CheckOhosAccountCanBind(const std::string & newOhosUid) const494 bool OhosAccountManager::CheckOhosAccountCanBind(const std::string &newOhosUid) const
495 {
496     if (newOhosUid.length() != OHOS_ACCOUNT_UDID_LENGTH) {
497         ACCOUNT_LOGE("newOhosUid invalid length, %{public}s.", newOhosUid.c_str());
498         return false;
499     }
500 
501     // check whether newOhosUid has been already bound to another account or not
502     DIR* rootDir = opendir(ACCOUNT_CFG_DIR_ROOT_PATH.c_str());
503     if (rootDir == nullptr) {
504         ACCOUNT_LOGE("cannot open dir %{public}s, err %{public}d.", ACCOUNT_CFG_DIR_ROOT_PATH.c_str(), errno);
505         return false;
506     }
507     struct dirent* curDir = nullptr;
508     while ((curDir = readdir(rootDir)) != nullptr) {
509         std::string curDirName(curDir->d_name);
510         if (curDirName == "." || curDirName == ".." || curDir->d_type != DT_DIR) {
511             continue;
512         }
513 
514         AccountInfo curInfo;
515         std::stringstream sstream;
516         sstream << curDirName;
517         std::int32_t userId = -1;
518         sstream >> userId;
519         if (dataDealer_->AccountInfoFromJson(curInfo, userId) != ERR_OK) {
520             ACCOUNT_LOGI("get ohos account info from user %{public}s failed.", curDirName.c_str());
521             continue;
522         }
523 
524         if (curInfo.ohosAccountStatus_ != ACCOUNT_STATE_LOGIN) {
525             continue; // account not bind, skip check
526         }
527 
528         if (newOhosUid == curInfo.ohosAccountUid_) {
529             ACCOUNT_LOGE("cannot bind, it has been bound with local account %{public}d.", curInfo.userId_);
530             (void)closedir(rootDir);
531             return false;
532         }
533     }
534 
535     (void)closedir(rootDir);
536     return true;
537 }
538 
GetCurOhosAccountAndCheckMatch(AccountInfo & curOhosAccountInfo,const std::string & inputName,const std::string & inputUid,const std::int32_t callingUserId) const539 bool OhosAccountManager::GetCurOhosAccountAndCheckMatch(AccountInfo &curOhosAccountInfo,
540                                                         const std::string &inputName,
541                                                         const std::string &inputUid,
542                                                         const std::int32_t callingUserId) const
543 {
544     if (dataDealer_->AccountInfoFromJson(curOhosAccountInfo, callingUserId) != ERR_OK) {
545         ACCOUNT_LOGE("cannot read from config, inputName %{public}s.", inputName.c_str());
546         return false;
547     }
548 
549     std::string ohosAccountUid = GenerateOhosUdidWithSha256(inputName, inputUid);
550     if (inputName != curOhosAccountInfo.ohosAccountName_ || ohosAccountUid != curOhosAccountInfo.ohosAccountUid_) {
551         ACCOUNT_LOGE("account name %{public}s or ohosAccountUid %{public}s mismatch, calling user %{public}d.",
552             inputName.c_str(), ohosAccountUid.c_str(), callingUserId);
553         return false;
554     }
555     return true;
556 }
557 } // namespace AccountSA
558 } // namespace OHOS
559