• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "user_idm_service.h"
17 
18 #include "string_ex.h"
19 #include "accesstoken_kit.h"
20 
21 #include "context_appstate_observer.h"
22 #include "context_helper.h"
23 #include "context_pool.h"
24 #include "hdi_wrapper.h"
25 #include "iam_check.h"
26 #include "iam_logger.h"
27 #include "iam_para2str.h"
28 #include "iam_defines.h"
29 #include "iam_time.h"
30 #include "ipc_common.h"
31 #include "ipc_skeleton.h"
32 #include "iam_common_defines.h"
33 #include "load_mode_handler.h"
34 #include "publish_event_adapter.h"
35 #include "resource_node_pool.h"
36 #include "resource_node_utils.h"
37 #include "service_init_manager.h"
38 #include "user_idm_callback_proxy.h"
39 #include "user_idm_database.h"
40 #include "user_idm_session_controller.h"
41 #include "xcollie_helper.h"
42 
43 #define LOG_TAG "USER_AUTH_SA"
44 
45 namespace OHOS {
46 namespace UserIam {
47 namespace UserAuth {
48 REGISTER_SYSTEM_ABILITY_BY_ID(UserIdmService, SUBSYS_USERIAM_SYS_ABILITY_USERIDM, true);
49 constexpr int32_t USERIAM_IPC_THREAD_NUM = 4;
UserIdmService(int32_t systemAbilityId,bool runOnCreate)50 UserIdmService::UserIdmService(int32_t systemAbilityId, bool runOnCreate) : SystemAbility(systemAbilityId, runOnCreate)
51 {
52 }
53 
OnStart()54 void UserIdmService::OnStart()
55 {
56     IAM_LOGI("Sa start UserIdmService");
57     IPCSkeleton::SetMaxWorkThreadNum(USERIAM_IPC_THREAD_NUM);
58     if (!Publish(this)) {
59         IAM_LOGE("failed to publish service");
60     }
61     ServiceInitManager::GetInstance().OnIdmServiceStart();
62 }
63 
OnStop()64 void UserIdmService::OnStop()
65 {
66     IAM_LOGI("Sa stop UserIdmService");
67     ServiceInitManager::GetInstance().OnIdmServiceStop();
68 }
69 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)70 int32_t UserIdmService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
71 {
72     IAM_LOGI("start");
73     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
74     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
75         IAM_LOGE("failed to check permission");
76         return CHECK_PERMISSION_FAILED;
77     }
78 
79     auto contextList = ContextPool::Instance().Select(CONTEXT_ENROLL);
80     for (const auto &context : contextList) {
81         if (auto ctx = context.lock(); ctx != nullptr) {
82             IAM_LOGE("force stop the old context ****%{public}hx", static_cast<uint16_t>(ctx->GetContextId()));
83             ctx->Stop();
84             ContextPool::Instance().Delete(ctx->GetContextId());
85         }
86     }
87 
88     if (!UserIdmSessionController::Instance().OpenSession(userId, challenge)) {
89         IAM_LOGE("failed to open session");
90         return GENERAL_ERROR;
91     }
92 
93     return SUCCESS;
94 }
95 
CloseSession(int32_t userId)96 void UserIdmService::CloseSession(int32_t userId)
97 {
98     IAM_LOGI("start");
99     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
100     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
101         IAM_LOGE("failed to check permission");
102         return;
103     }
104 
105     if (!UserIdmSessionController::Instance().CloseSession(userId)) {
106         IAM_LOGE("failed to get close session");
107     }
108 }
109 
GetCredentialInfoInner(int32_t userId,AuthType authType,std::vector<CredentialInfo> & credInfoList)110 int32_t UserIdmService::GetCredentialInfoInner(int32_t userId, AuthType authType,
111     std::vector<CredentialInfo> &credInfoList)
112 {
113     IAM_LOGI("start");
114     if (!IpcCommon::CheckPermission(*this, USE_USER_IDM_PERMISSION)) {
115         IAM_LOGE("failed to check permission");
116         return CHECK_PERMISSION_FAILED;
117     }
118 
119     std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
120     int32_t ret = UserIdmDatabase::Instance().GetCredentialInfo(userId, authType, credInfos);
121     if (ret != SUCCESS) {
122         IAM_LOGE("get credential fail, ret:%{public}d, userId:%{public}d, authType:%{public}d", ret,
123             userId, authType);
124         return GENERAL_ERROR;
125     }
126 
127     if (credInfos.empty()) {
128         IAM_LOGE("no cred enrolled");
129         return NOT_ENROLLED;
130     }
131     for (const auto &credInfo : credInfos) {
132         if (credInfo == nullptr) {
133             IAM_LOGE("credInfo is nullptr");
134             return GENERAL_ERROR;
135         }
136         CredentialInfo info = {};
137         info.credentialId = credInfo->GetCredentialId();
138         info.templateId = credInfo->GetTemplateId();
139         info.authType = credInfo->GetAuthType();
140         info.pinType = credInfo->GetAuthSubType();
141         credInfoList.push_back(info);
142     }
143     return SUCCESS;
144 }
145 
GetCredentialInfo(int32_t userId,AuthType authType,const sptr<IdmGetCredInfoCallbackInterface> & callback)146 int32_t UserIdmService::GetCredentialInfo(int32_t userId, AuthType authType,
147     const sptr<IdmGetCredInfoCallbackInterface> &callback)
148 {
149     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
150     if (callback == nullptr) {
151         IAM_LOGE("callback is nullptr");
152         return INVALID_PARAMETERS;
153     }
154 
155     std::vector<CredentialInfo> credInfoList;
156     int32_t ret = GetCredentialInfoInner(userId, authType, credInfoList);
157     if (ret != SUCCESS) {
158         IAM_LOGE("GetCredentialInfoInner fail, ret: %{public}d", ret);
159         credInfoList.clear();
160     }
161     callback->OnCredentialInfos(ret, credInfoList);
162 
163     return ret;
164 }
165 
GetSecInfoInner(int32_t userId,SecUserInfo & secUserInfo)166 int32_t UserIdmService::GetSecInfoInner(int32_t userId, SecUserInfo &secUserInfo)
167 {
168     IAM_LOGI("start");
169     if (!IpcCommon::CheckPermission(*this, USE_USER_IDM_PERMISSION)) {
170         IAM_LOGE("failed to check permission");
171         return CHECK_PERMISSION_FAILED;
172     }
173     std::shared_ptr<SecureUserInfoInterface> userInfos = nullptr;
174     int32_t ret = UserIdmDatabase::Instance().GetSecUserInfo(userId, userInfos);
175     if (ret != SUCCESS) {
176         IAM_LOGE("get secUserInfo fail, ret:%{public}d, userId:%{public}d", ret, userId);
177         return ret;
178     }
179     if (userInfos == nullptr) {
180         IAM_LOGE("current userid %{public}d is not existed", userId);
181         return GENERAL_ERROR;
182     }
183     std::vector<std::shared_ptr<EnrolledInfoInterface>> enrolledInfos = userInfos->GetEnrolledInfo();
184     for (const auto &enrolledInfo : enrolledInfos) {
185         if (enrolledInfo == nullptr) {
186             IAM_LOGE("enrolledInfo is nullptr");
187             return GENERAL_ERROR;
188         }
189         EnrolledInfo info = {enrolledInfo->GetAuthType(), enrolledInfo->GetEnrolledId()};
190         secUserInfo.enrolledInfo.push_back(info);
191     }
192     secUserInfo.secureUid = userInfos->GetSecUserId();
193     return SUCCESS;
194 }
195 
GetSecInfo(int32_t userId,const sptr<IdmGetSecureUserInfoCallbackInterface> & callback)196 int32_t UserIdmService::GetSecInfo(int32_t userId, const sptr<IdmGetSecureUserInfoCallbackInterface> &callback)
197 {
198     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
199     if (callback == nullptr) {
200         IAM_LOGE("callback is nullptr");
201         return INVALID_PARAMETERS;
202     }
203 
204     SecUserInfo secUserInfo = {};
205     int32_t ret = GetSecInfoInner(userId, secUserInfo);
206     if (ret != SUCCESS) {
207         IAM_LOGE("GetSecInfoInner fail, ret: %{public}d", ret);
208         secUserInfo.secureUid = 0;
209         secUserInfo.enrolledInfo.clear();
210     }
211     callback->OnSecureUserInfo(ret, secUserInfo);
212 
213     return ret;
214 }
215 
StartEnroll(Enrollment::EnrollmentPara & para,const std::shared_ptr<ContextCallback> & contextCallback,Attributes & extraInfo,bool needSubscribeAppState)216 void UserIdmService::StartEnroll(Enrollment::EnrollmentPara &para,
217     const std::shared_ptr<ContextCallback> &contextCallback, Attributes &extraInfo, bool needSubscribeAppState)
218 {
219     auto context = ContextFactory::CreateEnrollContext(para, contextCallback, needSubscribeAppState);
220     if (context == nullptr || !ContextPool::Instance().Insert(context)) {
221         IAM_LOGE("failed to insert context");
222         contextCallback->OnResult(GENERAL_ERROR, extraInfo);
223         return;
224     }
225     contextCallback->SetTraceRequestContextId(context->GetContextId());
226     auto cleaner = ContextHelper::Cleaner(context);
227     contextCallback->SetCleaner(cleaner);
228 
229     if (!context->Start()) {
230         IAM_LOGE("failed to start enroll");
231         contextCallback->OnResult(context->GetLatestError(), extraInfo);
232     }
233 }
234 
AddCredential(int32_t userId,const CredentialPara & credPara,const sptr<IdmCallbackInterface> & callback,bool isUpdate)235 void UserIdmService::AddCredential(int32_t userId, const CredentialPara &credPara,
236     const sptr<IdmCallbackInterface> &callback, bool isUpdate)
237 {
238     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
239     IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
240 
241     Attributes extraInfo;
242     auto contextCallback = ContextCallback::NewInstance(callback,
243         isUpdate ? TRACE_UPDATE_CREDENTIAL : TRACE_ADD_CREDENTIAL);
244     if (contextCallback == nullptr) {
245         IAM_LOGE("failed to construct context callback");
246         callback->OnResult(GENERAL_ERROR, extraInfo);
247         return;
248     }
249     std::string callerName = "";
250     int32_t callerType = Security::AccessToken::TOKEN_INVALID;
251     static_cast<void>(IpcCommon::GetCallerName(*this, callerName, callerType));
252     contextCallback->SetTraceCallerName(callerName);
253     contextCallback->SetTraceCallerType(callerType);
254     contextCallback->SetTraceUserId(userId);
255     contextCallback->SetTraceAuthType(credPara.authType);
256     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
257         IAM_LOGE("failed to check permission");
258         contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
259         return;
260     }
261 
262     std::lock_guard<std::mutex> lock(mutex_);
263     CancelCurrentEnrollIfExist();
264     Enrollment::EnrollmentPara para = {};
265     para.authType = credPara.authType;
266     para.userId = userId;
267     para.pinType = credPara.pinType;
268     para.tokenId = IpcCommon::GetAccessTokenId(*this);
269     para.token = credPara.token;
270     para.isUpdate = isUpdate;
271     para.sdkVersion = INNER_API_VERSION_10000;
272     para.callerName = callerName;
273     para.callerType = callerType;
274     bool needSubscribeAppState = !IpcCommon::CheckPermission(*this, USER_AUTH_FROM_BACKGROUND);
275     StartEnroll(para, contextCallback, extraInfo, needSubscribeAppState);
276 }
277 
UpdateCredential(int32_t userId,const CredentialPara & credPara,const sptr<IdmCallbackInterface> & callback)278 void UserIdmService::UpdateCredential(int32_t userId, const CredentialPara &credPara,
279     const sptr<IdmCallbackInterface> &callback)
280 {
281     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
282     if (callback == nullptr) {
283         IAM_LOGE("callback is nullptr");
284         return;
285     }
286 
287     std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
288     int32_t ret = UserIdmDatabase::Instance().GetCredentialInfo(userId, credPara.authType, credInfos);
289     if (ret != SUCCESS) {
290         IAM_LOGE("get credential fail, ret:%{public}d, userId:%{public}d, authType:%{public}d", ret,
291             userId, credPara.authType);
292         Attributes extraInfo;
293         callback->OnResult(GENERAL_ERROR, extraInfo);
294         return;
295     }
296 
297     if (credInfos.empty()) {
298         IAM_LOGE("current userid %{public}d has no credential for type %{public}u", userId, credPara.authType);
299         Attributes extraInfo;
300         callback->OnResult(NOT_ENROLLED, extraInfo);
301         return;
302     }
303 
304     AddCredential(userId, credPara, callback, true);
305 }
306 
Cancel(int32_t userId)307 int32_t UserIdmService::Cancel(int32_t userId)
308 {
309     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
310     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
311         IAM_LOGE("failed to check permission");
312         return CHECK_PERMISSION_FAILED;
313     }
314     if (!UserIdmSessionController::Instance().IsSessionOpened(userId)) {
315         IAM_LOGE("both user id and challenge are invalid");
316         return GENERAL_ERROR;
317     }
318 
319     std::lock_guard<std::mutex> lock(mutex_);
320     return CancelCurrentEnroll();
321 }
322 
CancelCurrentEnrollIfExist()323 void UserIdmService::CancelCurrentEnrollIfExist()
324 {
325     if (ContextPool::Instance().Select(CONTEXT_ENROLL).size() == 0) {
326         return;
327     }
328 
329     IAM_LOGI("cancel current enroll due to new add credential request or delete");
330     CancelCurrentEnroll();
331 }
332 
CancelCurrentEnroll()333 int32_t UserIdmService::CancelCurrentEnroll()
334 {
335     IAM_LOGD("start");
336     auto contextList = ContextPool::Instance().Select(CONTEXT_ENROLL);
337     int32_t ret = GENERAL_ERROR;
338     for (const auto &context : contextList) {
339         if (auto ctx = context.lock(); ctx != nullptr) {
340             IAM_LOGI("stop the old context %{public}s", GET_MASKED_STRING(ctx->GetContextId()).c_str());
341             ctx->Stop();
342             ContextPool::Instance().Delete(ctx->GetContextId());
343             ret = SUCCESS;
344         }
345     }
346     IAM_LOGI("result %{public}d", ret);
347     return ret;
348 }
349 
EnforceDelUser(int32_t userId,const sptr<IdmCallbackInterface> & callback)350 int32_t UserIdmService::EnforceDelUser(int32_t userId, const sptr<IdmCallbackInterface> &callback)
351 {
352     IAM_LOGI("to delete userid: %{public}d", userId);
353     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
354     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, INVALID_PARAMETERS);
355 
356     Attributes extraInfo;
357     auto contextCallback = ContextCallback::NewInstance(callback, TRACE_ENFORCE_DELETE_USER);
358     if (contextCallback == nullptr) {
359         IAM_LOGE("failed to construct context callback");
360         callback->OnResult(GENERAL_ERROR, extraInfo);
361         return GENERAL_ERROR;
362     }
363     std::string callerName = "";
364     int32_t callerType = Security::AccessToken::TOKEN_INVALID;
365     static_cast<void>(IpcCommon::GetCallerName(*this, callerName, callerType));
366     contextCallback->SetTraceCallerType(callerType);
367     contextCallback->SetTraceCallerName(callerName);
368     contextCallback->SetTraceUserId(userId);
369 
370     if (!IpcCommon::CheckPermission(*this, ENFORCE_USER_IDM)) {
371         IAM_LOGE("failed to check permission");
372         contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
373         return CHECK_PERMISSION_FAILED;
374     }
375 
376     std::lock_guard<std::mutex> lock(mutex_);
377     CancelCurrentEnrollIfExist();
378     std::shared_ptr<SecureUserInfoInterface> userInfo = nullptr;
379     int32_t ret = UserIdmDatabase::Instance().GetSecUserInfo(userId, userInfo);
380     if (ret != SUCCESS) {
381         IAM_LOGE("get secUserInfo fail, ret:%{public}d, userId:%{public}d", ret, userId);
382         contextCallback->OnResult(ret, extraInfo);
383         return ret;
384     }
385     if (userInfo == nullptr) {
386         IAM_LOGE("current userid %{public}d is not existed", userId);
387         contextCallback->OnResult(GENERAL_ERROR, extraInfo);
388         return GENERAL_ERROR;
389     }
390     ret = EnforceDelUserInner(userId, contextCallback, "EnforceDeleteUser");
391     if (ret != SUCCESS) {
392         IAM_LOGE("failed to enforce delete user");
393         static_cast<void>(extraInfo.SetUint64Value(Attributes::ATTR_CREDENTIAL_ID, 0));
394         contextCallback->OnResult(ret, extraInfo);
395         return ret;
396     }
397 
398     IAM_LOGI("delete user success");
399     contextCallback->OnResult(SUCCESS, extraInfo);
400     return SUCCESS;
401 }
402 
DelUser(int32_t userId,const std::vector<uint8_t> authToken,const sptr<IdmCallbackInterface> & callback)403 void UserIdmService::DelUser(int32_t userId, const std::vector<uint8_t> authToken,
404     const sptr<IdmCallbackInterface> &callback)
405 {
406     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
407     IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
408 
409     Attributes extraInfo;
410     auto contextCallback = ContextCallback::NewInstance(callback, TRACE_DELETE_USER);
411     if (contextCallback == nullptr) {
412         IAM_LOGE("failed to construct context callback");
413         callback->OnResult(GENERAL_ERROR, extraInfo);
414         return;
415     }
416     std::string callerName = "";
417     int32_t callerType = Security::AccessToken::TOKEN_INVALID;
418     static_cast<void>(IpcCommon::GetCallerName(*this, callerName, callerType));
419     contextCallback->SetTraceCallerName(callerName);
420     contextCallback->SetTraceCallerType(callerType);
421     contextCallback->SetTraceUserId(userId);
422 
423     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
424         IAM_LOGE("failed to check permission");
425         contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
426         return;
427     }
428 
429     std::lock_guard<std::mutex> lock(mutex_);
430     CancelCurrentEnrollIfExist();
431 
432     std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
433     std::vector<uint8_t> rootSecret;
434     int32_t ret = UserIdmDatabase::Instance().DeleteUser(userId, authToken, credInfos, rootSecret);
435     if (ret != SUCCESS) {
436         IAM_LOGE("failed to delete user");
437         contextCallback->OnResult(ret, extraInfo);
438         return;
439     }
440     ContextAppStateObserverManager::GetInstance().RemoveScreenLockState(userId);
441     if (!extraInfo.SetUint8ArrayValue(Attributes::ATTR_OLD_ROOT_SECRET, rootSecret)) {
442         IAM_LOGE("set rootsecret to extraInfo failed");
443         contextCallback->OnResult(ret, extraInfo);
444         return;
445     }
446     SetAuthTypeTrace(credInfos, contextCallback);
447     contextCallback->OnResult(ret, extraInfo);
448 
449     ret = ResourceNodeUtils::NotifyExecutorToDeleteTemplates(credInfos, "DeleteUser");
450     if (ret != SUCCESS) {
451         IAM_LOGE("failed to delete executor info, error code : %{public}d", ret);
452     }
453     IAM_LOGI("delete user end");
454     PublishEventAdapter::GetInstance().PublishDeletedEvent(userId);
455     PublishEventAdapter::GetInstance().PublishCredentialUpdatedEvent(userId, PIN, 0);
456 }
457 
DelCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const sptr<IdmCallbackInterface> & callback)458 void UserIdmService::DelCredential(int32_t userId, uint64_t credentialId,
459     const std::vector<uint8_t> &authToken, const sptr<IdmCallbackInterface> &callback)
460 {
461     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
462     IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
463 
464     Attributes extraInfo;
465     auto contextCallback = ContextCallback::NewInstance(callback, TRACE_DELETE_CREDENTIAL);
466     if (contextCallback == nullptr) {
467         IAM_LOGE("failed to construct context callback");
468         callback->OnResult(GENERAL_ERROR, extraInfo);
469         return;
470     }
471     std::string callerName = "";
472     int32_t callerType = Security::AccessToken::TOKEN_INVALID;
473     static_cast<void>(IpcCommon::GetCallerName(*this, callerName, callerType));
474     contextCallback->SetTraceCallerName(callerName);
475     contextCallback->SetTraceCallerType(callerType);
476     contextCallback->SetTraceUserId(userId);
477 
478     if (!IpcCommon::CheckPermission(*this, MANAGE_USER_IDM_PERMISSION)) {
479         IAM_LOGE("failed to check permission");
480         contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
481         return;
482     }
483 
484     std::lock_guard<std::mutex> lock(mutex_);
485     CancelCurrentEnrollIfExist();
486 
487     std::shared_ptr<CredentialInfoInterface> oldInfo;
488     auto ret = UserIdmDatabase::Instance().DeleteCredentialInfo(userId, credentialId, authToken, oldInfo);
489     if (ret != SUCCESS) {
490         IAM_LOGE("failed to delete CredentialInfo");
491         contextCallback->OnResult(ret, extraInfo);
492         return;
493     }
494     if (oldInfo != nullptr) {
495         contextCallback->SetTraceAuthType(oldInfo->GetAuthType());
496     }
497 
498     IAM_LOGI("delete credentialInfo success");
499     std::vector<std::shared_ptr<CredentialInfoInterface>> list = {oldInfo};
500     ret = ResourceNodeUtils::NotifyExecutorToDeleteTemplates(list, "DeleteTemplate");
501     if (ret != SUCCESS) {
502         IAM_LOGE("failed to delete executor info, error code : %{public}d", ret);
503     }
504 
505     contextCallback->OnResult(ret, extraInfo);
506     if (oldInfo != nullptr) {
507         PublishCommonEvent(userId, credentialId, oldInfo->GetAuthType());
508     }
509 }
510 
Dump(int fd,const std::vector<std::u16string> & args)511 int UserIdmService::Dump(int fd, const std::vector<std::u16string> &args)
512 {
513     IAM_LOGI("start");
514     if (fd < 0) {
515         IAM_LOGE("invalid parameters");
516         return INVALID_PARAMETERS;
517     }
518     std::string arg0 = (args.empty() ? "" : Str16ToStr8(args[0]));
519     if (arg0.empty() || arg0.compare("-h") == 0) {
520         dprintf(fd, "Usage:\n");
521         dprintf(fd, "      -h: command help.\n");
522         dprintf(fd, "      -l: active user info dump.\n");
523         return SUCCESS;
524     }
525     if (arg0.compare("-l") != 0) {
526         IAM_LOGE("invalid option");
527         dprintf(fd, "Invalid option\n");
528         return GENERAL_ERROR;
529     }
530 
531     std::optional<int32_t> activeUserId;
532     if (IpcCommon::GetActiveUserId(activeUserId) != SUCCESS) {
533         dprintf(fd, "Internal error.\n");
534         IAM_LOGE("failed to get active id");
535         return GENERAL_ERROR;
536     }
537     dprintf(fd, "Active user is %d\n", activeUserId.value());
538     std::shared_ptr<SecureUserInfoInterface> userInfo = nullptr;
539     int32_t ret = UserIdmDatabase::Instance().GetSecUserInfo(activeUserId.value(), userInfo);
540     if (ret != SUCCESS) {
541         IAM_LOGE("get secUserInfo fail, ret:%{public}d, userId:%{public}d", ret, activeUserId.value());
542         return GENERAL_ERROR;
543     }
544     if (userInfo == nullptr) {
545         IAM_LOGE("userInfo is null");
546         return SUCCESS;
547     }
548     auto enrolledInfo = userInfo->GetEnrolledInfo();
549     for (auto &info : enrolledInfo) {
550         if (info != nullptr) {
551             dprintf(fd, "AuthType %s is enrolled.\n", Common::AuthTypeToStr(info->GetAuthType()));
552         }
553     }
554     return SUCCESS;
555 }
556 
SetAuthTypeTrace(const std::vector<std::shared_ptr<CredentialInfoInterface>> & credInfos,const std::shared_ptr<ContextCallback> & contextCallback)557 void UserIdmService::SetAuthTypeTrace(const std::vector<std::shared_ptr<CredentialInfoInterface>> &credInfos,
558     const std::shared_ptr<ContextCallback> &contextCallback)
559 {
560     uint32_t authTypeTrace = 0;
561     for (const auto &credInfo : credInfos) {
562         if (credInfo == nullptr) {
563             IAM_LOGE("credInfo is nullptr");
564             continue;
565         }
566         authTypeTrace |= static_cast<uint32_t>(credInfo->GetAuthType());
567     }
568     contextCallback->SetTraceAuthType(static_cast<int32_t>(authTypeTrace));
569 }
570 
EnforceDelUserInner(int32_t userId,std::shared_ptr<ContextCallback> callbackForTrace,std::string changeReasonTrace)571 int32_t UserIdmService::EnforceDelUserInner(int32_t userId, std::shared_ptr<ContextCallback> callbackForTrace,
572     std::string changeReasonTrace)
573 {
574     std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
575     int32_t ret = UserIdmDatabase::Instance().DeleteUserEnforce(userId, credInfos);
576     if (ret != SUCCESS) {
577         IAM_LOGE("failed to enforce delete user, ret:%{public}d", ret);
578         return ret;
579     }
580     ContextAppStateObserverManager::GetInstance().RemoveScreenLockState(userId);
581     SetAuthTypeTrace(credInfos, callbackForTrace);
582     ret = ResourceNodeUtils::NotifyExecutorToDeleteTemplates(credInfos, changeReasonTrace);
583     if (ret != SUCCESS) {
584         IAM_LOGE("failed to delete executor info, error code : %{public}d", ret);
585         // The caller doesn't need to care executor delete result.
586         return SUCCESS;
587     }
588 
589     PublishEventAdapter::GetInstance().PublishDeletedEvent(userId);
590     PublishEventAdapter::GetInstance().PublishCredentialUpdatedEvent(userId, PIN, 0);
591     IAM_LOGI("delete user success, userId:%{public}d", userId);
592     return SUCCESS;
593 }
594 
ClearRedundancyCredentialInner(const std::string & callerName,int32_t callerType)595 int32_t UserIdmService::ClearRedundancyCredentialInner(const std::string &callerName, int32_t callerType)
596 {
597     IAM_LOGI("start");
598     std::vector<int32_t> accountInfo;
599     int32_t ret = IpcCommon::GetAllUserId(accountInfo);
600     if (ret != SUCCESS) {
601         IAM_LOGE("GetAllUserId failed");
602         return IPC_ERROR;
603     }
604 
605     std::vector<std::shared_ptr<UserInfoInterface>> userInfos;
606     ret = UserIdmDatabase::Instance().GetAllExtUserInfo(userInfos);
607     if (ret != SUCCESS) {
608         IAM_LOGE("GetAllExtUserInfo failed");
609         return INVALID_HDI_INTERFACE;
610     }
611 
612     if (userInfos.empty()) {
613         IAM_LOGE("no userInfo");
614         return SUCCESS;
615     }
616 
617     for (const auto &iter : userInfos) {
618         int32_t userId = iter->GetUserId();
619         auto callbackForTrace = ContextCallback::NewDummyInstance(TRACE_DELETE_REDUNDANCY);
620         if (callbackForTrace == nullptr) {
621             IAM_LOGE("failed to get callbackForTrace");
622             continue;
623         }
624         callbackForTrace->SetTraceUserId(userId);
625         callbackForTrace->SetTraceCallerName(callerName);
626         callbackForTrace->SetTraceCallerType(callerType);
627         std::vector<int32_t>::iterator it = std::find(accountInfo.begin(), accountInfo.end(), userId);
628         if (it == accountInfo.end()) {
629             ret = EnforceDelUserInner(userId, callbackForTrace, "DeleteRedundancy");
630             Attributes extraInfo;
631             callbackForTrace->OnResult(ret, extraInfo);
632             IAM_LOGE("ClearRedundancytCredential, userId: %{public}d", userId);
633         }
634     }
635     return SUCCESS;
636 }
637 
ClearRedundancyCredential(const sptr<IdmCallbackInterface> & callback)638 void UserIdmService::ClearRedundancyCredential(const sptr<IdmCallbackInterface> &callback)
639 {
640     IAM_LOGI("start");
641     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
642     IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
643 
644     Attributes extraInfo;
645     auto contextCallback = ContextCallback::NewInstance(callback, TRACE_DELETE_REDUNDANCY);
646     if (contextCallback == nullptr) {
647         IAM_LOGE("failed to construct context callback");
648         callback->OnResult(GENERAL_ERROR, extraInfo);
649         return;
650     }
651 
652     std::string callerName = "";
653     int32_t callerType = Security::AccessToken::TOKEN_INVALID;
654     static_cast<void>(IpcCommon::GetCallerName(*this, callerName, callerType));
655     contextCallback->SetTraceCallerName(callerName);
656     contextCallback->SetTraceCallerType(callerType);
657 
658     if (!IpcCommon::CheckPermission(*this, CLEAR_REDUNDANCY_PERMISSION)) {
659         IAM_LOGE("failed to check permission");
660         contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
661         return;
662     }
663 
664     std::lock_guard<std::mutex> lock(mutex_);
665     CancelCurrentEnrollIfExist();
666 
667     int32_t ret = ClearRedundancyCredentialInner(callerName, callerType);
668     if (ret != SUCCESS) {
669         IAM_LOGE("clearRedundancyCredentialInner fail, ret:%{public}d, ", ret);
670     }
671     contextCallback->OnResult(ret, extraInfo);
672 }
673 
PublishCommonEvent(int32_t userId,uint64_t credentialId,AuthType authType)674 void UserIdmService::PublishCommonEvent(int32_t userId, uint64_t credentialId, AuthType authType)
675 {
676     std::vector<std::shared_ptr<CredentialInfoInterface>> credentialInfos;
677     int32_t ret = UserIdmDatabase::Instance().GetCredentialInfo(userId, authType, credentialInfos);
678     if (ret != SUCCESS) {
679         IAM_LOGE("get credential fail, ret:%{public}d, userId:%{public}d, authType:%{public}d", ret, userId, authType);
680         return;
681     }
682     PublishEventAdapter::GetInstance().PublishCredentialUpdatedEvent(userId, authType, credentialInfos.size());
683     PublishEventAdapter::GetInstance().PublishUpdatedEvent(userId, credentialId);
684 }
685 } // namespace UserAuth
686 } // namespace UserIam
687 } // namespace OHOS