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