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