1/*
2 * Copyright (c) 2021-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 "account_stub.h"
17
18#include <dlfcn.h>
19#include <ipc_types.h>
20#include "accesstoken_kit.h"
21#include "account_error_no.h"
22#include "account_helper_data.h"
23#include "account_info.h"
24#include "account_info_parcel.h"
25#include "account_log_wrapper.h"
26#include "account_mgr_service.h"
27#include "bundle_manager_adapter.h"
28#include "account_hisysevent_adapter.h"
29#include "if_system_ability_manager.h"
30#include "ipc_skeleton.h"
31#include "iservice_registry.h"
32#include "memory_guard.h"
33#include "ohos_account_kits.h"
34#include "account_constants.h"
35#ifdef HICOLLIE_ENABLE
36#include "xcollie/xcollie.h"
37#endif // HICOLLIE_ENABLE
38
39namespace OHOS {
40namespace AccountSA {
41namespace {
42const std::string OHOS_ACCOUNT_QUIT_TIPS_TITLE = "";
43const std::string OHOS_ACCOUNT_QUIT_TIPS_CONTENT = "";
44const std::string PERMISSION_MANAGE_USERS = "ohos.permission.MANAGE_LOCAL_ACCOUNTS";
45const std::string PERMISSION_GET_LOCAL_ACCOUNTS = "ohos.permission.GET_LOCAL_ACCOUNTS";
46const std::string PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS = "ohos.permission.MANAGE_DISTRIBUTED_ACCOUNTS";
47const std::string PERMISSION_GET_DISTRIBUTED_ACCOUNTS = "ohos.permission.GET_DISTRIBUTED_ACCOUNTS";
48const std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
49const std::string INTERACT_ACROSS_LOCAL_ACCOUNTS = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS";
50#ifndef IS_RELEASE_VERSION
51constexpr std::int32_t ROOT_UID = 0;
52#endif
53#ifdef HICOLLIE_ENABLE
54constexpr std::int32_t RECOVERY_TIMEOUT = 6; // timeout 6s
55#endif // HICOLLIE_ENABLE
56constexpr std::int32_t INVALID_USERID = -1;
57const std::set<std::int32_t> WHITE_LIST = {
58    3012, // DISTRIBUTED_KV_DATA_SA_UID
59    3019, // DLP_UID
60    3553, // DLP_CREDENTIAL_SA_UID
61};
62#ifdef USE_MUSL
63constexpr std::int32_t DSOFTBUS_UID = 1024;
64#else
65constexpr std::int32_t DSOFTBUS_UID = 5533;
66#endif
67}  // namespace
68AccountStub::AccountStub()
69{
70    stubFuncMap_[AccountMgrInterfaceCode::UPDATE_OHOS_ACCOUNT_INFO] =
71        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdUpdateOhosAccountInfo(data, reply); };
72    stubFuncMap_[AccountMgrInterfaceCode::SET_OHOS_ACCOUNT_INFO] =
73        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdSetOhosAccountInfo(data, reply); };
74    stubFuncMap_[AccountMgrInterfaceCode::SET_OHOS_ACCOUNT_INFO_BY_USER_ID] =
75        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdSetOhosAccountInfoByUserId(data, reply); };
76    stubFuncMap_[AccountMgrInterfaceCode::QUERY_OHOS_ACCOUNT_INFO] =
77        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdQueryOhosAccountInfo(data, reply); };
78    stubFuncMap_[AccountMgrInterfaceCode::GET_OHOS_ACCOUNT_INFO] =
79        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetOhosAccountInfo(data, reply); };
80    stubFuncMap_[AccountMgrInterfaceCode::QUERY_OHOS_ACCOUNT_INFO_BY_USER_ID] =
81        [this] (MessageParcel &data, MessageParcel &reply) {
82        return this->CmdQueryOhosAccountInfoByUserId(data, reply);
83    };
84    stubFuncMap_[AccountMgrInterfaceCode::GET_OHOS_ACCOUNT_INFO_BY_USER_ID] =
85        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetOhosAccountInfoByUserId(data, reply); };
86    stubFuncMap_[AccountMgrInterfaceCode::QUERY_DEVICE_ACCOUNT_ID] =
87        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdQueryDeviceAccountId(data, reply); };
88    stubFuncMap_[AccountMgrInterfaceCode::SUBSCRIBE_DISTRIBUTED_ACCOUNT_EVENT] =
89        [this] (MessageParcel &data, MessageParcel &reply) {
90        return this->CmdSubscribeDistributedAccountEvent(data, reply);
91    };
92    stubFuncMap_[AccountMgrInterfaceCode::UNSUBSCRIBE_DISTRIBUTED_ACCOUNT_EVENT] =
93        [this] (MessageParcel &data, MessageParcel &reply) {
94        return this->CmdUnsubscribeDistributedAccountEvent(data, reply);
95    };
96    stubFuncMap_[AccountMgrInterfaceCode::GET_APP_ACCOUNT_SERVICE] =
97        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetAppAccountService(data, reply); };
98    stubFuncMap_[AccountMgrInterfaceCode::GET_OS_ACCOUNT_SERVICE] =
99        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetOsAccountService(data, reply); };
100    stubFuncMap_[AccountMgrInterfaceCode::GET_ACCOUNT_IAM_SERVICE] =
101        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetAccountIAMService(data, reply); };
102    stubFuncMap_[AccountMgrInterfaceCode::GET_DOMAIN_ACCOUNT_SERVICE] =
103        [this] (MessageParcel &data, MessageParcel &reply) { return this->CmdGetDomainAccountService(data, reply); };
104}
105
106std::int32_t AccountStub::InnerUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
107{
108    // ignore the real account name
109    const std::string accountName = Str16ToStr8(data.ReadString16());
110    if (accountName.empty()) {
111        ACCOUNT_LOGE("empty account name!");
112        return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR;
113    }
114    const std::string uid = Str16ToStr8(data.ReadString16());
115    if (uid.empty()) {
116        ACCOUNT_LOGE("empty uid!");
117        return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR;
118    }
119    const std::string eventStr = Str16ToStr8(data.ReadString16());
120
121    std::int32_t ret = ERR_OK;
122    bool result = UpdateOhosAccountInfo(accountName, uid, eventStr);
123    if (!result) {
124        ACCOUNT_LOGE("Update ohos account info failed");
125        ret = ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR;
126    }
127    if (!reply.WriteInt32(ret)) {
128        ACCOUNT_LOGE("Write result data failed");
129        ret = ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
130    }
131    return ret;
132}
133
134std::int32_t AccountStub::InnerSetOhosAccountInfo(int32_t userId, MessageParcel &data, MessageParcel &reply)
135{
136    OhosAccountInfo info;
137    std::int32_t ret = ReadOhosAccountInfo(data, info);
138    if (ret != ERR_OK) {
139        return ret;
140    }
141    if (!info.IsValid()) {
142        ACCOUNT_LOGE("Check OhosAccountInfo failed");
143        return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
144    }
145    // ignore the real account name
146    const std::string eventStr = Str16ToStr8(data.ReadString16());
147
148    if (userId == INVALID_USERID) {
149        userId = AccountMgrService::GetInstance().GetCallingUserID();
150    }
151    ret = SetOhosAccountInfoByUserId(userId, info, eventStr);
152    if (ret != ERR_OK) {
153        ACCOUNT_LOGE("Set ohos account info failed");
154    }
155    if (!reply.WriteInt32(ret)) {
156        ACCOUNT_LOGE("Write result data failed");
157        ret = ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
158    }
159    return ret;
160}
161
162std::int32_t AccountStub::CmdUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
163{
164    if (!HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) {
165        ACCOUNT_LOGE("Check permission failed");
166        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
167    }
168
169    return InnerUpdateOhosAccountInfo(data, reply);
170}
171
172std::int32_t AccountStub::CmdSetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
173{
174    if (!HasAccountRequestPermission(PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS)) {
175        ACCOUNT_LOGE("Check permission failed");
176        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
177    }
178
179    return InnerSetOhosAccountInfo(INVALID_USERID, data, reply);
180}
181
182static int32_t CheckUserIdValid(const int32_t userId)
183{
184    if ((userId >= 0) && (userId < Constants::START_USER_ID)) {
185        ACCOUNT_LOGE("userId %{public}d is system reserved", userId);
186        return ERR_OSACCOUNT_SERVICE_MANAGER_ID_ERROR;
187    }
188    bool isOsAccountExist = false;
189    IInnerOsAccountManager::GetInstance().IsOsAccountExists(userId, isOsAccountExist);
190    if (!isOsAccountExist) {
191        ACCOUNT_LOGE("os account is not exist");
192        return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
193    }
194    return ERR_OK;
195}
196
197std::int32_t AccountStub::CmdSetOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)
198{
199    std::int32_t ret = AccountPermissionManager::CheckSystemApp();
200    if (ret != ERR_OK) {
201        ACCOUNT_LOGE("the caller is not system application, ret = %{public}d.", ret);
202        return ret;
203    }
204    if (!HasAccountRequestPermission(PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS)) {
205        ACCOUNT_LOGE("Check permission failed");
206        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
207    }
208    int32_t userId = data.ReadInt32();
209    ret = CheckUserIdValid(userId);
210    if (ret != ERR_OK) {
211        ACCOUNT_LOGE("CheckUserIdValid failed, ret = %{public}d", ret);
212        return ret;
213    }
214    return InnerSetOhosAccountInfo(userId, data, reply);
215}
216
217std::int32_t AccountStub::InnerQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
218{
219    OhosAccountInfo info;
220#ifdef HICOLLIE_ENABLE
221    int timerId = HiviewDFX::XCollie::GetInstance().SetTimer(
222        TIMER_NAME, RECOVERY_TIMEOUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
223#endif // HICOLLIE_ENABLE
224    ErrCode result = QueryOhosAccountInfo(info);
225    if (result != ERR_OK) {
226        ACCOUNT_LOGE("Query ohos account info failed");
227#ifdef HICOLLIE_ENABLE
228        HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
229#endif // HICOLLIE_ENABLE
230        return result;
231    }
232
233    std::string name = info.name_;
234    std::string id = info.uid_;
235    if (!reply.WriteString16(Str8ToStr16(name))) {
236        ACCOUNT_LOGE("Write name data failed");
237#ifdef HICOLLIE_ENABLE
238        HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
239#endif // HICOLLIE_ENABLE
240        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
241    }
242    if (!reply.WriteString16(Str8ToStr16(id))) {
243        ACCOUNT_LOGE("Write id data failed");
244#ifdef HICOLLIE_ENABLE
245        HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
246#endif // HICOLLIE_ENABLE
247        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
248    }
249    if (!reply.WriteInt32(info.status_)) {
250        ACCOUNT_LOGE("Write status data failed");
251#ifdef HICOLLIE_ENABLE
252        HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
253#endif // HICOLLIE_ENABLE
254        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
255    }
256#ifdef HICOLLIE_ENABLE
257    HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
258#endif // HICOLLIE_ENABLE
259    return ERR_OK;
260}
261
262std::int32_t AccountStub::InnerGetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
263{
264    OhosAccountInfo ohosAccountInfo;
265    int ret = GetOhosAccountInfo(ohosAccountInfo);
266    ohosAccountInfo.SetRawUid("");
267    if (ret != ERR_OK) {
268        ACCOUNT_LOGE("Get ohos account info failed");
269        return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR;
270    }
271    if (!WriteOhosAccountInfo(reply, ohosAccountInfo)) {
272        ACCOUNT_LOGE("Write ohosAccountInfo failed!");
273        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
274    }
275    return ERR_OK;
276}
277
278std::int32_t AccountStub::CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
279{
280    if (!HasAccountRequestPermission(PERMISSION_MANAGE_USERS) &&
281        !HasAccountRequestPermission(PERMISSION_DISTRIBUTED_DATASYNC) &&
282        !HasAccountRequestPermission(PERMISSION_GET_LOCAL_ACCOUNTS)) {
283        ACCOUNT_LOGE("Check permission failed");
284        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
285    }
286
287    return InnerQueryOhosAccountInfo(data, reply);
288}
289
290ErrCode AccountStub::CmdGetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
291{
292    if (!HasAccountRequestPermission(PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS) &&
293        !HasAccountRequestPermission(PERMISSION_DISTRIBUTED_DATASYNC) &&
294        !HasAccountRequestPermission(PERMISSION_GET_DISTRIBUTED_ACCOUNTS)) {
295        ACCOUNT_LOGE("Check permission failed");
296        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
297    }
298
299    return InnerGetOhosAccountInfo(data, reply);
300}
301
302ErrCode AccountStub::CmdGetOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)
303{
304    ErrCode errCode = AccountPermissionManager::CheckSystemApp();
305    if (errCode != ERR_OK) {
306        ACCOUNT_LOGE("the caller is not system application, errCode = %{public}d.", errCode);
307        return errCode;
308    }
309    if (!HasAccountRequestPermission(PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS) &&
310        !HasAccountRequestPermission(INTERACT_ACROSS_LOCAL_ACCOUNTS) &&
311        !HasAccountRequestPermission(PERMISSION_DISTRIBUTED_DATASYNC) &&
312        !HasAccountRequestPermission(PERMISSION_GET_DISTRIBUTED_ACCOUNTS)) {
313        ACCOUNT_LOGE("Check permission failed");
314        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
315    }
316    int32_t userId = data.ReadInt32();
317    bool isOsAccountExits = false;
318    errCode = IInnerOsAccountManager::GetInstance().IsOsAccountExists(userId, isOsAccountExits);
319    if (errCode != ERR_OK) {
320        ACCOUNT_LOGE("IsOsAccountExists failed errCode is %{public}d", errCode);
321        return errCode;
322    }
323    if (!isOsAccountExits) {
324        ACCOUNT_LOGE("os account is not exit");
325        return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
326    }
327    OhosAccountInfo ohosAccountInfo;
328    errCode = GetOhosAccountInfoByUserId(userId, ohosAccountInfo);
329    if (errCode != ERR_OK) {
330        ACCOUNT_LOGE("Get ohos account info failed");
331        return errCode;
332    }
333    int32_t uid = IPCSkeleton::GetCallingUid();
334    if (WHITE_LIST.find(uid) == WHITE_LIST.end()) {
335        ohosAccountInfo.SetRawUid("");
336    }
337    if (!WriteOhosAccountInfo(reply, ohosAccountInfo)) {
338        ACCOUNT_LOGE("Write ohosAccountInfo failed!");
339        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
340    }
341    return ERR_OK;
342}
343
344std::int32_t AccountStub::CmdQueryOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)
345{
346    if ((!HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) &&
347        (!HasAccountRequestPermission(PERMISSION_DISTRIBUTED_DATASYNC)) &&
348        (IPCSkeleton::GetCallingUid() != DSOFTBUS_UID)) {
349        ACCOUNT_LOGE("Check permission failed");
350        return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
351    }
352
353    std::int32_t userId = data.ReadInt32();
354    if (userId < 0) {
355        ACCOUNT_LOGE("negative userID %{public}d detected!", userId);
356        return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_USERID_ERROR;
357    }
358
359    OhosAccountInfo info;
360    ErrCode result = QueryOhosAccountInfoByUserId(userId, info);
361    if (result != ERR_OK) {
362        ACCOUNT_LOGE("Query ohos account info failed! userId %{public}d.", userId);
363        return result;
364    }
365
366    std::string name = info.name_;
367    std::string id = info.uid_;
368    if (!reply.WriteString16(Str8ToStr16(name))) {
369        ACCOUNT_LOGE("Write name data failed! userId %{public}d.", userId);
370        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
371    }
372    if (!reply.WriteString16(Str8ToStr16(id))) {
373        ACCOUNT_LOGE("Write id data failed! userId %{public}d.", userId);
374        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
375    }
376    if (!reply.WriteInt32(info.status_)) {
377        ACCOUNT_LOGE("Write status data failed! userId %{public}d.", userId);
378        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
379    }
380    return ERR_OK;
381}
382
383std::int32_t AccountStub::CmdQueryDeviceAccountId(MessageParcel &data, MessageParcel &reply)
384{
385    std::int32_t id;
386    auto ret = QueryDeviceAccountId(id);
387    if (ret != ERR_OK) {
388        ACCOUNT_LOGE("QueryDevice AccountId failed: %{public}d", ret);
389        return ret;
390    }
391
392    if (!reply.WriteInt32(id)) {
393        ACCOUNT_LOGE("Write result data failed");
394        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
395    }
396    return ERR_OK;
397}
398
399std::int32_t AccountStub::CmdSubscribeDistributedAccountEvent(MessageParcel &data, MessageParcel &reply)
400{
401    int32_t type;
402    if (!data.ReadInt32(type)) {
403        ACCOUNT_LOGE("Read type failed.");
404        return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
405    }
406
407    sptr<IRemoteObject> eventListener = data.ReadRemoteObject();
408    if (eventListener == nullptr) {
409        ACCOUNT_LOGE("Read remote object for eventListener failed.");
410        return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
411    }
412
413    ErrCode result = SubscribeDistributedAccountEvent(
414        static_cast<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE>(type), eventListener);
415    if (!reply.WriteInt32(result)) {
416        ACCOUNT_LOGE("Write reply failed, result=%{public}d.", result);
417        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
418    }
419
420    return ERR_OK;
421}
422
423std::int32_t AccountStub::CmdUnsubscribeDistributedAccountEvent(MessageParcel &data, MessageParcel &reply)
424{
425    int32_t type;
426    if (!data.ReadInt32(type)) {
427        ACCOUNT_LOGE("Read type failed.");
428        return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
429    }
430
431    sptr<IRemoteObject> eventListener = data.ReadRemoteObject();
432    if (eventListener == nullptr) {
433        ACCOUNT_LOGE("Read remote object for eventListener failed.");
434        return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
435    }
436
437    ErrCode result = UnsubscribeDistributedAccountEvent(
438        static_cast<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE>(type), eventListener);
439    if (!reply.WriteInt32(result)) {
440        ACCOUNT_LOGE("Write reply failed, result=%{public}d.", result);
441        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
442    }
443
444    return ERR_OK;
445}
446
447std::int32_t AccountStub::CmdGetAppAccountService(MessageParcel &data, MessageParcel &reply)
448{
449    auto remoteObject = GetAppAccountService();
450    if (!reply.WriteRemoteObject(remoteObject)) {
451        ACCOUNT_LOGE("Write result data failed");
452        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
453    }
454
455    return ERR_OK;
456}
457std::int32_t AccountStub::CmdGetOsAccountService(MessageParcel &data, MessageParcel &reply)
458{
459    auto remoteObject = GetOsAccountService();
460    if (!reply.WriteRemoteObject(remoteObject)) {
461        ACCOUNT_LOGE("Write result data failed");
462        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
463    }
464
465    return ERR_OK;
466}
467
468std::int32_t AccountStub::CmdGetAccountIAMService(MessageParcel &data, MessageParcel &reply)
469{
470    auto remoteObject = GetAccountIAMService();
471    if (!reply.WriteRemoteObject(remoteObject)) {
472        ACCOUNT_LOGE("Write result data failed");
473        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
474    }
475
476    return ERR_OK;
477}
478
479std::int32_t AccountStub::CmdGetDomainAccountService(MessageParcel &data, MessageParcel &reply)
480{
481    auto remoteObject = GetDomainAccountService();
482    if (!reply.WriteRemoteObject(remoteObject)) {
483        ACCOUNT_LOGE("failed to write remote object");
484        return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
485    }
486    return ERR_OK;
487}
488
489std::int32_t AccountStub::OnRemoteRequest(
490    std::uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
491{
492    ACCOUNT_LOGD("Received stub message: %{public}d, callingUid: %{public}d", code, IPCSkeleton::GetCallingUid());
493    MemoryGuard cacheGuard;
494    if (!IsServiceStarted()) {
495        ACCOUNT_LOGE("account mgr not ready");
496        return ERR_ACCOUNT_ZIDL_MGR_NOT_READY_ERROR;
497    }
498
499    if (data.ReadInterfaceToken() != GetDescriptor()) {
500        ACCOUNT_LOGE("check descriptor failed! code %{public}u.", code);
501        return ERR_ACCOUNT_COMMON_CHECK_DESCRIPTOR_ERROR;
502    }
503
504#ifdef HICOLLIE_ENABLE
505    int timerId =
506        HiviewDFX::XCollie::GetInstance().SetTimer(TIMER_NAME, TIMEOUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
507#endif // HICOLLIE_ENABLE
508
509    AccountMgrInterfaceCode interfaceCode = static_cast<AccountMgrInterfaceCode>(code);
510    const auto &itFunc = stubFuncMap_.find(interfaceCode);
511    if (itFunc == stubFuncMap_.end()) {
512#ifdef HICOLLIE_ENABLE
513        HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
514#endif // HICOLLIE_ENABLE
515        ACCOUNT_LOGW("remote request unhandled: %{public}d", code);
516        return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
517    }
518    int32_t ret = (itFunc->second)(data, reply);
519#ifdef HICOLLIE_ENABLE
520    HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
521#endif // HICOLLIE_ENABLE
522    return ret;
523}
524
525bool AccountStub::HasAccountRequestPermission(const std::string &permissionName)
526{
527    std::int32_t uid = IPCSkeleton::GetCallingUid();
528#ifndef IS_RELEASE_VERSION
529    // root check in none release version for test
530    if (uid == ROOT_UID) {
531        return true;
532    }
533#endif
534
535    // check permission
536    Security::AccessToken::AccessTokenID callingTokenID = IPCSkeleton::GetCallingTokenID();
537    if (Security::AccessToken::AccessTokenKit::VerifyAccessToken(callingTokenID, permissionName) ==
538        Security::AccessToken::TypePermissionState::PERMISSION_GRANTED) {
539        return true;
540    }
541
542    ReportPermissionFail(uid, IPCSkeleton::GetCallingRealPid(), permissionName);
543    ACCOUNT_LOGE("permission %{public}s denied!", permissionName.c_str());
544    return false;
545}
546}  // namespace AccountSA
547}  // namespace OHOS
548