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 
39 namespace OHOS {
40 namespace AccountSA {
41 namespace {
42 const std::string OHOS_ACCOUNT_QUIT_TIPS_TITLE = "";
43 const std::string OHOS_ACCOUNT_QUIT_TIPS_CONTENT = "";
44 const std::string PERMISSION_MANAGE_USERS = "ohos.permission.MANAGE_LOCAL_ACCOUNTS";
45 const std::string PERMISSION_GET_LOCAL_ACCOUNTS = "ohos.permission.GET_LOCAL_ACCOUNTS";
46 const std::string PERMISSION_MANAGE_DISTRIBUTED_ACCOUNTS = "ohos.permission.MANAGE_DISTRIBUTED_ACCOUNTS";
47 const std::string PERMISSION_GET_DISTRIBUTED_ACCOUNTS = "ohos.permission.GET_DISTRIBUTED_ACCOUNTS";
48 const std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
49 const std::string INTERACT_ACROSS_LOCAL_ACCOUNTS = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS";
50 #ifndef IS_RELEASE_VERSION
51 constexpr std::int32_t ROOT_UID = 0;
52 #endif
53 #ifdef HICOLLIE_ENABLE
54 constexpr std::int32_t RECOVERY_TIMEOUT = 6; // timeout 6s
55 #endif // HICOLLIE_ENABLE
56 constexpr std::int32_t INVALID_USERID = -1;
57 const 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
63 constexpr std::int32_t DSOFTBUS_UID = 1024;
64 #else
65 constexpr std::int32_t DSOFTBUS_UID = 5533;
66 #endif
67 }  // namespace
AccountStub()68 AccountStub::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 
InnerUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply)106 std::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 
InnerSetOhosAccountInfo(int32_t userId, MessageParcel &data, MessageParcel &reply)134 std::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 
CmdUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply)162 std::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 
CmdSetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)172 std::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 
CheckUserIdValid(const int32_t userId)182 static 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 
CmdSetOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)197 std::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 
InnerQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply)217 std::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 
InnerGetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)262 std::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 
CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply)278 std::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 
CmdGetOhosAccountInfo(MessageParcel &data, MessageParcel &reply)290 ErrCode 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 
CmdGetOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)302 ErrCode 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 
CmdQueryOhosAccountInfoByUserId(MessageParcel &data, MessageParcel &reply)344 std::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 
CmdQueryDeviceAccountId(MessageParcel &data, MessageParcel &reply)383 std::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 
CmdSubscribeDistributedAccountEvent(MessageParcel &data, MessageParcel &reply)399 std::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 
CmdUnsubscribeDistributedAccountEvent(MessageParcel &data, MessageParcel &reply)423 std::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 
CmdGetAppAccountService(MessageParcel &data, MessageParcel &reply)447 std::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 }
CmdGetOsAccountService(MessageParcel &data, MessageParcel &reply)457 std::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 
CmdGetAccountIAMService(MessageParcel &data, MessageParcel &reply)468 std::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 
CmdGetDomainAccountService(MessageParcel &data, MessageParcel &reply)479 std::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 
OnRemoteRequest( std::uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)489 std::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 
HasAccountRequestPermission(const std::string &permissionName)525 bool 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