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