-/** @file\r
- This driver manages user information and produces user manager protocol.\r
-\r
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "UserIdentifyManager.h"\r
-\r
-//\r
-// Default user name.\r
-//\r
-CHAR16 mUserName[] = L"Administrator";\r
-\r
-//\r
-// Points to the user profile database.\r
-//\r
-USER_PROFILE_DB *mUserProfileDb = NULL;\r
-\r
-//\r
-// Points to the credential providers found in system.\r
-//\r
-CREDENTIAL_PROVIDER_INFO *mProviderDb = NULL;\r
-\r
-//\r
-// Current user shared in multi function.\r
-//\r
-EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;\r
-\r
-//\r
-// Flag indicates a user is identified.\r
-//\r
-BOOLEAN mIdentified = FALSE;\r
-USER_MANAGER_CALLBACK_INFO *mCallbackInfo = NULL;\r
-HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
- {\r
- {\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- {\r
- (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
- (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
- }\r
- },\r
- USER_IDENTIFY_MANAGER_GUID\r
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- (UINT8) (END_DEVICE_PATH_LENGTH),\r
- (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
- }\r
- }\r
-};\r
-\r
-\r
-EFI_USER_MANAGER_PROTOCOL gUserIdentifyManager = {\r
- UserProfileCreate,\r
- UserProfileDelete,\r
- UserProfileGetNext,\r
- UserProfileCurrent,\r
- UserProfileIdentify,\r
- UserProfileFind,\r
- UserProfileNotify,\r
- UserProfileGetInfo,\r
- UserProfileSetInfo,\r
- UserProfileDeleteInfo,\r
- UserProfileGetNextInfo,\r
-};\r
-\r
-\r
-/**\r
- Find the specified user in the user database.\r
-\r
- This function searches the specified user from the beginning of the user database.\r
- And if NextUser is TRUE, return the next User in the user database.\r
-\r
- @param[in, out] User On entry, points to the user profile entry to search.\r
- On return, points to the user profile entry or NULL if not found.\r
- @param[in] NextUser If FALSE, find the user in user profile database specifyed by User\r
- If TRUE, find the next user in user profile database specifyed\r
- by User.\r
- @param[out] ProfileIndex A pointer to the index of user profile database that matches the\r
- user specifyed by User.\r
-\r
- @retval EFI_NOT_FOUND User was NULL, or User was not found, or the next user was not found.\r
- @retval EFI_SUCCESS User or the next user are found in user profile database\r
-\r
-**/\r
-EFI_STATUS\r
-FindUserProfile (\r
- IN OUT USER_PROFILE_ENTRY **User,\r
- IN BOOLEAN NextUser,\r
- OUT UINTN *ProfileIndex OPTIONAL\r
- )\r
-{\r
- UINTN Index;\r
-\r
- //\r
- // Check parameters\r
- //\r
- if ((mUserProfileDb == NULL) || (User == NULL)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Check whether the user profile is in the user profile database.\r
- //\r
- for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
- if (mUserProfileDb->UserProfile[Index] == *User) {\r
- if (ProfileIndex != NULL) {\r
- *ProfileIndex = Index;\r
- }\r
- break;\r
- }\r
- }\r
-\r
- if (NextUser) {\r
- //\r
- // Find the next user profile.\r
- //\r
- Index++;\r
- if (Index < mUserProfileDb->UserProfileNum) {\r
- *User = mUserProfileDb->UserProfile[Index];\r
- } else if (Index == mUserProfileDb->UserProfileNum) {\r
- *User = NULL;\r
- return EFI_NOT_FOUND;\r
- } else {\r
- if ((mUserProfileDb->UserProfileNum > 0) && (*User == NULL)) {\r
- *User = mUserProfileDb->UserProfile[0];\r
- } else {\r
- *User = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
- } else if (Index == mUserProfileDb->UserProfileNum) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Find the specified user information record in the specified User profile.\r
-\r
- This function searches the specified user information record from the beginning of the user\r
- profile. And if NextInfo is TRUE, return the next info in the user profile.\r
-\r
- @param[in] User Points to the user profile entry.\r
- @param[in, out] Info On entry, points to the user information record or NULL to start\r
- searching with the first user information record.\r
- On return, points to the user information record or NULL if not found.\r
- @param[in] NextInfo If FALSE, find the user information record in profile specifyed by User.\r
- If TRUE, find the next user information record in profile specifyed\r
- by User.\r
- @param[out] Offset A pointer to the offset of the information record in the user profile.\r
-\r
- @retval EFI_INVALID_PARAMETER Info is NULL\r
- @retval EFI_NOT_FOUND Info was not found, or the next Info was not found.\r
- @retval EFI_SUCCESS Info or the next info are found in user profile.\r
-\r
-**/\r
-EFI_STATUS\r
-FindUserInfo (\r
- IN USER_PROFILE_ENTRY * User,\r
- IN OUT EFI_USER_INFO **Info,\r
- IN BOOLEAN NextInfo,\r
- OUT UINTN *Offset OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *UserInfo;\r
- UINTN InfoLen;\r
-\r
- if (Info == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check user profile entry\r
- //\r
- Status = FindUserProfile (&User, FALSE, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Find user information in the specified user record.\r
- //\r
- InfoLen = 0;\r
- while (InfoLen < User->UserProfileSize) {\r
- UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
- if (UserInfo == *Info) {\r
- if (Offset != NULL) {\r
- *Offset = InfoLen;\r
- }\r
- break;\r
- }\r
- InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
- }\r
-\r
- //\r
- // Check whether to find the next user information.\r
- //\r
- if (NextInfo) {\r
- if (InfoLen < User->UserProfileSize) {\r
- UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
- InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
- if (InfoLen < User->UserProfileSize) {\r
- *Info = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
- if (Offset != NULL) {\r
- *Offset = InfoLen;\r
- }\r
- } else if (InfoLen == User->UserProfileSize) {\r
- *Info = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
- } else {\r
- if (*Info == NULL) {\r
- *Info = (EFI_USER_INFO *) User->ProfileInfo;\r
- if (Offset != NULL) {\r
- *Offset = 0;\r
- }\r
- } else {\r
- *Info = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
- } else if (InfoLen == User->UserProfileSize) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Find a user infomation record by the information record type.\r
-\r
- This function searches all user information records of User. The search starts with the\r
- user information record following Info and continues until either the information is found\r
- or there are no more user infomation record.\r
- A match occurs when a Info.InfoType field matches the user information record type.\r
-\r
- @param[in] User Points to the user profile record to search.\r
- @param[in, out] Info On entry, points to the user information record or NULL to start\r
- searching with the first user information record.\r
- On return, points to the user information record or NULL if not found.\r
- @param[in] InfoType The infomation type to be searched.\r
-\r
- @retval EFI_SUCCESS User information was found. Info points to the user information record.\r
- @retval EFI_NOT_FOUND User information was not found.\r
- @retval EFI_INVALID_PARAMETER User is NULL or Info is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-FindUserInfoByType (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN OUT EFI_USER_INFO **Info,\r
- IN UINT8 InfoType\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *UserInfo;\r
- UINTN InfoLen;\r
-\r
- if (Info == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check whether the user has the specified user information.\r
- //\r
- InfoLen = 0;\r
- if (*Info == NULL) {\r
- Status = FindUserProfile (&User, FALSE, NULL);\r
- } else {\r
- Status = FindUserInfo (User, Info, TRUE, &InfoLen);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- while (InfoLen < User->UserProfileSize) {\r
- UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);\r
- if (UserInfo->InfoType == InfoType) {\r
- if (UserInfo != *Info) {\r
- *Info = UserInfo;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);\r
- }\r
-\r
- *Info = NULL;\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Find a user using a user information record.\r
-\r
- This function searches all user profiles for the specified user information record. The\r
- search starts with the user information record handle following UserInfo and continues\r
- until either the information is found or there are no more user profiles.\r
- A match occurs when the Info.InfoType field matches the user information record type and the\r
- user information record data matches the portion of Info passed the EFI_USER_INFO header.\r
-\r
- @param[in, out] User On entry, points to the previously returned user profile record,\r
- or NULL to start searching with the first user profile.\r
- On return, points to the user profile entry, or NULL if not found.\r
- @param[in, out] UserInfo On entry, points to the previously returned user information record,\r
- or NULL to start searching with the first.\r
- On return, points to the user information record, or NULL if not found.\r
- @param[in] Info Points to the buffer containing the user information to be compared\r
- to the user information record.\r
- @param[in] InfoSize The size of Info, in bytes. Same as Info->InfoSize.\r
-\r
- @retval EFI_SUCCESS User information was found. User points to the user profile record,\r
- and UserInfo points to the user information record.\r
- @retval EFI_NOT_FOUND User information was not found.\r
- @retval EFI_INVALID_PARAMETER User is NULL; Info is NULL; or, InfoSize is too small.\r
-\r
-**/\r
-EFI_STATUS\r
-FindUserProfileByInfo (\r
- IN OUT USER_PROFILE_ENTRY **User,\r
- IN OUT EFI_USER_INFO **UserInfo, OPTIONAL\r
- IN EFI_USER_INFO *Info,\r
- IN UINTN InfoSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *InfoEntry;\r
-\r
-\r
- if ((User == NULL) || (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (InfoSize < sizeof (EFI_USER_INFO)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (UserInfo != NULL) {\r
- InfoEntry = *UserInfo;\r
- } else {\r
- InfoEntry = NULL;\r
- }\r
- //\r
- // Find user profile according to information.\r
- //\r
- if (*User == NULL) {\r
- *User = mUserProfileDb->UserProfile[0];\r
- }\r
-\r
- //\r
- // Check user profile handle.\r
- //\r
- Status = FindUserProfile (User, FALSE, NULL);\r
-\r
- while (!EFI_ERROR (Status)) {\r
- //\r
- // Find the user information in a user profile.\r
- //\r
- while (TRUE) {\r
- Status = FindUserInfoByType (*User, &InfoEntry, Info->InfoType);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (InfoSize == Info->InfoSize) {\r
- if (CompareMem ((UINT8 *) (InfoEntry + 1), (UINT8 *) (Info + 1), InfoSize - sizeof (EFI_USER_INFO)) == 0) {\r
- //\r
- // Found the infomation record.\r
- //\r
- if (UserInfo != NULL) {\r
- *UserInfo = InfoEntry;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Get next user profile.\r
- //\r
- InfoEntry = NULL;\r
- Status = FindUserProfile (User, TRUE, NULL);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Check whether the access policy is valid.\r
-\r
- @param[in] PolicyInfo Point to the access policy.\r
- @param[in] InfoLen The policy length.\r
-\r
- @retval TRUE The policy is a valid access policy.\r
- @retval FALSE The access policy is not a valid access policy.\r
-\r
-**/\r
-BOOLEAN\r
-CheckAccessPolicy (\r
- IN UINT8 *PolicyInfo,\r
- IN UINTN InfoLen\r
- )\r
-{\r
- UINTN TotalLen;\r
- UINTN ValueLen;\r
- UINTN OffSet;\r
- EFI_USER_INFO_ACCESS_CONTROL Access;\r
- EFI_DEVICE_PATH_PROTOCOL *Path;\r
- UINTN PathSize;\r
-\r
- TotalLen = 0;\r
- while (TotalLen < InfoLen) {\r
- //\r
- // Check access policy according to type.\r
- //\r
- CopyMem (&Access, PolicyInfo + TotalLen, sizeof (Access));\r
- ValueLen = Access.Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
- switch (Access.Type) {\r
- case EFI_USER_INFO_ACCESS_FORBID_LOAD:\r
- case EFI_USER_INFO_ACCESS_PERMIT_LOAD:\r
- case EFI_USER_INFO_ACCESS_FORBID_CONNECT:\r
- case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:\r
- OffSet = 0;\r
- while (OffSet < ValueLen) {\r
- Path = (EFI_DEVICE_PATH_PROTOCOL *) (PolicyInfo + TotalLen + sizeof (Access) + OffSet);\r
- PathSize = GetDevicePathSize (Path);\r
- OffSet += PathSize;\r
- }\r
- if (OffSet != ValueLen) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_ACCESS_SETUP:\r
- if (ValueLen % sizeof (EFI_GUID) != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_ACCESS_BOOT_ORDER:\r
- if (ValueLen % sizeof (EFI_USER_INFO_ACCESS_BOOT_ORDER_HDR) != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_ACCESS_ENROLL_SELF:\r
- case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:\r
- case EFI_USER_INFO_ACCESS_MANAGE:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- default:\r
- return FALSE;\r
- break;\r
- }\r
-\r
- TotalLen += Access.Size;\r
- }\r
-\r
- if (TotalLen != InfoLen) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Check whether the identity policy is valid.\r
-\r
- @param[in] PolicyInfo Point to the identity policy.\r
- @param[in] InfoLen The policy length.\r
-\r
- @retval TRUE The policy is a valid identity policy.\r
- @retval FALSE The access policy is not a valid identity policy.\r
-\r
-**/\r
-BOOLEAN\r
-CheckIdentityPolicy (\r
- IN UINT8 *PolicyInfo,\r
- IN UINTN InfoLen\r
- )\r
-{\r
- UINTN TotalLen;\r
- UINTN ValueLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
-\r
- TotalLen = 0;\r
-\r
- //\r
- // Check each part of policy expression.\r
- //\r
- while (TotalLen < InfoLen) {\r
- //\r
- // Check access polisy according to type.\r
- //\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + TotalLen);\r
- ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
- switch (Identity->Type) {\r
- //\r
- // Check False option.\r
- //\r
- case EFI_USER_INFO_IDENTITY_FALSE:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check True option.\r
- //\r
- case EFI_USER_INFO_IDENTITY_TRUE:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check negative operation.\r
- //\r
- case EFI_USER_INFO_IDENTITY_NOT:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check and operation.\r
- //\r
- case EFI_USER_INFO_IDENTITY_AND:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check or operation.\r
- //\r
- case EFI_USER_INFO_IDENTITY_OR:\r
- if (ValueLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check credential provider by type.\r
- //\r
- case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
- if (ValueLen != sizeof (EFI_GUID)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- //\r
- // Check credential provider by ID.\r
- //\r
- case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
- if (ValueLen != sizeof (EFI_GUID)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- default:\r
- return FALSE;\r
- break;\r
- }\r
-\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- if (TotalLen != InfoLen) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Check whether the user information is a valid user information record.\r
-\r
- @param[in] Info points to the user information.\r
-\r
- @retval TRUE The info is a valid user information record.\r
- @retval FALSE The info is not a valid user information record.\r
-\r
-**/\r
-BOOLEAN\r
-CheckUserInfo (\r
- IN CONST EFI_USER_INFO *Info\r
- )\r
-{\r
- UINTN InfoLen;\r
-\r
- if (Info == NULL) {\r
- return FALSE;\r
- }\r
- //\r
- // Check user information according to information type.\r
- //\r
- InfoLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
- switch (Info->InfoType) {\r
- case EFI_USER_INFO_EMPTY_RECORD:\r
- if (InfoLen != 0) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_NAME_RECORD:\r
- case EFI_USER_INFO_CREDENTIAL_TYPE_NAME_RECORD:\r
- case EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD:\r
- break;\r
-\r
- case EFI_USER_INFO_CREATE_DATE_RECORD:\r
- case EFI_USER_INFO_USAGE_DATE_RECORD:\r
- if (InfoLen != sizeof (EFI_TIME)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_USAGE_COUNT_RECORD:\r
- if (InfoLen != sizeof (UINT64)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTIFIER_RECORD:\r
- if (InfoLen != 16) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_CREDENTIAL_TYPE_RECORD:\r
- case EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD:\r
- case EFI_USER_INFO_GUID_RECORD:\r
- if (InfoLen != sizeof (EFI_GUID)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_PKCS11_RECORD:\r
- case EFI_USER_INFO_CBEFF_RECORD:\r
- break;\r
-\r
- case EFI_USER_INFO_FAR_RECORD:\r
- case EFI_USER_INFO_RETRY_RECORD:\r
- if (InfoLen != 1) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_ACCESS_POLICY_RECORD:\r
- if(!CheckAccessPolicy ((UINT8 *) (Info + 1), InfoLen)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_POLICY_RECORD:\r
- if (!CheckIdentityPolicy ((UINT8 *) (Info + 1), InfoLen)) {\r
- return FALSE;\r
- }\r
- break;\r
-\r
- default:\r
- return FALSE;\r
- break;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Check the user profile data format to be added.\r
-\r
- @param[in] UserProfileInfo Points to the user profile data.\r
- @param[in] UserProfileSize The length of user profile data.\r
-\r
- @retval TRUE It is a valid user profile.\r
- @retval FALSE It is not a valid user profile.\r
-\r
-**/\r
-BOOLEAN\r
-CheckProfileInfo (\r
- IN UINT8 *UserProfileInfo,\r
- IN UINTN UserProfileSize\r
- )\r
-{\r
- UINTN ChkLen;\r
- EFI_USER_INFO *Info;\r
-\r
- if (UserProfileInfo == NULL) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Check user profile information length.\r
- //\r
- ChkLen = 0;\r
- while (ChkLen < UserProfileSize) {\r
- Info = (EFI_USER_INFO *) (UserProfileInfo + ChkLen);\r
- //\r
- // Check user information format.\r
- //\r
- if (!CheckUserInfo (Info)) {\r
- return FALSE;\r
- }\r
-\r
- ChkLen += ALIGN_VARIABLE (Info->InfoSize);\r
- }\r
-\r
- if (ChkLen != UserProfileSize) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Find the specified RightType in current user profile.\r
-\r
- @param[in] RightType Could be EFI_USER_INFO_ACCESS_MANAGE,\r
- EFI_USER_INFO_ACCESS_ENROLL_OTHERS or\r
- EFI_USER_INFO_ACCESS_ENROLL_SELF.\r
-\r
- @retval TRUE Find the specified RightType in current user profile.\r
- @retval FALSE Can't find the right in the profile.\r
-\r
-**/\r
-BOOLEAN\r
-CheckCurrentUserAccessRight (\r
- IN UINT32 RightType\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *Info;\r
- UINTN TotalLen;\r
- UINTN CheckLen;\r
- EFI_USER_INFO_ACCESS_CONTROL Access;\r
-\r
- //\r
- // Get user access right information.\r
- //\r
- Info = NULL;\r
- Status = FindUserInfoByType (\r
- (USER_PROFILE_ENTRY *) mCurrentUser,\r
- &Info,\r
- EFI_USER_INFO_ACCESS_POLICY_RECORD\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- ASSERT (Info != NULL);\r
- TotalLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
- CheckLen = 0;\r
- while (CheckLen < TotalLen) {\r
- //\r
- // Check right according to access type.\r
- //\r
- CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));\r
- if (Access.Type == RightType) {\r
- return TRUE;;\r
- }\r
-\r
- CheckLen += Access.Size;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- Create a unique user identifier.\r
-\r
- @param[out] Identifier This points to the identifier.\r
-\r
-**/\r
-VOID\r
-GenerateIdentifier (\r
- OUT UINT8 *Identifier\r
- )\r
-{\r
- EFI_TIME Time;\r
- UINT64 MonotonicCount;\r
- UINT32 *MonotonicPointer;\r
- UINTN Index;\r
-\r
- //\r
- // Create a unique user identifier.\r
- //\r
- gRT->GetTime (&Time, NULL);\r
- CopyMem (Identifier, &Time, sizeof (EFI_TIME));\r
- //\r
- // Remove zeros.\r
- //\r
- for (Index = 0; Index < sizeof (EFI_TIME); Index++) {\r
- if (Identifier[Index] == 0) {\r
- Identifier[Index] = 0x5a;\r
- }\r
- }\r
-\r
- MonotonicPointer = (UINT32 *) Identifier;\r
- gBS->GetNextMonotonicCount (&MonotonicCount);\r
- MonotonicPointer[0] += (UINT32) MonotonicCount;\r
- MonotonicPointer[1] += (UINT32) MonotonicCount;\r
- MonotonicPointer[2] += (UINT32) MonotonicCount;\r
- MonotonicPointer[3] += (UINT32) MonotonicCount;\r
-}\r
-\r
-\r
-/**\r
- Generate unique user ID.\r
-\r
- @param[out] UserId Points to the user identifer.\r
-\r
-**/\r
-VOID\r
-GenerateUserId (\r
- OUT UINT8 *UserId\r
- )\r
-{\r
- EFI_STATUS Status;\r
- USER_PROFILE_ENTRY *UserProfile;\r
- EFI_USER_INFO *UserInfo;\r
- UINTN Index;\r
-\r
- //\r
- // Generate unique user ID\r
- //\r
- while (TRUE) {\r
- GenerateIdentifier (UserId);\r
- //\r
- // Check whether it's unique in user profile database.\r
- //\r
- if (mUserProfileDb == NULL) {\r
- return ;\r
- }\r
-\r
- for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
- UserProfile = (USER_PROFILE_ENTRY *) (mUserProfileDb->UserProfile[Index]);\r
- UserInfo = NULL;\r
- Status = FindUserInfoByType (UserProfile, &UserInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (CompareMem ((UINT8 *) (UserInfo + 1), UserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == mUserProfileDb->UserProfileNum) {\r
- return ;\r
- }\r
- }\r
-}\r
-\r
-\r
-/**\r
- Expand user profile database.\r
-\r
- @retval TRUE Success to expand user profile database.\r
- @retval FALSE Fail to expand user profile database.\r
-\r
-**/\r
-BOOLEAN\r
-ExpandUsermUserProfileDb (\r
- VOID\r
- )\r
-{\r
- UINTN MaxNum;\r
- USER_PROFILE_DB *NewDataBase;\r
-\r
- //\r
- // Create new user profile database.\r
- //\r
- if (mUserProfileDb == NULL) {\r
- MaxNum = USER_NUMBER_INC;\r
- } else {\r
- MaxNum = mUserProfileDb->MaxProfileNum + USER_NUMBER_INC;\r
- }\r
-\r
- NewDataBase = AllocateZeroPool (\r
- sizeof (USER_PROFILE_DB) - sizeof (EFI_USER_PROFILE_HANDLE) +\r
- MaxNum * sizeof (EFI_USER_PROFILE_HANDLE)\r
- );\r
- if (NewDataBase == NULL) {\r
- return FALSE;\r
- }\r
-\r
- NewDataBase->MaxProfileNum = MaxNum;\r
-\r
- //\r
- // Copy old user profile database value\r
- //\r
- if (mUserProfileDb == NULL) {\r
- NewDataBase->UserProfileNum = 0;\r
- } else {\r
- NewDataBase->UserProfileNum = mUserProfileDb->UserProfileNum;\r
- CopyMem (\r
- NewDataBase->UserProfile,\r
- mUserProfileDb->UserProfile,\r
- NewDataBase->UserProfileNum * sizeof (EFI_USER_PROFILE_HANDLE)\r
- );\r
- FreePool (mUserProfileDb);\r
- }\r
-\r
- mUserProfileDb = NewDataBase;\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Expand user profile\r
-\r
- @param[in] User Points to user profile.\r
- @param[in] ExpandSize The size of user profile.\r
-\r
- @retval TRUE Success to expand user profile size.\r
- @retval FALSE Fail to expand user profile size.\r
-\r
-**/\r
-BOOLEAN\r
-ExpandUserProfile (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN UINTN ExpandSize\r
- )\r
-{\r
- UINT8 *Info;\r
- UINTN InfoSizeInc;\r
-\r
- //\r
- // Allocate new memory.\r
- //\r
- InfoSizeInc = 128;\r
- User->MaxProfileSize += ((ExpandSize + InfoSizeInc - 1) / InfoSizeInc) * InfoSizeInc;\r
- Info = AllocateZeroPool (User->MaxProfileSize);\r
- if (Info == NULL) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Copy exist information.\r
- //\r
- if (User->UserProfileSize > 0) {\r
- CopyMem (Info, User->ProfileInfo, User->UserProfileSize);\r
- FreePool (User->ProfileInfo);\r
- }\r
-\r
- User->ProfileInfo = Info;\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Save the user profile to non-volatile memory, or delete it from non-volatile memory.\r
-\r
- @param[in] User Point to the user profile\r
- @param[in] Delete If TRUE, delete the found user profile.\r
- If FALSE, save the user profile.\r
- @retval EFI_SUCCESS Save or delete user profile successfully.\r
- @retval Others Fail to change the profile.\r
-\r
-**/\r
-EFI_STATUS\r
-SaveNvUserProfile (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN BOOLEAN Delete\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check user profile entry.\r
- //\r
- Status = FindUserProfile (&User, FALSE, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Save the user profile to non-volatile memory.\r
- //\r
- Status = gRT->SetVariable (\r
- User->UserVarName,\r
- &gUserIdentifyManagerGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- Delete ? 0 : User->UserProfileSize,\r
- User->ProfileInfo\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- Add one new user info into the user's profile.\r
-\r
- @param[in] User point to the user profile\r
- @param[in] Info Points to the user information payload.\r
- @param[in] InfoSize The size of the user information payload, in bytes.\r
- @param[out] UserInfo Point to the new info in user profile\r
- @param[in] Save If TRUE, save the profile to NV flash.\r
- If FALSE, don't need to save the profile to NV flash.\r
-\r
- @retval EFI_SUCCESS Add user info to user profile successfully.\r
- @retval Others Fail to add user info to user profile.\r
-\r
-**/\r
-EFI_STATUS\r
-AddUserInfo (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN UINT8 *Info,\r
- IN UINTN InfoSize,\r
- OUT EFI_USER_INFO **UserInfo, OPTIONAL\r
- IN BOOLEAN Save\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((Info == NULL) || (User == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check user profile handle.\r
- //\r
- Status = FindUserProfile (&User, FALSE, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check user information memory size.\r
- //\r
- if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (InfoSize)) {\r
- if (!ExpandUserProfile (User, ALIGN_VARIABLE (InfoSize))) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- //\r
- // Add new user information.\r
- //\r
- CopyMem (User->ProfileInfo + User->UserProfileSize, Info, InfoSize);\r
- if (UserInfo != NULL) {\r
- *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);\r
- }\r
- User->UserProfileSize += ALIGN_VARIABLE (InfoSize);\r
-\r
- //\r
- // Save user profile information.\r
- //\r
- if (Save) {\r
- Status = SaveNvUserProfile (User, FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Get the user info from the specified user info handle.\r
-\r
- @param[in] User Point to the user profile.\r
- @param[in] UserInfo Point to the user information record to get.\r
- @param[out] Info On entry, points to a buffer of at least *InfoSize bytes.\r
- On exit, holds the user information.\r
- @param[in, out] InfoSize On entry, points to the size of Info.\r
- On return, points to the size of the user information.\r
- @param[in] ChkRight If TRUE, check the user info attribute.\r
- If FALSE, don't check the user info attribute.\r
-\r
-\r
- @retval EFI_ACCESS_DENIED The information cannot be accessed by the current user.\r
- @retval EFI_INVALID_PARAMETER InfoSize is NULL or UserInfo is NULL.\r
- @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the\r
- returned data. The actual size required is returned in *InfoSize.\r
- @retval EFI_SUCCESS Information returned successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-GetUserInfo (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN EFI_USER_INFO *UserInfo,\r
- OUT EFI_USER_INFO *Info,\r
- IN OUT UINTN *InfoSize,\r
- IN BOOLEAN ChkRight\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((InfoSize == NULL) || (UserInfo == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((*InfoSize != 0) && (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Find the user information to get.\r
- //\r
- Status = FindUserInfo (User, &UserInfo, FALSE, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check information attributes.\r
- //\r
- if (ChkRight) {\r
- switch (UserInfo->InfoAttribs & EFI_USER_INFO_ACCESS) {\r
- case EFI_USER_INFO_PRIVATE:\r
- case EFI_USER_INFO_PROTECTED:\r
- if (User != mCurrentUser) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_PUBLIC:\r
- break;\r
-\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Get user information.\r
- //\r
- if (UserInfo->InfoSize > *InfoSize) {\r
- *InfoSize = UserInfo->InfoSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- *InfoSize = UserInfo->InfoSize;\r
- if (Info != NULL) {\r
- CopyMem (Info, UserInfo, *InfoSize);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Delete the specified user information from user profile.\r
-\r
- @param[in] User Point to the user profile.\r
- @param[in] Info Point to the user information record to delete.\r
- @param[in] Save If TRUE, save the profile to NV flash.\r
- If FALSE, don't need to save the profile to NV flash.\r
-\r
- @retval EFI_SUCCESS Delete user info from user profile successfully.\r
- @retval Others Fail to delete user info from user profile.\r
-\r
-**/\r
-EFI_STATUS\r
-DelUserInfo (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN EFI_USER_INFO *Info,\r
- IN BOOLEAN Save\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Offset;\r
- UINTN NextOffset;\r
-\r
- //\r
- // Check user information handle.\r
- //\r
- Status = FindUserInfo (User, &Info, FALSE, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Delete the specified user information.\r
- //\r
- NextOffset = Offset + ALIGN_VARIABLE (Info->InfoSize);\r
- User->UserProfileSize -= ALIGN_VARIABLE (Info->InfoSize);\r
- if (Offset < User->UserProfileSize) {\r
- CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);\r
- }\r
-\r
- if (Save) {\r
- Status = SaveNvUserProfile (User, FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Add or update user information.\r
-\r
- @param[in] User Point to the user profile.\r
- @param[in, out] UserInfo On entry, points to the user information to modify,\r
- or NULL to add a new UserInfo.\r
- On return, points to the modified user information.\r
- @param[in] Info Points to the new user information.\r
- @param[in] InfoSize The size of Info,in bytes.\r
-\r
- @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.\r
- @retval EFI_ACCESS_DENIED The record is exclusive.\r
- @retval EFI_SUCCESS User information was successfully changed/added.\r
-\r
-**/\r
-EFI_STATUS\r
-ModifyUserInfo (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN OUT EFI_USER_INFO **UserInfo,\r
- IN CONST EFI_USER_INFO *Info,\r
- IN UINTN InfoSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN PayloadLen;\r
- EFI_USER_INFO *OldInfo;\r
-\r
- if ((UserInfo == NULL) || (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (InfoSize < sizeof (EFI_USER_INFO) || InfoSize != Info->InfoSize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check user information.\r
- //\r
- if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- if (!CheckUserInfo (Info)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
-\r
- if (*UserInfo == NULL) {\r
- //\r
- // Add new user information.\r
- //\r
- OldInfo = NULL;\r
- do {\r
- Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- ASSERT (OldInfo != NULL);\r
-\r
- if (((OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) ||\r
- ((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0)) {\r
- //\r
- // Same type can not co-exist for exclusive information.\r
- //\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Check whether it exists in DB.\r
- //\r
- if (Info->InfoSize != OldInfo->InfoSize) {\r
- continue;\r
- }\r
-\r
- if (!CompareGuid (&OldInfo->Credential, &Info->Credential)) {\r
- continue;\r
- }\r
-\r
- PayloadLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
- if (PayloadLen == 0) {\r
- continue;\r
- }\r
-\r
- if (CompareMem ((UINT8 *)(OldInfo + 1), (UINT8 *)(Info + 1), PayloadLen) != 0) {\r
- continue;\r
- }\r
-\r
- //\r
- // Yes. The new info is as same as the one in profile.\r
- //\r
- return EFI_SUCCESS;\r
- } while (!EFI_ERROR (Status));\r
-\r
- Status = AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
- return Status;\r
- }\r
-\r
- //\r
- // Modify existing user information.\r
- //\r
- OldInfo = *UserInfo;\r
- if (OldInfo->InfoType != Info->InfoType) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) &&\r
- (OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) == 0) {\r
- //\r
- // Try to add exclusive attrib in new info.\r
- // Check whether there is another information with the same type in profile.\r
- //\r
- OldInfo = NULL;\r
- do {\r
- Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- if (OldInfo != *UserInfo) {\r
- //\r
- // There is another information with the same type in profile.\r
- // Therefore, can't modify existing user information to add exclusive attribute.\r
- //\r
- return EFI_ACCESS_DENIED;\r
- }\r
- } while (TRUE);\r
- }\r
-\r
- Status = DelUserInfo (User, *UserInfo, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
-}\r
-\r
-\r
-/**\r
- Delete the user profile from non-volatile memory and database.\r
-\r
- @param[in] User Points to the user profile.\r
-\r
- @retval EFI_SUCCESS Delete user from the user profile successfully.\r
- @retval Others Fail to delete user from user profile\r
-\r
-**/\r
-EFI_STATUS\r
-DelUserProfile (\r
- IN USER_PROFILE_ENTRY *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
-\r
- //\r
- // Check whether it is in the user profile database.\r
- //\r
- Status = FindUserProfile (&User, FALSE, &Index);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check whether it is the current user.\r
- //\r
- if (User == mCurrentUser) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Delete user profile from the non-volatile memory.\r
- //\r
- Status = SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- mUserProfileDb->UserProfileNum--;\r
-\r
- //\r
- // Modify user profile database.\r
- //\r
- if (Index != mUserProfileDb->UserProfileNum) {\r
- mUserProfileDb->UserProfile[Index] = mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum];\r
- CopyMem (\r
- ((USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index])->UserVarName,\r
- User->UserVarName,\r
- sizeof (User->UserVarName)\r
- );\r
- Status = SaveNvUserProfile (mUserProfileDb->UserProfile[Index], FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- //\r
- // Delete user profile information.\r
- //\r
- if (User->ProfileInfo != NULL) {\r
- FreePool (User->ProfileInfo);\r
- }\r
-\r
- FreePool (User);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Add user profile to user profile database.\r
-\r
- @param[out] UserProfile Point to the newly added user profile.\r
- @param[in] ProfileSize The size of the user profile.\r
- @param[in] ProfileInfo Point to the user profie data.\r
- @param[in] Save If TRUE, save the new added profile to NV flash.\r
- If FALSE, don't save the profile to NV flash.\r
-\r
- @retval EFI_SUCCESS Add user profile to user profile database successfully.\r
- @retval Others Fail to add user profile to user profile database.\r
-\r
-**/\r
-EFI_STATUS\r
-AddUserProfile (\r
- OUT USER_PROFILE_ENTRY **UserProfile, OPTIONAL\r
- IN UINTN ProfileSize,\r
- IN UINT8 *ProfileInfo,\r
- IN BOOLEAN Save\r
- )\r
-{\r
- EFI_STATUS Status;\r
- USER_PROFILE_ENTRY *User;\r
-\r
- //\r
- // Check the data format to be added.\r
- //\r
- if (!CheckProfileInfo (ProfileInfo, ProfileSize)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Create user profile entry.\r
- //\r
- User = AllocateZeroPool (sizeof (USER_PROFILE_ENTRY));\r
- if (User == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Add the entry to the user profile database.\r
- //\r
- if (mUserProfileDb->UserProfileNum == mUserProfileDb->MaxProfileNum) {\r
- if (!ExpandUsermUserProfileDb ()) {\r
- FreePool (User);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- UnicodeSPrint (\r
- User->UserVarName,\r
- sizeof (User->UserVarName),\r
- L"User%04x",\r
- mUserProfileDb->UserProfileNum\r
- );\r
- User->UserProfileSize = 0;\r
- User->MaxProfileSize = 0;\r
- User->ProfileInfo = NULL;\r
- mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum] = (EFI_USER_PROFILE_HANDLE) User;\r
- mUserProfileDb->UserProfileNum++;\r
-\r
- //\r
- // Add user profile information.\r
- //\r
- Status = AddUserInfo (User, ProfileInfo, ProfileSize, NULL, Save);\r
- if (EFI_ERROR (Status)) {\r
- DelUserProfile (User);\r
- return Status;\r
- }\r
- //\r
- // Set new user profile handle.\r
- //\r
- if (UserProfile != NULL) {\r
- *UserProfile = User;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- This function creates a new user profile with only a new user identifier\r
- attached and returns its handle. The user profile is non-volatile, but the\r
- handle User can change across reboots.\r
-\r
- @param[out] User Handle of a new user profile.\r
-\r
- @retval EFI_SUCCESS User profile was successfully created.\r
- @retval Others Fail to create user profile\r
-\r
-**/\r
-EFI_STATUS\r
-CreateUserProfile (\r
- OUT USER_PROFILE_ENTRY **User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *UserInfo;\r
-\r
- if (User == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Generate user id information.\r
- //\r
- UserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
- if (UserInfo == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- UserInfo->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
- UserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
- UserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- GenerateUserId ((UINT8 *) (UserInfo + 1));\r
-\r
- //\r
- // Add user profile to the user profile database.\r
- //\r
- Status = AddUserProfile (User, UserInfo->InfoSize, (UINT8 *) UserInfo, TRUE);\r
- FreePool (UserInfo);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Add a default user profile to user profile database.\r
-\r
- @retval EFI_SUCCESS A default user profile is added successfully.\r
- @retval Others Fail to add a default user profile\r
-\r
-**/\r
-EFI_STATUS\r
-AddDefaultUserProfile (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- USER_PROFILE_ENTRY *User;\r
- EFI_USER_INFO *Info;\r
- EFI_USER_INFO *NewInfo;\r
- EFI_USER_INFO_CREATE_DATE CreateDate;\r
- EFI_USER_INFO_USAGE_COUNT UsageCount;\r
- EFI_USER_INFO_ACCESS_CONTROL *Access;\r
- EFI_USER_INFO_IDENTITY_POLICY *Policy;\r
-\r
- //\r
- // Create a user profile.\r
- //\r
- Status = CreateUserProfile (&User);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Allocate a buffer to add all default user information.\r
- //\r
- Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + INFO_PAYLOAD_SIZE);\r
- if (Info == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Add user name.\r
- //\r
- Info->InfoType = EFI_USER_INFO_NAME_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (mUserName);\r
- CopyMem ((UINT8 *) (Info + 1), mUserName, sizeof (mUserName));\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Add user profile create date record.\r
- //\r
- Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
- Status = gRT->GetTime (&CreateDate, NULL);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- CopyMem ((UINT8 *) (Info + 1), &CreateDate, sizeof (EFI_USER_INFO_CREATE_DATE));\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Add user profile usage count record.\r
- //\r
- Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
- UsageCount = 0;\r
- CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Add user access right.\r
- //\r
- Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Access = (EFI_USER_INFO_ACCESS_CONTROL *) (Info + 1);\r
- Access->Type = EFI_USER_INFO_ACCESS_MANAGE;\r
- Access->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + Access->Size;\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Add user identity policy.\r
- //\r
- Info->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PRIVATE | EFI_USER_INFO_EXCLUSIVE;\r
- Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (Info + 1);\r
- Policy->Type = EFI_USER_INFO_IDENTITY_TRUE;\r
- Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length;\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
-\r
-Done:\r
- FreePool (Info);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Publish current user information into EFI System Configuration Table.\r
-\r
- By UEFI spec, the User Identity Manager will publish the current user profile\r
- into the EFI System Configuration Table. Currently, only the user identifier and user\r
- name are published.\r
-\r
- @retval EFI_SUCCESS Current user information is published successfully.\r
- @retval Others Fail to publish current user information\r
-\r
-**/\r
-EFI_STATUS\r
-PublishUserTable (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_CONFIGURATION_TABLE *EfiConfigurationTable;\r
- EFI_USER_INFO_TABLE *UserInfoTable;\r
- EFI_USER_INFO *IdInfo;\r
- EFI_USER_INFO *NameInfo;\r
-\r
- Status = EfiGetSystemConfigurationTable (\r
- &gEfiUserManagerProtocolGuid,\r
- (VOID **) &EfiConfigurationTable\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // The table existed!\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Get user ID information.\r
- //\r
- IdInfo = NULL;\r
- Status = FindUserInfoByType (mCurrentUser, &IdInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
-\r
- }\r
- //\r
- // Get user name information.\r
- //\r
- NameInfo = NULL;\r
- Status = FindUserInfoByType (mCurrentUser, &NameInfo, EFI_USER_INFO_NAME_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Allocate a buffer for user information table.\r
- //\r
- UserInfoTable = (EFI_USER_INFO_TABLE *) AllocateRuntimePool (\r
- sizeof (EFI_USER_INFO_TABLE) +\r
- IdInfo->InfoSize +\r
- NameInfo->InfoSize\r
- );\r
- if (UserInfoTable == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- return Status;\r
- }\r
-\r
- UserInfoTable->Size = sizeof (EFI_USER_INFO_TABLE);\r
-\r
- //\r
- // Append the user information to the user info table\r
- //\r
- CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) IdInfo, IdInfo->InfoSize);\r
- UserInfoTable->Size += IdInfo->InfoSize;\r
-\r
- CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) NameInfo, NameInfo->InfoSize);\r
- UserInfoTable->Size += NameInfo->InfoSize;\r
-\r
- Status = gBS->InstallConfigurationTable (&gEfiUserManagerProtocolGuid, (VOID *) UserInfoTable);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Get the user's identity type.\r
-\r
- The identify manager only supports the identity policy in which the credential\r
- provider handles are connected by the operator 'AND' or 'OR'.\r
-\r
-\r
- @param[in] User Handle of a user profile.\r
- @param[out] PolicyType Point to the identity type.\r
-\r
- @retval EFI_SUCCESS Get user's identity type successfully.\r
- @retval Others Fail to get user's identity type.\r
-\r
-**/\r
-EFI_STATUS\r
-GetIdentifyType (\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- OUT UINT8 *PolicyType\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *IdentifyInfo;\r
- UINTN TotalLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
-\r
- //\r
- // Get user identify policy information.\r
- //\r
- IdentifyInfo = NULL;\r
- Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- ASSERT (IdentifyInfo != NULL);\r
-\r
- //\r
- // Search the user identify policy according to type.\r
- //\r
- TotalLen = 0;\r
- *PolicyType = EFI_USER_INFO_IDENTITY_FALSE;\r
- while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_AND) {\r
- *PolicyType = EFI_USER_INFO_IDENTITY_AND;\r
- break;\r
- }\r
-\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_OR) {\r
- *PolicyType = EFI_USER_INFO_IDENTITY_OR;\r
- break;\r
- }\r
- TotalLen += Identity->Length;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Identify the User by the specfied provider.\r
-\r
- @param[in] User Handle of a user profile.\r
- @param[in] Provider Points to the identifier of credential provider.\r
-\r
- @retval EFI_INVALID_PARAMETER Provider is NULL.\r
- @retval EFI_NOT_FOUND Fail to identify the specified user.\r
- @retval EFI_SUCCESS User is identified successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-IdentifyByProviderId (\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- IN EFI_GUID *Provider\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO_IDENTIFIER UserId;\r
- UINTN Index;\r
- EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_GUID FormSetId;\r
- EFI_FORM_ID FormId;\r
- EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
-\r
- if (Provider == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the user ID identified by the specified credential provider.\r
- //\r
- for (Index = 0; Index < mProviderDb->Count; Index++) {\r
- //\r
- // Check credential provider class.\r
- //\r
- UserCredential = mProviderDb->Provider[Index];\r
- if (CompareGuid (&UserCredential->Identifier, Provider)) {\r
- Status = UserCredential->Select (UserCredential, &AutoLogon);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((AutoLogon & EFI_CREDENTIAL_LOGON_FLAG_AUTO) == 0) {\r
- //\r
- // Get credential provider form.\r
- //\r
- Status = UserCredential->Form (\r
- UserCredential,\r
- &HiiHandle,\r
- &FormSetId,\r
- &FormId\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Send form to get user input.\r
- //\r
- Status = mCallbackInfo->FormBrowser2->SendForm (\r
- mCallbackInfo->FormBrowser2,\r
- &HiiHandle,\r
- 1,\r
- &FormSetId,\r
- FormId,\r
- NULL,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- }\r
-\r
- Status = UserCredential->User (UserCredential, User, &UserId);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = UserCredential->Deselect (UserCredential);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Update user information when user is logon on successfully.\r
-\r
- @param[in] User Points to user profile.\r
-\r
- @retval EFI_SUCCESS Update user information successfully.\r
- @retval Others Fail to update user information.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateUserInfo (\r
- IN USER_PROFILE_ENTRY *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *Info;\r
- EFI_USER_INFO *NewInfo;\r
- EFI_USER_INFO_CREATE_DATE Date;\r
- EFI_USER_INFO_USAGE_COUNT UsageCount;\r
- UINTN InfoLen;\r
-\r
- //\r
- // Allocate a buffer to update user's date record and usage record.\r
- //\r
- InfoLen = MAX (sizeof (EFI_USER_INFO_CREATE_DATE), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
- Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + InfoLen);\r
- if (Info == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Check create date record.\r
- //\r
- NewInfo = NULL;\r
- Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_CREATE_DATE_RECORD);\r
- if (Status == EFI_NOT_FOUND) {\r
- Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
- Status = gRT->GetTime (&Date, NULL);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
-\r
- CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));\r
- NewInfo = NULL;\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Update usage date record.\r
- //\r
- NewInfo = NULL;\r
- Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_DATE_RECORD);\r
- if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
- Info->InfoType = EFI_USER_INFO_USAGE_DATE_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_DATE);\r
- Status = gRT->GetTime (&Date, NULL);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
-\r
- CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_USAGE_DATE));\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Update usage count record.\r
- //\r
- UsageCount = 0;\r
- NewInfo = NULL;\r
- Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_COUNT_RECORD);\r
- //\r
- // Get usage count.\r
- //\r
- if (Status == EFI_SUCCESS) {\r
- CopyMem (&UsageCount, (UINT8 *) (NewInfo + 1), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
- }\r
-\r
- UsageCount++;\r
- if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
- Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
- Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
- CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
- Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
- }\r
-\r
- FreePool (Info);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Add a credenetial provider item in form.\r
-\r
- @param[in] ProviderGuid Points to the identifir of credential provider.\r
- @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
-\r
-**/\r
-VOID\r
-AddProviderSelection (\r
- IN EFI_GUID *ProviderGuid,\r
- IN VOID *OpCodeHandle\r
- )\r
-{\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_STRING_ID ProvID;\r
- CHAR16 *ProvStr;\r
- UINTN Index;\r
- EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
-\r
- for (Index = 0; Index < mProviderDb->Count; Index++) {\r
- UserCredential = mProviderDb->Provider[Index];\r
- if (CompareGuid (&UserCredential->Identifier, ProviderGuid)) {\r
- //\r
- // Add credential provider selection.\r
- //\r
- UserCredential->Title (UserCredential, &HiiHandle, &ProvID);\r
- ProvStr = HiiGetString (HiiHandle, ProvID, NULL);\r
- if (ProvStr == NULL) {\r
- continue ;\r
- }\r
- ProvID = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);\r
- FreePool (ProvStr);\r
- HiiCreateActionOpCode (\r
- OpCodeHandle, // Container for dynamic created opcodes\r
- (EFI_QUESTION_ID)(LABEL_PROVIDER_NAME + Index), // Question ID\r
- ProvID, // Prompt text\r
- STRING_TOKEN (STR_NULL_STRING), // Help text\r
- EFI_IFR_FLAG_CALLBACK, // Question flag\r
- 0 // Action String ID\r
- );\r
- break;\r
- }\r
- }\r
-}\r
-\r
-\r
-/**\r
- Add a username item in form.\r
-\r
- @param[in] Index The index of the user in the user name list.\r
- @param[in] User Points to the user profile whose username is added.\r
- @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
-\r
- @retval EFI_SUCCESS Add a username successfully.\r
- @retval Others Fail to add a username.\r
-\r
-**/\r
-EFI_STATUS\r
-AddUserSelection (\r
- IN UINT16 Index,\r
- IN USER_PROFILE_ENTRY *User,\r
- IN VOID *OpCodeHandle\r
- )\r
-{\r
- EFI_STRING_ID UserName;\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *UserInfo;\r
-\r
- UserInfo = NULL;\r
- Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_NAME_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Add user name selection.\r
- //\r
- UserName = HiiSetString (mCallbackInfo->HiiHandle, 0, (EFI_STRING) (UserInfo + 1), NULL);\r
- if (UserName == 0) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- HiiCreateGotoOpCode (\r
- OpCodeHandle, // Container for dynamic created opcodes\r
- FORMID_PROVIDER_FORM, // Target Form ID\r
- UserName, // Prompt text\r
- STRING_TOKEN (STR_NULL_STRING), // Help text\r
- EFI_IFR_FLAG_CALLBACK, // Question flag\r
- (UINT16) Index // Question ID\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Identify the user whose identity policy does not contain the operator 'OR'.\r
-\r
- @param[in] User Points to the user profile.\r
-\r
- @retval EFI_SUCCESS The specified user is identified successfully.\r
- @retval Others Fail to identify the user.\r
-\r
-**/\r
-EFI_STATUS\r
-IdentifyAndTypeUser (\r
- IN USER_PROFILE_ENTRY *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *IdentifyInfo;\r
- BOOLEAN Success;\r
- UINTN TotalLen;\r
- UINTN ValueLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
-\r
- //\r
- // Get user identify policy information.\r
- //\r
- IdentifyInfo = NULL;\r
- Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- ASSERT (IdentifyInfo != NULL);\r
-\r
- //\r
- // Check each part of identification policy expression.\r
- //\r
- Success = FALSE;\r
- TotalLen = 0;\r
- while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
- ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
- switch (Identity->Type) {\r
-\r
- case EFI_USER_INFO_IDENTITY_FALSE:\r
- //\r
- // Check False option.\r
- //\r
- Success = FALSE;\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_TRUE:\r
- //\r
- // Check True option.\r
- //\r
- Success = TRUE;\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_NOT:\r
- //\r
- // Check negative operation.\r
- //\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_AND:\r
- //\r
- // Check and operation.\r
- //\r
- if (!Success) {\r
- return EFI_NOT_READY;\r
- }\r
-\r
- Success = FALSE;\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_OR:\r
- //\r
- // Check or operation.\r
- //\r
- if (Success) {\r
- return EFI_SUCCESS;\r
- }\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
- //\r
- // Check credential provider by type.\r
- //\r
- break;\r
-\r
- case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
- //\r
- // Check credential provider by ID.\r
- //\r
- if (ValueLen != sizeof (EFI_GUID)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = IdentifyByProviderId (User, (EFI_GUID *) (Identity + 1));\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Success = TRUE;\r
- break;\r
-\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
-\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- if (TotalLen != IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!Success) {\r
- return EFI_NOT_READY;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Identify the user whose identity policy does not contain the operator 'AND'.\r
-\r
- @param[in] User Points to the user profile.\r
-\r
- @retval EFI_SUCCESS The specified user is identified successfully.\r
- @retval Others Fail to identify the user.\r
-\r
-**/\r
-EFI_STATUS\r
-IdentifyOrTypeUser (\r
- IN USER_PROFILE_ENTRY *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *IdentifyInfo;\r
- UINTN TotalLen;\r
- UINTN ValueLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel;\r
-\r
- //\r
- // Get user identify policy information.\r
- //\r
- IdentifyInfo = NULL;\r
- Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- ASSERT (IdentifyInfo != NULL);\r
-\r
- //\r
- // Initialize the container for dynamic opcodes.\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode.\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
- StartOpCodeHandle,\r
- &gEfiIfrTianoGuid,\r
- NULL,\r
- sizeof (EFI_IFR_GUID_LABEL)\r
- );\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = LABEL_PROVIDER_NAME;\r
-\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
- EndOpCodeHandle,\r
- &gEfiIfrTianoGuid,\r
- NULL,\r
- sizeof (EFI_IFR_GUID_LABEL)\r
- );\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Add the providers that exists in the user's policy.\r
- //\r
- TotalLen = 0;\r
- while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
- ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
- AddProviderSelection ((EFI_GUID *) (Identity + 1), StartOpCodeHandle);\r
- }\r
-\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- HiiUpdateForm (\r
- mCallbackInfo->HiiHandle, // HII handle\r
- &gUserIdentifyManagerGuid,// Formset GUID\r
- FORMID_PROVIDER_FORM, // Form ID\r
- StartOpCodeHandle, // Label for where to insert opcodes\r
- EndOpCodeHandle // Replace data\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser.\r
- @param QuestionId A unique value which is sent to the original\r
- exporting driver so that it can identify the type\r
- of data to expect.\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original\r
- exporting driver.\r
- @param ActionRequest On return, points to the action requested by the\r
- callback function.\r
-\r
- @retval EFI_SUCCESS The callback successfully handled the action.\r
- @retval Others Fail to handle the action.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserIdentifyManagerCallback (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN EFI_BROWSER_ACTION Action,\r
- IN EFI_QUESTION_ID QuestionId,\r
- IN UINT8 Type,\r
- IN EFI_IFR_TYPE_VALUE *Value,\r
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
- )\r
-{\r
- EFI_STATUS Status;\r
- USER_PROFILE_ENTRY *User;\r
- UINT8 PolicyType;\r
- UINT16 Index;\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- switch (Action) {\r
- case EFI_BROWSER_ACTION_FORM_OPEN:\r
- {\r
- //\r
- // Update user Form when user Form is opened.\r
- // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.\r
- //\r
- if (QuestionId != FORM_OPEN_QUESTION_ID) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Initialize the container for dynamic opcodes.\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode.\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
- StartOpCodeHandle,\r
- &gEfiIfrTianoGuid,\r
- NULL,\r
- sizeof (EFI_IFR_GUID_LABEL)\r
- );\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = LABEL_USER_NAME;\r
-\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
- EndOpCodeHandle,\r
- &gEfiIfrTianoGuid,\r
- NULL,\r
- sizeof (EFI_IFR_GUID_LABEL)\r
- );\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Add all the user profile in the user profile database.\r
- //\r
- for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
- User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index];\r
- AddUserSelection ((UINT16)(LABEL_USER_NAME + Index), User, StartOpCodeHandle);\r
- }\r
-\r
- HiiUpdateForm (\r
- mCallbackInfo->HiiHandle, // HII handle\r
- &gUserIdentifyManagerGuid,// Formset GUID\r
- FORMID_USER_FORM, // Form ID\r
- StartOpCodeHandle, // Label for where to insert opcodes\r
- EndOpCodeHandle // Replace data\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
-\r
- return EFI_SUCCESS;\r
- }\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_FORM_CLOSE:\r
- Status = EFI_SUCCESS;\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_CHANGED:\r
- if (QuestionId >= LABEL_PROVIDER_NAME) {\r
- //\r
- // QuestionId comes from the second Form (Select a Credential Provider if identity\r
- // policy is OR type). Identify the user by the selected provider.\r
- //\r
- Status = IdentifyByProviderId (mCurrentUser, &mProviderDb->Provider[QuestionId & 0xFFF]->Identifier);\r
- if (Status == EFI_SUCCESS) {\r
- mIdentified = TRUE;\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_CHANGING:\r
- //\r
- // QuestionId comes from the first Form (Select a user to identify).\r
- //\r
- if (QuestionId >= LABEL_PROVIDER_NAME) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[QuestionId & 0xFFF];\r
- Status = GetIdentifyType (User, &PolicyType);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (PolicyType == EFI_USER_INFO_IDENTITY_OR) {\r
- //\r
- // Identify the user by "OR" logical.\r
- //\r
- Status = IdentifyOrTypeUser (User);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
- } else {\r
- //\r
- // Identify the user by "AND" logical.\r
- //\r
- Status = IdentifyAndTypeUser (User);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
- mIdentified = TRUE;\r
- if (Type == EFI_IFR_TYPE_REF) {\r
- Value->ref.FormId = FORMID_INVALID_FORM;\r
- }\r
- }\r
- break;\r
-\r
- default:\r
- //\r
- // All other action return unsupported.\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
- }\r
-\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- This function construct user profile database from user data saved in the Flash.\r
- If no user is found in Flash, add one default user "administrator" in the user\r
- profile database.\r
-\r
- @retval EFI_SUCCESS Init user profile database successfully.\r
- @retval Others Fail to init user profile database.\r
-\r
-**/\r
-EFI_STATUS\r
-InitUserProfileDb (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *VarData;\r
- UINTN VarSize;\r
- UINTN CurVarSize;\r
- CHAR16 VarName[10];\r
- UINTN Index;\r
- UINT32 VarAttr;\r
-\r
- if (mUserProfileDb != NULL) {\r
- //\r
- // The user profiles had been already initialized.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Init user profile database structure.\r
- //\r
- if (!ExpandUsermUserProfileDb ()) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CurVarSize = DEFAULT_PROFILE_SIZE;\r
- VarData = AllocateZeroPool (CurVarSize);\r
- if (VarData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Get all user proifle entries.\r
- //\r
- Index = 0;\r
- while (TRUE) {\r
- //\r
- // Get variable name.\r
- //\r
- UnicodeSPrint (\r
- VarName,\r
- sizeof (VarName),\r
- L"User%04x",\r
- Index\r
- );\r
- Index++;\r
-\r
- //\r
- // Get variable value.\r
- //\r
- VarSize = CurVarSize;\r
- Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- FreePool (VarData);\r
- VarData = AllocatePool (VarSize);\r
- if (VarData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- break;\r
- }\r
-\r
- CurVarSize = VarSize;\r
- Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_NOT_FOUND) {\r
- Status = EFI_SUCCESS;\r
- }\r
- break;\r
- }\r
-\r
- //\r
- // Check variable attributes.\r
- //\r
- if (VarAttr != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) {\r
- Status = gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
- continue;\r
- }\r
-\r
- //\r
- // Add user profile to the user profile database.\r
- //\r
- Status = AddUserProfile (NULL, VarSize, VarData, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_SECURITY_VIOLATION) {\r
- //\r
- // Delete invalid user profile\r
- //\r
- gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
- } else if (Status == EFI_OUT_OF_RESOURCES) {\r
- break;\r
- }\r
- } else {\r
- //\r
- // Delete and save the profile again if some invalid profiles are deleted.\r
- //\r
- if (mUserProfileDb->UserProfileNum < Index) {\r
- gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
- SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], FALSE);\r
- }\r
- }\r
- }\r
-\r
- if (VarData != NULL) {\r
- FreePool (VarData);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check whether the user profile database is empty.\r
- //\r
- if (mUserProfileDb->UserProfileNum == 0) {\r
- Status = AddDefaultUserProfile ();\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- This function collects all the credential providers and saves to mProviderDb.\r
-\r
- @retval EFI_SUCCESS Collect credential providers successfully.\r
- @retval Others Fail to collect credential providers.\r
-\r
-**/\r
-EFI_STATUS\r
-InitProviderInfo (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuf;\r
- UINTN Index;\r
-\r
- if (mProviderDb != NULL) {\r
- //\r
- // The credential providers had been collected before.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Try to find all the user credential provider driver.\r
- //\r
- HandleCount = 0;\r
- HandleBuf = NULL;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiUserCredential2ProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuf\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get provider infomation.\r
- //\r
- mProviderDb = AllocateZeroPool (\r
- sizeof (CREDENTIAL_PROVIDER_INFO) -\r
- sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *) +\r
- HandleCount * sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *)\r
- );\r
- if (mProviderDb == NULL) {\r
- FreePool (HandleBuf);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- mProviderDb->Count = HandleCount;\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuf[Index],\r
- &gEfiUserCredential2ProtocolGuid,\r
- (VOID **) &mProviderDb->Provider[Index]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (HandleBuf);\r
- FreePool (mProviderDb);\r
- mProviderDb = NULL;\r
- return Status;\r
- }\r
- }\r
-\r
- FreePool (HandleBuf);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- This function allows a caller to extract the current configuration for one\r
- or more named elements from the target driver.\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
- @param Progress On return, points to a character in the Request string.\r
- Points to the string's null terminator if request was successful.\r
- Points to the most recent '&' before the first failing name/value\r
- pair (or the beginning of the string if the failure is in the\r
- first name/value pair) if the request was not successful.\r
- @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
- has all values filled in for the names in the Request string.\r
- String to be allocated by the called function.\r
-\r
- @retval EFI_SUCCESS The Results is filled with the requested values.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FakeExtractConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Request,\r
- OUT EFI_STRING *Progress,\r
- OUT EFI_STRING *Results\r
- )\r
-{\r
- if (Progress == NULL || Results == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- *Progress = Request;\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
- @param Progress A pointer to a string filled in with the offset of the most\r
- recent '&' before the first failing name/value pair (or the\r
- beginning of the string if the failure is in the first\r
- name/value pair) or the terminating NULL if all was successful.\r
-\r
- @retval EFI_SUCCESS The Results is processed successfully.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FakeRouteConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Configuration,\r
- OUT EFI_STRING *Progress\r
- )\r
-{\r
- if (Configuration == NULL || Progress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Progress = Configuration;\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- This function initialize the data mainly used in form browser.\r
-\r
- @retval EFI_SUCCESS Initialize form data successfully.\r
- @retval Others Fail to Initialize form data.\r
-\r
-**/\r
-EFI_STATUS\r
-InitFormBrowser (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- USER_MANAGER_CALLBACK_INFO *CallbackInfo;\r
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
- EFI_HII_STRING_PROTOCOL *HiiString;\r
- EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
-\r
- //\r
- // Initialize driver private data.\r
- //\r
- CallbackInfo = AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO));\r
- if (CallbackInfo == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CallbackInfo->Signature = USER_MANAGER_SIGNATURE;\r
- CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
- CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
- CallbackInfo->ConfigAccess.Callback = UserIdentifyManagerCallback;\r
-\r
- //\r
- // Locate Hii Database protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- CallbackInfo->HiiDatabase = HiiDatabase;\r
-\r
- //\r
- // Locate HiiString protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- CallbackInfo->HiiString = HiiString;\r
-\r
- //\r
- // Locate Formbrowser2 protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CallbackInfo->FormBrowser2 = FormBrowser2;\r
- CallbackInfo->DriverHandle = NULL;\r
-\r
- //\r
- // Install Device Path Protocol and Config Access protocol to driver handle.\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &CallbackInfo->DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- &mHiiVendorDevicePath,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &CallbackInfo->ConfigAccess,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Publish HII data.\r
- //\r
- CallbackInfo->HiiHandle = HiiAddPackages (\r
- &gUserIdentifyManagerGuid,\r
- CallbackInfo->DriverHandle,\r
- UserIdentifyManagerStrings,\r
- UserIdentifyManagerVfrBin,\r
- NULL\r
- );\r
- if (CallbackInfo->HiiHandle == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- mCallbackInfo = CallbackInfo;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Identify the user whose identification policy supports auto logon.\r
-\r
- @param[in] ProviderIndex The provider index in the provider list.\r
- @param[out] User Points to user user profile if a user is identified successfully.\r
-\r
- @retval EFI_SUCCESS Identify a user with the specified provider successfully.\r
- @retval Others Fail to identify a user.\r
-\r
-**/\r
-EFI_STATUS\r
-IdentifyAutoLogonUser (\r
- IN UINTN ProviderIndex,\r
- OUT USER_PROFILE_ENTRY **User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *Info;\r
- UINT8 PolicyType;\r
-\r
- Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
- if (Info == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Info->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
- Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
-\r
- //\r
- // Identify the specified credential provider's auto logon user.\r
- //\r
- Status = mProviderDb->Provider[ProviderIndex]->User (\r
- mProviderDb->Provider[ProviderIndex],\r
- NULL,\r
- (EFI_USER_INFO_IDENTIFIER *) (Info + 1)\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- return Status;\r
- }\r
-\r
- //\r
- // Find user with the specified user ID.\r
- //\r
- *User = NULL;\r
- Status = FindUserProfileByInfo (User, NULL, Info, Info->InfoSize);\r
- FreePool (Info);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = GetIdentifyType ((EFI_USER_PROFILE_HANDLE) * User, &PolicyType);\r
- if (PolicyType == EFI_USER_INFO_IDENTITY_AND) {\r
- //\r
- // The identified user need also identified by other credential provider.\r
- // This can handle through select user.\r
- //\r
- return EFI_NOT_READY;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Check whether the given console is ready.\r
-\r
- @param[in] ProtocolGuid Points to the protocol guid of sonsole .\r
-\r
- @retval TRUE The given console is ready.\r
- @retval FALSE The given console is not ready.\r
-\r
-**/\r
-BOOLEAN\r
-CheckConsole (\r
- EFI_GUID *ProtocolGuid\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuf;\r
- UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- //\r
- // Try to find all the handle driver.\r
- //\r
- HandleCount = 0;\r
- HandleBuf = NULL;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- ProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuf\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- DevicePath = DevicePathFromHandle (HandleBuf[Index]);\r
- if (DevicePath != NULL) {\r
- FreePool (HandleBuf);\r
- return TRUE;\r
- }\r
- }\r
- FreePool (HandleBuf);\r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- Check whether the console is ready.\r
-\r
- @retval TRUE The console is ready.\r
- @retval FALSE The console is not ready.\r
-\r
-**/\r
-BOOLEAN\r
-IsConsoleReady (\r
- VOID\r
- )\r
-{\r
- if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid)) {\r
- return FALSE;\r
- }\r
-\r
- if (!CheckConsole (&gEfiSimpleTextInProtocolGuid)) {\r
- if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid)) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Identify a user to logon.\r
-\r
- @param[out] User Points to user user profile if a user is identified successfully.\r
-\r
- @retval EFI_SUCCESS Identify a user successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-IdentifyUser (\r
- OUT USER_PROFILE_ENTRY **User\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
- EFI_USER_INFO *IdentifyInfo;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
- EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;\r
- USER_PROFILE_ENTRY *UserEntry;\r
-\r
- //\r
- // Initialize credential providers.\r
- //\r
- InitProviderInfo ();\r
-\r
- //\r
- // Initialize user profile database.\r
- //\r
- InitUserProfileDb ();\r
-\r
- //\r
- // If only one user in system, and its identify policy is TRUE, then auto logon.\r
- //\r
- if (mUserProfileDb->UserProfileNum == 1) {\r
- UserEntry = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[0];\r
- IdentifyInfo = NULL;\r
- Status = FindUserInfoByType (UserEntry, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- ASSERT (IdentifyInfo != NULL);\r
-\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1));\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_TRUE) {\r
- mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
- UpdateUserInfo (UserEntry);\r
- *User = UserEntry;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Find and login the default & AutoLogon user.\r
- //\r
- for (Index = 0; Index < mProviderDb->Count; Index++) {\r
- UserCredential = mProviderDb->Provider[Index];\r
- Status = UserCredential->Default (UserCredential, &AutoLogon);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if ((AutoLogon & (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT | EFI_CREDENTIAL_LOGON_FLAG_AUTO)) != 0) {\r
- Status = IdentifyAutoLogonUser (Index, &UserEntry);\r
- if (Status == EFI_SUCCESS) {\r
- mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
- UpdateUserInfo (UserEntry);\r
- *User = UserEntry;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- if (!IsConsoleReady ()) {\r
- //\r
- // The console is still not ready for user selection.\r
- //\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Select a user and identify it.\r
- //\r
- mCallbackInfo->FormBrowser2->SendForm (\r
- mCallbackInfo->FormBrowser2,\r
- &mCallbackInfo->HiiHandle,\r
- 1,\r
- &gUserIdentifyManagerGuid,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
- if (mIdentified) {\r
- *User = (USER_PROFILE_ENTRY *) mCurrentUser;\r
- UpdateUserInfo (*User);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_ACCESS_DENIED;\r
-}\r
-\r
-\r
-/**\r
- An empty function to pass error checking of CreateEventEx ().\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context,\r
- which is implementation-dependent.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-InternalEmptyFuntion (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
-}\r
-\r
-\r
-/**\r
- Create, Signal, and Close the User Profile Changed event.\r
-\r
-**/\r
-VOID\r
-SignalEventUserProfileChanged (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT Event;\r
-\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- InternalEmptyFuntion,\r
- NULL,\r
- &gEfiEventUserProfileChangedGuid,\r
- &Event\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- gBS->SignalEvent (Event);\r
- gBS->CloseEvent (Event);\r
-}\r
-\r
-\r
-/**\r
- Create a new user profile.\r
-\r
- This function creates a new user profile with only a new user identifier attached and returns\r
- its handle. The user profile is non-volatile, but the handle User can change across reboots.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[out] User On return, points to the new user profile handle.\r
- The user profile handle is unique only during this boot.\r
-\r
- @retval EFI_SUCCESS User profile was successfully created.\r
- @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a\r
- user profile.\r
- @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.\r
- @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileCreate (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- OUT EFI_USER_PROFILE_HANDLE *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (User == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the right of the current user.\r
- //\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- }\r
-\r
- //\r
- // Create new user profile\r
- //\r
- Status = CreateUserProfile ((USER_PROFILE_ENTRY **) User);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Delete an existing user profile.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] User User profile handle.\r
-\r
- @retval EFI_SUCCESS User profile was successfully deleted.\r
- @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user\r
- profile or there is only one user profile.\r
- @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.\r
- @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileDelete (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_USER_PROFILE_HANDLE User\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the right of the current user.\r
- //\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Delete user profile.\r
- //\r
- Status = DelUserProfile (User);\r
- if (EFI_ERROR (Status)) {\r
- if (Status != EFI_INVALID_PARAMETER) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Enumerate all of the enrolled users on the platform.\r
-\r
- This function returns the next enrolled user profile. To retrieve the first user profile handle,\r
- point User at a NULL. Each subsequent call will retrieve another user profile handle until there\r
- are no more, at which point User will point to NULL.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in, out] User On entry, points to the previous user profile handle or NULL to\r
- start enumeration. On exit, points to the next user profile handle\r
- or NULL if there are no more user profiles.\r
-\r
- @retval EFI_SUCCESS Next enrolled user profile successfully returned.\r
- @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.\r
- @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileGetNext (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN OUT EFI_USER_PROFILE_HANDLE *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (User == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FindUserProfile ((USER_PROFILE_ENTRY **) User, TRUE, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Return the current user profile handle.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[out] CurrentUser On return, points to the current user profile handle.\r
-\r
- @retval EFI_SUCCESS Current user profile handle returned successfully.\r
- @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileCurrent (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- OUT EFI_USER_PROFILE_HANDLE *CurrentUser\r
- )\r
-{\r
- //\r
- // Get current user profile.\r
- //\r
- if ((This == NULL) || (CurrentUser == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *CurrentUser = mCurrentUser;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Identify a user.\r
-\r
- Identify the user and, if authenticated, returns the user handle and changes the current\r
- user profile. All user information marked as private in a previously selected profile\r
- is no longer available for inspection.\r
- Whenever the current user profile is changed then the an event with the GUID\r
- EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[out] User On return, points to the user profile handle for the current\r
- user profile.\r
-\r
- @retval EFI_SUCCESS User was successfully identified.\r
- @retval EFI_ACCESS_DENIED User was not successfully identified.\r
- @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileIdentify (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- OUT EFI_USER_PROFILE_HANDLE *User\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (User == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (mCurrentUser != NULL) {\r
- *User = mCurrentUser;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Identify user\r
- //\r
- Status = IdentifyUser ((USER_PROFILE_ENTRY **) User);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Publish the user info into the EFI system configuration table.\r
- //\r
- PublishUserTable ();\r
-\r
- //\r
- // Signal User Profile Changed event.\r
- //\r
- SignalEventUserProfileChanged ();\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Find a user using a user information record.\r
-\r
- This function searches all user profiles for the specified user information record.\r
- The search starts with the user information record handle following UserInfo and\r
- continues until either the information is found or there are no more user profiles.\r
- A match occurs when the Info.InfoType field matches the user information record\r
- type and the user information record data matches the portion of Info.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in, out] User On entry, points to the previously returned user profile\r
- handle, or NULL to start searching with the first user profile.\r
- On return, points to the user profile handle, or NULL if not\r
- found.\r
- @param[in, out] UserInfo On entry, points to the previously returned user information\r
- handle, or NULL to start searching with the first. On return,\r
- points to the user information handle of the user information\r
- record, or NULL if not found. Can be NULL, in which case only\r
- one user information record per user can be returned.\r
- @param[in] Info Points to the buffer containing the user information to be\r
- compared to the user information record. If the user information\r
- record data is empty, then only the user information record type\r
- is compared. If InfoSize is 0, then the user information record\r
- must be empty.\r
-\r
- @param[in] InfoSize The size of Info, in bytes.\r
-\r
- @retval EFI_SUCCESS User information was found. User points to the user profile\r
- handle, and UserInfo points to the user information handle.\r
- @retval EFI_NOT_FOUND User information was not found. User points to NULL, and\r
- UserInfo points to NULL.\r
- @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileFind (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN OUT EFI_USER_PROFILE_HANDLE *User,\r
- IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,\r
- IN CONST EFI_USER_INFO *Info,\r
- IN UINTN InfoSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Size;\r
-\r
- if ((This == NULL) || (User == NULL) || (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (InfoSize == 0) {\r
- //\r
- // If InfoSize is 0, then the user information record must be empty.\r
- //\r
- if (Info->InfoSize != sizeof (EFI_USER_INFO)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else {\r
- if (InfoSize != Info->InfoSize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- Size = Info->InfoSize;\r
-\r
- //\r
- // Find user profile accdoring to user information.\r
- //\r
- Status = FindUserProfileByInfo (\r
- (USER_PROFILE_ENTRY **) User,\r
- (EFI_USER_INFO **) UserInfo,\r
- (EFI_USER_INFO *) Info,\r
- Size\r
- );\r
- if (EFI_ERROR (Status)) {\r
- *User = NULL;\r
- if (UserInfo != NULL) {\r
- *UserInfo = NULL;\r
- }\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Return information attached to the user.\r
-\r
- This function returns user information. The format of the information is described in User\r
- Information. The function may return EFI_ACCESS_DENIED if the information is marked private\r
- and the handle specified by User is not the current user profile. The function may return\r
- EFI_ACCESS_DENIED if the information is marked protected and the information is associated\r
- with a credential provider for which the user has not been authenticated.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] User Handle of the user whose profile will be retrieved.\r
- @param[in] UserInfo Handle of the user information data record.\r
- @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,\r
- holds the user information. If the buffer is too small to hold the\r
- information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is\r
- updated to contain the number of bytes actually required.\r
- @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size\r
- of the user information.\r
-\r
- @retval EFI_SUCCESS Information returned successfully.\r
- @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the\r
- current user.\r
- @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the\r
- returned data. The actual size required is returned in *InfoSize.\r
- @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer\r
- to a valid user info handle.\r
- @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileGetInfo (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- IN EFI_USER_INFO_HANDLE UserInfo,\r
- OUT EFI_USER_INFO *Info,\r
- IN OUT UINTN *InfoSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (InfoSize == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((*InfoSize != 0) && (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((User == NULL) || (UserInfo == NULL)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = GetUserInfo (User, UserInfo, Info, InfoSize, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Add or update user information.\r
-\r
- This function changes user information. If NULL is pointed to by UserInfo, then a new user\r
- information record is created and its handle is returned in UserInfo. Otherwise, the existing\r
- one is replaced.\r
- If EFI_USER_INFO_IDENITTY_POLICY_RECORD is changed, it is the caller's responsibility to keep\r
- it to be synced with the information on credential providers.\r
- If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same\r
- type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo\r
- will point to the handle of the existing record.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] User Handle of the user whose profile will be retrieved.\r
- @param[in, out] UserInfo Handle of the user information data record.\r
- @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,\r
- holds the user information. If the buffer is too small to hold the\r
- information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is\r
- updated to contain the number of bytes actually required.\r
- @param[in] InfoSize On entry, points to the size of Info. On return, points to the size\r
- of the user information.\r
-\r
- @retval EFI_SUCCESS Information returned successfully.\r
- @retval EFI_ACCESS_DENIED The record is exclusive.\r
- @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified\r
- user profile or user information record.\r
- @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not\r
- refer to a valid user info handle.\r
- @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileSetInfo (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- IN OUT EFI_USER_INFO_HANDLE *UserInfo,\r
- IN CONST EFI_USER_INFO *Info,\r
- IN UINTN InfoSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (User == NULL) || (UserInfo == NULL) || (Info == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the right of the current user.\r
- //\r
- if (User != mCurrentUser) {\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
- if (*UserInfo != NULL) {\r
- //\r
- // Can't update info in other profiles without MANAGE right.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
- //\r
- // Can't add info into other profiles.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- }\r
-\r
- if (User == mCurrentUser) {\r
- if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF)) {\r
- //\r
- // Only identify policy can be added/updated.\r
- //\r
- if (Info->InfoType != EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Modify user information.\r
- //\r
- Status = ModifyUserInfo (User, (EFI_USER_INFO **) UserInfo, Info, InfoSize);\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_ACCESS_DENIED) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Called by credential provider to notify of information change.\r
-\r
- This function allows the credential provider to notify the User Identity Manager when user status\r
- has changed.\r
- If the User Identity Manager doesn't support asynchronous changes in credentials, then this function\r
- should return EFI_UNSUPPORTED.\r
- If current user does not exist, and the credential provider can identify a user, then make the user\r
- to be current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
- If current user already exists, and the credential provider can identify another user, then switch\r
- current user to the newly identified user, and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
- If current user was identified by this credential provider and now the credential provider cannot identify\r
- current user, then logout current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL2_PROTOCOL\r
- where the user has changed.\r
-\r
- @retval EFI_SUCCESS The User Identity Manager has handled the notification.\r
- @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.\r
- @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileNotify (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_HANDLE Changed\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-/**\r
- Delete user information.\r
-\r
- Delete the user information attached to the user profile specified by the UserInfo.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] User Handle of the user whose information will be deleted.\r
- @param[in] UserInfo Handle of the user information to remove.\r
-\r
- @retval EFI_SUCCESS User information deleted successfully.\r
- @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.\r
- @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileDeleteInfo (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- IN EFI_USER_INFO_HANDLE UserInfo\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the right of the current user.\r
- //\r
- if (User != mCurrentUser) {\r
- if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- }\r
-\r
- //\r
- // Delete user information.\r
- //\r
- Status = DelUserInfo (User, UserInfo, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_NOT_FOUND) {\r
- return EFI_NOT_FOUND;\r
- }\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Enumerate user information of all the enrolled users on the platform.\r
-\r
- This function returns the next user information record. To retrieve the first user\r
- information record handle, point UserInfo at a NULL. Each subsequent call will retrieve\r
- another user information record handle until there are no more, at which point UserInfo\r
- will point to NULL.\r
-\r
- @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
- @param[in] User Handle of the user whose information will be deleted.\r
- @param[in, out] UserInfo Handle of the user information to remove.\r
-\r
- @retval EFI_SUCCESS User information returned.\r
- @retval EFI_NOT_FOUND No more user information found.\r
- @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserProfileGetNextInfo (\r
- IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
- IN EFI_USER_PROFILE_HANDLE User,\r
- IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
- )\r
-{\r
- if ((This == NULL) || (UserInfo == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Get next user information entry.\r
- //\r
- return FindUserInfo (User, (EFI_USER_INFO **) UserInfo, TRUE, NULL);\r
-}\r
-\r
-\r
-/**\r
- Main entry for this driver.\r
-\r
- @param[in] ImageHandle Image handle this driver.\r
- @param[in] SystemTable Pointer to SystemTable.\r
-\r
- @retval EFI_SUCESS This function always complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UserIdentifyManagerInit (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
-\r
- EFI_STATUS Status;\r
-\r
- //\r
- // It is NOT robust enough to be included in production.\r
- //\r
- #error "This implementation is just a sample, please comment this line if you really want to use this driver."\r
-\r
- //\r
- // Initiate form browser.\r
- //\r
- InitFormBrowser ();\r
-\r
- //\r
- // Install protocol interfaces for the User Identity Manager.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mCallbackInfo->DriverHandle,\r
- &gEfiUserManagerProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &gUserIdentifyManager\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- LoadDeferredImageInit (ImageHandle);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r