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