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