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 ¶,
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