-\r
-/**\r
- Replace the old identity info with NewInfo in NV Flash.\r
-\r
- This function only replace the identity record in the user profile. Don't update\r
- the the information on the credential provider.\r
- \r
- @param[in] User Point to the user profile.\r
- @param[in] NewInfo Point to the new identity policy info.\r
- @param[out] UserInfo Point to the new added identity info.\r
-\r
- @retval EFI_SUCCESS Replace user identity successfully.\r
- @retval Others Fail to Replace user identity.\r
-\r
-**/\r
-EFI_STATUS\r
-SaveUserIpInfo (\r
- IN USER_PROFILE_ENTRY * User,\r
- IN CONST EFI_USER_INFO * NewInfo,\r
- OUT EFI_USER_INFO **UserInfo OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *OldIpInfo;\r
- UINTN Offset;\r
- UINTN NextOffset;\r
-\r
- if ((NewInfo == NULL) || (User == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- //\r
- // Get user old identify policy information.\r
- //\r
- OldIpInfo = NULL;\r
- Status = FindUserInfoByType (User, &OldIpInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- \r
- //\r
- // Get the old identity policy offset.\r
- //\r
- Status = FindUserInfo (User, &OldIpInfo, FALSE, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- \r
- //\r
- // Delete the old identity policy information.\r
- //\r
- NextOffset = ALIGN_VARIABLE (OldIpInfo->InfoSize) + Offset;\r
- User->UserProfileSize -= ALIGN_VARIABLE (OldIpInfo->InfoSize);\r
- if (Offset < User->UserProfileSize) {\r
- CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);\r
- }\r
- \r
- //\r
- // Add new user information.\r
- //\r
- if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (NewInfo->InfoSize)) {\r
- if (!ExpandUserProfile (User, ALIGN_VARIABLE (NewInfo->InfoSize))) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- CopyMem (User->ProfileInfo + User->UserProfileSize, (VOID *) NewInfo, NewInfo->InfoSize);\r
- if (UserInfo != NULL) {\r
- *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);\r
- }\r
-\r
- User->UserProfileSize += ALIGN_VARIABLE (NewInfo->InfoSize);\r
-\r
- //\r
- // Save user profile information.\r
- //\r
- Status = SaveNvUserProfile (User, FALSE);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Remove the provider in FindIdentity from the user identification information record.\r
- \r
- @param[in, out] NewInfo On entry, points to the user information to remove provider. \r
- On return, points to the user information the provider is removed.\r
- @param[in] FindIdentity Point to the user identity policy.\r
-\r
- @retval TRUE The provider is removed successfully.\r
- @retval FALSE Fail to remove the provider.\r
-\r
-**/\r
-BOOLEAN\r
-RemoveProvider (\r
- IN OUT EFI_USER_INFO **NewInfo,\r
- IN EFI_USER_INFO_IDENTITY_POLICY *FindIdentity\r
- )\r
-{\r
- UINTN TotalLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
- EFI_USER_INFO *IdentifyInfo;\r
- UINT8 *Buffer;\r
-\r
- IdentifyInfo = *NewInfo;\r
- TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
- if (TotalLen == FindIdentity->Length) {\r
- //\r
- // Only one credential provider in the identification policy.\r
- // Set the new policy to be TRUE after removed the provider.\r
- //\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (IdentifyInfo + 1);\r
- Identity->Type = EFI_USER_INFO_IDENTITY_TRUE;\r
- Identity->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); \r
- IdentifyInfo->InfoSize = sizeof (EFI_USER_INFO) + Identity->Length;\r
- return TRUE;\r
- }\r
-\r
- //\r
- // Found the credential provider.\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
- if ((Identity->Type == FindIdentity->Type) &&\r
- (Identity->Length == FindIdentity->Length) &&\r
- CompareGuid ((EFI_GUID *) (Identity + 1), (EFI_GUID *) (FindIdentity + 1))\r
- ) {\r
- //\r
- // Found the credential provider to delete\r
- //\r
- if (Identity == (EFI_USER_INFO_IDENTITY_POLICY *)(IdentifyInfo + 1)) {\r
- //\r
- // It is the first item in the identification policy, delete it and the connector after it.\r
- //\r
- Buffer = (UINT8 *) Identity + Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
- IdentifyInfo->InfoSize -= Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
- TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
- CopyMem (Identity, Buffer, TotalLen);\r
- } else {\r
- //\r
- // It is not the first item in the identification policy, delete it and the connector before it.\r
- //\r
- Buffer = (UINT8 *) Identity + Identity->Length;\r
- TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
- TotalLen -= (Buffer - (UINT8 *)(IdentifyInfo + 1));\r
- IdentifyInfo->InfoSize -= Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
- CopyMem ((UINT8 *) (Identity - 1), Buffer, TotalLen);\r
- } \r
- return TRUE;\r
- }\r
-\r
- TotalLen += Identity->Length;\r
- } \r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- This function replaces the old identity policy with a new identity policy.\r
-\r
- This function changes user identity policy information.\r
- If enroll new credential failed, recover the old identity policy.\r
-\r
- For new policy:\r
- a. For each credential, if it is newly added, try to enroll it.\r
- If enroll failed, try to delete the newly added ones.\r
- \r
- b. For each credential, if it exists in the old policy, delete old one, \r
- and enroll new one. If failed to enroll the new one, removed it from new \r
- identification policy.\r
-\r
- For old policy: \r
- a. For each credential, if it does not exist in new one, delete it.\r
-\r
- @param[in] User Point to the user profile.\r
- @param[in] Info Points to the user identity information.\r
- @param[in] InfoSize The size of Info (Not used in this function).\r
- @param[out] IpInfo The new identification info after modify.\r
-\r
- @retval EFI_SUCCESS Modify user identity policy successfully.\r
- @retval Others Fail to modify user identity policy.\r
-\r
-**/\r
-EFI_STATUS\r
-ModifyUserIpInfo (\r
- IN USER_PROFILE_ENTRY *User,\r
- IN CONST EFI_USER_INFO *Info,\r
- IN UINTN InfoSize,\r
- OUT EFI_USER_INFO **IpInfo\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_USER_INFO *OldIpInfo;\r
- UINTN TotalLen;\r
- EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
- UINT32 CredentialCount;\r
- EFI_USER_INFO *NewIpInfo;\r
-\r
- //\r
- // Get user old identify policy information.\r
- //\r
- OldIpInfo = NULL;\r
- Status = FindUserInfoByType (User, &OldIpInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- ASSERT (OldIpInfo != NULL);\r
- \r
- //\r
- // Enroll new added credential provider.\r
- //\r
- CredentialCount = 0;\r
- TotalLen = 0;\r
- while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
- if (!FindProvider (Identity, OldIpInfo)) {\r
- //\r
- // The credential is NOT found in the old identity policy; add it.\r
- //\r
- Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- CredentialCount++;\r
- }\r
- }\r
-\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Enroll new credential failed. Delete the newly enrolled credential, and return.\r
- //\r
- TotalLen = 0;\r
- while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
- if (!FindProvider (Identity, OldIpInfo)) {\r
- //\r
- // The credential is NOT found in the old identity policy. Delete it.\r
- //\r
- if (CredentialCount == 0) {\r
- break;\r
- }\r
-\r
- ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
- CredentialCount--;\r
- }\r
- }\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
- }\r
- \r
- //\r
- // Backup new identification policy\r
- //\r
- NewIpInfo = AllocateCopyPool (Info->InfoSize, Info); \r
- ASSERT (NewIpInfo != NULL);\r
-\r
- //\r
- // Enroll the credential that existed in the old identity policy.\r
- //\r
- TotalLen = 0;\r
- while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
- if (FindProvider (Identity, OldIpInfo)) {\r
- //\r
- // The credential is found in the old identity policy, so delete the old credential first.\r
- //\r
- Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Failed to delete old credential.\r
- //\r
- FreePool (NewIpInfo);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Add the new credential.\r
- //\r
- Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Failed to enroll the user by new identification policy.\r
- // So removed the credential provider from the identification policy \r
- //\r
- RemoveProvider (&NewIpInfo, Identity);\r
- } \r
- }\r
- }\r
- TotalLen += Identity->Length;\r
- }\r
- \r
- //\r
- // Delete old credential that didn't exist in the new identity policy.\r
- //\r
- TotalLen = 0;\r
- while (TotalLen < OldIpInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
- Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (OldIpInfo + 1) + TotalLen);\r
- if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
- if (!FindProvider (Identity, Info)) {\r
- //\r
- // The credential is NOT found in the new identity policy. Delete the old credential.\r
- //\r
- ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
- }\r
- }\r
- TotalLen += Identity->Length;\r
- }\r
-\r
- *IpInfo = NewIpInfo;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r