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