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