• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &parameters)
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))(&param, 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, &param,
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 &parameters, 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))(&parameters, &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