1 /*
2 * Copyright (c) 2022-2025 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 "inner_domain_account_manager.h"
17 #include <dlfcn.h>
18 #include <pthread.h>
19 #include <thread>
20 #include <securec.h>
21 #include <cstring>
22 #include <vector>
23 #include "account_constants.h"
24 #include "account_hisysevent_adapter.h"
25 #include "account_info_report.h"
26 #include "account_log_wrapper.h"
27 #include "bool_wrapper.h"
28 #ifdef HAS_CES_PART
29 #include "account_event_provider.h"
30 #include "common_event_support.h"
31 #endif // HAS_CES_PART
32 #include "domain_account_common.h"
33 #include "domain_account_plugin_death_recipient.h"
34 #include "domain_account_callback_service.h"
35 #include "domain_has_domain_info_callback.h"
36 #include "idomain_account_callback.h"
37 #include "iinner_os_account_manager.h"
38 #include "inner_account_iam_manager.h"
39 #include "int_wrapper.h"
40 #include "ipc_skeleton.h"
41 #include "os_account_constants.h"
42 #include "parameters.h"
43 #include "status_listener_manager.h"
44 #include "string_wrapper.h"
45 #ifdef HICOLLIE_ENABLE
46 #include "xcollie/xcollie.h"
47 #endif // HICOLLIE_ENABLE
48
49 namespace OHOS {
50 namespace AccountSA {
51 namespace {
52 constexpr char THREAD_AUTH[] = "auth";
53 constexpr char THREAD_INNER_AUTH[] = "innerAuth";
54 constexpr char THREAD_HAS_ACCOUNT[] = "hasAccount";
55 constexpr char THREAD_GET_ACCOUNT[] = "getAccount";
56 constexpr char THREAD_BIND_ACCOUNT[] = "bindAccount";
57 constexpr char THREAD_UNBIND_ACCOUNT[] = "unbindAccount";
58 constexpr char THREAD_GET_ACCESS_TOKEN[] = "getAccessToken";
59 constexpr char THREAD_IS_ACCOUNT_VALID[] = "isAccountTokenValid";
60 constexpr char DLOPEN_ERR[] = "dlopen failed";
61 constexpr int32_t INVALID_USERID = -1;
62 constexpr int32_t ADMIN_USERID = 0;
63 constexpr uint32_t RETRY_SLEEP_MS = 5;
64 static const char OPERATOR_LOAD_LIB[] = "LoaderLib";
65 #ifdef _ARM64_
66 static const char LIB_PATH[] = "/system/lib64/platformsdk/";
67 #else
68 static const char LIB_PATH[] = "/system/lib/platformsdk/";
69 #endif
70 static const char LIB_NAME[] = "libdomain_account_plugin.z.so";
71 static const char EDM_FREEZE_BACKGROUND_PARAM[] = "persist.edm.inactive_user_freeze";
72 #ifdef HICOLLIE_ENABLE
73 constexpr int32_t DOMAIN_ACCOUNT_RECOVERY_TIMEOUT = 30; // 30s
74 #endif // HICOLLIE_ENABLE
75
ConvertToAccountErrCode(ErrCode idlErrCode)76 ErrCode ConvertToAccountErrCode(ErrCode idlErrCode)
77 {
78 if (idlErrCode == ERR_INVALID_VALUE || idlErrCode == ERR_INVALID_DATA) {
79 return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
80 }
81 return idlErrCode;
82 }
83 }
84 static const std::map<PluginMethodEnum, std::string> METHOD_NAME_MAP = {
85 {PluginMethodEnum::ADD_SERVER_CONFIG, "AddServerConfig"},
86 {PluginMethodEnum::REMOVE_SERVER_CONFIG, "RemoveServerConfig"},
87 {PluginMethodEnum::UPDATE_SERVER_CONFIG, "UpdateServerConfig"},
88 {PluginMethodEnum::GET_SERVER_CONFIG, "GetServerConfig"},
89 {PluginMethodEnum::GET_ALL_SERVER_CONFIGS, "GetServerConfigList"},
90 {PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG, "GetAccountServerConfig"},
91 {PluginMethodEnum::AUTH, "Auth"},
92 {PluginMethodEnum::AUTH_WITH_POPUP, "AuthWithPopup"},
93 {PluginMethodEnum::AUTH_WITH_TOKEN, "AuthWithToken"},
94 {PluginMethodEnum::GET_ACCOUNT_INFO, "GetAccountInfo"},
95 {PluginMethodEnum::GET_AUTH_STATUS_INFO, "GetAuthStatusInfo"},
96 {PluginMethodEnum::BIND_ACCOUNT, "BindAccount"},
97 {PluginMethodEnum::UNBIND_ACCOUNT, "UnbindAccount"},
98 {PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID, "IsAccountTokenValid"},
99 {PluginMethodEnum::GET_ACCESS_TOKEN, "GetAccessToken"},
100 {PluginMethodEnum::UPDATE_ACCOUNT_INFO, "UpdateAccountInfo"},
101 {PluginMethodEnum::IS_AUTHENTICATION_EXPIRED, "IsAuthenticationExpired"},
102 {PluginMethodEnum::SET_ACCOUNT_POLICY, "SetAccountPolicy"},
103 {PluginMethodEnum::GET_ACCOUNT_POLICY, "GetAccountPolicy"},
104 };
105
IsSupportNetRequest()106 static bool IsSupportNetRequest()
107 {
108 bool isBackgroundFreezeEnabled = OHOS::system::GetBoolParameter(EDM_FREEZE_BACKGROUND_PARAM, false);
109 if (!isBackgroundFreezeEnabled) {
110 return true;
111 }
112 int32_t accountId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
113 if (accountId == 0) { // account 0 not limited by network policy
114 return true;
115 }
116 bool isForeground = false;
117 IInnerOsAccountManager::GetInstance().IsOsAccountForeground(accountId, 0, isForeground);
118 return isForeground;
119 }
120
GetCallingUserID()121 static int32_t GetCallingUserID()
122 {
123 std::int32_t userId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
124 if (userId <= 0) {
125 std::vector<int32_t> userIds;
126 (void)IInnerOsAccountManager::GetInstance().QueryActiveOsAccountIds(userIds);
127 if (userIds.empty()) {
128 return INVALID_USERID; // invalid user id
129 }
130 userId = userIds[0];
131 }
132 return userId;
133 }
134
InnerDomainAccountManager()135 InnerDomainAccountManager::InnerDomainAccountManager()
136 {
137 int times = 0;
138 while (times < Constants::MAX_RETRY_TIMES) {
139 LoaderLib(LIB_PATH, LIB_NAME);
140 if (libHandle_ != nullptr) {
141 return;
142 }
143 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_SLEEP_MS));
144 times++;
145 }
146 if (libHandle_ == nullptr) {
147 ACCOUNT_LOGE("LoaderLib failed, tryTime: %{public}d", times);
148 }
149 }
150
~InnerDomainAccountManager()151 InnerDomainAccountManager::~InnerDomainAccountManager()
152 {
153 CloseLib();
154 }
155
GetInstance()156 InnerDomainAccountManager &InnerDomainAccountManager::GetInstance()
157 {
158 static InnerDomainAccountManager *instance = new (std::nothrow) InnerDomainAccountManager();
159 return *instance;
160 }
161
InnerDomainAuthCallback(int32_t userId,const sptr<IDomainAccountCallback> & callback)162 InnerDomainAuthCallback::InnerDomainAuthCallback(int32_t userId, const sptr<IDomainAccountCallback> &callback)
163 : userId_(userId), callback_(callback)
164 {}
165
~InnerDomainAuthCallback()166 InnerDomainAuthCallback::~InnerDomainAuthCallback()
167 {}
168
CallbackOnResult(sptr<IDomainAccountCallback> & callback,const int32_t errCode,Parcel & resultParcel)169 static void CallbackOnResult(sptr<IDomainAccountCallback> &callback, const int32_t errCode, Parcel &resultParcel)
170 {
171 if (callback == nullptr) {
172 ACCOUNT_LOGI("callback_ is nullptr");
173 return;
174 }
175 DomainAccountParcel domainAccountParcel;
176 domainAccountParcel.SetParcelData(resultParcel);
177 callback->OnResult(errCode, domainAccountParcel);
178 return;
179 }
180
OnResult(int32_t errCode,const DomainAccountParcel & domainAccountParcel)181 ErrCode InnerDomainAuthCallback::OnResult(int32_t errCode, const DomainAccountParcel &domainAccountParcel)
182 {
183 Parcel parcel;
184 domainAccountParcel.GetParcelData(parcel);
185 Parcel resultParcel;
186 std::shared_ptr<DomainAuthResult> authResult(DomainAuthResult::Unmarshalling(parcel));
187 if (authResult == nullptr) {
188 ACCOUNT_LOGE("authResult is nullptr");
189 CallbackOnResult(callback_, ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR, resultParcel);
190 return ERR_OK;
191 }
192 if ((errCode == ERR_OK) && (userId_ != 0)) {
193 InnerDomainAccountManager::GetInstance().InsertTokenToMap(userId_, (*authResult).token);
194 DomainAccountInfo domainInfo;
195 InnerDomainAccountManager::GetInstance().GetDomainAccountInfoByUserId(userId_, domainInfo);
196 InnerDomainAccountManager::GetInstance().NotifyDomainAccountEvent(
197 userId_, DomainAccountEvent::LOG_IN, DomainAccountStatus::LOG_END, domainInfo);
198 bool isActivated = false;
199 (void)IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId_, isActivated);
200 DomainAccountStatus status = isActivated ? DomainAccountStatus::LOGIN : DomainAccountStatus::LOGIN_BACKGROUND;
201 IInnerOsAccountManager::GetInstance().UpdateAccountStatusForDomain(userId_, status);
202 }
203 (void)memset_s(authResult->token.data(), authResult->token.size(), 0, authResult->token.size());
204 authResult->token.clear();
205
206 if (!(*authResult).Marshalling(resultParcel)) {
207 ACCOUNT_LOGE("authResult Marshalling failed");
208 CallbackOnResult(callback_, ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR, resultParcel);
209 return ERR_OK;
210 }
211 AccountInfoReport::ReportSecurityInfo("", userId_, ReportEvent::EVENT_LOGIN, errCode);
212 CallbackOnResult(callback_, errCode, resultParcel);
213 return ERR_OK;
214 }
215
RegisterPlugin(const sptr<IDomainAccountPlugin> & plugin)216 ErrCode InnerDomainAccountManager::RegisterPlugin(const sptr<IDomainAccountPlugin> &plugin)
217 {
218 std::lock_guard<std::mutex> lock(mutex_);
219 if (plugin == nullptr) {
220 ACCOUNT_LOGE("the registered plugin is nullptr");
221 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
222 }
223 if (plugin_ != nullptr) {
224 ACCOUNT_LOGE("plugin already exists");
225 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_ALREADY_EXIST;
226 }
227 auto deathRecipient = GetDeathRecipient();
228 if ((plugin->AsObject()->IsProxyObject()) &&
229 ((deathRecipient == nullptr) || (!plugin->AsObject()->AddDeathRecipient(deathRecipient)))) {
230 ACCOUNT_LOGE("failed to add death recipient for plugin");
231 return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
232 }
233 plugin_ = plugin;
234 callingUid_ = IPCSkeleton::GetCallingUid();
235 return ERR_OK;
236 }
237
UnregisterPlugin()238 ErrCode InnerDomainAccountManager::UnregisterPlugin()
239 {
240 std::lock_guard<std::mutex> lock(mutex_);
241 if (callingUid_ == -1) {
242 ACCOUNT_LOGI("No plugin register.");
243 return ERR_OK;
244 }
245 if (callingUid_ != IPCSkeleton::GetCallingUid()) {
246 ACCOUNT_LOGE("Failed to check callingUid, register callingUid=%{public}d, unregister callingUid=%{public}d.",
247 callingUid_, IPCSkeleton::GetCallingUid());
248 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
249 }
250 if ((plugin_ != nullptr) && (plugin_->AsObject() != nullptr)) {
251 plugin_->AsObject()->RemoveDeathRecipient(deathRecipient_);
252 }
253 plugin_ = nullptr;
254 callingUid_ = -1;
255 deathRecipient_ = nullptr;
256 return ERR_OK;
257 }
258
StartAuth(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const std::vector<uint8_t> & authData,const sptr<IDomainAccountCallback> & callback,AuthMode authMode)259 ErrCode InnerDomainAccountManager::StartAuth(const sptr<IDomainAccountPlugin> &plugin, const DomainAccountInfo &info,
260 const std::vector<uint8_t> &authData, const sptr<IDomainAccountCallback> &callback, AuthMode authMode)
261 {
262 if (callback == nullptr) {
263 ACCOUNT_LOGE("invalid callback, cannot return result to client");
264 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
265 }
266 Parcel emptyParcel;
267 AccountSA::DomainAuthResult emptyResult;
268 if (!emptyResult.Marshalling(emptyParcel)) {
269 ACCOUNT_LOGE("authResult Marshalling failed");
270 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
271 }
272 if (plugin == nullptr) {
273 ACCOUNT_LOGE("plugin not exists");
274 DomainAccountParcel domainAccountParcel;
275 domainAccountParcel.SetParcelData(emptyParcel);
276 callback->OnResult(ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST), domainAccountParcel);
277 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
278 }
279 ErrCode errCode = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
280 switch (authMode) {
281 case AUTH_WITH_CREDENTIAL_MODE:
282 errCode = ConvertToAccountErrCode(plugin->Auth(info, authData, callback));
283 break;
284 case AUTH_WITH_POPUP_MODE:
285 errCode = ConvertToAccountErrCode(plugin->AuthWithPopup(info, callback));
286 break;
287 case AUTH_WITH_TOKEN_MODE:
288 errCode = ConvertToAccountErrCode(plugin->AuthWithToken(info, authData, callback));
289 break;
290 default:
291 break;
292 }
293 if (errCode != ERR_OK) {
294 ACCOUNT_LOGE("failed to auth domain account, errCode: %{public}d", errCode);
295 DomainAccountParcel domainAccountParcel;
296 domainAccountParcel.SetParcelData(emptyParcel);
297 callback->OnResult(ConvertToJSErrCode(errCode), domainAccountParcel);
298 return errCode;
299 }
300 return ERR_OK;
301 }
302
GetDomainAccountInfoByUserId(int32_t userId,DomainAccountInfo & domainInfo)303 ErrCode InnerDomainAccountManager::GetDomainAccountInfoByUserId(int32_t userId, DomainAccountInfo &domainInfo)
304 {
305 OsAccountInfo accountInfo;
306 ErrCode errCode = IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(userId, accountInfo);
307 if (errCode != ERR_OK) {
308 ACCOUNT_LOGE("get os account info failed, errCode: %{public}d", errCode);
309 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
310 }
311 accountInfo.GetDomainInfo(domainInfo);
312 if (domainInfo.accountName_.empty()) {
313 ACCOUNT_LOGE("the target user is not a domain account");
314 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
315 }
316 return ERR_OK;
317 }
318
GetMethodNameByEnum(PluginMethodEnum methondEnum)319 std::string GetMethodNameByEnum(PluginMethodEnum methondEnum)
320 {
321 const auto& it = METHOD_NAME_MAP.find(methondEnum);
322 if (it != METHOD_NAME_MAP.end()) {
323 return it->second;
324 }
325 ACCOUNT_LOGE("enum=%{public}d can not find string", methondEnum);
326 return "";
327 }
328
LoaderLib(const std::string & path,const std::string & libName)329 void InnerDomainAccountManager::LoaderLib(const std::string &path, const std::string &libName)
330 {
331 std::lock_guard<std::mutex> lock(libMutex_);
332 std::string soPath = path + libName;
333 libHandle_ = dlopen(soPath.c_str(), RTLD_LAZY);
334 if (libHandle_ == nullptr) {
335 const char *dlsym_error = dlerror();
336 if (dlsym_error == NULL) {
337 dlsym_error = DLOPEN_ERR;
338 }
339 ACCOUNT_LOGE("Call dlopen failed error=%{public}s", dlsym_error);
340 ReportOsAccountOperationFail(
341 ADMIN_USERID, OPERATOR_LOAD_LIB, ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, dlsym_error);
342 return;
343 }
344 for (auto i = 0; i < static_cast<int>(PluginMethodEnum::COUNT); ++i) {
345 std::string methodName = GetMethodNameByEnum(static_cast<PluginMethodEnum>(i));
346 if (methodName.empty()) {
347 ACCOUNT_LOGE("Call check methodName emtpty");
348 libHandle_ = nullptr;
349 methodMap_.clear();
350 return;
351 }
352 dlerror();
353 void *func = dlsym(libHandle_, methodName.c_str());
354 const char *dlsym_error = dlerror();
355 if (dlsym_error != nullptr) {
356 ACCOUNT_LOGE("Call check method=%{public}s error=%{public}s", methodName.c_str(), dlsym_error);
357 ReportOsAccountOperationFail(
358 ADMIN_USERID, OPERATOR_LOAD_LIB, ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, dlsym_error);
359 libHandle_ = nullptr;
360 methodMap_.clear();
361 return;
362 }
363 methodMap_.emplace(static_cast<PluginMethodEnum>(i), func);
364 }
365 }
366
CloseLib()367 void InnerDomainAccountManager::CloseLib()
368 {
369 std::lock_guard<std::mutex> lock(libMutex_);
370 if (libHandle_ == nullptr) {
371 ACCOUNT_LOGE("LibHandle_ is nullptr.");
372 return;
373 }
374 dlclose(libHandle_);
375 libHandle_ = nullptr;
376 methodMap_.clear();
377 }
378
SetPluginString(const std::string & str,PluginString & pStr)379 static void SetPluginString(const std::string &str, PluginString &pStr)
380 {
381 if (str.empty()) {
382 ACCOUNT_LOGE("Str is empty.");
383 pStr.data = nullptr;
384 pStr.length = 0;
385 return;
386 }
387 pStr.data = strdup(str.c_str());
388 if (pStr.data == nullptr) {
389 ACCOUNT_LOGE("Failed to duplicate string.");
390 pStr.length = 0;
391 return;
392 }
393 pStr.length = str.length();
394 }
395
CleanPluginString(char ** data,size_t length)396 static void CleanPluginString(char** data, size_t length)
397 {
398 if (data == nullptr || *data == nullptr) {
399 ACCOUNT_LOGE("Data is nullptr.");
400 return;
401 }
402 (void)memset_s(*data, length, 0, length);
403 free(*data);
404 *(data) = nullptr;
405 return;
406 }
407
SetPluginUint8Vector(const std::vector<uint8_t> & vector,PluginUint8Vector & pVector)408 static bool SetPluginUint8Vector(const std::vector<uint8_t> &vector, PluginUint8Vector &pVector)
409 {
410 if (vector.empty()) {
411 ACCOUNT_LOGE("Vector is empty.");
412 pVector.data = nullptr;
413 pVector.capcity = 0;
414 pVector.size = 0;
415 return true;
416 }
417 pVector.data = (uint8_t *)vector.data();
418 pVector.capcity = vector.size();
419 pVector.size = vector.size();
420 return true;
421 }
422
GetAndCleanPluginUint8Vector(PluginUint8Vector & pVector,std::vector<uint8_t> & vector)423 static ErrCode GetAndCleanPluginUint8Vector(PluginUint8Vector &pVector, std::vector<uint8_t> &vector)
424 {
425 if (pVector.data == nullptr) {
426 ACCOUNT_LOGE("PluginUint8Vector data is null.");
427 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
428 }
429 vector.assign(pVector.data, pVector.data + pVector.size);
430 (void)memset_s(pVector.data, pVector.capcity, 0, pVector.capcity);
431 free(pVector.data);
432 pVector.data = nullptr;
433 pVector.capcity = 0;
434 pVector.size = 0;
435 return ERR_OK;
436 }
437
GetAndCleanPluginBussnessError(PluginBussnessError ** error,PluginMethodEnum methodEnum)438 static ErrCode GetAndCleanPluginBussnessError(PluginBussnessError **error, PluginMethodEnum methodEnum)
439 {
440 if (error == nullptr || (*error) == nullptr) {
441 ACCOUNT_LOGE("Error is nullptr.");
442 return ERR_JS_SYSTEM_SERVICE_EXCEPTION;
443 }
444 ErrCode err = (*error)->code;
445 std::string methodName = GetMethodNameByEnum(methodEnum);
446 std::string msg;
447 if ((*error)->msg.data == nullptr) {
448 ACCOUNT_LOGW("PluginString's data is null.");
449 } else {
450 msg = std::string((*error)->msg.data);
451 (void)memset_s((*error)->msg.data, (*error)->msg.length, 0, (*error)->msg.length);
452 free((*error)->msg.data);
453 (*error)->msg.data = nullptr;
454 }
455 free((*error));
456 (*error) = nullptr;
457 if (err == ERR_OK) {
458 ACCOUNT_LOGD("Call method=%{public}s is ok msg=%{public}s.", methodName.c_str(), msg.c_str());
459 return err;
460 }
461 ACCOUNT_LOGE("Call method=%{public}s is error, errorCode=%{public}d msg=%{public}s.",
462 methodName.c_str(), err, msg.c_str());
463 ReportOsAccountOperationFail(GetCallingUserID(), methodName, err, msg);
464 return err;
465 }
466
GetAndCleanPluginString(PluginString & pStr,std::string & str)467 static ErrCode GetAndCleanPluginString(PluginString &pStr, std::string &str)
468 {
469 if (pStr.data == nullptr) {
470 ACCOUNT_LOGE("PluginString's data is null.");
471 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
472 }
473 str = std::string(pStr.data);
474 (void)memset_s(pStr.data, pStr.length, 0, pStr.length);
475 free(pStr.data);
476 pStr.data = nullptr;
477 pStr.length = 0;
478 return ERR_OK;
479 }
480
GetAndCleanPluginServerConfigInfo(PluginServerConfigInfo ** pConfigInfo,std::string & id,std::string & domain,std::string & parameters)481 static void GetAndCleanPluginServerConfigInfo(PluginServerConfigInfo **pConfigInfo,
482 std::string &id, std::string &domain, std::string ¶meters)
483 {
484 if (pConfigInfo == nullptr || *pConfigInfo == nullptr) {
485 ACCOUNT_LOGE("PluginServerConfigInfo is null");
486 return;
487 }
488 GetAndCleanPluginString((*pConfigInfo)->id, id);
489 GetAndCleanPluginString((*pConfigInfo)->domain, domain);
490 GetAndCleanPluginString((*pConfigInfo)->parameters, parameters);
491 free((*pConfigInfo));
492 (*pConfigInfo) = nullptr;
493 }
494
SetPluginDomainAccountInfo(const DomainAccountInfo & info,PluginDomainAccountInfo & pluginInfo)495 static void SetPluginDomainAccountInfo(const DomainAccountInfo &info, PluginDomainAccountInfo &pluginInfo)
496 {
497 SetPluginString(info.domain_, pluginInfo.domain);
498 SetPluginString(info.accountName_, pluginInfo.accountName);
499 SetPluginString(info.accountId_, pluginInfo.accountId);
500 if (!info.serverConfigId_.empty()) {
501 SetPluginString(info.serverConfigId_, pluginInfo.serverConfigId);
502 return;
503 }
504 int32_t userId = GetCallingUserID();
505 OsAccountInfo accountInfo;
506 ErrCode errCode = IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(userId, accountInfo);
507 if (errCode != ERR_OK) {
508 ACCOUNT_LOGE("QueryOsAccountById fail code=%{public}d.", errCode);
509 pluginInfo.serverConfigId.data = nullptr;
510 return;
511 }
512 DomainAccountInfo savedInfo;
513 accountInfo.GetDomainInfo(savedInfo);
514 SetPluginString(savedInfo.serverConfigId_, pluginInfo.serverConfigId);
515 return;
516 }
517
CleanPluginDomainAccountInfo(PluginDomainAccountInfo & domainAccountInfo)518 static void CleanPluginDomainAccountInfo(PluginDomainAccountInfo &domainAccountInfo)
519 {
520 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
521 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
522 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
523 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
524 }
525
GetAndCleanPluginDomainAccountInfo(DomainAccountInfo & info,PluginDomainAccountInfo ** pDomainAccountInfo)526 static void GetAndCleanPluginDomainAccountInfo(DomainAccountInfo &info, PluginDomainAccountInfo **pDomainAccountInfo)
527 {
528 if (pDomainAccountInfo == nullptr || *pDomainAccountInfo == nullptr) {
529 ACCOUNT_LOGE("PluginDomainAccountInfo is null.");
530 return;
531 }
532 GetAndCleanPluginString((*pDomainAccountInfo)->serverConfigId, info.serverConfigId_);
533 GetAndCleanPluginString((*pDomainAccountInfo)->domain, info.domain_);
534 GetAndCleanPluginString((*pDomainAccountInfo)->accountName, info.accountName_);
535 GetAndCleanPluginString((*pDomainAccountInfo)->accountId, info.accountId_);
536 info.isAuthenticated = (*pDomainAccountInfo)->isAuthenticated == 1;
537 free((*pDomainAccountInfo));
538 (*pDomainAccountInfo) = nullptr;
539 }
540
GetAndCleanPluginAuthResultInfo(PluginAuthResultInfo ** authResultInfo,std::vector<uint8_t> & token,int32_t & remainTimes,int32_t & freezingTime)541 static void GetAndCleanPluginAuthResultInfo(PluginAuthResultInfo **authResultInfo,
542 std::vector<uint8_t> &token, int32_t &remainTimes, int32_t &freezingTime)
543 {
544 if (authResultInfo == nullptr || *authResultInfo == nullptr) {
545 ACCOUNT_LOGE("PluginAuthResultInfo is null");
546 return;
547 }
548 freezingTime = (*authResultInfo)->freezingTime;
549 remainTimes = (*authResultInfo)->remainTimes;
550 GetAndCleanPluginUint8Vector((*authResultInfo)->accountToken, token);
551 free((*authResultInfo));
552 (*authResultInfo) = nullptr;
553 }
554
GetAndCleanPluginAuthStatusInfo(PluginAuthStatusInfo ** statusInfo,int32_t & remainTimes,int32_t & freezingTime)555 static void GetAndCleanPluginAuthStatusInfo(PluginAuthStatusInfo **statusInfo,
556 int32_t &remainTimes, int32_t &freezingTime)
557 {
558 if (statusInfo == nullptr || *statusInfo == nullptr) {
559 ACCOUNT_LOGE("PluginAuthStatusInfo is null.");
560 return;
561 }
562 remainTimes = (*statusInfo)->remainTimes;
563 freezingTime = (*statusInfo)->freezingTime;
564 free((*statusInfo));
565 (*statusInfo) = nullptr;
566 }
567
GetAndCleanPluginDomainAccountPolicy(PluginDomainAccountPolicy ** accountPolicy,std::string & policy)568 static void GetAndCleanPluginDomainAccountPolicy(PluginDomainAccountPolicy **accountPolicy, std::string &policy)
569 {
570 if (accountPolicy == nullptr || *accountPolicy == nullptr) {
571 ACCOUNT_LOGE("PluginDomainAccountPolicy is null.");
572 return;
573 }
574 GetAndCleanPluginString((*accountPolicy)->parameters, policy);
575 free(*accountPolicy);
576 *accountPolicy = nullptr;
577 }
578
SetPluginGetDomainAccessTokenOptions(const GetAccessTokenOptions & option,const std::vector<uint8_t> & token,const DomainAccountInfo & info,PluginGetDomainAccessTokenOptions & pluginOptions)579 static void SetPluginGetDomainAccessTokenOptions(const GetAccessTokenOptions &option,
580 const std::vector<uint8_t> &token, const DomainAccountInfo &info, PluginGetDomainAccessTokenOptions &pluginOptions)
581 {
582 PluginDomainAccountInfo domainAccountInfo;
583 SetPluginDomainAccountInfo(info, domainAccountInfo);
584 PluginUint8Vector domainAccountToken;
585 SetPluginUint8Vector(token, domainAccountToken);
586 PluginString bussinessParams;
587 AAFwk::Want want;
588 want.SetParams(option.getTokenParams_);
589 std::string params = want.ToString();
590 SetPluginString(params, bussinessParams);
591 pluginOptions.domainAccountInfo = domainAccountInfo;
592 pluginOptions.domainAccountToken = domainAccountToken;
593 pluginOptions.bussinessParams = bussinessParams;
594 pluginOptions.callerUid = option.callingUid_;
595 }
596
AddServerConfig(const std::string & paremters,DomainServerConfig & config)597 ErrCode InnerDomainAccountManager::AddServerConfig(
598 const std::string &paremters, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
599 {
600 if (!IsSupportNetRequest()) {
601 ACCOUNT_LOGE("Not support background account request");
602 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
603 }
604 auto iter = methodMap_.find(PluginMethodEnum::ADD_SERVER_CONFIG);
605 if (iter == methodMap_.end() || iter->second == nullptr) {
606 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::ADD_SERVER_CONFIG);
607 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
608 }
609 int32_t localId = GetCallingUserID();
610 if (localId == INVALID_USERID) {
611 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
612 }
613 PluginString param;
614 SetPluginString(paremters, param);
615 PluginServerConfigInfo *configInfo = nullptr;
616 PluginBussnessError* error = (*reinterpret_cast<AddServerConfigFunc>(iter->second))(¶m, localId, &configInfo);
617 GetAndCleanPluginServerConfigInfo(&configInfo, config.id_, config.domain_, config.parameters_);
618 CleanPluginString(&(param.data), param.length);
619 return GetAndCleanPluginBussnessError(&error, iter->first);
620 }
621
RemoveServerConfig(const std::string & configId)622 ErrCode InnerDomainAccountManager::RemoveServerConfig(const std::string &configId) __attribute__((no_sanitize("cfi")))
623 {
624 if (!IsSupportNetRequest()) {
625 ACCOUNT_LOGE("Not support background account request");
626 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
627 }
628 auto iter = methodMap_.find(PluginMethodEnum::REMOVE_SERVER_CONFIG);
629 if (iter == methodMap_.end() || iter->second == nullptr) {
630 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::REMOVE_SERVER_CONFIG);
631 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
632 }
633 int32_t localId = GetCallingUserID();
634 if (localId == -1) {
635 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
636 }
637 PluginString serverConfigId;
638 SetPluginString(configId, serverConfigId);
639 PluginBussnessError* error = (*reinterpret_cast<RemoveServerConfigFunc>(iter->second))(&serverConfigId, localId);
640 CleanPluginString(&(serverConfigId.data), serverConfigId.length);
641 ErrCode errCode = GetAndCleanPluginBussnessError(&error, iter->first);
642 if (errCode == ERR_JS_INVALID_PARAMETER) {
643 return ERR_JS_SERVER_CONFIG_NOT_FOUND;
644 }
645 return errCode;
646 }
647
UpdateServerConfig(const std::string & configId,const std::string & paremters,DomainServerConfig & config)648 ErrCode InnerDomainAccountManager::UpdateServerConfig(const std::string &configId,
649 const std::string &paremters, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
650 {
651 if (!IsSupportNetRequest()) {
652 ACCOUNT_LOGE("Not support background account request");
653 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
654 }
655 auto iter = methodMap_.find(PluginMethodEnum::UPDATE_SERVER_CONFIG);
656 if (iter == methodMap_.end() || iter->second == nullptr) {
657 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::UPDATE_SERVER_CONFIG);
658 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
659 }
660 int32_t localId = GetCallingUserID();
661 if (localId == INVALID_USERID) {
662 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
663 }
664 PluginString serverConfigId;
665 PluginString param;
666 SetPluginString(configId, serverConfigId);
667 SetPluginString(paremters, param);
668 PluginServerConfigInfo *configInfo = nullptr;
669 PluginBussnessError* error = (*reinterpret_cast<UpdateServerConfigFunc>(iter->second))(&serverConfigId, ¶m,
670 localId, &configInfo);
671 GetAndCleanPluginServerConfigInfo(&configInfo, config.id_, config.domain_, config.parameters_);
672 CleanPluginString(&(param.data), param.length);
673 CleanPluginString(&(serverConfigId.data), serverConfigId.length);
674 ErrCode errCode = GetAndCleanPluginBussnessError(&error, iter->first);
675 if (errCode != ERR_OK) {
676 return errCode;
677 }
678 (void)IInnerOsAccountManager::GetInstance().UpdateServerConfig(configId, config);
679 return errCode;
680 }
681
GetServerConfig(const std::string & configId,DomainServerConfig & config)682 ErrCode InnerDomainAccountManager::GetServerConfig(const std::string &configId,
683 DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
684 {
685 if (!IsSupportNetRequest()) {
686 ACCOUNT_LOGE("Not support background account request");
687 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
688 }
689 auto iter = methodMap_.find(PluginMethodEnum::GET_SERVER_CONFIG);
690 if (iter == methodMap_.end() || iter->second == nullptr) {
691 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_SERVER_CONFIG);
692 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
693 }
694 int32_t localId = GetCallingUserID();
695 if (localId == INVALID_USERID) {
696 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
697 }
698 PluginString serverConfigId;
699 SetPluginString(configId, serverConfigId);
700 PluginServerConfigInfo *configInfo = nullptr;
701 PluginBussnessError* error = (*reinterpret_cast<GetServerConfigFunc>(iter->second))(
702 &serverConfigId, localId, &configInfo);
703 GetAndCleanPluginServerConfigInfo(&configInfo, config.id_, config.domain_, config.parameters_);
704 CleanPluginString(&(serverConfigId.data), serverConfigId.length);
705 return GetAndCleanPluginBussnessError(&error, iter->first);
706 }
707
GetAllServerConfigs(std::vector<DomainServerConfig> & configs)708 ErrCode InnerDomainAccountManager::GetAllServerConfigs(
709 std::vector<DomainServerConfig> &configs) __attribute__((no_sanitize("cfi")))
710 {
711 if (!IsSupportNetRequest()) {
712 ACCOUNT_LOGE("Not support background account request");
713 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
714 }
715 auto iter = methodMap_.find(PluginMethodEnum::GET_ALL_SERVER_CONFIGS);
716 if (iter == methodMap_.end() || iter->second == nullptr) {
717 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ALL_SERVER_CONFIGS);
718 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
719 }
720 int32_t localId = GetCallingUserID();
721 if (localId == INVALID_USERID) {
722 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
723 }
724 PluginServerConfigInfoList *configInfoList = nullptr;
725 PluginBussnessError* error = (*reinterpret_cast<GetServerConfigListFunc>(iter->second))(&configInfoList);
726 if (configInfoList == nullptr) {
727 ACCOUNT_LOGE("configInfoList is nullptr");
728 return GetAndCleanPluginBussnessError(&error, iter->first);
729 }
730 if (configInfoList->size == 0) {
731 delete configInfoList;
732 return GetAndCleanPluginBussnessError(&error, iter->first);
733 }
734 for (size_t i = 0; i < configInfoList->size; ++i) {
735 DomainServerConfig config;
736 if (GetAndCleanPluginString(configInfoList->items[i].id, config.id_) != ERR_OK) {
737 ACCOUNT_LOGE("Failed to get server config id at index %{public}zu", i);
738 continue;
739 }
740 if (GetAndCleanPluginString(configInfoList->items[i].domain, config.domain_) != ERR_OK) {
741 ACCOUNT_LOGE("Failed to get server config domain at index %{public}zu", i);
742 continue;
743 }
744 if (GetAndCleanPluginString(configInfoList->items[i].parameters, config.parameters_) != ERR_OK) {
745 ACCOUNT_LOGE("Failed to get server config parameters at index %{public}zu", i);
746 continue;
747 }
748 configs.push_back(config);
749 }
750 delete[] configInfoList->items;
751 delete configInfoList;
752 return GetAndCleanPluginBussnessError(&error, iter->first);
753 }
754
GetAccountServerConfig(const std::string & accountName,const std::string & configId,DomainServerConfig & config)755 ErrCode InnerDomainAccountManager::GetAccountServerConfig(const std::string &accountName,
756 const std::string &configId, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
757 {
758 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG);
759 if (iter == methodMap_.end() || iter->second == nullptr) {
760 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG);
761 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
762 }
763 DomainAccountInfo info;
764 info.accountName_ = accountName;
765 info.serverConfigId_ = configId;
766 PluginDomainAccountInfo domainAccountInfo;
767 SetPluginDomainAccountInfo(info, domainAccountInfo);
768 PluginServerConfigInfo *serverConfigInfo = nullptr;
769 PluginBussnessError* error = (*reinterpret_cast<GetAccountServerConfigFunc>(iter->second))(&domainAccountInfo,
770 &serverConfigInfo);
771 GetAndCleanPluginServerConfigInfo(&serverConfigInfo, config.id_, config.domain_, config.parameters_);
772 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
773 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
774 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
775 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
776 ErrCode errCode = GetAndCleanPluginBussnessError(&error, iter->first);
777 if (errCode == ERR_JS_INVALID_PARAMETER) {
778 return ERR_JS_ACCOUNT_NOT_FOUND;
779 }
780 return errCode;
781 }
782
GetAccountServerConfig(const DomainAccountInfo & info,DomainServerConfig & config)783 ErrCode InnerDomainAccountManager::GetAccountServerConfig(
784 const DomainAccountInfo &info, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
785 {
786 if (!IsSupportNetRequest()) {
787 ACCOUNT_LOGE("Not support background account request");
788 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
789 }
790 {
791 std::lock_guard<std::mutex> lock(libMutex_);
792 if (libHandle_ == nullptr) {
793 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG);
794 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
795 }
796 }
797 int32_t localId = 0;
798 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, localId);
799 if (result != ERR_OK) {
800 ACCOUNT_LOGE("Get os account localId from domain failed, result: %{public}d", result);
801 if (result != ERR_ACCOUNT_COMMON_INVALID_PARAMETER) {
802 return result;
803 }
804 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
805 }
806 return GetAccountServerConfig(info.accountName_, info.serverConfigId_, config);
807 }
808
PluginAuth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,DomainAuthResult & resultParcel)809 ErrCode InnerDomainAccountManager::PluginAuth(const DomainAccountInfo &info,
810 const std::vector<uint8_t> &password, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
811 {
812 auto iter = methodMap_.find(PluginMethodEnum::AUTH);
813 if (iter == methodMap_.end() || iter->second == nullptr) {
814 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH);
815 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
816 }
817 int32_t localId = GetCallingUserID();
818 if (localId == -1) {
819 ACCOUNT_LOGE("fail to get activated os account ids");
820 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
821 }
822 PluginDomainAccountInfo domainAccountInfo;
823 SetPluginDomainAccountInfo(info, domainAccountInfo);
824 PluginUint8Vector credential;
825 SetPluginUint8Vector(password, credential);
826 PluginAuthResultInfo *authResultInfo = nullptr;
827 ACCOUNT_LOGD("Param localId=%{public}d.", localId);
828 PluginBussnessError* error = (*reinterpret_cast<AuthFunc>(iter->second))(&domainAccountInfo, &credential, localId,
829 &authResultInfo);
830 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
831 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
832 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
833 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
834 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
835 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
836 return GetAndCleanPluginBussnessError(&error, iter->first);
837 }
838
Auth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,const sptr<IDomainAccountCallback> & callback)839 ErrCode InnerDomainAccountManager::Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
840 const sptr<IDomainAccountCallback> &callback)
841 {
842 if (!IsSupportNetRequest()) {
843 ACCOUNT_LOGE("Not support background account request");
844 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
845 }
846 int32_t userId = -1;
847 sptr<IDomainAccountCallback> innerCallback = callback;
848 IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
849 if (userId >= 0) {
850 innerCallback = new (std::nothrow) InnerDomainAuthCallback(userId, callback);
851 if (innerCallback == nullptr) {
852 ACCOUNT_LOGE("failed to create innerCallback");
853 innerCallback = callback;
854 }
855 }
856 if (plugin_ == nullptr) {
857 Parcel emptyParcel;
858 AccountSA::DomainAuthResult result;
859 ErrCode err = PluginAuth(info, password, result);
860 if (!result.Marshalling(emptyParcel)) {
861 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
862 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
863 }
864 if (innerCallback != nullptr) {
865 DomainAccountParcel domainAccountParcel;
866 domainAccountParcel.SetParcelData(emptyParcel);
867 innerCallback->OnResult(err, domainAccountParcel);
868 }
869 return ERR_OK;
870 }
871 auto task = [this, info, password, innerCallback] {
872 this->StartAuth(this->plugin_, info, password, innerCallback, AUTH_WITH_CREDENTIAL_MODE);
873 };
874 std::thread taskThread(task);
875 pthread_setname_np(taskThread.native_handle(), THREAD_AUTH);
876 taskThread.detach();
877 return ERR_OK;
878 }
879
PluginBindAccount(const DomainAccountInfo & info,const int32_t localId,DomainAuthResult & resultParcel)880 ErrCode InnerDomainAccountManager::PluginBindAccount(const DomainAccountInfo &info, const int32_t localId,
881 DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
882 {
883 auto iter = methodMap_.find(PluginMethodEnum::BIND_ACCOUNT);
884 if (iter == methodMap_.end() || iter->second == nullptr) {
885 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::BIND_ACCOUNT);
886 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
887 }
888 ACCOUNT_LOGD("Param localId=%{public}d.", localId);
889 int32_t callerLocalId = GetCallingUserID();
890 if (localId == -1) {
891 ACCOUNT_LOGE("fail to get activated os account ids");
892 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
893 }
894 PluginDomainAccountInfo domainAccountInfo;
895 SetPluginDomainAccountInfo(info, domainAccountInfo);
896 PluginBussnessError* error =
897 (*reinterpret_cast<BindAccountFunc>(iter->second))(&domainAccountInfo, localId, callerLocalId);
898 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
899 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
900 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
901 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
902 return GetAndCleanPluginBussnessError(&error, iter->first);
903 }
904
PluginUnBindAccount(const DomainAccountInfo & info,DomainAuthResult & resultParcel,const int32_t localId)905 ErrCode InnerDomainAccountManager::PluginUnBindAccount(
906 const DomainAccountInfo &info, DomainAuthResult &resultParcel,
907 const int32_t localId) __attribute__((no_sanitize("cfi")))
908 {
909 auto iter = methodMap_.find(PluginMethodEnum::UNBIND_ACCOUNT);
910 if (iter == methodMap_.end() || iter->second == nullptr) {
911 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::UNBIND_ACCOUNT);
912 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
913 }
914 PluginDomainAccountInfo domainAccountInfo;
915 SetPluginDomainAccountInfo(info, domainAccountInfo);
916 PluginBussnessError* error = (*reinterpret_cast<UnbindAccountFunc>(iter->second))(&domainAccountInfo, localId);
917 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
918 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
919 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
920 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
921 return GetAndCleanPluginBussnessError(&error, iter->first);
922 }
923
PluginIsAccountTokenValid(const DomainAccountInfo & info,const std::vector<uint8_t> & token,int32_t & isValid)924 ErrCode InnerDomainAccountManager::PluginIsAccountTokenValid(const DomainAccountInfo &info,
925 const std::vector<uint8_t> &token, int32_t &isValid) __attribute__((no_sanitize("cfi")))
926 {
927 auto iter = methodMap_.find(PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID);
928 if (iter == methodMap_.end() || iter->second == nullptr) {
929 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID);
930 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
931 }
932 PluginDomainAccountInfo domainAccountInfo;
933 SetPluginDomainAccountInfo(info, domainAccountInfo);
934 PluginUint8Vector pToken;
935 SetPluginUint8Vector(token, pToken);
936 PluginBussnessError* error =
937 (*reinterpret_cast<IsAccountTokenValidFunc>(iter->second))(&domainAccountInfo, &pToken, &isValid);
938 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
939 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
940 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
941 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
942 ACCOUNT_LOGD("return isValid=%{public}d.", isValid);
943 return GetAndCleanPluginBussnessError(&error, iter->first);
944 }
945
PluginGetAccessToken(const GetAccessTokenOptions & option,const std::vector<uint8_t> & token,const DomainAccountInfo & info,DomainAuthResult & resultParcel)946 ErrCode InnerDomainAccountManager::PluginGetAccessToken(const GetAccessTokenOptions &option,
947 const std::vector<uint8_t> &token, const DomainAccountInfo &info,
948 DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
949 {
950 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCESS_TOKEN);
951 if (iter == methodMap_.end() || iter->second == nullptr) {
952 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCESS_TOKEN);
953 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
954 }
955 PluginGetDomainAccessTokenOptions pOption;
956 SetPluginGetDomainAccessTokenOptions(option, token, info, pOption);
957 PluginUint8Vector *accessToken = nullptr;
958 ACCOUNT_LOGD("Param params=%{public}s callerUid=%{public}d.", pOption.bussinessParams.data, pOption.callerUid);
959 PluginBussnessError* error = (*reinterpret_cast<GetAccessTokenFunc>(iter->second))(&pOption, &accessToken);
960 if (accessToken != nullptr) {
961 GetAndCleanPluginUint8Vector(*accessToken, resultParcel.token);
962 free(accessToken);
963 }
964 accessToken = nullptr;
965 CleanPluginString(&(pOption.domainAccountInfo.domain.data), pOption.domainAccountInfo.domain.length);
966 CleanPluginString(&(pOption.domainAccountInfo.serverConfigId.data),
967 pOption.domainAccountInfo.serverConfigId.length);
968 CleanPluginString(&(pOption.domainAccountInfo.accountName.data),
969 pOption.domainAccountInfo.accountName.length);
970 CleanPluginString(&(pOption.domainAccountInfo.accountId.data),
971 pOption.domainAccountInfo.accountId.length);
972 CleanPluginString(&(pOption.bussinessParams.data), pOption.bussinessParams.length);
973 return GetAndCleanPluginBussnessError(&error, iter->first);
974 }
975
PluginAuthWithPopup(const DomainAccountInfo & info,DomainAuthResult & resultParcel)976 ErrCode InnerDomainAccountManager::PluginAuthWithPopup(
977 const DomainAccountInfo &info, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
978 {
979 auto iter = methodMap_.find(PluginMethodEnum::AUTH_WITH_POPUP);
980 if (iter == methodMap_.end() || iter->second == nullptr) {
981 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH_WITH_POPUP);
982 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
983 }
984 PluginDomainAccountInfo domainAccountInfo;
985 SetPluginDomainAccountInfo(info, domainAccountInfo);
986 PluginAuthResultInfo *authResultInfo = nullptr;
987 PluginBussnessError* error = (*reinterpret_cast<AuthWithPopupFunc>(iter->second))(&domainAccountInfo,
988 &authResultInfo);
989 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
990 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
991 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
992 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
993 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
994 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
995 return GetAndCleanPluginBussnessError(&error, iter->first);
996 }
997
PluginAuthToken(const DomainAccountInfo & info,const std::vector<uint8_t> & authData,DomainAuthResult & resultParcel)998 ErrCode InnerDomainAccountManager::PluginAuthToken(const DomainAccountInfo &info,
999 const std::vector<uint8_t> &authData, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
1000 {
1001 auto iter = methodMap_.find(PluginMethodEnum::AUTH_WITH_TOKEN);
1002 if (iter == methodMap_.end() || iter->second == nullptr) {
1003 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH_WITH_TOKEN);
1004 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
1005 }
1006 PluginDomainAccountInfo domainAccountInfo;
1007 SetPluginDomainAccountInfo(info, domainAccountInfo);
1008 PluginUint8Vector token;
1009 SetPluginUint8Vector(authData, token);
1010 PluginAuthResultInfo *authResultInfo = nullptr;
1011 PluginBussnessError* error = (*reinterpret_cast<AuthWithTokenFunc>(iter->second))(&domainAccountInfo, &token,
1012 &authResultInfo);
1013 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
1014 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
1015 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
1016 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
1017 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
1018 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
1019 return GetAndCleanPluginBussnessError(&error, iter->first);
1020 }
1021
PluginGetAuthStatusInfo(const DomainAccountInfo & info,AuthStatusInfo & authInfo)1022 ErrCode InnerDomainAccountManager::PluginGetAuthStatusInfo(const DomainAccountInfo &info,
1023 AuthStatusInfo &authInfo) __attribute__((no_sanitize("cfi")))
1024 {
1025 auto iter = methodMap_.find(PluginMethodEnum::GET_AUTH_STATUS_INFO);
1026 if (iter == methodMap_.end() || iter->second == nullptr) {
1027 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_AUTH_STATUS_INFO);
1028 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
1029 }
1030 PluginDomainAccountInfo domainAccountInfo;
1031 SetPluginDomainAccountInfo(info, domainAccountInfo);
1032 PluginAuthStatusInfo *authStatusInfo = nullptr;
1033 PluginBussnessError* error =
1034 (*reinterpret_cast<GetAuthStatusInfoFunc>(iter->second))(&domainAccountInfo, &authStatusInfo);
1035 GetAndCleanPluginAuthStatusInfo(&authStatusInfo, authInfo.remainingTimes, authInfo.freezingTime);
1036 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
1037 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
1038 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
1039 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
1040 return GetAndCleanPluginBussnessError(&error, iter->first);
1041 }
1042
PluginUpdateAccountInfo(const DomainAccountInfo & oldAccountInfo,const DomainAccountInfo & newAccountInfo)1043 ErrCode InnerDomainAccountManager::PluginUpdateAccountInfo(const DomainAccountInfo &oldAccountInfo,
1044 const DomainAccountInfo &newAccountInfo) __attribute__((no_sanitize("cfi")))
1045 {
1046 auto iter = methodMap_.find(PluginMethodEnum::UPDATE_ACCOUNT_INFO);
1047 if (iter == methodMap_.end() || iter->second == nullptr) {
1048 ACCOUNT_LOGE("Caller method = %{public}d not exsit.", PluginMethodEnum::UPDATE_ACCOUNT_INFO);
1049 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
1050 }
1051 int32_t callerLocalId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
1052 PluginDomainAccountInfo oldDomainAccountInfo;
1053 SetPluginDomainAccountInfo(oldAccountInfo, oldDomainAccountInfo);
1054 PluginDomainAccountInfo newDomainAccountInfo;
1055 SetPluginDomainAccountInfo(newAccountInfo, newDomainAccountInfo);
1056 PluginBussnessError* error = (*reinterpret_cast<UpdateAccountInfoFunc>(iter->second))(&oldDomainAccountInfo,
1057 &newDomainAccountInfo, callerLocalId);
1058 CleanPluginString(&(oldDomainAccountInfo.domain.data), oldDomainAccountInfo.domain.length);
1059 CleanPluginString(&(oldDomainAccountInfo.serverConfigId.data), oldDomainAccountInfo.serverConfigId.length);
1060 CleanPluginString(&(oldDomainAccountInfo.accountName.data), oldDomainAccountInfo.accountName.length);
1061 CleanPluginString(&(oldDomainAccountInfo.accountId.data), oldDomainAccountInfo.accountId.length);
1062 CleanPluginString(&(newDomainAccountInfo.domain.data), newDomainAccountInfo.domain.length);
1063 CleanPluginString(&(newDomainAccountInfo.serverConfigId.data), newDomainAccountInfo.serverConfigId.length);
1064 CleanPluginString(&(newDomainAccountInfo.accountName.data), newDomainAccountInfo.accountName.length);
1065 CleanPluginString(&(newDomainAccountInfo.accountId.data), newDomainAccountInfo.accountId.length);
1066 return GetAndCleanPluginBussnessError(&error, iter->first);
1067 }
1068
InnerAuth(int32_t userId,const std::vector<uint8_t> & authData,const sptr<IDomainAccountCallback> & callback,AuthMode authMode)1069 ErrCode InnerDomainAccountManager::InnerAuth(int32_t userId, const std::vector<uint8_t> &authData,
1070 const sptr<IDomainAccountCallback> &callback, AuthMode authMode)
1071 {
1072 DomainAccountInfo domainInfo;
1073 ErrCode errCode = GetDomainAccountInfoByUserId(userId, domainInfo);
1074 if (errCode != ERR_OK) {
1075 return errCode;
1076 }
1077 sptr<InnerDomainAuthCallback> innerCallback = new (std::nothrow) InnerDomainAuthCallback(userId, callback);
1078 if (innerCallback == nullptr) {
1079 ACCOUNT_LOGE("failed to create innerCallback");
1080 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1081 }
1082 if (plugin_ == nullptr) {
1083 Parcel emptyParcel;
1084 AccountSA::DomainAuthResult result;
1085 switch (authMode) {
1086 case AUTH_WITH_CREDENTIAL_MODE:
1087 errCode = PluginAuth(domainInfo, authData, result);
1088 break;
1089 case AUTH_WITH_POPUP_MODE:
1090 errCode = PluginAuthWithPopup(domainInfo, result);
1091 break;
1092 case AUTH_WITH_TOKEN_MODE:
1093 errCode = PluginAuthToken(domainInfo, authData, result);
1094 break;
1095 default:
1096 ACCOUNT_LOGE("AuthMode not match.");
1097 break;
1098 }
1099 if (!result.Marshalling(emptyParcel)) {
1100 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1101 errCode = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1102 }
1103 DomainAccountParcel domainAccountParcel;
1104 domainAccountParcel.SetParcelData(emptyParcel);
1105 innerCallback->OnResult(errCode, domainAccountParcel);
1106 return ERR_OK;
1107 }
1108 auto task = [this, domainInfo, authData, innerCallback, authMode] {
1109 this->StartAuth(this->plugin_, domainInfo, authData, innerCallback, authMode);
1110 };
1111 std::thread taskThread(task);
1112 pthread_setname_np(taskThread.native_handle(), THREAD_INNER_AUTH);
1113 taskThread.detach();
1114 return ERR_OK;
1115 }
1116
AuthUser(int32_t userId,const std::vector<uint8_t> & password,const sptr<IDomainAccountCallback> & callback)1117 ErrCode InnerDomainAccountManager::AuthUser(int32_t userId, const std::vector<uint8_t> &password,
1118 const sptr<IDomainAccountCallback> &callback)
1119 {
1120 if (!IsSupportNetRequest()) {
1121 ACCOUNT_LOGE("Not support background account request");
1122 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1123 }
1124 bool isVerified = false;
1125 (void) IInnerOsAccountManager::GetInstance().IsOsAccountVerified(userId, isVerified);
1126 if (isVerified) {
1127 return InnerAuth(userId, password, callback, AUTH_WITH_CREDENTIAL_MODE);
1128 }
1129
1130 uint64_t credentialId = 0;
1131 (void) IInnerOsAccountManager::GetInstance().GetOsAccountCredentialId(userId, credentialId);
1132 if (credentialId > 0) {
1133 ACCOUNT_LOGE("unsupported auth type");
1134 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
1135 }
1136 return InnerAuth(userId, password, callback, AUTH_WITH_CREDENTIAL_MODE);
1137 }
1138
AuthWithPopup(int32_t userId,const sptr<IDomainAccountCallback> & callback)1139 ErrCode InnerDomainAccountManager::AuthWithPopup(int32_t userId, const sptr<IDomainAccountCallback> &callback)
1140 {
1141 if (!IsSupportNetRequest()) {
1142 ACCOUNT_LOGE("Not support background account request");
1143 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1144 }
1145 if (userId == 0) {
1146 std::vector<int32_t> userIds;
1147 (void)IInnerOsAccountManager::GetInstance().QueryActiveOsAccountIds(userIds);
1148 if (userIds.empty()) {
1149 ACCOUNT_LOGE("fail to get activated os account ids");
1150 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
1151 }
1152 userId = userIds[0];
1153 }
1154 return InnerAuth(userId, {}, callback, AUTH_WITH_POPUP_MODE);
1155 }
1156
AuthWithToken(int32_t userId,const std::vector<uint8_t> & token)1157 ErrCode InnerDomainAccountManager::AuthWithToken(int32_t userId, const std::vector<uint8_t> &token)
1158 {
1159 if (!IsSupportNetRequest()) {
1160 ACCOUNT_LOGE("Not support background account request");
1161 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1162 }
1163 return InnerAuth(userId, token, nullptr, AUTH_WITH_TOKEN_MODE);
1164 }
1165
InsertTokenToMap(int32_t userId,const std::vector<uint8_t> & token)1166 void InnerDomainAccountManager::InsertTokenToMap(int32_t userId, const std::vector<uint8_t> &token)
1167 {
1168 std::lock_guard<std::mutex> lock(mutex_);
1169 userTokenMap_[userId] = token;
1170 }
1171
GetTokenFromMap(int32_t userId,std::vector<uint8_t> & token)1172 bool InnerDomainAccountManager::GetTokenFromMap(int32_t userId, std::vector<uint8_t> &token)
1173 {
1174 std::lock_guard<std::mutex> lock(mutex_);
1175 auto it = userTokenMap_.find(userId);
1176 if (it == userTokenMap_.end()) {
1177 token.clear();
1178 return false;
1179 }
1180 token = it->second;
1181 return true;
1182 }
1183
RemoveTokenFromMap(int32_t userId)1184 void InnerDomainAccountManager::RemoveTokenFromMap(int32_t userId)
1185 {
1186 std::lock_guard<std::mutex> lock(mutex_);
1187 userTokenMap_.erase(userId);
1188 return;
1189 }
1190
NotifyDomainAccountEvent(int32_t userId,DomainAccountEvent event,DomainAccountStatus status,const DomainAccountInfo & info)1191 void InnerDomainAccountManager::NotifyDomainAccountEvent(
1192 int32_t userId, DomainAccountEvent event, DomainAccountStatus status, const DomainAccountInfo &info)
1193 {
1194 if (status == DomainAccountStatus::LOG_END) {
1195 bool isActivated = false;
1196 (void)IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId, isActivated);
1197 status = isActivated ? DomainAccountStatus::LOGIN : DomainAccountStatus::LOGIN_BACKGROUND;
1198 }
1199
1200 // There is not need to check userid.
1201 DomainAccountEventData report;
1202 report.domainAccountInfo = info;
1203 report.event = event;
1204 report.status = status;
1205 report.userId = userId;
1206 StatusListenerManager::GetInstance().NotifyEventAsync(report);
1207 }
1208
UpdateAccountToken(const DomainAccountInfo & info,const std::vector<uint8_t> & token)1209 ErrCode InnerDomainAccountManager::UpdateAccountToken(const DomainAccountInfo &info, const std::vector<uint8_t> &token)
1210 {
1211 int32_t callingUid = IPCSkeleton::GetCallingUid();
1212 if ((callingUid_ != -1) && (callingUid != callingUid_)) {
1213 ACCOUNT_LOGE("callingUid and register callinguid is not same!");
1214 return ERR_DOMAIN_ACCOUNT_SERVICE_INVALID_CALLING_UID;
1215 }
1216 int32_t userId = 0;
1217 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1218 if (result != ERR_OK) {
1219 ACCOUNT_LOGE("Get localId failed, result: %{public}d", result);
1220 if (result != ERR_ACCOUNT_COMMON_INVALID_PARAMETER) {
1221 return result;
1222 }
1223 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
1224 }
1225
1226 if (token.empty()) {
1227 RemoveTokenFromMap(userId);
1228 result =
1229 IInnerOsAccountManager::GetInstance().UpdateAccountStatusForDomain(userId, DomainAccountStatus::LOGOUT);
1230 if (result != ERR_OK) {
1231 ACCOUNT_LOGE("Update domain account status failed, result: %{public}d", result);
1232 return result;
1233 }
1234 NotifyDomainAccountEvent(userId, DomainAccountEvent::TOKEN_INVALID, DomainAccountStatus::LOGOUT, info);
1235 return ERR_OK;
1236 }
1237 InsertTokenToMap(userId, token);
1238 NotifyDomainAccountEvent(userId, DomainAccountEvent::TOKEN_UPDATED, DomainAccountStatus::LOG_END, info);
1239 return ERR_OK;
1240 }
1241
OnResultForGetAccessToken(const ErrCode errCode,const sptr<IDomainAccountCallback> & callback)1242 static void OnResultForGetAccessToken(const ErrCode errCode, const sptr<IDomainAccountCallback> &callback)
1243 {
1244 std::vector<uint8_t> token;
1245 Parcel emptyParcel;
1246 emptyParcel.WriteUInt8Vector(token);
1247 DomainAccountParcel domainAccountParcel;
1248 domainAccountParcel.SetParcelData(emptyParcel);
1249 callback->OnResult(errCode, domainAccountParcel);
1250 }
1251
StartGetAccessToken(const sptr<IDomainAccountPlugin> & plugin,const std::vector<uint8_t> & accountToken,const DomainAccountInfo & info,const GetAccessTokenOptions & option,const sptr<IDomainAccountCallback> & callback)1252 ErrCode InnerDomainAccountManager::StartGetAccessToken(const sptr<IDomainAccountPlugin> &plugin,
1253 const std::vector<uint8_t> &accountToken, const DomainAccountInfo &info, const GetAccessTokenOptions &option,
1254 const sptr<IDomainAccountCallback> &callback)
1255 {
1256 if (callback == nullptr) {
1257 ACCOUNT_LOGE("invalid callback");
1258 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1259 }
1260 if (plugin == nullptr) {
1261 ACCOUNT_LOGE("plugin is nullptr");
1262 OnResultForGetAccessToken(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1263 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1264 }
1265 DomainAccountCallbackFunc callbackFunc = [callback](const int32_t errCode, Parcel &parcel) {
1266 if (callback != nullptr) {
1267 DomainAccountParcel domainAccountParcel;
1268 domainAccountParcel.SetParcelData(parcel);
1269 callback->OnResult(errCode, domainAccountParcel);
1270 }
1271 };
1272 sptr<DomainAccountCallbackService> callbackService =
1273 new (std::nothrow) DomainAccountCallbackService(callbackFunc);
1274 if (callbackService == nullptr) {
1275 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1276 OnResultForGetAccessToken(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1277 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1278 }
1279 ErrCode result = plugin->GetAccessToken(info, accountToken, option, callbackService);
1280 result = ConvertToAccountErrCode(result);
1281 if (result != ERR_OK) {
1282 ACCOUNT_LOGE("failed to get access token, errCode: %{public}d", result);
1283 OnResultForGetAccessToken(result, callback);
1284 return result;
1285 }
1286 return ERR_OK;
1287 }
1288
QueryAccountInfo(const DomainAccountInfo & info,const int32_t & callingUid,DomainAccountInfo & targetInfo,int32_t & userId)1289 static ErrCode QueryAccountInfo(const DomainAccountInfo &info, const int32_t &callingUid,
1290 DomainAccountInfo &targetInfo, int32_t &userId)
1291 {
1292 ErrCode result = ERR_OK;
1293 if (!info.accountName_.empty()) {
1294 result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1295 if (result != ERR_OK) {
1296 ACCOUNT_LOGE("domain account not found");
1297 return result;
1298 }
1299 } else {
1300 userId = callingUid / UID_TRANSFORM_DIVISOR;
1301 OsAccountInfo osAccountInfo;
1302 (void) IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(userId, osAccountInfo);
1303 osAccountInfo.GetDomainInfo(targetInfo);
1304 if (targetInfo.accountName_.empty()) {
1305 ACCOUNT_LOGE("domain account not found");
1306 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
1307 }
1308 }
1309 return result;
1310 }
1311
GetAccessToken(const DomainAccountInfo & info,const AAFwk::WantParams & parameters,const sptr<IDomainAccountCallback> & callback)1312 ErrCode InnerDomainAccountManager::GetAccessToken(
1313 const DomainAccountInfo &info, const AAFwk::WantParams ¶meters, const sptr<IDomainAccountCallback> &callback)
1314 {
1315 if (callback == nullptr) {
1316 ACCOUNT_LOGE("invalid callback");
1317 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1318 }
1319 if (!IsSupportNetRequest()) {
1320 ACCOUNT_LOGE("Not support background account request");
1321 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1322 }
1323 int32_t callingUid = IPCSkeleton::GetCallingUid();
1324 int32_t userId = 0;
1325 DomainAccountInfo targetInfo = info;
1326 ErrCode result = QueryAccountInfo(info, callingUid, targetInfo, userId);
1327 if (result != ERR_OK) {
1328 return result;
1329 }
1330 std::vector<uint8_t> accountToken;
1331 if (!GetTokenFromMap(userId, accountToken)) {
1332 ACCOUNT_LOGI("The target domain account has not authenticated");
1333 }
1334 GetAccessTokenOptions option(callingUid, parameters);
1335 if (plugin_ == nullptr) {
1336 Parcel emptyParcel;
1337 AccountSA::DomainAuthResult authResult;
1338 ErrCode err = PluginGetAccessToken(option, accountToken, targetInfo, authResult);
1339 if (!authResult.Marshalling(emptyParcel)) {
1340 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1341 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1342 }
1343 DomainAccountParcel domainAccountParcel;
1344 domainAccountParcel.SetParcelData(emptyParcel);
1345 callback->OnResult(err, domainAccountParcel);
1346 return ERR_OK;
1347 }
1348 auto task = [this, accountToken, targetInfo, option, callback] {
1349 this->StartGetAccessToken(this->plugin_, accountToken, targetInfo, option, callback);
1350 };
1351 std::thread taskThread(task);
1352 pthread_setname_np(taskThread.native_handle(), THREAD_GET_ACCESS_TOKEN);
1353 taskThread.detach();
1354 return ERR_OK;
1355 }
1356
IsAuthenticationExpired(const DomainAccountInfo & info,bool & isExpired)1357 ErrCode InnerDomainAccountManager::IsAuthenticationExpired(
1358 const DomainAccountInfo &info, bool &isExpired) __attribute__((no_sanitize("cfi")))
1359 {
1360 if (!IsSupportNetRequest()) {
1361 ACCOUNT_LOGE("Not support background account request");
1362 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1363 }
1364 auto iter = methodMap_.find(PluginMethodEnum::IS_AUTHENTICATION_EXPIRED);
1365 if (iter == methodMap_.end() || iter->second == nullptr) {
1366 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::IS_AUTHENTICATION_EXPIRED);
1367 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1368 }
1369 int32_t userId = 0;
1370 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1371 if (result != ERR_OK) {
1372 ACCOUNT_LOGI("The target domain account not found, isExpired=true.");
1373 isExpired = true;
1374 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
1375 }
1376 OsAccountInfo osAccountInfo;
1377 result = IInnerOsAccountManager::GetInstance().GetOsAccountInfoById(userId, osAccountInfo);
1378 if (result != ERR_OK) {
1379 ACCOUNT_LOGI("Failed to get account info");
1380 return result;
1381 }
1382 DomainAccountInfo domainInfo;
1383 osAccountInfo.GetDomainInfo(domainInfo);
1384 if (domainInfo.serverConfigId_.empty()) {
1385 ACCOUNT_LOGI("No server config id, isExpired=false");
1386 isExpired = false;
1387 return ERR_OK;
1388 }
1389 std::vector<uint8_t> accountToken;
1390 if (!GetTokenFromMap(userId, accountToken)) {
1391 ACCOUNT_LOGI("The target domain account has not authenticated");
1392 }
1393 PluginDomainAccountInfo domainAccountInfo;
1394 SetPluginDomainAccountInfo(info, domainAccountInfo);
1395 PluginUint8Vector pToken;
1396 SetPluginUint8Vector(accountToken, pToken);
1397 int32_t isValid = 0;
1398 PluginBussnessError* error =
1399 (*reinterpret_cast<IsAuthenticationExpiredFunc>(iter->second))(&domainAccountInfo, &pToken, &isValid);
1400 CleanPluginDomainAccountInfo(domainAccountInfo);
1401 if (error == nullptr) {
1402 ACCOUNT_LOGE("Error is nullptr.");
1403 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1404 }
1405 isExpired = (isValid == 0);
1406 return GetAndCleanPluginBussnessError(&error, iter->first);
1407 }
1408
SetAccountPolicy(const DomainAccountInfo & info,const std::string & policy)1409 ErrCode InnerDomainAccountManager::SetAccountPolicy(const DomainAccountInfo &info,
1410 const std::string &policy) __attribute__((no_sanitize("cfi")))
1411 {
1412 if (!IsSupportNetRequest()) {
1413 ACCOUNT_LOGE("Not support background account request");
1414 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1415 }
1416 auto iter = methodMap_.find(PluginMethodEnum::SET_ACCOUNT_POLICY);
1417 if (iter == methodMap_.end() || iter->second == nullptr) {
1418 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::SET_ACCOUNT_POLICY);
1419 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1420 }
1421 int32_t callerLocalId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
1422 if (!info.IsEmpty()) {
1423 int32_t userId = 0;
1424 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1425 if (result != ERR_OK) {
1426 ACCOUNT_LOGI("The target domain account not found.");
1427 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
1428 }
1429 }
1430 PluginString parameters;
1431 SetPluginString(policy, parameters);
1432 PluginDomainAccountInfo domainAccountInfo;
1433 SetPluginDomainAccountInfo(info, domainAccountInfo);
1434 PluginBussnessError* error =
1435 (*reinterpret_cast<SetAccountPolicyFunc>(iter->second))(¶meters, &domainAccountInfo, callerLocalId);
1436 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
1437 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
1438 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
1439 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
1440 CleanPluginString(&(parameters.data), parameters.length);
1441 return GetAndCleanPluginBussnessError(&error, iter->first);
1442 }
1443
GetAccountPolicy(const DomainAccountInfo & info,std::string & policy)1444 ErrCode InnerDomainAccountManager::GetAccountPolicy(const DomainAccountInfo &info,
1445 std::string &policy) __attribute__((no_sanitize("cfi")))
1446 {
1447 if (!IsSupportNetRequest()) {
1448 ACCOUNT_LOGE("Not support background account request");
1449 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1450 }
1451 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCOUNT_POLICY);
1452 if (iter == methodMap_.end() || iter->second == nullptr) {
1453 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_POLICY);
1454 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1455 }
1456 int32_t callerLocalId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
1457 if (!info.IsEmpty()) {
1458 int32_t userId = 0;
1459 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1460 if (result != ERR_OK) {
1461 ACCOUNT_LOGI("The target domain account not found.");
1462 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
1463 }
1464 }
1465 PluginDomainAccountInfo domainAccountInfo;
1466 SetPluginDomainAccountInfo(info, domainAccountInfo);
1467 PluginDomainAccountPolicy *domainAccountPolicy = nullptr;
1468 PluginBussnessError* error = (*reinterpret_cast<GetAccountPolicyFunc>(iter->second))(&domainAccountInfo,
1469 callerLocalId, &domainAccountPolicy);
1470 if (domainAccountPolicy != nullptr) {
1471 GetAndCleanPluginDomainAccountPolicy(&domainAccountPolicy, policy);
1472 }
1473 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
1474 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
1475 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
1476 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
1477 return GetAndCleanPluginBussnessError(&error, iter->first);
1478 }
1479
ErrorOnResult(const ErrCode errCode,const sptr<IDomainAccountCallback> & callback)1480 static void ErrorOnResult(const ErrCode errCode, const sptr<IDomainAccountCallback> &callback)
1481 {
1482 Parcel emptyParcel;
1483 emptyParcel.WriteBool(false);
1484 DomainAccountParcel domainAccountParcel;
1485 domainAccountParcel.SetParcelData(emptyParcel);
1486 callback->OnResult(errCode, domainAccountParcel);
1487 }
1488
ErrorOnResultWithRet(const ErrCode errCode,const sptr<IDomainAccountCallback> & callback)1489 static ErrCode ErrorOnResultWithRet(const ErrCode errCode, const sptr<IDomainAccountCallback> &callback)
1490 {
1491 ErrorOnResult(errCode, callback);
1492 return errCode;
1493 }
1494
OnResult(int32_t result,Parcel & parcel)1495 void CheckUserTokenCallback::OnResult(int32_t result, Parcel &parcel)
1496 {
1497 ACCOUNT_LOGI("enter");
1498 if (result == ERR_OK) {
1499 isValid_ = parcel.ReadBool();
1500 }
1501 NotifyCallbackEnd();
1502 }
1503
GetValidity(void)1504 bool CheckUserTokenCallback::GetValidity(void)
1505 {
1506 return isValid_;
1507 }
1508
WaitForCallbackResult()1509 void CheckUserTokenCallback::WaitForCallbackResult()
1510 {
1511 std::unique_lock<std::mutex> lock(lock_);
1512 condition_.wait(lock, [this] {
1513 return threadInSleep_ == false;
1514 });
1515 ACCOUNT_LOGI("WaitForCallbackResult.");
1516 }
1517
NotifyCallbackEnd()1518 void CheckUserTokenCallback::NotifyCallbackEnd()
1519 {
1520 std::unique_lock<std::mutex> lock(lock_);
1521 if (threadInSleep_) {
1522 ACCOUNT_LOGI("threadInSleep_ set false.");
1523 threadInSleep_ = false;
1524 condition_.notify_one();
1525 }
1526 }
1527
CheckUserToken(const std::vector<uint8_t> & token,bool & isValid,const DomainAccountInfo & info)1528 ErrCode InnerDomainAccountManager::CheckUserToken(
1529 const std::vector<uint8_t> &token, bool &isValid, const DomainAccountInfo &info)
1530 {
1531 if (!IsSupportNetRequest()) {
1532 ACCOUNT_LOGE("Not support background account request");
1533 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1534 }
1535 std::shared_ptr<CheckUserTokenCallback> callback = std::make_shared<CheckUserTokenCallback>();
1536 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1537 if (callbackService == nullptr) {
1538 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1539 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1540 }
1541
1542 ErrCode errCode = ERR_OK;
1543 {
1544 std::lock_guard<std::mutex> lock(mutex_);
1545 if (plugin_ == nullptr) {
1546 Parcel emptyParcel;
1547 int32_t isTokenValid = -1;
1548 ErrCode err = PluginIsAccountTokenValid(info, token, isTokenValid);
1549 if (err == ERR_OK) {
1550 isValid = (isTokenValid == 1);
1551 }
1552 return err;
1553 }
1554 errCode = plugin_->IsAccountTokenValid(info, token, callbackService);
1555 errCode = ConvertToAccountErrCode(errCode);
1556 }
1557 callback->WaitForCallbackResult();
1558 isValid = callback->GetValidity();
1559 return errCode;
1560 }
1561
GetAccountStatus(const DomainAccountInfo & info,DomainAccountStatus & status)1562 ErrCode InnerDomainAccountManager::GetAccountStatus(const DomainAccountInfo &info, DomainAccountStatus &status)
1563 {
1564 status = DomainAccountStatus::LOGOUT;
1565
1566 int32_t userId = 0;
1567 ErrCode res = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1568 if (res != ERR_OK) {
1569 return res;
1570 }
1571 std::vector<uint8_t> token;
1572 if (!GetTokenFromMap(userId, token)) {
1573 ACCOUNT_LOGI("the target domain account has not authenticated");
1574 return ERR_OK;
1575 }
1576
1577 bool isValid = false;
1578 res = CheckUserToken(token, isValid, info);
1579 if (!isValid) {
1580 ACCOUNT_LOGI("Token is invalid.");
1581 return res;
1582 }
1583
1584 bool isActivated = false;
1585 res = IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId, isActivated);
1586 if (isActivated) {
1587 status = DomainAccountStatus::LOGIN;
1588 } else {
1589 status = DomainAccountStatus::LOGIN_BACKGROUND;
1590 }
1591 return res;
1592 }
1593
RegisterAccountStatusListener(const sptr<IDomainAccountCallback> & listener)1594 ErrCode InnerDomainAccountManager::RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
1595 {
1596 return StatusListenerManager::GetInstance().InsertListenerToRecords(listener->AsObject());
1597 }
1598
UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> & listener)1599 ErrCode InnerDomainAccountManager::UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
1600 {
1601 // userid may be removed already.
1602 return StatusListenerManager::GetInstance().RemoveListenerByListener(listener->AsObject());
1603 }
1604
GetAuthStatusInfo(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)1605 ErrCode InnerDomainAccountManager::GetAuthStatusInfo(
1606 const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
1607 {
1608 if (!IsSupportNetRequest()) {
1609 ACCOUNT_LOGE("Not support background account request");
1610 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1611 }
1612 sptr<IDomainAccountCallback> callbackService =
1613 new (std::nothrow) DomainAccountCallbackService(callback);
1614 if (callbackService == nullptr) {
1615 ACCOUNT_LOGE("failed to create DomainAccountCallbackService");
1616 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
1617 }
1618 if (plugin_ == nullptr) {
1619 Parcel emptyParcel;
1620 AuthStatusInfo authInfo;
1621 ErrCode err = PluginGetAuthStatusInfo(info, authInfo);
1622 if (!authInfo.Marshalling(emptyParcel)) {
1623 ACCOUNT_LOGE("AuthStatusInfo marshalling failed.");
1624 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1625 }
1626 DomainAccountParcel domainAccountParcel;
1627 domainAccountParcel.SetParcelData(emptyParcel);
1628 callbackService->OnResult(err, domainAccountParcel);
1629 return ERR_OK;
1630 }
1631 std::lock_guard<std::mutex> lock(mutex_);
1632 auto errCode = plugin_->GetAuthStatusInfo(info, callbackService);
1633 errCode = ConvertToAccountErrCode(errCode);
1634 return errCode;
1635 }
1636
GetDeathRecipient()1637 sptr<IRemoteObject::DeathRecipient> InnerDomainAccountManager::GetDeathRecipient()
1638 {
1639 if (deathRecipient_ != nullptr) {
1640 return deathRecipient_;
1641 }
1642 deathRecipient_ = new (std::nothrow) DomainAccountPluginDeathRecipient();
1643 return deathRecipient_;
1644 }
1645
IsPluginAvailable()1646 bool InnerDomainAccountManager::IsPluginAvailable()
1647 {
1648 std::lock(mutex_, libMutex_);
1649 std::lock_guard<std::mutex> lock1(mutex_, std::adopt_lock);
1650 std::lock_guard<std::mutex> lock2(libMutex_, std::adopt_lock);
1651 return plugin_ != nullptr || libHandle_ != nullptr;
1652 }
1653
StartHasDomainAccount(const sptr<IDomainAccountPlugin> & plugin,const GetDomainAccountInfoOptions & options,const sptr<IDomainAccountCallback> & callback)1654 ErrCode InnerDomainAccountManager::StartHasDomainAccount(const sptr<IDomainAccountPlugin> &plugin,
1655 const GetDomainAccountInfoOptions &options, const sptr<IDomainAccountCallback> &callback)
1656 {
1657 if (callback == nullptr) {
1658 ACCOUNT_LOGE("invalid callback");
1659 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1660 }
1661 if (plugin == nullptr) {
1662 ACCOUNT_LOGE("plugin is nullptr");
1663 ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1664 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1665 }
1666 auto callbackWrapper = std::make_shared<DomainHasDomainInfoCallback>(
1667 callback, options.accountInfo.domain_, options.accountInfo.accountName_);
1668 if (callbackWrapper == nullptr) {
1669 ACCOUNT_LOGE("make shared DomainHasDomainInfoCallback failed");
1670 ErrorOnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, callback);
1671 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1672 }
1673 sptr<DomainAccountCallbackService> callbackService =
1674 new (std::nothrow) DomainAccountCallbackService(callbackWrapper);
1675 if (callbackService == nullptr) {
1676 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1677 ErrorOnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, callback);
1678 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1679 }
1680 ErrCode result = plugin->GetDomainAccountInfo(options, callbackService);
1681 result = ConvertToAccountErrCode(result);
1682 if (result != ERR_OK) {
1683 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", result);
1684 ErrorOnResult(result, callback);
1685 return result;
1686 }
1687 return ERR_OK;
1688 }
1689
HasDomainAccount(const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1690 ErrCode InnerDomainAccountManager::HasDomainAccount(
1691 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1692 {
1693 if (!IsSupportNetRequest()) {
1694 ACCOUNT_LOGE("Not support background account request");
1695 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1696 }
1697 int32_t callingUid = IPCSkeleton::GetCallingUid();
1698 GetDomainAccountInfoOptions options;
1699 options.accountInfo = info;
1700 options.callingUid = callingUid;
1701 auto task = [this, options, callback] { this->StartHasDomainAccount(this->plugin_, options, callback); };
1702 std::thread taskThread(task);
1703 pthread_setname_np(taskThread.native_handle(), THREAD_HAS_ACCOUNT);
1704 taskThread.detach();
1705 return ERR_OK;
1706 }
1707
StartOnAccountBound(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const int32_t localId,const sptr<IDomainAccountCallback> & callback)1708 void InnerDomainAccountManager::StartOnAccountBound(const sptr<IDomainAccountPlugin> &plugin,
1709 const DomainAccountInfo &info, const int32_t localId, const sptr<IDomainAccountCallback> &callback)
1710 {
1711 if (plugin == nullptr) {
1712 ACCOUNT_LOGE("plugin not exists");
1713 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1714 }
1715 plugin->OnAccountBound(info, localId, callback);
1716 }
1717
OnAccountBound(const DomainAccountInfo & info,const int32_t localId,const std::shared_ptr<DomainAccountCallback> & callback)1718 ErrCode InnerDomainAccountManager::OnAccountBound(const DomainAccountInfo &info, const int32_t localId,
1719 const std::shared_ptr<DomainAccountCallback> &callback)
1720 {
1721 if (!IsSupportNetRequest()) {
1722 ACCOUNT_LOGE("Not support background account request");
1723 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1724 }
1725 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1726 if (callbackService == nullptr) {
1727 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1728 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1729 }
1730 if (plugin_ == nullptr) {
1731 Parcel emptyParcel;
1732 AccountSA::DomainAuthResult result;
1733 ErrCode err = PluginBindAccount(info, localId, result);
1734 if (!result.Marshalling(emptyParcel)) {
1735 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1736 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1737 }
1738 DomainAccountParcel domainAccountParcel;
1739 domainAccountParcel.SetParcelData(emptyParcel);
1740 callbackService->OnResult(err, domainAccountParcel);
1741 return ERR_OK;
1742 }
1743 auto task = [this, info, localId, callbackService] {
1744 this->StartOnAccountBound(this->plugin_, info, localId, callbackService);
1745 };
1746 std::thread taskThread(task);
1747 pthread_setname_np(taskThread.native_handle(), THREAD_BIND_ACCOUNT);
1748 taskThread.detach();
1749 return ERR_OK;
1750 }
1751
StartOnAccountUnBound(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1752 void InnerDomainAccountManager::StartOnAccountUnBound(const sptr<IDomainAccountPlugin> &plugin,
1753 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1754 {
1755 if (plugin == nullptr) {
1756 ACCOUNT_LOGE("plugin not exists");
1757 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1758 }
1759 plugin->OnAccountUnBound(info, callback);
1760 }
1761
OnAccountUnBound(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback,const int32_t localId)1762 ErrCode InnerDomainAccountManager::OnAccountUnBound(const DomainAccountInfo &info,
1763 const std::shared_ptr<DomainAccountCallback> &callback, const int32_t localId)
1764 {
1765 if (!IsSupportNetRequest()) {
1766 ACCOUNT_LOGE("Not support background account request");
1767 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1768 }
1769 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1770 if (callbackService == nullptr) {
1771 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1772 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1773 }
1774 if (plugin_ == nullptr) {
1775 Parcel emptyParcel;
1776 AccountSA::DomainAuthResult result;
1777 ErrCode err = PluginUnBindAccount(info, result, localId);
1778 if (!result.Marshalling(emptyParcel)) {
1779 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1780 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1781 }
1782 DomainAccountParcel domainAccountParcel;
1783 domainAccountParcel.SetParcelData(emptyParcel);
1784 callbackService->OnResult(err, domainAccountParcel);
1785 return ERR_OK;
1786 }
1787 auto task = [this, info, callbackService] {
1788 this->StartOnAccountUnBound(this->plugin_, info, callbackService);
1789 };
1790 std::thread taskThread(task);
1791 pthread_setname_np(taskThread.native_handle(), THREAD_UNBIND_ACCOUNT);
1792 taskThread.detach();
1793 return ERR_OK;
1794 }
1795
StartGetDomainAccountInfo(const sptr<IDomainAccountPlugin> & plugin,const GetDomainAccountInfoOptions & options,const sptr<IDomainAccountCallback> & callback)1796 void InnerDomainAccountManager::StartGetDomainAccountInfo(const sptr<IDomainAccountPlugin> &plugin,
1797 const GetDomainAccountInfoOptions &options, const sptr<IDomainAccountCallback> &callback)
1798 {
1799 if (plugin == nullptr) {
1800 ACCOUNT_LOGE("plugin not exists");
1801 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1802 }
1803 ErrCode errCode = plugin->GetDomainAccountInfo(options, callback);
1804 errCode = ConvertToAccountErrCode(errCode);
1805 if (errCode != ERR_OK) {
1806 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", errCode);
1807 ErrorOnResult(errCode, callback);
1808 }
1809 }
1810
PluginGetDomainAccountInfo(const GetDomainAccountInfoOptions & options,DomainAccountInfo & info)1811 ErrCode InnerDomainAccountManager::PluginGetDomainAccountInfo(const GetDomainAccountInfoOptions &options,
1812 DomainAccountInfo &info) __attribute__((no_sanitize("cfi")))
1813 {
1814 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCOUNT_INFO);
1815 if (iter == methodMap_.end() || iter->second == nullptr) {
1816 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_INFO);
1817 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
1818 }
1819 int32_t localId = GetCallingUserID();
1820 if (localId == -1) {
1821 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
1822 }
1823 PluginGetDomainAccountInfoOptions pluginOptions;
1824 SetPluginDomainAccountInfo(options.accountInfo, pluginOptions.domainAccountInfo);
1825 pluginOptions.callerUid = options.callingUid;
1826 PluginDomainAccountInfo *accountInfoResult = nullptr;
1827 PluginBussnessError* error =
1828 (*reinterpret_cast<GetAccountInfoFunc>(iter->second))(&pluginOptions, localId, &accountInfoResult);
1829 GetAndCleanPluginDomainAccountInfo(info, &accountInfoResult);
1830 CleanPluginString(&(pluginOptions.domainAccountInfo.domain.data), pluginOptions.domainAccountInfo.domain.length);
1831 CleanPluginString(&(pluginOptions.domainAccountInfo.serverConfigId.data),
1832 pluginOptions.domainAccountInfo.serverConfigId.length);
1833 CleanPluginString(&(pluginOptions.domainAccountInfo.accountName.data),
1834 pluginOptions.domainAccountInfo.accountName.length);
1835 CleanPluginString(&(pluginOptions.domainAccountInfo.accountId.data),
1836 pluginOptions.domainAccountInfo.accountId.length);
1837 return GetAndCleanPluginBussnessError(&error, iter->first);
1838 }
1839
GetDomainAccountInfo(const DomainAccountInfo & info,DomainAccountInfo & result)1840 ErrCode InnerDomainAccountManager::GetDomainAccountInfo(const DomainAccountInfo &info, DomainAccountInfo &result)
1841 {
1842 if (info.accountName_.empty()) {
1843 ACCOUNT_LOGI("Domian Account not bind");
1844 return ERR_OK;
1845 }
1846 if (plugin_ == nullptr) {
1847 GetDomainAccountInfoOptions options;
1848 options.accountInfo = info;
1849 options.callingUid = IPCSkeleton::GetCallingUid();
1850 return PluginGetDomainAccountInfo(options, result);
1851 }
1852 return ERR_OK;
1853 }
1854
GetDomainAccountInfo(const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1855 ErrCode InnerDomainAccountManager::GetDomainAccountInfo(
1856 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1857 {
1858 if (!IsSupportNetRequest()) {
1859 ACCOUNT_LOGE("Not support background account request");
1860 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1861 }
1862 DomainAccountCallbackFunc callbackFunc = [callback](const int32_t errCode, Parcel &parcel) {
1863 if (callback != nullptr) {
1864 DomainAccountParcel domainAccountParcel;
1865 domainAccountParcel.SetParcelData(parcel);
1866 callback->OnResult(errCode, domainAccountParcel);
1867 }
1868 };
1869 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callbackFunc);
1870 if (callbackService == nullptr) {
1871 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1872 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1873 }
1874 int32_t callingUid = IPCSkeleton::GetCallingUid();
1875 GetDomainAccountInfoOptions options;
1876 options.accountInfo = info;
1877 options.callingUid = callingUid;
1878 if (plugin_ == nullptr) {
1879 Parcel emptyParcel;
1880 DomainAccountInfo result;
1881 ErrCode err = PluginGetDomainAccountInfo(options, result);
1882 AAFwk::WantParams wParam;
1883 wParam.SetParam("domain", OHOS::AAFwk::String::Box(result.domain_));
1884 wParam.SetParam("accountName", OHOS::AAFwk::String::Box(result.accountName_));
1885 wParam.SetParam("accountId", OHOS::AAFwk::String::Box(result.accountId_));
1886 wParam.SetParam("serverConfigId", OHOS::AAFwk::String::Box(result.serverConfigId_));
1887 wParam.SetParam("isAuthenticated", OHOS::AAFwk::Boolean::Box(result.isAuthenticated));
1888 wParam.SetParam("status", OHOS::AAFwk::Integer::Box(result.status_));
1889 if (!wParam.Marshalling(emptyParcel)) {
1890 ACCOUNT_LOGE("DomainAccountInfo marshalling failed.");
1891 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1892 }
1893 DomainAccountParcel domainAccountParcel;
1894 domainAccountParcel.SetParcelData(emptyParcel);
1895 callbackService->OnResult(err, domainAccountParcel);
1896 return ERR_OK;
1897 }
1898 auto task = [this, options, callbackService] {
1899 this->StartGetDomainAccountInfo(this->plugin_, options, callbackService);
1900 };
1901 std::thread taskThread(task);
1902 pthread_setname_np(taskThread.native_handle(), THREAD_GET_ACCOUNT);
1903 taskThread.detach();
1904 return ERR_OK;
1905 }
1906
StartIsAccountTokenValid(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const std::vector<uint8_t> & token,const sptr<IDomainAccountCallback> & callback)1907 void InnerDomainAccountManager::StartIsAccountTokenValid(const sptr<IDomainAccountPlugin> &plugin,
1908 const DomainAccountInfo &info, const std::vector<uint8_t> &token, const sptr<IDomainAccountCallback> &callback)
1909 {
1910 if (plugin == nullptr) {
1911 ACCOUNT_LOGE("plugin not exists");
1912 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1913 }
1914 ErrCode errCode = plugin->IsAccountTokenValid(info, token, callback);
1915 errCode = ConvertToAccountErrCode(errCode);
1916 if (errCode != ERR_OK) {
1917 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", errCode);
1918 ErrorOnResult(errCode, callback);
1919 }
1920 }
1921
IsAccountTokenValid(const DomainAccountInfo & info,const std::vector<uint8_t> & token,const std::shared_ptr<DomainAccountCallback> & callback)1922 ErrCode InnerDomainAccountManager::IsAccountTokenValid(const DomainAccountInfo &info,
1923 const std::vector<uint8_t> &token, const std::shared_ptr<DomainAccountCallback> &callback)
1924 {
1925 if (!IsSupportNetRequest()) {
1926 ACCOUNT_LOGE("Not support background account request");
1927 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
1928 }
1929 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1930 if (callbackService == nullptr) {
1931 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1932 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1933 }
1934 if (plugin_ == nullptr) {
1935 Parcel emptyParcel;
1936 int32_t isValid = -1;
1937 ErrCode err = PluginIsAccountTokenValid(info, token, isValid);
1938 if (!emptyParcel.WriteBool(isValid == 1)) {
1939 ACCOUNT_LOGE("IsValid marshalling failed.");
1940 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1941 }
1942 DomainAccountParcel domainAccountParcel;
1943 domainAccountParcel.SetParcelData(emptyParcel);
1944 callbackService->OnResult(err, domainAccountParcel);
1945 return ERR_OK;
1946 }
1947 auto task = [this, info, token, callbackService] {
1948 this->StartIsAccountTokenValid(this->plugin_, info, token, callbackService);
1949 };
1950 std::thread taskThread(task);
1951 pthread_setname_np(taskThread.native_handle(), THREAD_IS_ACCOUNT_VALID);
1952 taskThread.detach();
1953 return ERR_OK;
1954 }
1955
OnResult(int32_t result,Parcel & parcel)1956 void UpdateAccountInfoCallback::OnResult(int32_t result, Parcel &parcel)
1957 {
1958 std::unique_lock<std::mutex> lock(lock_);
1959 if (result_ >= 0) {
1960 return;
1961 }
1962 if (result == ERR_JS_ACCOUNT_NOT_FOUND) {
1963 result_ = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1964 } else if (result == ERR_JS_CAPABILITY_NOT_SUPPORTED) {
1965 result_ = ERR_OK;
1966 } else {
1967 result_ = result;
1968 }
1969 if (result_ == ERR_OK) {
1970 std::shared_ptr<AAFwk::WantParams> parameters(AAFwk::WantParams::Unmarshalling(parcel));
1971 if (parameters == nullptr) {
1972 ACCOUNT_LOGE("Parameters unmarshalling error");
1973 result_ = ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
1974 } else {
1975 accountInfo_.accountName_ = parameters->GetStringParam("accountName");
1976 accountInfo_.domain_ = parameters->GetStringParam("domain");
1977 accountInfo_.accountId_ = parameters->GetStringParam("accountId");
1978 accountInfo_.serverConfigId_ = parameters->GetStringParam("serverConfigId");
1979 }
1980 }
1981 ACCOUNT_LOGI("ThreadInSleep_ set false.");
1982 threadInSleep_ = false;
1983 condition_.notify_one();
1984 }
1985
GetResult()1986 int32_t UpdateAccountInfoCallback::GetResult()
1987 {
1988 return result_;
1989 }
1990
WaitForCallbackResult()1991 void UpdateAccountInfoCallback::WaitForCallbackResult()
1992 {
1993 std::unique_lock<std::mutex> lock(lock_);
1994 condition_.wait(lock, [this] {
1995 return threadInSleep_ == false;
1996 });
1997 ACCOUNT_LOGI("WaitForCallbackResult.");
1998 }
1999
GetAccountInfo()2000 DomainAccountInfo UpdateAccountInfoCallback::GetAccountInfo()
2001 {
2002 return accountInfo_;
2003 }
2004
CheckNewDomainAccountInfo(const DomainAccountInfo & oldAccountInfo,DomainAccountInfo & newAccountInfo)2005 static ErrCode CheckNewDomainAccountInfo(const DomainAccountInfo &oldAccountInfo, DomainAccountInfo &newAccountInfo)
2006 {
2007 if (!oldAccountInfo.serverConfigId_.empty()) {
2008 if (newAccountInfo.serverConfigId_.empty()) {
2009 newAccountInfo.serverConfigId_ = oldAccountInfo.serverConfigId_;
2010 }
2011 }
2012 ErrCode result = ERR_OK;
2013 if (!IInnerOsAccountManager::GetInstance().IsSameAccount(oldAccountInfo, newAccountInfo)) {
2014 int32_t userId = 0;
2015 result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(newAccountInfo, userId);
2016 if (result == ERR_OK && userId > 0) {
2017 ACCOUNT_LOGE("NewAccountInfo already exists");
2018 return ERR_OSACCOUNT_SERVICE_INNER_DOMAIN_ALREADY_BIND_ERROR;
2019 }
2020 if (result != ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT) {
2021 return result;
2022 }
2023 }
2024 std::shared_ptr<UpdateAccountInfoCallback> callback = std::make_shared<UpdateAccountInfoCallback>();
2025 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
2026 if (callbackService == nullptr) {
2027 ACCOUNT_LOGE("Make shared DomainAccountCallbackService failed");
2028 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
2029 }
2030 result = InnerDomainAccountManager::GetInstance().GetDomainAccountInfo(newAccountInfo, callbackService);
2031 if (result != ERR_OK) {
2032 ACCOUNT_LOGE("GetDomainAccountInfo failed, result = %{public}d", result);
2033 return result;
2034 }
2035 callback->WaitForCallbackResult();
2036 result = callback->GetResult();
2037 if (result != ERR_OK) {
2038 ACCOUNT_LOGE("NewAccountInfo is invaild");
2039 return result;
2040 }
2041 newAccountInfo = callback->GetAccountInfo();
2042 return ERR_OK;
2043 }
2044
UpdateAccountInfo(const DomainAccountInfo & oldAccountInfo,const DomainAccountInfo & newAccountInfo)2045 ErrCode InnerDomainAccountManager::UpdateAccountInfo(
2046 const DomainAccountInfo &oldAccountInfo, const DomainAccountInfo &newAccountInfo)
2047 {
2048 if (!IsSupportNetRequest()) {
2049 ACCOUNT_LOGE("Not support background account request");
2050 return ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST;
2051 }
2052 if (!IsPluginAvailable()) {
2053 ACCOUNT_LOGE("Plugin is nullptr.");
2054 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
2055 }
2056 // check old account info
2057 int32_t userId = 0;
2058 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(oldAccountInfo, userId);
2059 if (result != ERR_OK) {
2060 ACCOUNT_LOGE("GetOsAccountLocalIdFromDomain failed, result = %{public}d", result);
2061 if (result != ERR_ACCOUNT_COMMON_INVALID_PARAMETER) {
2062 return result;
2063 }
2064 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
2065 }
2066 // check new account info
2067 DomainAccountInfo newDomainAccountInfo(newAccountInfo);
2068 result = CheckNewDomainAccountInfo(oldAccountInfo, newDomainAccountInfo);
2069 if (result != ERR_OK) {
2070 return result;
2071 }
2072
2073 if (oldAccountInfo.serverConfigId_.empty() && !newAccountInfo.serverConfigId_.empty()) {
2074 Parcel emptyParcel;
2075 AccountSA::DomainAuthResult authResult;
2076 result = PluginBindAccount(newAccountInfo, userId, authResult);
2077 if (result != ERR_OK) {
2078 ACCOUNT_LOGE("PluginBindAccount failed, errCode = %{public}d", result);
2079 return result;
2080 }
2081 if (!authResult.Marshalling(emptyParcel)) {
2082 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
2083 return ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
2084 }
2085 } else {
2086 // update account info
2087 if (plugin_ == nullptr) {
2088 result = PluginUpdateAccountInfo(oldAccountInfo, newDomainAccountInfo);
2089 if (result != ERR_OK) {
2090 ACCOUNT_LOGE("PluginUpdateAccountInfo failed, errCode = %{public}d", result);
2091 return result;
2092 }
2093 }
2094 }
2095
2096 // update local info
2097 return IInnerOsAccountManager::GetInstance().UpdateAccountInfoByDomainAccountInfo(
2098 userId, newDomainAccountInfo);
2099 }
2100
OnResult(int32_t result,Parcel & parcel)2101 void DomainAccountCallbackSync::OnResult(int32_t result, Parcel &parcel)
2102 {
2103 std::unique_lock<std::mutex> lock(lock_);
2104 if (isCalled_) {
2105 ACCOUNT_LOGE("Called twice.");
2106 return;
2107 }
2108 result_ = result;
2109 ACCOUNT_LOGI("ThreadInSleep_ set false.");
2110 isCalled_ = true;
2111 condition_.notify_one();
2112 }
2113
GetResult()2114 int32_t DomainAccountCallbackSync::GetResult()
2115 {
2116 std::unique_lock<std::mutex> lock(lock_);
2117 return result_;
2118 }
2119
WaitForCallbackResult()2120 void DomainAccountCallbackSync::WaitForCallbackResult()
2121 {
2122 std::unique_lock<std::mutex> lock(lock_);
2123 ACCOUNT_LOGI("WaitForCallbackResult.");
2124 condition_.wait(lock, [this] { return isCalled_; });
2125 }
2126
UnbindDomainAccountSync(const DomainAccountInfo & info,const int32_t localId)2127 ErrCode InnerDomainAccountManager::UnbindDomainAccountSync(const DomainAccountInfo &info, const int32_t localId)
2128 {
2129 #ifdef HICOLLIE_ENABLE
2130 XCollieCallback callbackFunc = [localId = localId](void *) {
2131 ACCOUNT_LOGE("UnbindDomainAccountSync timeout, bind localId = %{public}d.", localId);
2132 REPORT_OS_ACCOUNT_FAIL(localId, "watchDog", -1, "Unbind domain account sync time out");
2133 };
2134 int32_t timerId = HiviewDFX::XCollie::GetInstance().SetTimer(
2135 TIMER_NAME, DOMAIN_ACCOUNT_RECOVERY_TIMEOUT, callbackFunc, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2136 #endif // HICOLLIE_ENABLE
2137 std::shared_ptr<DomainAccountCallbackSync> callback = std::make_shared<DomainAccountCallbackSync>();
2138 ErrCode err = OnAccountUnBound(info, callback, localId);
2139 if (err != ERR_OK) {
2140 ACCOUNT_LOGE("OnAccountUnBound failed, errCode = %{public}d", err);
2141 #ifdef HICOLLIE_ENABLE
2142 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2143 #endif // HICOLLIE_ENABLE
2144 return err;
2145 }
2146 callback->WaitForCallbackResult();
2147 #ifdef HICOLLIE_ENABLE
2148 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2149 #endif // HICOLLIE_ENABLE
2150 err = callback->GetResult();
2151 if (err != ERR_OK) {
2152 ACCOUNT_LOGE("Callback get failed, errCode = %{public}d", err);
2153 }
2154 return err;
2155 }
2156
BindDomainAccountSync(const DomainAccountInfo & info,const int32_t localId)2157 ErrCode InnerDomainAccountManager::BindDomainAccountSync(const DomainAccountInfo &info, const int32_t localId)
2158 {
2159 #ifdef HICOLLIE_ENABLE
2160 XCollieCallback callbackFunc = [localId = localId](void *) {
2161 ACCOUNT_LOGE("BindDomainAccountSync timeout, bind localId = %{public}d.", localId);
2162 REPORT_OS_ACCOUNT_FAIL(localId, "watchDog", -1, "Bind domain account sync time out");
2163 };
2164 int32_t timerId = HiviewDFX::XCollie::GetInstance().SetTimer(
2165 TIMER_NAME, DOMAIN_ACCOUNT_RECOVERY_TIMEOUT, callbackFunc, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2166 #endif // HICOLLIE_ENABLE
2167 std::shared_ptr<DomainAccountCallbackSync> callback = std::make_shared<DomainAccountCallbackSync>();
2168 ErrCode err = OnAccountBound(info, localId, callback);
2169 if (err != ERR_OK) {
2170 ACCOUNT_LOGE("OnAccountUnBound failed, errCode = %{public}d", err);
2171 #ifdef HICOLLIE_ENABLE
2172 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2173 #endif // HICOLLIE_ENABLE
2174 return err;
2175 }
2176 callback->WaitForCallbackResult();
2177 #ifdef HICOLLIE_ENABLE
2178 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2179 #endif // HICOLLIE_ENABLE
2180 err = callback->GetResult();
2181 if (err != ERR_OK) {
2182 ACCOUNT_LOGE("Callback get failed, errCode = %{public}d", err);
2183 }
2184 return err;
2185 }
2186
GetDomainAccountInfoSync(const int32_t localId,const DomainAccountInfo & info,DomainAccountInfo & fullInfo)2187 ErrCode InnerDomainAccountManager::GetDomainAccountInfoSync(const int32_t localId,
2188 const DomainAccountInfo &info, DomainAccountInfo &fullInfo)
2189 {
2190 fullInfo.Clear();
2191 std::shared_ptr<UpdateAccountInfoCallback> callback = std::make_shared<UpdateAccountInfoCallback>();
2192 sptr<DomainAccountCallbackService> callbackService = sptr<DomainAccountCallbackService>::MakeSptr(callback);
2193 if (callbackService == nullptr) {
2194 ACCOUNT_LOGE("Make shared DomainAccountCallbackService failed");
2195 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
2196 }
2197 #ifdef HICOLLIE_ENABLE
2198 XCollieCallback callbackFunc = [localId = localId](void *) {
2199 ACCOUNT_LOGE("GetDomainAccountInfoSync timeout, bind localId = %{public}d.", localId);
2200 REPORT_OS_ACCOUNT_FAIL(localId, "watchDog", -1, "Get domain account info sync time out");
2201 };
2202 int32_t timerId = HiviewDFX::XCollie::GetInstance().SetTimer(
2203 TIMER_NAME, DOMAIN_ACCOUNT_RECOVERY_TIMEOUT, callbackFunc, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2204 #endif // HICOLLIE_ENABLE
2205 ErrCode err = GetDomainAccountInfo(info, callbackService);
2206 if (err != ERR_OK) {
2207 ACCOUNT_LOGE("GetDomainAccountInfo failed, result = %{public}d", err);
2208 #ifdef HICOLLIE_ENABLE
2209 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2210 #endif // HICOLLIE_ENABLE
2211 return err;
2212 }
2213 callback->WaitForCallbackResult();
2214 #ifdef HICOLLIE_ENABLE
2215 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
2216 #endif // HICOLLIE_ENABLE
2217 err = callback->GetResult();
2218 if (err != ERR_OK) {
2219 ACCOUNT_LOGE("Callback get failed, errCode = %{public}d", err);
2220 } else {
2221 fullInfo = callback->GetAccountInfo();
2222 }
2223 return err;
2224 }
2225
RecoverBindDomainForUncomplete(const OsAccountInfo & osAccountInfo,const DomainAccountInfo & domainInfo)2226 ErrCode InnerDomainAccountManager::RecoverBindDomainForUncomplete(
2227 const OsAccountInfo &osAccountInfo, const DomainAccountInfo &domainInfo)
2228 {
2229 int32_t localId = osAccountInfo.GetLocalId();
2230 OsAccountControlFileManager &fileController = IInnerOsAccountManager::GetInstance().GetFileController();
2231 ErrCode err = 0;
2232 if (!osAccountInfo.domainInfo_.IsEmpty()) {
2233 ACCOUNT_LOGE("The account %{public}d already bound domain account", localId);
2234 err = fileController.SetDomainBoundFlag(localId, true);
2235 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT,
2236 err, "Last domain bind operation successed, delete flag.");
2237 return err;
2238 }
2239 err = UnbindDomainAccountSync(domainInfo, localId);
2240 if ((err != ERR_OK) && (err != ERR_JS_ACCOUNT_NOT_FOUND)) {
2241 ACCOUNT_LOGE("UnbindDomainAccountSync failed, ret = %{public}d", err);
2242 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT, err,
2243 "Unbound domain account failed.");
2244 return err;
2245 }
2246 // delete flag file
2247 err = fileController.SetDomainBoundFlag(localId, true);
2248 if (err != ERR_OK) {
2249 ACCOUNT_LOGW("Delete bound flag failed, ret = %{public}d", err);
2250 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT,
2251 err, "Delete bind flag failed.");
2252 }
2253 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT,
2254 err, "Recover bind domain account success.");
2255 return ERR_OK;
2256 }
2257
BindDomainAccountWork(const int32_t localId,const DomainAccountInfo & domainInfo,const OsAccountInfo & info)2258 ErrCode InnerDomainAccountManager::BindDomainAccountWork(
2259 const int32_t localId, const DomainAccountInfo &domainInfo, const OsAccountInfo &info)
2260 {
2261 DomainAccountInfo fullInfo;
2262 ErrCode err = GetDomainAccountInfoSync(localId, domainInfo, fullInfo);
2263 if (err != ERR_OK) {
2264 ACCOUNT_LOGW("Get domain account info failed, ret = %{public}d.", err);
2265 return err;
2266 }
2267 OsAccountControlFileManager &fileController = IInnerOsAccountManager::GetInstance().GetFileController();
2268 err = fileController.SetDomainBoundFlag(localId, false, fullInfo);
2269 if (err != ERR_OK) {
2270 ACCOUNT_LOGW("Set domain bound flag failed, ret = %{public}d.", err);
2271 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2272 err, "Create bind flag failed.");
2273 return err;
2274 }
2275 err = BindDomainAccountSync(fullInfo, localId);
2276 if (err != ERR_OK) {
2277 ACCOUNT_LOGW("Bound domain account failed, ret = %{public}d.", err);
2278 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2279 err, "Bound domain account failed.");
2280 fileController.SetDomainBoundFlag(localId, true);
2281 return err;
2282 }
2283 OsAccountInfo selectAccountInfo = info;
2284 selectAccountInfo.SetDomainInfo(fullInfo);
2285 err = fileController.UpdateOsAccount(selectAccountInfo);
2286 if (err != ERR_OK) {
2287 ACCOUNT_LOGW("Update os account failed, ret = %{public}d.", err);
2288 REPORT_OS_ACCOUNT_FAIL(
2289 localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT, err, "Update OS account info failed.");
2290 RecoverBindDomainForUncomplete(info, fullInfo);
2291 return err;
2292 }
2293 fileController.SetDomainBoundFlag(localId, true);
2294 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2295 err, "Bind domain account success.");
2296 return err;
2297 }
2298
CleanUnbindDomainAccount()2299 ErrCode InnerDomainAccountManager::CleanUnbindDomainAccount()
2300 {
2301 std::vector<int32_t> allOsAccountIds;
2302 OsAccountControlFileManager &fileController = IInnerOsAccountManager::GetInstance().GetFileController();
2303 ErrCode errCode = fileController.GetOsAccountIdList(allOsAccountIds);
2304 if (errCode != ERR_OK) {
2305 ACCOUNT_LOGE("Get osaccount info list error, errCode %{public}d.", errCode);
2306 return errCode;
2307 }
2308 std::vector<OsAccountInfo> infos;
2309 for (auto id : allOsAccountIds) {
2310 OsAccountInfo osAccountInfo;
2311 if (!IInnerOsAccountManager::GetInstance().CheckAndAddLocalIdOperating(id)) {
2312 ACCOUNT_LOGE("Check and add local id operating error, id %{public}d.", id);
2313 REPORT_OS_ACCOUNT_FAIL(id, Constants::OPERATION_BOOT_RECOVER_BIND_DOMAIN_ACCOUNT,
2314 ERR_OSACCOUNT_SERVICE_INNER_ACCOUNT_OPERATING_ERROR, "Target account is in operating on boot.");
2315 continue;
2316 }
2317 ErrCode err = IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(id, osAccountInfo);
2318 if (err != ERR_OK) {
2319 ACCOUNT_LOGE("Get osaccount info error, errCode %{public}d.", err);
2320 REPORT_OS_ACCOUNT_FAIL(
2321 id, Constants::OPERATION_BOOT_RECOVER_BIND_DOMAIN_ACCOUNT, err, "Get OS account info error on boot.");
2322 IInnerOsAccountManager::GetInstance().RemoveLocalIdToOperating(id);
2323 continue;
2324 }
2325 err = CheckAndRecoverBindDomainForUncomplete(osAccountInfo);
2326 if (err != ERR_OK) {
2327 ACCOUNT_LOGE("CheckAndRecoverBindDomainForUncomplete failed, ret = %{public}d", err);
2328 REPORT_OS_ACCOUNT_FAIL(id, Constants::OPERATION_BOOT_RECOVER_BIND_DOMAIN_ACCOUNT, err,
2329 "Recover bind domain account on boot failed.");
2330 } else {
2331 REPORT_OS_ACCOUNT_FAIL(id, Constants::OPERATION_BOOT_RECOVER_BIND_DOMAIN_ACCOUNT, err,
2332 "Recover bind domain account on boot success.");
2333 }
2334 IInnerOsAccountManager::GetInstance().RemoveLocalIdToOperating(id);
2335 }
2336 return ERR_OK;
2337 }
2338
BindDomainAccount(const int32_t localId,const DomainAccountInfo & domainInfo,const sptr<IDomainAccountCallback> & callback)2339 ErrCode InnerDomainAccountManager::BindDomainAccount(
2340 const int32_t localId, const DomainAccountInfo &domainInfo, const sptr<IDomainAccountCallback> &callback)
2341 {
2342 std::lock_guard<std::mutex> lock(IInnerOsAccountManager::GetInstance().createOrBindDomainAccountMutex_);
2343 OsAccountInfo selectInfo;
2344 ErrCode errCode = IInnerOsAccountManager::GetInstance().GetOsAccountInfoById(localId, selectInfo);
2345 if (errCode != ERR_OK) {
2346 ACCOUNT_LOGE("Get osaccount info error, errCode = %{public}d, localId = %{public}d.", errCode, localId);
2347 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2348 errCode, "Get OS account Info failed.");
2349 return ErrorOnResultWithRet(errCode, callback);
2350 }
2351 if (!IInnerOsAccountManager::GetInstance().CheckAndAddLocalIdOperating(localId)) {
2352 ACCOUNT_LOGE("The account %{public}d already in operating", localId);
2353 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2354 ERR_OSACCOUNT_SERVICE_INNER_ACCOUNT_OPERATING_ERROR, "Input OS account is already in operating.");
2355 return ErrorOnResultWithRet(ERR_OSACCOUNT_SERVICE_INNER_ACCOUNT_OPERATING_ERROR, callback);
2356 }
2357 errCode = CheckOsAccountCanBindDomainAccount(selectInfo);
2358 if (errCode != ERR_OK) {
2359 ACCOUNT_LOGE("Check os account bind domain failed, " \
2360 "errCode = %{public}d, localId = %{public}d.", errCode, localId);
2361 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT,
2362 errCode, "Input OS account cannnot bind domain account.");
2363 IInnerOsAccountManager::GetInstance().RemoveLocalIdToOperating(localId);
2364 return ErrorOnResultWithRet(errCode, callback);
2365 }
2366
2367 errCode = CheckDomainAccountCanBindOsAccount(domainInfo);
2368 if (errCode != ERR_OK) {
2369 ACCOUNT_LOGE("Check domain account bound failed, ret = %{public}d", errCode);
2370 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_BIND_DOMAIN_ACCOUNT, errCode,
2371 "Input domain cannnot bind to OS account.");
2372 IInnerOsAccountManager::GetInstance().RemoveLocalIdToOperating(localId);
2373 return ErrorOnResultWithRet(errCode, callback);
2374 }
2375 errCode = BindDomainAccountWork(localId, domainInfo, selectInfo);
2376 if (errCode != ERR_OK) {
2377 ACCOUNT_LOGW("Bound domain account failed, ret = %{public}d.", errCode);
2378 }
2379 IInnerOsAccountManager::GetInstance().RemoveLocalIdToOperating(localId);
2380 return ErrorOnResultWithRet(errCode, callback);
2381 }
2382
CheckOsAccountCanBindDomainAccount(const OsAccountInfo & osAccountInfo)2383 ErrCode InnerDomainAccountManager::CheckOsAccountCanBindDomainAccount(const OsAccountInfo &osAccountInfo)
2384 {
2385 int32_t localId = osAccountInfo.GetLocalId();
2386 if (!osAccountInfo.GetIsCreateCompleted() || osAccountInfo.GetToBeRemoved()) {
2387 ACCOUNT_LOGE("Not create completed account or to be removed account are not allowed to bind domain.");
2388 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
2389 }
2390 ErrCode errCode = CheckAndRecoverBindDomainForUncomplete(osAccountInfo);
2391 if (errCode != ERR_OK) {
2392 ACCOUNT_LOGE("Check and recover bind domain for uncomplete error, " \
2393 "errCode = %{public}d, localId = %{public}d.", errCode, localId);
2394 return errCode;
2395 }
2396 if (!osAccountInfo.domainInfo_.IsEmpty()) {
2397 ACCOUNT_LOGW("Os account is bound to a domain account, localId = %{public}d", localId);
2398 return ERR_OSACCOUNT_SERVICE_INNER_OS_ACCOUNT_ALREADY_BOUND;
2399 }
2400 return ERR_OK;
2401 }
2402
CheckDomainAccountCanBindOsAccount(const DomainAccountInfo & domainInfo)2403 ErrCode InnerDomainAccountManager::CheckDomainAccountCanBindOsAccount(const DomainAccountInfo &domainInfo)
2404 {
2405 bool isBound = true;
2406 ErrCode errCode = IInnerOsAccountManager::GetInstance().CheckDomainAccountBound(domainInfo, isBound);
2407 if (errCode != ERR_OK) {
2408 ACCOUNT_LOGE("Check domain account bound failed, ret = %{public}d", errCode);
2409 return errCode;
2410 }
2411 if (isBound) {
2412 ACCOUNT_LOGW("Domain account is already bound.");
2413 return ERR_OSACCOUNT_SERVICE_INNER_DOMAIN_ACCOUNT_ALREADY_BOUND;
2414 }
2415 return ERR_OK;
2416 }
2417
CheckAndRecoverBindDomainForUncomplete(const OsAccountInfo & accountInfo)2418 ErrCode InnerDomainAccountManager::CheckAndRecoverBindDomainForUncomplete(const OsAccountInfo &accountInfo)
2419 {
2420 bool isBoundCompleted = false;
2421 int32_t localId = accountInfo.GetLocalId();
2422 DomainAccountInfo storedDomainInfo;
2423 OsAccountControlFileManager &fileController = IInnerOsAccountManager::GetInstance().GetFileController();
2424 ErrCode errCode = fileController.GetDomainBoundFlag(localId, isBoundCompleted, storedDomainInfo);
2425 // if file data format error, ignore this
2426 if (errCode == ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR) {
2427 ACCOUNT_LOGW("GetDomainBoundFlag failed, bad json format.");
2428 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT,
2429 ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR, "Bad json format, delete file and set flag to true.");
2430 errCode = fileController.SetDomainBoundFlag(localId, true);
2431 isBoundCompleted = true;
2432 }
2433 if (errCode != ERR_OK) {
2434 ACCOUNT_LOGE("Get domain bound flag failed, errCode = %{public}d, isBoundCompleted = %{public}d",
2435 errCode, isBoundCompleted);
2436 REPORT_OS_ACCOUNT_FAIL(
2437 localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT, errCode, "Get bind domain account flag failed.");
2438 return errCode;
2439 }
2440 if (!isBoundCompleted) {
2441 ACCOUNT_LOGW("Domain bound flag is not empty, need unbind");
2442 REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_RECOVER_BIND_DOMAIN_ACCOUNT, -1,
2443 "Domain bound flag is not empty, need unbind");
2444 errCode = RecoverBindDomainForUncomplete(accountInfo, storedDomainInfo);
2445 if (errCode != ERR_OK) {
2446 ACCOUNT_LOGE("Recover bind domain account failed.");
2447 return errCode;
2448 }
2449 }
2450 return ERR_OK;
2451 }
2452 } // namespace AccountSA
2453 } // namespace OHOS
2454