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