2 This driver manages user information and produces user manager protocol.
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UserIdentifyManager.h"
20 CHAR16 mUserName
[] = L
"Administrator";
23 // Points to the user profile database.
25 USER_PROFILE_DB
*mUserProfileDb
= NULL
;
28 // Points to the credential providers found in system.
30 CREDENTIAL_PROVIDER_INFO
*mProviderDb
= NULL
;
33 // Current user shared in multi function.
35 EFI_USER_PROFILE_HANDLE mCurrentUser
= NULL
;
38 // Flag indicates a user is identified.
40 BOOLEAN mIdentified
= FALSE
;
41 USER_MANAGER_CALLBACK_INFO
*mCallbackInfo
= NULL
;
42 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath
= {
48 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
49 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
52 USER_IDENTIFY_MANAGER_GUID
56 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
58 (UINT8
) (END_DEVICE_PATH_LENGTH
),
59 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
65 EFI_USER_MANAGER_PROTOCOL gUserIdentifyManager
= {
75 UserProfileDeleteInfo
,
76 UserProfileGetNextInfo
,
81 Find the specified user in the user database.
83 This function searches the specified user from the beginning of the user database.
84 And if NextUser is TRUE, return the next User in the user database.
86 @param[in, out] User On entry, points to the user profile entry to search.
87 On return, points to the user profile entry or NULL if not found.
88 @param[in] NextUser If FALSE, find the user in user profile database specifyed by User
89 If TRUE, find the next user in user profile database specifyed
91 @param[out] ProfileIndex A pointer to the index of user profile database that matches the
92 user specifyed by User.
94 @retval EFI_NOT_FOUND User was NULL, or User was not found, or the next user was not found.
95 @retval EFI_SUCCESS User or the next user are found in user profile database
100 IN OUT USER_PROFILE_ENTRY
**User
,
102 OUT UINTN
*ProfileIndex OPTIONAL
110 if ((mUserProfileDb
== NULL
) || (User
== NULL
)) {
111 return EFI_NOT_FOUND
;
115 // Check whether the user profile is in the user profile database.
117 for (Index
= 0; Index
< mUserProfileDb
->UserProfileNum
; Index
++) {
118 if (mUserProfileDb
->UserProfile
[Index
] == *User
) {
119 if (ProfileIndex
!= NULL
) {
120 *ProfileIndex
= Index
;
128 // Find the next user profile.
131 if (Index
< mUserProfileDb
->UserProfileNum
) {
132 *User
= mUserProfileDb
->UserProfile
[Index
];
133 } else if (Index
== mUserProfileDb
->UserProfileNum
) {
135 return EFI_NOT_FOUND
;
137 if ((mUserProfileDb
->UserProfileNum
> 0) && (*User
== NULL
)) {
138 *User
= mUserProfileDb
->UserProfile
[0];
141 return EFI_NOT_FOUND
;
144 } else if (Index
== mUserProfileDb
->UserProfileNum
) {
145 return EFI_NOT_FOUND
;
152 Find the specified user information record in the specified User profile.
154 This function searches the specified user information record from the beginning of the user
155 profile. And if NextInfo is TRUE, return the next info in the user profile.
157 @param[in] User Points to the user profile entry.
158 @param[in, out] Info On entry, points to the user information record or NULL to start
159 searching with the first user information record.
160 On return, points to the user information record or NULL if not found.
161 @param[in] NextInfo If FALSE, find the user information record in profile specifyed by User.
162 If TRUE, find the next user information record in profile specifyed
164 @param[out] Offset A pointer to the offset of the information record in the user profile.
166 @retval EFI_INVALID_PARAMETER Info is NULL
167 @retval EFI_NOT_FOUND Info was not found, or the next Info was not found.
168 @retval EFI_SUCCESS Info or the next info are found in user profile.
173 IN USER_PROFILE_ENTRY
* User
,
174 IN OUT EFI_USER_INFO
**Info
,
176 OUT UINTN
*Offset OPTIONAL
180 EFI_USER_INFO
*UserInfo
;
184 return EFI_INVALID_PARAMETER
;
188 // Check user profile entry
190 Status
= FindUserProfile (&User
, FALSE
, NULL
);
191 if (EFI_ERROR (Status
)) {
196 // Find user information in the specified user record.
199 while (InfoLen
< User
->UserProfileSize
) {
200 UserInfo
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ InfoLen
);
201 if (UserInfo
== *Info
) {
202 if (Offset
!= NULL
) {
207 InfoLen
+= ALIGN_VARIABLE (UserInfo
->InfoSize
);
211 // Check whether to find the next user information.
214 if (InfoLen
< User
->UserProfileSize
) {
215 UserInfo
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ InfoLen
);
216 InfoLen
+= ALIGN_VARIABLE (UserInfo
->InfoSize
);
217 if (InfoLen
< User
->UserProfileSize
) {
218 *Info
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ InfoLen
);
219 if (Offset
!= NULL
) {
222 } else if (InfoLen
== User
->UserProfileSize
) {
224 return EFI_NOT_FOUND
;
228 *Info
= (EFI_USER_INFO
*) User
->ProfileInfo
;
229 if (Offset
!= NULL
) {
234 return EFI_NOT_FOUND
;
237 } else if (InfoLen
== User
->UserProfileSize
) {
238 return EFI_NOT_FOUND
;
245 Find a user infomation record by the information record type.
247 This function searches all user information records of User. The search starts with the
248 user information record following Info and continues until either the information is found
249 or there are no more user infomation record.
250 A match occurs when a Info.InfoType field matches the user information record type.
252 @param[in] User Points to the user profile record to search.
253 @param[in, out] Info On entry, points to the user information record or NULL to start
254 searching with the first user information record.
255 On return, points to the user information record or NULL if not found.
256 @param[in] InfoType The infomation type to be searched.
258 @retval EFI_SUCCESS User information was found. Info points to the user information record.
259 @retval EFI_NOT_FOUND User information was not found.
260 @retval EFI_INVALID_PARAMETER User is NULL or Info is NULL.
265 IN USER_PROFILE_ENTRY
*User
,
266 IN OUT EFI_USER_INFO
**Info
,
271 EFI_USER_INFO
*UserInfo
;
275 return EFI_INVALID_PARAMETER
;
279 // Check whether the user has the specified user information.
283 Status
= FindUserProfile (&User
, FALSE
, NULL
);
285 Status
= FindUserInfo (User
, Info
, TRUE
, &InfoLen
);
288 if (EFI_ERROR (Status
)) {
289 return EFI_NOT_FOUND
;
292 while (InfoLen
< User
->UserProfileSize
) {
293 UserInfo
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ InfoLen
);
294 if (UserInfo
->InfoType
== InfoType
) {
295 if (UserInfo
!= *Info
) {
301 InfoLen
+= ALIGN_VARIABLE (UserInfo
->InfoSize
);
305 return EFI_NOT_FOUND
;
309 Find a user using a user information record.
311 This function searches all user profiles for the specified user information record. The
312 search starts with the user information record handle following UserInfo and continues
313 until either the information is found or there are no more user profiles.
314 A match occurs when the Info.InfoType field matches the user information record type and the
315 user information record data matches the portion of Info passed the EFI_USER_INFO header.
317 @param[in, out] User On entry, points to the previously returned user profile record,
318 or NULL to start searching with the first user profile.
319 On return, points to the user profile entry, or NULL if not found.
320 @param[in, out] UserInfo On entry, points to the previously returned user information record,
321 or NULL to start searching with the first.
322 On return, points to the user information record, or NULL if not found.
323 @param[in] Info Points to the buffer containing the user information to be compared
324 to the user information record.
325 @param[in] InfoSize The size of Info, in bytes. Same as Info->InfoSize.
327 @retval EFI_SUCCESS User information was found. User points to the user profile record,
328 and UserInfo points to the user information record.
329 @retval EFI_NOT_FOUND User information was not found.
330 @retval EFI_INVALID_PARAMETER User is NULL; Info is NULL; or, InfoSize is too small.
334 FindUserProfileByInfo (
335 IN OUT USER_PROFILE_ENTRY
**User
,
336 IN OUT EFI_USER_INFO
**UserInfo
, OPTIONAL
337 IN EFI_USER_INFO
*Info
,
342 EFI_USER_INFO
*InfoEntry
;
345 if ((User
== NULL
) || (Info
== NULL
)) {
346 return EFI_INVALID_PARAMETER
;
349 if (InfoSize
< sizeof (EFI_USER_INFO
)) {
350 return EFI_INVALID_PARAMETER
;
353 if (UserInfo
!= NULL
) {
354 InfoEntry
= *UserInfo
;
359 // Find user profile according to information.
362 *User
= mUserProfileDb
->UserProfile
[0];
366 // Check user profile handle.
368 Status
= FindUserProfile (User
, FALSE
, NULL
);
370 while (!EFI_ERROR (Status
)) {
372 // Find the user information in a user profile.
375 Status
= FindUserInfoByType (*User
, &InfoEntry
, Info
->InfoType
);
376 if (EFI_ERROR (Status
)) {
380 if (InfoSize
== Info
->InfoSize
) {
381 if (CompareMem ((UINT8
*) (InfoEntry
+ 1), (UINT8
*) (Info
+ 1), InfoSize
- sizeof (EFI_USER_INFO
)) == 0) {
383 // Found the infomation record.
385 if (UserInfo
!= NULL
) {
386 *UserInfo
= InfoEntry
;
394 // Get next user profile.
397 Status
= FindUserProfile (User
, TRUE
, NULL
);
400 return EFI_NOT_FOUND
;
404 Find the credential provider in the specified identity policy.
406 @param[in] FindIdentity Point to the user identity policy.
407 @param[in] IdentifyInfo Point to the user information to be searched.
409 @retval TRUE The credential provider was found in the identity policy.
410 @retval FALSE The credential provider was not found.
414 IN EFI_USER_INFO_IDENTITY_POLICY
*FindIdentity
,
415 IN CONST EFI_USER_INFO
*IdentifyInfo
419 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
422 // Found the credential provider.
425 while (TotalLen
< IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
426 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1) + TotalLen
);
427 if ((Identity
->Type
== FindIdentity
->Type
) &&
428 (Identity
->Length
== FindIdentity
->Length
) &&
429 CompareGuid ((EFI_GUID
*) (Identity
+ 1), (EFI_GUID
*) (FindIdentity
+ 1))
434 TotalLen
+= Identity
->Length
;
442 Check whether the access policy is valid.
444 @param[in] PolicyInfo Point to the access policy.
445 @param[in] InfoLen The policy length.
447 @retval TRUE The policy is a valid access policy.
448 @retval FALSE The access policy is not a valid access policy.
453 IN UINT8
*PolicyInfo
,
460 EFI_USER_INFO_ACCESS_CONTROL Access
;
461 EFI_DEVICE_PATH_PROTOCOL
*Path
;
465 while (TotalLen
< InfoLen
) {
467 // Check access policy according to type.
469 CopyMem (&Access
, PolicyInfo
+ TotalLen
, sizeof (Access
));
470 ValueLen
= Access
.Size
- sizeof (EFI_USER_INFO_ACCESS_CONTROL
);
471 switch (Access
.Type
) {
472 case EFI_USER_INFO_ACCESS_FORBID_LOAD
:
473 case EFI_USER_INFO_ACCESS_PERMIT_LOAD
:
474 case EFI_USER_INFO_ACCESS_FORBID_CONNECT
:
475 case EFI_USER_INFO_ACCESS_PERMIT_CONNECT
:
477 while (OffSet
< ValueLen
) {
478 Path
= (EFI_DEVICE_PATH_PROTOCOL
*) (PolicyInfo
+ TotalLen
+ sizeof (Access
) + OffSet
);
479 PathSize
= GetDevicePathSize (Path
);
482 if (OffSet
!= ValueLen
) {
487 case EFI_USER_INFO_ACCESS_SETUP
:
488 if (ValueLen
% sizeof (EFI_GUID
) != 0) {
493 case EFI_USER_INFO_ACCESS_BOOT_ORDER
:
494 if (ValueLen
% sizeof (EFI_USER_INFO_ACCESS_BOOT_ORDER_HDR
) != 0) {
499 case EFI_USER_INFO_ACCESS_ENROLL_SELF
:
500 case EFI_USER_INFO_ACCESS_ENROLL_OTHERS
:
501 case EFI_USER_INFO_ACCESS_MANAGE
:
512 TotalLen
+= Access
.Size
;
515 if (TotalLen
!= InfoLen
) {
524 Check whether the identity policy is valid.
526 @param[in] PolicyInfo Point to the identity policy.
527 @param[in] InfoLen The policy length.
529 @retval TRUE The policy is a valid identity policy.
530 @retval FALSE The access policy is not a valid identity policy.
534 CheckIdentityPolicy (
535 IN UINT8
*PolicyInfo
,
541 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
546 // Check each part of policy expression.
548 while (TotalLen
< InfoLen
) {
550 // Check access polisy according to type.
552 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) (PolicyInfo
+ TotalLen
);
553 ValueLen
= Identity
->Length
- sizeof (EFI_USER_INFO_IDENTITY_POLICY
);
554 switch (Identity
->Type
) {
556 // Check False option.
558 case EFI_USER_INFO_IDENTITY_FALSE
:
565 // Check True option.
567 case EFI_USER_INFO_IDENTITY_TRUE
:
574 // Check negative operation.
576 case EFI_USER_INFO_IDENTITY_NOT
:
583 // Check and operation.
585 case EFI_USER_INFO_IDENTITY_AND
:
592 // Check or operation.
594 case EFI_USER_INFO_IDENTITY_OR
:
601 // Check credential provider by type.
603 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE
:
604 if (ValueLen
!= sizeof (EFI_GUID
)) {
610 // Check credential provider by ID.
612 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
:
613 if (ValueLen
!= sizeof (EFI_GUID
)) {
623 TotalLen
+= Identity
->Length
;
626 if (TotalLen
!= InfoLen
) {
635 Check whether the user information is a valid user information record.
637 @param[in] Info points to the user information.
639 @retval TRUE The info is a valid user information record.
640 @retval FALSE The info is not a valid user information record.
645 IN CONST EFI_USER_INFO
*Info
654 // Check user information according to information type.
656 InfoLen
= Info
->InfoSize
- sizeof (EFI_USER_INFO
);
657 switch (Info
->InfoType
) {
658 case EFI_USER_INFO_EMPTY_RECORD
:
664 case EFI_USER_INFO_NAME_RECORD
:
665 case EFI_USER_INFO_CREDENTIAL_TYPE_NAME_RECORD
:
666 case EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD
:
669 case EFI_USER_INFO_CREATE_DATE_RECORD
:
670 case EFI_USER_INFO_USAGE_DATE_RECORD
:
671 if (InfoLen
!= sizeof (EFI_TIME
)) {
676 case EFI_USER_INFO_USAGE_COUNT_RECORD
:
677 if (InfoLen
!= sizeof (UINT64
)) {
682 case EFI_USER_INFO_IDENTIFIER_RECORD
:
688 case EFI_USER_INFO_CREDENTIAL_TYPE_RECORD
:
689 case EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD
:
690 case EFI_USER_INFO_GUID_RECORD
:
691 if (InfoLen
!= sizeof (EFI_GUID
)) {
696 case EFI_USER_INFO_PKCS11_RECORD
:
697 case EFI_USER_INFO_CBEFF_RECORD
:
700 case EFI_USER_INFO_FAR_RECORD
:
701 case EFI_USER_INFO_RETRY_RECORD
:
707 case EFI_USER_INFO_ACCESS_POLICY_RECORD
:
708 if(!CheckAccessPolicy ((UINT8
*) (Info
+ 1), InfoLen
)) {
713 case EFI_USER_INFO_IDENTITY_POLICY_RECORD
:
714 if (!CheckIdentityPolicy ((UINT8
*) (Info
+ 1), InfoLen
)) {
729 Check the user profile data format to be added.
731 @param[in] UserProfileInfo Points to the user profile data.
732 @param[in] UserProfileSize The length of user profile data.
734 @retval TRUE It is a valid user profile.
735 @retval FALSE It is not a valid user profile.
740 IN UINT8
*UserProfileInfo
,
741 IN UINTN UserProfileSize
747 if (UserProfileInfo
== NULL
) {
752 // Check user profile information length.
755 while (ChkLen
< UserProfileSize
) {
756 Info
= (EFI_USER_INFO
*) (UserProfileInfo
+ ChkLen
);
758 // Check user information format.
760 if (!CheckUserInfo (Info
)) {
764 ChkLen
+= ALIGN_VARIABLE (Info
->InfoSize
);
767 if (ChkLen
!= UserProfileSize
) {
776 Find the specified RightType in current user profile.
778 @param[in] RightType Could be EFI_USER_INFO_ACCESS_MANAGE,
779 EFI_USER_INFO_ACCESS_ENROLL_OTHERS or
780 EFI_USER_INFO_ACCESS_ENROLL_SELF.
782 @retval TRUE Find the specified RightType in current user profile.
783 @retval FALSE Can't find the right in the profile.
787 CheckCurrentUserAccessRight (
795 EFI_USER_INFO_ACCESS_CONTROL Access
;
798 // Get user access right information.
801 Status
= FindUserInfoByType (
802 (USER_PROFILE_ENTRY
*) mCurrentUser
,
804 EFI_USER_INFO_ACCESS_POLICY_RECORD
806 if (EFI_ERROR (Status
)) {
810 ASSERT (Info
!= NULL
);
811 TotalLen
= Info
->InfoSize
- sizeof (EFI_USER_INFO
);
813 while (CheckLen
< TotalLen
) {
815 // Check right according to access type.
817 CopyMem (&Access
, (UINT8
*) (Info
+ 1) + CheckLen
, sizeof (Access
));
818 if (Access
.Type
== RightType
) {
822 CheckLen
+= Access
.Size
;
830 Create a unique user identifier.
832 @param[out] Identifier This points to the identifier.
837 OUT UINT8
*Identifier
841 UINT64 MonotonicCount
;
842 UINT32
*MonotonicPointer
;
846 // Create a unique user identifier.
848 gRT
->GetTime (&Time
, NULL
);
849 CopyMem (Identifier
, &Time
, sizeof (EFI_TIME
));
853 for (Index
= 0; Index
< sizeof (EFI_TIME
); Index
++) {
854 if (Identifier
[Index
] == 0) {
855 Identifier
[Index
] = 0x5a;
859 MonotonicPointer
= (UINT32
*) Identifier
;
860 gBS
->GetNextMonotonicCount (&MonotonicCount
);
861 MonotonicPointer
[0] += (UINT32
) MonotonicCount
;
862 MonotonicPointer
[1] += (UINT32
) MonotonicCount
;
863 MonotonicPointer
[2] += (UINT32
) MonotonicCount
;
864 MonotonicPointer
[3] += (UINT32
) MonotonicCount
;
869 Generate unique user ID.
871 @param[out] UserId Points to the user identifer.
880 USER_PROFILE_ENTRY
*UserProfile
;
881 EFI_USER_INFO
*UserInfo
;
885 // Generate unique user ID
888 GenerateIdentifier (UserId
);
890 // Check whether it's unique in user profile database.
892 if (mUserProfileDb
== NULL
) {
896 for (Index
= 0; Index
< mUserProfileDb
->UserProfileNum
; Index
++) {
897 UserProfile
= (USER_PROFILE_ENTRY
*) (mUserProfileDb
->UserProfile
[Index
]);
899 Status
= FindUserInfoByType (UserProfile
, &UserInfo
, EFI_USER_INFO_IDENTIFIER_RECORD
);
900 if (EFI_ERROR (Status
)) {
904 if (CompareMem ((UINT8
*) (UserInfo
+ 1), UserId
, sizeof (EFI_USER_INFO_IDENTIFIER
)) == 0) {
909 if (Index
== mUserProfileDb
->UserProfileNum
) {
917 Expand user profile database.
919 @retval TRUE Success to expand user profile database.
920 @retval FALSE Fail to expand user profile database.
924 ExpandUsermUserProfileDb (
929 USER_PROFILE_DB
*NewDataBase
;
932 // Create new user profile database.
934 if (mUserProfileDb
== NULL
) {
935 MaxNum
= USER_NUMBER_INC
;
937 MaxNum
= mUserProfileDb
->MaxProfileNum
+ USER_NUMBER_INC
;
940 NewDataBase
= AllocateZeroPool (
941 sizeof (USER_PROFILE_DB
) - sizeof (EFI_USER_PROFILE_HANDLE
) +
942 MaxNum
* sizeof (EFI_USER_PROFILE_HANDLE
)
944 if (NewDataBase
== NULL
) {
948 NewDataBase
->MaxProfileNum
= MaxNum
;
951 // Copy old user profile database value
953 if (mUserProfileDb
== NULL
) {
954 NewDataBase
->UserProfileNum
= 0;
956 NewDataBase
->UserProfileNum
= mUserProfileDb
->UserProfileNum
;
958 NewDataBase
->UserProfile
,
959 mUserProfileDb
->UserProfile
,
960 NewDataBase
->UserProfileNum
* sizeof (EFI_USER_PROFILE_HANDLE
)
962 FreePool (mUserProfileDb
);
965 mUserProfileDb
= NewDataBase
;
973 @param[in] User Points to user profile.
974 @param[in] ExpandSize The size of user profile.
976 @retval TRUE Success to expand user profile size.
977 @retval FALSE Fail to expand user profile size.
982 IN USER_PROFILE_ENTRY
*User
,
990 // Allocate new memory.
993 User
->MaxProfileSize
+= ((ExpandSize
+ InfoSizeInc
- 1) / InfoSizeInc
) * InfoSizeInc
;
994 Info
= AllocateZeroPool (User
->MaxProfileSize
);
1000 // Copy exist information.
1002 if (User
->UserProfileSize
> 0) {
1003 CopyMem (Info
, User
->ProfileInfo
, User
->UserProfileSize
);
1004 FreePool (User
->ProfileInfo
);
1007 User
->ProfileInfo
= Info
;
1013 Add or delete the user's credential record in the provider.
1015 @param[in] ProviderGuid Point to credential provider guid or class guid.
1016 @param[in] ByType If TRUE, Provider is credential class guid.
1017 If FALSE, Provider is provider guid.
1018 @param[in] User Points to user profile.
1019 @param[in] Delete If TRUE, delete User from the provider; If FALSE, add
1020 User info from the provider.
1022 @retval EFI_SUCCESS Add or delete record successfully.
1023 @retval Others Fail to add or delete record.
1027 ModifyProviderCredential (
1028 IN EFI_GUID
*Provider
,
1030 IN USER_PROFILE_ENTRY
*User
,
1035 EFI_USER_CREDENTIAL2_PROTOCOL
*UserCredential
;
1037 if (Provider
== NULL
) {
1038 return EFI_INVALID_PARAMETER
;
1042 // Find the specified credential provider.
1044 for (Index
= 0; Index
< mProviderDb
->Count
; Index
++) {
1046 // Check credential provider ID.
1048 UserCredential
= mProviderDb
->Provider
[Index
];
1049 if (CompareGuid (&UserCredential
->Identifier
, Provider
)) {
1051 return UserCredential
->Delete (UserCredential
, User
);
1053 return UserCredential
->Enroll (UserCredential
, User
);
1058 return EFI_NOT_FOUND
;
1063 Modify user's credential record in the providers.
1065 Found the providers information in PolicyInfo, and then add or delete the user's credential
1066 record in the providers.
1068 @param[in] User Points to user profile.
1069 @param[in] PolicyInfo Point to identification policy to be modified.
1070 @param[in] InfoLen The length of PolicyInfo.
1071 @param[in] Delete If TRUE, delete User from the provider; If FALSE, add
1072 User info from the provider.
1074 @retval EFI_SUCCESS Modify PolicyInfo successfully.
1075 @retval Others Fail to modify PolicyInfo.
1079 ModifyCredentialInfo (
1080 IN USER_PROFILE_ENTRY
*User
,
1081 IN UINT8
*PolicyInfo
,
1088 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
1091 // Modify user's credential.
1094 while (TotalLen
< InfoLen
) {
1096 // Check identification policy according to type.
1098 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) (PolicyInfo
+ TotalLen
);
1099 switch (Identity
->Type
) {
1100 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE
:
1101 Status
= ModifyProviderCredential ((EFI_GUID
*) (Identity
+ 1), TRUE
, User
, Delete
);
1102 if (EFI_ERROR (Status
)) {
1107 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
:
1108 Status
= ModifyProviderCredential ((EFI_GUID
*) (Identity
+ 1), FALSE
, User
, Delete
);
1109 if (EFI_ERROR (Status
)) {
1118 TotalLen
+= Identity
->Length
;
1126 Save the user profile to non-volatile memory, or delete it from non-volatile memory.
1128 @param[in] User Point to the user profile
1129 @param[in] Delete If TRUE, delete the found user profile.
1130 If FALSE, save the user profile.
1131 @retval EFI_SUCCESS Save or delete user profile successfully.
1132 @retval Others Fail to change the profile.
1137 IN USER_PROFILE_ENTRY
*User
,
1144 // Check user profile entry.
1146 Status
= FindUserProfile (&User
, FALSE
, NULL
);
1147 if (EFI_ERROR (Status
)) {
1152 // Save the user profile to non-volatile memory.
1154 Status
= gRT
->SetVariable (
1156 &gUserIdentifyManagerGuid
,
1157 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1158 Delete
? 0 : User
->UserProfileSize
,
1166 Replace the old identity info with NewInfo in NV Flash.
1168 This function only replace the identity record in the user profile. Don't update
1169 the the information on the credential provider.
1171 @param[in] User Point to the user profile.
1172 @param[in] NewInfo Point to the new identity policy info.
1173 @param[out] UserInfo Point to the new added identity info.
1175 @retval EFI_SUCCESS Replace user identity successfully.
1176 @retval Others Fail to Replace user identity.
1181 IN USER_PROFILE_ENTRY
* User
,
1182 IN CONST EFI_USER_INFO
* NewInfo
,
1183 OUT EFI_USER_INFO
**UserInfo OPTIONAL
1187 EFI_USER_INFO
*OldIpInfo
;
1191 if ((NewInfo
== NULL
) || (User
== NULL
)) {
1192 return EFI_INVALID_PARAMETER
;
1196 // Get user old identify policy information.
1199 Status
= FindUserInfoByType (User
, &OldIpInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
1200 if (EFI_ERROR (Status
)) {
1205 // Get the old identity policy offset.
1207 Status
= FindUserInfo (User
, &OldIpInfo
, FALSE
, &Offset
);
1208 if (EFI_ERROR (Status
)) {
1213 // Delete the old identity policy information.
1215 NextOffset
= ALIGN_VARIABLE (OldIpInfo
->InfoSize
) + Offset
;
1216 User
->UserProfileSize
-= ALIGN_VARIABLE (OldIpInfo
->InfoSize
);
1217 if (Offset
< User
->UserProfileSize
) {
1218 CopyMem (User
->ProfileInfo
+ Offset
, User
->ProfileInfo
+ NextOffset
, User
->UserProfileSize
- Offset
);
1222 // Add new user information.
1224 if (User
->MaxProfileSize
- User
->UserProfileSize
< ALIGN_VARIABLE (NewInfo
->InfoSize
)) {
1225 if (!ExpandUserProfile (User
, ALIGN_VARIABLE (NewInfo
->InfoSize
))) {
1226 return EFI_OUT_OF_RESOURCES
;
1230 CopyMem (User
->ProfileInfo
+ User
->UserProfileSize
, (VOID
*) NewInfo
, NewInfo
->InfoSize
);
1231 if (UserInfo
!= NULL
) {
1232 *UserInfo
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ User
->UserProfileSize
);
1235 User
->UserProfileSize
+= ALIGN_VARIABLE (NewInfo
->InfoSize
);
1238 // Save user profile information.
1240 Status
= SaveNvUserProfile (User
, FALSE
);
1246 Remove the provider in FindIdentity from the user identification information record.
1248 @param[in, out] NewInfo On entry, points to the user information to remove provider.
1249 On return, points to the user information the provider is removed.
1250 @param[in] FindIdentity Point to the user identity policy.
1252 @retval TRUE The provider is removed successfully.
1253 @retval FALSE Fail to remove the provider.
1258 IN OUT EFI_USER_INFO
**NewInfo
,
1259 IN EFI_USER_INFO_IDENTITY_POLICY
*FindIdentity
1263 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
1264 EFI_USER_INFO
*IdentifyInfo
;
1267 IdentifyInfo
= *NewInfo
;
1268 TotalLen
= IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
);
1269 if (TotalLen
== FindIdentity
->Length
) {
1271 // Only one credential provider in the identification policy.
1272 // Set the new policy to be TRUE after removed the provider.
1274 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) (IdentifyInfo
+ 1);
1275 Identity
->Type
= EFI_USER_INFO_IDENTITY_TRUE
;
1276 Identity
->Length
= sizeof (EFI_USER_INFO_IDENTITY_POLICY
);
1277 IdentifyInfo
->InfoSize
= sizeof (EFI_USER_INFO
) + Identity
->Length
;
1282 // Found the credential provider.
1285 while (TotalLen
< IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
1286 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1) + TotalLen
);
1287 if ((Identity
->Type
== FindIdentity
->Type
) &&
1288 (Identity
->Length
== FindIdentity
->Length
) &&
1289 CompareGuid ((EFI_GUID
*) (Identity
+ 1), (EFI_GUID
*) (FindIdentity
+ 1))
1292 // Found the credential provider to delete
1294 if (Identity
== (EFI_USER_INFO_IDENTITY_POLICY
*)(IdentifyInfo
+ 1)) {
1296 // It is the first item in the identification policy, delete it and the connector after it.
1298 Buffer
= (UINT8
*) Identity
+ Identity
->Length
+ sizeof(EFI_USER_INFO_IDENTITY_POLICY
);
1299 IdentifyInfo
->InfoSize
-= Identity
->Length
+ sizeof(EFI_USER_INFO_IDENTITY_POLICY
);
1300 TotalLen
= IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
);
1301 CopyMem (Identity
, Buffer
, TotalLen
);
1304 // It is not the first item in the identification policy, delete it and the connector before it.
1306 Buffer
= (UINT8
*) Identity
+ Identity
->Length
;
1307 TotalLen
= IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
);
1308 TotalLen
-= (Buffer
- (UINT8
*)(IdentifyInfo
+ 1));
1309 IdentifyInfo
->InfoSize
-= Identity
->Length
+ sizeof(EFI_USER_INFO_IDENTITY_POLICY
);
1310 CopyMem ((UINT8
*) (Identity
- 1), Buffer
, TotalLen
);
1315 TotalLen
+= Identity
->Length
;
1322 This function replaces the old identity policy with a new identity policy.
1324 This function changes user identity policy information.
1325 If enroll new credential failed, recover the old identity policy.
1328 a. For each credential, if it is newly added, try to enroll it.
1329 If enroll failed, try to delete the newly added ones.
1331 b. For each credential, if it exists in the old policy, delete old one,
1332 and enroll new one. If failed to enroll the new one, removed it from new
1333 identification policy.
1336 a. For each credential, if it does not exist in new one, delete it.
1338 @param[in] User Point to the user profile.
1339 @param[in] Info Points to the user identity information.
1340 @param[in] InfoSize The size of Info (Not used in this function).
1341 @param[out] IpInfo The new identification info after modify.
1343 @retval EFI_SUCCESS Modify user identity policy successfully.
1344 @retval Others Fail to modify user identity policy.
1349 IN USER_PROFILE_ENTRY
*User
,
1350 IN CONST EFI_USER_INFO
*Info
,
1352 OUT EFI_USER_INFO
**IpInfo
1356 EFI_USER_INFO
*OldIpInfo
;
1358 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
1359 UINT32 CredentialCount
;
1360 EFI_USER_INFO
*NewIpInfo
;
1363 // Get user old identify policy information.
1366 Status
= FindUserInfoByType (User
, &OldIpInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
1367 if (EFI_ERROR (Status
)) {
1370 ASSERT (OldIpInfo
!= NULL
);
1373 // Enroll new added credential provider.
1375 CredentialCount
= 0;
1377 while (TotalLen
< Info
->InfoSize
- sizeof (EFI_USER_INFO
)) {
1378 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (Info
+ 1) + TotalLen
);
1379 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
) {
1380 if (!FindProvider (Identity
, OldIpInfo
)) {
1382 // The credential is NOT found in the old identity policy; add it.
1384 Status
= ModifyCredentialInfo (User
, (UINT8
*) Identity
, Identity
->Length
, FALSE
);
1385 if (EFI_ERROR (Status
)) {
1392 TotalLen
+= Identity
->Length
;
1395 if (EFI_ERROR (Status
)) {
1397 // Enroll new credential failed. Delete the newly enrolled credential, and return.
1400 while (TotalLen
< Info
->InfoSize
- sizeof (EFI_USER_INFO
)) {
1401 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (Info
+ 1) + TotalLen
);
1402 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
) {
1403 if (!FindProvider (Identity
, OldIpInfo
)) {
1405 // The credential is NOT found in the old identity policy. Delete it.
1407 if (CredentialCount
== 0) {
1411 ModifyCredentialInfo (User
, (UINT8
*) Identity
, Identity
->Length
, TRUE
);
1415 TotalLen
+= Identity
->Length
;
1418 return EFI_DEVICE_ERROR
;
1422 // Backup new identification policy
1424 NewIpInfo
= AllocateCopyPool (Info
->InfoSize
, Info
);
1425 ASSERT (NewIpInfo
!= NULL
);
1428 // Enroll the credential that existed in the old identity policy.
1431 while (TotalLen
< Info
->InfoSize
- sizeof (EFI_USER_INFO
)) {
1432 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (Info
+ 1) + TotalLen
);
1433 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
) {
1434 if (FindProvider (Identity
, OldIpInfo
)) {
1436 // The credential is found in the old identity policy, so delete the old credential first.
1438 Status
= ModifyCredentialInfo (User
, (UINT8
*) Identity
, Identity
->Length
, TRUE
);
1439 if (EFI_ERROR (Status
)) {
1441 // Failed to delete old credential.
1443 FreePool (NewIpInfo
);
1444 return EFI_DEVICE_ERROR
;
1448 // Add the new credential.
1450 Status
= ModifyCredentialInfo (User
, (UINT8
*) Identity
, Identity
->Length
, FALSE
);
1451 if (EFI_ERROR (Status
)) {
1453 // Failed to enroll the user by new identification policy.
1454 // So removed the credential provider from the identification policy
1456 RemoveProvider (&NewIpInfo
, Identity
);
1460 TotalLen
+= Identity
->Length
;
1464 // Delete old credential that didn't exist in the new identity policy.
1467 while (TotalLen
< OldIpInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
1468 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (OldIpInfo
+ 1) + TotalLen
);
1469 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
) {
1470 if (!FindProvider (Identity
, Info
)) {
1472 // The credential is NOT found in the new identity policy. Delete the old credential.
1474 ModifyCredentialInfo (User
, (UINT8
*) Identity
, Identity
->Length
, TRUE
);
1477 TotalLen
+= Identity
->Length
;
1480 *IpInfo
= NewIpInfo
;
1486 Add one new user info into the user's profile.
1488 @param[in] User point to the user profile
1489 @param[in] Info Points to the user information payload.
1490 @param[in] InfoSize The size of the user information payload, in bytes.
1491 @param[out] UserInfo Point to the new info in user profile
1492 @param[in] Save If TRUE, save the profile to NV flash.
1493 If FALSE, don't need to save the profile to NV flash.
1495 @retval EFI_SUCCESS Add user info to user profile successfully.
1496 @retval Others Fail to add user info to user profile.
1501 IN USER_PROFILE_ENTRY
*User
,
1504 OUT EFI_USER_INFO
**UserInfo
, OPTIONAL
1510 if ((Info
== NULL
) || (User
== NULL
)) {
1511 return EFI_INVALID_PARAMETER
;
1515 // Check user profile handle.
1517 Status
= FindUserProfile (&User
, FALSE
, NULL
);
1518 if (EFI_ERROR (Status
)) {
1523 // Check user information memory size.
1525 if (User
->MaxProfileSize
- User
->UserProfileSize
< ALIGN_VARIABLE (InfoSize
)) {
1526 if (!ExpandUserProfile (User
, ALIGN_VARIABLE (InfoSize
))) {
1527 return EFI_OUT_OF_RESOURCES
;
1534 if (((EFI_USER_INFO
*) Info
)->InfoType
== EFI_USER_INFO_IDENTITY_POLICY_RECORD
) {
1535 Status
= ModifyCredentialInfo (
1537 (UINT8
*) ((EFI_USER_INFO
*) Info
+ 1),
1538 InfoSize
- sizeof (EFI_USER_INFO
),
1541 if (EFI_ERROR (Status
)) {
1547 // Add new user information.
1549 CopyMem (User
->ProfileInfo
+ User
->UserProfileSize
, Info
, InfoSize
);
1550 if (UserInfo
!= NULL
) {
1551 *UserInfo
= (EFI_USER_INFO
*) (User
->ProfileInfo
+ User
->UserProfileSize
);
1553 User
->UserProfileSize
+= ALIGN_VARIABLE (InfoSize
);
1556 // Save user profile information.
1559 Status
= SaveNvUserProfile (User
, FALSE
);
1567 Get the user info from the specified user info handle.
1569 @param[in] User Point to the user profile.
1570 @param[in] UserInfo Point to the user information record to get.
1571 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes.
1572 On exit, holds the user information.
1573 @param[in, out] InfoSize On entry, points to the size of Info.
1574 On return, points to the size of the user information.
1575 @param[in] ChkRight If TRUE, check the user info attribute.
1576 If FALSE, don't check the user info attribute.
1579 @retval EFI_ACCESS_DENIED The information cannot be accessed by the current user.
1580 @retval EFI_INVALID_PARAMETER InfoSize is NULL or UserInfo is NULL.
1581 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the
1582 returned data. The actual size required is returned in *InfoSize.
1583 @retval EFI_SUCCESS Information returned successfully.
1588 IN USER_PROFILE_ENTRY
*User
,
1589 IN EFI_USER_INFO
*UserInfo
,
1590 OUT EFI_USER_INFO
*Info
,
1591 IN OUT UINTN
*InfoSize
,
1597 if ((InfoSize
== NULL
) || (UserInfo
== NULL
)) {
1598 return EFI_INVALID_PARAMETER
;
1601 if ((*InfoSize
!= 0) && (Info
== NULL
)) {
1602 return EFI_INVALID_PARAMETER
;
1606 // Find the user information to get.
1608 Status
= FindUserInfo (User
, &UserInfo
, FALSE
, NULL
);
1609 if (EFI_ERROR (Status
)) {
1614 // Check information attributes.
1617 switch (UserInfo
->InfoAttribs
& EFI_USER_INFO_ACCESS
) {
1618 case EFI_USER_INFO_PRIVATE
:
1619 case EFI_USER_INFO_PROTECTED
:
1620 if (User
!= mCurrentUser
) {
1621 return EFI_ACCESS_DENIED
;
1625 case EFI_USER_INFO_PUBLIC
:
1629 return EFI_INVALID_PARAMETER
;
1635 // Get user information.
1637 if (UserInfo
->InfoSize
> *InfoSize
) {
1638 *InfoSize
= UserInfo
->InfoSize
;
1639 return EFI_BUFFER_TOO_SMALL
;
1642 *InfoSize
= UserInfo
->InfoSize
;
1644 CopyMem (Info
, UserInfo
, *InfoSize
);
1652 Delete the specified user information from user profile.
1654 @param[in] User Point to the user profile.
1655 @param[in] Info Point to the user information record to delete.
1656 @param[in] Save If TRUE, save the profile to NV flash.
1657 If FALSE, don't need to save the profile to NV flash.
1659 @retval EFI_SUCCESS Delete user info from user profile successfully.
1660 @retval Others Fail to delete user info from user profile.
1665 IN USER_PROFILE_ENTRY
*User
,
1666 IN EFI_USER_INFO
*Info
,
1675 // Check user information handle.
1677 Status
= FindUserInfo (User
, &Info
, FALSE
, &Offset
);
1678 if (EFI_ERROR (Status
)) {
1682 if (Info
->InfoType
== EFI_USER_INFO_IDENTIFIER_RECORD
) {
1683 return EFI_ACCESS_DENIED
;
1684 } else if (Info
->InfoType
== EFI_USER_INFO_IDENTITY_POLICY_RECORD
) {
1685 Status
= ModifyCredentialInfo (User
, (UINT8
*) (Info
+ 1), Info
->InfoSize
- sizeof (EFI_USER_INFO
), TRUE
);
1686 if (EFI_ERROR (Status
)) {
1692 // Delete the specified user information.
1694 NextOffset
= Offset
+ ALIGN_VARIABLE (Info
->InfoSize
);
1695 User
->UserProfileSize
-= ALIGN_VARIABLE (Info
->InfoSize
);
1696 if (Offset
< User
->UserProfileSize
) {
1697 CopyMem (User
->ProfileInfo
+ Offset
, User
->ProfileInfo
+ NextOffset
, User
->UserProfileSize
- Offset
);
1701 Status
= SaveNvUserProfile (User
, FALSE
);
1709 Add or update user information.
1711 @param[in] User Point to the user profile.
1712 @param[in, out] UserInfo On entry, points to the user information to modify,
1713 or NULL to add a new UserInfo.
1714 On return, points to the modified user information.
1715 @param[in] Info Points to the new user information.
1716 @param[in] InfoSize The size of Info,in bytes.
1718 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.
1719 @retval EFI_ACCESS_DENIED The record is exclusive.
1720 @retval EFI_SUCCESS User information was successfully changed/added.
1725 IN USER_PROFILE_ENTRY
*User
,
1726 IN OUT EFI_USER_INFO
**UserInfo
,
1727 IN CONST EFI_USER_INFO
*Info
,
1733 EFI_USER_INFO
*OldInfo
;
1734 EFI_USER_INFO
*IpInfo
;
1736 if ((UserInfo
== NULL
) || (Info
== NULL
)) {
1737 return EFI_INVALID_PARAMETER
;
1740 if (InfoSize
< sizeof (EFI_USER_INFO
) || InfoSize
!= Info
->InfoSize
) {
1741 return EFI_INVALID_PARAMETER
;
1745 // Check user information.
1747 if (Info
->InfoType
== EFI_USER_INFO_IDENTIFIER_RECORD
) {
1748 return EFI_ACCESS_DENIED
;
1751 if (!CheckUserInfo (Info
)) {
1752 return EFI_INVALID_PARAMETER
;
1756 if (*UserInfo
== NULL
) {
1758 // Add new user information.
1762 Status
= FindUserInfoByType (User
, &OldInfo
, Info
->InfoType
);
1763 if (EFI_ERROR (Status
)) {
1766 ASSERT (OldInfo
!= NULL
);
1768 if (((OldInfo
->InfoAttribs
& EFI_USER_INFO_EXCLUSIVE
) != 0) ||
1769 ((Info
->InfoAttribs
& EFI_USER_INFO_EXCLUSIVE
) != 0)) {
1771 // Same type can not co-exist for exclusive information.
1773 return EFI_ACCESS_DENIED
;
1777 // Check whether it exists in DB.
1779 if (Info
->InfoSize
!= OldInfo
->InfoSize
) {
1783 if (!CompareGuid (&OldInfo
->Credential
, &Info
->Credential
)) {
1787 PayloadLen
= Info
->InfoSize
- sizeof (EFI_USER_INFO
);
1788 if (PayloadLen
== 0) {
1792 if (CompareMem ((UINT8
*)(OldInfo
+ 1), (UINT8
*)(Info
+ 1), PayloadLen
) != 0) {
1797 // Yes. The new info is as same as the one in profile.
1800 } while (!EFI_ERROR (Status
));
1802 Status
= AddUserInfo (User
, (UINT8
*) Info
, InfoSize
, UserInfo
, TRUE
);
1807 // Modify existing user information.
1809 OldInfo
= *UserInfo
;
1810 if (OldInfo
->InfoType
!= Info
->InfoType
) {
1811 return EFI_INVALID_PARAMETER
;
1814 if (((Info
->InfoAttribs
& EFI_USER_INFO_EXCLUSIVE
) != 0) &&
1815 (OldInfo
->InfoAttribs
& EFI_USER_INFO_EXCLUSIVE
) == 0) {
1817 // Try to add exclusive attrib in new info.
1818 // Check whether there is another information with the same type in profile.
1822 Status
= FindUserInfoByType (User
, &OldInfo
, Info
->InfoType
);
1823 if (EFI_ERROR (Status
)) {
1826 if (OldInfo
!= *UserInfo
) {
1828 // There is another information with the same type in profile.
1829 // Therefore, can't modify existing user information to add exclusive attribute.
1831 return EFI_ACCESS_DENIED
;
1836 if (Info
->InfoType
== EFI_USER_INFO_IDENTITY_POLICY_RECORD
) {
1838 // For user identification policy, need to update the info in credential provider.
1841 Status
= ModifyUserIpInfo (User
, Info
, InfoSize
, &IpInfo
);
1842 if (EFI_ERROR (Status
)) {
1846 ASSERT (IpInfo
!= NULL
);
1847 Status
= SaveUserIpInfo (User
, IpInfo
, UserInfo
);
1848 if (IpInfo
->InfoSize
!= Info
->InfoSize
) {
1849 Status
= EFI_DEVICE_ERROR
;
1855 Status
= DelUserInfo (User
, *UserInfo
, FALSE
);
1856 if (EFI_ERROR (Status
)) {
1860 return AddUserInfo (User
, (UINT8
*) Info
, InfoSize
, UserInfo
, TRUE
);
1865 Delete the user profile from non-volatile memory and database.
1867 @param[in] User Points to the user profile.
1869 @retval EFI_SUCCESS Delete user from the user profile successfully.
1870 @retval Others Fail to delete user from user profile
1875 IN USER_PROFILE_ENTRY
*User
1880 EFI_USER_INFO
*UserInfo
;
1883 // Check whether it is in the user profile database.
1885 Status
= FindUserProfile (&User
, FALSE
, &Index
);
1886 if (EFI_ERROR (Status
)) {
1887 return EFI_INVALID_PARAMETER
;
1891 // Check whether it is the current user.
1893 if (User
== mCurrentUser
) {
1894 return EFI_ACCESS_DENIED
;
1898 // Delete user credential information.
1901 Status
= FindUserInfoByType (User
, &UserInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
1902 if (Status
== EFI_SUCCESS
) {
1903 Status
= DelUserInfo (User
, UserInfo
, FALSE
);
1904 if (EFI_ERROR (Status
)) {
1910 // Delete user profile from the non-volatile memory.
1912 Status
= SaveNvUserProfile (mUserProfileDb
->UserProfile
[mUserProfileDb
->UserProfileNum
- 1], TRUE
);
1913 if (EFI_ERROR (Status
)) {
1916 mUserProfileDb
->UserProfileNum
--;
1919 // Modify user profile database.
1921 if (Index
!= mUserProfileDb
->UserProfileNum
) {
1922 mUserProfileDb
->UserProfile
[Index
] = mUserProfileDb
->UserProfile
[mUserProfileDb
->UserProfileNum
];
1924 ((USER_PROFILE_ENTRY
*) mUserProfileDb
->UserProfile
[Index
])->UserVarName
,
1926 sizeof (User
->UserVarName
)
1928 Status
= SaveNvUserProfile (mUserProfileDb
->UserProfile
[Index
], FALSE
);
1929 if (EFI_ERROR (Status
)) {
1934 // Delete user profile information.
1936 if (User
->ProfileInfo
!= NULL
) {
1937 FreePool (User
->ProfileInfo
);
1946 Add user profile to user profile database.
1948 @param[out] UserProfile Point to the newly added user profile.
1949 @param[in] ProfileSize The size of the user profile.
1950 @param[in] ProfileInfo Point to the user profie data.
1951 @param[in] Save If TRUE, save the new added profile to NV flash.
1952 If FALSE, don't save the profile to NV flash.
1954 @retval EFI_SUCCESS Add user profile to user profile database successfully.
1955 @retval Others Fail to add user profile to user profile database.
1960 OUT USER_PROFILE_ENTRY
**UserProfile
, OPTIONAL
1961 IN UINTN ProfileSize
,
1962 IN UINT8
*ProfileInfo
,
1967 USER_PROFILE_ENTRY
*User
;
1970 // Check the data format to be added.
1972 if (!CheckProfileInfo (ProfileInfo
, ProfileSize
)) {
1973 return EFI_SECURITY_VIOLATION
;
1977 // Create user profile entry.
1979 User
= AllocateZeroPool (sizeof (USER_PROFILE_ENTRY
));
1981 return EFI_OUT_OF_RESOURCES
;
1984 // Add the entry to the user profile database.
1986 if (mUserProfileDb
->UserProfileNum
== mUserProfileDb
->MaxProfileNum
) {
1987 if (!ExpandUsermUserProfileDb ()) {
1989 return EFI_OUT_OF_RESOURCES
;
1995 sizeof (User
->UserVarName
),
1997 mUserProfileDb
->UserProfileNum
1999 User
->UserProfileSize
= 0;
2000 User
->MaxProfileSize
= 0;
2001 User
->ProfileInfo
= NULL
;
2002 mUserProfileDb
->UserProfile
[mUserProfileDb
->UserProfileNum
] = (EFI_USER_PROFILE_HANDLE
) User
;
2003 mUserProfileDb
->UserProfileNum
++;
2006 // Add user profile information.
2008 Status
= AddUserInfo (User
, ProfileInfo
, ProfileSize
, NULL
, Save
);
2009 if (EFI_ERROR (Status
)) {
2010 DelUserProfile (User
);
2014 // Set new user profile handle.
2016 if (UserProfile
!= NULL
) {
2017 *UserProfile
= User
;
2025 This function creates a new user profile with only a new user identifier
2026 attached and returns its handle. The user profile is non-volatile, but the
2027 handle User can change across reboots.
2029 @param[out] User Handle of a new user profile.
2031 @retval EFI_SUCCESS User profile was successfully created.
2032 @retval Others Fail to create user profile
2037 OUT USER_PROFILE_ENTRY
**User
2041 EFI_USER_INFO
*UserInfo
;
2044 return EFI_INVALID_PARAMETER
;
2047 // Generate user id information.
2049 UserInfo
= AllocateZeroPool (sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_IDENTIFIER
));
2050 if (UserInfo
== NULL
) {
2051 return EFI_OUT_OF_RESOURCES
;
2054 UserInfo
->InfoType
= EFI_USER_INFO_IDENTIFIER_RECORD
;
2055 UserInfo
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_IDENTIFIER
);
2056 UserInfo
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2057 GenerateUserId ((UINT8
*) (UserInfo
+ 1));
2060 // Add user profile to the user profile database.
2062 Status
= AddUserProfile (User
, UserInfo
->InfoSize
, (UINT8
*) UserInfo
, TRUE
);
2063 FreePool (UserInfo
);
2069 Add a default user profile to user profile database.
2071 @retval EFI_SUCCESS A default user profile is added successfully.
2072 @retval Others Fail to add a default user profile
2076 AddDefaultUserProfile (
2081 USER_PROFILE_ENTRY
*User
;
2082 EFI_USER_INFO
*Info
;
2083 EFI_USER_INFO
*NewInfo
;
2084 EFI_USER_INFO_CREATE_DATE CreateDate
;
2085 EFI_USER_INFO_USAGE_COUNT UsageCount
;
2086 EFI_USER_INFO_ACCESS_CONTROL
*Access
;
2087 EFI_USER_INFO_IDENTITY_POLICY
*Policy
;
2090 // Create a user profile.
2092 Status
= CreateUserProfile (&User
);
2093 if (EFI_ERROR (Status
)) {
2098 // Allocate a buffer to add all default user information.
2100 Info
= AllocateZeroPool (sizeof (EFI_USER_INFO
) + INFO_PAYLOAD_SIZE
);
2102 return EFI_OUT_OF_RESOURCES
;
2108 Info
->InfoType
= EFI_USER_INFO_NAME_RECORD
;
2109 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2110 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (mUserName
);
2111 CopyMem ((UINT8
*) (Info
+ 1), mUserName
, sizeof (mUserName
));
2113 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2114 if (EFI_ERROR (Status
)) {
2119 // Add user profile create date record.
2121 Info
->InfoType
= EFI_USER_INFO_CREATE_DATE_RECORD
;
2122 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2123 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_CREATE_DATE
);
2124 Status
= gRT
->GetTime (&CreateDate
, NULL
);
2125 if (EFI_ERROR (Status
)) {
2129 CopyMem ((UINT8
*) (Info
+ 1), &CreateDate
, sizeof (EFI_USER_INFO_CREATE_DATE
));
2131 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2132 if (EFI_ERROR (Status
)) {
2137 // Add user profile usage count record.
2139 Info
->InfoType
= EFI_USER_INFO_USAGE_COUNT_RECORD
;
2140 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2141 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_USAGE_COUNT
);
2143 CopyMem ((UINT8
*) (Info
+ 1), &UsageCount
, sizeof (EFI_USER_INFO_USAGE_COUNT
));
2145 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2146 if (EFI_ERROR (Status
)) {
2151 // Add user access right.
2153 Info
->InfoType
= EFI_USER_INFO_ACCESS_POLICY_RECORD
;
2154 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2155 Access
= (EFI_USER_INFO_ACCESS_CONTROL
*) (Info
+ 1);
2156 Access
->Type
= EFI_USER_INFO_ACCESS_MANAGE
;
2157 Access
->Size
= sizeof (EFI_USER_INFO_ACCESS_CONTROL
);
2158 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + Access
->Size
;
2160 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2161 if (EFI_ERROR (Status
)) {
2166 // Add user identity policy.
2168 Info
->InfoType
= EFI_USER_INFO_IDENTITY_POLICY_RECORD
;
2169 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PRIVATE
| EFI_USER_INFO_EXCLUSIVE
;
2170 Policy
= (EFI_USER_INFO_IDENTITY_POLICY
*) (Info
+ 1);
2171 Policy
->Type
= EFI_USER_INFO_IDENTITY_TRUE
;
2172 Policy
->Length
= sizeof (EFI_USER_INFO_IDENTITY_POLICY
);
2173 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + Policy
->Length
;
2175 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2184 Publish current user information into EFI System Configuration Table.
2186 By UEFI spec, the User Identity Manager will publish the current user profile
2187 into the EFI System Configuration Table. Currently, only the user identifier and user
2190 @retval EFI_SUCCESS Current user information is published successfully.
2191 @retval Others Fail to publish current user information
2200 EFI_CONFIGURATION_TABLE
*EfiConfigurationTable
;
2201 EFI_USER_INFO_TABLE
*UserInfoTable
;
2202 EFI_USER_INFO
*IdInfo
;
2203 EFI_USER_INFO
*NameInfo
;
2205 Status
= EfiGetSystemConfigurationTable (
2206 &gEfiUserManagerProtocolGuid
,
2207 (VOID
**) &EfiConfigurationTable
2209 if (!EFI_ERROR (Status
)) {
2211 // The table existed!
2217 // Get user ID information.
2220 Status
= FindUserInfoByType (mCurrentUser
, &IdInfo
, EFI_USER_INFO_IDENTIFIER_RECORD
);
2221 if (EFI_ERROR (Status
)) {
2226 // Get user name information.
2229 Status
= FindUserInfoByType (mCurrentUser
, &NameInfo
, EFI_USER_INFO_NAME_RECORD
);
2230 if (EFI_ERROR (Status
)) {
2235 // Allocate a buffer for user information table.
2237 UserInfoTable
= (EFI_USER_INFO_TABLE
*) AllocateRuntimePool (
2238 sizeof (EFI_USER_INFO_TABLE
) +
2242 if (UserInfoTable
== NULL
) {
2243 Status
= EFI_OUT_OF_RESOURCES
;
2247 UserInfoTable
->Size
= sizeof (EFI_USER_INFO_TABLE
);
2250 // Append the user information to the user info table
2252 CopyMem ((UINT8
*) UserInfoTable
+ UserInfoTable
->Size
, (UINT8
*) IdInfo
, IdInfo
->InfoSize
);
2253 UserInfoTable
->Size
+= IdInfo
->InfoSize
;
2255 CopyMem ((UINT8
*) UserInfoTable
+ UserInfoTable
->Size
, (UINT8
*) NameInfo
, NameInfo
->InfoSize
);
2256 UserInfoTable
->Size
+= NameInfo
->InfoSize
;
2258 Status
= gBS
->InstallConfigurationTable (&gEfiUserManagerProtocolGuid
, (VOID
*) UserInfoTable
);
2264 Get the user's identity type.
2266 The identify manager only supports the identity policy in which the credential
2267 provider handles are connected by the operator 'AND' or 'OR'.
2270 @param[in] User Handle of a user profile.
2271 @param[out] PolicyType Point to the identity type.
2273 @retval EFI_SUCCESS Get user's identity type successfully.
2274 @retval Others Fail to get user's identity type.
2279 IN EFI_USER_PROFILE_HANDLE User
,
2280 OUT UINT8
*PolicyType
2284 EFI_USER_INFO
*IdentifyInfo
;
2286 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
2289 // Get user identify policy information.
2291 IdentifyInfo
= NULL
;
2292 Status
= FindUserInfoByType (User
, &IdentifyInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
2293 if (EFI_ERROR (Status
)) {
2296 ASSERT (IdentifyInfo
!= NULL
);
2299 // Search the user identify policy according to type.
2302 *PolicyType
= EFI_USER_INFO_IDENTITY_FALSE
;
2303 while (TotalLen
< IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
2304 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1) + TotalLen
);
2305 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_AND
) {
2306 *PolicyType
= EFI_USER_INFO_IDENTITY_AND
;
2310 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_OR
) {
2311 *PolicyType
= EFI_USER_INFO_IDENTITY_OR
;
2314 TotalLen
+= Identity
->Length
;
2321 Identify the User by the specfied provider.
2323 @param[in] User Handle of a user profile.
2324 @param[in] Provider Points to the identifier of credential provider.
2326 @retval EFI_INVALID_PARAMETER Provider is NULL.
2327 @retval EFI_NOT_FOUND Fail to identify the specified user.
2328 @retval EFI_SUCCESS User is identified successfully.
2332 IdentifyByProviderId (
2333 IN EFI_USER_PROFILE_HANDLE User
,
2334 IN EFI_GUID
*Provider
2338 EFI_USER_INFO_IDENTIFIER UserId
;
2340 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon
;
2341 EFI_HII_HANDLE HiiHandle
;
2344 EFI_USER_CREDENTIAL2_PROTOCOL
*UserCredential
;
2346 if (Provider
== NULL
) {
2347 return EFI_INVALID_PARAMETER
;
2351 // Check the user ID identified by the specified credential provider.
2353 for (Index
= 0; Index
< mProviderDb
->Count
; Index
++) {
2355 // Check credential provider class.
2357 UserCredential
= mProviderDb
->Provider
[Index
];
2358 if (CompareGuid (&UserCredential
->Identifier
, Provider
)) {
2359 Status
= UserCredential
->Select (UserCredential
, &AutoLogon
);
2360 if (EFI_ERROR (Status
)) {
2364 if ((AutoLogon
& EFI_CREDENTIAL_LOGON_FLAG_AUTO
) == 0) {
2366 // Get credential provider form.
2368 Status
= UserCredential
->Form (
2374 if (!EFI_ERROR (Status
)) {
2376 // Send form to get user input.
2378 Status
= mCallbackInfo
->FormBrowser2
->SendForm (
2379 mCallbackInfo
->FormBrowser2
,
2387 if (EFI_ERROR (Status
)) {
2393 Status
= UserCredential
->User (UserCredential
, User
, &UserId
);
2394 if (EFI_ERROR (Status
)) {
2398 Status
= UserCredential
->Deselect (UserCredential
);
2399 if (EFI_ERROR (Status
)) {
2407 return EFI_NOT_FOUND
;
2412 Update user information when user is logon on successfully.
2414 @param[in] User Points to user profile.
2416 @retval EFI_SUCCESS Update user information successfully.
2417 @retval Others Fail to update user information.
2422 IN USER_PROFILE_ENTRY
*User
2426 EFI_USER_INFO
*Info
;
2427 EFI_USER_INFO
*NewInfo
;
2428 EFI_USER_INFO_CREATE_DATE Date
;
2429 EFI_USER_INFO_USAGE_COUNT UsageCount
;
2433 // Allocate a buffer to update user's date record and usage record.
2435 InfoLen
= MAX (sizeof (EFI_USER_INFO_CREATE_DATE
), sizeof (EFI_USER_INFO_USAGE_COUNT
));
2436 Info
= AllocateZeroPool (sizeof (EFI_USER_INFO
) + InfoLen
);
2438 return EFI_OUT_OF_RESOURCES
;
2442 // Check create date record.
2445 Status
= FindUserInfoByType (User
, &NewInfo
, EFI_USER_INFO_CREATE_DATE_RECORD
);
2446 if (Status
== EFI_NOT_FOUND
) {
2447 Info
->InfoType
= EFI_USER_INFO_CREATE_DATE_RECORD
;
2448 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2449 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_CREATE_DATE
);
2450 Status
= gRT
->GetTime (&Date
, NULL
);
2451 if (EFI_ERROR (Status
)) {
2456 CopyMem ((UINT8
*) (Info
+ 1), &Date
, sizeof (EFI_USER_INFO_CREATE_DATE
));
2458 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2459 if (EFI_ERROR (Status
)) {
2466 // Update usage date record.
2469 Status
= FindUserInfoByType (User
, &NewInfo
, EFI_USER_INFO_USAGE_DATE_RECORD
);
2470 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_NOT_FOUND
)) {
2471 Info
->InfoType
= EFI_USER_INFO_USAGE_DATE_RECORD
;
2472 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2473 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_USAGE_DATE
);
2474 Status
= gRT
->GetTime (&Date
, NULL
);
2475 if (EFI_ERROR (Status
)) {
2480 CopyMem ((UINT8
*) (Info
+ 1), &Date
, sizeof (EFI_USER_INFO_USAGE_DATE
));
2481 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2482 if (EFI_ERROR (Status
)) {
2489 // Update usage count record.
2493 Status
= FindUserInfoByType (User
, &NewInfo
, EFI_USER_INFO_USAGE_COUNT_RECORD
);
2497 if (Status
== EFI_SUCCESS
) {
2498 CopyMem (&UsageCount
, (UINT8
*) (NewInfo
+ 1), sizeof (EFI_USER_INFO_USAGE_COUNT
));
2502 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_NOT_FOUND
)) {
2503 Info
->InfoType
= EFI_USER_INFO_USAGE_COUNT_RECORD
;
2504 Info
->InfoAttribs
= EFI_USER_INFO_STORAGE_PLATFORM_NV
| EFI_USER_INFO_PUBLIC
| EFI_USER_INFO_EXCLUSIVE
;
2505 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_USAGE_COUNT
);
2506 CopyMem ((UINT8
*) (Info
+ 1), &UsageCount
, sizeof (EFI_USER_INFO_USAGE_COUNT
));
2507 Status
= ModifyUserInfo (User
, &NewInfo
, Info
, Info
->InfoSize
);
2508 if (EFI_ERROR (Status
)) {
2520 Add a credenetial provider item in form.
2522 @param[in] ProviderGuid Points to the identifir of credential provider.
2523 @param[in] OpCodeHandle Points to container for dynamic created opcodes.
2527 AddProviderSelection (
2528 IN EFI_GUID
*ProviderGuid
,
2529 IN VOID
*OpCodeHandle
2532 EFI_HII_HANDLE HiiHandle
;
2533 EFI_STRING_ID ProvID
;
2536 EFI_USER_CREDENTIAL2_PROTOCOL
*UserCredential
;
2538 for (Index
= 0; Index
< mProviderDb
->Count
; Index
++) {
2539 UserCredential
= mProviderDb
->Provider
[Index
];
2540 if (CompareGuid (&UserCredential
->Identifier
, ProviderGuid
)) {
2542 // Add credential provider selection.
2544 UserCredential
->Title (UserCredential
, &HiiHandle
, &ProvID
);
2545 ProvStr
= HiiGetString (HiiHandle
, ProvID
, NULL
);
2546 if (ProvStr
== NULL
) {
2549 ProvID
= HiiSetString (mCallbackInfo
->HiiHandle
, 0, ProvStr
, NULL
);
2551 HiiCreateActionOpCode (
2552 OpCodeHandle
, // Container for dynamic created opcodes
2553 (EFI_QUESTION_ID
)(LABEL_PROVIDER_NAME
+ Index
), // Question ID
2554 ProvID
, // Prompt text
2555 STRING_TOKEN (STR_NULL_STRING
), // Help text
2556 EFI_IFR_FLAG_CALLBACK
, // Question flag
2557 0 // Action String ID
2566 Add a username item in form.
2568 @param[in] Index The index of the user in the user name list.
2569 @param[in] User Points to the user profile whose username is added.
2570 @param[in] OpCodeHandle Points to container for dynamic created opcodes.
2572 @retval EFI_SUCCESS Add a username successfully.
2573 @retval Others Fail to add a username.
2579 IN USER_PROFILE_ENTRY
*User
,
2580 IN VOID
*OpCodeHandle
2583 EFI_STRING_ID UserName
;
2585 EFI_USER_INFO
*UserInfo
;
2588 Status
= FindUserInfoByType (User
, &UserInfo
, EFI_USER_INFO_NAME_RECORD
);
2589 if (EFI_ERROR (Status
)) {
2594 // Add user name selection.
2596 UserName
= HiiSetString (mCallbackInfo
->HiiHandle
, 0, (EFI_STRING
) (UserInfo
+ 1), NULL
);
2597 if (UserName
== 0) {
2598 return EFI_OUT_OF_RESOURCES
;
2601 HiiCreateGotoOpCode (
2602 OpCodeHandle
, // Container for dynamic created opcodes
2603 FORMID_PROVIDER_FORM
, // Target Form ID
2604 UserName
, // Prompt text
2605 STRING_TOKEN (STR_NULL_STRING
), // Help text
2606 EFI_IFR_FLAG_CALLBACK
, // Question flag
2607 (UINT16
) Index
// Question ID
2615 Identify the user whose identity policy does not contain the operator 'OR'.
2617 @param[in] User Points to the user profile.
2619 @retval EFI_SUCCESS The specified user is identified successfully.
2620 @retval Others Fail to identify the user.
2624 IdentifyAndTypeUser (
2625 IN USER_PROFILE_ENTRY
*User
2629 EFI_USER_INFO
*IdentifyInfo
;
2633 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
2636 // Get user identify policy information.
2638 IdentifyInfo
= NULL
;
2639 Status
= FindUserInfoByType (User
, &IdentifyInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
2640 if (EFI_ERROR (Status
)) {
2643 ASSERT (IdentifyInfo
!= NULL
);
2646 // Check each part of identification policy expression.
2650 while (TotalLen
< IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
2651 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1) + TotalLen
);
2652 ValueLen
= Identity
->Length
- sizeof (EFI_USER_INFO_IDENTITY_POLICY
);
2653 switch (Identity
->Type
) {
2655 case EFI_USER_INFO_IDENTITY_FALSE
:
2657 // Check False option.
2662 case EFI_USER_INFO_IDENTITY_TRUE
:
2664 // Check True option.
2669 case EFI_USER_INFO_IDENTITY_NOT
:
2671 // Check negative operation.
2675 case EFI_USER_INFO_IDENTITY_AND
:
2677 // Check and operation.
2680 return EFI_NOT_READY
;
2686 case EFI_USER_INFO_IDENTITY_OR
:
2688 // Check or operation.
2695 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE
:
2697 // Check credential provider by type.
2701 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
:
2703 // Check credential provider by ID.
2705 if (ValueLen
!= sizeof (EFI_GUID
)) {
2706 return EFI_INVALID_PARAMETER
;
2709 Status
= IdentifyByProviderId (User
, (EFI_GUID
*) (Identity
+ 1));
2710 if (EFI_ERROR (Status
)) {
2718 return EFI_INVALID_PARAMETER
;
2722 TotalLen
+= Identity
->Length
;
2725 if (TotalLen
!= IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
2726 return EFI_INVALID_PARAMETER
;
2730 return EFI_NOT_READY
;
2738 Identify the user whose identity policy does not contain the operator 'AND'.
2740 @param[in] User Points to the user profile.
2742 @retval EFI_SUCCESS The specified user is identified successfully.
2743 @retval Others Fail to identify the user.
2747 IdentifyOrTypeUser (
2748 IN USER_PROFILE_ENTRY
*User
2752 EFI_USER_INFO
*IdentifyInfo
;
2755 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
2756 VOID
*StartOpCodeHandle
;
2757 VOID
*EndOpCodeHandle
;
2758 EFI_IFR_GUID_LABEL
*StartLabel
;
2759 EFI_IFR_GUID_LABEL
*EndLabel
;
2762 // Get user identify policy information.
2764 IdentifyInfo
= NULL
;
2765 Status
= FindUserInfoByType (User
, &IdentifyInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
2766 if (EFI_ERROR (Status
)) {
2769 ASSERT (IdentifyInfo
!= NULL
);
2772 // Initialize the container for dynamic opcodes.
2774 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
2775 ASSERT (StartOpCodeHandle
!= NULL
);
2777 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
2778 ASSERT (EndOpCodeHandle
!= NULL
);
2781 // Create Hii Extend Label OpCode.
2783 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2787 sizeof (EFI_IFR_GUID_LABEL
)
2789 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2790 StartLabel
->Number
= LABEL_PROVIDER_NAME
;
2792 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2796 sizeof (EFI_IFR_GUID_LABEL
)
2798 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2799 EndLabel
->Number
= LABEL_END
;
2802 // Add the providers that exists in the user's policy.
2805 while (TotalLen
< IdentifyInfo
->InfoSize
- sizeof (EFI_USER_INFO
)) {
2806 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1) + TotalLen
);
2807 ValueLen
= Identity
->Length
- sizeof (EFI_USER_INFO_IDENTITY_POLICY
);
2808 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER
) {
2809 AddProviderSelection ((EFI_GUID
*) (Identity
+ 1), StartOpCodeHandle
);
2812 TotalLen
+= Identity
->Length
;
2816 mCallbackInfo
->HiiHandle
, // HII handle
2817 &gUserIdentifyManagerGuid
,// Formset GUID
2818 FORMID_PROVIDER_FORM
, // Form ID
2819 StartOpCodeHandle
, // Label for where to insert opcodes
2820 EndOpCodeHandle
// Replace data
2823 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2824 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2831 This function processes the results of changes in configuration.
2833 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2834 @param Action Specifies the type of action taken by the browser.
2835 @param QuestionId A unique value which is sent to the original
2836 exporting driver so that it can identify the type
2838 @param Type The type of value for the question.
2839 @param Value A pointer to the data being sent to the original
2841 @param ActionRequest On return, points to the action requested by the
2844 @retval EFI_SUCCESS The callback successfully handled the action.
2845 @retval Others Fail to handle the action.
2850 UserIdentifyManagerCallback (
2851 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
2852 IN EFI_BROWSER_ACTION Action
,
2853 IN EFI_QUESTION_ID QuestionId
,
2855 IN EFI_IFR_TYPE_VALUE
*Value
,
2856 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
2860 USER_PROFILE_ENTRY
*User
;
2863 VOID
*StartOpCodeHandle
;
2864 VOID
*EndOpCodeHandle
;
2865 EFI_IFR_GUID_LABEL
*StartLabel
;
2866 EFI_IFR_GUID_LABEL
*EndLabel
;
2868 Status
= EFI_SUCCESS
;
2871 case EFI_BROWSER_ACTION_FORM_OPEN
:
2874 // Update user Form when user Form is opened.
2875 // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.
2877 if (QuestionId
!= FORM_OPEN_QUESTION_ID
) {
2882 // Initialize the container for dynamic opcodes.
2884 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
2885 ASSERT (StartOpCodeHandle
!= NULL
);
2887 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
2888 ASSERT (EndOpCodeHandle
!= NULL
);
2891 // Create Hii Extend Label OpCode.
2893 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2897 sizeof (EFI_IFR_GUID_LABEL
)
2899 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2900 StartLabel
->Number
= LABEL_USER_NAME
;
2902 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2906 sizeof (EFI_IFR_GUID_LABEL
)
2908 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2909 EndLabel
->Number
= LABEL_END
;
2912 // Add all the user profile in the user profile database.
2914 for (Index
= 0; Index
< mUserProfileDb
->UserProfileNum
; Index
++) {
2915 User
= (USER_PROFILE_ENTRY
*) mUserProfileDb
->UserProfile
[Index
];
2916 AddUserSelection ((UINT16
)(LABEL_USER_NAME
+ Index
), User
, StartOpCodeHandle
);
2920 mCallbackInfo
->HiiHandle
, // HII handle
2921 &gUserIdentifyManagerGuid
,// Formset GUID
2922 FORMID_USER_FORM
, // Form ID
2923 StartOpCodeHandle
, // Label for where to insert opcodes
2924 EndOpCodeHandle
// Replace data
2927 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2928 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2934 case EFI_BROWSER_ACTION_FORM_CLOSE
:
2935 Status
= EFI_SUCCESS
;
2938 case EFI_BROWSER_ACTION_CHANGING
:
2940 if (QuestionId
>= LABEL_PROVIDER_NAME
) {
2942 // QuestionId comes from the second Form (Select a Credential Provider if identity
2943 // policy is OR type). Identify the user by the selected provider.
2945 Status
= IdentifyByProviderId (mCurrentUser
, &mProviderDb
->Provider
[QuestionId
& 0xFFF]->Identifier
);
2946 if (Status
== EFI_SUCCESS
) {
2948 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
2954 // QuestionId comes from the first Form (Select a user to identify).
2956 User
= (USER_PROFILE_ENTRY
*) mUserProfileDb
->UserProfile
[QuestionId
& 0xFFF];
2957 Status
= GetIdentifyType (User
, &PolicyType
);
2958 if (EFI_ERROR (Status
)) {
2962 if (PolicyType
== EFI_USER_INFO_IDENTITY_OR
) {
2964 // Identify the user by "OR" logical.
2966 Status
= IdentifyOrTypeUser (User
);
2967 if (EFI_ERROR (Status
)) {
2971 mCurrentUser
= (EFI_USER_PROFILE_HANDLE
) User
;
2974 // Identify the user by "AND" logical.
2976 Status
= IdentifyAndTypeUser (User
);
2977 if (EFI_ERROR (Status
)) {
2981 mCurrentUser
= (EFI_USER_PROFILE_HANDLE
) User
;
2983 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
2990 // All other action return unsupported.
2992 Status
= EFI_UNSUPPORTED
;
3002 This function construct user profile database from user data saved in the Flash.
3003 If no user is found in Flash, add one default user "administrator" in the user
3006 @retval EFI_SUCCESS Init user profile database successfully.
3007 @retval Others Fail to init user profile database.
3023 if (mUserProfileDb
!= NULL
) {
3025 // The user profiles had been already initialized.
3031 // Init user profile database structure.
3033 if (!ExpandUsermUserProfileDb ()) {
3034 return EFI_OUT_OF_RESOURCES
;
3037 CurVarSize
= DEFAULT_PROFILE_SIZE
;
3038 VarData
= AllocateZeroPool (CurVarSize
);
3039 if (VarData
== NULL
) {
3040 return EFI_OUT_OF_RESOURCES
;
3044 // Get all user proifle entries.
3049 // Get variable name.
3060 // Get variable value.
3062 VarSize
= CurVarSize
;
3063 Status
= gRT
->GetVariable (VarName
, &gUserIdentifyManagerGuid
, &VarAttr
, &VarSize
, VarData
);
3064 if (Status
== EFI_BUFFER_TOO_SMALL
) {
3066 VarData
= AllocatePool (VarSize
);
3067 if (VarData
== NULL
) {
3068 Status
= EFI_OUT_OF_RESOURCES
;
3072 CurVarSize
= VarSize
;
3073 Status
= gRT
->GetVariable (VarName
, &gUserIdentifyManagerGuid
, &VarAttr
, &VarSize
, VarData
);
3076 if (EFI_ERROR (Status
)) {
3077 if (Status
== EFI_NOT_FOUND
) {
3078 Status
= EFI_SUCCESS
;
3084 // Check variable attributes.
3086 if (VarAttr
!= (EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
)) {
3087 Status
= gRT
->SetVariable (VarName
, &gUserIdentifyManagerGuid
, VarAttr
, 0, NULL
);
3092 // Add user profile to the user profile database.
3094 Status
= AddUserProfile (NULL
, VarSize
, VarData
, FALSE
);
3095 if (EFI_ERROR (Status
)) {
3096 if (Status
== EFI_SECURITY_VIOLATION
) {
3098 // Delete invalid user profile
3100 gRT
->SetVariable (VarName
, &gUserIdentifyManagerGuid
, VarAttr
, 0, NULL
);
3101 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
3106 // Delete and save the profile again if some invalid profiles are deleted.
3108 if (mUserProfileDb
->UserProfileNum
< Index
) {
3109 gRT
->SetVariable (VarName
, &gUserIdentifyManagerGuid
, VarAttr
, 0, NULL
);
3110 SaveNvUserProfile (mUserProfileDb
->UserProfile
[mUserProfileDb
->UserProfileNum
- 1], FALSE
);
3115 if (VarData
!= NULL
) {
3119 if (EFI_ERROR (Status
)) {
3124 // Check whether the user profile database is empty.
3126 if (mUserProfileDb
->UserProfileNum
== 0) {
3127 Status
= AddDefaultUserProfile ();
3135 This function collects all the credential providers and saves to mProviderDb.
3137 @retval EFI_SUCCESS Collect credential providers successfully.
3138 @retval Others Fail to collect credential providers.
3148 EFI_HANDLE
*HandleBuf
;
3151 if (mProviderDb
!= NULL
) {
3153 // The credential providers had been collected before.
3159 // Try to find all the user credential provider driver.
3163 Status
= gBS
->LocateHandleBuffer (
3165 &gEfiUserCredential2ProtocolGuid
,
3170 if (EFI_ERROR (Status
)) {
3175 // Get provider infomation.
3177 mProviderDb
= AllocateZeroPool (
3178 sizeof (CREDENTIAL_PROVIDER_INFO
) -
3179 sizeof (EFI_USER_CREDENTIAL2_PROTOCOL
*) +
3180 HandleCount
* sizeof (EFI_USER_CREDENTIAL2_PROTOCOL
*)
3182 if (mProviderDb
== NULL
) {
3183 FreePool (HandleBuf
);
3184 return EFI_OUT_OF_RESOURCES
;
3187 mProviderDb
->Count
= HandleCount
;
3188 for (Index
= 0; Index
< HandleCount
; Index
++) {
3189 Status
= gBS
->HandleProtocol (
3191 &gEfiUserCredential2ProtocolGuid
,
3192 (VOID
**) &mProviderDb
->Provider
[Index
]
3194 if (EFI_ERROR (Status
)) {
3195 FreePool (HandleBuf
);
3196 FreePool (mProviderDb
);
3202 FreePool (HandleBuf
);
3208 This function allows a caller to extract the current configuration for one
3209 or more named elements from the target driver.
3212 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3213 @param Request A null-terminated Unicode string in <ConfigRequest> format.
3214 @param Progress On return, points to a character in the Request string.
3215 Points to the string's null terminator if request was successful.
3216 Points to the most recent '&' before the first failing name/value
3217 pair (or the beginning of the string if the failure is in the
3218 first name/value pair) if the request was not successful.
3219 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
3220 has all values filled in for the names in the Request string.
3221 String to be allocated by the called function.
3223 @retval EFI_SUCCESS The Results is filled with the requested values.
3224 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
3225 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
3226 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
3232 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3233 IN CONST EFI_STRING Request
,
3234 OUT EFI_STRING
*Progress
,
3235 OUT EFI_STRING
*Results
3238 if (Progress
== NULL
|| Results
== NULL
) {
3239 return EFI_INVALID_PARAMETER
;
3241 *Progress
= Request
;
3242 return EFI_NOT_FOUND
;
3246 This function processes the results of changes in configuration.
3249 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3250 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
3251 @param Progress A pointer to a string filled in with the offset of the most
3252 recent '&' before the first failing name/value pair (or the
3253 beginning of the string if the failure is in the first
3254 name/value pair) or the terminating NULL if all was successful.
3256 @retval EFI_SUCCESS The Results is processed successfully.
3257 @retval EFI_INVALID_PARAMETER Configuration is NULL.
3258 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
3264 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3265 IN CONST EFI_STRING Configuration
,
3266 OUT EFI_STRING
*Progress
3269 if (Configuration
== NULL
|| Progress
== NULL
) {
3270 return EFI_INVALID_PARAMETER
;
3273 return EFI_NOT_FOUND
;
3278 This function initialize the data mainly used in form browser.
3280 @retval EFI_SUCCESS Initialize form data successfully.
3281 @retval Others Fail to Initialize form data.
3290 USER_MANAGER_CALLBACK_INFO
*CallbackInfo
;
3291 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
3292 EFI_HII_STRING_PROTOCOL
*HiiString
;
3293 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
3296 // Initialize driver private data.
3298 CallbackInfo
= AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO
));
3299 if (CallbackInfo
== NULL
) {
3300 return EFI_OUT_OF_RESOURCES
;
3303 CallbackInfo
->Signature
= USER_MANAGER_SIGNATURE
;
3304 CallbackInfo
->ConfigAccess
.ExtractConfig
= FakeExtractConfig
;
3305 CallbackInfo
->ConfigAccess
.RouteConfig
= FakeRouteConfig
;
3306 CallbackInfo
->ConfigAccess
.Callback
= UserIdentifyManagerCallback
;
3309 // Locate Hii Database protocol.
3311 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
3312 if (EFI_ERROR (Status
)) {
3315 CallbackInfo
->HiiDatabase
= HiiDatabase
;
3318 // Locate HiiString protocol.
3320 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
3321 if (EFI_ERROR (Status
)) {
3324 CallbackInfo
->HiiString
= HiiString
;
3327 // Locate Formbrowser2 protocol.
3329 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
3330 if (EFI_ERROR (Status
)) {
3334 CallbackInfo
->FormBrowser2
= FormBrowser2
;
3335 CallbackInfo
->DriverHandle
= NULL
;
3338 // Install Device Path Protocol and Config Access protocol to driver handle.
3340 Status
= gBS
->InstallMultipleProtocolInterfaces (
3341 &CallbackInfo
->DriverHandle
,
3342 &gEfiDevicePathProtocolGuid
,
3343 &mHiiVendorDevicePath
,
3344 &gEfiHiiConfigAccessProtocolGuid
,
3345 &CallbackInfo
->ConfigAccess
,
3348 ASSERT_EFI_ERROR (Status
);
3351 // Publish HII data.
3353 CallbackInfo
->HiiHandle
= HiiAddPackages (
3354 &gUserIdentifyManagerGuid
,
3355 CallbackInfo
->DriverHandle
,
3356 UserIdentifyManagerStrings
,
3357 UserIdentifyManagerVfrBin
,
3360 if (CallbackInfo
->HiiHandle
== NULL
) {
3361 return EFI_OUT_OF_RESOURCES
;
3364 mCallbackInfo
= CallbackInfo
;
3371 Identify the user whose identification policy supports auto logon.
3373 @param[in] ProviderIndex The provider index in the provider list.
3374 @param[out] User Points to user user profile if a user is identified successfully.
3376 @retval EFI_SUCCESS Identify a user with the specified provider successfully.
3377 @retval Others Fail to identify a user.
3381 IdentifyAutoLogonUser (
3382 IN UINTN ProviderIndex
,
3383 OUT USER_PROFILE_ENTRY
**User
3387 EFI_USER_INFO
*Info
;
3390 Info
= AllocateZeroPool (sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_IDENTIFIER
));
3392 return EFI_OUT_OF_RESOURCES
;
3395 Info
->InfoType
= EFI_USER_INFO_IDENTIFIER_RECORD
;
3396 Info
->InfoSize
= sizeof (EFI_USER_INFO
) + sizeof (EFI_USER_INFO_IDENTIFIER
);
3399 // Identify the specified credential provider's auto logon user.
3401 Status
= mProviderDb
->Provider
[ProviderIndex
]->User (
3402 mProviderDb
->Provider
[ProviderIndex
],
3404 (EFI_USER_INFO_IDENTIFIER
*) (Info
+ 1)
3406 if (EFI_ERROR (Status
)) {
3412 // Find user with the specified user ID.
3415 Status
= FindUserProfileByInfo (User
, NULL
, Info
, Info
->InfoSize
);
3417 if (EFI_ERROR (Status
)) {
3421 Status
= GetIdentifyType ((EFI_USER_PROFILE_HANDLE
) * User
, &PolicyType
);
3422 if (PolicyType
== EFI_USER_INFO_IDENTITY_AND
) {
3424 // The identified user need also identified by other credential provider.
3425 // This can handle through select user.
3427 return EFI_NOT_READY
;
3435 Check whether the given console is ready.
3437 @param[in] ProtocolGuid Points to the protocol guid of sonsole .
3439 @retval TRUE The given console is ready.
3440 @retval FALSE The given console is not ready.
3445 EFI_GUID
*ProtocolGuid
3450 EFI_HANDLE
*HandleBuf
;
3452 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
3455 // Try to find all the handle driver.
3459 Status
= gBS
->LocateHandleBuffer (
3466 if (EFI_ERROR (Status
)) {
3470 for (Index
= 0; Index
< HandleCount
; Index
++) {
3471 DevicePath
= DevicePathFromHandle (HandleBuf
[Index
]);
3472 if (DevicePath
!= NULL
) {
3473 FreePool (HandleBuf
);
3477 FreePool (HandleBuf
);
3483 Check whether the console is ready.
3485 @retval TRUE The console is ready.
3486 @retval FALSE The console is not ready.
3494 if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid
)) {
3498 if (!CheckConsole (&gEfiSimpleTextInProtocolGuid
)) {
3499 if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid
)) {
3509 Identify a user to logon.
3511 @param[out] User Points to user user profile if a user is identified successfully.
3513 @retval EFI_SUCCESS Identify a user successfully.
3518 OUT USER_PROFILE_ENTRY
**User
3523 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon
;
3524 EFI_USER_INFO
*IdentifyInfo
;
3525 EFI_USER_INFO_IDENTITY_POLICY
*Identity
;
3526 EFI_USER_CREDENTIAL2_PROTOCOL
*UserCredential
;
3527 USER_PROFILE_ENTRY
*UserEntry
;
3530 // Initialize credential providers.
3532 InitProviderInfo ();
3535 // Initialize user profile database.
3537 InitUserProfileDb ();
3540 // If only one user in system, and its identify policy is TRUE, then auto logon.
3542 if (mUserProfileDb
->UserProfileNum
== 1) {
3543 UserEntry
= (USER_PROFILE_ENTRY
*) mUserProfileDb
->UserProfile
[0];
3544 IdentifyInfo
= NULL
;
3545 Status
= FindUserInfoByType (UserEntry
, &IdentifyInfo
, EFI_USER_INFO_IDENTITY_POLICY_RECORD
);
3546 if (EFI_ERROR (Status
)) {
3549 ASSERT (IdentifyInfo
!= NULL
);
3551 Identity
= (EFI_USER_INFO_IDENTITY_POLICY
*) ((UINT8
*) (IdentifyInfo
+ 1));
3552 if (Identity
->Type
== EFI_USER_INFO_IDENTITY_TRUE
) {
3553 mCurrentUser
= (EFI_USER_PROFILE_HANDLE
) UserEntry
;
3554 UpdateUserInfo (UserEntry
);
3561 // Find and login the default & AutoLogon user.
3563 for (Index
= 0; Index
< mProviderDb
->Count
; Index
++) {
3564 UserCredential
= mProviderDb
->Provider
[Index
];
3565 Status
= UserCredential
->Default (UserCredential
, &AutoLogon
);
3566 if (EFI_ERROR (Status
)) {
3570 if ((AutoLogon
& (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT
| EFI_CREDENTIAL_LOGON_FLAG_AUTO
)) != 0) {
3571 Status
= IdentifyAutoLogonUser (Index
, &UserEntry
);
3572 if (Status
== EFI_SUCCESS
) {
3573 mCurrentUser
= (EFI_USER_PROFILE_HANDLE
) UserEntry
;
3574 UpdateUserInfo (UserEntry
);
3581 if (!IsConsoleReady ()) {
3583 // The console is still not ready for user selection.
3585 return EFI_ACCESS_DENIED
;
3589 // Select a user and identify it.
3591 mCallbackInfo
->FormBrowser2
->SendForm (
3592 mCallbackInfo
->FormBrowser2
,
3593 &mCallbackInfo
->HiiHandle
,
3595 &gUserIdentifyManagerGuid
,
3602 *User
= (USER_PROFILE_ENTRY
*) mCurrentUser
;
3603 UpdateUserInfo (*User
);
3607 return EFI_ACCESS_DENIED
;
3612 An empty function to pass error checking of CreateEventEx ().
3614 @param Event Event whose notification function is being invoked.
3615 @param Context Pointer to the notification function's context,
3616 which is implementation-dependent.
3621 InternalEmptyFuntion (
3630 Create, Signal, and Close the User Profile Changed event.
3634 SignalEventUserProfileChanged (
3641 Status
= gBS
->CreateEventEx (
3644 InternalEmptyFuntion
,
3646 &gEfiEventUserProfileChangedGuid
,
3649 ASSERT_EFI_ERROR (Status
);
3650 gBS
->SignalEvent (Event
);
3651 gBS
->CloseEvent (Event
);
3656 Create a new user profile.
3658 This function creates a new user profile with only a new user identifier attached and returns
3659 its handle. The user profile is non-volatile, but the handle User can change across reboots.
3661 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3662 @param[out] User On return, points to the new user profile handle.
3663 The user profile handle is unique only during this boot.
3665 @retval EFI_SUCCESS User profile was successfully created.
3666 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a
3668 @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.
3669 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3675 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3676 OUT EFI_USER_PROFILE_HANDLE
*User
3681 if ((This
== NULL
) || (User
== NULL
)) {
3682 return EFI_INVALID_PARAMETER
;
3686 // Check the right of the current user.
3688 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE
)) {
3689 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS
)) {
3690 return EFI_ACCESS_DENIED
;
3695 // Create new user profile
3697 Status
= CreateUserProfile ((USER_PROFILE_ENTRY
**) User
);
3698 if (EFI_ERROR (Status
)) {
3699 return EFI_ACCESS_DENIED
;
3706 Delete an existing user profile.
3708 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3709 @param[in] User User profile handle.
3711 @retval EFI_SUCCESS User profile was successfully deleted.
3712 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user
3713 profile or there is only one user profile.
3714 @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.
3715 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.
3721 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3722 IN EFI_USER_PROFILE_HANDLE User
3728 return EFI_INVALID_PARAMETER
;
3732 // Check the right of the current user.
3734 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE
)) {
3735 return EFI_ACCESS_DENIED
;
3739 // Delete user profile.
3741 Status
= DelUserProfile (User
);
3742 if (EFI_ERROR (Status
)) {
3743 if (Status
!= EFI_INVALID_PARAMETER
) {
3744 return EFI_ACCESS_DENIED
;
3746 return EFI_INVALID_PARAMETER
;
3754 Enumerate all of the enrolled users on the platform.
3756 This function returns the next enrolled user profile. To retrieve the first user profile handle,
3757 point User at a NULL. Each subsequent call will retrieve another user profile handle until there
3758 are no more, at which point User will point to NULL.
3760 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3761 @param[in, out] User On entry, points to the previous user profile handle or NULL to
3762 start enumeration. On exit, points to the next user profile handle
3763 or NULL if there are no more user profiles.
3765 @retval EFI_SUCCESS Next enrolled user profile successfully returned.
3766 @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.
3767 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3771 UserProfileGetNext (
3772 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3773 IN OUT EFI_USER_PROFILE_HANDLE
*User
3778 if ((This
== NULL
) || (User
== NULL
)) {
3779 return EFI_INVALID_PARAMETER
;
3782 Status
= FindUserProfile ((USER_PROFILE_ENTRY
**) User
, TRUE
, NULL
);
3783 if (EFI_ERROR (Status
)) {
3784 return EFI_ACCESS_DENIED
;
3791 Return the current user profile handle.
3793 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3794 @param[out] CurrentUser On return, points to the current user profile handle.
3796 @retval EFI_SUCCESS Current user profile handle returned successfully.
3797 @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.
3802 UserProfileCurrent (
3803 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3804 OUT EFI_USER_PROFILE_HANDLE
*CurrentUser
3808 // Get current user profile.
3810 if ((This
== NULL
) || (CurrentUser
== NULL
)) {
3811 return EFI_INVALID_PARAMETER
;
3814 *CurrentUser
= mCurrentUser
;
3822 Identify the user and, if authenticated, returns the user handle and changes the current
3823 user profile. All user information marked as private in a previously selected profile
3824 is no longer available for inspection.
3825 Whenever the current user profile is changed then the an event with the GUID
3826 EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.
3828 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3829 @param[out] User On return, points to the user profile handle for the current
3832 @retval EFI_SUCCESS User was successfully identified.
3833 @retval EFI_ACCESS_DENIED User was not successfully identified.
3834 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3839 UserProfileIdentify (
3840 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3841 OUT EFI_USER_PROFILE_HANDLE
*User
3846 if ((This
== NULL
) || (User
== NULL
)) {
3847 return EFI_INVALID_PARAMETER
;
3850 if (mCurrentUser
!= NULL
) {
3851 *User
= mCurrentUser
;
3858 Status
= IdentifyUser ((USER_PROFILE_ENTRY
**) User
);
3859 if (EFI_ERROR (Status
)) {
3860 return EFI_ACCESS_DENIED
;
3864 // Publish the user info into the EFI system configuration table.
3866 PublishUserTable ();
3869 // Signal User Profile Changed event.
3871 SignalEventUserProfileChanged ();
3876 Find a user using a user information record.
3878 This function searches all user profiles for the specified user information record.
3879 The search starts with the user information record handle following UserInfo and
3880 continues until either the information is found or there are no more user profiles.
3881 A match occurs when the Info.InfoType field matches the user information record
3882 type and the user information record data matches the portion of Info.
3884 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3885 @param[in, out] User On entry, points to the previously returned user profile
3886 handle, or NULL to start searching with the first user profile.
3887 On return, points to the user profile handle, or NULL if not
3889 @param[in, out] UserInfo On entry, points to the previously returned user information
3890 handle, or NULL to start searching with the first. On return,
3891 points to the user information handle of the user information
3892 record, or NULL if not found. Can be NULL, in which case only
3893 one user information record per user can be returned.
3894 @param[in] Info Points to the buffer containing the user information to be
3895 compared to the user information record. If the user information
3896 record data is empty, then only the user information record type
3897 is compared. If InfoSize is 0, then the user information record
3900 @param[in] InfoSize The size of Info, in bytes.
3902 @retval EFI_SUCCESS User information was found. User points to the user profile
3903 handle, and UserInfo points to the user information handle.
3904 @retval EFI_NOT_FOUND User information was not found. User points to NULL, and
3905 UserInfo points to NULL.
3906 @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL.
3912 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3913 IN OUT EFI_USER_PROFILE_HANDLE
*User
,
3914 IN OUT EFI_USER_INFO_HANDLE
*UserInfo OPTIONAL
,
3915 IN CONST EFI_USER_INFO
*Info
,
3922 if ((This
== NULL
) || (User
== NULL
) || (Info
== NULL
)) {
3923 return EFI_INVALID_PARAMETER
;
3926 if (InfoSize
== 0) {
3928 // If InfoSize is 0, then the user information record must be empty.
3930 if (Info
->InfoSize
!= sizeof (EFI_USER_INFO
)) {
3931 return EFI_INVALID_PARAMETER
;
3934 if (InfoSize
!= Info
->InfoSize
) {
3935 return EFI_INVALID_PARAMETER
;
3938 Size
= Info
->InfoSize
;
3941 // Find user profile accdoring to user information.
3943 Status
= FindUserProfileByInfo (
3944 (USER_PROFILE_ENTRY
**) User
,
3945 (EFI_USER_INFO
**) UserInfo
,
3946 (EFI_USER_INFO
*) Info
,
3949 if (EFI_ERROR (Status
)) {
3951 if (UserInfo
!= NULL
) {
3954 return EFI_NOT_FOUND
;
3962 Return information attached to the user.
3964 This function returns user information. The format of the information is described in User
3965 Information. The function may return EFI_ACCESS_DENIED if the information is marked private
3966 and the handle specified by User is not the current user profile. The function may return
3967 EFI_ACCESS_DENIED if the information is marked protected and the information is associated
3968 with a credential provider for which the user has not been authenticated.
3970 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3971 @param[in] User Handle of the user whose profile will be retrieved.
3972 @param[in] UserInfo Handle of the user information data record.
3973 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,
3974 holds the user information. If the buffer is too small to hold the
3975 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is
3976 updated to contain the number of bytes actually required.
3977 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size
3978 of the user information.
3980 @retval EFI_SUCCESS Information returned successfully.
3981 @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the
3983 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the
3984 returned data. The actual size required is returned in *InfoSize.
3985 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer
3986 to a valid user info handle.
3987 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.
3992 UserProfileGetInfo (
3993 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
3994 IN EFI_USER_PROFILE_HANDLE User
,
3995 IN EFI_USER_INFO_HANDLE UserInfo
,
3996 OUT EFI_USER_INFO
*Info
,
3997 IN OUT UINTN
*InfoSize
4002 if ((This
== NULL
) || (InfoSize
== NULL
)) {
4003 return EFI_INVALID_PARAMETER
;
4006 if ((*InfoSize
!= 0) && (Info
== NULL
)) {
4007 return EFI_INVALID_PARAMETER
;
4010 if ((User
== NULL
) || (UserInfo
== NULL
)) {
4011 return EFI_NOT_FOUND
;
4014 Status
= GetUserInfo (User
, UserInfo
, Info
, InfoSize
, TRUE
);
4015 if (EFI_ERROR (Status
)) {
4016 if (Status
== EFI_BUFFER_TOO_SMALL
) {
4017 return EFI_BUFFER_TOO_SMALL
;
4019 return EFI_ACCESS_DENIED
;
4026 Add or update user information.
4028 This function changes user information. If NULL is pointed to by UserInfo, then a new user
4029 information record is created and its handle is returned in UserInfo. Otherwise, the existing
4031 If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same
4032 type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo
4033 will point to the handle of the existing record.
4035 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
4036 @param[in] User Handle of the user whose profile will be retrieved.
4037 @param[in, out] UserInfo Handle of the user information data record.
4038 @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,
4039 holds the user information. If the buffer is too small to hold the
4040 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is
4041 updated to contain the number of bytes actually required.
4042 @param[in] InfoSize On entry, points to the size of Info. On return, points to the size
4043 of the user information.
4045 @retval EFI_SUCCESS Information returned successfully.
4046 @retval EFI_ACCESS_DENIED The record is exclusive.
4047 @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified
4048 user profile or user information record.
4049 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not
4050 refer to a valid user info handle.
4051 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.
4055 UserProfileSetInfo (
4056 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
4057 IN EFI_USER_PROFILE_HANDLE User
,
4058 IN OUT EFI_USER_INFO_HANDLE
*UserInfo
,
4059 IN CONST EFI_USER_INFO
*Info
,
4065 if ((This
== NULL
) || (User
== NULL
) || (UserInfo
== NULL
) || (Info
== NULL
)) {
4066 return EFI_INVALID_PARAMETER
;
4070 // Check the right of the current user.
4072 if (User
!= mCurrentUser
) {
4073 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE
)) {
4074 if (*UserInfo
!= NULL
) {
4076 // Can't update info in other profiles without MANAGE right.
4078 return EFI_SECURITY_VIOLATION
;
4081 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS
)) {
4083 // Can't add info into other profiles.
4085 return EFI_SECURITY_VIOLATION
;
4090 if (User
== mCurrentUser
) {
4091 if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF
)) {
4093 // Only identify policy can be added/updated.
4095 if (Info
->InfoType
!= EFI_USER_INFO_IDENTITY_POLICY_RECORD
) {
4096 return EFI_SECURITY_VIOLATION
;
4102 // Modify user information.
4104 Status
= ModifyUserInfo (User
, (EFI_USER_INFO
**) UserInfo
, Info
, InfoSize
);
4105 if (EFI_ERROR (Status
)) {
4106 if (Status
== EFI_ACCESS_DENIED
) {
4107 return EFI_ACCESS_DENIED
;
4109 return EFI_SECURITY_VIOLATION
;
4116 Called by credential provider to notify of information change.
4118 This function allows the credential provider to notify the User Identity Manager when user status
4119 has changed while deselected.
4120 If the User Identity Manager doesn't support asynchronous changes in credentials, then this function
4121 should return EFI_UNSUPPORTED.
4122 If the User Identity Manager supports this, it will call User() to get the user identifier and then
4123 GetNextInfo() and GetInfo() in the User Credential Protocol to get all of the information from the
4124 credential and add it.
4126 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
4127 @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL2_PROTOCOL
4128 where the user has changed.
4130 @retval EFI_SUCCESS The User Identity Manager has handled the notification.
4131 @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.
4132 @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.
4138 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
4139 IN EFI_HANDLE Changed
4143 EFI_USER_CREDENTIAL2_PROTOCOL
*Provider
;
4144 EFI_USER_INFO_IDENTIFIER UserId
;
4145 EFI_USER_INFO_HANDLE UserInfo
;
4146 EFI_USER_INFO_HANDLE UserInfo2
;
4148 EFI_USER_INFO
*Info
;
4149 USER_PROFILE_ENTRY
*User
;
4152 return EFI_INVALID_PARAMETER
;
4155 Status
= gBS
->HandleProtocol (
4157 &gEfiUserCredential2ProtocolGuid
,
4160 if (EFI_ERROR (Status
)) {
4164 Status
= Provider
->User (Provider
, NULL
, &UserId
);
4165 if (EFI_ERROR (Status
)) {
4166 return EFI_NOT_READY
;
4170 // Find user with the UserId.
4175 // Find next user profile.
4177 Status
= FindUserProfile (&User
, TRUE
, NULL
);
4178 if (EFI_ERROR (Status
)) {
4183 // Find the user information.
4186 FindUserInfoByType (User
, &Info
, EFI_USER_INFO_IDENTIFIER_RECORD
);
4187 if (CompareMem ((UINT8
*) (Info
+ 1), UserId
, sizeof (UserId
)) == 0) {
4189 // Found the infomation record.
4198 // Get user info handle.
4200 Status
= Provider
->GetNextInfo(Provider
, &UserInfo
);
4201 if (EFI_ERROR (Status
)) {
4206 // Get the user information from the user info handle.
4209 Status
= Provider
->GetInfo(Provider
, UserInfo
, NULL
, &InfoSize
);
4210 if (EFI_ERROR (Status
)) {
4211 if (Status
== EFI_BUFFER_TOO_SMALL
) {
4212 Info
= AllocateZeroPool (InfoSize
);
4214 return EFI_OUT_OF_RESOURCES
;
4216 Status
= Provider
->GetInfo(Provider
, UserInfo
, Info
, &InfoSize
);
4217 if (EFI_ERROR (Status
)) {
4226 // Save the user information.
4229 Status
= UserProfileSetInfo (&gUserIdentifyManager
, (EFI_USER_PROFILE_HANDLE
)User
, &UserInfo2
, Info
, InfoSize
);
4231 if (EFI_ERROR (Status
)) {
4241 Delete user information.
4243 Delete the user information attached to the user profile specified by the UserInfo.
4245 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
4246 @param[in] User Handle of the user whose information will be deleted.
4247 @param[in] UserInfo Handle of the user information to remove.
4249 @retval EFI_SUCCESS User information deleted successfully.
4250 @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.
4251 @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information.
4256 UserProfileDeleteInfo (
4257 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
4258 IN EFI_USER_PROFILE_HANDLE User
,
4259 IN EFI_USER_INFO_HANDLE UserInfo
4265 return EFI_INVALID_PARAMETER
;
4269 // Check the right of the current user.
4271 if (User
!= mCurrentUser
) {
4272 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE
)) {
4273 return EFI_ACCESS_DENIED
;
4278 // Delete user information.
4280 Status
= DelUserInfo (User
, UserInfo
, TRUE
);
4281 if (EFI_ERROR (Status
)) {
4282 if (Status
== EFI_NOT_FOUND
) {
4283 return EFI_NOT_FOUND
;
4285 return EFI_ACCESS_DENIED
;
4292 Enumerate user information of all the enrolled users on the platform.
4294 This function returns the next user information record. To retrieve the first user
4295 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve
4296 another user information record handle until there are no more, at which point UserInfo
4299 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
4300 @param[in] User Handle of the user whose information will be deleted.
4301 @param[in, out] UserInfo Handle of the user information to remove.
4303 @retval EFI_SUCCESS User information returned.
4304 @retval EFI_NOT_FOUND No more user information found.
4305 @retval EFI_INVALID_PARAMETER UserInfo is NULL.
4310 UserProfileGetNextInfo (
4311 IN CONST EFI_USER_MANAGER_PROTOCOL
*This
,
4312 IN EFI_USER_PROFILE_HANDLE User
,
4313 IN OUT EFI_USER_INFO_HANDLE
*UserInfo
4316 if ((This
== NULL
) || (UserInfo
== NULL
)) {
4317 return EFI_INVALID_PARAMETER
;
4320 // Get next user information entry.
4322 return FindUserInfo (User
, (EFI_USER_INFO
**) UserInfo
, TRUE
, NULL
);
4327 Main entry for this driver.
4329 @param[in] ImageHandle Image handle this driver.
4330 @param[in] SystemTable Pointer to SystemTable.
4332 @retval EFI_SUCESS This function always complete successfully.
4337 UserIdentifyManagerInit (
4338 IN EFI_HANDLE ImageHandle
,
4339 IN EFI_SYSTEM_TABLE
*SystemTable
4346 // Initiate form browser.
4351 // Install protocol interfaces for the User Identity Manager.
4353 Status
= gBS
->InstallProtocolInterface (
4354 &mCallbackInfo
->DriverHandle
,
4355 &gEfiUserManagerProtocolGuid
,
4356 EFI_NATIVE_INTERFACE
,
4357 &gUserIdentifyManager
4359 ASSERT_EFI_ERROR (Status
);
4361 LoadDeferredImageInit (ImageHandle
);